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