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