    001package net.minecraft.entity.player;
    002
    003import cpw.mods.fml.common.FMLCommonHandler;
    004import cpw.mods.fml.common.network.FMLNetworkHandler;
    005import cpw.mods.fml.relauncher.Side;
    006import cpw.mods.fml.relauncher.SideOnly;
    007import java.util.Collection;
    008import java.util.Iterator;
    009import java.util.List;
    010import net.minecraft.block.Block;
    011import net.minecraft.block.BlockBed;
    012import net.minecraft.block.material.Material;
    013import net.minecraft.command.ICommandSender;
    014import net.minecraft.enchantment.EnchantmentHelper;
    015import net.minecraft.enchantment.EnchantmentThorns;
    016import net.minecraft.entity.Entity;
    017import net.minecraft.entity.EntityLiving;
    018import net.minecraft.entity.IEntityMultiPart;
    019import net.minecraft.entity.IMerchant;
    020import net.minecraft.entity.boss.EntityDragonPart;
    021import net.minecraft.entity.item.EntityBoat;
    022import net.minecraft.entity.item.EntityItem;
    023import net.minecraft.entity.item.EntityMinecart;
    024import net.minecraft.entity.item.EntityMinecartHopper;
    025import net.minecraft.entity.monster.EntityCreeper;
    026import net.minecraft.entity.monster.EntityGhast;
    027import net.minecraft.entity.monster.EntityMob;
    028import net.minecraft.entity.monster.IMob;
    029import net.minecraft.entity.passive.EntityPig;
    030import net.minecraft.entity.passive.EntityWolf;
    031import net.minecraft.entity.projectile.EntityArrow;
    032import net.minecraft.entity.projectile.EntityFishHook;
    033import net.minecraft.inventory.Container;
    034import net.minecraft.inventory.ContainerPlayer;
    035import net.minecraft.inventory.IInventory;
    036import net.minecraft.inventory.InventoryEnderChest;
    037import net.minecraft.item.EnumAction;
    038import net.minecraft.item.Item;
    039import net.minecraft.item.ItemStack;
    040import net.minecraft.nbt.NBTTagCompound;
    041import net.minecraft.nbt.NBTTagList;
    042import net.minecraft.potion.Potion;
    043import net.minecraft.scoreboard.Score;
    044import net.minecraft.scoreboard.ScoreObjective;
    045import net.minecraft.scoreboard.ScoreObjectiveCriteria;
    046import net.minecraft.scoreboard.ScorePlayerTeam;
    047import net.minecraft.scoreboard.Scoreboard;
    048import net.minecraft.stats.AchievementList;
    049import net.minecraft.stats.StatBase;
    050import net.minecraft.stats.StatList;
    051import net.minecraft.tileentity.TileEntity;
    052import net.minecraft.tileentity.TileEntityBeacon;
    053import net.minecraft.tileentity.TileEntityBrewingStand;
    054import net.minecraft.tileentity.TileEntityDispenser;
    055import net.minecraft.tileentity.TileEntityFurnace;
    056import net.minecraft.tileentity.TileEntityHopper;
    057import net.minecraft.util.AxisAlignedBB;
    058import net.minecraft.util.ChunkCoordinates;
    059import net.minecraft.util.DamageSource;
    060import net.minecraft.util.FoodStats;
    061import net.minecraft.util.Icon;
    062import net.minecraft.util.MathHelper;
    063import net.minecraft.util.StringTranslate;
    064import net.minecraft.util.Vec3;
    065import net.minecraft.world.EnumGameType;
    066import net.minecraft.world.World;
    067import net.minecraft.world.chunk.IChunkProvider;
    068
    069import net.minecraftforge.common.ForgeHooks;
    070import net.minecraftforge.common.ISpecialArmor.ArmorProperties;
    071import net.minecraftforge.common.MinecraftForge;
    072import net.minecraftforge.event.ForgeEventFactory;
    073import net.minecraftforge.event.entity.living.LivingHurtEvent;
    074import net.minecraftforge.event.entity.player.AttackEntityEvent;
    075import net.minecraftforge.event.entity.player.EntityInteractEvent;
    076import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;
    077import net.minecraftforge.event.entity.player.PlayerDropsEvent;
    078import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent;
    079import net.minecraftforge.event.entity.player.PlayerSleepInBedEvent;
    080
    081public abstract class EntityPlayer extends EntityLiving implements ICommandSender
    082{
    083    public static final String PERSISTED_NBT_TAG = "PlayerPersisted";
    084    public int maxHealth = 20;
    085
    086    /** Inventory of the player */
    087    public InventoryPlayer inventory = new InventoryPlayer(this);
    088    private InventoryEnderChest theInventoryEnderChest = new InventoryEnderChest();
    089
    090    /**
    091     * The Container for the player's inventory (which opens when they press E)
    092     */
    093    public Container inventoryContainer;
    094
    095    /** The Container the player has open. */
    096    public Container openContainer;
    097
    098    /** The player's food stats. (See class FoodStats) */
    099    protected FoodStats foodStats = new FoodStats();
    100
    101    /**
    102     * Used to tell if the player pressed jump twice. If this is at 0 and it's pressed (And they are allowed to fly, as
    103     * defined in the player's movementInput) it sets this to 7. If it's pressed and it's greater than 0 enable fly.
    104     */
    105    protected int flyToggleTimer = 0;
    106    public byte field_71098_bD = 0;
    107    public float prevCameraYaw;
    108    public float cameraYaw;
    109    public String username;
    110
    111    /**
    112     * Used by EntityPlayer to prevent too many xp orbs from getting absorbed at once.
    113     */
    114    public int xpCooldown = 0;
    115    public double field_71091_bM;
    116    public double field_71096_bN;
    117    public double field_71097_bO;
    118    public double field_71094_bP;
    119    public double field_71095_bQ;
    120    public double field_71085_bR;
    121
    122    /** Boolean value indicating weather a player is sleeping or not */
    123    protected boolean sleeping;
    124
    125    /**
    126     * The chunk coordinates of the bed the player is in (null if player isn't in a bed).
    127     */
    128    public ChunkCoordinates playerLocation;
    129    public int sleepTimer;
    130    public float field_71079_bU;
    131    @SideOnly(Side.CLIENT)
    132    public float field_71082_cx;
    133    public float field_71089_bV;
    134
    135    /**
    136     * Holds the last coordinate to spawn based on last bed that the player sleep.
    137     */
    138    private ChunkCoordinates spawnChunk;
    139
    140    /**
    141     * Whether this player's spawn point is forced, preventing execution of bed checks.
    142     */
    143    private boolean spawnForced;
    144
    145    /** Holds the coordinate of the player when enter a minecraft to ride. */
    146    private ChunkCoordinates startMinecartRidingCoordinate;
    147
    148    /** The player's capabilities. (See class PlayerCapabilities) */
    149    public PlayerCapabilities capabilities = new PlayerCapabilities();
    150
    151    /** The current experience level the player is on. */
    152    public int experienceLevel;
    153
    154    /**
    155     * The total amount of experience the player has. This also includes the amount of experience within their
    156     * Experience Bar.
    157     */
    158    public int experienceTotal;
    159
    160    /**
    161     * The current amount of experience the player has within their Experience Bar.
    162     */
    163    public float experience;
    164
    165    /**
    166     * This is the item that is in use when the player is holding down the useItemButton (e.g., bow, food, sword)
    167     */
    168    private ItemStack itemInUse;
    169
    170    /**
    171     * This field starts off equal to getMaxItemUseDuration and is decremented on each tick
    172     */
    173    private int itemInUseCount;
    174    protected float speedOnGround = 0.1F;
    175    protected float speedInAir = 0.02F;
    176    private int field_82249_h = 0;
    177
    178    /**
    179     * An instance of a fishing rod's hook. If this isn't null, the icon image of the fishing rod is slightly different
    180     */
    181    public EntityFishHook fishEntity = null;
    182
    183    public EntityPlayer(World par1World)
    184    {
    185        super(par1World);
    186        this.inventoryContainer = new ContainerPlayer(this.inventory, !par1World.isRemote, this);
    187        this.openContainer = this.inventoryContainer;
    188        this.yOffset = 1.62F;
    189        ChunkCoordinates chunkcoordinates = par1World.getSpawnPoint();
    190        this.setLocationAndAngles((double)chunkcoordinates.posX + 0.5D, (double)(chunkcoordinates.posY + 1), (double)chunkcoordinates.posZ + 0.5D, 0.0F, 0.0F);
    191        this.entityType = "humanoid";
    192        this.field_70741_aB = 180.0F;
    193        this.fireResistance = 20;
    194        this.texture = "/mob/char.png";
    195    }
    196
    197    public int getMaxHealth()
    198    {
    199        return maxHealth <= 0 ? 20 : maxHealth;
    200    }
    201
    202    protected void entityInit()
    203    {
    204        super.entityInit();
    205        this.dataWatcher.addObject(16, Byte.valueOf((byte)0));
    206        this.dataWatcher.addObject(17, Byte.valueOf((byte)0));
    207        this.dataWatcher.addObject(18, Integer.valueOf(0));
    208    }
    209
    210    @SideOnly(Side.CLIENT)
    211
    212    /**
    213     * returns the ItemStack containing the itemInUse
    214     */
    215    public ItemStack getItemInUse()
    216    {
    217        return this.itemInUse;
    218    }
    219
    220    @SideOnly(Side.CLIENT)
    221
    222    /**
    223     * Returns the item in use count
    224     */
    225    public int getItemInUseCount()
    226    {
    227        return this.itemInUseCount;
    228    }
    229
    230    /**
    231     * Checks if the entity is currently using an item (e.g., bow, food, sword) by holding down the useItemButton
    232     */
    233    public boolean isUsingItem()
    234    {
    235        return this.itemInUse != null;
    236    }
    237
    238    @SideOnly(Side.CLIENT)
    239
    240    /**
    241     * gets the duration for how long the current itemInUse has been in use
    242     */
    243    public int getItemInUseDuration()
    244    {
    245        return this.isUsingItem() ? this.itemInUse.getMaxItemUseDuration() - this.itemInUseCount : 0;
    246    }
    247
    248    public void stopUsingItem()
    249    {
    250        if (this.itemInUse != null)
    251        {
    252            this.itemInUse.onPlayerStoppedUsing(this.worldObj, this, this.itemInUseCount);
    253        }
    254
    255        this.clearItemInUse();
    256    }
    257
    258    public void clearItemInUse()
    259    {
    260        this.itemInUse = null;
    261        this.itemInUseCount = 0;
    262
    263        if (!this.worldObj.isRemote)
    264        {
    265            this.setEating(false);
    266        }
    267    }
    268
    269    public boolean isBlocking()
    270    {
    271        return this.isUsingItem() && Item.itemsList[this.itemInUse.itemID].getItemUseAction(this.itemInUse) == EnumAction.block;
    272    }
    273
    274    /**
    275     * Called to update the entity's position/logic.
    276     */
    277    public void onUpdate()
    278    {
    279        FMLCommonHandler.instance().onPlayerPreTick(this);
    280        if (this.itemInUse != null)
    281        {
    282            ItemStack itemstack = this.inventory.getCurrentItem();
    283
    284            if (itemstack == this.itemInUse)
    285            {
    286                itemInUse.getItem().onUsingItemTick(itemInUse, this, itemInUseCount);
    287                if (this.itemInUseCount <= 25 && this.itemInUseCount % 4 == 0)
    288                {
    289                    this.updateItemUse(itemstack, 5);
    290                }
    291
    292                if (--this.itemInUseCount == 0 && !this.worldObj.isRemote)
    293                {
    294                    this.onItemUseFinish();
    295                }
    296            }
    297            else
    298            {
    299                this.clearItemInUse();
    300            }
    301        }
    302
    303        if (this.xpCooldown > 0)
    304        {
    305            --this.xpCooldown;
    306        }
    307
    308        if (this.isPlayerSleeping())
    309        {
    310            ++this.sleepTimer;
    311
    312            if (this.sleepTimer > 100)
    313            {
    314                this.sleepTimer = 100;
    315            }
    316
    317            if (!this.worldObj.isRemote)
    318            {
    319                if (!this.isInBed())
    320                {
    321                    this.wakeUpPlayer(true, true, false);
    322                }
    323                else if (this.worldObj.isDaytime())
    324                {
    325                    this.wakeUpPlayer(false, true, true);
    326                }
    327            }
    328        }
    329        else if (this.sleepTimer > 0)
    330        {
    331            ++this.sleepTimer;
    332
    333            if (this.sleepTimer >= 110)
    334            {
    335                this.sleepTimer = 0;
    336            }
    337        }
    338
    339        super.onUpdate();
    340
    341        if (!this.worldObj.isRemote && this.openContainer != null && !this.openContainer.canInteractWith(this))
    342        {
    343            this.closeScreen();
    344            this.openContainer = this.inventoryContainer;
    345        }
    346
    347        if (this.isBurning() && this.capabilities.disableDamage)
    348        {
    349            this.extinguish();
    350        }
    351
    352        this.field_71091_bM = this.field_71094_bP;
    353        this.field_71096_bN = this.field_71095_bQ;
    354        this.field_71097_bO = this.field_71085_bR;
    355        double d0 = this.posX - this.field_71094_bP;
    356        double d1 = this.posY - this.field_71095_bQ;
    357        double d2 = this.posZ - this.field_71085_bR;
    358        double d3 = 10.0D;
    359
    360        if (d0 > d3)
    361        {
    362            this.field_71091_bM = this.field_71094_bP = this.posX;
    363        }
    364
    365        if (d2 > d3)
    366        {
    367            this.field_71097_bO = this.field_71085_bR = this.posZ;
    368        }
    369
    370        if (d1 > d3)
    371        {
    372            this.field_71096_bN = this.field_71095_bQ = this.posY;
    373        }
    374
    375        if (d0 < -d3)
    376        {
    377            this.field_71091_bM = this.field_71094_bP = this.posX;
    378        }
    379
    380        if (d2 < -d3)
    381        {
    382            this.field_71097_bO = this.field_71085_bR = this.posZ;
    383        }
    384
    385        if (d1 < -d3)
    386        {
    387            this.field_71096_bN = this.field_71095_bQ = this.posY;
    388        }
    389
    390        this.field_71094_bP += d0 * 0.25D;
    391        this.field_71085_bR += d2 * 0.25D;
    392        this.field_71095_bQ += d1 * 0.25D;
    393        this.addStat(StatList.minutesPlayedStat, 1);
    394
    395        if (this.ridingEntity == null)
    396        {
    397            this.startMinecartRidingCoordinate = null;
    398        }
    399
    400        if (!this.worldObj.isRemote)
    401        {
    402            this.foodStats.onUpdate(this);
    403        }
    404        FMLCommonHandler.instance().onPlayerPostTick(this);
    405    }
    406
    407    /**
    408     * Return the amount of time this entity should stay in a portal before being transported.
    409     */
    410    public int getMaxInPortalTime()
    411    {
    412        return this.capabilities.disableDamage ? 0 : 80;
    413    }
    414
    415    /**
    416     * Return the amount of cooldown before this entity can use a portal again.
    417     */
    418    public int getPortalCooldown()
    419    {
    420        return 10;
    421    }
    422
    423    public void playSound(String par1Str, float par2, float par3)
    424    {
    425        this.worldObj.playSoundToNearExcept(this, par1Str, par2, par3);
    426    }
    427
    428    /**
    429     * Plays sounds and makes particles for item in use state
    430     */
    431    protected void updateItemUse(ItemStack par1ItemStack, int par2)
    432    {
    433        if (par1ItemStack.getItemUseAction() == EnumAction.drink)
    434        {
    435            this.playSound("random.drink", 0.5F, this.worldObj.rand.nextFloat() * 0.1F + 0.9F);
    436        }
    437
    438        if (par1ItemStack.getItemUseAction() == EnumAction.eat)
    439        {
    440            for (int j = 0; j < par2; ++j)
    441            {
    442                Vec3 vec3 = this.worldObj.getWorldVec3Pool().getVecFromPool(((double)this.rand.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D);
    443                vec3.rotateAroundX(-this.rotationPitch * (float)Math.PI / 180.0F);
    444                vec3.rotateAroundY(-this.rotationYaw * (float)Math.PI / 180.0F);
    445                Vec3 vec31 = this.worldObj.getWorldVec3Pool().getVecFromPool(((double)this.rand.nextFloat() - 0.5D) * 0.3D, (double)(-this.rand.nextFloat()) * 0.6D - 0.3D, 0.6D);
    446                vec31.rotateAroundX(-this.rotationPitch * (float)Math.PI / 180.0F);
    447                vec31.rotateAroundY(-this.rotationYaw * (float)Math.PI / 180.0F);
    448                vec31 = vec31.addVector(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ);
    449                this.worldObj.spawnParticle("iconcrack_" + par1ItemStack.getItem().itemID, vec31.xCoord, vec31.yCoord, vec31.zCoord, vec3.xCoord, vec3.yCoord + 0.05D, vec3.zCoord);
    450            }
    451
    452            this.playSound("random.eat", 0.5F + 0.5F * (float)this.rand.nextInt(2), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
    453        }
    454    }
    455
    456    /**
    457     * Used for when item use count runs out, ie: eating completed
    458     */
    459    protected void onItemUseFinish()
    460    {
    461        if (this.itemInUse != null)
    462        {
    463            this.updateItemUse(this.itemInUse, 16);
    464            int i = this.itemInUse.stackSize;
    465            ItemStack itemstack = this.itemInUse.onFoodEaten(this.worldObj, this);
    466
    467            if (itemstack != this.itemInUse || itemstack != null && itemstack.stackSize != i)
    468            {
    469                this.inventory.mainInventory[this.inventory.currentItem] = itemstack;
    470
    471                if (itemstack.stackSize == 0)
    472                {
    473                    this.inventory.mainInventory[this.inventory.currentItem] = null;
    474                }
    475            }
    476
    477            this.clearItemInUse();
    478        }
    479    }
    480
    481    @SideOnly(Side.CLIENT)
    482    public void handleHealthUpdate(byte par1)
    483    {
    484        if (par1 == 9)
    485        {
    486            this.onItemUseFinish();
    487        }
    488        else
    489        {
    490            super.handleHealthUpdate(par1);
    491        }
    492    }
    493
    494    /**
    495     * Dead and sleeping entities cannot move
    496     */
    497    protected boolean isMovementBlocked()
    498    {
    499        return this.getHealth() <= 0 || this.isPlayerSleeping();
    500    }
    501
    502    /**
    503     * sets current screen to null (used on escape buttons of GUIs)
    504     */
    505    public void closeScreen()
    506    {
    507        this.openContainer = this.inventoryContainer;
    508    }
    509
    510    /**
    511     * Called when a player mounts an entity. e.g. mounts a pig, mounts a boat.
    512     */
    513    public void mountEntity(Entity par1Entity)
    514    {
    515        if (this.ridingEntity == par1Entity)
    516        {
    517            this.unmountEntity(par1Entity);
    518
    519            if (this.ridingEntity != null)
    520            {
    521                this.ridingEntity.riddenByEntity = null;
    522            }
    523
    524            this.ridingEntity = null;
    525        }
    526        else
    527        {
    528            super.mountEntity(par1Entity);
    529        }
    530    }
    531
    532    /**
    533     * Handles updating while being ridden by an entity
    534     */
    535    public void updateRidden()
    536    {
    537        double d0 = this.posX;
    538        double d1 = this.posY;
    539        double d2 = this.posZ;
    540        float f = this.rotationYaw;
    541        float f1 = this.rotationPitch;
    542        super.updateRidden();
    543        this.prevCameraYaw = this.cameraYaw;
    544        this.cameraYaw = 0.0F;
    545        this.addMountedMovementStat(this.posX - d0, this.posY - d1, this.posZ - d2);
    546
    547        if (this.ridingEntity instanceof EntityLiving && ((EntityLiving)ridingEntity).shouldRiderFaceForward(this))
    548        {
    549            this.rotationPitch = f1;
    550            this.rotationYaw = f;
    551            this.renderYawOffset = ((EntityLiving)this.ridingEntity).renderYawOffset;
    552        }
    553    }
    554
    555    @SideOnly(Side.CLIENT)
    556
    557    /**
    558     * Keeps moving the entity up so it isn't colliding with blocks and other requirements for this entity to be spawned
    559     * (only actually used on players though its also on Entity)
    560     */
    561    public void preparePlayerToSpawn()
    562    {
    563        this.yOffset = 1.62F;
    564        this.setSize(0.6F, 1.8F);
    565        super.preparePlayerToSpawn();
    566        this.setEntityHealth(this.getMaxHealth());
    567        this.deathTime = 0;
    568    }
    569
    570    protected void updateEntityActionState()
    571    {
    572        this.updateArmSwingProgress();
    573    }
    574
    575    /**
    576     * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
    577     * use this to react to sunlight and start to burn.
    578     */
    579    public void onLivingUpdate()
    580    {
    581        if (this.flyToggleTimer > 0)
    582        {
    583            --this.flyToggleTimer;
    584        }
    585
    586        if (this.worldObj.difficultySetting == 0 && this.getHealth() < this.getMaxHealth() && this.ticksExisted % 20 * 12 == 0)
    587        {
    588            this.heal(1);
    589        }
    590
    591        this.inventory.decrementAnimations();
    592        this.prevCameraYaw = this.cameraYaw;
    593        super.onLivingUpdate();
    594        this.landMovementFactor = this.capabilities.getWalkSpeed();
    595        this.jumpMovementFactor = this.speedInAir;
    596
    597        if (this.isSprinting())
    598        {
    599            this.landMovementFactor = (float)((double)this.landMovementFactor + (double)this.capabilities.getWalkSpeed() * 0.3D);
    600            this.jumpMovementFactor = (float)((double)this.jumpMovementFactor + (double)this.speedInAir * 0.3D);
    601        }
    602
    603        float f = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
    604        float f1 = (float)Math.atan(-this.motionY * 0.20000000298023224D) * 15.0F;
    605
    606        if (f > 0.1F)
    607        {
    608            f = 0.1F;
    609        }
    610
    611        if (!this.onGround || this.getHealth() <= 0)
    612        {
    613            f = 0.0F;
    614        }
    615
    616        if (this.onGround || this.getHealth() <= 0)
    617        {
    618            f1 = 0.0F;
    619        }
    620
    621        this.cameraYaw += (f - this.cameraYaw) * 0.4F;
    622        this.cameraPitch += (f1 - this.cameraPitch) * 0.8F;
    623
    624        if (this.getHealth() > 0)
    625        {
    626            List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(1.0D, 0.5D, 1.0D));
    627
    628            if (list != null)
    629            {
    630                for (int i = 0; i < list.size(); ++i)
    631                {
    632                    Entity entity = (Entity)list.get(i);
    633
    634                    if (!entity.isDead)
    635                    {
    636                        this.collideWithPlayer(entity);
    637                    }
    638                }
    639            }
    640        }
    641    }
    642
    643    private void collideWithPlayer(Entity par1Entity)
    644    {
    645        par1Entity.onCollideWithPlayer(this);
    646    }
    647
    648    public int getScore()
    649    {
    650        return this.dataWatcher.getWatchableObjectInt(18);
    651    }
    652
    653    /**
    654     * Set player's score
    655     */
    656    public void setScore(int par1)
    657    {
    658        this.dataWatcher.updateObject(18, Integer.valueOf(par1));
    659    }
    660
    661    /**
    662     * Add to player's score
    663     */
    664    public void addScore(int par1)
    665    {
    666        int j = this.getScore();
    667        this.dataWatcher.updateObject(18, Integer.valueOf(j + par1));
    668    }
    669
    670    /**
    671     * Called when the mob's health reaches 0.
    672     */
    673    public void onDeath(DamageSource par1DamageSource)
    674    {
    675        super.onDeath(par1DamageSource);
    676        this.setSize(0.2F, 0.2F);
    677        this.setPosition(this.posX, this.posY, this.posZ);
    678        this.motionY = 0.10000000149011612D;
    679
    680        captureDrops = true;
    681        capturedDrops.clear();
    682
    683        if (this.username.equals("Notch"))
    684        {
    685            this.dropPlayerItemWithRandomChoice(new ItemStack(Item.appleRed, 1), true);
    686        }
    687
    688        if (!this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory"))
    689        {
    690            this.inventory.dropAllItems();
    691        }
    692
    693        captureDrops = false;
    694
    695        if (!worldObj.isRemote)
    696        {
    697            PlayerDropsEvent event = new PlayerDropsEvent(this, par1DamageSource, capturedDrops, recentlyHit > 0);
    698            if (!MinecraftForge.EVENT_BUS.post(event))
    699            {
    700                for (EntityItem item : capturedDrops)
    701                {
    702                    joinEntityItemWithWorld(item);
    703                }
    704            }
    705        }
    706
    707        if (par1DamageSource != null)
    708        {
    709            this.motionX = (double)(-MathHelper.cos((this.attackedAtYaw + this.rotationYaw) * (float)Math.PI / 180.0F) * 0.1F);
    710            this.motionZ = (double)(-MathHelper.sin((this.attackedAtYaw + this.rotationYaw) * (float)Math.PI / 180.0F) * 0.1F);
    711        }
    712        else
    713        {
    714            this.motionX = this.motionZ = 0.0D;
    715        }
    716
    717        this.yOffset = 0.1F;
    718        this.addStat(StatList.deathsStat, 1);
    719    }
    720
    721    /**
    722     * Adds a value to the player score. Currently not actually used and the entity passed in does nothing. Args:
    723     * entity, scoreToAdd
    724     */
    725    public void addToPlayerScore(Entity par1Entity, int par2)
    726    {
    727        this.addScore(par2);
    728        Collection collection = this.func_96123_co().func_96520_a(ScoreObjectiveCriteria.field_96640_e);
    729
    730        if (par1Entity instanceof EntityPlayer)
    731        {
    732            this.addStat(StatList.playerKillsStat, 1);
    733            collection.addAll(this.func_96123_co().func_96520_a(ScoreObjectiveCriteria.field_96639_d));
    734        }
    735        else
    736        {
    737            this.addStat(StatList.mobKillsStat, 1);
    738        }
    739
    740        Iterator iterator = collection.iterator();
    741
    742        while (iterator.hasNext())
    743        {
    744            ScoreObjective scoreobjective = (ScoreObjective)iterator.next();
    745            Score score = this.func_96123_co().func_96529_a(this.getEntityName(), scoreobjective);
    746            score.func_96648_a();
    747        }
    748    }
    749
    750    /**
    751     * Called when player presses the drop item key
    752     */
    753    public EntityItem dropOneItem(boolean par1)
    754    {
    755        ItemStack stack = inventory.getCurrentItem();
    756
    757        if (stack == null)
    758        {
    759            return null;
    760        }
    761
    762        if (stack.getItem().onDroppedByPlayer(stack, this))
    763        {
    764            int count = par1 && this.inventory.getCurrentItem() != null ? this.inventory.getCurrentItem().stackSize : 1;
    765            return ForgeHooks.onPlayerTossEvent(this, inventory.decrStackSize(inventory.currentItem, count));
    766        }
    767
    768        return null;
    769    }
    770
    771    /**
    772     * Args: itemstack - called when player drops an item stack that's not in his inventory (like items still placed in
    773     * a workbench while the workbench'es GUI gets closed)
    774     */
    775    public EntityItem dropPlayerItem(ItemStack par1ItemStack)
    776    {
    777        return ForgeHooks.onPlayerTossEvent(this, par1ItemStack);
    778    }
    779
    780    /**
    781     * Args: itemstack, flag
    782     */
    783    public EntityItem dropPlayerItemWithRandomChoice(ItemStack par1ItemStack, boolean par2)
    784    {
    785        if (par1ItemStack == null)
    786        {
    787            return null;
    788        }
    789        else
    790        {
    791            EntityItem entityitem = new EntityItem(this.worldObj, this.posX, this.posY - 0.30000001192092896D + (double)this.getEyeHeight(), this.posZ, par1ItemStack);
    792            entityitem.delayBeforeCanPickup = 40;
    793            float f = 0.1F;
    794            float f1;
    795
    796            if (par2)
    797            {
    798                f1 = this.rand.nextFloat() * 0.5F;
    799                float f2 = this.rand.nextFloat() * (float)Math.PI * 2.0F;
    800                entityitem.motionX = (double)(-MathHelper.sin(f2) * f1);
    801                entityitem.motionZ = (double)(MathHelper.cos(f2) * f1);
    802                entityitem.motionY = 0.20000000298023224D;
    803            }
    804            else
    805            {
    806                f = 0.3F;
    807                entityitem.motionX = (double)(-MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI) * f);
    808                entityitem.motionZ = (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI) * f);
    809                entityitem.motionY = (double)(-MathHelper.sin(this.rotationPitch / 180.0F * (float)Math.PI) * f + 0.1F);
    810                f = 0.02F;
    811                f1 = this.rand.nextFloat() * (float)Math.PI * 2.0F;
    812                f *= this.rand.nextFloat();
    813                entityitem.motionX += Math.cos((double)f1) * (double)f;
    814                entityitem.motionY += (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1F);
    815                entityitem.motionZ += Math.sin((double)f1) * (double)f;
    816            }
    817
    818            this.joinEntityItemWithWorld(entityitem);
    819            this.addStat(StatList.dropStat, 1);
    820            return entityitem;
    821        }
    822    }
    823
    824    /**
    825     * Joins the passed in entity item with the world. Args: entityItem
    826     */
    827    public void joinEntityItemWithWorld(EntityItem par1EntityItem)
    828    {
    829        if (captureDrops)
    830        {
    831            capturedDrops.add(par1EntityItem);
    832            return;
    833        }
    834        this.worldObj.spawnEntityInWorld(par1EntityItem);
    835    }
    836
    837    /**
    838     * Returns how strong the player is against the specified block at this moment
    839     * Deprecated in favor of the more sensitive version
    840     */
    841    @Deprecated
    842    public float getCurrentPlayerStrVsBlock(Block par1Block, boolean par2)
    843    {
    844        return getCurrentPlayerStrVsBlock(par1Block, par2, 0);
    845    }
    846
    847    public float getCurrentPlayerStrVsBlock(Block par1Block, boolean par2, int meta)
    848    {
    849        ItemStack stack = inventory.getCurrentItem();
    850        float f = (stack == null ? 1.0F : stack.getItem().getStrVsBlock(stack, par1Block, meta));
    851
    852        if (f > 1.0F)
    853        {
    854            int i = EnchantmentHelper.getEfficiencyModifier(this);
    855            ItemStack itemstack = this.inventory.getCurrentItem();
    856
    857            if (i > 0 && itemstack != null)
    858            {
    859                float f1 = (float)(i * i + 1);
    860
    861                boolean canHarvest = ForgeHooks.canToolHarvestBlock(par1Block, meta, itemstack);
    862
    863                if (!canHarvest && f <= 1.0F)
    864                {
    865                    f += f1 * 0.08F;
    866                }
    867                else
    868                {
    869                    f += f1;
    870                }
    871            }
    872        }
    873
    874        if (this.isPotionActive(Potion.digSpeed))
    875        {
    876            f *= 1.0F + (float)(this.getActivePotionEffect(Potion.digSpeed).getAmplifier() + 1) * 0.2F;
    877        }
    878
    879        if (this.isPotionActive(Potion.digSlowdown))
    880        {
    881            f *= 1.0F - (float)(this.getActivePotionEffect(Potion.digSlowdown).getAmplifier() + 1) * 0.2F;
    882        }
    883
    884        if (this.isInsideOfMaterial(Material.water) && !EnchantmentHelper.getAquaAffinityModifier(this))
    885        {
    886            f /= 5.0F;
    887        }
    888
    889        if (!this.onGround)
    890        {
    891            f /= 5.0F;
    892        }
    893
    894        f = ForgeEventFactory.getBreakSpeed(this, par1Block, meta, f);
    895        return (f < 0 ? 0 : f);
    896    }
    897
    898    /**
    899     * Checks if the player has the ability to harvest a block (checks current inventory item for a tool if necessary)
    900     */
    901    public boolean canHarvestBlock(Block par1Block)
    902    {
    903        return ForgeEventFactory.doPlayerHarvestCheck(this, par1Block, inventory.canHarvestBlock(par1Block));
    904    }
    905
    906    /**
    907     * (abstract) Protected helper method to read subclass entity data from NBT.
    908     */
    909    public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
    910    {
    911        super.readEntityFromNBT(par1NBTTagCompound);
    912        NBTTagList nbttaglist = par1NBTTagCompound.getTagList("Inventory");
    913        this.inventory.readFromNBT(nbttaglist);
    914        this.inventory.currentItem = par1NBTTagCompound.getInteger("SelectedItemSlot");
    915        this.sleeping = par1NBTTagCompound.getBoolean("Sleeping");
    916        this.sleepTimer = par1NBTTagCompound.getShort("SleepTimer");
    917        this.experience = par1NBTTagCompound.getFloat("XpP");
    918        this.experienceLevel = par1NBTTagCompound.getInteger("XpLevel");
    919        this.experienceTotal = par1NBTTagCompound.getInteger("XpTotal");
    920        this.setScore(par1NBTTagCompound.getInteger("Score"));
    921
    922        int tmp = par1NBTTagCompound.getInteger("MaxHealth");
    923        maxHealth = (tmp <= 0 ? 20 : tmp);
    924
    925        if (this.sleeping)
    926        {
    927            this.playerLocation = new ChunkCoordinates(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ));
    928            this.wakeUpPlayer(true, true, false);
    929        }
    930
    931        if (par1NBTTagCompound.hasKey("SpawnX") && par1NBTTagCompound.hasKey("SpawnY") && par1NBTTagCompound.hasKey("SpawnZ"))
    932        {
    933            this.spawnChunk = new ChunkCoordinates(par1NBTTagCompound.getInteger("SpawnX"), par1NBTTagCompound.getInteger("SpawnY"), par1NBTTagCompound.getInteger("SpawnZ"));
    934            this.spawnForced = par1NBTTagCompound.getBoolean("SpawnForced");
    935        }
    936
    937        this.foodStats.readNBT(par1NBTTagCompound);
    938        this.capabilities.readCapabilitiesFromNBT(par1NBTTagCompound);
    939
    940        if (par1NBTTagCompound.hasKey("EnderItems"))
    941        {
    942            NBTTagList nbttaglist1 = par1NBTTagCompound.getTagList("EnderItems");
    943            this.theInventoryEnderChest.loadInventoryFromNBT(nbttaglist1);
    944        }
    945    }
    946
    947    /**
    948     * (abstract) Protected helper method to write subclass entity data to NBT.
    949     */
    950    public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
    951    {
    952        super.writeEntityToNBT(par1NBTTagCompound);
    953        par1NBTTagCompound.setTag("Inventory", this.inventory.writeToNBT(new NBTTagList()));
    954        par1NBTTagCompound.setInteger("SelectedItemSlot", this.inventory.currentItem);
    955        par1NBTTagCompound.setBoolean("Sleeping", this.sleeping);
    956        par1NBTTagCompound.setShort("SleepTimer", (short)this.sleepTimer);
    957        par1NBTTagCompound.setFloat("XpP", this.experience);
    958        par1NBTTagCompound.setInteger("XpLevel", this.experienceLevel);
    959        par1NBTTagCompound.setInteger("XpTotal", this.experienceTotal);
    960        par1NBTTagCompound.setInteger("Score", this.getScore());
    961        par1NBTTagCompound.setInteger("MaxHealth", maxHealth);
    962
    963        if (this.spawnChunk != null)
    964        {
    965            par1NBTTagCompound.setInteger("SpawnX", this.spawnChunk.posX);
    966            par1NBTTagCompound.setInteger("SpawnY", this.spawnChunk.posY);
    967            par1NBTTagCompound.setInteger("SpawnZ", this.spawnChunk.posZ);
    968            par1NBTTagCompound.setBoolean("SpawnForced", this.spawnForced);
    969        }
    970
    971        this.foodStats.writeNBT(par1NBTTagCompound);
    972        this.capabilities.writeCapabilitiesToNBT(par1NBTTagCompound);
    973        par1NBTTagCompound.setTag("EnderItems", this.theInventoryEnderChest.saveInventoryToNBT());
    974    }
    975
    976    /**
    977     * Displays the GUI for interacting with a chest inventory. Args: chestInventory
    978     */
    979    public void displayGUIChest(IInventory par1IInventory) {}
    980
    981    public void func_94064_a(TileEntityHopper par1TileEntityHopper) {}
    982
    983    public void func_96125_a(EntityMinecartHopper par1EntityMinecartHopper) {}
    984
    985    public void displayGUIEnchantment(int par1, int par2, int par3, String par4Str) {}
    986
    987    /**
    988     * Displays the GUI for interacting with an anvil.
    989     */
    990    public void displayGUIAnvil(int par1, int par2, int par3) {}
    991
    992    /**
    993     * Displays the crafting GUI for a workbench.
    994     */
    995    public void displayGUIWorkbench(int par1, int par2, int par3) {}
    996
    997    public float getEyeHeight()
    998    {
    999        return 0.12F;
    1000    }
    1001
    1002    /**
    1003     * sets the players height back to normal after doing things like sleeping and dieing
    1004     */
    1005    protected void resetHeight()
    1006    {
    1007        this.yOffset = 1.62F;
    1008    }
    1009
    1010    /**
    1011     * Called when the entity is attacked.
    1012     */
    1013    public boolean attackEntityFrom(DamageSource par1DamageSource, int par2)
    1014    {
    1015        if (this.isEntityInvulnerable())
    1016        {
    1017            return false;
    1018        }
    1019        else if (this.capabilities.disableDamage && !par1DamageSource.canHarmInCreative())
    1020        {
    1021            return false;
    1022        }
    1023        else
    1024        {
    1025            this.entityAge = 0;
    1026
    1027            if (this.getHealth() <= 0)
    1028            {
    1029                return false;
    1030            }
    1031            else
    1032            {
    1033                if (this.isPlayerSleeping() && !this.worldObj.isRemote)
    1034                {
    1035                    this.wakeUpPlayer(true, true, false);
    1036                }
    1037
    1038                if (par1DamageSource.isDifficultyScaled())
    1039                {
    1040                    if (this.worldObj.difficultySetting == 0)
    1041                    {
    1042                        par2 = 0;
    1043                    }
    1044
    1045                    if (this.worldObj.difficultySetting == 1)
    1046                    {
    1047                        par2 = par2 / 2 + 1;
    1048                    }
    1049
    1050                    if (this.worldObj.difficultySetting == 3)
    1051                    {
    1052                        par2 = par2 * 3 / 2;
    1053                    }
    1054                }
    1055
    1056                if (par2 == 0)
    1057                {
    1058                    return false;
    1059                }
    1060                else
    1061                {
    1062                    Entity entity = par1DamageSource.getEntity();
    1063
    1064                    if (entity instanceof EntityArrow && ((EntityArrow)entity).shootingEntity != null)
    1065                    {
    1066                        entity = ((EntityArrow)entity).shootingEntity;
    1067                    }
    1068
    1069                    if (entity instanceof EntityLiving)
    1070                    {
    1071                        this.alertWolves((EntityLiving)entity, false);
    1072                    }
    1073
    1074                    this.addStat(StatList.damageTakenStat, par2);
    1075                    return super.attackEntityFrom(par1DamageSource, par2);
    1076                }
    1077            }
    1078        }
    1079    }
    1080
    1081    public boolean func_96122_a(EntityPlayer par1EntityPlayer)
    1082    {
    1083        ScorePlayerTeam scoreplayerteam = this.func_96124_cp();
    1084        ScorePlayerTeam scoreplayerteam1 = par1EntityPlayer.func_96124_cp();
    1085        return scoreplayerteam != scoreplayerteam1 ? true : (scoreplayerteam != null ? scoreplayerteam.func_96665_g() : true);
    1086    }
    1087
    1088    /**
    1089     * Called when the player attack or gets attacked, it's alert all wolves in the area that are owned by the player to
    1090     * join the attack or defend the player.
    1091     */
    1092    protected void alertWolves(EntityLiving par1EntityLiving, boolean par2)
    1093    {
    1094        if (!(par1EntityLiving instanceof EntityCreeper) && !(par1EntityLiving instanceof EntityGhast))
    1095        {
    1096            if (par1EntityLiving instanceof EntityWolf)
    1097            {
    1098                EntityWolf entitywolf = (EntityWolf)par1EntityLiving;
    1099
    1100                if (entitywolf.isTamed() && this.username.equals(entitywolf.getOwnerName()))
    1101                {
    1102                    return;
    1103                }
    1104            }
    1105
    1106            if (!(par1EntityLiving instanceof EntityPlayer) || this.func_96122_a((EntityPlayer)par1EntityLiving))
    1107            {
    1108                List list = this.worldObj.getEntitiesWithinAABB(EntityWolf.class, AxisAlignedBB.getAABBPool().getAABB(this.posX, this.posY, this.posZ, this.posX + 1.0D, this.posY + 1.0D, this.posZ + 1.0D).expand(16.0D, 4.0D, 16.0D));
    1109                Iterator iterator = list.iterator();
    1110
    1111                while (iterator.hasNext())
    1112                {
    1113                    EntityWolf entitywolf1 = (EntityWolf)iterator.next();
    1114
    1115                    if (entitywolf1.isTamed() && entitywolf1.getEntityToAttack() == null && this.username.equals(entitywolf1.getOwnerName()) && (!par2 || !entitywolf1.isSitting()))
    1116                    {
    1117                        entitywolf1.setSitting(false);
    1118                        entitywolf1.setTarget(par1EntityLiving);
    1119                    }
    1120                }
    1121            }
    1122        }
    1123    }
    1124
    1125    protected void damageArmor(int par1)
    1126    {
    1127        this.inventory.damageArmor(par1);
    1128    }
    1129
    1130    /**
    1131     * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue
    1132     */
    1133    public int getTotalArmorValue()
    1134    {
    1135        return this.inventory.getTotalArmorValue();
    1136    }
    1137
    1138    public float func_82243_bO()
    1139    {
    1140        int i = 0;
    1141        ItemStack[] aitemstack = this.inventory.armorInventory;
    1142        int j = aitemstack.length;
    1143
    1144        for (int k = 0; k < j; ++k)
    1145        {
    1146            ItemStack itemstack = aitemstack[k];
    1147
    1148            if (itemstack != null)
    1149            {
    1150                ++i;
    1151            }
    1152        }
    1153
    1154        return (float)i / (float)this.inventory.armorInventory.length;
    1155    }
    1156
    1157    /**
    1158     * Deals damage to the entity. If its a EntityPlayer then will take damage from the armor first and then health
    1159     * second with the reduced value. Args: damageAmount
    1160     */
    1161    protected void damageEntity(DamageSource par1DamageSource, int par2)
    1162    {
    1163        if (!this.isEntityInvulnerable())
    1164        {
    1165            par2 = ForgeHooks.onLivingHurt(this, par1DamageSource, par2);
    1166            if (par2 <= 0)
    1167            {
    1168                return;
    1169            }
    1170
    1171            if (!par1DamageSource.isUnblockable() && this.isBlocking())
    1172            {
    1173                par2 = 1 + par2 >> 1;
    1174            }
    1175
    1176            par2 = ArmorProperties.ApplyArmor(this, inventory.armorInventory, par1DamageSource, par2);
    1177            if (par2 <= 0)
    1178            {
    1179                return;
    1180            }
    1181            par2 = this.applyPotionDamageCalculations(par1DamageSource, par2);
    1182            this.addExhaustion(par1DamageSource.getHungerDamage());
    1183            int j = this.getHealth();
    1184            this.setEntityHealth(this.getHealth() - par2);
    1185            this.field_94063_bt.func_94547_a(par1DamageSource, j, par2);
    1186        }
    1187    }
    1188
    1189    /**
    1190     * Displays the furnace GUI for the passed in furnace entity. Args: tileEntityFurnace
    1191     */
    1192    public void displayGUIFurnace(TileEntityFurnace par1TileEntityFurnace) {}
    1193
    1194    /**
    1195     * Displays the dipsenser GUI for the passed in dispenser entity. Args: TileEntityDispenser
    1196     */
    1197    public void displayGUIDispenser(TileEntityDispenser par1TileEntityDispenser) {}
    1198
    1199    /**
    1200     * Displays the GUI for editing a sign. Args: tileEntitySign
    1201     */
    1202    public void displayGUIEditSign(TileEntity par1TileEntity) {}
    1203
    1204    /**
    1205     * Displays the GUI for interacting with a brewing stand.
    1206     */
    1207    public void displayGUIBrewingStand(TileEntityBrewingStand par1TileEntityBrewingStand) {}
    1208
    1209    /**
    1210     * Displays the GUI for interacting with a beacon.
    1211     */
    1212    public void displayGUIBeacon(TileEntityBeacon par1TileEntityBeacon) {}
    1213
    1214    public void displayGUIMerchant(IMerchant par1IMerchant, String par2Str) {}
    1215
    1216    /**
    1217     * Displays the GUI for interacting with a book.
    1218     */
    1219    public void displayGUIBook(ItemStack par1ItemStack) {}
    1220
    1221    public boolean interactWith(Entity par1Entity)
    1222    {
    1223        if (MinecraftForge.EVENT_BUS.post(new EntityInteractEvent(this, par1Entity)))
    1224        {
    1225            return false;
    1226        }
    1227        if (par1Entity.interact(this))
    1228        {
    1229            return true;
    1230        }
    1231        else
    1232        {
    1233            ItemStack itemstack = this.getCurrentEquippedItem();
    1234
    1235            if (itemstack != null && par1Entity instanceof EntityLiving)
    1236            {
    1237                if (this.capabilities.isCreativeMode)
    1238                {
    1239                    itemstack = itemstack.copy();
    1240                }
    1241
    1242                if (itemstack.interactWith((EntityLiving)par1Entity))
    1243                {
    1244                    if (itemstack.stackSize <= 0 && !this.capabilities.isCreativeMode)
    1245                    {
    1246                        this.destroyCurrentEquippedItem();
    1247                    }
    1248
    1249                    return true;
    1250                }
    1251            }
    1252
    1253            return false;
    1254        }
    1255    }
    1256
    1257    /**
    1258     * Returns the currently being used item by the player.
    1259     */
    1260    public ItemStack getCurrentEquippedItem()
    1261    {
    1262        return this.inventory.getCurrentItem();
    1263    }
    1264
    1265    /**
    1266     * Destroys the currently equipped item from the player's inventory.
    1267     */
    1268    public void destroyCurrentEquippedItem()
    1269    {
    1270        ItemStack orig = getCurrentEquippedItem();
    1271        this.inventory.setInventorySlotContents(this.inventory.currentItem, (ItemStack)null);
    1272        MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(this, orig));
    1273    }
    1274
    1275    /**
    1276     * Returns the Y Offset of this entity.
    1277     */
    1278    public double getYOffset()
    1279    {
    1280        return (double)(this.yOffset - 0.5F);
    1281    }
    1282
    1283    /**
    1284     * Attacks for the player the targeted entity with the currently equipped item.  The equipped item has hitEntity
    1285     * called on it. Args: targetEntity
    1286     */
    1287    public void attackTargetEntityWithCurrentItem(Entity par1Entity)
    1288    {
    1289        if (MinecraftForge.EVENT_BUS.post(new AttackEntityEvent(this, par1Entity)))
    1290        {
    1291            return;
    1292        }
    1293        ItemStack stack = getCurrentEquippedItem();
    1294        if (stack != null && stack.getItem().onLeftClickEntity(stack, this, par1Entity))
    1295        {
    1296            return;
    1297        }
    1298        if (par1Entity.canAttackWithItem())
    1299        {
    1300            if (!par1Entity.func_85031_j(this))
    1301            {
    1302                int i = this.inventory.getDamageVsEntity(par1Entity);
    1303
    1304                if (this.isPotionActive(Potion.damageBoost))
    1305                {
    1306                    i += 3 << this.getActivePotionEffect(Potion.damageBoost).getAmplifier();
    1307                }
    1308
    1309                if (this.isPotionActive(Potion.weakness))
    1310                {
    1311                    i -= 2 << this.getActivePotionEffect(Potion.weakness).getAmplifier();
    1312                }
    1313
    1314                int j = 0;
    1315                int k = 0;
    1316
    1317                if (par1Entity instanceof EntityLiving)
    1318                {
    1319                    k = EnchantmentHelper.getEnchantmentModifierLiving(this, (EntityLiving)par1Entity);
    1320                    j += EnchantmentHelper.getKnockbackModifier(this, (EntityLiving)par1Entity);
    1321                }
    1322
    1323                if (this.isSprinting())
    1324                {
    1325                    ++j;
    1326                }
    1327
    1328                if (i > 0 || k > 0)
    1329                {
    1330                    boolean flag = this.fallDistance > 0.0F && !this.onGround && !this.isOnLadder() && !this.isInWater() && !this.isPotionActive(Potion.blindness) && this.ridingEntity == null && par1Entity instanceof EntityLiving;
    1331
    1332                    if (flag && i > 0)
    1333                    {
    1334                        i += this.rand.nextInt(i / 2 + 2);
    1335                    }
    1336
    1337                    i += k;
    1338                    boolean flag1 = false;
    1339                    int l = EnchantmentHelper.getFireAspectModifier(this);
    1340
    1341                    if (par1Entity instanceof EntityLiving && l > 0 && !par1Entity.isBurning())
    1342                    {
    1343                        flag1 = true;
    1344                        par1Entity.setFire(1);
    1345                    }
    1346
    1347                    boolean flag2 = par1Entity.attackEntityFrom(DamageSource.causePlayerDamage(this), i);
    1348
    1349                    if (flag2)
    1350                    {
    1351                        if (j > 0)
    1352                        {
    1353                            par1Entity.addVelocity((double)(-MathHelper.sin(this.rotationYaw * (float)Math.PI / 180.0F) * (float)j * 0.5F), 0.1D, (double)(MathHelper.cos(this.rotationYaw * (float)Math.PI / 180.0F) * (float)j * 0.5F));
    1354                            this.motionX *= 0.6D;
    1355                            this.motionZ *= 0.6D;
    1356                            this.setSprinting(false);
    1357                        }
    1358
    1359                        if (flag)
    1360                        {
    1361                            this.onCriticalHit(par1Entity);
    1362                        }
    1363
    1364                        if (k > 0)
    1365                        {
    1366                            this.onEnchantmentCritical(par1Entity);
    1367                        }
    1368
    1369                        if (i >= 18)
    1370                        {
    1371                            this.triggerAchievement(AchievementList.overkill);
    1372                        }
    1373
    1374                        this.setLastAttackingEntity(par1Entity);
    1375
    1376                        if (par1Entity instanceof EntityLiving)
    1377                        {
    1378                            EnchantmentThorns.func_92096_a(this, (EntityLiving)par1Entity, this.rand);
    1379                        }
    1380                    }
    1381
    1382                    ItemStack itemstack = this.getCurrentEquippedItem();
    1383                    Object object = par1Entity;
    1384
    1385                    if (par1Entity instanceof EntityDragonPart)
    1386                    {
    1387                        IEntityMultiPart ientitymultipart = ((EntityDragonPart)par1Entity).entityDragonObj;
    1388
    1389                        if (ientitymultipart != null && ientitymultipart instanceof EntityLiving)
    1390                        {
    1391                            object = (EntityLiving)ientitymultipart;
    1392                        }
    1393                    }
    1394
    1395                    if (itemstack != null && object instanceof EntityLiving)
    1396                    {
    1397                        itemstack.hitEntity((EntityLiving)object, this);
    1398
    1399                        if (itemstack.stackSize <= 0)
    1400                        {
    1401                            this.destroyCurrentEquippedItem();
    1402                        }
    1403                    }
    1404
    1405                    if (par1Entity instanceof EntityLiving)
    1406                    {
    1407                        if (par1Entity.isEntityAlive())
    1408                        {
    1409                            this.alertWolves((EntityLiving)par1Entity, true);
    1410                        }
    1411
    1412                        this.addStat(StatList.damageDealtStat, i);
    1413
    1414                        if (l > 0 && flag2)
    1415                        {
    1416                            par1Entity.setFire(l * 4);
    1417                        }
    1418                        else if (flag1)
    1419                        {
    1420                            par1Entity.extinguish();
    1421                        }
    1422                    }
    1423
    1424                    this.addExhaustion(0.3F);
    1425                }
    1426            }
    1427        }
    1428    }
    1429
    1430    /**
    1431     * Called when the player performs a critical hit on the Entity. Args: entity that was hit critically
    1432     */
    1433    public void onCriticalHit(Entity par1Entity) {}
    1434
    1435    public void onEnchantmentCritical(Entity par1Entity) {}
    1436
    1437    @SideOnly(Side.CLIENT)
    1438    public void respawnPlayer() {}
    1439
    1440    /**
    1441     * Will get destroyed next tick.
    1442     */
    1443    public void setDead()
    1444    {
    1445        super.setDead();
    1446        this.inventoryContainer.onCraftGuiClosed(this);
    1447
    1448        if (this.openContainer != null)
    1449        {
    1450            this.openContainer.onCraftGuiClosed(this);
    1451        }
    1452    }
    1453
    1454    /**
    1455     * Checks if this entity is inside of an opaque block
    1456     */
    1457    public boolean isEntityInsideOpaqueBlock()
    1458    {
    1459        return !this.sleeping && super.isEntityInsideOpaqueBlock();
    1460    }
    1461
    1462    public boolean func_71066_bF()
    1463    {
    1464        return false;
    1465    }
    1466
    1467    /**
    1468     * Attempts to have the player sleep in a bed at the specified location.
    1469     */
    1470    public EnumStatus sleepInBedAt(int par1, int par2, int par3)
    1471    {
    1472        PlayerSleepInBedEvent event = new PlayerSleepInBedEvent(this, par1, par2, par3);
    1473        MinecraftForge.EVENT_BUS.post(event);
    1474        if (event.result != null)
    1475        {
    1476            return event.result;
    1477        }
    1478        if (!this.worldObj.isRemote)
    1479        {
    1480            if (this.isPlayerSleeping() || !this.isEntityAlive())
    1481            {
    1482                return EnumStatus.OTHER_PROBLEM;
    1483            }
    1484
    1485            if (!this.worldObj.provider.isSurfaceWorld())
    1486            {
    1487                return EnumStatus.NOT_POSSIBLE_HERE;
    1488            }
    1489
    1490            if (this.worldObj.isDaytime())
    1491            {
    1492                return EnumStatus.NOT_POSSIBLE_NOW;
    1493            }
    1494
    1495            if (Math.abs(this.posX - (double)par1) > 3.0D || Math.abs(this.posY - (double)par2) > 2.0D || Math.abs(this.posZ - (double)par3) > 3.0D)
    1496            {
    1497                return EnumStatus.TOO_FAR_AWAY;
    1498            }
    1499
    1500            double d0 = 8.0D;
    1501            double d1 = 5.0D;
    1502            List list = this.worldObj.getEntitiesWithinAABB(EntityMob.class, AxisAlignedBB.getAABBPool().getAABB((double)par1 - d0, (double)par2 - d1, (double)par3 - d0, (double)par1 + d0, (double)par2 + d1, (double)par3 + d0));
    1503
    1504            if (!list.isEmpty())
    1505            {
    1506                return EnumStatus.NOT_SAFE;
    1507            }
    1508        }
    1509
    1510        this.setSize(0.2F, 0.2F);
    1511        this.yOffset = 0.2F;
    1512
    1513        if (this.worldObj.blockExists(par1, par2, par3))
    1514        {
    1515            int l = this.worldObj.getBlockMetadata(par1, par2, par3);
    1516            int i1 = BlockBed.getDirection(l);
    1517            Block block = Block.blocksList[worldObj.getBlockId(par1, par2, par3)];
    1518            if (block != null)
    1519            {
    1520                i1 = block.getBedDirection(worldObj, par1, par2, par3);
    1521            }
    1522            float f = 0.5F;
    1523            float f1 = 0.5F;
    1524
    1525            switch (i1)
    1526            {
    1527                case 0:
    1528                    f1 = 0.9F;
    1529                    break;
    1530                case 1:
    1531                    f = 0.1F;
    1532                    break;
    1533                case 2:
    1534                    f1 = 0.1F;
    1535                    break;
    1536                case 3:
    1537                    f = 0.9F;
    1538            }
    1539
    1540            this.func_71013_b(i1);
    1541            this.setPosition((double)((float)par1 + f), (double)((float)par2 + 0.9375F), (double)((float)par3 + f1));
    1542        }
    1543        else
    1544        {
    1545            this.setPosition((double)((float)par1 + 0.5F), (double)((float)par2 + 0.9375F), (double)((float)par3 + 0.5F));
    1546        }
    1547
    1548        this.sleeping = true;
    1549        this.sleepTimer = 0;
    1550        this.playerLocation = new ChunkCoordinates(par1, par2, par3);
    1551        this.motionX = this.motionZ = this.motionY = 0.0D;
    1552
    1553        if (!this.worldObj.isRemote)
    1554        {
    1555            this.worldObj.updateAllPlayersSleepingFlag();
    1556        }
    1557
    1558        return EnumStatus.OK;
    1559    }
    1560
    1561    private void func_71013_b(int par1)
    1562    {
    1563        this.field_71079_bU = 0.0F;
    1564        this.field_71089_bV = 0.0F;
    1565
    1566        switch (par1)
    1567        {
    1568            case 0:
    1569                this.field_71089_bV = -1.8F;
    1570                break;
    1571            case 1:
    1572                this.field_71079_bU = 1.8F;
    1573                break;
    1574            case 2:
    1575                this.field_71089_bV = 1.8F;
    1576                break;
    1577            case 3:
    1578                this.field_71079_bU = -1.8F;
    1579        }
    1580    }
    1581
    1582    /**
    1583     * Wake up the player if they're sleeping.
    1584     */
    1585    public void wakeUpPlayer(boolean par1, boolean par2, boolean par3)
    1586    {
    1587        this.setSize(0.6F, 1.8F);
    1588        this.resetHeight();
    1589        ChunkCoordinates chunkcoordinates = this.playerLocation;
    1590        ChunkCoordinates chunkcoordinates1 = this.playerLocation;
    1591
    1592        Block block = (chunkcoordinates == null ? null : Block.blocksList[worldObj.getBlockId(chunkcoordinates.posX, chunkcoordinates.posY, chunkcoordinates.posZ)]);
    1593
    1594        if (chunkcoordinates != null && block != null && block.isBed(worldObj, chunkcoordinates.posX, chunkcoordinates.posY, chunkcoordinates.posZ, this))
    1595        {
    1596            block.setBedOccupied(this.worldObj, chunkcoordinates.posX, chunkcoordinates.posY, chunkcoordinates.posZ, this, false);
    1597            chunkcoordinates1 = block.getBedSpawnPosition(worldObj, chunkcoordinates.posX, chunkcoordinates.posY, chunkcoordinates.posZ, this);
    1598
    1599            if (chunkcoordinates1 == null)
    1600            {
    1601                chunkcoordinates1 = new ChunkCoordinates(chunkcoordinates.posX, chunkcoordinates.posY + 1, chunkcoordinates.posZ);
    1602            }
    1603
    1604            this.setPosition((double)((float)chunkcoordinates1.posX + 0.5F), (double)((float)chunkcoordinates1.posY + this.yOffset + 0.1F), (double)((float)chunkcoordinates1.posZ + 0.5F));
    1605        }
    1606
    1607        this.sleeping = false;
    1608
    1609        if (!this.worldObj.isRemote && par2)
    1610        {
    1611            this.worldObj.updateAllPlayersSleepingFlag();
    1612        }
    1613
    1614        if (par1)
    1615        {
    1616            this.sleepTimer = 0;
    1617        }
    1618        else
    1619        {
    1620            this.sleepTimer = 100;
    1621        }
    1622
    1623        if (par3)
    1624        {
    1625            this.setSpawnChunk(this.playerLocation, false);
    1626        }
    1627    }
    1628
    1629    /**
    1630     * Checks if the player is currently in a bed
    1631     */
    1632    private boolean isInBed()
    1633    {
    1634        ChunkCoordinates c = playerLocation;
    1635        int blockID = worldObj.getBlockId(c.posX, c.posY, c.posZ);
    1636        return Block.blocksList[blockID] != null && Block.blocksList[blockID].isBed(worldObj, c.posX, c.posY, c.posZ, this);
    1637    }
    1638
    1639    /**
    1640     * Ensure that a block enabling respawning exists at the specified coordinates and find an empty space nearby to
    1641     * spawn.
    1642     */
    1643    public static ChunkCoordinates verifyRespawnCoordinates(World par0World, ChunkCoordinates par1ChunkCoordinates, boolean par2)
    1644    {
    1645        IChunkProvider ichunkprovider = par0World.getChunkProvider();
    1646        ichunkprovider.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ - 3 >> 4);
    1647        ichunkprovider.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ - 3 >> 4);
    1648        ichunkprovider.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4);
    1649        ichunkprovider.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4);
    1650
    1651        ChunkCoordinates c = par1ChunkCoordinates;
    1652        Block block = Block.blocksList[par0World.getBlockId(c.posX, c.posY, c.posZ)];
    1653
    1654        if (block != null && block.isBed(par0World, c.posX, c.posY, c.posZ, null))
    1655        {
    1656            ChunkCoordinates chunkcoordinates1 = block.getBedSpawnPosition(par0World, c.posX, c.posY, c.posZ, null);
    1657            return chunkcoordinates1;
    1658        }
    1659        else
    1660        {
    1661            Material material = par0World.getBlockMaterial(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY, par1ChunkCoordinates.posZ);
    1662            Material material1 = par0World.getBlockMaterial(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY + 1, par1ChunkCoordinates.posZ);
    1663            boolean flag1 = !material.isSolid() && !material.isLiquid();
    1664            boolean flag2 = !material1.isSolid() && !material1.isLiquid();
    1665            return par2 && flag1 && flag2 ? par1ChunkCoordinates : null;
    1666        }
    1667    }
    1668
    1669    @SideOnly(Side.CLIENT)
    1670
    1671    /**
    1672     * Returns the orientation of the bed in degrees.
    1673     */
    1674    public float getBedOrientationInDegrees()
    1675    {
    1676        if (this.playerLocation != null)
    1677        {
    1678            int x = playerLocation.posX;
    1679            int y = playerLocation.posY;
    1680            int z = playerLocation.posZ;
    1681            Block block = Block.blocksList[worldObj.getBlockId(x, y, z)];
    1682            int i = (block == null ? 0 : block.getBedDirection(worldObj, x, y, z));
    1683
    1684            switch (i)
    1685            {
    1686                case 0:
    1687                    return 90.0F;
    1688                case 1:
    1689                    return 0.0F;
    1690                case 2:
    1691                    return 270.0F;
    1692                case 3:
    1693                    return 180.0F;
    1694            }
    1695        }
    1696
    1697        return 0.0F;
    1698    }
    1699
    1700    /**
    1701     * Returns whether player is sleeping or not
    1702     */
    1703    public boolean isPlayerSleeping()
    1704    {
    1705        return this.sleeping;
    1706    }
    1707
    1708    /**
    1709     * Returns whether or not the player is asleep and the screen has fully faded.
    1710     */
    1711    public boolean isPlayerFullyAsleep()
    1712    {
    1713        return this.sleeping && this.sleepTimer >= 100;
    1714    }
    1715
    1716    @SideOnly(Side.CLIENT)
    1717    public int getSleepTimer()
    1718    {
    1719        return this.sleepTimer;
    1720    }
    1721
    1722    @SideOnly(Side.CLIENT)
    1723    protected boolean getHideCape(int par1)
    1724    {
    1725        return (this.dataWatcher.getWatchableObjectByte(16) & 1 << par1) != 0;
    1726    }
    1727
    1728    protected void setHideCape(int par1, boolean par2)
    1729    {
    1730        byte b0 = this.dataWatcher.getWatchableObjectByte(16);
    1731
    1732        if (par2)
    1733        {
    1734            this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 | 1 << par1)));
    1735        }
    1736        else
    1737        {
    1738            this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 & ~(1 << par1))));
    1739        }
    1740    }
    1741
    1742    /**
    1743     * Add a chat message to the player
    1744     */
    1745    public void addChatMessage(String par1Str) {}
    1746
    1747    /**
    1748     * Returns the location of the bed the player will respawn at, or null if the player has not slept in a bed.
    1749     */
    1750    public ChunkCoordinates getBedLocation()
    1751    {
    1752        return this.spawnChunk;
    1753    }
    1754
    1755    public boolean isSpawnForced()
    1756    {
    1757        return this.spawnForced;
    1758    }
    1759
    1760    /**
    1761     * Defines a spawn coordinate to player spawn. Used by bed after the player sleep on it.
    1762     */
    1763    public void setSpawnChunk(ChunkCoordinates par1ChunkCoordinates, boolean par2)
    1764    {
    1765        if (par1ChunkCoordinates != null)
    1766        {
    1767            this.spawnChunk = new ChunkCoordinates(par1ChunkCoordinates);
    1768            this.spawnForced = par2;
    1769        }
    1770        else
    1771        {
    1772            this.spawnChunk = null;
    1773            this.spawnForced = false;
    1774        }
    1775    }
    1776
    1777    /**
    1778     * Will trigger the specified trigger.
    1779     */
    1780    public void triggerAchievement(StatBase par1StatBase)
    1781    {
    1782        this.addStat(par1StatBase, 1);
    1783    }
    1784
    1785    /**
    1786     * Adds a value to a statistic field.
    1787     */
    1788    public void addStat(StatBase par1StatBase, int par2) {}
    1789
    1790    /**
    1791     * Causes this entity to do an upwards motion (jumping).
    1792     */
    1793    protected void jump()
    1794    {
    1795        super.jump();
    1796        this.addStat(StatList.jumpStat, 1);
    1797
    1798        if (this.isSprinting())
    1799        {
    1800            this.addExhaustion(0.8F);
    1801        }
    1802        else
    1803        {
    1804            this.addExhaustion(0.2F);
    1805        }
    1806    }
    1807
    1808    /**
    1809     * Moves the entity based on the specified heading.  Args: strafe, forward
    1810     */
    1811    public void moveEntityWithHeading(float par1, float par2)
    1812    {
    1813        double d0 = this.posX;
    1814        double d1 = this.posY;
    1815        double d2 = this.posZ;
    1816
    1817        if (this.capabilities.isFlying && this.ridingEntity == null)
    1818        {
    1819            double d3 = this.motionY;
    1820            float f2 = this.jumpMovementFactor;
    1821            this.jumpMovementFactor = this.capabilities.getFlySpeed();
    1822            super.moveEntityWithHeading(par1, par2);
    1823            this.motionY = d3 * 0.6D;
    1824            this.jumpMovementFactor = f2;
    1825        }
    1826        else
    1827        {
    1828            super.moveEntityWithHeading(par1, par2);
    1829        }
    1830
    1831        this.addMovementStat(this.posX - d0, this.posY - d1, this.posZ - d2);
    1832    }
    1833
    1834    /**
    1835     * Adds a value to a movement statistic field - like run, walk, swin or climb.
    1836     */
    1837    public void addMovementStat(double par1, double par3, double par5)
    1838    {
    1839        if (this.ridingEntity == null)
    1840        {
    1841            int i;
    1842
    1843            if (this.isInsideOfMaterial(Material.water))
    1844            {
    1845                i = Math.round(MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5) * 100.0F);
    1846
    1847                if (i > 0)
    1848                {
    1849                    this.addStat(StatList.distanceDoveStat, i);
    1850                    this.addExhaustion(0.015F * (float)i * 0.01F);
    1851                }
    1852            }
    1853            else if (this.isInWater())
    1854            {
    1855                i = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F);
    1856
    1857                if (i > 0)
    1858                {
    1859                    this.addStat(StatList.distanceSwumStat, i);
    1860                    this.addExhaustion(0.015F * (float)i * 0.01F);
    1861                }
    1862            }
    1863            else if (this.isOnLadder())
    1864            {
    1865                if (par3 > 0.0D)
    1866                {
    1867                    this.addStat(StatList.distanceClimbedStat, (int)Math.round(par3 * 100.0D));
    1868                }
    1869            }
    1870            else if (this.onGround)
    1871            {
    1872                i = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F);
    1873
    1874                if (i > 0)
    1875                {
    1876                    this.addStat(StatList.distanceWalkedStat, i);
    1877
    1878                    if (this.isSprinting())
    1879                    {
    1880                        this.addExhaustion(0.099999994F * (float)i * 0.01F);
    1881                    }
    1882                    else
    1883                    {
    1884                        this.addExhaustion(0.01F * (float)i * 0.01F);
    1885                    }
    1886                }
    1887            }
    1888            else
    1889            {
    1890                i = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F);
    1891
    1892                if (i > 25)
    1893                {
    1894                    this.addStat(StatList.distanceFlownStat, i);
    1895                }
    1896            }
    1897        }
    1898    }
    1899
    1900    /**
    1901     * Adds a value to a mounted movement statistic field - by minecart, boat, or pig.
    1902     */
    1903    private void addMountedMovementStat(double par1, double par3, double par5)
    1904    {
    1905        if (this.ridingEntity != null)
    1906        {
    1907            int i = Math.round(MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5) * 100.0F);
    1908
    1909            if (i > 0)
    1910            {
    1911                if (this.ridingEntity instanceof EntityMinecart)
    1912                {
    1913                    this.addStat(StatList.distanceByMinecartStat, i);
    1914
    1915                    if (this.startMinecartRidingCoordinate == null)
    1916                    {
    1917                        this.startMinecartRidingCoordinate = new ChunkCoordinates(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ));
    1918                    }
    1919                    else if ((double)this.startMinecartRidingCoordinate.getDistanceSquared(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) >= 1000000.0D)
    1920                    {
    1921                        this.addStat(AchievementList.onARail, 1);
    1922                    }
    1923                }
    1924                else if (this.ridingEntity instanceof EntityBoat)
    1925                {
    1926                    this.addStat(StatList.distanceByBoatStat, i);
    1927                }
    1928                else if (this.ridingEntity instanceof EntityPig)
    1929                {
    1930                    this.addStat(StatList.distanceByPigStat, i);
    1931                }
    1932            }
    1933        }
    1934    }
    1935
    1936    /**
    1937     * Called when the mob is falling. Calculates and applies fall damage.
    1938     */
    1939    protected void fall(float par1)
    1940    {
    1941        if (!this.capabilities.allowFlying)
    1942        {
    1943            if (par1 >= 2.0F)
    1944            {
    1945                this.addStat(StatList.distanceFallenStat, (int)Math.round((double)par1 * 100.0D));
    1946            }
    1947
    1948            super.fall(par1);
    1949        }
    1950        else
    1951        {
    1952            MinecraftForge.EVENT_BUS.post(new PlayerFlyableFallEvent(this, par1));
    1953        }
    1954    }
    1955
    1956    /**
    1957     * This method gets called when the entity kills another one.
    1958     */
    1959    public void onKillEntity(EntityLiving par1EntityLiving)
    1960    {
    1961        if (par1EntityLiving instanceof IMob)
    1962        {
    1963            this.triggerAchievement(AchievementList.killEnemy);
    1964        }
    1965    }
    1966
    1967    /**
    1968     * Sets the Entity inside a web block.
    1969     */
    1970    public void setInWeb()
    1971    {
    1972        if (!this.capabilities.isFlying)
    1973        {
    1974            super.setInWeb();
    1975        }
    1976    }
    1977
    1978    @SideOnly(Side.CLIENT)
    1979
    1980    /**
    1981     * Gets the Icon Index of the item currently held
    1982     */
    1983    public Icon getItemIcon(ItemStack par1ItemStack, int par2)
    1984    {
    1985        Icon icon = super.getItemIcon(par1ItemStack, par2);
    1986
    1987        if (par1ItemStack.itemID == Item.fishingRod.itemID && this.fishEntity != null)
    1988        {
    1989            icon = Item.fishingRod.func_94597_g();
    1990        }
    1991        else
    1992        {
    1993            if (par1ItemStack.getItem().requiresMultipleRenderPasses())
    1994            {
    1995                return par1ItemStack.getItem().getIcon(par1ItemStack, par2);
    1996            }
    1997
    1998            if (this.itemInUse != null && par1ItemStack.itemID == Item.bow.itemID)
    1999            {
    2000                int j = par1ItemStack.getMaxItemUseDuration() - this.itemInUseCount;
    2001
    2002                if (j >= 18)
    2003                {
    2004                    return Item.bow.func_94599_c(2);
    2005                }
    2006
    2007                if (j > 13)
    2008                {
    2009                    return Item.bow.func_94599_c(1);
    2010                }
    2011
    2012                if (j > 0)
    2013                {
    2014                    return Item.bow.func_94599_c(0);
    2015                }
    2016            }
    2017            icon = par1ItemStack.getItem().getIcon(par1ItemStack, par2, this, itemInUse, itemInUseCount);
    2018        }
    2019
    2020        return icon;
    2021    }
    2022
    2023    public ItemStack getCurrentArmor(int par1)
    2024    {
    2025        return this.inventory.armorItemInSlot(par1);
    2026    }
    2027
    2028    /**
    2029     * Makes entity wear random armor based on difficulty
    2030     */
    2031    protected void addRandomArmor() {}
    2032
    2033    protected void func_82162_bC() {}
    2034
    2035    /**
    2036     * This method increases the player's current amount of experience.
    2037     */
    2038    public void addExperience(int par1)
    2039    {
    2040        this.addScore(par1);
    2041        int j = Integer.MAX_VALUE - this.experienceTotal;
    2042
    2043        if (par1 > j)
    2044        {
    2045            par1 = j;
    2046        }
    2047
    2048        this.experience += (float)par1 / (float)this.xpBarCap();
    2049
    2050        for (this.experienceTotal += par1; this.experience >= 1.0F; this.experience /= (float)this.xpBarCap())
    2051        {
    2052            this.experience = (this.experience - 1.0F) * (float)this.xpBarCap();
    2053            this.addExperienceLevel(1);
    2054        }
    2055    }
    2056
    2057    /**
    2058     * Add experience levels to this player.
    2059     */
    2060    public void addExperienceLevel(int par1)
    2061    {
    2062        this.experienceLevel += par1;
    2063
    2064        if (this.experienceLevel < 0)
    2065        {
    2066            this.experienceLevel = 0;
    2067            this.experience = 0.0F;
    2068            this.experienceTotal = 0;
    2069        }
    2070
    2071        if (par1 > 0 && this.experienceLevel % 5 == 0 && (float)this.field_82249_h < (float)this.ticksExisted - 100.0F)
    2072        {
    2073            float f = this.experienceLevel > 30 ? 1.0F : (float)this.experienceLevel / 30.0F;
    2074            this.worldObj.playSoundAtEntity(this, "random.levelup", f * 0.75F, 1.0F);
    2075            this.field_82249_h = this.ticksExisted;
    2076        }
    2077    }
    2078
    2079    /**
    2080     * This method returns the cap amount of experience that the experience bar can hold. With each level, the
    2081     * experience cap on the player's experience bar is raised by 10.
    2082     */
    2083    public int xpBarCap()
    2084    {
    2085        return this.experienceLevel >= 30 ? 62 + (this.experienceLevel - 30) * 7 : (this.experienceLevel >= 15 ? 17 + (this.experienceLevel - 15) * 3 : 17);
    2086    }
    2087
    2088    /**
    2089     * increases exhaustion level by supplied amount
    2090     */
    2091    public void addExhaustion(float par1)
    2092    {
    2093        if (!this.capabilities.disableDamage)
    2094        {
    2095            if (!this.worldObj.isRemote)
    2096            {
    2097                this.foodStats.addExhaustion(par1);
    2098            }
    2099        }
    2100    }
    2101
    2102    /**
    2103     * Returns the player's FoodStats object.
    2104     */
    2105    public FoodStats getFoodStats()
    2106    {
    2107        return this.foodStats;
    2108    }
    2109
    2110    public boolean canEat(boolean par1)
    2111    {
    2112        return (par1 || this.foodStats.needFood()) && !this.capabilities.disableDamage;
    2113    }
    2114
    2115    /**
    2116     * Checks if the player's health is not full and not zero.
    2117     */
    2118    public boolean shouldHeal()
    2119    {
    2120        return this.getHealth() > 0 && this.getHealth() < this.getMaxHealth();
    2121    }
    2122
    2123    /**
    2124     * sets the itemInUse when the use item button is clicked. Args: itemstack, int maxItemUseDuration
    2125     */
    2126    public void setItemInUse(ItemStack par1ItemStack, int par2)
    2127    {
    2128        if (par1ItemStack != this.itemInUse)
    2129        {
    2130            this.itemInUse = par1ItemStack;
    2131            this.itemInUseCount = par2;
    2132
    2133            if (!this.worldObj.isRemote)
    2134            {
    2135                this.setEating(true);
    2136            }
    2137        }
    2138    }
    2139
    2140    /**
    2141     * Returns true if the item the player is holding can harvest the block at the given coords. Args: x, y, z.
    2142     */
    2143    public boolean canCurrentToolHarvestBlock(int par1, int par2, int par3)
    2144    {
    2145        if (this.capabilities.allowEdit)
    2146        {
    2147            return true;
    2148        }
    2149        else
    2150        {
    2151            int l = this.worldObj.getBlockId(par1, par2, par3);
    2152
    2153            if (l > 0)
    2154            {
    2155                Block block = Block.blocksList[l];
    2156
    2157                if (block.blockMaterial.isAlwaysHarvested())
    2158                {
    2159                    return true;
    2160                }
    2161
    2162                if (this.getCurrentEquippedItem() != null)
    2163                {
    2164                    ItemStack itemstack = this.getCurrentEquippedItem();
    2165
    2166                    if (itemstack.canHarvestBlock(block) || itemstack.getStrVsBlock(block) > 1.0F)
    2167                    {
    2168                        return true;
    2169                    }
    2170                }
    2171            }
    2172
    2173            return false;
    2174        }
    2175    }
    2176
    2177    public boolean canPlayerEdit(int par1, int par2, int par3, int par4, ItemStack par5ItemStack)
    2178    {
    2179        return this.capabilities.allowEdit ? true : (par5ItemStack != null ? par5ItemStack.func_82835_x() : false);
    2180    }
    2181
    2182    /**
    2183     * Get the experience points the entity currently has.
    2184     */
    2185    protected int getExperiencePoints(EntityPlayer par1EntityPlayer)
    2186    {
    2187        if (this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory"))
    2188        {
    2189            return 0;
    2190        }
    2191        else
    2192        {
    2193            int i = this.experienceLevel * 7;
    2194            return i > 100 ? 100 : i;
    2195        }
    2196    }
    2197
    2198    /**
    2199     * Only use is to identify if class is an instance of player for experience dropping
    2200     */
    2201    protected boolean isPlayer()
    2202    {
    2203        return true;
    2204    }
    2205
    2206    /**
    2207     * Gets the username of the entity.
    2208     */
    2209    public String getEntityName()
    2210    {
    2211        return this.username;
    2212    }
    2213
    2214    public boolean func_94062_bN()
    2215    {
    2216        return super.func_94062_bN();
    2217    }
    2218
    2219    @SideOnly(Side.CLIENT)
    2220    public boolean func_94059_bO()
    2221    {
    2222        return true;
    2223    }
    2224
    2225    public boolean canPickUpLoot()
    2226    {
    2227        return false;
    2228    }
    2229
    2230    /**
    2231     * Copies the values from the given player into this player if boolean par2 is true. Always clones Ender Chest
    2232     * Inventory.
    2233     */
    2234    public void clonePlayer(EntityPlayer par1EntityPlayer, boolean par2)
    2235    {
    2236        if (par2)
    2237        {
    2238            this.inventory.copyInventory(par1EntityPlayer.inventory);
    2239            this.health = par1EntityPlayer.health;
    2240            this.foodStats = par1EntityPlayer.foodStats;
    2241            this.experienceLevel = par1EntityPlayer.experienceLevel;
    2242            this.experienceTotal = par1EntityPlayer.experienceTotal;
    2243            this.experience = par1EntityPlayer.experience;
    2244            this.setScore(par1EntityPlayer.getScore());
    2245            this.teleportDirection = par1EntityPlayer.teleportDirection;
    2246        }
    2247        else if (this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory"))
    2248        {
    2249            this.inventory.copyInventory(par1EntityPlayer.inventory);
    2250            this.experienceLevel = par1EntityPlayer.experienceLevel;
    2251            this.experienceTotal = par1EntityPlayer.experienceTotal;
    2252            this.experience = par1EntityPlayer.experience;
    2253            this.setScore(par1EntityPlayer.getScore());
    2254        }
    2255
    2256        this.theInventoryEnderChest = par1EntityPlayer.theInventoryEnderChest;
    2257
    2258        //Copy over a section of the Entity Data from the old player.
    2259        //Allows mods to specify data that persists after players respawn.
    2260        NBTTagCompound old = par1EntityPlayer.getEntityData();
    2261        if (old.hasKey(PERSISTED_NBT_TAG))
    2262        {
    2263            getEntityData().setCompoundTag(PERSISTED_NBT_TAG, old.getCompoundTag(PERSISTED_NBT_TAG));
    2264        }
    2265    }
    2266
    2267    /**
    2268     * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
    2269     * prevent them from trampling crops
    2270     */
    2271    protected boolean canTriggerWalking()
    2272    {
    2273        return !this.capabilities.isFlying;
    2274    }
    2275
    2276    /**
    2277     * Sends the player's abilities to the server (if there is one).
    2278     */
    2279    public void sendPlayerAbilities() {}
    2280
    2281    /**
    2282     * Sets the player's game mode and sends it to them.
    2283     */
    2284    public void setGameType(EnumGameType par1EnumGameType) {}
    2285
    2286    /**
    2287     * Gets the name of this command sender (usually username, but possibly "Rcon")
    2288     */
    2289    public String getCommandSenderName()
    2290    {
    2291        return this.username;
    2292    }
    2293
    2294    public StringTranslate getTranslator()
    2295    {
    2296        return StringTranslate.getInstance();
    2297    }
    2298
    2299    /**
    2300     * Translates and formats the given string key with the given arguments.
    2301     */
    2302    public String translateString(String par1Str, Object ... par2ArrayOfObj)
    2303    {
    2304        return this.getTranslator().translateKeyFormat(par1Str, par2ArrayOfObj);
    2305    }
    2306
    2307    /**
    2308     * Returns the InventoryEnderChest of this player.
    2309     */
    2310    public InventoryEnderChest getInventoryEnderChest()
    2311    {
    2312        return this.theInventoryEnderChest;
    2313    }
    2314
    2315    /**
    2316     * 0 = item, 1-n is armor
    2317     */
    2318    public ItemStack getCurrentItemOrArmor(int par1)
    2319    {
    2320        return par1 == 0 ? this.inventory.getCurrentItem() : this.inventory.armorInventory[par1 - 1];
    2321    }
    2322
    2323    /**
    2324     * Returns the item that this EntityLiving is holding, if any.
    2325     */
    2326    public ItemStack getHeldItem()
    2327    {
    2328        return this.inventory.getCurrentItem();
    2329    }
    2330
    2331    /**
    2332     * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. Params: Item, slot
    2333     */
    2334    public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack)
    2335    {
    2336        if (par1 == 0)
    2337        {
    2338            this.inventory.mainInventory[this.inventory.currentItem] = par2ItemStack;
    2339        }
    2340        else
    2341        {
    2342            this.inventory.armorInventory[par1 - 1] = par2ItemStack;
    2343        }
    2344    }
    2345
    2346    @SideOnly(Side.CLIENT)
    2347    public boolean func_98034_c(EntityPlayer par1EntityPlayer)
    2348    {
    2349        if (!this.getHasActivePotion())
    2350        {
    2351            return false;
    2352        }
    2353        else
    2354        {
    2355            ScorePlayerTeam scoreplayerteam = this.func_96124_cp();
    2356            return scoreplayerteam == null || par1EntityPlayer == null || par1EntityPlayer.func_96124_cp() != scoreplayerteam || !scoreplayerteam.func_98297_h();
    2357        }
    2358    }
    2359
    2360    public ItemStack[] getLastActiveItems()
    2361    {
    2362        return this.inventory.armorInventory;
    2363    }
    2364
    2365    @SideOnly(Side.CLIENT)
    2366    public boolean getHideCape()
    2367    {
    2368        return this.getHideCape(1);
    2369    }
    2370
    2371    public boolean func_96092_aw()
    2372    {
    2373        return !this.capabilities.isFlying;
    2374    }
    2375
    2376    public Scoreboard func_96123_co()
    2377    {
    2378        return this.worldObj.getScoreboard();
    2379    }
    2380
    2381    public ScorePlayerTeam func_96124_cp()
    2382    {
    2383        return this.func_96123_co().func_96509_i(this.username);
    2384    }
    2385
    2386    public String func_96090_ax()
    2387    {
    2388        return ScorePlayerTeam.func_96667_a(this.func_96124_cp(), this.username);
    2389    }
    2390
    2391    public void openGui(Object mod, int modGuiId, World world, int x, int y, int z)
    2392    {
    2393        FMLNetworkHandler.openGui(this, mod, modGuiId, world, x, y, z);
    2394    }
    2395}