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