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