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