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