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