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