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