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