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