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