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