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