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 EntityLiving && ((EntityLiving)ridingEntity).shouldRiderFaceForward(this))
464            {
465                this.rotationPitch = var8;
466                this.rotationYaw = var7;
467                this.renderYawOffset = ((EntityLiving)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                    for (int var4 = 0; var4 < var3.size(); ++var4)
547                    {
548                        Entity var5 = (Entity)var3.get(var4);
549    
550                        if (!var5.isDead)
551                        {
552                            this.collideWithPlayer(var5);
553                        }
554                    }
555                }
556            }
557        }
558    
559        private void collideWithPlayer(Entity par1Entity)
560        {
561            par1Entity.onCollideWithPlayer(this);
562        }
563    
564        public int getScore()
565        {
566            return this.dataWatcher.getWatchableObjectInt(18);
567        }
568    
569        public void func_85040_s(int par1)
570        {
571            this.dataWatcher.updateObject(18, Integer.valueOf(par1));
572        }
573    
574        public void func_85039_t(int par1)
575        {
576            int var2 = this.getScore();
577            this.dataWatcher.updateObject(18, Integer.valueOf(var2 + par1));
578        }
579    
580        /**
581         * Called when the mob's health reaches 0.
582         */
583        public void onDeath(DamageSource par1DamageSource)
584        {
585            super.onDeath(par1DamageSource);
586            this.setSize(0.2F, 0.2F);
587            this.setPosition(this.posX, this.posY, this.posZ);
588            this.motionY = 0.10000000149011612D;
589    
590            captureDrops = true;
591            capturedDrops.clear();
592    
593            if (this.username.equals("Notch"))
594            {
595                this.dropPlayerItemWithRandomChoice(new ItemStack(Item.appleRed, 1), true);
596            }
597    
598            if (!this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory"))
599            {
600                this.inventory.dropAllItems();
601            }
602    
603            captureDrops = false;
604    
605            if (!worldObj.isRemote)
606            {
607                PlayerDropsEvent event = new PlayerDropsEvent(this, par1DamageSource, capturedDrops, recentlyHit > 0);
608                if (!MinecraftForge.EVENT_BUS.post(event))
609                {
610                    for (EntityItem item : capturedDrops)
611                    {
612                        joinEntityItemWithWorld(item);
613                    }
614                }
615            }
616    
617            if (par1DamageSource != null)
618            {
619                this.motionX = (double)(-MathHelper.cos((this.attackedAtYaw + this.rotationYaw) * (float)Math.PI / 180.0F) * 0.1F);
620                this.motionZ = (double)(-MathHelper.sin((this.attackedAtYaw + this.rotationYaw) * (float)Math.PI / 180.0F) * 0.1F);
621            }
622            else
623            {
624                this.motionX = this.motionZ = 0.0D;
625            }
626    
627            this.yOffset = 0.1F;
628            this.addStat(StatList.deathsStat, 1);
629        }
630    
631        /**
632         * Adds a value to the player score. Currently not actually used and the entity passed in does nothing. Args:
633         * entity, scoreToAdd
634         */
635        public void addToPlayerScore(Entity par1Entity, int par2)
636        {
637            this.func_85039_t(par2);
638    
639            if (par1Entity instanceof EntityPlayer)
640            {
641                this.addStat(StatList.playerKillsStat, 1);
642            }
643            else
644            {
645                this.addStat(StatList.mobKillsStat, 1);
646            }
647        }
648    
649        /**
650         * Called when player presses the drop item key
651         */
652        public EntityItem dropOneItem()
653        {
654            ItemStack stack = inventory.getCurrentItem();
655            if (stack == null)
656            {
657                return null;
658            }
659            if (stack.getItem().onDroppedByPlayer(stack, this))
660            {
661                return ForgeHooks.onPlayerTossEvent(this, inventory.decrStackSize(inventory.currentItem, 1));
662            }
663            return null;
664        }
665    
666        /**
667         * Args: itemstack - called when player drops an item stack that's not in his inventory (like items still placed in
668         * a workbench while the workbench'es GUI gets closed)
669         */
670        public EntityItem dropPlayerItem(ItemStack par1ItemStack)
671        {
672            return ForgeHooks.onPlayerTossEvent(this, par1ItemStack);
673        }
674    
675        /**
676         * Args: itemstack, flag
677         */
678        public EntityItem dropPlayerItemWithRandomChoice(ItemStack par1ItemStack, boolean par2)
679        {
680            if (par1ItemStack == null)
681            {
682                return null;
683            }
684            else
685            {
686                EntityItem var3 = new EntityItem(this.worldObj, this.posX, this.posY - 0.30000001192092896D + (double)this.getEyeHeight(), this.posZ, par1ItemStack);
687                var3.delayBeforeCanPickup = 40;
688                float var4 = 0.1F;
689                float var5;
690    
691                if (par2)
692                {
693                    var5 = this.rand.nextFloat() * 0.5F;
694                    float var6 = this.rand.nextFloat() * (float)Math.PI * 2.0F;
695                    var3.motionX = (double)(-MathHelper.sin(var6) * var5);
696                    var3.motionZ = (double)(MathHelper.cos(var6) * var5);
697                    var3.motionY = 0.20000000298023224D;
698                }
699                else
700                {
701                    var4 = 0.3F;
702                    var3.motionX = (double)(-MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI) * var4);
703                    var3.motionZ = (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI) * var4);
704                    var3.motionY = (double)(-MathHelper.sin(this.rotationPitch / 180.0F * (float)Math.PI) * var4 + 0.1F);
705                    var4 = 0.02F;
706                    var5 = this.rand.nextFloat() * (float)Math.PI * 2.0F;
707                    var4 *= this.rand.nextFloat();
708                    var3.motionX += Math.cos((double)var5) * (double)var4;
709                    var3.motionY += (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1F);
710                    var3.motionZ += Math.sin((double)var5) * (double)var4;
711                }
712    
713                this.joinEntityItemWithWorld(var3);
714                this.addStat(StatList.dropStat, 1);
715                return var3;
716            }
717        }
718    
719        /**
720         * Joins the passed in entity item with the world. Args: entityItem
721         */
722        public void joinEntityItemWithWorld(EntityItem par1EntityItem)
723        {
724            if (captureDrops)
725            {
726                capturedDrops.add(par1EntityItem);
727            }
728            else
729            {
730                this.worldObj.spawnEntityInWorld(par1EntityItem);
731            }
732        }
733    
734        /**
735         * Returns how strong the player is against the specified block at this moment
736         * Deprecated in favor of the more sensitive version
737         */
738        @Deprecated
739        public float getCurrentPlayerStrVsBlock(Block par1Block)
740        {
741            return getCurrentPlayerStrVsBlock(par1Block, 0);
742        }
743    
744        public float getCurrentPlayerStrVsBlock(Block par1Block, int meta)
745        {
746            ItemStack stack = inventory.getCurrentItem();
747            float var2 = (stack == null ? 1.0F : stack.getItem().getStrVsBlock(stack, par1Block, meta));
748            int var3 = EnchantmentHelper.getEfficiencyModifier(this);
749    
750            if (var3 > 0 && ForgeHooks.canHarvestBlock(par1Block, this, meta))
751            {
752                var2 += (float)(var3 * var3 + 1);
753            }
754    
755            if (this.isPotionActive(Potion.digSpeed))
756            {
757                var2 *= 1.0F + (float)(this.getActivePotionEffect(Potion.digSpeed).getAmplifier() + 1) * 0.2F;
758            }
759    
760            if (this.isPotionActive(Potion.digSlowdown))
761            {
762                var2 *= 1.0F - (float)(this.getActivePotionEffect(Potion.digSlowdown).getAmplifier() + 1) * 0.2F;
763            }
764    
765            if (this.isInsideOfMaterial(Material.water) && !EnchantmentHelper.getAquaAffinityModifier(this))
766            {
767                var2 /= 5.0F;
768            }
769    
770            if (!this.onGround)
771            {
772                var2 /= 5.0F;
773            }
774    
775            var2 = ForgeEventFactory.getBreakSpeed(this, par1Block, meta, var2);
776            return (var2 < 0 ? 0 : var2);
777        }
778    
779        /**
780         * Checks if the player has the ability to harvest a block (checks current inventory item for a tool if necessary)
781         */
782        public boolean canHarvestBlock(Block par1Block)
783        {
784            return ForgeEventFactory.doPlayerHarvestCheck(this, par1Block, inventory.canHarvestBlock(par1Block));
785        }
786    
787        /**
788         * (abstract) Protected helper method to read subclass entity data from NBT.
789         */
790        public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
791        {
792            super.readEntityFromNBT(par1NBTTagCompound);
793            NBTTagList var2 = par1NBTTagCompound.getTagList("Inventory");
794            this.inventory.readFromNBT(var2);
795            this.sleeping = par1NBTTagCompound.getBoolean("Sleeping");
796            this.sleepTimer = par1NBTTagCompound.getShort("SleepTimer");
797            this.experience = par1NBTTagCompound.getFloat("XpP");
798            this.experienceLevel = par1NBTTagCompound.getInteger("XpLevel");
799            this.experienceTotal = par1NBTTagCompound.getInteger("XpTotal");
800            this.func_85040_s(par1NBTTagCompound.getInteger("Score"));
801    
802            if (this.sleeping)
803            {
804                this.playerLocation = new ChunkCoordinates(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ));
805                this.wakeUpPlayer(true, true, false);
806            }
807    
808            if (par1NBTTagCompound.hasKey("SpawnX") && par1NBTTagCompound.hasKey("SpawnY") && par1NBTTagCompound.hasKey("SpawnZ"))
809            {
810                this.spawnChunk = new ChunkCoordinates(par1NBTTagCompound.getInteger("SpawnX"), par1NBTTagCompound.getInteger("SpawnY"), par1NBTTagCompound.getInteger("SpawnZ"));
811                this.spawnForced = par1NBTTagCompound.getBoolean("SpawnForced");
812            }
813    
814            this.foodStats.readNBT(par1NBTTagCompound);
815            this.capabilities.readCapabilitiesFromNBT(par1NBTTagCompound);
816    
817            if (par1NBTTagCompound.hasKey("EnderItems"))
818            {
819                NBTTagList var3 = par1NBTTagCompound.getTagList("EnderItems");
820                this.theInventoryEnderChest.loadInventoryFromNBT(var3);
821            }
822        }
823    
824        /**
825         * (abstract) Protected helper method to write subclass entity data to NBT.
826         */
827        public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
828        {
829            super.writeEntityToNBT(par1NBTTagCompound);
830            par1NBTTagCompound.setTag("Inventory", this.inventory.writeToNBT(new NBTTagList()));
831            par1NBTTagCompound.setBoolean("Sleeping", this.sleeping);
832            par1NBTTagCompound.setShort("SleepTimer", (short)this.sleepTimer);
833            par1NBTTagCompound.setFloat("XpP", this.experience);
834            par1NBTTagCompound.setInteger("XpLevel", this.experienceLevel);
835            par1NBTTagCompound.setInteger("XpTotal", this.experienceTotal);
836            par1NBTTagCompound.setInteger("Score", this.getScore());
837    
838            if (this.spawnChunk != null)
839            {
840                par1NBTTagCompound.setInteger("SpawnX", this.spawnChunk.posX);
841                par1NBTTagCompound.setInteger("SpawnY", this.spawnChunk.posY);
842                par1NBTTagCompound.setInteger("SpawnZ", this.spawnChunk.posZ);
843                par1NBTTagCompound.setBoolean("SpawnForced", this.spawnForced);
844            }
845    
846            this.foodStats.writeNBT(par1NBTTagCompound);
847            this.capabilities.writeCapabilitiesToNBT(par1NBTTagCompound);
848            par1NBTTagCompound.setTag("EnderItems", this.theInventoryEnderChest.saveInventoryToNBT());
849        }
850    
851        /**
852         * Displays the GUI for interacting with a chest inventory. Args: chestInventory
853         */
854        public void displayGUIChest(IInventory par1IInventory) {}
855    
856        public void displayGUIEnchantment(int par1, int par2, int par3) {}
857    
858        /**
859         * Displays the GUI for interacting with an anvil.
860         */
861        public void displayGUIAnvil(int par1, int par2, int par3) {}
862    
863        /**
864         * Displays the crafting GUI for a workbench.
865         */
866        public void displayGUIWorkbench(int par1, int par2, int par3) {}
867    
868        public float getEyeHeight()
869        {
870            return 0.12F;
871        }
872    
873        /**
874         * sets the players height back to normal after doing things like sleeping and dieing
875         */
876        protected void resetHeight()
877        {
878            this.yOffset = 1.62F;
879        }
880    
881        /**
882         * Called when the entity is attacked.
883         */
884        public boolean attackEntityFrom(DamageSource par1DamageSource, int par2)
885        {
886            if (this.func_85032_ar())
887            {
888                return false;
889            }
890            else if (this.capabilities.disableDamage && !par1DamageSource.canHarmInCreative())
891            {
892                return false;
893            }
894            else
895            {
896                this.entityAge = 0;
897    
898                if (this.getHealth() <= 0)
899                {
900                    return false;
901                }
902                else
903                {
904                    if (this.isPlayerSleeping() && !this.worldObj.isRemote)
905                    {
906                        this.wakeUpPlayer(true, true, false);
907                    }
908    
909                    if (par1DamageSource.func_76350_n())
910                    {
911                        if (this.worldObj.difficultySetting == 0)
912                        {
913                            par2 = 0;
914                        }
915    
916                        if (this.worldObj.difficultySetting == 1)
917                        {
918                            par2 = par2 / 2 + 1;
919                        }
920    
921                        if (this.worldObj.difficultySetting == 3)
922                        {
923                            par2 = par2 * 3 / 2;
924                        }
925                    }
926    
927                    if (par2 == 0)
928                    {
929                        return false;
930                    }
931                    else
932                    {
933                        Entity var3 = par1DamageSource.getEntity();
934    
935                        if (var3 instanceof EntityArrow && ((EntityArrow)var3).shootingEntity != null)
936                        {
937                            var3 = ((EntityArrow)var3).shootingEntity;
938                        }
939    
940                        if (var3 instanceof EntityLiving)
941                        {
942                            this.alertWolves((EntityLiving)var3, false);
943                        }
944    
945                        this.addStat(StatList.damageTakenStat, par2);
946                        return super.attackEntityFrom(par1DamageSource, par2);
947                    }
948                }
949            }
950        }
951    
952        /**
953         * Reduces damage, depending on potions
954         */
955        protected int applyPotionDamageCalculations(DamageSource par1DamageSource, int par2)
956        {
957            int var3 = super.applyPotionDamageCalculations(par1DamageSource, par2);
958    
959            if (var3 <= 0)
960            {
961                return 0;
962            }
963            else
964            {
965                int var4 = EnchantmentHelper.getEnchantmentModifierDamage(this.inventory.armorInventory, par1DamageSource);
966    
967                if (var4 > 20)
968                {
969                    var4 = 20;
970                }
971    
972                if (var4 > 0 && var4 <= 20)
973                {
974                    int var5 = 25 - var4;
975                    int var6 = var3 * var5 + this.carryoverDamage;
976                    var3 = var6 / 25;
977                    this.carryoverDamage = var6 % 25;
978                }
979    
980                return var3;
981            }
982        }
983    
984        /**
985         * returns if pvp is enabled or not
986         */
987        protected boolean isPVPEnabled()
988        {
989            return false;
990        }
991    
992        /**
993         * Called when the player attack or gets attacked, it's alert all wolves in the area that are owned by the player to
994         * join the attack or defend the player.
995         */
996        protected void alertWolves(EntityLiving par1EntityLiving, boolean par2)
997        {
998            if (!(par1EntityLiving instanceof EntityCreeper) && !(par1EntityLiving instanceof EntityGhast))
999            {
1000                if (par1EntityLiving instanceof EntityWolf)
1001                {
1002                    EntityWolf var3 = (EntityWolf)par1EntityLiving;
1003    
1004                    if (var3.isTamed() && this.username.equals(var3.getOwnerName()))
1005                    {
1006                        return;
1007                    }
1008                }
1009    
1010                if (!(par1EntityLiving instanceof EntityPlayer) || this.isPVPEnabled())
1011                {
1012                    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));
1013                    Iterator var4 = var6.iterator();
1014    
1015                    while (var4.hasNext())
1016                    {
1017                        EntityWolf var5 = (EntityWolf)var4.next();
1018    
1019                        if (var5.isTamed() && var5.getEntityToAttack() == null && this.username.equals(var5.getOwnerName()) && (!par2 || !var5.isSitting()))
1020                        {
1021                            var5.setSitting(false);
1022                            var5.setTarget(par1EntityLiving);
1023                        }
1024                    }
1025                }
1026            }
1027        }
1028    
1029        protected void damageArmor(int par1)
1030        {
1031            this.inventory.damageArmor(par1);
1032        }
1033    
1034        /**
1035         * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue
1036         */
1037        public int getTotalArmorValue()
1038        {
1039            return this.inventory.getTotalArmorValue();
1040        }
1041    
1042        public float func_82243_bO()
1043        {
1044            int var1 = 0;
1045            ItemStack[] var2 = this.inventory.armorInventory;
1046            int var3 = var2.length;
1047    
1048            for (int var4 = 0; var4 < var3; ++var4)
1049            {
1050                ItemStack var5 = var2[var4];
1051    
1052                if (var5 != null)
1053                {
1054                    ++var1;
1055                }
1056            }
1057    
1058            return (float)var1 / (float)this.inventory.armorInventory.length;
1059        }
1060    
1061        /**
1062         * Deals damage to the entity. If its a EntityPlayer then will take damage from the armor first and then health
1063         * second with the reduced value. Args: damageAmount
1064         */
1065        protected void damageEntity(DamageSource par1DamageSource, int par2)
1066        {
1067            if (!this.func_85032_ar())
1068            {
1069                par2 = ForgeHooks.onLivingHurt(this, par1DamageSource, par2);
1070                if (par2 <= 0)
1071                {
1072                    return;
1073                }
1074    
1075                if (!par1DamageSource.isUnblockable() && this.isBlocking())
1076                {
1077                    par2 = 1 + par2 >> 1;
1078                }
1079    
1080                par2 = ArmorProperties.ApplyArmor(this, inventory.armorInventory, par1DamageSource, par2);
1081                if (par2 <= 0)
1082                {
1083                    return;
1084                }
1085                par2 = this.applyPotionDamageCalculations(par1DamageSource, par2);
1086                this.addExhaustion(par1DamageSource.getHungerDamage());
1087                this.health -= par2;
1088            }
1089        }
1090    
1091        /**
1092         * Displays the furnace GUI for the passed in furnace entity. Args: tileEntityFurnace
1093         */
1094        public void displayGUIFurnace(TileEntityFurnace par1TileEntityFurnace) {}
1095    
1096        /**
1097         * Displays the dipsenser GUI for the passed in dispenser entity. Args: TileEntityDispenser
1098         */
1099        public void displayGUIDispenser(TileEntityDispenser par1TileEntityDispenser) {}
1100    
1101        /**
1102         * Displays the GUI for editing a sign. Args: tileEntitySign
1103         */
1104        public void displayGUIEditSign(TileEntity par1TileEntity) {}
1105    
1106        /**
1107         * Displays the GUI for interacting with a brewing stand.
1108         */
1109        public void displayGUIBrewingStand(TileEntityBrewingStand par1TileEntityBrewingStand) {}
1110    
1111        /**
1112         * Displays the GUI for interacting with a beacon.
1113         */
1114        public void displayGUIBeacon(TileEntityBeacon par1TileEntityBeacon) {}
1115    
1116        public void displayGUIMerchant(IMerchant par1IMerchant) {}
1117    
1118        /**
1119         * Displays the GUI for interacting with a book.
1120         */
1121        public void displayGUIBook(ItemStack par1ItemStack) {}
1122    
1123        public boolean interactWith(Entity par1Entity)
1124        {
1125            if (MinecraftForge.EVENT_BUS.post(new EntityInteractEvent(this, par1Entity)))
1126            {
1127                return false;
1128            }
1129            if (par1Entity.interact(this))
1130            {
1131                return true;
1132            }
1133            else
1134            {
1135                ItemStack var2 = this.getCurrentEquippedItem();
1136    
1137                if (var2 != null && par1Entity instanceof EntityLiving)
1138                {
1139                    if (this.capabilities.isCreativeMode)
1140                    {
1141                        var2 = var2.copy();
1142                    }
1143    
1144                    if (var2.interactWith((EntityLiving)par1Entity))
1145                    {
1146                        if (var2.stackSize <= 0 && !this.capabilities.isCreativeMode)
1147                        {
1148                            this.destroyCurrentEquippedItem();
1149                        }
1150    
1151                        return true;
1152                    }
1153                }
1154    
1155                return false;
1156            }
1157        }
1158    
1159        /**
1160         * Returns the currently being used item by the player.
1161         */
1162        public ItemStack getCurrentEquippedItem()
1163        {
1164            return this.inventory.getCurrentItem();
1165        }
1166    
1167        /**
1168         * Destroys the currently equipped item from the player's inventory.
1169         */
1170        public void destroyCurrentEquippedItem()
1171        {
1172            ItemStack orig = getCurrentEquippedItem();
1173            this.inventory.setInventorySlotContents(this.inventory.currentItem, (ItemStack)null);
1174            MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(this, orig));
1175        }
1176    
1177        /**
1178         * Returns the Y Offset of this entity.
1179         */
1180        public double getYOffset()
1181        {
1182            return (double)(this.yOffset - 0.5F);
1183        }
1184    
1185        /**
1186         * Attacks for the player the targeted entity with the currently equipped item.  The equipped item has hitEntity
1187         * called on it. Args: targetEntity
1188         */
1189        public void attackTargetEntityWithCurrentItem(Entity par1Entity)
1190        {
1191            if (MinecraftForge.EVENT_BUS.post(new AttackEntityEvent(this, par1Entity)))
1192            {
1193                return;
1194            }
1195            ItemStack stack = getCurrentEquippedItem();
1196            if (stack != null && stack.getItem().onLeftClickEntity(stack, this, par1Entity))
1197            {
1198                return;
1199            }
1200            if (par1Entity.canAttackWithItem())
1201            {
1202                if (!par1Entity.func_85031_j(this))
1203                {
1204                    int var2 = this.inventory.getDamageVsEntity(par1Entity);
1205    
1206                    if (this.isPotionActive(Potion.damageBoost))
1207                    {
1208                        var2 += 3 << this.getActivePotionEffect(Potion.damageBoost).getAmplifier();
1209                    }
1210    
1211                    if (this.isPotionActive(Potion.weakness))
1212                    {
1213                        var2 -= 2 << this.getActivePotionEffect(Potion.weakness).getAmplifier();
1214                    }
1215    
1216                    int var3 = 0;
1217                    int var4 = 0;
1218    
1219                    if (par1Entity instanceof EntityLiving)
1220                    {
1221                        var4 = EnchantmentHelper.getEnchantmentModifierLiving(this, (EntityLiving)par1Entity);
1222                        var3 += EnchantmentHelper.getKnockbackModifier(this, (EntityLiving)par1Entity);
1223                    }
1224    
1225                    if (this.isSprinting())
1226                    {
1227                        ++var3;
1228                    }
1229    
1230                    if (var2 > 0 || var4 > 0)
1231                    {
1232                        boolean var5 = this.fallDistance > 0.0F && !this.onGround && !this.isOnLadder() && !this.isInWater() && !this.isPotionActive(Potion.blindness) && this.ridingEntity == null && par1Entity instanceof EntityLiving;
1233    
1234                        if (var5)
1235                        {
1236                            var2 += this.rand.nextInt(var2 / 2 + 2);
1237                        }
1238    
1239                        var2 += var4;
1240                        boolean var6 = false;
1241                        int var7 = EnchantmentHelper.func_90036_a(this);
1242    
1243                        if (par1Entity instanceof EntityLiving && var7 > 0 && !par1Entity.isBurning())
1244                        {
1245                            var6 = true;
1246                            par1Entity.setFire(1);
1247                        }
1248    
1249                        boolean var8 = par1Entity.attackEntityFrom(DamageSource.causePlayerDamage(this), var2);
1250    
1251                        if (var8)
1252                        {
1253                            if (var3 > 0)
1254                            {
1255                                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));
1256                                this.motionX *= 0.6D;
1257                                this.motionZ *= 0.6D;
1258                                this.setSprinting(false);
1259                            }
1260    
1261                            if (var5)
1262                            {
1263                                this.onCriticalHit(par1Entity);
1264                            }
1265    
1266                            if (var4 > 0)
1267                            {
1268                                this.onEnchantmentCritical(par1Entity);
1269                            }
1270    
1271                            if (var2 >= 18)
1272                            {
1273                                this.triggerAchievement(AchievementList.overkill);
1274                            }
1275    
1276                            this.setLastAttackingEntity(par1Entity);
1277                        }
1278    
1279                        ItemStack var9 = this.getCurrentEquippedItem();
1280    
1281                        if (var9 != null && par1Entity instanceof EntityLiving)
1282                        {
1283                            var9.hitEntity((EntityLiving)par1Entity, this);
1284    
1285                            if (var9.stackSize <= 0)
1286                            {
1287                                this.destroyCurrentEquippedItem();
1288                            }
1289                        }
1290    
1291                        if (par1Entity instanceof EntityLiving)
1292                        {
1293                            if (par1Entity.isEntityAlive())
1294                            {
1295                                this.alertWolves((EntityLiving)par1Entity, true);
1296                            }
1297    
1298                            this.addStat(StatList.damageDealtStat, var2);
1299    
1300                            if (var7 > 0 && var8)
1301                            {
1302                                par1Entity.setFire(var7 * 4);
1303                            }
1304                            else if (var6)
1305                            {
1306                                par1Entity.extinguish();
1307                            }
1308                        }
1309    
1310                        this.addExhaustion(0.3F);
1311                    }
1312                }
1313            }
1314        }
1315    
1316        /**
1317         * Called when the player performs a critical hit on the Entity. Args: entity that was hit critically
1318         */
1319        public void onCriticalHit(Entity par1Entity) {}
1320    
1321        public void onEnchantmentCritical(Entity par1Entity) {}
1322    
1323        @SideOnly(Side.CLIENT)
1324        public void respawnPlayer() {}
1325    
1326        /**
1327         * Will get destroyed next tick.
1328         */
1329        public void setDead()
1330        {
1331            super.setDead();
1332            this.inventorySlots.onCraftGuiClosed(this);
1333    
1334            if (this.craftingInventory != null)
1335            {
1336                this.craftingInventory.onCraftGuiClosed(this);
1337            }
1338        }
1339    
1340        /**
1341         * Checks if this entity is inside of an opaque block
1342         */
1343        public boolean isEntityInsideOpaqueBlock()
1344        {
1345            return !this.sleeping && super.isEntityInsideOpaqueBlock();
1346        }
1347    
1348        public boolean func_71066_bF()
1349        {
1350            return false;
1351        }
1352    
1353        /**
1354         * Attempts to have the player sleep in a bed at the specified location.
1355         */
1356        public EnumStatus sleepInBedAt(int par1, int par2, int par3)
1357        {
1358            PlayerSleepInBedEvent event = new PlayerSleepInBedEvent(this, par1, par2, par3);
1359            MinecraftForge.EVENT_BUS.post(event);
1360            if (event.result != null)
1361            {
1362                return event.result;
1363            }
1364            if (!this.worldObj.isRemote)
1365            {
1366                if (this.isPlayerSleeping() || !this.isEntityAlive())
1367                {
1368                    return EnumStatus.OTHER_PROBLEM;
1369                }
1370    
1371                if (!this.worldObj.provider.isSurfaceWorld())
1372                {
1373                    return EnumStatus.NOT_POSSIBLE_HERE;
1374                }
1375    
1376                if (this.worldObj.isDaytime())
1377                {
1378                    return EnumStatus.NOT_POSSIBLE_NOW;
1379                }
1380    
1381                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)
1382                {
1383                    return EnumStatus.TOO_FAR_AWAY;
1384                }
1385    
1386                double var4 = 8.0D;
1387                double var6 = 5.0D;
1388                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));
1389    
1390                if (!var8.isEmpty())
1391                {
1392                    return EnumStatus.NOT_SAFE;
1393                }
1394            }
1395    
1396            this.setSize(0.2F, 0.2F);
1397            this.yOffset = 0.2F;
1398    
1399            if (this.worldObj.blockExists(par1, par2, par3))
1400            {
1401                int var9 = this.worldObj.getBlockMetadata(par1, par2, par3);
1402                int var5 = BlockBed.getDirection(var9);
1403                Block block = Block.blocksList[worldObj.getBlockId(par1, par2, par3)];
1404                if (block != null)
1405                {
1406                    var5 = block.getBedDirection(worldObj, par1, par2, par3);
1407                }
1408                float var10 = 0.5F;
1409                float var7 = 0.5F;
1410    
1411                switch (var5)
1412                {
1413                    case 0:
1414                        var7 = 0.9F;
1415                        break;
1416                    case 1:
1417                        var10 = 0.1F;
1418                        break;
1419                    case 2:
1420                        var7 = 0.1F;
1421                        break;
1422                    case 3:
1423                        var10 = 0.9F;
1424                }
1425    
1426                this.func_71013_b(var5);
1427                this.setPosition((double)((float)par1 + var10), (double)((float)par2 + 0.9375F), (double)((float)par3 + var7));
1428            }
1429            else
1430            {
1431                this.setPosition((double)((float)par1 + 0.5F), (double)((float)par2 + 0.9375F), (double)((float)par3 + 0.5F));
1432            }
1433    
1434            this.sleeping = true;
1435            this.sleepTimer = 0;
1436            this.playerLocation = new ChunkCoordinates(par1, par2, par3);
1437            this.motionX = this.motionZ = this.motionY = 0.0D;
1438    
1439            if (!this.worldObj.isRemote)
1440            {
1441                this.worldObj.updateAllPlayersSleepingFlag();
1442            }
1443    
1444            return EnumStatus.OK;
1445        }
1446    
1447        private void func_71013_b(int par1)
1448        {
1449            this.field_71079_bU = 0.0F;
1450            this.field_71089_bV = 0.0F;
1451    
1452            switch (par1)
1453            {
1454                case 0:
1455                    this.field_71089_bV = -1.8F;
1456                    break;
1457                case 1:
1458                    this.field_71079_bU = 1.8F;
1459                    break;
1460                case 2:
1461                    this.field_71089_bV = 1.8F;
1462                    break;
1463                case 3:
1464                    this.field_71079_bU = -1.8F;
1465            }
1466        }
1467    
1468        /**
1469         * Wake up the player if they're sleeping.
1470         */
1471        public void wakeUpPlayer(boolean par1, boolean par2, boolean par3)
1472        {
1473            this.setSize(0.6F, 1.8F);
1474            this.resetHeight();
1475            ChunkCoordinates var4 = this.playerLocation;
1476            ChunkCoordinates var5 = this.playerLocation;
1477    
1478            Block block = (var4 == null ? null : Block.blocksList[worldObj.getBlockId(var4.posX, var4.posY, var4.posZ)]);
1479    
1480            if (var4 != null && block != null && block.isBed(worldObj, var4.posX, var4.posY, var4.posZ, this))
1481            {
1482                block.setBedOccupied(this.worldObj, var4.posX, var4.posY, var4.posZ, this, false);
1483                var5 = block.getBedSpawnPosition(worldObj, var4.posX, var4.posY, var4.posZ, this);
1484    
1485                if (var5 == null)
1486                {
1487                    var5 = new ChunkCoordinates(var4.posX, var4.posY + 1, var4.posZ);
1488                }
1489    
1490                this.setPosition((double)((float)var5.posX + 0.5F), (double)((float)var5.posY + this.yOffset + 0.1F), (double)((float)var5.posZ + 0.5F));
1491            }
1492    
1493            this.sleeping = false;
1494    
1495            if (!this.worldObj.isRemote && par2)
1496            {
1497                this.worldObj.updateAllPlayersSleepingFlag();
1498            }
1499    
1500            if (par1)
1501            {
1502                this.sleepTimer = 0;
1503            }
1504            else
1505            {
1506                this.sleepTimer = 100;
1507            }
1508    
1509            if (par3)
1510            {
1511                this.setSpawnChunk(this.playerLocation, false);
1512            }
1513        }
1514    
1515        /**
1516         * Checks if the player is currently in a bed
1517         */
1518        private boolean isInBed()
1519        {
1520            ChunkCoordinates c = playerLocation;
1521            int blockID = worldObj.getBlockId(c.posX, c.posY, c.posZ);
1522            return Block.blocksList[blockID] != null && Block.blocksList[blockID].isBed(worldObj, c.posX, c.posY, c.posZ, this);
1523        }
1524    
1525        /**
1526         * Ensure that a block enabling respawning exists at the specified coordinates and find an empty space nearby to
1527         * spawn.
1528         */
1529        public static ChunkCoordinates verifyRespawnCoordinates(World par0World, ChunkCoordinates par1ChunkCoordinates, boolean par2)
1530        {
1531            IChunkProvider var3 = par0World.getChunkProvider();
1532            var3.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ - 3 >> 4);
1533            var3.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ - 3 >> 4);
1534            var3.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4);
1535            var3.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4);
1536    
1537            ChunkCoordinates c = par1ChunkCoordinates;
1538            Block block = Block.blocksList[par0World.getBlockId(c.posX, c.posY, c.posZ)];
1539    
1540            if (block == null || !block.isBed(par0World, c.posX, c.posY, c.posZ, null))
1541            {
1542                ChunkCoordinates var8 = block.getBedSpawnPosition(par0World, c.posX, c.posY, c.posZ, null);
1543                return var8;
1544            }
1545            else
1546            {
1547                Material var4 = par0World.getBlockMaterial(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY, par1ChunkCoordinates.posZ);
1548                Material var5 = par0World.getBlockMaterial(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY + 1, par1ChunkCoordinates.posZ);
1549                boolean var6 = !var4.isSolid() && !var4.isLiquid();
1550                boolean var7 = !var5.isSolid() && !var5.isLiquid();
1551                return par2 && var6 && var7 ? par1ChunkCoordinates : null;
1552            }
1553        }
1554    
1555        @SideOnly(Side.CLIENT)
1556    
1557        /**
1558         * Returns the orientation of the bed in degrees.
1559         */
1560        public float getBedOrientationInDegrees()
1561        {
1562            if (this.playerLocation != null)
1563            {
1564                int x = playerLocation.posX;
1565                int y = playerLocation.posY;
1566                int z = playerLocation.posZ;
1567                Block block = Block.blocksList[worldObj.getBlockId(x, y, z)];
1568                int var2 = (block == null ? 0 : block.getBedDirection(worldObj, x, y, z));
1569    
1570                switch (var2)
1571                {
1572                    case 0:
1573                        return 90.0F;
1574                    case 1:
1575                        return 0.0F;
1576                    case 2:
1577                        return 270.0F;
1578                    case 3:
1579                        return 180.0F;
1580                }
1581            }
1582    
1583            return 0.0F;
1584        }
1585    
1586        /**
1587         * Returns whether player is sleeping or not
1588         */
1589        public boolean isPlayerSleeping()
1590        {
1591            return this.sleeping;
1592        }
1593    
1594        /**
1595         * Returns whether or not the player is asleep and the screen has fully faded.
1596         */
1597        public boolean isPlayerFullyAsleep()
1598        {
1599            return this.sleeping && this.sleepTimer >= 100;
1600        }
1601    
1602        @SideOnly(Side.CLIENT)
1603        public int getSleepTimer()
1604        {
1605            return this.sleepTimer;
1606        }
1607    
1608        @SideOnly(Side.CLIENT)
1609        protected boolean func_82241_s(int par1)
1610        {
1611            return (this.dataWatcher.getWatchableObjectByte(16) & 1 << par1) != 0;
1612        }
1613    
1614        protected void func_82239_b(int par1, boolean par2)
1615        {
1616            byte var3 = this.dataWatcher.getWatchableObjectByte(16);
1617    
1618            if (par2)
1619            {
1620                this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var3 | 1 << par1)));
1621            }
1622            else
1623            {
1624                this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var3 & ~(1 << par1))));
1625            }
1626        }
1627    
1628        /**
1629         * Add a chat message to the player
1630         */
1631        public void addChatMessage(String par1Str) {}
1632    
1633        /**
1634         * Returns the coordinates to respawn the player based on last bed that the player sleep.
1635         */
1636        public ChunkCoordinates getSpawnChunk()
1637        {
1638            return this.spawnChunk;
1639        }
1640    
1641        public boolean func_82245_bX()
1642        {
1643            return this.spawnForced;
1644        }
1645    
1646        /**
1647         * Defines a spawn coordinate to player spawn. Used by bed after the player sleep on it.
1648         */
1649        public void setSpawnChunk(ChunkCoordinates par1ChunkCoordinates, boolean par2)
1650        {
1651            if (par1ChunkCoordinates != null)
1652            {
1653                this.spawnChunk = new ChunkCoordinates(par1ChunkCoordinates);
1654                this.spawnForced = par2;
1655            }
1656            else
1657            {
1658                this.spawnChunk = null;
1659                this.spawnForced = false;
1660            }
1661        }
1662    
1663        /**
1664         * Will trigger the specified trigger.
1665         */
1666        public void triggerAchievement(StatBase par1StatBase)
1667        {
1668            this.addStat(par1StatBase, 1);
1669        }
1670    
1671        /**
1672         * Adds a value to a statistic field.
1673         */
1674        public void addStat(StatBase par1StatBase, int par2) {}
1675    
1676        /**
1677         * Causes this entity to do an upwards motion (jumping).
1678         */
1679        protected void jump()
1680        {
1681            super.jump();
1682            this.addStat(StatList.jumpStat, 1);
1683    
1684            if (this.isSprinting())
1685            {
1686                this.addExhaustion(0.8F);
1687            }
1688            else
1689            {
1690                this.addExhaustion(0.2F);
1691            }
1692        }
1693    
1694        /**
1695         * Moves the entity based on the specified heading.  Args: strafe, forward
1696         */
1697        public void moveEntityWithHeading(float par1, float par2)
1698        {
1699            double var3 = this.posX;
1700            double var5 = this.posY;
1701            double var7 = this.posZ;
1702    
1703            if (this.capabilities.isFlying && this.ridingEntity == null)
1704            {
1705                double var9 = this.motionY;
1706                float var11 = this.jumpMovementFactor;
1707                this.jumpMovementFactor = this.capabilities.getFlySpeed();
1708                super.moveEntityWithHeading(par1, par2);
1709                this.motionY = var9 * 0.6D;
1710                this.jumpMovementFactor = var11;
1711            }
1712            else
1713            {
1714                super.moveEntityWithHeading(par1, par2);
1715            }
1716    
1717            this.addMovementStat(this.posX - var3, this.posY - var5, this.posZ - var7);
1718        }
1719    
1720        /**
1721         * Adds a value to a movement statistic field - like run, walk, swin or climb.
1722         */
1723        public void addMovementStat(double par1, double par3, double par5)
1724        {
1725            if (this.ridingEntity == null)
1726            {
1727                int var7;
1728    
1729                if (this.isInsideOfMaterial(Material.water))
1730                {
1731                    var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5) * 100.0F);
1732    
1733                    if (var7 > 0)
1734                    {
1735                        this.addStat(StatList.distanceDoveStat, var7);
1736                        this.addExhaustion(0.015F * (float)var7 * 0.01F);
1737                    }
1738                }
1739                else if (this.isInWater())
1740                {
1741                    var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F);
1742    
1743                    if (var7 > 0)
1744                    {
1745                        this.addStat(StatList.distanceSwumStat, var7);
1746                        this.addExhaustion(0.015F * (float)var7 * 0.01F);
1747                    }
1748                }
1749                else if (this.isOnLadder())
1750                {
1751                    if (par3 > 0.0D)
1752                    {
1753                        this.addStat(StatList.distanceClimbedStat, (int)Math.round(par3 * 100.0D));
1754                    }
1755                }
1756                else if (this.onGround)
1757                {
1758                    var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F);
1759    
1760                    if (var7 > 0)
1761                    {
1762                        this.addStat(StatList.distanceWalkedStat, var7);
1763    
1764                        if (this.isSprinting())
1765                        {
1766                            this.addExhaustion(0.099999994F * (float)var7 * 0.01F);
1767                        }
1768                        else
1769                        {
1770                            this.addExhaustion(0.01F * (float)var7 * 0.01F);
1771                        }
1772                    }
1773                }
1774                else
1775                {
1776                    var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F);
1777    
1778                    if (var7 > 25)
1779                    {
1780                        this.addStat(StatList.distanceFlownStat, var7);
1781                    }
1782                }
1783            }
1784        }
1785    
1786        /**
1787         * Adds a value to a mounted movement statistic field - by minecart, boat, or pig.
1788         */
1789        private void addMountedMovementStat(double par1, double par3, double par5)
1790        {
1791            if (this.ridingEntity != null)
1792            {
1793                int var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5) * 100.0F);
1794    
1795                if (var7 > 0)
1796                {
1797                    if (this.ridingEntity instanceof EntityMinecart)
1798                    {
1799                        this.addStat(StatList.distanceByMinecartStat, var7);
1800    
1801                        if (this.startMinecartRidingCoordinate == null)
1802                        {
1803                            this.startMinecartRidingCoordinate = new ChunkCoordinates(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ));
1804                        }
1805                        else if ((double)this.startMinecartRidingCoordinate.getDistanceSquared(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) >= 1000000.0D)
1806                        {
1807                            this.addStat(AchievementList.onARail, 1);
1808                        }
1809                    }
1810                    else if (this.ridingEntity instanceof EntityBoat)
1811                    {
1812                        this.addStat(StatList.distanceByBoatStat, var7);
1813                    }
1814                    else if (this.ridingEntity instanceof EntityPig)
1815                    {
1816                        this.addStat(StatList.distanceByPigStat, var7);
1817                    }
1818                }
1819            }
1820        }
1821    
1822        /**
1823         * Called when the mob is falling. Calculates and applies fall damage.
1824         */
1825        protected void fall(float par1)
1826        {
1827            if (!this.capabilities.allowFlying)
1828            {
1829                if (par1 >= 2.0F)
1830                {
1831                    this.addStat(StatList.distanceFallenStat, (int)Math.round((double)par1 * 100.0D));
1832                }
1833    
1834                super.fall(par1);
1835            }
1836        }
1837    
1838        /**
1839         * This method gets called when the entity kills another one.
1840         */
1841        public void onKillEntity(EntityLiving par1EntityLiving)
1842        {
1843            if (par1EntityLiving instanceof IMob)
1844            {
1845                this.triggerAchievement(AchievementList.killEnemy);
1846            }
1847        }
1848    
1849        /**
1850         * Sets the Entity inside a web block.
1851         */
1852        public void setInWeb()
1853        {
1854            if (!this.capabilities.isFlying)
1855            {
1856                super.setInWeb();
1857            }
1858        }
1859    
1860        @SideOnly(Side.CLIENT)
1861    
1862        /**
1863         * Gets the Icon Index of the item currently held
1864         */
1865        public int getItemIcon(ItemStack par1ItemStack, int par2)
1866        {
1867            int var3 = super.getItemIcon(par1ItemStack, par2);
1868    
1869            if (par1ItemStack.itemID == Item.fishingRod.shiftedIndex && this.fishEntity != null)
1870            {
1871                var3 = par1ItemStack.getIconIndex() + 16;
1872            }
1873            else
1874            {
1875                if (par1ItemStack.getItem().requiresMultipleRenderPasses())
1876                {
1877                    return par1ItemStack.getItem().getIconFromItemStackForMultiplePasses(par1ItemStack, par2);
1878                }
1879    
1880                if (this.itemInUse != null && par1ItemStack.itemID == Item.bow.shiftedIndex)
1881                {
1882                    int var4 = par1ItemStack.getMaxItemUseDuration() - this.itemInUseCount;
1883    
1884                    if (var4 >= 18)
1885                    {
1886                        return 133;
1887                    }
1888    
1889                    if (var4 > 13)
1890                    {
1891                        return 117;
1892                    }
1893    
1894                    if (var4 > 0)
1895                    {
1896                        return 101;
1897                    }
1898                }
1899                var3 = par1ItemStack.getItem().getIconIndex(par1ItemStack, par2, this, itemInUse, itemInUseCount);
1900            }
1901    
1902            return var3;
1903        }
1904    
1905        public ItemStack getCurrentArmor(int par1)
1906        {
1907            return this.inventory.armorItemInSlot(par1);
1908        }
1909    
1910        protected void func_82164_bB() {}
1911    
1912        protected void func_82162_bC() {}
1913    
1914        /**
1915         * This method increases the player's current amount of experience.
1916         */
1917        public void addExperience(int par1)
1918        {
1919            this.func_85039_t(par1);
1920            int var2 = Integer.MAX_VALUE - this.experienceTotal;
1921    
1922            if (par1 > var2)
1923            {
1924                par1 = var2;
1925            }
1926    
1927            this.experience += (float)par1 / (float)this.xpBarCap();
1928    
1929            for (this.experienceTotal += par1; this.experience >= 1.0F; this.experience /= (float)this.xpBarCap())
1930            {
1931                this.experience = (this.experience - 1.0F) * (float)this.xpBarCap();
1932                this.addExperienceLevel(1);
1933            }
1934        }
1935    
1936        /**
1937         * Add experience levels to this player.
1938         */
1939        public void addExperienceLevel(int par1)
1940        {
1941            this.experienceLevel += par1;
1942    
1943            if (this.experienceLevel < 0)
1944            {
1945                this.experienceLevel = 0;
1946            }
1947    
1948            if (par1 > 0 && this.experienceLevel % 5 == 0 && (float)this.field_82249_h < (float)this.ticksExisted - 100.0F)
1949            {
1950                float var2 = this.experienceLevel > 30 ? 1.0F : (float)this.experienceLevel / 30.0F;
1951                this.func_85030_a("random.levelup", var2 * 0.75F, 1.0F);
1952                this.field_82249_h = this.ticksExisted;
1953            }
1954        }
1955    
1956        /**
1957         * This method returns the cap amount of experience that the experience bar can hold. With each level, the
1958         * experience cap on the player's experience bar is raised by 10.
1959         */
1960        public int xpBarCap()
1961        {
1962            return this.experienceLevel >= 30 ? 62 + (this.experienceLevel - 30) * 7 : (this.experienceLevel >= 15 ? 17 + (this.experienceLevel - 15) * 3 : 17);
1963        }
1964    
1965        /**
1966         * increases exhaustion level by supplied amount
1967         */
1968        public void addExhaustion(float par1)
1969        {
1970            if (!this.capabilities.disableDamage)
1971            {
1972                if (!this.worldObj.isRemote)
1973                {
1974                    this.foodStats.addExhaustion(par1);
1975                }
1976            }
1977        }
1978    
1979        /**
1980         * Returns the player's FoodStats object.
1981         */
1982        public FoodStats getFoodStats()
1983        {
1984            return this.foodStats;
1985        }
1986    
1987        public boolean canEat(boolean par1)
1988        {
1989            return (par1 || this.foodStats.needFood()) && !this.capabilities.disableDamage;
1990        }
1991    
1992        /**
1993         * Checks if the player's health is not full and not zero.
1994         */
1995        public boolean shouldHeal()
1996        {
1997            return this.getHealth() > 0 && this.getHealth() < this.getMaxHealth();
1998        }
1999    
2000        /**
2001         * sets the itemInUse when the use item button is clicked. Args: itemstack, int maxItemUseDuration
2002         */
2003        public void setItemInUse(ItemStack par1ItemStack, int par2)
2004        {
2005            if (par1ItemStack != this.itemInUse)
2006            {
2007                this.itemInUse = par1ItemStack;
2008                this.itemInUseCount = par2;
2009    
2010                if (!this.worldObj.isRemote)
2011                {
2012                    this.setEating(true);
2013                }
2014            }
2015        }
2016    
2017        /**
2018         * Returns true if the item the player is holding can harvest the block at the given coords. Args: x, y, z.
2019         */
2020        public boolean canCurrentToolHarvestBlock(int par1, int par2, int par3)
2021        {
2022            if (this.capabilities.allowEdit)
2023            {
2024                return true;
2025            }
2026            else
2027            {
2028                int var4 = this.worldObj.getBlockId(par1, par2, par3);
2029    
2030                if (var4 > 0)
2031                {
2032                    Block var5 = Block.blocksList[var4];
2033    
2034                    if (var5.blockMaterial.func_85157_q())
2035                    {
2036                        return true;
2037                    }
2038    
2039                    if (this.getCurrentEquippedItem() != null)
2040                    {
2041                        ItemStack var6 = this.getCurrentEquippedItem();
2042    
2043                        if (var6.canHarvestBlock(var5) || var6.getStrVsBlock(var5) > 1.0F)
2044                        {
2045                            return true;
2046                        }
2047                    }
2048                }
2049    
2050                return false;
2051            }
2052        }
2053    
2054        public boolean func_82247_a(int par1, int par2, int par3, int par4, ItemStack par5ItemStack)
2055        {
2056            return this.capabilities.allowEdit ? true : (par5ItemStack != null ? par5ItemStack.func_82835_x() : false);
2057        }
2058    
2059        /**
2060         * Get the experience points the entity currently has.
2061         */
2062        protected int getExperiencePoints(EntityPlayer par1EntityPlayer)
2063        {
2064            if (this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory"))
2065            {
2066                return 0;
2067            }
2068            else
2069            {
2070                int var2 = this.experienceLevel * 7;
2071                return var2 > 100 ? 100 : var2;
2072            }
2073        }
2074    
2075        /**
2076         * Only use is to identify if class is an instance of player for experience dropping
2077         */
2078        protected boolean isPlayer()
2079        {
2080            return true;
2081        }
2082    
2083        /**
2084         * Gets the username of the entity.
2085         */
2086        public String getEntityName()
2087        {
2088            return this.username;
2089        }
2090    
2091        /**
2092         * Copies the values from the given player into this player if boolean par2 is true. Always clones Ender Chest
2093         * Inventory.
2094         */
2095        public void clonePlayer(EntityPlayer par1EntityPlayer, boolean par2)
2096        {
2097            if (par2)
2098            {
2099                this.inventory.copyInventory(par1EntityPlayer.inventory);
2100                this.health = par1EntityPlayer.health;
2101                this.foodStats = par1EntityPlayer.foodStats;
2102                this.experienceLevel = par1EntityPlayer.experienceLevel;
2103                this.experienceTotal = par1EntityPlayer.experienceTotal;
2104                this.experience = par1EntityPlayer.experience;
2105                this.func_85040_s(par1EntityPlayer.getScore());
2106                this.field_82152_aq = par1EntityPlayer.field_82152_aq;
2107            }
2108            else if (this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory"))
2109            {
2110                this.inventory.copyInventory(par1EntityPlayer.inventory);
2111                this.experienceLevel = par1EntityPlayer.experienceLevel;
2112                this.experienceTotal = par1EntityPlayer.experienceTotal;
2113                this.experience = par1EntityPlayer.experience;
2114                this.func_85040_s(par1EntityPlayer.getScore());
2115            }
2116    
2117            this.theInventoryEnderChest = par1EntityPlayer.theInventoryEnderChest;
2118        }
2119    
2120        /**
2121         * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
2122         * prevent them from trampling crops
2123         */
2124        protected boolean canTriggerWalking()
2125        {
2126            return !this.capabilities.isFlying;
2127        }
2128    
2129        /**
2130         * Sends the player's abilities to the server (if there is one).
2131         */
2132        public void sendPlayerAbilities() {}
2133    
2134        public void sendGameTypeToPlayer(EnumGameType par1EnumGameType) {}
2135    
2136        /**
2137         * Gets the name of this command sender (usually username, but possibly "Rcon")
2138         */
2139        public String getCommandSenderName()
2140        {
2141            return this.username;
2142        }
2143    
2144        public StringTranslate getTranslator()
2145        {
2146            return StringTranslate.getInstance();
2147        }
2148    
2149        /**
2150         * Translates and formats the given string key with the given arguments.
2151         */
2152        public String translateString(String par1Str, Object ... par2ArrayOfObj)
2153        {
2154            return this.getTranslator().translateKeyFormat(par1Str, par2ArrayOfObj);
2155        }
2156    
2157        /**
2158         * Returns the InventoryEnderChest of this player.
2159         */
2160        public InventoryEnderChest getInventoryEnderChest()
2161        {
2162            return this.theInventoryEnderChest;
2163        }
2164    
2165        /**
2166         * 0 = item, 1-n is armor
2167         */
2168        public ItemStack getCurrentItemOrArmor(int par1)
2169        {
2170            return par1 == 0 ? this.inventory.getCurrentItem() : this.inventory.armorInventory[par1 - 1];
2171        }
2172    
2173        /**
2174         * Returns the item that this EntityLiving is holding, if any.
2175         */
2176        public ItemStack getHeldItem()
2177        {
2178            return this.inventory.getCurrentItem();
2179        }
2180    
2181        /**
2182         * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. Params: Item, slot
2183         */
2184        public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack)
2185        {
2186            this.inventory.armorInventory[par1] = par2ItemStack;
2187        }
2188    
2189        public ItemStack[] getLastActiveItems()
2190        {
2191            return this.inventory.armorInventory;
2192        }
2193    
2194        @SideOnly(Side.CLIENT)
2195        public boolean func_82238_cc()
2196        {
2197            return this.func_82241_s(1);
2198        }
2199    
2200        public void openGui(Object mod, int modGuiId, World world, int x, int y, int z)
2201        {
2202            FMLNetworkHandler.openGui(this, mod, modGuiId, world, x, y, z);
2203        }
2204    }