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