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