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