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