    001    package net.minecraft.src;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.util.Collection;
    006    import java.util.HashMap;
    007    import java.util.Iterator;
    008    import java.util.List;
    009    import java.util.Random;
    010    import net.minecraftforge.common.ForgeHooks;
    011    import net.minecraftforge.common.MinecraftForge;
    012    import net.minecraftforge.event.entity.living.*;
    013    import static net.minecraftforge.event.entity.living.LivingEvent.*;
    014
    015    public abstract class EntityLiving extends Entity
    016    {
    017        private static final float[] field_82177_b = new float[] {0.0F, 0.0F, 0.005F, 0.01F};
    018        private static final float[] field_82178_c = new float[] {0.0F, 0.0F, 0.05F, 0.1F};
    019        private static final float[] field_82176_d = new float[] {0.0F, 0.0F, 0.005F, 0.02F};
    020        public static final float[] field_82181_as = new float[] {0.0F, 0.01F, 0.07F, 0.2F};
    021        public int maxHurtResistantTime = 20;
    022        public float field_70769_ao;
    023        public float field_70770_ap;
    024        public float renderYawOffset = 0.0F;
    025        public float prevRenderYawOffset = 0.0F;
    026
    027        /** Entity head rotation yaw */
    028        public float rotationYawHead = 0.0F;
    029
    030        /** Entity head rotation yaw at previous tick */
    031        public float prevRotationYawHead = 0.0F;
    032        protected float field_70768_au;
    033        protected float field_70766_av;
    034        protected float field_70764_aw;
    035        protected float field_70763_ax;
    036        protected boolean field_70753_ay = true;
    037
    038        /** the path for the texture of this entityLiving */
    039        protected String texture = "/mob/char.png";
    040        protected boolean field_70740_aA = true;
    041        protected float field_70741_aB = 0.0F;
    042
    043        /**
    044         * a string holding the type of entity it is currently only implemented in entityPlayer(as 'humanoid')
    045         */
    046        protected String entityType = null;
    047        protected float field_70743_aD = 1.0F;
    048
    049        /** The score value of the Mob, the amount of points the mob is worth. */
    050        protected int scoreValue = 0;
    051        protected float field_70745_aF = 0.0F;
    052
    053        /**
    054         * A factor used to determine how far this entity will move each tick if it is walking on land. Adjusted by speed,
    055         * and slipperiness of the current block.
    056         */
    057        public float landMovementFactor = 0.1F;
    058
    059        /**
    060         * A factor used to determine how far this entity will move each tick if it is jumping or falling.
    061         */
    062        public float jumpMovementFactor = 0.02F;
    063        public float prevSwingProgress;
    064        public float swingProgress;
    065        protected int health = this.getMaxHealth();
    066        public int prevHealth;
    067
    068        /**
    069         * in each step in the damage calculations, this is set to the 'carryover' that would result if someone was damaged
    070         * .25 hearts (for example), and added to the damage in the next step
    071         */
    072        public int carryoverDamage;
    073
    074        /** Number of ticks since this EntityLiving last produced its sound */
    075        public int livingSoundTime;
    076
    077        /**
    078         * The amount of time remaining this entity should act 'hurt'. (Visual appearance of red tint)
    079         */
    080        public int hurtTime;
    081
    082        /** What the hurt time was max set to last. */
    083        public int maxHurtTime;
    084
    085        /** The yaw at which this entity was last attacked from. */
    086        public float attackedAtYaw = 0.0F;
    087
    088        /**
    089         * The amount of time remaining this entity should act 'dead', i.e. have a corpse in the world.
    090         */
    091        public int deathTime = 0;
    092        public int attackTime = 0;
    093        public float prevCameraPitch;
    094        public float cameraPitch;
    095
    096        /**
    097         * This gets set on entity death, but never used. Looks like a duplicate of isDead
    098         */
    099        protected boolean dead = false;
    100
    101        /** The experience points the Entity gives. */
    102        protected int experienceValue;
    103        public int field_70731_aW = -1;
    104        public float field_70730_aX = (float)(Math.random() * 0.8999999761581421D + 0.10000000149011612D);
    105        public float prevLegYaw;
    106        public float legYaw;
    107
    108        /**
    109         * Only relevant when legYaw is not 0(the entity is moving). Influences where in its swing legs and arms currently
    110         * are.
    111         */
    112        public float legSwing;
    113
    114        /** The most recent player that has attacked this entity */
    115        protected EntityPlayer attackingPlayer = null;
    116
    117        /**
    118         * Set to 60 when hit by the player or the player's wolf, then decrements. Used to determine whether the entity
    119         * should drop items on death.
    120         */
    121        protected int recentlyHit = 0;
    122
    123        /** is only being set, has no uses as of MC 1.1 */
    124        private EntityLiving entityLivingToAttack = null;
    125        private int revengeTimer = 0;
    126        private EntityLiving lastAttackingEntity = null;
    127
    128        /**
    129         * Set to 60 when hit by the player or the player's wolf, then decrements. Used to determine whether the entity
    130         * should drop items on death.
    131         */
    132        public int arrowHitTempCounter = 0;
    133        public int arrowHitTimer = 0;
    134        protected HashMap activePotionsMap = new HashMap();
    135
    136        /** Whether the DataWatcher needs to be updated with the active potions */
    137        private boolean potionsNeedUpdate = true;
    138        private int field_70748_f;
    139        private EntityLookHelper lookHelper;
    140        private EntityMoveHelper moveHelper;
    141
    142        /** Entity jumping helper */
    143        private EntityJumpHelper jumpHelper;
    144        private EntityBodyHelper bodyHelper;
    145        private PathNavigate navigator;
    146        public final EntityAITasks tasks;
    147        protected final EntityAITasks targetTasks;
    148
    149        /** The active target the Task system uses for tracking */
    150        private EntityLiving attackTarget;
    151        private EntitySenses senses;
    152        private float AIMoveSpeed;
    153        private ChunkCoordinates homePosition = new ChunkCoordinates(0, 0, 0);
    154
    155        /** If -1 there is no maximum distance */
    156        private float maximumHomeDistance = -1.0F;
    157        private ItemStack[] field_82182_bS = new ItemStack[5];
    158        protected float[] field_82174_bp = new float[5];
    159        private ItemStack[] field_82180_bT = new ItemStack[5];
    160        public boolean field_82175_bq = false;
    161        public int field_82173_br = 0;
    162        protected boolean field_82172_bs = false;
    163        private boolean field_82179_bU = false;
    164
    165        /**
    166         * The number of updates over which the new position and rotation are to be applied to the entity.
    167         */
    168        protected int newPosRotationIncrements;
    169
    170        /** The new X position to be applied to the entity. */
    171        protected double newPosX;
    172
    173        /** The new Y position to be applied to the entity. */
    174        protected double newPosY;
    175
    176        /** The new Z position to be applied to the entity. */
    177        protected double newPosZ;
    178
    179        /** The new yaw rotation to be applied to the entity. */
    180        protected double newRotationYaw;
    181
    182        /** The new yaw rotation to be applied to the entity. */
    183        protected double newRotationPitch;
    184        float field_70706_bo = 0.0F;
    185
    186        /** Amount of damage taken in last hit, in half-hearts */
    187        protected int lastDamage = 0;
    188
    189        /** Holds the living entity age, used to control the despawn. */
    190        protected int entityAge = 0;
    191        protected float moveStrafing;
    192        protected float moveForward;
    193        protected float randomYawVelocity;
    194
    195        /** used to check whether entity is jumping. */
    196        public boolean isJumping = false;
    197        protected float defaultPitch = 0.0F;
    198        protected float moveSpeed = 0.7F;
    199
    200        /** Number of ticks since last jump */
    201        private int jumpTicks = 0;
    202
    203        /** This entity's current target. */
    204        private Entity currentTarget;
    205
    206        /** How long to keep a specific target entity */
    207        protected int numTicksToChaseTarget = 0;
    208
    209        public EntityLiving(World par1World)
    210        {
    211            super(par1World);
    212            this.preventEntitySpawning = true;
    213            this.tasks = new EntityAITasks(par1World != null && par1World.theProfiler != null ? par1World.theProfiler : null);
    214            this.targetTasks = new EntityAITasks(par1World != null && par1World.theProfiler != null ? par1World.theProfiler : null);
    215            this.lookHelper = new EntityLookHelper(this);
    216            this.moveHelper = new EntityMoveHelper(this);
    217            this.jumpHelper = new EntityJumpHelper(this);
    218            this.bodyHelper = new EntityBodyHelper(this);
    219            this.navigator = new PathNavigate(this, par1World, 16.0F);
    220            this.senses = new EntitySenses(this);
    221            this.field_70770_ap = (float)(Math.random() + 1.0D) * 0.01F;
    222            this.setPosition(this.posX, this.posY, this.posZ);
    223            this.field_70769_ao = (float)Math.random() * 12398.0F;
    224            this.rotationYaw = (float)(Math.random() * Math.PI * 2.0D);
    225            this.rotationYawHead = this.rotationYaw;
    226
    227            for (int var2 = 0; var2 < this.field_82174_bp.length; ++var2)
    228            {
    229                this.field_82174_bp[var2] = 0.05F;
    230            }
    231
    232            this.stepHeight = 0.5F;
    233        }
    234
    235        public EntityLookHelper getLookHelper()
    236        {
    237            return this.lookHelper;
    238        }
    239
    240        public EntityMoveHelper getMoveHelper()
    241        {
    242            return this.moveHelper;
    243        }
    244
    245        public EntityJumpHelper getJumpHelper()
    246        {
    247            return this.jumpHelper;
    248        }
    249
    250        public PathNavigate getNavigator()
    251        {
    252            return this.navigator;
    253        }
    254
    255        /**
    256         * returns the EntitySenses Object for the EntityLiving
    257         */
    258        public EntitySenses getEntitySenses()
    259        {
    260            return this.senses;
    261        }
    262
    263        public Random getRNG()
    264        {
    265            return this.rand;
    266        }
    267
    268        public EntityLiving getAITarget()
    269        {
    270            return this.entityLivingToAttack;
    271        }
    272
    273        public EntityLiving getLastAttackingEntity()
    274        {
    275            return this.lastAttackingEntity;
    276        }
    277
    278        public void setLastAttackingEntity(Entity par1Entity)
    279        {
    280            if (par1Entity instanceof EntityLiving)
    281            {
    282                this.lastAttackingEntity = (EntityLiving)par1Entity;
    283            }
    284        }
    285
    286        public int getAge()
    287        {
    288            return this.entityAge;
    289        }
    290
    291        public float func_70079_am()
    292        {
    293            return this.rotationYawHead;
    294        }
    295
    296        @SideOnly(Side.CLIENT)
    297
    298        /**
    299         * Sets the head's yaw rotation of the entity.
    300         */
    301        public void setHeadRotationYaw(float par1)
    302        {
    303            this.rotationYawHead = par1;
    304        }
    305
    306        /**
    307         * the movespeed used for the new AI system
    308         */
    309        public float getAIMoveSpeed()
    310        {
    311            return this.AIMoveSpeed;
    312        }
    313
    314        /**
    315         * set the movespeed used for the new AI system
    316         */
    317        public void setAIMoveSpeed(float par1)
    318        {
    319            this.AIMoveSpeed = par1;
    320            this.setMoveForward(par1);
    321        }
    322
    323        public boolean attackEntityAsMob(Entity par1Entity)
    324        {
    325            this.setLastAttackingEntity(par1Entity);
    326            return false;
    327        }
    328
    329        /**
    330         * Gets the active target the Task system uses for tracking
    331         */
    332        public EntityLiving getAttackTarget()
    333        {
    334            return this.attackTarget;
    335        }
    336
    337        /**
    338         * Sets the active target the Task system uses for tracking
    339         */
    340        public void setAttackTarget(EntityLiving par1EntityLiving)
    341        {
    342            this.attackTarget = par1EntityLiving;
    343            ForgeHooks.onLivingSetAttackTarget(this, par1EntityLiving);
    344        }
    345
    346        public boolean isExplosiveMob(Class par1Class)
    347        {
    348            return EntityCreeper.class != par1Class && EntityGhast.class != par1Class;
    349        }
    350
    351        /**
    352         * This function applies the benefits of growing back wool and faster growing up to the acting entity. (This
    353         * function is used in the AIEatGrass)
    354         */
    355        public void eatGrassBonus() {}
    356
    357        /**
    358         * Takes in the distance the entity has fallen this tick and whether its on the ground to update the fall distance
    359         * and deal fall damage if landing on the ground.  Args: distanceFallenThisTick, onGround
    360         */
    361        protected void updateFallState(double par1, boolean par3)
    362        {
    363            if (par3 && this.fallDistance > 0.0F)
    364            {
    365                int var4 = MathHelper.floor_double(this.posX);
    366                int var5 = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double)this.yOffset);
    367                int var6 = MathHelper.floor_double(this.posZ);
    368                int var7 = this.worldObj.getBlockId(var4, var5, var6);
    369
    370                if (var7 == 0 && this.worldObj.getBlockId(var4, var5 - 1, var6) == Block.fence.blockID)
    371                {
    372                    var7 = this.worldObj.getBlockId(var4, var5 - 1, var6);
    373                }
    374
    375                if (var7 > 0)
    376                {
    377                    Block.blocksList[var7].onFallenUpon(this.worldObj, var4, var5, var6, this, this.fallDistance);
    378                }
    379            }
    380
    381            super.updateFallState(par1, par3);
    382        }
    383
    384        /**
    385         * Returns true if entity is within home distance from current position
    386         */
    387        public boolean isWithinHomeDistanceCurrentPosition()
    388        {
    389            return this.isWithinHomeDistance(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ));
    390        }
    391
    392        public boolean isWithinHomeDistance(int par1, int par2, int par3)
    393        {
    394            return this.maximumHomeDistance == -1.0F ? true : this.homePosition.getDistanceSquared(par1, par2, par3) < this.maximumHomeDistance * this.maximumHomeDistance;
    395        }
    396
    397        public void setHomeArea(int par1, int par2, int par3, int par4)
    398        {
    399            this.homePosition.set(par1, par2, par3);
    400            this.maximumHomeDistance = (float)par4;
    401        }
    402
    403        public ChunkCoordinates getHomePosition()
    404        {
    405            return this.homePosition;
    406        }
    407
    408        public float getMaximumHomeDistance()
    409        {
    410            return this.maximumHomeDistance;
    411        }
    412
    413        public void detachHome()
    414        {
    415            this.maximumHomeDistance = -1.0F;
    416        }
    417
    418        public boolean hasHome()
    419        {
    420            return this.maximumHomeDistance != -1.0F;
    421        }
    422
    423        public void setRevengeTarget(EntityLiving par1EntityLiving)
    424        {
    425            this.entityLivingToAttack = par1EntityLiving;
    426            this.revengeTimer = this.entityLivingToAttack != null ? 60 : 0;
    427            ForgeHooks.onLivingSetAttackTarget(this, par1EntityLiving);
    428        }
    429
    430        protected void entityInit()
    431        {
    432            this.dataWatcher.addObject(8, Integer.valueOf(this.field_70748_f));
    433            this.dataWatcher.addObject(9, Byte.valueOf((byte)0));
    434        }
    435
    436        /**
    437         * returns true if the entity provided in the argument can be seen. (Raytrace)
    438         */
    439        public boolean canEntityBeSeen(Entity par1Entity)
    440        {
    441            return this.worldObj.rayTraceBlocks(this.worldObj.func_82732_R().getVecFromPool(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ), this.worldObj.func_82732_R().getVecFromPool(par1Entity.posX, par1Entity.posY + (double)par1Entity.getEyeHeight(), par1Entity.posZ)) == null;
    442        }
    443
    444        @SideOnly(Side.CLIENT)
    445
    446        /**
    447         * Returns the texture's file path as a String.
    448         */
    449        public String getTexture()
    450        {
    451            return this.texture;
    452        }
    453
    454        /**
    455         * Returns true if other Entities should be prevented from moving through this Entity.
    456         */
    457        public boolean canBeCollidedWith()
    458        {
    459            return !this.isDead;
    460        }
    461
    462        /**
    463         * Returns true if this entity should push and be pushed by other entities when colliding.
    464         */
    465        public boolean canBePushed()
    466        {
    467            return !this.isDead;
    468        }
    469
    470        public float getEyeHeight()
    471        {
    472            return this.height * 0.85F;
    473        }
    474
    475        /**
    476         * Get number of ticks, at least during which the living entity will be silent.
    477         */
    478        public int getTalkInterval()
    479        {
    480            return 80;
    481        }
    482
    483        /**
    484         * Plays living's sound at its position
    485         */
    486        public void playLivingSound()
    487        {
    488            String var1 = this.getLivingSound();
    489
    490            if (var1 != null)
    491            {
    492                this.worldObj.playSoundAtEntity(this, var1, this.getSoundVolume(), this.getSoundPitch());
    493            }
    494        }
    495
    496        /**
    497         * Gets called every tick from main Entity class
    498         */
    499        public void onEntityUpdate()
    500        {
    501            this.prevSwingProgress = this.swingProgress;
    502            super.onEntityUpdate();
    503            this.worldObj.theProfiler.startSection("mobBaseTick");
    504
    505            if (this.isEntityAlive() && this.rand.nextInt(1000) < this.livingSoundTime++)
    506            {
    507                this.livingSoundTime = -this.getTalkInterval();
    508                this.playLivingSound();
    509            }
    510
    511            if (this.isEntityAlive() && this.isEntityInsideOpaqueBlock())
    512            {
    513                this.attackEntityFrom(DamageSource.inWall, 1);
    514            }
    515
    516            if (this.isImmuneToFire() || this.worldObj.isRemote)
    517            {
    518                this.extinguish();
    519            }
    520
    521            if (this.isEntityAlive() && this.isInsideOfMaterial(Material.water) && !this.canBreatheUnderwater() && !this.activePotionsMap.containsKey(Integer.valueOf(Potion.waterBreathing.id)))
    522            {
    523                this.setAir(this.decreaseAirSupply(this.getAir()));
    524
    525                if (this.getAir() == -20)
    526                {
    527                    this.setAir(0);
    528
    529                    for (int var1 = 0; var1 < 8; ++var1)
    530                    {
    531                        float var2 = this.rand.nextFloat() - this.rand.nextFloat();
    532                        float var3 = this.rand.nextFloat() - this.rand.nextFloat();
    533                        float var4 = this.rand.nextFloat() - this.rand.nextFloat();
    534                        this.worldObj.spawnParticle("bubble", this.posX + (double)var2, this.posY + (double)var3, this.posZ + (double)var4, this.motionX, this.motionY, this.motionZ);
    535                    }
    536
    537                    this.attackEntityFrom(DamageSource.drown, 2);
    538                }
    539
    540                this.extinguish();
    541            }
    542            else
    543            {
    544                this.setAir(300);
    545            }
    546
    547            this.prevCameraPitch = this.cameraPitch;
    548
    549            if (this.attackTime > 0)
    550            {
    551                --this.attackTime;
    552            }
    553
    554            if (this.hurtTime > 0)
    555            {
    556                --this.hurtTime;
    557            }
    558
    559            if (this.hurtResistantTime > 0)
    560            {
    561                --this.hurtResistantTime;
    562            }
    563
    564            if (this.health <= 0)
    565            {
    566                this.onDeathUpdate();
    567            }
    568
    569            if (this.recentlyHit > 0)
    570            {
    571                --this.recentlyHit;
    572            }
    573            else
    574            {
    575                this.attackingPlayer = null;
    576            }
    577
    578            if (this.lastAttackingEntity != null && !this.lastAttackingEntity.isEntityAlive())
    579            {
    580                this.lastAttackingEntity = null;
    581            }
    582
    583            if (this.entityLivingToAttack != null)
    584            {
    585                if (!this.entityLivingToAttack.isEntityAlive())
    586                {
    587                    this.setRevengeTarget((EntityLiving)null);
    588                }
    589                else if (this.revengeTimer > 0)
    590                {
    591                    --this.revengeTimer;
    592                }
    593                else
    594                {
    595                    this.setRevengeTarget((EntityLiving)null);
    596                }
    597            }
    598
    599            this.updatePotionEffects();
    600            this.field_70763_ax = this.field_70764_aw;
    601            this.prevRenderYawOffset = this.renderYawOffset;
    602            this.prevRotationYawHead = this.rotationYawHead;
    603            this.prevRotationYaw = this.rotationYaw;
    604            this.prevRotationPitch = this.rotationPitch;
    605            this.worldObj.theProfiler.endSection();
    606        }
    607
    608        /**
    609         * handles entity death timer, experience orb and particle creation
    610         */
    611        protected void onDeathUpdate()
    612        {
    613            ++this.deathTime;
    614
    615            if (this.deathTime == 20)
    616            {
    617                int var1;
    618
    619                if (!this.worldObj.isRemote && (this.recentlyHit > 0 || this.isPlayer()) && !this.isChild())
    620                {
    621                    var1 = this.getExperiencePoints(this.attackingPlayer);
    622
    623                    while (var1 > 0)
    624                    {
    625                        int var2 = EntityXPOrb.getXPSplit(var1);
    626                        var1 -= var2;
    627                        this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, var2));
    628                    }
    629                }
    630
    631                this.setDead();
    632
    633                for (var1 = 0; var1 < 20; ++var1)
    634                {
    635                    double var8 = this.rand.nextGaussian() * 0.02D;
    636                    double var4 = this.rand.nextGaussian() * 0.02D;
    637                    double var6 = this.rand.nextGaussian() * 0.02D;
    638                    this.worldObj.spawnParticle("explode", this.posX + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, this.posY + (double)(this.rand.nextFloat() * this.height), this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, var8, var4, var6);
    639                }
    640            }
    641        }
    642
    643        /**
    644         * Decrements the entity's air supply when underwater
    645         */
    646        protected int decreaseAirSupply(int par1)
    647        {
    648            int var2 = EnchantmentHelper.getRespiration(this);
    649            return var2 > 0 && this.rand.nextInt(var2 + 1) > 0 ? par1 : par1 - 1;
    650        }
    651
    652        /**
    653         * Get the experience points the entity currently has.
    654         */
    655        protected int getExperiencePoints(EntityPlayer par1EntityPlayer)
    656        {
    657            return this.experienceValue;
    658        }
    659
    660        /**
    661         * Only use is to identify if class is an instance of player for experience dropping
    662         */
    663        protected boolean isPlayer()
    664        {
    665            return false;
    666        }
    667
    668        /**
    669         * Spawns an explosion particle around the Entity's location
    670         */
    671        public void spawnExplosionParticle()
    672        {
    673            for (int var1 = 0; var1 < 20; ++var1)
    674            {
    675                double var2 = this.rand.nextGaussian() * 0.02D;
    676                double var4 = this.rand.nextGaussian() * 0.02D;
    677                double var6 = this.rand.nextGaussian() * 0.02D;
    678                double var8 = 10.0D;
    679                this.worldObj.spawnParticle("explode", this.posX + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width - var2 * var8, this.posY + (double)(this.rand.nextFloat() * this.height) - var4 * var8, this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width - var6 * var8, var2, var4, var6);
    680            }
    681        }
    682
    683        /**
    684         * Handles updating while being ridden by an entity
    685         */
    686        public void updateRidden()
    687        {
    688            super.updateRidden();
    689            this.field_70768_au = this.field_70766_av;
    690            this.field_70766_av = 0.0F;
    691            this.fallDistance = 0.0F;
    692        }
    693
    694        @SideOnly(Side.CLIENT)
    695
    696        /**
    697         * Sets the position and rotation. Only difference from the other one is no bounding on the rotation. Args: posX,
    698         * posY, posZ, yaw, pitch
    699         */
    700        public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9)
    701        {
    702            this.yOffset = 0.0F;
    703            this.newPosX = par1;
    704            this.newPosY = par3;
    705            this.newPosZ = par5;
    706            this.newRotationYaw = (double)par7;
    707            this.newRotationPitch = (double)par8;
    708            this.newPosRotationIncrements = par9;
    709        }
    710
    711        /**
    712         * Called to update the entity's position/logic.
    713         */
    714        public void onUpdate()
    715        {
    716            if (ForgeHooks.onLivingUpdate(this))
    717            {
    718                return;
    719            }
    720
    721            super.onUpdate();
    722
    723            if (!this.worldObj.isRemote)
    724            {
    725                for (int var1 = 0; var1 < 5; ++var1)
    726                {
    727                    ItemStack var2 = this.getCurrentItemOrArmor(var1);
    728
    729                    if (!ItemStack.areItemStacksEqual(var2, this.field_82180_bT[var1]))
    730                    {
    731                        ((WorldServer)this.worldObj).getEntityTracker().sendPacketToAllPlayersTrackingEntity(this, new Packet5PlayerInventory(this.entityId, var1, var2));
    732                        this.field_82180_bT[var1] = var2 == null ? null : var2.copy();
    733                    }
    734                }
    735            }
    736
    737            if (this.arrowHitTempCounter > 0)
    738            {
    739                if (this.arrowHitTimer <= 0)
    740                {
    741                    this.arrowHitTimer = 60;
    742                }
    743
    744                --this.arrowHitTimer;
    745
    746                if (this.arrowHitTimer <= 0)
    747                {
    748                    --this.arrowHitTempCounter;
    749                }
    750            }
    751
    752            this.onLivingUpdate();
    753            double var12 = this.posX - this.prevPosX;
    754            double var3 = this.posZ - this.prevPosZ;
    755            float var5 = (float)(var12 * var12 + var3 * var3);
    756            float var6 = this.renderYawOffset;
    757            float var7 = 0.0F;
    758            this.field_70768_au = this.field_70766_av;
    759            float var8 = 0.0F;
    760
    761            if (var5 > 0.0025000002F)
    762            {
    763                var8 = 1.0F;
    764                var7 = (float)Math.sqrt((double)var5) * 3.0F;
    765                var6 = (float)Math.atan2(var3, var12) * 180.0F / (float)Math.PI - 90.0F;
    766            }
    767
    768            if (this.swingProgress > 0.0F)
    769            {
    770                var6 = this.rotationYaw;
    771            }
    772
    773            if (!this.onGround)
    774            {
    775                var8 = 0.0F;
    776            }
    777
    778            this.field_70766_av += (var8 - this.field_70766_av) * 0.3F;
    779            this.worldObj.theProfiler.startSection("headTurn");
    780
    781            if (this.isAIEnabled())
    782            {
    783                this.bodyHelper.func_75664_a();
    784            }
    785            else
    786            {
    787                float var9 = MathHelper.wrapAngleTo180_float(var6 - this.renderYawOffset);
    788                this.renderYawOffset += var9 * 0.3F;
    789                float var10 = MathHelper.wrapAngleTo180_float(this.rotationYaw - this.renderYawOffset);
    790                boolean var11 = var10 < -90.0F || var10 >= 90.0F;
    791
    792                if (var10 < -75.0F)
    793                {
    794                    var10 = -75.0F;
    795                }
    796
    797                if (var10 >= 75.0F)
    798                {
    799                    var10 = 75.0F;
    800                }
    801
    802                this.renderYawOffset = this.rotationYaw - var10;
    803
    804                if (var10 * var10 > 2500.0F)
    805                {
    806                    this.renderYawOffset += var10 * 0.2F;
    807                }
    808
    809                if (var11)
    810                {
    811                    var7 *= -1.0F;
    812                }
    813            }
    814
    815            this.worldObj.theProfiler.endSection();
    816            this.worldObj.theProfiler.startSection("rangeChecks");
    817
    818            while (this.rotationYaw - this.prevRotationYaw < -180.0F)
    819            {
    820                this.prevRotationYaw -= 360.0F;
    821            }
    822
    823            while (this.rotationYaw - this.prevRotationYaw >= 180.0F)
    824            {
    825                this.prevRotationYaw += 360.0F;
    826            }
    827
    828            while (this.renderYawOffset - this.prevRenderYawOffset < -180.0F)
    829            {
    830                this.prevRenderYawOffset -= 360.0F;
    831            }
    832
    833            while (this.renderYawOffset - this.prevRenderYawOffset >= 180.0F)
    834            {
    835                this.prevRenderYawOffset += 360.0F;
    836            }
    837
    838            while (this.rotationPitch - this.prevRotationPitch < -180.0F)
    839            {
    840                this.prevRotationPitch -= 360.0F;
    841            }
    842
    843            while (this.rotationPitch - this.prevRotationPitch >= 180.0F)
    844            {
    845                this.prevRotationPitch += 360.0F;
    846            }
    847
    848            while (this.rotationYawHead - this.prevRotationYawHead < -180.0F)
    849            {
    850                this.prevRotationYawHead -= 360.0F;
    851            }
    852
    853            while (this.rotationYawHead - this.prevRotationYawHead >= 180.0F)
    854            {
    855                this.prevRotationYawHead += 360.0F;
    856            }
    857
    858            this.worldObj.theProfiler.endSection();
    859            this.field_70764_aw += var7;
    860        }
    861
    862        /**
    863         * Heal living entity (param: amount of half-hearts)
    864         */
    865        public void heal(int par1)
    866        {
    867            if (this.health > 0)
    868            {
    869                this.health += par1;
    870
    871                if (this.health > this.getMaxHealth())
    872                {
    873                    this.health = this.getMaxHealth();
    874                }
    875
    876                this.hurtResistantTime = this.maxHurtResistantTime / 2;
    877            }
    878        }
    879
    880        public abstract int getMaxHealth();
    881
    882        public int getHealth()
    883        {
    884            return this.health;
    885        }
    886
    887        public void setEntityHealth(int par1)
    888        {
    889            this.health = par1;
    890
    891            if (par1 > this.getMaxHealth())
    892            {
    893                par1 = this.getMaxHealth();
    894            }
    895        }
    896
    897        /**
    898         * Called when the entity is attacked.
    899         */
    900        public boolean attackEntityFrom(DamageSource par1DamageSource, int par2)
    901        {
    902            if (ForgeHooks.onLivingAttack(this, par1DamageSource, par2))
    903            {
    904                return false;
    905            }
    906
    907            if (this.worldObj.isRemote)
    908            {
    909                return false;
    910            }
    911            else
    912            {
    913                this.entityAge = 0;
    914
    915                if (this.health <= 0)
    916                {
    917                    return false;
    918                }
    919                else if (par1DamageSource.fireDamage() && this.isPotionActive(Potion.fireResistance))
    920                {
    921                    return false;
    922                }
    923                else
    924                {
    925                    if ((par1DamageSource == DamageSource.field_82728_o || par1DamageSource == DamageSource.field_82729_p) && this.getCurrentItemOrArmor(4) != null)
    926                    {
    927                        par2 = (int)((float)par2 * 0.55F);
    928                    }
    929
    930                    this.legYaw = 1.5F;
    931                    boolean var3 = true;
    932
    933                    if ((float)this.hurtResistantTime > (float)this.maxHurtResistantTime / 2.0F)
    934                    {
    935                        if (par2 <= this.lastDamage)
    936                        {
    937                            return false;
    938                        }
    939
    940                        this.damageEntity(par1DamageSource, par2 - this.lastDamage);
    941                        this.lastDamage = par2;
    942                        var3 = false;
    943                    }
    944                    else
    945                    {
    946                        this.lastDamage = par2;
    947                        this.prevHealth = this.health;
    948                        this.hurtResistantTime = this.maxHurtResistantTime;
    949                        this.damageEntity(par1DamageSource, par2);
    950                        this.hurtTime = this.maxHurtTime = 10;
    951                    }
    952
    953                    this.attackedAtYaw = 0.0F;
    954                    Entity var4 = par1DamageSource.getEntity();
    955
    956                    if (var4 != null)
    957                    {
    958                        if (var4 instanceof EntityLiving)
    959                        {
    960                            this.setRevengeTarget((EntityLiving)var4);
    961                        }
    962
    963                        if (var4 instanceof EntityPlayer)
    964                        {
    965                            this.recentlyHit = 60;
    966                            this.attackingPlayer = (EntityPlayer)var4;
    967                        }
    968                        else if (var4 instanceof EntityWolf)
    969                        {
    970                            EntityWolf var5 = (EntityWolf)var4;
    971
    972                            if (var5.isTamed())
    973                            {
    974                                this.recentlyHit = 60;
    975                                this.attackingPlayer = null;
    976                            }
    977                        }
    978                    }
    979
    980                    if (var3)
    981                    {
    982                        this.worldObj.setEntityState(this, (byte)2);
    983
    984                        if (par1DamageSource != DamageSource.drown && par1DamageSource != DamageSource.field_76375_l)
    985                        {
    986                            this.setBeenAttacked();
    987                        }
    988
    989                        if (var4 != null)
    990                        {
    991                            double var9 = var4.posX - this.posX;
    992                            double var7;
    993
    994                            for (var7 = var4.posZ - this.posZ; var9 * var9 + var7 * var7 < 1.0E-4D; var7 = (Math.random() - Math.random()) * 0.01D)
    995                            {
    996                                var9 = (Math.random() - Math.random()) * 0.01D;
    997                            }
    998
    999                            this.attackedAtYaw = (float)(Math.atan2(var7, var9) * 180.0D / Math.PI) - this.rotationYaw;
    1000                            this.knockBack(var4, par2, var9, var7);
    1001                        }
    1002                        else
    1003                        {
    1004                            this.attackedAtYaw = (float)((int)(Math.random() * 2.0D) * 180);
    1005                        }
    1006                    }
    1007
    1008                    if (this.health <= 0)
    1009                    {
    1010                        if (var3)
    1011                        {
    1012                            this.worldObj.playSoundAtEntity(this, this.getDeathSound(), this.getSoundVolume(), this.getSoundPitch());
    1013                        }
    1014
    1015                        this.onDeath(par1DamageSource);
    1016                    }
    1017                    else if (var3)
    1018                    {
    1019                        this.worldObj.playSoundAtEntity(this, this.getHurtSound(), this.getSoundVolume(), this.getSoundPitch());
    1020                    }
    1021
    1022                    return true;
    1023                }
    1024            }
    1025        }
    1026
    1027        /**
    1028         * Gets the pitch of living sounds in living entities.
    1029         */
    1030        private float getSoundPitch()
    1031        {
    1032            return this.isChild() ? (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.5F : (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F;
    1033        }
    1034
    1035        @SideOnly(Side.CLIENT)
    1036
    1037        /**
    1038         * Setups the entity to do the hurt animation. Only used by packets in multiplayer.
    1039         */
    1040        public void performHurtAnimation()
    1041        {
    1042            this.hurtTime = this.maxHurtTime = 10;
    1043            this.attackedAtYaw = 0.0F;
    1044        }
    1045
    1046        /**
    1047         * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue
    1048         */
    1049        public int getTotalArmorValue()
    1050        {
    1051            int var1 = 0;
    1052            ItemStack[] var2 = this.getLastActiveItems();
    1053            int var3 = var2.length;
    1054
    1055            for (int var4 = 0; var4 < var3; ++var4)
    1056            {
    1057                ItemStack var5 = var2[var4];
    1058
    1059                if (var5 != null && var5.getItem() instanceof ItemArmor)
    1060                {
    1061                    int var6 = ((ItemArmor)var5.getItem()).damageReduceAmount;
    1062                    var1 += var6;
    1063                }
    1064            }
    1065
    1066            return var1;
    1067        }
    1068
    1069        protected void damageArmor(int par1) {}
    1070
    1071        /**
    1072         * Reduces damage, depending on armor
    1073         */
    1074        protected int applyArmorCalculations(DamageSource par1DamageSource, int par2)
    1075        {
    1076            if (!par1DamageSource.isUnblockable())
    1077            {
    1078                int var3 = 25 - this.getTotalArmorValue();
    1079                int var4 = par2 * var3 + this.carryoverDamage;
    1080                this.damageArmor(par2);
    1081                par2 = var4 / 25;
    1082                this.carryoverDamage = var4 % 25;
    1083            }
    1084
    1085            return par2;
    1086        }
    1087
    1088        /**
    1089         * Reduces damage, depending on potions
    1090         */
    1091        protected int applyPotionDamageCalculations(DamageSource par1DamageSource, int par2)
    1092        {
    1093            if (this.isPotionActive(Potion.resistance))
    1094            {
    1095                int var3 = (this.getActivePotionEffect(Potion.resistance).getAmplifier() + 1) * 5;
    1096                int var4 = 25 - var3;
    1097                int var5 = par2 * var4 + this.carryoverDamage;
    1098                par2 = var5 / 25;
    1099                this.carryoverDamage = var5 % 25;
    1100            }
    1101
    1102            return par2;
    1103        }
    1104
    1105        /**
    1106         * Deals damage to the entity. If its a EntityPlayer then will take damage from the armor first and then health
    1107         * second with the reduced value. Args: damageAmount
    1108         */
    1109        protected void damageEntity(DamageSource par1DamageSource, int par2)
    1110        {
    1111            par2 = ForgeHooks.onLivingHurt(this, par1DamageSource, par2);
    1112            if (par2 <= 0)
    1113            {
    1114                return;
    1115            }
    1116
    1117            par2 = this.applyArmorCalculations(par1DamageSource, par2);
    1118            par2 = this.applyPotionDamageCalculations(par1DamageSource, par2);
    1119            this.health -= par2;
    1120        }
    1121
    1122        /**
    1123         * Returns the volume for the sounds this mob makes.
    1124         */
    1125        protected float getSoundVolume()
    1126        {
    1127            return 1.0F;
    1128        }
    1129
    1130        /**
    1131         * Returns the sound this mob makes while it's alive.
    1132         */
    1133        protected String getLivingSound()
    1134        {
    1135            return null;
    1136        }
    1137
    1138        /**
    1139         * Returns the sound this mob makes when it is hurt.
    1140         */
    1141        protected String getHurtSound()
    1142        {
    1143            return "damage.hit";
    1144        }
    1145
    1146        /**
    1147         * Returns the sound this mob makes on death.
    1148         */
    1149        protected String getDeathSound()
    1150        {
    1151            return "damage.hit";
    1152        }
    1153
    1154        /**
    1155         * knocks back this entity
    1156         */
    1157        public void knockBack(Entity par1Entity, int par2, double par3, double par5)
    1158        {
    1159            this.isAirBorne = true;
    1160            float var7 = MathHelper.sqrt_double(par3 * par3 + par5 * par5);
    1161            float var8 = 0.4F;
    1162            this.motionX /= 2.0D;
    1163            this.motionY /= 2.0D;
    1164            this.motionZ /= 2.0D;
    1165            this.motionX -= par3 / (double)var7 * (double)var8;
    1166            this.motionY += (double)var8;
    1167            this.motionZ -= par5 / (double)var7 * (double)var8;
    1168
    1169            if (this.motionY > 0.4000000059604645D)
    1170            {
    1171                this.motionY = 0.4000000059604645D;
    1172            }
    1173        }
    1174
    1175        /**
    1176         * Called when the mob's health reaches 0.
    1177         */
    1178        public void onDeath(DamageSource par1DamageSource)
    1179        {
    1180            if (ForgeHooks.onLivingDeath(this, par1DamageSource))
    1181            {
    1182                return;
    1183            }
    1184
    1185            Entity var2 = par1DamageSource.getEntity();
    1186
    1187            if (this.scoreValue >= 0 && var2 != null)
    1188            {
    1189                var2.addToPlayerScore(this, this.scoreValue);
    1190            }
    1191
    1192            if (var2 != null)
    1193            {
    1194                var2.onKillEntity(this);
    1195            }
    1196
    1197            this.dead = true;
    1198
    1199            if (!this.worldObj.isRemote)
    1200            {
    1201                int var3 = 0;
    1202
    1203                if (var2 instanceof EntityPlayer)
    1204                {
    1205                    var3 = EnchantmentHelper.getLootingModifier((EntityLiving)var2);
    1206                }
    1207
    1208                captureDrops = true;
    1209                capturedDrops.clear();
    1210                int var4 = 0;
    1211
    1212                if (!this.isChild() && this.worldObj.func_82736_K().func_82766_b("doMobLoot"))
    1213                {
    1214                    this.dropFewItems(this.recentlyHit > 0, var3);
    1215                    this.func_82160_b(this.recentlyHit > 0, var3);
    1216
    1217                    if (this.recentlyHit > 0)
    1218                    {
    1219                        var4 = this.rand.nextInt(200) - var3;
    1220
    1221                        if (var4 < 5)
    1222                        {
    1223                            this.dropRareDrop(var4 <= 0 ? 1 : 0);
    1224                        }
    1225                    }
    1226                }
    1227
    1228                captureDrops = false;
    1229
    1230                if (!ForgeHooks.onLivingDrops(this, par1DamageSource, capturedDrops, var3, recentlyHit > 0, var4))
    1231                {
    1232                    for (EntityItem item : capturedDrops)
    1233                    {
    1234                        worldObj.spawnEntityInWorld(item);
    1235                    }
    1236                }
    1237            }
    1238
    1239            this.worldObj.setEntityState(this, (byte)3);
    1240        }
    1241
    1242        protected void dropRareDrop(int par1) {}
    1243
    1244        /**
    1245         * Drop 0-2 items of this living's type
    1246         */
    1247        protected void dropFewItems(boolean par1, int par2)
    1248        {
    1249            int var3 = this.getDropItemId();
    1250
    1251            if (var3 > 0)
    1252            {
    1253                int var4 = this.rand.nextInt(3);
    1254
    1255                if (par2 > 0)
    1256                {
    1257                    var4 += this.rand.nextInt(par2 + 1);
    1258                }
    1259
    1260                for (int var5 = 0; var5 < var4; ++var5)
    1261                {
    1262                    this.dropItem(var3, 1);
    1263                }
    1264            }
    1265        }
    1266
    1267        /**
    1268         * Returns the item ID for the item the mob drops on death.
    1269         */
    1270        protected int getDropItemId()
    1271        {
    1272            return 0;
    1273        }
    1274
    1275        /**
    1276         * Called when the mob is falling. Calculates and applies fall damage.
    1277         */
    1278        protected void fall(float par1)
    1279        {
    1280            par1 = ForgeHooks.onLivingFall(this, par1);
    1281            if (par1 <= 0)
    1282            {
    1283                return;
    1284            }
    1285
    1286            super.fall(par1);
    1287            int var2 = MathHelper.ceiling_float_int(par1 - 3.0F);
    1288
    1289            if (var2 > 0)
    1290            {
    1291                if (var2 > 4)
    1292                {
    1293                    this.worldObj.playSoundAtEntity(this, "damage.fallbig", 1.0F, 1.0F);
    1294                }
    1295                else
    1296                {
    1297                    this.worldObj.playSoundAtEntity(this, "damage.fallsmall", 1.0F, 1.0F);
    1298                }
    1299
    1300                this.attackEntityFrom(DamageSource.fall, var2);
    1301                int var3 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY - 0.20000000298023224D - (double)this.yOffset), MathHelper.floor_double(this.posZ));
    1302
    1303                if (var3 > 0)
    1304                {
    1305                    StepSound var4 = Block.blocksList[var3].stepSound;
    1306                    this.worldObj.playSoundAtEntity(this, var4.getStepSound(), var4.getVolume() * 0.5F, var4.getPitch() * 0.75F);
    1307                }
    1308            }
    1309        }
    1310
    1311        /**
    1312         * Moves the entity based on the specified heading.  Args: strafe, forward
    1313         */
    1314        public void moveEntityWithHeading(float par1, float par2)
    1315        {
    1316            double var9;
    1317
    1318            if (this.isInWater() && (!(this instanceof EntityPlayer) || !((EntityPlayer)this).capabilities.isFlying))
    1319            {
    1320                var9 = this.posY;
    1321                this.moveFlying(par1, par2, this.isAIEnabled() ? 0.04F : 0.02F);
    1322                this.moveEntity(this.motionX, this.motionY, this.motionZ);
    1323                this.motionX *= 0.800000011920929D;
    1324                this.motionY *= 0.800000011920929D;
    1325                this.motionZ *= 0.800000011920929D;
    1326                this.motionY -= 0.02D;
    1327
    1328                if (this.isCollidedHorizontally && this.isOffsetPositionInLiquid(this.motionX, this.motionY + 0.6000000238418579D - this.posY + var9, this.motionZ))
    1329                {
    1330                    this.motionY = 0.30000001192092896D;
    1331                }
    1332            }
    1333            else if (this.handleLavaMovement() && (!(this instanceof EntityPlayer) || !((EntityPlayer)this).capabilities.isFlying))
    1334            {
    1335                var9 = this.posY;
    1336                this.moveFlying(par1, par2, 0.02F);
    1337                this.moveEntity(this.motionX, this.motionY, this.motionZ);
    1338                this.motionX *= 0.5D;
    1339                this.motionY *= 0.5D;
    1340                this.motionZ *= 0.5D;
    1341                this.motionY -= 0.02D;
    1342
    1343                if (this.isCollidedHorizontally && this.isOffsetPositionInLiquid(this.motionX, this.motionY + 0.6000000238418579D - this.posY + var9, this.motionZ))
    1344                {
    1345                    this.motionY = 0.30000001192092896D;
    1346                }
    1347            }
    1348            else
    1349            {
    1350                float var3 = 0.91F;
    1351
    1352                if (this.onGround)
    1353                {
    1354                    var3 = 0.54600006F;
    1355                    int var4 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ));
    1356
    1357                    if (var4 > 0)
    1358                    {
    1359                        var3 = Block.blocksList[var4].slipperiness * 0.91F;
    1360                    }
    1361                }
    1362
    1363                float var8 = 0.16277136F / (var3 * var3 * var3);
    1364                float var5;
    1365
    1366                if (this.onGround)
    1367                {
    1368                    if (this.isAIEnabled())
    1369                    {
    1370                        var5 = this.getAIMoveSpeed();
    1371                    }
    1372                    else
    1373                    {
    1374                        var5 = this.landMovementFactor;
    1375                    }
    1376
    1377                    var5 *= var8;
    1378                }
    1379                else
    1380                {
    1381                    var5 = this.jumpMovementFactor;
    1382                }
    1383
    1384                this.moveFlying(par1, par2, var5);
    1385                var3 = 0.91F;
    1386
    1387                if (this.onGround)
    1388                {
    1389                    var3 = 0.54600006F;
    1390                    int var6 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ));
    1391
    1392                    if (var6 > 0)
    1393                    {
    1394                        var3 = Block.blocksList[var6].slipperiness * 0.91F;
    1395                    }
    1396                }
    1397
    1398                if (this.isOnLadder())
    1399                {
    1400                    float var10 = 0.15F;
    1401
    1402                    if (this.motionX < (double)(-var10))
    1403                    {
    1404                        this.motionX = (double)(-var10);
    1405                    }
    1406
    1407                    if (this.motionX > (double)var10)
    1408                    {
    1409                        this.motionX = (double)var10;
    1410                    }
    1411
    1412                    if (this.motionZ < (double)(-var10))
    1413                    {
    1414                        this.motionZ = (double)(-var10);
    1415                    }
    1416
    1417                    if (this.motionZ > (double)var10)
    1418                    {
    1419                        this.motionZ = (double)var10;
    1420                    }
    1421
    1422                    this.fallDistance = 0.0F;
    1423
    1424                    if (this.motionY < -0.15D)
    1425                    {
    1426                        this.motionY = -0.15D;
    1427                    }
    1428
    1429                    boolean var7 = this.isSneaking() && this instanceof EntityPlayer;
    1430
    1431                    if (var7 && this.motionY < 0.0D)
    1432                    {
    1433                        this.motionY = 0.0D;
    1434                    }
    1435                }
    1436
    1437                this.moveEntity(this.motionX, this.motionY, this.motionZ);
    1438
    1439                if (this.isCollidedHorizontally && this.isOnLadder())
    1440                {
    1441                    this.motionY = 0.2D;
    1442                }
    1443
    1444                this.motionY -= 0.08D;
    1445                this.motionY *= 0.9800000190734863D;
    1446                this.motionX *= (double)var3;
    1447                this.motionZ *= (double)var3;
    1448            }
    1449
    1450            this.prevLegYaw = this.legYaw;
    1451            var9 = this.posX - this.prevPosX;
    1452            double var12 = this.posZ - this.prevPosZ;
    1453            float var11 = MathHelper.sqrt_double(var9 * var9 + var12 * var12) * 4.0F;
    1454
    1455            if (var11 > 1.0F)
    1456            {
    1457                var11 = 1.0F;
    1458            }
    1459
    1460            this.legYaw += (var11 - this.legYaw) * 0.4F;
    1461            this.legSwing += this.legYaw;
    1462        }
    1463
    1464        /**
    1465         * returns true if this entity is by a ladder, false otherwise
    1466         */
    1467        public boolean isOnLadder()
    1468        {
    1469            int var1 = MathHelper.floor_double(this.posX);
    1470            int var2 = MathHelper.floor_double(this.boundingBox.minY);
    1471            int var3 = MathHelper.floor_double(this.posZ);
    1472            int var4 = this.worldObj.getBlockId(var1, var2, var3);
    1473            return ForgeHooks.isLivingOnLadder(Block.blocksList[var4], worldObj, var1, var2, var3);
    1474        }
    1475
    1476        /**
    1477         * (abstract) Protected helper method to write subclass entity data to NBT.
    1478         */
    1479        public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
    1480        {
    1481            par1NBTTagCompound.setShort("Health", (short)this.health);
    1482            par1NBTTagCompound.setShort("HurtTime", (short)this.hurtTime);
    1483            par1NBTTagCompound.setShort("DeathTime", (short)this.deathTime);
    1484            par1NBTTagCompound.setShort("AttackTime", (short)this.attackTime);
    1485            par1NBTTagCompound.setBoolean("CanPickUpLoot", this.field_82172_bs);
    1486            par1NBTTagCompound.setBoolean("PersistenceRequired", this.field_82179_bU);
    1487            NBTTagList var2 = new NBTTagList();
    1488
    1489            for (int var3 = 0; var3 < this.field_82182_bS.length; ++var3)
    1490            {
    1491                NBTTagCompound var4 = new NBTTagCompound();
    1492
    1493                if (this.field_82182_bS[var3] != null)
    1494                {
    1495                    this.field_82182_bS[var3].writeToNBT(var4);
    1496                }
    1497
    1498                var2.appendTag(var4);
    1499            }
    1500
    1501            par1NBTTagCompound.setTag("Equipment", var2);
    1502            NBTTagList var6;
    1503
    1504            if (!this.activePotionsMap.isEmpty())
    1505            {
    1506                var6 = new NBTTagList();
    1507                Iterator var7 = this.activePotionsMap.values().iterator();
    1508
    1509                while (var7.hasNext())
    1510                {
    1511                    PotionEffect var5 = (PotionEffect)var7.next();
    1512                    var6.appendTag(var5.func_82719_a(new NBTTagCompound()));
    1513                }
    1514
    1515                par1NBTTagCompound.setTag("ActiveEffects", var6);
    1516            }
    1517
    1518            var6 = new NBTTagList();
    1519
    1520            for (int var8 = 0; var8 < this.field_82174_bp.length; ++var8)
    1521            {
    1522                var6.appendTag(new NBTTagFloat(var8 + "", this.field_82174_bp[var8]));
    1523            }
    1524
    1525            par1NBTTagCompound.setTag("DropChances", var6);
    1526        }
    1527
    1528        /**
    1529         * (abstract) Protected helper method to read subclass entity data from NBT.
    1530         */
    1531        public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
    1532        {
    1533            if (this.health < -32768)
    1534            {
    1535                this.health = -32768;
    1536            }
    1537
    1538            this.health = par1NBTTagCompound.getShort("Health");
    1539
    1540            if (!par1NBTTagCompound.hasKey("Health"))
    1541            {
    1542                this.health = this.getMaxHealth();
    1543            }
    1544
    1545            this.hurtTime = par1NBTTagCompound.getShort("HurtTime");
    1546            this.deathTime = par1NBTTagCompound.getShort("DeathTime");
    1547            this.attackTime = par1NBTTagCompound.getShort("AttackTime");
    1548            this.field_82172_bs = par1NBTTagCompound.getBoolean("CanPickUpLoot");
    1549            this.field_82179_bU = par1NBTTagCompound.getBoolean("PersistenceRequired");
    1550            NBTTagList var2;
    1551            int var3;
    1552
    1553            if (par1NBTTagCompound.hasKey("Equipment"))
    1554            {
    1555                var2 = par1NBTTagCompound.getTagList("Equipment");
    1556
    1557                for (var3 = 0; var3 < this.field_82182_bS.length; ++var3)
    1558                {
    1559                    this.field_82182_bS[var3] = ItemStack.loadItemStackFromNBT((NBTTagCompound)var2.tagAt(var3));
    1560                }
    1561            }
    1562
    1563            if (par1NBTTagCompound.hasKey("ActiveEffects"))
    1564            {
    1565                var2 = par1NBTTagCompound.getTagList("ActiveEffects");
    1566
    1567                for (var3 = 0; var3 < var2.tagCount(); ++var3)
    1568                {
    1569                    NBTTagCompound var4 = (NBTTagCompound)var2.tagAt(var3);
    1570                    PotionEffect var5 = PotionEffect.func_82722_b(var4);
    1571                    this.activePotionsMap.put(Integer.valueOf(var5.getPotionID()), var5);
    1572                }
    1573            }
    1574
    1575            if (par1NBTTagCompound.hasKey("DropChances"))
    1576            {
    1577                var2 = par1NBTTagCompound.getTagList("DropChances");
    1578
    1579                for (var3 = 0; var3 < var2.tagCount(); ++var3)
    1580                {
    1581                    this.field_82174_bp[var3] = ((NBTTagFloat)var2.tagAt(var3)).data;
    1582                }
    1583            }
    1584        }
    1585
    1586        /**
    1587         * Checks whether target entity is alive.
    1588         */
    1589        public boolean isEntityAlive()
    1590        {
    1591            return !this.isDead && this.health > 0;
    1592        }
    1593
    1594        public boolean canBreatheUnderwater()
    1595        {
    1596            return false;
    1597        }
    1598
    1599        public void setMoveForward(float par1)
    1600        {
    1601            this.moveForward = par1;
    1602        }
    1603
    1604        public void setJumping(boolean par1)
    1605        {
    1606            this.isJumping = par1;
    1607        }
    1608
    1609        /**
    1610         * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
    1611         * use this to react to sunlight and start to burn.
    1612         */
    1613        public void onLivingUpdate()
    1614        {
    1615            if (this.jumpTicks > 0)
    1616            {
    1617                --this.jumpTicks;
    1618            }
    1619
    1620            if (this.newPosRotationIncrements > 0)
    1621            {
    1622                double var1 = this.posX + (this.newPosX - this.posX) / (double)this.newPosRotationIncrements;
    1623                double var3 = this.posY + (this.newPosY - this.posY) / (double)this.newPosRotationIncrements;
    1624                double var5 = this.posZ + (this.newPosZ - this.posZ) / (double)this.newPosRotationIncrements;
    1625                double var7 = MathHelper.wrapAngleTo180_double(this.newRotationYaw - (double)this.rotationYaw);
    1626                this.rotationYaw = (float)((double)this.rotationYaw + var7 / (double)this.newPosRotationIncrements);
    1627                this.rotationPitch = (float)((double)this.rotationPitch + (this.newRotationPitch - (double)this.rotationPitch) / (double)this.newPosRotationIncrements);
    1628                --this.newPosRotationIncrements;
    1629                this.setPosition(var1, var3, var5);
    1630                this.setRotation(this.rotationYaw, this.rotationPitch);
    1631            }
    1632
    1633            if (Math.abs(this.motionX) < 0.005D)
    1634            {
    1635                this.motionX = 0.0D;
    1636            }
    1637
    1638            if (Math.abs(this.motionY) < 0.005D)
    1639            {
    1640                this.motionY = 0.0D;
    1641            }
    1642
    1643            if (Math.abs(this.motionZ) < 0.005D)
    1644            {
    1645                this.motionZ = 0.0D;
    1646            }
    1647
    1648            this.worldObj.theProfiler.startSection("ai");
    1649
    1650            if (this.isMovementBlocked())
    1651            {
    1652                this.isJumping = false;
    1653                this.moveStrafing = 0.0F;
    1654                this.moveForward = 0.0F;
    1655                this.randomYawVelocity = 0.0F;
    1656            }
    1657            else if (this.isClientWorld())
    1658            {
    1659                if (this.isAIEnabled())
    1660                {
    1661                    this.worldObj.theProfiler.startSection("newAi");
    1662                    this.updateAITasks();
    1663                    this.worldObj.theProfiler.endSection();
    1664                }
    1665                else
    1666                {
    1667                    this.worldObj.theProfiler.startSection("oldAi");
    1668                    this.updateEntityActionState();
    1669                    this.worldObj.theProfiler.endSection();
    1670                    this.rotationYawHead = this.rotationYaw;
    1671                }
    1672            }
    1673
    1674            this.worldObj.theProfiler.endSection();
    1675            this.worldObj.theProfiler.startSection("jump");
    1676
    1677            if (this.isJumping)
    1678            {
    1679                if (!this.isInWater() && !this.handleLavaMovement())
    1680                {
    1681                    if (this.onGround && this.jumpTicks == 0)
    1682                    {
    1683                        this.jump();
    1684                        this.jumpTicks = 10;
    1685                    }
    1686                }
    1687                else
    1688                {
    1689                    this.motionY += 0.03999999910593033D;
    1690                }
    1691            }
    1692            else
    1693            {
    1694                this.jumpTicks = 0;
    1695            }
    1696
    1697            this.worldObj.theProfiler.endSection();
    1698            this.worldObj.theProfiler.startSection("travel");
    1699            this.moveStrafing *= 0.98F;
    1700            this.moveForward *= 0.98F;
    1701            this.randomYawVelocity *= 0.9F;
    1702            float var11 = this.landMovementFactor;
    1703            this.landMovementFactor *= this.getSpeedModifier();
    1704            this.moveEntityWithHeading(this.moveStrafing, this.moveForward);
    1705            this.landMovementFactor = var11;
    1706            this.worldObj.theProfiler.endSection();
    1707            this.worldObj.theProfiler.startSection("push");
    1708            List var2;
    1709            Iterator var12;
    1710
    1711            if (!this.worldObj.isRemote)
    1712            {
    1713                var2 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D));
    1714
    1715                if (var2 != null && !var2.isEmpty())
    1716                {
    1717                    var12 = var2.iterator();
    1718
    1719                    while (var12.hasNext())
    1720                    {
    1721                        Entity var4 = (Entity)var12.next();
    1722
    1723                        if (var4.canBePushed())
    1724                        {
    1725                            this.func_82167_n(var4);
    1726                        }
    1727                    }
    1728                }
    1729            }
    1730
    1731            this.worldObj.theProfiler.endSection();
    1732            this.worldObj.theProfiler.startSection("looting");
    1733
    1734            if (!this.worldObj.isRemote && this.field_82172_bs)
    1735            {
    1736                var2 = this.worldObj.getEntitiesWithinAABB(EntityItem.class, this.boundingBox.expand(1.0D, 0.0D, 1.0D));
    1737                var12 = var2.iterator();
    1738
    1739                while (var12.hasNext())
    1740                {
    1741                    EntityItem var13 = (EntityItem)var12.next();
    1742
    1743                    if (!var13.isDead && var13.item != null)
    1744                    {
    1745                        ItemStack var14 = var13.item;
    1746                        int var6 = func_82159_b(var14);
    1747
    1748                        if (var6 > -1)
    1749                        {
    1750                            boolean var15 = true;
    1751                            ItemStack var8 = this.getCurrentItemOrArmor(var6);
    1752
    1753                            if (var8 != null)
    1754                            {
    1755                                if (var6 == 0)
    1756                                {
    1757                                    if (var14.getItem() instanceof ItemSword && !(var8.getItem() instanceof ItemSword))
    1758                                    {
    1759                                        var15 = true;
    1760                                    }
    1761                                    else if (var14.getItem() instanceof ItemSword && var8.getItem() instanceof ItemSword)
    1762                                    {
    1763                                        ItemSword var9 = (ItemSword)var14.getItem();
    1764                                        ItemSword var10 = (ItemSword)var8.getItem();
    1765
    1766                                        if (var9.func_82803_g() == var10.func_82803_g())
    1767                                        {
    1768                                            var15 = var14.getItemDamage() > var8.getItemDamage() || var14.hasTagCompound() && !var8.hasTagCompound();
    1769                                        }
    1770                                        else
    1771                                        {
    1772                                            var15 = var9.func_82803_g() > var10.func_82803_g();
    1773                                        }
    1774                                    }
    1775                                    else
    1776                                    {
    1777                                        var15 = false;
    1778                                    }
    1779                                }
    1780                                else if (var14.getItem() instanceof ItemArmor && !(var8.getItem() instanceof ItemArmor))
    1781                                {
    1782                                    var15 = true;
    1783                                }
    1784                                else if (var14.getItem() instanceof ItemArmor && var8.getItem() instanceof ItemArmor)
    1785                                {
    1786                                    ItemArmor var16 = (ItemArmor)var14.getItem();
    1787                                    ItemArmor var17 = (ItemArmor)var8.getItem();
    1788
    1789                                    if (var16.damageReduceAmount == var17.damageReduceAmount)
    1790                                    {
    1791                                        var15 = var14.getItemDamage() > var8.getItemDamage() || var14.hasTagCompound() && !var8.hasTagCompound();
    1792                                    }
    1793                                    else
    1794                                    {
    1795                                        var15 = var16.damageReduceAmount > var17.damageReduceAmount;
    1796                                    }
    1797                                }
    1798                                else
    1799                                {
    1800                                    var15 = false;
    1801                                }
    1802                            }
    1803
    1804                            if (var15)
    1805                            {
    1806                                if (var8 != null && this.rand.nextFloat() - 0.1F < this.field_82174_bp[var6])
    1807                                {
    1808                                    this.entityDropItem(var8, 0.0F);
    1809                                }
    1810
    1811                                this.func_70062_b(var6, var14);
    1812                                this.field_82174_bp[var6] = 2.0F;
    1813                                this.onItemPickup(var13, 1);
    1814                                var13.setDead();
    1815                            }
    1816                        }
    1817                    }
    1818                }
    1819            }
    1820
    1821            this.worldObj.theProfiler.endSection();
    1822        }
    1823
    1824        protected void func_82167_n(Entity par1Entity)
    1825        {
    1826            par1Entity.applyEntityCollision(this);
    1827        }
    1828
    1829        /**
    1830         * Returns true if the newer Entity AI code should be run
    1831         */
    1832        protected boolean isAIEnabled()
    1833        {
    1834            return false;
    1835        }
    1836
    1837        /**
    1838         * Returns whether the entity is in a local (client) world
    1839         */
    1840        protected boolean isClientWorld()
    1841        {
    1842            return !this.worldObj.isRemote;
    1843        }
    1844
    1845        /**
    1846         * Dead and sleeping entities cannot move
    1847         */
    1848        protected boolean isMovementBlocked()
    1849        {
    1850            return this.health <= 0;
    1851        }
    1852
    1853        public boolean isBlocking()
    1854        {
    1855            return false;
    1856        }
    1857
    1858        /**
    1859         * Causes this entity to do an upwards motion (jumping).
    1860         */
    1861        protected void jump()
    1862        {
    1863            this.motionY = 0.41999998688697815D;
    1864
    1865            if (this.isPotionActive(Potion.jump))
    1866            {
    1867                this.motionY += (double)((float)(this.getActivePotionEffect(Potion.jump).getAmplifier() + 1) * 0.1F);
    1868            }
    1869
    1870            if (this.isSprinting())
    1871            {
    1872                float var1 = this.rotationYaw * 0.017453292F;
    1873                this.motionX -= (double)(MathHelper.sin(var1) * 0.2F);
    1874                this.motionZ += (double)(MathHelper.cos(var1) * 0.2F);
    1875            }
    1876
    1877            this.isAirBorne = true;
    1878            ForgeHooks.onLivingJump(this);
    1879        }
    1880
    1881        /**
    1882         * Determines if an entity can be despawned, used on idle far away entities
    1883         */
    1884        protected boolean canDespawn()
    1885        {
    1886            return true;
    1887        }
    1888
    1889        /**
    1890         * Makes the entity despawn if requirements are reached
    1891         */
    1892        protected void despawnEntity()
    1893        {
    1894            if (!this.field_82179_bU)
    1895            {
    1896                EntityPlayer var1 = this.worldObj.getClosestPlayerToEntity(this, -1.0D);
    1897
    1898                if (var1 != null)
    1899                {
    1900                    double var2 = var1.posX - this.posX;
    1901                    double var4 = var1.posY - this.posY;
    1902                    double var6 = var1.posZ - this.posZ;
    1903                    double var8 = var2 * var2 + var4 * var4 + var6 * var6;
    1904
    1905                    if (this.canDespawn() && var8 > 16384.0D)
    1906                    {
    1907                        this.setDead();
    1908                    }
    1909
    1910                    if (this.entityAge > 600 && this.rand.nextInt(800) == 0 && var8 > 1024.0D && this.canDespawn())
    1911                    {
    1912                        this.setDead();
    1913                    }
    1914                    else if (var8 < 1024.0D)
    1915                    {
    1916                        this.entityAge = 0;
    1917                    }
    1918                }
    1919            }
    1920        }
    1921
    1922        protected void updateAITasks()
    1923        {
    1924            ++this.entityAge;
    1925            this.worldObj.theProfiler.startSection("checkDespawn");
    1926            this.despawnEntity();
    1927            this.worldObj.theProfiler.endSection();
    1928            this.worldObj.theProfiler.startSection("sensing");
    1929            this.senses.clearSensingCache();
    1930            this.worldObj.theProfiler.endSection();
    1931            this.worldObj.theProfiler.startSection("targetSelector");
    1932            this.targetTasks.onUpdateTasks();
    1933            this.worldObj.theProfiler.endSection();
    1934            this.worldObj.theProfiler.startSection("goalSelector");
    1935            this.tasks.onUpdateTasks();
    1936            this.worldObj.theProfiler.endSection();
    1937            this.worldObj.theProfiler.startSection("navigation");
    1938            this.navigator.onUpdateNavigation();
    1939            this.worldObj.theProfiler.endSection();
    1940            this.worldObj.theProfiler.startSection("mob tick");
    1941            this.updateAITick();
    1942            this.worldObj.theProfiler.endSection();
    1943            this.worldObj.theProfiler.startSection("controls");
    1944            this.worldObj.theProfiler.startSection("move");
    1945            this.moveHelper.onUpdateMoveHelper();
    1946            this.worldObj.theProfiler.endStartSection("look");
    1947            this.lookHelper.onUpdateLook();
    1948            this.worldObj.theProfiler.endStartSection("jump");
    1949            this.jumpHelper.doJump();
    1950            this.worldObj.theProfiler.endSection();
    1951            this.worldObj.theProfiler.endSection();
    1952        }
    1953
    1954        /**
    1955         * main AI tick function, replaces updateEntityActionState
    1956         */
    1957        protected void updateAITick() {}
    1958
    1959        protected void updateEntityActionState()
    1960        {
    1961            ++this.entityAge;
    1962            this.despawnEntity();
    1963            this.moveStrafing = 0.0F;
    1964            this.moveForward = 0.0F;
    1965            float var1 = 8.0F;
    1966
    1967            if (this.rand.nextFloat() < 0.02F)
    1968            {
    1969                EntityPlayer var2 = this.worldObj.getClosestPlayerToEntity(this, (double)var1);
    1970
    1971                if (var2 != null)
    1972                {
    1973                    this.currentTarget = var2;
    1974                    this.numTicksToChaseTarget = 10 + this.rand.nextInt(20);
    1975                }
    1976                else
    1977                {
    1978                    this.randomYawVelocity = (this.rand.nextFloat() - 0.5F) * 20.0F;
    1979                }
    1980            }
    1981
    1982            if (this.currentTarget != null)
    1983            {
    1984                this.faceEntity(this.currentTarget, 10.0F, (float)this.getVerticalFaceSpeed());
    1985
    1986                if (this.numTicksToChaseTarget-- <= 0 || this.currentTarget.isDead || this.currentTarget.getDistanceSqToEntity(this) > (double)(var1 * var1))
    1987                {
    1988                    this.currentTarget = null;
    1989                }
    1990            }
    1991            else
    1992            {
    1993                if (this.rand.nextFloat() < 0.05F)
    1994                {
    1995                    this.randomYawVelocity = (this.rand.nextFloat() - 0.5F) * 20.0F;
    1996                }
    1997
    1998                this.rotationYaw += this.randomYawVelocity;
    1999                this.rotationPitch = this.defaultPitch;
    2000            }
    2001
    2002            boolean var4 = this.isInWater();
    2003            boolean var3 = this.handleLavaMovement();
    2004
    2005            if (var4 || var3)
    2006            {
    2007                this.isJumping = this.rand.nextFloat() < 0.8F;
    2008            }
    2009        }
    2010
    2011        protected void func_82168_bl()
    2012        {
    2013            int var1 = this.func_82166_i();
    2014
    2015            if (this.field_82175_bq)
    2016            {
    2017                ++this.field_82173_br;
    2018
    2019                if (this.field_82173_br >= var1)
    2020                {
    2021                    this.field_82173_br = 0;
    2022                    this.field_82175_bq = false;
    2023                }
    2024            }
    2025            else
    2026            {
    2027                this.field_82173_br = 0;
    2028            }
    2029
    2030            this.swingProgress = (float)this.field_82173_br / (float)var1;
    2031        }
    2032
    2033        /**
    2034         * The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently
    2035         * use in wolves.
    2036         */
    2037        public int getVerticalFaceSpeed()
    2038        {
    2039            return 40;
    2040        }
    2041
    2042        /**
    2043         * Changes pitch and yaw so that the entity calling the function is facing the entity provided as an argument.
    2044         */
    2045        public void faceEntity(Entity par1Entity, float par2, float par3)
    2046        {
    2047            double var4 = par1Entity.posX - this.posX;
    2048            double var8 = par1Entity.posZ - this.posZ;
    2049            double var6;
    2050
    2051            if (par1Entity instanceof EntityLiving)
    2052            {
    2053                EntityLiving var10 = (EntityLiving)par1Entity;
    2054                var6 = this.posY + (double)this.getEyeHeight() - (var10.posY + (double)var10.getEyeHeight());
    2055            }
    2056            else
    2057            {
    2058                var6 = (par1Entity.boundingBox.minY + par1Entity.boundingBox.maxY) / 2.0D - (this.posY + (double)this.getEyeHeight());
    2059            }
    2060
    2061            double var14 = (double)MathHelper.sqrt_double(var4 * var4 + var8 * var8);
    2062            float var12 = (float)(Math.atan2(var8, var4) * 180.0D / Math.PI) - 90.0F;
    2063            float var13 = (float)(-(Math.atan2(var6, var14) * 180.0D / Math.PI));
    2064            this.rotationPitch = -this.updateRotation(this.rotationPitch, var13, par3);
    2065            this.rotationYaw = this.updateRotation(this.rotationYaw, var12, par2);
    2066        }
    2067
    2068        /**
    2069         * Arguments: current rotation, intended rotation, max increment.
    2070         */
    2071        private float updateRotation(float par1, float par2, float par3)
    2072        {
    2073            float var4 = MathHelper.wrapAngleTo180_float(par2 - par1);
    2074
    2075            if (var4 > par3)
    2076            {
    2077                var4 = par3;
    2078            }
    2079
    2080            if (var4 < -par3)
    2081            {
    2082                var4 = -par3;
    2083            }
    2084
    2085            return par1 + var4;
    2086        }
    2087
    2088        /**
    2089         * Checks if the entity's current position is a valid location to spawn this entity.
    2090         */
    2091        public boolean getCanSpawnHere()
    2092        {
    2093            return this.worldObj.checkIfAABBIsClear(this.boundingBox) && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(this.boundingBox);
    2094        }
    2095
    2096        /**
    2097         * sets the dead flag. Used when you fall off the bottom of the world.
    2098         */
    2099        protected void kill()
    2100        {
    2101            this.attackEntityFrom(DamageSource.outOfWorld, 4);
    2102        }
    2103
    2104        @SideOnly(Side.CLIENT)
    2105
    2106        /**
    2107         * Returns where in the swing animation the living entity is (from 0 to 1).  Args: partialTickTime
    2108         */
    2109        public float getSwingProgress(float par1)
    2110        {
    2111            float var2 = this.swingProgress - this.prevSwingProgress;
    2112
    2113            if (var2 < 0.0F)
    2114            {
    2115                ++var2;
    2116            }
    2117
    2118            return this.prevSwingProgress + var2 * par1;
    2119        }
    2120
    2121        @SideOnly(Side.CLIENT)
    2122
    2123        /**
    2124         * interpolated position vector
    2125         */
    2126        public Vec3 getPosition(float par1)
    2127        {
    2128            if (par1 == 1.0F)
    2129            {
    2130                return this.worldObj.func_82732_R().getVecFromPool(this.posX, this.posY, this.posZ);
    2131            }
    2132            else
    2133            {
    2134                double var2 = this.prevPosX + (this.posX - this.prevPosX) * (double)par1;
    2135                double var4 = this.prevPosY + (this.posY - this.prevPosY) * (double)par1;
    2136                double var6 = this.prevPosZ + (this.posZ - this.prevPosZ) * (double)par1;
    2137                return this.worldObj.func_82732_R().getVecFromPool(var2, var4, var6);
    2138            }
    2139        }
    2140
    2141        /**
    2142         * returns a (normalized) vector of where this entity is looking
    2143         */
    2144        public Vec3 getLookVec()
    2145        {
    2146            return this.getLook(1.0F);
    2147        }
    2148
    2149        /**
    2150         * interpolated look vector
    2151         */
    2152        public Vec3 getLook(float par1)
    2153        {
    2154            float var2;
    2155            float var3;
    2156            float var4;
    2157            float var5;
    2158
    2159            if (par1 == 1.0F)
    2160            {
    2161                var2 = MathHelper.cos(-this.rotationYaw * 0.017453292F - (float)Math.PI);
    2162                var3 = MathHelper.sin(-this.rotationYaw * 0.017453292F - (float)Math.PI);
    2163                var4 = -MathHelper.cos(-this.rotationPitch * 0.017453292F);
    2164                var5 = MathHelper.sin(-this.rotationPitch * 0.017453292F);
    2165                return this.worldObj.func_82732_R().getVecFromPool((double)(var3 * var4), (double)var5, (double)(var2 * var4));
    2166            }
    2167            else
    2168            {
    2169                var2 = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * par1;
    2170                var3 = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * par1;
    2171                var4 = MathHelper.cos(-var3 * 0.017453292F - (float)Math.PI);
    2172                var5 = MathHelper.sin(-var3 * 0.017453292F - (float)Math.PI);
    2173                float var6 = -MathHelper.cos(-var2 * 0.017453292F);
    2174                float var7 = MathHelper.sin(-var2 * 0.017453292F);
    2175                return this.worldObj.func_82732_R().getVecFromPool((double)(var5 * var6), (double)var7, (double)(var4 * var6));
    2176            }
    2177        }
    2178
    2179        @SideOnly(Side.CLIENT)
    2180
    2181        /**
    2182         * Returns render size modifier
    2183         */
    2184        public float getRenderSizeModifier()
    2185        {
    2186            return 1.0F;
    2187        }
    2188
    2189        @SideOnly(Side.CLIENT)
    2190
    2191        /**
    2192         * Performs a ray trace for the distance specified and using the partial tick time. Args: distance, partialTickTime
    2193         */
    2194        public MovingObjectPosition rayTrace(double par1, float par3)
    2195        {
    2196            Vec3 var4 = this.getPosition(par3);
    2197            Vec3 var5 = this.getLook(par3);
    2198            Vec3 var6 = var4.addVector(var5.xCoord * par1, var5.yCoord * par1, var5.zCoord * par1);
    2199            return this.worldObj.rayTraceBlocks(var4, var6);
    2200        }
    2201
    2202        /**
    2203         * Will return how many at most can spawn in a chunk at once.
    2204         */
    2205        public int getMaxSpawnedInChunk()
    2206        {
    2207            return 4;
    2208        }
    2209
    2210        @SideOnly(Side.CLIENT)
    2211        public void handleHealthUpdate(byte par1)
    2212        {
    2213            if (par1 == 2)
    2214            {
    2215                this.legYaw = 1.5F;
    2216                this.hurtResistantTime = this.maxHurtResistantTime;
    2217                this.hurtTime = this.maxHurtTime = 10;
    2218                this.attackedAtYaw = 0.0F;
    2219                this.worldObj.playSoundAtEntity(this, this.getHurtSound(), this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
    2220                this.attackEntityFrom(DamageSource.generic, 0);
    2221            }
    2222            else if (par1 == 3)
    2223            {
    2224                this.worldObj.playSoundAtEntity(this, this.getDeathSound(), this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
    2225                this.health = 0;
    2226                this.onDeath(DamageSource.generic);
    2227            }
    2228            else
    2229            {
    2230                super.handleHealthUpdate(par1);
    2231            }
    2232        }
    2233
    2234        /**
    2235         * Returns whether player is sleeping or not
    2236         */
    2237        public boolean isPlayerSleeping()
    2238        {
    2239            return false;
    2240        }
    2241
    2242        @SideOnly(Side.CLIENT)
    2243
    2244        /**
    2245         * Gets the Icon Index of the item currently held
    2246         */
    2247        public int getItemIcon(ItemStack par1ItemStack, int par2)
    2248        {
    2249            return par1ItemStack.getIconIndex();
    2250        }
    2251
    2252        protected void updatePotionEffects()
    2253        {
    2254            Iterator var1 = this.activePotionsMap.keySet().iterator();
    2255
    2256            while (var1.hasNext())
    2257            {
    2258                Integer var2 = (Integer)var1.next();
    2259                PotionEffect var3 = (PotionEffect)this.activePotionsMap.get(var2);
    2260
    2261                if (!var3.onUpdate(this) && !this.worldObj.isRemote)
    2262                {
    2263                    var1.remove();
    2264                    this.onFinishedPotionEffect(var3);
    2265                }
    2266            }
    2267
    2268            int var11;
    2269
    2270            if (this.potionsNeedUpdate)
    2271            {
    2272                if (!this.worldObj.isRemote)
    2273                {
    2274                    if (this.activePotionsMap.isEmpty())
    2275                    {
    2276                        this.dataWatcher.updateObject(9, Byte.valueOf((byte)0));
    2277                        this.dataWatcher.updateObject(8, Integer.valueOf(0));
    2278                        this.func_82142_c(false);
    2279                    }
    2280                    else
    2281                    {
    2282                        var11 = PotionHelper.calcPotionLiquidColor(this.activePotionsMap.values());
    2283                        this.dataWatcher.updateObject(9, Byte.valueOf((byte)(PotionHelper.func_82817_b(this.activePotionsMap.values()) ? 1 : 0)));
    2284                        this.dataWatcher.updateObject(8, Integer.valueOf(var11));
    2285                        this.func_82142_c(this.func_82165_m(Potion.invisibility.id));
    2286                    }
    2287                }
    2288
    2289                this.potionsNeedUpdate = false;
    2290            }
    2291
    2292            var11 = this.dataWatcher.getWatchableObjectInt(8);
    2293            boolean var12 = this.dataWatcher.getWatchableObjectByte(9) > 0;
    2294
    2295            if (var11 > 0)
    2296            {
    2297                boolean var4 = false;
    2298
    2299                if (!this.func_82150_aj())
    2300                {
    2301                    var4 = this.rand.nextBoolean();
    2302                }
    2303                else
    2304                {
    2305                    var4 = this.rand.nextInt(15) == 0;
    2306                }
    2307
    2308                if (var12)
    2309                {
    2310                    var4 &= this.rand.nextInt(5) == 0;
    2311                }
    2312
    2313                if (var4 && var11 > 0)
    2314                {
    2315                    double var5 = (double)(var11 >> 16 & 255) / 255.0D;
    2316                    double var7 = (double)(var11 >> 8 & 255) / 255.0D;
    2317                    double var9 = (double)(var11 >> 0 & 255) / 255.0D;
    2318                    this.worldObj.spawnParticle(var12 ? "mobSpellAmbient" : "mobSpell", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height - (double)this.yOffset, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, var5, var7, var9);
    2319                }
    2320            }
    2321        }
    2322
    2323        public void clearActivePotions()
    2324        {
    2325            Iterator var1 = this.activePotionsMap.keySet().iterator();
    2326
    2327            while (var1.hasNext())
    2328            {
    2329                Integer var2 = (Integer)var1.next();
    2330                PotionEffect var3 = (PotionEffect)this.activePotionsMap.get(var2);
    2331
    2332                if (!this.worldObj.isRemote)
    2333                {
    2334                    var1.remove();
    2335                    this.onFinishedPotionEffect(var3);
    2336                }
    2337            }
    2338        }
    2339
    2340        public Collection getActivePotionEffects()
    2341        {
    2342            return this.activePotionsMap.values();
    2343        }
    2344
    2345        public boolean func_82165_m(int par1)
    2346        {
    2347            return this.activePotionsMap.containsKey(Integer.valueOf(par1));
    2348        }
    2349
    2350        public boolean isPotionActive(Potion par1Potion)
    2351        {
    2352            return this.activePotionsMap.containsKey(Integer.valueOf(par1Potion.id));
    2353        }
    2354
    2355        /**
    2356         * returns the PotionEffect for the supplied Potion if it is active, null otherwise.
    2357         */
    2358        public PotionEffect getActivePotionEffect(Potion par1Potion)
    2359        {
    2360            return (PotionEffect)this.activePotionsMap.get(Integer.valueOf(par1Potion.id));
    2361        }
    2362
    2363        /**
    2364         * adds a PotionEffect to the entity
    2365         */
    2366        public void addPotionEffect(PotionEffect par1PotionEffect)
    2367        {
    2368            if (this.isPotionApplicable(par1PotionEffect))
    2369            {
    2370                if (this.activePotionsMap.containsKey(Integer.valueOf(par1PotionEffect.getPotionID())))
    2371                {
    2372                    ((PotionEffect)this.activePotionsMap.get(Integer.valueOf(par1PotionEffect.getPotionID()))).combine(par1PotionEffect);
    2373                    this.onChangedPotionEffect((PotionEffect)this.activePotionsMap.get(Integer.valueOf(par1PotionEffect.getPotionID())));
    2374                }
    2375                else
    2376                {
    2377                    this.activePotionsMap.put(Integer.valueOf(par1PotionEffect.getPotionID()), par1PotionEffect);
    2378                    this.onNewPotionEffect(par1PotionEffect);
    2379                }
    2380            }
    2381        }
    2382
    2383        public boolean isPotionApplicable(PotionEffect par1PotionEffect)
    2384        {
    2385            if (this.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD)
    2386            {
    2387                int var2 = par1PotionEffect.getPotionID();
    2388
    2389                if (var2 == Potion.regeneration.id || var2 == Potion.poison.id)
    2390                {
    2391                    return false;
    2392                }
    2393            }
    2394
    2395            return true;
    2396        }
    2397
    2398        /**
    2399         * Returns true if this entity is undead.
    2400         */
    2401        public boolean isEntityUndead()
    2402        {
    2403            return this.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD;
    2404        }
    2405
    2406        /**
    2407         * input is the potion id to remove from the current active potion effects
    2408         */
    2409        public void removePotionEffect(int par1)
    2410        {
    2411            this.activePotionsMap.remove(Integer.valueOf(par1));
    2412        }
    2413
    2414        public void func_82170_o(int par1)
    2415        {
    2416            PotionEffect var2 = (PotionEffect)this.activePotionsMap.remove(Integer.valueOf(par1));
    2417
    2418            if (var2 != null)
    2419            {
    2420                this.onFinishedPotionEffect(var2);
    2421            }
    2422        }
    2423
    2424        protected void onNewPotionEffect(PotionEffect par1PotionEffect)
    2425        {
    2426            this.potionsNeedUpdate = true;
    2427        }
    2428
    2429        protected void onChangedPotionEffect(PotionEffect par1PotionEffect)
    2430        {
    2431            this.potionsNeedUpdate = true;
    2432        }
    2433
    2434        protected void onFinishedPotionEffect(PotionEffect par1PotionEffect)
    2435        {
    2436            this.potionsNeedUpdate = true;
    2437        }
    2438
    2439        /**
    2440         * This method returns a value to be applied directly to entity speed, this factor is less than 1 when a slowdown
    2441         * potion effect is applied, more than 1 when a haste potion effect is applied and 2 for fleeing entities.
    2442         */
    2443        public float getSpeedModifier()
    2444        {
    2445            float var1 = 1.0F;
    2446
    2447            if (this.isPotionActive(Potion.moveSpeed))
    2448            {
    2449                var1 *= 1.0F + 0.2F * (float)(this.getActivePotionEffect(Potion.moveSpeed).getAmplifier() + 1);
    2450            }
    2451
    2452            if (this.isPotionActive(Potion.moveSlowdown))
    2453            {
    2454                var1 *= 1.0F - 0.15F * (float)(this.getActivePotionEffect(Potion.moveSlowdown).getAmplifier() + 1);
    2455            }
    2456
    2457            return var1;
    2458        }
    2459
    2460        /**
    2461         * Move the entity to the coordinates informed, but keep yaw/pitch values.
    2462         */
    2463        public void setPositionAndUpdate(double par1, double par3, double par5)
    2464        {
    2465            this.setLocationAndAngles(par1, par3, par5, this.rotationYaw, this.rotationPitch);
    2466        }
    2467
    2468        /**
    2469         * If Animal, checks if the age timer is negative
    2470         */
    2471        public boolean isChild()
    2472        {
    2473            return false;
    2474        }
    2475
    2476        /**
    2477         * Get this Entity's EnumCreatureAttribute
    2478         */
    2479        public EnumCreatureAttribute getCreatureAttribute()
    2480        {
    2481            return EnumCreatureAttribute.UNDEFINED;
    2482        }
    2483
    2484        /**
    2485         * Renders broken item particles using the given ItemStack
    2486         */
    2487        public void renderBrokenItemStack(ItemStack par1ItemStack)
    2488        {
    2489            this.worldObj.playSoundAtEntity(this, "random.break", 0.8F, 0.8F + this.worldObj.rand.nextFloat() * 0.4F);
    2490
    2491            for (int var2 = 0; var2 < 5; ++var2)
    2492            {
    2493                Vec3 var3 = this.worldObj.func_82732_R().getVecFromPool(((double)this.rand.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D);
    2494                var3.rotateAroundX(-this.rotationPitch * (float)Math.PI / 180.0F);
    2495                var3.rotateAroundY(-this.rotationYaw * (float)Math.PI / 180.0F);
    2496                Vec3 var4 = this.worldObj.func_82732_R().getVecFromPool(((double)this.rand.nextFloat() - 0.5D) * 0.3D, (double)(-this.rand.nextFloat()) * 0.6D - 0.3D, 0.6D);
    2497                var4.rotateAroundX(-this.rotationPitch * (float)Math.PI / 180.0F);
    2498                var4.rotateAroundY(-this.rotationYaw * (float)Math.PI / 180.0F);
    2499                var4 = var4.addVector(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ);
    2500                this.worldObj.spawnParticle("iconcrack_" + par1ItemStack.getItem().shiftedIndex, var4.xCoord, var4.yCoord, var4.zCoord, var3.xCoord, var3.yCoord + 0.05D, var3.zCoord);
    2501            }
    2502        }
    2503
    2504        public int func_82143_as()
    2505        {
    2506            if (this.getAttackTarget() == null)
    2507            {
    2508                return 3;
    2509            }
    2510            else
    2511            {
    2512                int var1 = (int)((float)this.health - (float)this.getMaxHealth() * 0.33F);
    2513                var1 -= (3 - this.worldObj.difficultySetting) * 4;
    2514
    2515                if (var1 < 0)
    2516                {
    2517                    var1 = 0;
    2518                }
    2519
    2520                return var1 + 3;
    2521            }
    2522        }
    2523
    2524        /**
    2525         * Returns the item that this EntityLiving is holding, if any.
    2526         */
    2527        public ItemStack getHeldItem()
    2528        {
    2529            return this.field_82182_bS[0];
    2530        }
    2531
    2532        /**
    2533         * 0 = item, 1-n is armor
    2534         */
    2535        public ItemStack getCurrentItemOrArmor(int par1)
    2536        {
    2537            return this.field_82182_bS[par1];
    2538        }
    2539
    2540        public ItemStack func_82169_q(int par1)
    2541        {
    2542            return this.field_82182_bS[par1 + 1];
    2543        }
    2544
    2545        public void func_70062_b(int par1, ItemStack par2ItemStack)
    2546        {
    2547            this.field_82182_bS[par1] = par2ItemStack;
    2548        }
    2549
    2550        public ItemStack[] getLastActiveItems()
    2551        {
    2552            return this.field_82182_bS;
    2553        }
    2554
    2555        protected void func_82160_b(boolean par1, int par2)
    2556        {
    2557            for (int var3 = 0; var3 < this.getLastActiveItems().length; ++var3)
    2558            {
    2559                ItemStack var4 = this.getCurrentItemOrArmor(var3);
    2560                boolean var5 = this.field_82174_bp[var3] > 1.0F;
    2561
    2562                if (var4 != null && (par1 || var5) && this.rand.nextFloat() - (float)par2 * 0.01F < this.field_82174_bp[var3])
    2563                {
    2564                    if (!var5 && var4.isItemStackDamageable())
    2565                    {
    2566                        int var6 = Math.max(var4.getMaxDamage() - 25, 1);
    2567                        int var7 = var4.getMaxDamage() - this.rand.nextInt(this.rand.nextInt(var6) + 1);
    2568
    2569                        if (var7 > var6)
    2570                        {
    2571                            var7 = var6;
    2572                        }
    2573
    2574                        if (var7 < 1)
    2575                        {
    2576                            var7 = 1;
    2577                        }
    2578
    2579                        var4.setItemDamage(var7);
    2580                    }
    2581
    2582                    this.entityDropItem(var4, 0.0F);
    2583                }
    2584            }
    2585        }
    2586
    2587        protected void func_82164_bB()
    2588        {
    2589            if (this.rand.nextFloat() < field_82176_d[this.worldObj.difficultySetting])
    2590            {
    2591                int var1 = this.rand.nextInt(2);
    2592                float var2 = this.worldObj.difficultySetting == 3 ? 0.1F : 0.25F;
    2593
    2594                if (this.rand.nextFloat() < 0.07F)
    2595                {
    2596                    ++var1;
    2597                }
    2598
    2599                if (this.rand.nextFloat() < 0.07F)
    2600                {
    2601                    ++var1;
    2602                }
    2603
    2604                if (this.rand.nextFloat() < 0.07F)
    2605                {
    2606                    ++var1;
    2607                }
    2608
    2609                for (int var3 = 3; var3 >= 0; --var3)
    2610                {
    2611                    ItemStack var4 = this.func_82169_q(var3);
    2612
    2613                    if (var3 < 3 && this.rand.nextFloat() < var2)
    2614                    {
    2615                        break;
    2616                    }
    2617
    2618                    if (var4 == null)
    2619                    {
    2620                        Item var5 = func_82161_a(var3 + 1, var1);
    2621
    2622                        if (var5 != null)
    2623                        {
    2624                            this.func_70062_b(var3 + 1, new ItemStack(var5));
    2625                        }
    2626                    }
    2627                }
    2628            }
    2629        }
    2630
    2631        /**
    2632         * Called whenever an item is picked up from walking over it. Args: pickedUpEntity, stackSize
    2633         */
    2634        public void onItemPickup(Entity par1Entity, int par2)
    2635        {
    2636            if (!par1Entity.isDead && !this.worldObj.isRemote)
    2637            {
    2638                EntityTracker var3 = ((WorldServer)this.worldObj).getEntityTracker();
    2639
    2640                if (par1Entity instanceof EntityItem)
    2641                {
    2642                    var3.sendPacketToAllPlayersTrackingEntity(par1Entity, new Packet22Collect(par1Entity.entityId, this.entityId));
    2643                }
    2644
    2645                if (par1Entity instanceof EntityArrow)
    2646                {
    2647                    var3.sendPacketToAllPlayersTrackingEntity(par1Entity, new Packet22Collect(par1Entity.entityId, this.entityId));
    2648                }
    2649
    2650                if (par1Entity instanceof EntityXPOrb)
    2651                {
    2652                    var3.sendPacketToAllPlayersTrackingEntity(par1Entity, new Packet22Collect(par1Entity.entityId, this.entityId));
    2653                }
    2654            }
    2655        }
    2656
    2657        public static int func_82159_b(ItemStack par0ItemStack)
    2658        {
    2659            if (par0ItemStack.itemID != Block.pumpkin.blockID && par0ItemStack.itemID != Item.field_82799_bQ.shiftedIndex)
    2660            {
    2661                if (par0ItemStack.getItem() instanceof ItemArmor)
    2662                {
    2663                    switch (((ItemArmor)par0ItemStack.getItem()).armorType)
    2664                    {
    2665                        case 0:
    2666                            return 4;
    2667                        case 1:
    2668                            return 3;
    2669                        case 2:
    2670                            return 2;
    2671                        case 3:
    2672                            return 1;
    2673                    }
    2674                }
    2675
    2676                return 0;
    2677            }
    2678            else
    2679            {
    2680                return 4;
    2681            }
    2682        }
    2683
    2684        public static Item func_82161_a(int par0, int par1)
    2685        {
    2686            switch (par0)
    2687            {
    2688                case 4:
    2689                    if (par1 == 0)
    2690                    {
    2691                        return Item.helmetLeather;
    2692                    }
    2693                    else if (par1 == 1)
    2694                    {
    2695                        return Item.helmetGold;
    2696                    }
    2697                    else if (par1 == 2)
    2698                    {
    2699                        return Item.helmetChain;
    2700                    }
    2701                    else if (par1 == 3)
    2702                    {
    2703                        return Item.helmetSteel;
    2704                    }
    2705                    else if (par1 == 4)
    2706                    {
    2707                        return Item.helmetDiamond;
    2708                    }
    2709                case 3:
    2710                    if (par1 == 0)
    2711                    {
    2712                        return Item.plateLeather;
    2713                    }
    2714                    else if (par1 == 1)
    2715                    {
    2716                        return Item.plateGold;
    2717                    }
    2718                    else if (par1 == 2)
    2719                    {
    2720                        return Item.plateChain;
    2721                    }
    2722                    else if (par1 == 3)
    2723                    {
    2724                        return Item.plateSteel;
    2725                    }
    2726                    else if (par1 == 4)
    2727                    {
    2728                        return Item.plateDiamond;
    2729                    }
    2730                case 2:
    2731                    if (par1 == 0)
    2732                    {
    2733                        return Item.legsLeather;
    2734                    }
    2735                    else if (par1 == 1)
    2736                    {
    2737                        return Item.legsGold;
    2738                    }
    2739                    else if (par1 == 2)
    2740                    {
    2741                        return Item.legsChain;
    2742                    }
    2743                    else if (par1 == 3)
    2744                    {
    2745                        return Item.legsSteel;
    2746                    }
    2747                    else if (par1 == 4)
    2748                    {
    2749                        return Item.legsDiamond;
    2750                    }
    2751                case 1:
    2752                    if (par1 == 0)
    2753                    {
    2754                        return Item.bootsLeather;
    2755                    }
    2756                    else if (par1 == 1)
    2757                    {
    2758                        return Item.bootsGold;
    2759                    }
    2760                    else if (par1 == 2)
    2761                    {
    2762                        return Item.bootsChain;
    2763                    }
    2764                    else if (par1 == 3)
    2765                    {
    2766                        return Item.bootsSteel;
    2767                    }
    2768                    else if (par1 == 4)
    2769                    {
    2770                        return Item.bootsDiamond;
    2771                    }
    2772                default:
    2773                    return null;
    2774            }
    2775        }
    2776
    2777        protected void func_82162_bC()
    2778        {
    2779            if (this.getHeldItem() != null && this.rand.nextFloat() < field_82177_b[this.worldObj.difficultySetting])
    2780            {
    2781                EnchantmentHelper.addRandomEnchantment(this.rand, this.getHeldItem(), 5);
    2782            }
    2783
    2784            for (int var1 = 0; var1 < 4; ++var1)
    2785            {
    2786                ItemStack var2 = this.func_82169_q(var1);
    2787
    2788                if (var2 != null && this.rand.nextFloat() < field_82178_c[this.worldObj.difficultySetting])
    2789                {
    2790                    EnchantmentHelper.addRandomEnchantment(this.rand, var2, 5);
    2791                }
    2792            }
    2793        }
    2794
    2795        public void func_82163_bD() {}
    2796
    2797        private int func_82166_i()
    2798        {
    2799            return this.isPotionActive(Potion.digSpeed) ? 6 - (1 + this.getActivePotionEffect(Potion.digSpeed).getAmplifier()) * 1 : (this.isPotionActive(Potion.digSlowdown) ? 6 + (1 + this.getActivePotionEffect(Potion.digSlowdown).getAmplifier()) * 2 : 6);
    2800        }
    2801
    2802        /**
    2803         * Swings the item the player is holding.
    2804         */
    2805        public void swingItem()
    2806        {
    2807            if (!this.field_82175_bq || this.field_82173_br >= this.func_82166_i() / 2 || this.field_82173_br < 0)
    2808            {
    2809                this.field_82173_br = -1;
    2810                this.field_82175_bq = true;
    2811
    2812                if (this.worldObj instanceof WorldServer)
    2813                {
    2814                    ((WorldServer)this.worldObj).getEntityTracker().sendPacketToAllPlayersTrackingEntity(this, new Packet18Animation(this, 1));
    2815                }
    2816            }
    2817        }
    2818
    2819        public boolean func_82171_bF()
    2820        {
    2821            return false;
    2822        }
    2823
    2824        /***
    2825         * Removes all potion effects that have curativeItem as a curative item for its effect
    2826         * @param curativeItem The itemstack we are using to cure potion effects
    2827         */
    2828        public void curePotionEffects(ItemStack curativeItem)
    2829        {
    2830            Iterator<Integer> potionKey = activePotionsMap.keySet().iterator();
    2831
    2832            if (worldObj.isRemote)
    2833            {
    2834                return;
    2835            }
    2836
    2837            while (potionKey.hasNext())
    2838            {
    2839                Integer key = potionKey.next();
    2840                PotionEffect effect = (PotionEffect)activePotionsMap.get(key);
    2841
    2842                if (effect.isCurativeItem(curativeItem))
    2843                {
    2844                    potionKey.remove();
    2845                    onFinishedPotionEffect(effect);
    2846                }
    2847            }
    2848        }
    2849    }