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