    001    package net.minecraft.src;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.util.Collection;
    006    import java.util.HashMap;
    007    import java.util.Iterator;
    008    import java.util.List;
    009    import java.util.Random;
    010    import net.minecraftforge.common.ForgeHooks;
    011    import net.minecraftforge.common.MinecraftForge;
    012    import net.minecraftforge.event.entity.living.*;
    013    import static net.minecraftforge.event.entity.living.LivingEvent.*;
    014
    015    public abstract class EntityLiving extends Entity
    016    {
    017        public int maxHurtResistantTime = 20;
    018        public float field_70769_ao;
    019        public float field_70770_ap;
    020        public float renderYawOffset = 0.0F;
    021        public float prevRenderYawOffset = 0.0F;
    022
    023        /** Entity head rotation yaw */
    024        public float rotationYawHead = 0.0F;
    025
    026        /** Entity head rotation yaw at previous tick */
    027        public float prevRotationYawHead = 0.0F;
    028        protected float field_70768_au;
    029        protected float field_70766_av;
    030        protected float field_70764_aw;
    031        protected float field_70763_ax;
    032        protected boolean field_70753_ay = true;
    033
    034        /** the path for the texture of this entityLiving */
    035        protected String texture = "/mob/char.png";
    036        protected boolean field_70740_aA = true;
    037        protected float field_70741_aB = 0.0F;
    038
    039        /**
    040         * a string holding the type of entity it is currently only implemented in entityPlayer(as 'humanoid')
    041         */
    042        protected String entityType = null;
    043        protected float field_70743_aD = 1.0F;
    044
    045        /** The score value of the Mob, the amount of points the mob is worth. */
    046        protected int scoreValue = 0;
    047        protected float field_70745_aF = 0.0F;
    048
    049        /**
    050         * A factor used to determine how far this entity will move each tick if it is walking on land. Adjusted by speed,
    051         * and slipperiness of the current block.
    052         */
    053        public float landMovementFactor = 0.1F;
    054
    055        /**
    056         * A factor used to determine how far this entity will move each tick if it is jumping or falling.
    057         */
    058        public float jumpMovementFactor = 0.02F;
    059        public float prevSwingProgress;
    060        public float swingProgress;
    061        protected int health = this.getMaxHealth();
    062        public int prevHealth;
    063
    064        /**
    065         * in each step in the damage calculations, this is set to the 'carryover' that would result if someone was damaged
    066         * .25 hearts (for example), and added to the damage in the next step
    067         */
    068        public int carryoverDamage;
    069
    070        /** Number of ticks since this EntityLiving last produced its sound */
    071        private int livingSoundTime;
    072
    073        /**
    074         * The amount of time remaining this entity should act 'hurt'. (Visual appearance of red tint)
    075         */
    076        public int hurtTime;
    077
    078        /** What the hurt time was max set to last. */
    079        public int maxHurtTime;
    080
    081        /** The yaw at which this entity was last attacked from. */
    082        public float attackedAtYaw = 0.0F;
    083
    084        /**
    085         * The amount of time remaining this entity should act 'dead', i.e. have a corpse in the world.
    086         */
    087        public int deathTime = 0;
    088        public int attackTime = 0;
    089        public float prevCameraPitch;
    090        public float cameraPitch;
    091
    092        /**
    093         * This gets set on entity death, but never used. Looks like a duplicate of isDead
    094         */
    095        protected boolean dead = false;
    096
    097        /** The experience points the Entity gives. */
    098        protected int experienceValue;
    099        public int field_70731_aW = -1;
    100        public float field_70730_aX = (float)(Math.random() * 0.8999999761581421D + 0.10000000149011612D);
    101        public float prevLegYaw;
    102        public float legYaw;
    103
    104        /**
    105         * Only relevant when legYaw is not 0(the entity is moving). Influences where in its swing legs and arms currently
    106         * are.
    107         */
    108        public float legSwing;
    109
    110        /** The most recent player that has attacked this entity */
    111        protected EntityPlayer attackingPlayer = null;
    112
    113        /**
    114         * Set to 60 when hit by the player or the player's wolf, then decrements. Used to determine whether the entity
    115         * should drop items on death.
    116         */
    117        protected int recentlyHit = 0;
    118
    119        /** is only being set, has no uses as of MC 1.1 */
    120        private EntityLiving entityLivingToAttack = null;
    121        private int revengeTimer = 0;
    122        private EntityLiving lastAttackingEntity = null;
    123
    124        /**
    125         * Set to 60 when hit by the player or the player's wolf, then decrements. Used to determine whether the entity
    126         * should drop items on death.
    127         */
    128        public int arrowHitTempCounter = 0;
    129        public int arrowHitTimer = 0;
    130        protected HashMap activePotionsMap = new HashMap();
    131
    132        /** Whether the DataWatcher needs to be updated with the active potions */
    133        private boolean potionsNeedUpdate = true;
    134        private int field_70748_f;
    135        private EntityLookHelper lookHelper;
    136        private EntityMoveHelper moveHelper;
    137
    138        /** Entity jumping helper */
    139        private EntityJumpHelper jumpHelper;
    140        private EntityBodyHelper bodyHelper;
    141        private PathNavigate navigator;
    142        public final EntityAITasks tasks;
    143        protected final EntityAITasks targetTasks;
    144
    145        /** The active target the Task system uses for tracking */
    146        private EntityLiving attackTarget;
    147        private EntitySenses senses;
    148        private float AIMoveSpeed;
    149        private ChunkCoordinates homePosition = new ChunkCoordinates(0, 0, 0);
    150
    151        /** If -1 there is no maximum distance */
    152        private float maximumHomeDistance = -1.0F;
    153
    154        /**
    155         * The number of updates over which the new position and rotation are to be applied to the entity.
    156         */
    157        protected int newPosRotationIncrements;
    158
    159        /** The new X position to be applied to the entity. */
    160        protected double newPosX;
    161
    162        /** The new Y position to be applied to the entity. */
    163        protected double newPosY;
    164
    165        /** The new Z position to be applied to the entity. */
    166        protected double newPosZ;
    167
    168        /** The new yaw rotation to be applied to the entity. */
    169        protected double newRotationYaw;
    170
    171        /** The new yaw rotation to be applied to the entity. */
    172        protected double newRotationPitch;
    173        float field_70706_bo = 0.0F;
    174
    175        /** Amount of damage taken in last hit, in half-hearts */
    176        protected int lastDamage = 0;
    177
    178        /** Holds the living entity age, used to control the despawn. */
    179        protected int entityAge = 0;
    180        protected float moveStrafing;
    181        protected float moveForward;
    182        protected float randomYawVelocity;
    183
    184        /** used to check whether entity is jumping. */
    185        public boolean isJumping = false;
    186        protected float defaultPitch = 0.0F;
    187        protected float moveSpeed = 0.7F;
    188
    189        /** Number of ticks since last jump */
    190        private int jumpTicks = 0;
    191
    192        /** This entity's current target. */
    193        private Entity currentTarget;
    194
    195        /** How long to keep a specific target entity */
    196        protected int numTicksToChaseTarget = 0;
    197
    198        public EntityLiving(World par1World)
    199        {
    200            super(par1World);
    201            this.preventEntitySpawning = true;
    202            this.tasks = new EntityAITasks(par1World != null && par1World.theProfiler != null ? par1World.theProfiler : null);
    203            this.targetTasks = new EntityAITasks(par1World != null && par1World.theProfiler != null ? par1World.theProfiler : null);
    204            this.lookHelper = new EntityLookHelper(this);
    205            this.moveHelper = new EntityMoveHelper(this);
    206            this.jumpHelper = new EntityJumpHelper(this);
    207            this.bodyHelper = new EntityBodyHelper(this);
    208            this.navigator = new PathNavigate(this, par1World, 16.0F);
    209            this.senses = new EntitySenses(this);
    210            this.field_70770_ap = (float)(Math.random() + 1.0D) * 0.01F;
    211            this.setPosition(this.posX, this.posY, this.posZ);
    212            this.field_70769_ao = (float)Math.random() * 12398.0F;
    213            this.rotationYaw = (float)(Math.random() * Math.PI * 2.0D);
    214            this.rotationYawHead = this.rotationYaw;
    215            this.stepHeight = 0.5F;
    216        }
    217
    218        public EntityLookHelper getLookHelper()
    219        {
    220            return this.lookHelper;
    221        }
    222
    223        public EntityMoveHelper getMoveHelper()
    224        {
    225            return this.moveHelper;
    226        }
    227
    228        public EntityJumpHelper getJumpHelper()
    229        {
    230            return this.jumpHelper;
    231        }
    232
    233        public PathNavigate getNavigator()
    234        {
    235            return this.navigator;
    236        }
    237
    238        /**
    239         * returns the EntitySenses Object for the EntityLiving
    240         */
    241        public EntitySenses getEntitySenses()
    242        {
    243            return this.senses;
    244        }
    245
    246        public Random getRNG()
    247        {
    248            return this.rand;
    249        }
    250
    251        public EntityLiving getAITarget()
    252        {
    253            return this.entityLivingToAttack;
    254        }
    255
    256        public EntityLiving getLastAttackingEntity()
    257        {
    258            return this.lastAttackingEntity;
    259        }
    260
    261        public void setLastAttackingEntity(Entity par1Entity)
    262        {
    263            if (par1Entity instanceof EntityLiving)
    264            {
    265                this.lastAttackingEntity = (EntityLiving)par1Entity;
    266            }
    267        }
    268
    269        public int getAge()
    270        {
    271            return this.entityAge;
    272        }
    273
    274        public float func_70079_am()
    275        {
    276            return this.rotationYawHead;
    277        }
    278
    279        @SideOnly(Side.CLIENT)
    280
    281        /**
    282         * Sets the head's yaw rotation of the entity.
    283         */
    284        public void setHeadRotationYaw(float par1)
    285        {
    286            this.rotationYawHead = par1;
    287        }
    288
    289        /**
    290         * the movespeed used for the new AI system
    291         */
    292        public float getAIMoveSpeed()
    293        {
    294            return this.AIMoveSpeed;
    295        }
    296
    297        /**
    298         * set the movespeed used for the new AI system
    299         */
    300        public void setAIMoveSpeed(float par1)
    301        {
    302            this.AIMoveSpeed = par1;
    303            this.setMoveForward(par1);
    304        }
    305
    306        public boolean attackEntityAsMob(Entity par1Entity)
    307        {
    308            this.setLastAttackingEntity(par1Entity);
    309            return false;
    310        }
    311
    312        /**
    313         * Gets the active target the Task system uses for tracking
    314         */
    315        public EntityLiving getAttackTarget()
    316        {
    317            return this.attackTarget;
    318        }
    319
    320        /**
    321         * Sets the active target the Task system uses for tracking
    322         */
    323        public void setAttackTarget(EntityLiving par1EntityLiving)
    324        {
    325            this.attackTarget = par1EntityLiving;
    326            ForgeHooks.onLivingSetAttackTarget(this, par1EntityLiving);
    327        }
    328
    329        public boolean isExplosiveMob(Class par1Class)
    330        {
    331            return EntityCreeper.class != par1Class && EntityGhast.class != par1Class;
    332        }
    333
    334        /**
    335         * This function applies the benefits of growing back wool and faster growing up to the acting entity. (This
    336         * function is used in the AIEatGrass)
    337         */
    338        public void eatGrassBonus() {}
    339
    340        /**
    341         * Returns true if entity is within home distance from current position
    342         */
    343        public boolean isWithinHomeDistanceCurrentPosition()
    344        {
    345            return this.isWithinHomeDistance(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ));
    346        }
    347
    348        public boolean isWithinHomeDistance(int par1, int par2, int par3)
    349        {
    350            return this.maximumHomeDistance == -1.0F ? true : this.homePosition.getDistanceSquared(par1, par2, par3) < this.maximumHomeDistance * this.maximumHomeDistance;
    351        }
    352
    353        public void setHomeArea(int par1, int par2, int par3, int par4)
    354        {
    355            this.homePosition.set(par1, par2, par3);
    356            this.maximumHomeDistance = (float)par4;
    357        }
    358
    359        public ChunkCoordinates getHomePosition()
    360        {
    361            return this.homePosition;
    362        }
    363
    364        public float getMaximumHomeDistance()
    365        {
    366            return this.maximumHomeDistance;
    367        }
    368
    369        public void detachHome()
    370        {
    371            this.maximumHomeDistance = -1.0F;
    372        }
    373
    374        public boolean hasHome()
    375        {
    376            return this.maximumHomeDistance != -1.0F;
    377        }
    378
    379        public void setRevengeTarget(EntityLiving par1EntityLiving)
    380        {
    381            this.entityLivingToAttack = par1EntityLiving;
    382            this.revengeTimer = this.entityLivingToAttack != null ? 60 : 0;
    383            ForgeHooks.onLivingSetAttackTarget(this, par1EntityLiving);
    384        }
    385
    386        protected void entityInit()
    387        {
    388            this.dataWatcher.addObject(8, Integer.valueOf(this.field_70748_f));
    389        }
    390
    391        /**
    392         * returns true if the entity provided in the argument can be seen. (Raytrace)
    393         */
    394        public boolean canEntityBeSeen(Entity par1Entity)
    395        {
    396            return this.worldObj.rayTraceBlocks(Vec3.getVec3Pool().getVecFromPool(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ), Vec3.getVec3Pool().getVecFromPool(par1Entity.posX, par1Entity.posY + (double)par1Entity.getEyeHeight(), par1Entity.posZ)) == null;
    397        }
    398
    399        @SideOnly(Side.CLIENT)
    400
    401        /**
    402         * Returns the texture's file path as a String.
    403         */
    404        public String getTexture()
    405        {
    406            return this.texture;
    407        }
    408
    409        /**
    410         * Returns true if other Entities should be prevented from moving through this Entity.
    411         */
    412        public boolean canBeCollidedWith()
    413        {
    414            return !this.isDead;
    415        }
    416
    417        /**
    418         * Returns true if this entity should push and be pushed by other entities when colliding.
    419         */
    420        public boolean canBePushed()
    421        {
    422            return !this.isDead;
    423        }
    424
    425        public float getEyeHeight()
    426        {
    427            return this.height * 0.85F;
    428        }
    429
    430        /**
    431         * Get number of ticks, at least during which the living entity will be silent.
    432         */
    433        public int getTalkInterval()
    434        {
    435            return 80;
    436        }
    437
    438        /**
    439         * Plays living's sound at its position
    440         */
    441        public void playLivingSound()
    442        {
    443            String var1 = this.getLivingSound();
    444
    445            if (var1 != null)
    446            {
    447                this.worldObj.playSoundAtEntity(this, var1, this.getSoundVolume(), this.getSoundPitch());
    448            }
    449        }
    450
    451        /**
    452         * Gets called every tick from main Entity class
    453         */
    454        public void onEntityUpdate()
    455        {
    456            this.prevSwingProgress = this.swingProgress;
    457            super.onEntityUpdate();
    458            this.worldObj.theProfiler.startSection("mobBaseTick");
    459
    460            if (this.isEntityAlive() && this.rand.nextInt(1000) < this.livingSoundTime++)
    461            {
    462                this.livingSoundTime = -this.getTalkInterval();
    463                this.playLivingSound();
    464            }
    465
    466            if (this.isEntityAlive() && this.isEntityInsideOpaqueBlock())
    467            {
    468                this.attackEntityFrom(DamageSource.inWall, 1);
    469            }
    470
    471            if (this.isImmuneToFire() || this.worldObj.isRemote)
    472            {
    473                this.extinguish();
    474            }
    475
    476            if (this.isEntityAlive() && this.isInsideOfMaterial(Material.water) && !this.canBreatheUnderwater() && !this.activePotionsMap.containsKey(Integer.valueOf(Potion.waterBreathing.id)))
    477            {
    478                this.setAir(this.decreaseAirSupply(this.getAir()));
    479
    480                if (this.getAir() == -20)
    481                {
    482                    this.setAir(0);
    483
    484                    for (int var1 = 0; var1 < 8; ++var1)
    485                    {
    486                        float var2 = this.rand.nextFloat() - this.rand.nextFloat();
    487                        float var3 = this.rand.nextFloat() - this.rand.nextFloat();
    488                        float var4 = this.rand.nextFloat() - this.rand.nextFloat();
    489                        this.worldObj.spawnParticle("bubble", this.posX + (double)var2, this.posY + (double)var3, this.posZ + (double)var4, this.motionX, this.motionY, this.motionZ);
    490                    }
    491
    492                    this.attackEntityFrom(DamageSource.drown, 2);
    493                }
    494
    495                this.extinguish();
    496            }
    497            else
    498            {
    499                this.setAir(300);
    500            }
    501
    502            this.prevCameraPitch = this.cameraPitch;
    503
    504            if (this.attackTime > 0)
    505            {
    506                --this.attackTime;
    507            }
    508
    509            if (this.hurtTime > 0)
    510            {
    511                --this.hurtTime;
    512            }
    513
    514            if (this.hurtResistantTime > 0)
    515            {
    516                --this.hurtResistantTime;
    517            }
    518
    519            if (this.health <= 0)
    520            {
    521                this.onDeathUpdate();
    522            }
    523
    524            if (this.recentlyHit > 0)
    525            {
    526                --this.recentlyHit;
    527            }
    528            else
    529            {
    530                this.attackingPlayer = null;
    531            }
    532
    533            if (this.lastAttackingEntity != null && !this.lastAttackingEntity.isEntityAlive())
    534            {
    535                this.lastAttackingEntity = null;
    536            }
    537
    538            if (this.entityLivingToAttack != null)
    539            {
    540                if (!this.entityLivingToAttack.isEntityAlive())
    541                {
    542                    this.setRevengeTarget((EntityLiving)null);
    543                }
    544                else if (this.revengeTimer > 0)
    545                {
    546                    --this.revengeTimer;
    547                }
    548                else
    549                {
    550                    this.setRevengeTarget((EntityLiving)null);
    551                }
    552            }
    553
    554            this.updatePotionEffects();
    555            this.field_70763_ax = this.field_70764_aw;
    556            this.prevRenderYawOffset = this.renderYawOffset;
    557            this.prevRotationYawHead = this.rotationYawHead;
    558            this.prevRotationYaw = this.rotationYaw;
    559            this.prevRotationPitch = this.rotationPitch;
    560            this.worldObj.theProfiler.endSection();
    561        }
    562
    563        /**
    564         * handles entity death timer, experience orb and particle creation
    565         */
    566        protected void onDeathUpdate()
    567        {
    568            ++this.deathTime;
    569
    570            if (this.deathTime == 20)
    571            {
    572                int var1;
    573
    574                if (!this.worldObj.isRemote && (this.recentlyHit > 0 || this.isPlayer()) && !this.isChild())
    575                {
    576                    var1 = this.getExperiencePoints(this.attackingPlayer);
    577
    578                    while (var1 > 0)
    579                    {
    580                        int var2 = EntityXPOrb.getXPSplit(var1);
    581                        var1 -= var2;
    582                        this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, var2));
    583                    }
    584                }
    585
    586                this.setDead();
    587
    588                for (var1 = 0; var1 < 20; ++var1)
    589                {
    590                    double var8 = this.rand.nextGaussian() * 0.02D;
    591                    double var4 = this.rand.nextGaussian() * 0.02D;
    592                    double var6 = this.rand.nextGaussian() * 0.02D;
    593                    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);
    594                }
    595            }
    596        }
    597
    598        /**
    599         * Decrements the entity's air supply when underwater
    600         */
    601        protected int decreaseAirSupply(int par1)
    602        {
    603            return par1 - 1;
    604        }
    605
    606        /**
    607         * Get the experience points the entity currently has.
    608         */
    609        protected int getExperiencePoints(EntityPlayer par1EntityPlayer)
    610        {
    611            return this.experienceValue;
    612        }
    613
    614        /**
    615         * Only use is to identify if class is an instance of player for experience dropping
    616         */
    617        protected boolean isPlayer()
    618        {
    619            return false;
    620        }
    621
    622        /**
    623         * Spawns an explosion particle around the Entity's location
    624         */
    625        public void spawnExplosionParticle()
    626        {
    627            for (int var1 = 0; var1 < 20; ++var1)
    628            {
    629                double var2 = this.rand.nextGaussian() * 0.02D;
    630                double var4 = this.rand.nextGaussian() * 0.02D;
    631                double var6 = this.rand.nextGaussian() * 0.02D;
    632                double var8 = 10.0D;
    633                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);
    634            }
    635        }
    636
    637        /**
    638         * Handles updating while being ridden by an entity
    639         */
    640        public void updateRidden()
    641        {
    642            super.updateRidden();
    643            this.field_70768_au = this.field_70766_av;
    644            this.field_70766_av = 0.0F;
    645            this.fallDistance = 0.0F;
    646        }
    647
    648        @SideOnly(Side.CLIENT)
    649
    650        /**
    651         * Sets the position and rotation. Only difference from the other one is no bounding on the rotation. Args: posX,
    652         * posY, posZ, yaw, pitch
    653         */
    654        public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9)
    655        {
    656            this.yOffset = 0.0F;
    657            this.newPosX = par1;
    658            this.newPosY = par3;
    659            this.newPosZ = par5;
    660            this.newRotationYaw = (double)par7;
    661            this.newRotationPitch = (double)par8;
    662            this.newPosRotationIncrements = par9;
    663        }
    664
    665        /**
    666         * Called to update the entity's position/logic.
    667         */
    668        public void onUpdate()
    669        {
    670            if (ForgeHooks.onLivingUpdate(this))
    671            {
    672                return;
    673            }
    674
    675            super.onUpdate();
    676
    677            if (this.arrowHitTempCounter > 0)
    678            {
    679                if (this.arrowHitTimer <= 0)
    680                {
    681                    this.arrowHitTimer = 60;
    682                }
    683
    684                --this.arrowHitTimer;
    685
    686                if (this.arrowHitTimer <= 0)
    687                {
    688                    --this.arrowHitTempCounter;
    689                }
    690            }
    691
    692            this.onLivingUpdate();
    693            double var1 = this.posX - this.prevPosX;
    694            double var3 = this.posZ - this.prevPosZ;
    695            float var5 = (float)(var1 * var1 + var3 * var3);
    696            float var6 = this.renderYawOffset;
    697            float var7 = 0.0F;
    698            this.field_70768_au = this.field_70766_av;
    699            float var8 = 0.0F;
    700
    701            if (var5 > 0.0025000002F)
    702            {
    703                var8 = 1.0F;
    704                var7 = (float)Math.sqrt((double)var5) * 3.0F;
    705                var6 = (float)Math.atan2(var3, var1) * 180.0F / (float)Math.PI - 90.0F;
    706            }
    707
    708            if (this.swingProgress > 0.0F)
    709            {
    710                var6 = this.rotationYaw;
    711            }
    712
    713            if (!this.onGround)
    714            {
    715                var8 = 0.0F;
    716            }
    717
    718            this.field_70766_av += (var8 - this.field_70766_av) * 0.3F;
    719            this.worldObj.theProfiler.startSection("headTurn");
    720
    721            if (this.isAIEnabled())
    722            {
    723                this.bodyHelper.func_75664_a();
    724            }
    725            else
    726            {
    727                float var9 = MathHelper.wrapAngleTo180_float(var6 - this.renderYawOffset);
    728                this.renderYawOffset += var9 * 0.3F;
    729                float var10 = MathHelper.wrapAngleTo180_float(this.rotationYaw - this.renderYawOffset);
    730                boolean var11 = var10 < -90.0F || var10 >= 90.0F;
    731
    732                if (var10 < -75.0F)
    733                {
    734                    var10 = -75.0F;
    735                }
    736
    737                if (var10 >= 75.0F)
    738                {
    739                    var10 = 75.0F;
    740                }
    741
    742                this.renderYawOffset = this.rotationYaw - var10;
    743
    744                if (var10 * var10 > 2500.0F)
    745                {
    746                    this.renderYawOffset += var10 * 0.2F;
    747                }
    748
    749                if (var11)
    750                {
    751                    var7 *= -1.0F;
    752                }
    753            }
    754
    755            this.worldObj.theProfiler.endSection();
    756            this.worldObj.theProfiler.startSection("rangeChecks");
    757
    758            while (this.rotationYaw - this.prevRotationYaw < -180.0F)
    759            {
    760                this.prevRotationYaw -= 360.0F;
    761            }
    762
    763            while (this.rotationYaw - this.prevRotationYaw >= 180.0F)
    764            {
    765                this.prevRotationYaw += 360.0F;
    766            }
    767
    768            while (this.renderYawOffset - this.prevRenderYawOffset < -180.0F)
    769            {
    770                this.prevRenderYawOffset -= 360.0F;
    771            }
    772
    773            while (this.renderYawOffset - this.prevRenderYawOffset >= 180.0F)
    774            {
    775                this.prevRenderYawOffset += 360.0F;
    776            }
    777
    778            while (this.rotationPitch - this.prevRotationPitch < -180.0F)
    779            {
    780                this.prevRotationPitch -= 360.0F;
    781            }
    782
    783            while (this.rotationPitch - this.prevRotationPitch >= 180.0F)
    784            {
    785                this.prevRotationPitch += 360.0F;
    786            }
    787
    788            while (this.rotationYawHead - this.prevRotationYawHead < -180.0F)
    789            {
    790                this.prevRotationYawHead -= 360.0F;
    791            }
    792
    793            while (this.rotationYawHead - this.prevRotationYawHead >= 180.0F)
    794            {
    795                this.prevRotationYawHead += 360.0F;
    796            }
    797
    798            this.worldObj.theProfiler.endSection();
    799            this.field_70764_aw += var7;
    800        }
    801
    802        /**
    803         * Heal living entity (param: amount of half-hearts)
    804         */
    805        public void heal(int par1)
    806        {
    807            if (this.health > 0)
    808            {
    809                this.health += par1;
    810
    811                if (this.health > this.getMaxHealth())
    812                {
    813                    this.health = this.getMaxHealth();
    814                }
    815
    816                this.hurtResistantTime = this.maxHurtResistantTime / 2;
    817            }
    818        }
    819
    820        public abstract int getMaxHealth();
    821
    822        public int getHealth()
    823        {
    824            return this.health;
    825        }
    826
    827        public void setEntityHealth(int par1)
    828        {
    829            this.health = par1;
    830
    831            if (par1 > this.getMaxHealth())
    832            {
    833                par1 = this.getMaxHealth();
    834            }
    835        }
    836
    837        /**
    838         * Called when the entity is attacked.
    839         */
    840        public boolean attackEntityFrom(DamageSource par1DamageSource, int par2)
    841        {
    842            if (ForgeHooks.onLivingAttack(this, par1DamageSource, par2))
    843            {
    844                return false;
    845            }
    846
    847            if (this.worldObj.isRemote)
    848            {
    849                return false;
    850            }
    851            else
    852            {
    853                this.entityAge = 0;
    854
    855                if (this.health <= 0)
    856                {
    857                    return false;
    858                }
    859                else if (par1DamageSource.fireDamage() && this.isPotionActive(Potion.fireResistance))
    860                {
    861                    return false;
    862                }
    863                else
    864                {
    865                    this.legYaw = 1.5F;
    866                    boolean var3 = true;
    867
    868                    if ((float)this.hurtResistantTime > (float)this.maxHurtResistantTime / 2.0F)
    869                    {
    870                        if (par2 <= this.lastDamage)
    871                        {
    872                            return false;
    873                        }
    874
    875                        this.damageEntity(par1DamageSource, par2 - this.lastDamage);
    876                        this.lastDamage = par2;
    877                        var3 = false;
    878                    }
    879                    else
    880                    {
    881                        this.lastDamage = par2;
    882                        this.prevHealth = this.health;
    883                        this.hurtResistantTime = this.maxHurtResistantTime;
    884                        this.damageEntity(par1DamageSource, par2);
    885                        this.hurtTime = this.maxHurtTime = 10;
    886                    }
    887
    888                    this.attackedAtYaw = 0.0F;
    889                    Entity var4 = par1DamageSource.getEntity();
    890
    891                    if (var4 != null)
    892                    {
    893                        if (var4 instanceof EntityLiving)
    894                        {
    895                            this.setRevengeTarget((EntityLiving)var4);
    896                        }
    897
    898                        if (var4 instanceof EntityPlayer)
    899                        {
    900                            this.recentlyHit = 60;
    901                            this.attackingPlayer = (EntityPlayer)var4;
    902                        }
    903                        else if (var4 instanceof EntityWolf)
    904                        {
    905                            EntityWolf var5 = (EntityWolf)var4;
    906
    907                            if (var5.isTamed())
    908                            {
    909                                this.recentlyHit = 60;
    910                                this.attackingPlayer = null;
    911                            }
    912                        }
    913                    }
    914
    915                    if (var3)
    916                    {
    917                        this.worldObj.setEntityState(this, (byte)2);
    918
    919                        if (par1DamageSource != DamageSource.drown && par1DamageSource != DamageSource.field_76375_l)
    920                        {
    921                            this.setBeenAttacked();
    922                        }
    923
    924                        if (var4 != null)
    925                        {
    926                            double var9 = var4.posX - this.posX;
    927                            double var7;
    928
    929                            for (var7 = var4.posZ - this.posZ; var9 * var9 + var7 * var7 < 1.0E-4D; var7 = (Math.random() - Math.random()) * 0.01D)
    930                            {
    931                                var9 = (Math.random() - Math.random()) * 0.01D;
    932                            }
    933
    934                            this.attackedAtYaw = (float)(Math.atan2(var7, var9) * 180.0D / Math.PI) - this.rotationYaw;
    935                            this.knockBack(var4, par2, var9, var7);
    936                        }
    937                        else
    938                        {
    939                            this.attackedAtYaw = (float)((int)(Math.random() * 2.0D) * 180);
    940                        }
    941                    }
    942
    943                    if (this.health <= 0)
    944                    {
    945                        if (var3)
    946                        {
    947                            this.worldObj.playSoundAtEntity(this, this.getDeathSound(), this.getSoundVolume(), this.getSoundPitch());
    948                        }
    949
    950                        this.onDeath(par1DamageSource);
    951                    }
    952                    else if (var3)
    953                    {
    954                        this.worldObj.playSoundAtEntity(this, this.getHurtSound(), this.getSoundVolume(), this.getSoundPitch());
    955                    }
    956
    957                    return true;
    958                }
    959            }
    960        }
    961
    962        /**
    963         * Gets the pitch of living sounds in living entities.
    964         */
    965        private float getSoundPitch()
    966        {
    967            return this.isChild() ? (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.5F : (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F;
    968        }
    969
    970        @SideOnly(Side.CLIENT)
    971
    972        /**
    973         * Setups the entity to do the hurt animation. Only used by packets in multiplayer.
    974         */
    975        public void performHurtAnimation()
    976        {
    977            this.hurtTime = this.maxHurtTime = 10;
    978            this.attackedAtYaw = 0.0F;
    979        }
    980
    981        /**
    982         * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue
    983         */
    984        public int getTotalArmorValue()
    985        {
    986            return 0;
    987        }
    988
    989        protected void damageArmor(int par1) {}
    990
    991        /**
    992         * Reduces damage, depending on armor
    993         */
    994        protected int applyArmorCalculations(DamageSource par1DamageSource, int par2)
    995        {
    996            if (!par1DamageSource.isUnblockable())
    997            {
    998                int var3 = 25 - this.getTotalArmorValue();
    999                int var4 = par2 * var3 + this.carryoverDamage;
    1000                this.damageArmor(par2);
    1001                par2 = var4 / 25;
    1002                this.carryoverDamage = var4 % 25;
    1003            }
    1004
    1005            return par2;
    1006        }
    1007
    1008        /**
    1009         * Reduces damage, depending on potions
    1010         */
    1011        protected int applyPotionDamageCalculations(DamageSource par1DamageSource, int par2)
    1012        {
    1013            if (this.isPotionActive(Potion.resistance))
    1014            {
    1015                int var3 = (this.getActivePotionEffect(Potion.resistance).getAmplifier() + 1) * 5;
    1016                int var4 = 25 - var3;
    1017                int var5 = par2 * var4 + this.carryoverDamage;
    1018                par2 = var5 / 25;
    1019                this.carryoverDamage = var5 % 25;
    1020            }
    1021
    1022            return par2;
    1023        }
    1024
    1025        /**
    1026         * Deals damage to the entity. If its a EntityPlayer then will take damage from the armor first and then health
    1027         * second with the reduced value. Args: damageAmount
    1028         */
    1029        protected void damageEntity(DamageSource par1DamageSource, int par2)
    1030        {
    1031            par2 = ForgeHooks.onLivingHurt(this, par1DamageSource, par2);
    1032            if (par2 <= 0)
    1033            {
    1034                return;
    1035            }
    1036
    1037            par2 = this.applyArmorCalculations(par1DamageSource, par2);
    1038            par2 = this.applyPotionDamageCalculations(par1DamageSource, par2);
    1039            this.health -= par2;
    1040        }
    1041
    1042        /**
    1043         * Returns the volume for the sounds this mob makes.
    1044         */
    1045        protected float getSoundVolume()
    1046        {
    1047            return 1.0F;
    1048        }
    1049
    1050        /**
    1051         * Returns the sound this mob makes while it's alive.
    1052         */
    1053        protected String getLivingSound()
    1054        {
    1055            return null;
    1056        }
    1057
    1058        /**
    1059         * Returns the sound this mob makes when it is hurt.
    1060         */
    1061        protected String getHurtSound()
    1062        {
    1063            return "damage.hurtflesh";
    1064        }
    1065
    1066        /**
    1067         * Returns the sound this mob makes on death.
    1068         */
    1069        protected String getDeathSound()
    1070        {
    1071            return "damage.hurtflesh";
    1072        }
    1073
    1074        /**
    1075         * knocks back this entity
    1076         */
    1077        public void knockBack(Entity par1Entity, int par2, double par3, double par5)
    1078        {
    1079            this.isAirBorne = true;
    1080            float var7 = MathHelper.sqrt_double(par3 * par3 + par5 * par5);
    1081            float var8 = 0.4F;
    1082            this.motionX /= 2.0D;
    1083            this.motionY /= 2.0D;
    1084            this.motionZ /= 2.0D;
    1085            this.motionX -= par3 / (double)var7 * (double)var8;
    1086            this.motionY += (double)var8;
    1087            this.motionZ -= par5 / (double)var7 * (double)var8;
    1088
    1089            if (this.motionY > 0.4000000059604645D)
    1090            {
    1091                this.motionY = 0.4000000059604645D;
    1092            }
    1093        }
    1094
    1095        /**
    1096         * Called when the mob's health reaches 0.
    1097         */
    1098        public void onDeath(DamageSource par1DamageSource)
    1099        {
    1100            if (ForgeHooks.onLivingDeath(this, par1DamageSource))
    1101            {
    1102                return;
    1103            }
    1104
    1105            Entity var2 = par1DamageSource.getEntity();
    1106
    1107            if (this.scoreValue >= 0 && var2 != null)
    1108            {
    1109                var2.addToPlayerScore(this, this.scoreValue);
    1110            }
    1111
    1112            if (var2 != null)
    1113            {
    1114                var2.onKillEntity(this);
    1115            }
    1116
    1117            this.dead = true;
    1118
    1119            if (!this.worldObj.isRemote)
    1120            {
    1121                int var3 = 0;
    1122
    1123                if (var2 instanceof EntityPlayer)
    1124                {
    1125                    var3 = EnchantmentHelper.getLootingModifier(((EntityPlayer)var2).inventory);
    1126                }
    1127
    1128                captureDrops = true;
    1129                capturedDrops.clear();
    1130                int var4 = 0;
    1131
    1132                if (!this.isChild())
    1133                {
    1134                    this.dropFewItems(this.recentlyHit > 0, var3);
    1135
    1136                    if (this.recentlyHit > 0)
    1137                    {
    1138                        var4 = this.rand.nextInt(200) - var3;
    1139
    1140                        if (var4 < 5)
    1141                        {
    1142                            this.dropRareDrop(var4 <= 0 ? 1 : 0);
    1143                        }
    1144                    }
    1145                }
    1146
    1147                captureDrops = false;
    1148
    1149                if (!ForgeHooks.onLivingDrops(this, par1DamageSource, capturedDrops, var3, recentlyHit > 0, var4))
    1150                {
    1151                    for (EntityItem item : capturedDrops)
    1152                    {
    1153                        worldObj.spawnEntityInWorld(item);
    1154                    }
    1155                }
    1156            }
    1157
    1158            this.worldObj.setEntityState(this, (byte)3);
    1159        }
    1160
    1161        protected void dropRareDrop(int par1) {}
    1162
    1163        /**
    1164         * Drop 0-2 items of this living's type
    1165         */
    1166        protected void dropFewItems(boolean par1, int par2)
    1167        {
    1168            int var3 = this.getDropItemId();
    1169
    1170            if (var3 > 0)
    1171            {
    1172                int var4 = this.rand.nextInt(3);
    1173
    1174                if (par2 > 0)
    1175                {
    1176                    var4 += this.rand.nextInt(par2 + 1);
    1177                }
    1178
    1179                for (int var5 = 0; var5 < var4; ++var5)
    1180                {
    1181                    this.dropItem(var3, 1);
    1182                }
    1183            }
    1184        }
    1185
    1186        /**
    1187         * Returns the item ID for the item the mob drops on death.
    1188         */
    1189        protected int getDropItemId()
    1190        {
    1191            return 0;
    1192        }
    1193
    1194        /**
    1195         * Called when the mob is falling. Calculates and applies fall damage.
    1196         */
    1197        protected void fall(float par1)
    1198        {
    1199            par1 = ForgeHooks.onLivingFall(this, par1);
    1200            if (par1 <= 0)
    1201            {
    1202                return;
    1203            }
    1204
    1205            super.fall(par1);
    1206            int var2 = MathHelper.ceiling_float_int(par1 - 3.0F);
    1207
    1208            if (var2 > 0)
    1209            {
    1210                if (var2 > 4)
    1211                {
    1212                    this.worldObj.playSoundAtEntity(this, "damage.fallbig", 1.0F, 1.0F);
    1213                }
    1214                else
    1215                {
    1216                    this.worldObj.playSoundAtEntity(this, "damage.fallsmall", 1.0F, 1.0F);
    1217                }
    1218
    1219                this.attackEntityFrom(DamageSource.fall, var2);
    1220                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));
    1221
    1222                if (var3 > 0)
    1223                {
    1224                    StepSound var4 = Block.blocksList[var3].stepSound;
    1225                    this.worldObj.playSoundAtEntity(this, var4.getStepSound(), var4.getVolume() * 0.5F, var4.getPitch() * 0.75F);
    1226                }
    1227            }
    1228        }
    1229
    1230        /**
    1231         * Moves the entity based on the specified heading.  Args: strafe, forward
    1232         */
    1233        public void moveEntityWithHeading(float par1, float par2)
    1234        {
    1235            double var9;
    1236
    1237            if (this.isInWater() && (!(this instanceof EntityPlayer) || !((EntityPlayer)this).capabilities.isFlying))
    1238            {
    1239                var9 = this.posY;
    1240                this.moveFlying(par1, par2, this.isAIEnabled() ? 0.04F : 0.02F);
    1241                this.moveEntity(this.motionX, this.motionY, this.motionZ);
    1242                this.motionX *= 0.800000011920929D;
    1243                this.motionY *= 0.800000011920929D;
    1244                this.motionZ *= 0.800000011920929D;
    1245                this.motionY -= 0.02D;
    1246
    1247                if (this.isCollidedHorizontally && this.isOffsetPositionInLiquid(this.motionX, this.motionY + 0.6000000238418579D - this.posY + var9, this.motionZ))
    1248                {
    1249                    this.motionY = 0.30000001192092896D;
    1250                }
    1251            }
    1252            else if (this.handleLavaMovement() && (!(this instanceof EntityPlayer) || !((EntityPlayer)this).capabilities.isFlying))
    1253            {
    1254                var9 = this.posY;
    1255                this.moveFlying(par1, par2, 0.02F);
    1256                this.moveEntity(this.motionX, this.motionY, this.motionZ);
    1257                this.motionX *= 0.5D;
    1258                this.motionY *= 0.5D;
    1259                this.motionZ *= 0.5D;
    1260                this.motionY -= 0.02D;
    1261
    1262                if (this.isCollidedHorizontally && this.isOffsetPositionInLiquid(this.motionX, this.motionY + 0.6000000238418579D - this.posY + var9, this.motionZ))
    1263                {
    1264                    this.motionY = 0.30000001192092896D;
    1265                }
    1266            }
    1267            else
    1268            {
    1269                float var3 = 0.91F;
    1270
    1271                if (this.onGround)
    1272                {
    1273                    var3 = 0.54600006F;
    1274                    int var4 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ));
    1275
    1276                    if (var4 > 0)
    1277                    {
    1278                        var3 = Block.blocksList[var4].slipperiness * 0.91F;
    1279                    }
    1280                }
    1281
    1282                float var8 = 0.16277136F / (var3 * var3 * var3);
    1283                float var5;
    1284
    1285                if (this.onGround)
    1286                {
    1287                    if (this.isAIEnabled())
    1288                    {
    1289                        var5 = this.getAIMoveSpeed();
    1290                    }
    1291                    else
    1292                    {
    1293                        var5 = this.landMovementFactor;
    1294                    }
    1295
    1296                    var5 *= var8;
    1297                }
    1298                else
    1299                {
    1300                    var5 = this.jumpMovementFactor;
    1301                }
    1302
    1303                this.moveFlying(par1, par2, var5);
    1304                var3 = 0.91F;
    1305
    1306                if (this.onGround)
    1307                {
    1308                    var3 = 0.54600006F;
    1309                    int var6 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ));
    1310
    1311                    if (var6 > 0)
    1312                    {
    1313                        var3 = Block.blocksList[var6].slipperiness * 0.91F;
    1314                    }
    1315                }
    1316
    1317                if (this.isOnLadder())
    1318                {
    1319                    float var10 = 0.15F;
    1320
    1321                    if (this.motionX < (double)(-var10))
    1322                    {
    1323                        this.motionX = (double)(-var10);
    1324                    }
    1325
    1326                    if (this.motionX > (double)var10)
    1327                    {
    1328                        this.motionX = (double)var10;
    1329                    }
    1330
    1331                    if (this.motionZ < (double)(-var10))
    1332                    {
    1333                        this.motionZ = (double)(-var10);
    1334                    }
    1335
    1336                    if (this.motionZ > (double)var10)
    1337                    {
    1338                        this.motionZ = (double)var10;
    1339                    }
    1340
    1341                    this.fallDistance = 0.0F;
    1342
    1343                    if (this.motionY < -0.15D)
    1344                    {
    1345                        this.motionY = -0.15D;
    1346                    }
    1347
    1348                    boolean var7 = this.isSneaking() && this instanceof EntityPlayer;
    1349
    1350                    if (var7 && this.motionY < 0.0D)
    1351                    {
    1352                        this.motionY = 0.0D;
    1353                    }
    1354                }
    1355
    1356                this.moveEntity(this.motionX, this.motionY, this.motionZ);
    1357
    1358                if (this.isCollidedHorizontally && this.isOnLadder())
    1359                {
    1360                    this.motionY = 0.2D;
    1361                }
    1362
    1363                this.motionY -= 0.08D;
    1364                this.motionY *= 0.9800000190734863D;
    1365                this.motionX *= (double)var3;
    1366                this.motionZ *= (double)var3;
    1367            }
    1368
    1369            this.prevLegYaw = this.legYaw;
    1370            var9 = this.posX - this.prevPosX;
    1371            double var12 = this.posZ - this.prevPosZ;
    1372            float var11 = MathHelper.sqrt_double(var9 * var9 + var12 * var12) * 4.0F;
    1373
    1374            if (var11 > 1.0F)
    1375            {
    1376                var11 = 1.0F;
    1377            }
    1378
    1379            this.legYaw += (var11 - this.legYaw) * 0.4F;
    1380            this.legSwing += this.legYaw;
    1381        }
    1382
    1383        /**
    1384         * returns true if this entity is by a ladder, false otherwise
    1385         */
    1386        public boolean isOnLadder()
    1387        {
    1388            int var1 = MathHelper.floor_double(this.posX);
    1389            int var2 = MathHelper.floor_double(this.boundingBox.minY);
    1390            int var3 = MathHelper.floor_double(this.posZ);
    1391            int var4 = this.worldObj.getBlockId(var1, var2, var3);
    1392            return ForgeHooks.isLivingOnLadder(Block.blocksList[var4], worldObj, var1, var2, var3);
    1393        }
    1394
    1395        /**
    1396         * (abstract) Protected helper method to write subclass entity data to NBT.
    1397         */
    1398        public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
    1399        {
    1400            par1NBTTagCompound.setShort("Health", (short)this.health);
    1401            par1NBTTagCompound.setShort("HurtTime", (short)this.hurtTime);
    1402            par1NBTTagCompound.setShort("DeathTime", (short)this.deathTime);
    1403            par1NBTTagCompound.setShort("AttackTime", (short)this.attackTime);
    1404
    1405            if (!this.activePotionsMap.isEmpty())
    1406            {
    1407                NBTTagList var2 = new NBTTagList();
    1408                Iterator var3 = this.activePotionsMap.values().iterator();
    1409
    1410                while (var3.hasNext())
    1411                {
    1412                    PotionEffect var4 = (PotionEffect)var3.next();
    1413                    NBTTagCompound var5 = new NBTTagCompound();
    1414                    var5.setByte("Id", (byte)var4.getPotionID());
    1415                    var5.setByte("Amplifier", (byte)var4.getAmplifier());
    1416                    var5.setInteger("Duration", var4.getDuration());
    1417                    var2.appendTag(var5);
    1418                }
    1419
    1420                par1NBTTagCompound.setTag("ActiveEffects", var2);
    1421            }
    1422        }
    1423
    1424        /**
    1425         * (abstract) Protected helper method to read subclass entity data from NBT.
    1426         */
    1427        public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
    1428        {
    1429            if (this.health < -32768)
    1430            {
    1431                this.health = -32768;
    1432            }
    1433
    1434            this.health = par1NBTTagCompound.getShort("Health");
    1435
    1436            if (!par1NBTTagCompound.hasKey("Health"))
    1437            {
    1438                this.health = this.getMaxHealth();
    1439            }
    1440
    1441            this.hurtTime = par1NBTTagCompound.getShort("HurtTime");
    1442            this.deathTime = par1NBTTagCompound.getShort("DeathTime");
    1443            this.attackTime = par1NBTTagCompound.getShort("AttackTime");
    1444
    1445            if (par1NBTTagCompound.hasKey("ActiveEffects"))
    1446            {
    1447                NBTTagList var2 = par1NBTTagCompound.getTagList("ActiveEffects");
    1448
    1449                for (int var3 = 0; var3 < var2.tagCount(); ++var3)
    1450                {
    1451                    NBTTagCompound var4 = (NBTTagCompound)var2.tagAt(var3);
    1452                    byte var5 = var4.getByte("Id");
    1453                    byte var6 = var4.getByte("Amplifier");
    1454                    int var7 = var4.getInteger("Duration");
    1455                    this.activePotionsMap.put(Integer.valueOf(var5), new PotionEffect(var5, var7, var6));
    1456                }
    1457            }
    1458        }
    1459
    1460        /**
    1461         * Checks whether target entity is alive.
    1462         */
    1463        public boolean isEntityAlive()
    1464        {
    1465            return !this.isDead && this.health > 0;
    1466        }
    1467
    1468        public boolean canBreatheUnderwater()
    1469        {
    1470            return false;
    1471        }
    1472
    1473        public void setMoveForward(float par1)
    1474        {
    1475            this.moveForward = par1;
    1476        }
    1477
    1478        public void setJumping(boolean par1)
    1479        {
    1480            this.isJumping = par1;
    1481        }
    1482
    1483        /**
    1484         * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
    1485         * use this to react to sunlight and start to burn.
    1486         */
    1487        public void onLivingUpdate()
    1488        {
    1489            if (this.jumpTicks > 0)
    1490            {
    1491                --this.jumpTicks;
    1492            }
    1493
    1494            if (this.newPosRotationIncrements > 0)
    1495            {
    1496                double var1 = this.posX + (this.newPosX - this.posX) / (double)this.newPosRotationIncrements;
    1497                double var3 = this.posY + (this.newPosY - this.posY) / (double)this.newPosRotationIncrements;
    1498                double var5 = this.posZ + (this.newPosZ - this.posZ) / (double)this.newPosRotationIncrements;
    1499                double var7 = MathHelper.wrapAngleTo180_double(this.newRotationYaw - (double)this.rotationYaw);
    1500                this.rotationYaw = (float)((double)this.rotationYaw + var7 / (double)this.newPosRotationIncrements);
    1501                this.rotationPitch = (float)((double)this.rotationPitch + (this.newRotationPitch - (double)this.rotationPitch) / (double)this.newPosRotationIncrements);
    1502                --this.newPosRotationIncrements;
    1503                this.setPosition(var1, var3, var5);
    1504                this.setRotation(this.rotationYaw, this.rotationPitch);
    1505            }
    1506
    1507            if (Math.abs(this.motionX) < 0.005D)
    1508            {
    1509                this.motionX = 0.0D;
    1510            }
    1511
    1512            if (Math.abs(this.motionY) < 0.005D)
    1513            {
    1514                this.motionY = 0.0D;
    1515            }
    1516
    1517            if (Math.abs(this.motionZ) < 0.005D)
    1518            {
    1519                this.motionZ = 0.0D;
    1520            }
    1521
    1522            this.worldObj.theProfiler.startSection("ai");
    1523
    1524            if (this.isMovementBlocked())
    1525            {
    1526                this.isJumping = false;
    1527                this.moveStrafing = 0.0F;
    1528                this.moveForward = 0.0F;
    1529                this.randomYawVelocity = 0.0F;
    1530            }
    1531            else if (this.isClientWorld())
    1532            {
    1533                if (this.isAIEnabled())
    1534                {
    1535                    this.worldObj.theProfiler.startSection("newAi");
    1536                    this.updateAITasks();
    1537                    this.worldObj.theProfiler.endSection();
    1538                }
    1539                else
    1540                {
    1541                    this.worldObj.theProfiler.startSection("oldAi");
    1542                    this.updateEntityActionState();
    1543                    this.worldObj.theProfiler.endSection();
    1544                    this.rotationYawHead = this.rotationYaw;
    1545                }
    1546            }
    1547
    1548            this.worldObj.theProfiler.endSection();
    1549            this.worldObj.theProfiler.startSection("jump");
    1550
    1551            if (this.isJumping)
    1552            {
    1553                if (!this.isInWater() && !this.handleLavaMovement())
    1554                {
    1555                    if (this.onGround && this.jumpTicks == 0)
    1556                    {
    1557                        this.jump();
    1558                        this.jumpTicks = 10;
    1559                    }
    1560                }
    1561                else
    1562                {
    1563                    this.motionY += 0.03999999910593033D;
    1564                }
    1565            }
    1566            else
    1567            {
    1568                this.jumpTicks = 0;
    1569            }
    1570
    1571            this.worldObj.theProfiler.endSection();
    1572            this.worldObj.theProfiler.startSection("travel");
    1573            this.moveStrafing *= 0.98F;
    1574            this.moveForward *= 0.98F;
    1575            this.randomYawVelocity *= 0.9F;
    1576            float var9 = this.landMovementFactor;
    1577            this.landMovementFactor *= this.getSpeedModifier();
    1578            this.moveEntityWithHeading(this.moveStrafing, this.moveForward);
    1579            this.landMovementFactor = var9;
    1580            this.worldObj.theProfiler.endSection();
    1581            this.worldObj.theProfiler.startSection("push");
    1582
    1583            if (!this.worldObj.isRemote)
    1584            {
    1585                List var2 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D));
    1586
    1587                if (var2 != null && !var2.isEmpty())
    1588                {
    1589                    Iterator var10 = var2.iterator();
    1590
    1591                    while (var10.hasNext())
    1592                    {
    1593                        Entity var4 = (Entity)var10.next();
    1594
    1595                        if (var4.canBePushed())
    1596                        {
    1597                            var4.applyEntityCollision(this);
    1598                        }
    1599                    }
    1600                }
    1601            }
    1602
    1603            this.worldObj.theProfiler.endSection();
    1604        }
    1605
    1606        /**
    1607         * Returns true if the newer Entity AI code should be run
    1608         */
    1609        protected boolean isAIEnabled()
    1610        {
    1611            return false;
    1612        }
    1613
    1614        /**
    1615         * Returns whether the entity is in a local (client) world
    1616         */
    1617        protected boolean isClientWorld()
    1618        {
    1619            return !this.worldObj.isRemote;
    1620        }
    1621
    1622        /**
    1623         * Dead and sleeping entities cannot move
    1624         */
    1625        protected boolean isMovementBlocked()
    1626        {
    1627            return this.health <= 0;
    1628        }
    1629
    1630        public boolean isBlocking()
    1631        {
    1632            return false;
    1633        }
    1634
    1635        /**
    1636         * Causes this entity to do an upwards motion (jumping).
    1637         */
    1638        protected void jump()
    1639        {
    1640            this.motionY = 0.41999998688697815D;
    1641
    1642            if (this.isPotionActive(Potion.jump))
    1643            {
    1644                this.motionY += (double)((float)(this.getActivePotionEffect(Potion.jump).getAmplifier() + 1) * 0.1F);
    1645            }
    1646
    1647            if (this.isSprinting())
    1648            {
    1649                float var1 = this.rotationYaw * 0.017453292F;
    1650                this.motionX -= (double)(MathHelper.sin(var1) * 0.2F);
    1651                this.motionZ += (double)(MathHelper.cos(var1) * 0.2F);
    1652            }
    1653
    1654            this.isAirBorne = true;
    1655            ForgeHooks.onLivingJump(this);
    1656        }
    1657
    1658        /**
    1659         * Determines if an entity can be despawned, used on idle far away entities
    1660         */
    1661        protected boolean canDespawn()
    1662        {
    1663            return true;
    1664        }
    1665
    1666        /**
    1667         * Makes the entity despawn if requirements are reached
    1668         */
    1669        protected void despawnEntity()
    1670        {
    1671            EntityPlayer var1 = this.worldObj.getClosestPlayerToEntity(this, -1.0D);
    1672
    1673            if (var1 != null)
    1674            {
    1675                double var2 = var1.posX - this.posX;
    1676                double var4 = var1.posY - this.posY;
    1677                double var6 = var1.posZ - this.posZ;
    1678                double var8 = var2 * var2 + var4 * var4 + var6 * var6;
    1679
    1680                if (this.canDespawn() && var8 > 16384.0D)
    1681                {
    1682                    this.setDead();
    1683                }
    1684
    1685                if (this.entityAge > 600 && this.rand.nextInt(800) == 0 && var8 > 1024.0D && this.canDespawn())
    1686                {
    1687                    this.setDead();
    1688                }
    1689                else if (var8 < 1024.0D)
    1690                {
    1691                    this.entityAge = 0;
    1692                }
    1693            }
    1694        }
    1695
    1696        protected void updateAITasks()
    1697        {
    1698            ++this.entityAge;
    1699            this.worldObj.theProfiler.startSection("checkDespawn");
    1700            this.despawnEntity();
    1701            this.worldObj.theProfiler.endSection();
    1702            this.worldObj.theProfiler.startSection("sensing");
    1703            this.senses.clearSensingCache();
    1704            this.worldObj.theProfiler.endSection();
    1705            this.worldObj.theProfiler.startSection("targetSelector");
    1706            this.targetTasks.onUpdateTasks();
    1707            this.worldObj.theProfiler.endSection();
    1708            this.worldObj.theProfiler.startSection("goalSelector");
    1709            this.tasks.onUpdateTasks();
    1710            this.worldObj.theProfiler.endSection();
    1711            this.worldObj.theProfiler.startSection("navigation");
    1712            this.navigator.onUpdateNavigation();
    1713            this.worldObj.theProfiler.endSection();
    1714            this.worldObj.theProfiler.startSection("mob tick");
    1715            this.updateAITick();
    1716            this.worldObj.theProfiler.endSection();
    1717            this.worldObj.theProfiler.startSection("controls");
    1718            this.worldObj.theProfiler.startSection("move");
    1719            this.moveHelper.onUpdateMoveHelper();
    1720            this.worldObj.theProfiler.endStartSection("look");
    1721            this.lookHelper.onUpdateLook();
    1722            this.worldObj.theProfiler.endStartSection("jump");
    1723            this.jumpHelper.doJump();
    1724            this.worldObj.theProfiler.endSection();
    1725            this.worldObj.theProfiler.endSection();
    1726        }
    1727
    1728        /**
    1729         * main AI tick function, replaces updateEntityActionState
    1730         */
    1731        protected void updateAITick() {}
    1732
    1733        protected void updateEntityActionState()
    1734        {
    1735            ++this.entityAge;
    1736            this.despawnEntity();
    1737            this.moveStrafing = 0.0F;
    1738            this.moveForward = 0.0F;
    1739            float var1 = 8.0F;
    1740
    1741            if (this.rand.nextFloat() < 0.02F)
    1742            {
    1743                EntityPlayer var2 = this.worldObj.getClosestPlayerToEntity(this, (double)var1);
    1744
    1745                if (var2 != null)
    1746                {
    1747                    this.currentTarget = var2;
    1748                    this.numTicksToChaseTarget = 10 + this.rand.nextInt(20);
    1749                }
    1750                else
    1751                {
    1752                    this.randomYawVelocity = (this.rand.nextFloat() - 0.5F) * 20.0F;
    1753                }
    1754            }
    1755
    1756            if (this.currentTarget != null)
    1757            {
    1758                this.faceEntity(this.currentTarget, 10.0F, (float)this.getVerticalFaceSpeed());
    1759
    1760                if (this.numTicksToChaseTarget-- <= 0 || this.currentTarget.isDead || this.currentTarget.getDistanceSqToEntity(this) > (double)(var1 * var1))
    1761                {
    1762                    this.currentTarget = null;
    1763                }
    1764            }
    1765            else
    1766            {
    1767                if (this.rand.nextFloat() < 0.05F)
    1768                {
    1769                    this.randomYawVelocity = (this.rand.nextFloat() - 0.5F) * 20.0F;
    1770                }
    1771
    1772                this.rotationYaw += this.randomYawVelocity;
    1773                this.rotationPitch = this.defaultPitch;
    1774            }
    1775
    1776            boolean var4 = this.isInWater();
    1777            boolean var3 = this.handleLavaMovement();
    1778
    1779            if (var4 || var3)
    1780            {
    1781                this.isJumping = this.rand.nextFloat() < 0.8F;
    1782            }
    1783        }
    1784
    1785        /**
    1786         * The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently
    1787         * use in wolves.
    1788         */
    1789        public int getVerticalFaceSpeed()
    1790        {
    1791            return 40;
    1792        }
    1793
    1794        /**
    1795         * Changes pitch and yaw so that the entity calling the function is facing the entity provided as an argument.
    1796         */
    1797        public void faceEntity(Entity par1Entity, float par2, float par3)
    1798        {
    1799            double var4 = par1Entity.posX - this.posX;
    1800            double var8 = par1Entity.posZ - this.posZ;
    1801            double var6;
    1802
    1803            if (par1Entity instanceof EntityLiving)
    1804            {
    1805                EntityLiving var10 = (EntityLiving)par1Entity;
    1806                var6 = this.posY + (double)this.getEyeHeight() - (var10.posY + (double)var10.getEyeHeight());
    1807            }
    1808            else
    1809            {
    1810                var6 = (par1Entity.boundingBox.minY + par1Entity.boundingBox.maxY) / 2.0D - (this.posY + (double)this.getEyeHeight());
    1811            }
    1812
    1813            double var14 = (double)MathHelper.sqrt_double(var4 * var4 + var8 * var8);
    1814            float var12 = (float)(Math.atan2(var8, var4) * 180.0D / Math.PI) - 90.0F;
    1815            float var13 = (float)(-(Math.atan2(var6, var14) * 180.0D / Math.PI));
    1816            this.rotationPitch = -this.updateRotation(this.rotationPitch, var13, par3);
    1817            this.rotationYaw = this.updateRotation(this.rotationYaw, var12, par2);
    1818        }
    1819
    1820        /**
    1821         * Arguments: current rotation, intended rotation, max increment.
    1822         */
    1823        private float updateRotation(float par1, float par2, float par3)
    1824        {
    1825            float var4 = MathHelper.wrapAngleTo180_float(par2 - par1);
    1826
    1827            if (var4 > par3)
    1828            {
    1829                var4 = par3;
    1830            }
    1831
    1832            if (var4 < -par3)
    1833            {
    1834                var4 = -par3;
    1835            }
    1836
    1837            return par1 + var4;
    1838        }
    1839
    1840        /**
    1841         * Checks if the entity's current position is a valid location to spawn this entity.
    1842         */
    1843        public boolean getCanSpawnHere()
    1844        {
    1845            return this.worldObj.checkIfAABBIsClear(this.boundingBox) && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(this.boundingBox);
    1846        }
    1847
    1848        /**
    1849         * sets the dead flag. Used when you fall off the bottom of the world.
    1850         */
    1851        protected void kill()
    1852        {
    1853            this.attackEntityFrom(DamageSource.outOfWorld, 4);
    1854        }
    1855
    1856        @SideOnly(Side.CLIENT)
    1857
    1858        /**
    1859         * Returns where in the swing animation the living entity is (from 0 to 1).  Args: partialTickTime
    1860         */
    1861        public float getSwingProgress(float par1)
    1862        {
    1863            float var2 = this.swingProgress - this.prevSwingProgress;
    1864
    1865            if (var2 < 0.0F)
    1866            {
    1867                ++var2;
    1868            }
    1869
    1870            return this.prevSwingProgress + var2 * par1;
    1871        }
    1872
    1873        @SideOnly(Side.CLIENT)
    1874
    1875        /**
    1876         * interpolated position vector
    1877         */
    1878        public Vec3 getPosition(float par1)
    1879        {
    1880            if (par1 == 1.0F)
    1881            {
    1882                return Vec3.getVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ);
    1883            }
    1884            else
    1885            {
    1886                double var2 = this.prevPosX + (this.posX - this.prevPosX) * (double)par1;
    1887                double var4 = this.prevPosY + (this.posY - this.prevPosY) * (double)par1;
    1888                double var6 = this.prevPosZ + (this.posZ - this.prevPosZ) * (double)par1;
    1889                return Vec3.getVec3Pool().getVecFromPool(var2, var4, var6);
    1890            }
    1891        }
    1892
    1893        /**
    1894         * returns a (normalized) vector of where this entity is looking
    1895         */
    1896        public Vec3 getLookVec()
    1897        {
    1898            return this.getLook(1.0F);
    1899        }
    1900
    1901        /**
    1902         * interpolated look vector
    1903         */
    1904        public Vec3 getLook(float par1)
    1905        {
    1906            float var2;
    1907            float var3;
    1908            float var4;
    1909            float var5;
    1910
    1911            if (par1 == 1.0F)
    1912            {
    1913                var2 = MathHelper.cos(-this.rotationYaw * 0.017453292F - (float)Math.PI);
    1914                var3 = MathHelper.sin(-this.rotationYaw * 0.017453292F - (float)Math.PI);
    1915                var4 = -MathHelper.cos(-this.rotationPitch * 0.017453292F);
    1916                var5 = MathHelper.sin(-this.rotationPitch * 0.017453292F);
    1917                return Vec3.getVec3Pool().getVecFromPool((double)(var3 * var4), (double)var5, (double)(var2 * var4));
    1918            }
    1919            else
    1920            {
    1921                var2 = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * par1;
    1922                var3 = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * par1;
    1923                var4 = MathHelper.cos(-var3 * 0.017453292F - (float)Math.PI);
    1924                var5 = MathHelper.sin(-var3 * 0.017453292F - (float)Math.PI);
    1925                float var6 = -MathHelper.cos(-var2 * 0.017453292F);
    1926                float var7 = MathHelper.sin(-var2 * 0.017453292F);
    1927                return Vec3.getVec3Pool().getVecFromPool((double)(var5 * var6), (double)var7, (double)(var4 * var6));
    1928            }
    1929        }
    1930
    1931        @SideOnly(Side.CLIENT)
    1932
    1933        /**
    1934         * Returns render size modifier
    1935         */
    1936        public float getRenderSizeModifier()
    1937        {
    1938            return 1.0F;
    1939        }
    1940
    1941        @SideOnly(Side.CLIENT)
    1942
    1943        /**
    1944         * Performs a ray trace for the distance specified and using the partial tick time. Args: distance, partialTickTime
    1945         */
    1946        public MovingObjectPosition rayTrace(double par1, float par3)
    1947        {
    1948            Vec3 var4 = this.getPosition(par3);
    1949            Vec3 var5 = this.getLook(par3);
    1950            Vec3 var6 = var4.addVector(var5.xCoord * par1, var5.yCoord * par1, var5.zCoord * par1);
    1951            return this.worldObj.rayTraceBlocks(var4, var6);
    1952        }
    1953
    1954        /**
    1955         * Will return how many at most can spawn in a chunk at once.
    1956         */
    1957        public int getMaxSpawnedInChunk()
    1958        {
    1959            return 4;
    1960        }
    1961
    1962        @SideOnly(Side.CLIENT)
    1963
    1964        /**
    1965         * Returns the item that this EntityLiving is holding, if any.
    1966         */
    1967        public ItemStack getHeldItem()
    1968        {
    1969            return null;
    1970        }
    1971
    1972        @SideOnly(Side.CLIENT)
    1973        public void handleHealthUpdate(byte par1)
    1974        {
    1975            if (par1 == 2)
    1976            {
    1977                this.legYaw = 1.5F;
    1978                this.hurtResistantTime = this.maxHurtResistantTime;
    1979                this.hurtTime = this.maxHurtTime = 10;
    1980                this.attackedAtYaw = 0.0F;
    1981                this.worldObj.playSoundAtEntity(this, this.getHurtSound(), this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
    1982                this.attackEntityFrom(DamageSource.generic, 0);
    1983            }
    1984            else if (par1 == 3)
    1985            {
    1986                this.worldObj.playSoundAtEntity(this, this.getDeathSound(), this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
    1987                this.health = 0;
    1988                this.onDeath(DamageSource.generic);
    1989            }
    1990            else
    1991            {
    1992                super.handleHealthUpdate(par1);
    1993            }
    1994        }
    1995
    1996        /**
    1997         * Returns whether player is sleeping or not
    1998         */
    1999        public boolean isPlayerSleeping()
    2000        {
    2001            return false;
    2002        }
    2003
    2004        @SideOnly(Side.CLIENT)
    2005
    2006        /**
    2007         * Gets the Icon Index of the item currently held
    2008         */
    2009        public int getItemIcon(ItemStack par1ItemStack, int par2)
    2010        {
    2011            return par1ItemStack.getIconIndex();
    2012        }
    2013
    2014        protected void updatePotionEffects()
    2015        {
    2016            Iterator var1 = this.activePotionsMap.keySet().iterator();
    2017
    2018            while (var1.hasNext())
    2019            {
    2020                Integer var2 = (Integer)var1.next();
    2021                PotionEffect var3 = (PotionEffect)this.activePotionsMap.get(var2);
    2022
    2023                if (!var3.onUpdate(this) && !this.worldObj.isRemote)
    2024                {
    2025                    var1.remove();
    2026                    this.onFinishedPotionEffect(var3);
    2027                }
    2028            }
    2029
    2030            int var9;
    2031
    2032            if (this.potionsNeedUpdate)
    2033            {
    2034                if (!this.worldObj.isRemote)
    2035                {
    2036                    if (this.activePotionsMap.isEmpty())
    2037                    {
    2038                        this.dataWatcher.updateObject(8, Integer.valueOf(0));
    2039                    }
    2040                    else
    2041                    {
    2042                        var9 = PotionHelper.calcPotionLiquidColor(this.activePotionsMap.values());
    2043                        this.dataWatcher.updateObject(8, Integer.valueOf(var9));
    2044                    }
    2045                }
    2046
    2047                this.potionsNeedUpdate = false;
    2048            }
    2049
    2050            if (this.rand.nextBoolean())
    2051            {
    2052                var9 = this.dataWatcher.getWatchableObjectInt(8);
    2053
    2054                if (var9 > 0)
    2055                {
    2056                    double var10 = (double)(var9 >> 16 & 255) / 255.0D;
    2057                    double var5 = (double)(var9 >> 8 & 255) / 255.0D;
    2058                    double var7 = (double)(var9 >> 0 & 255) / 255.0D;
    2059                    this.worldObj.spawnParticle("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, var10, var5, var7);
    2060                }
    2061            }
    2062        }
    2063
    2064        public void clearActivePotions()
    2065        {
    2066            Iterator var1 = this.activePotionsMap.keySet().iterator();
    2067
    2068            while (var1.hasNext())
    2069            {
    2070                Integer var2 = (Integer)var1.next();
    2071                PotionEffect var3 = (PotionEffect)this.activePotionsMap.get(var2);
    2072
    2073                if (!this.worldObj.isRemote)
    2074                {
    2075                    var1.remove();
    2076                    this.onFinishedPotionEffect(var3);
    2077                }
    2078            }
    2079        }
    2080
    2081        public Collection getActivePotionEffects()
    2082        {
    2083            return this.activePotionsMap.values();
    2084        }
    2085
    2086        public boolean isPotionActive(Potion par1Potion)
    2087        {
    2088            return this.activePotionsMap.containsKey(Integer.valueOf(par1Potion.id));
    2089        }
    2090
    2091        /**
    2092         * returns the PotionEffect for the supplied Potion if it is active, null otherwise.
    2093         */
    2094        public PotionEffect getActivePotionEffect(Potion par1Potion)
    2095        {
    2096            return (PotionEffect)this.activePotionsMap.get(Integer.valueOf(par1Potion.id));
    2097        }
    2098
    2099        /**
    2100         * adds a PotionEffect to the entity
    2101         */
    2102        public void addPotionEffect(PotionEffect par1PotionEffect)
    2103        {
    2104            if (this.isPotionApplicable(par1PotionEffect))
    2105            {
    2106                if (this.activePotionsMap.containsKey(Integer.valueOf(par1PotionEffect.getPotionID())))
    2107                {
    2108                    ((PotionEffect)this.activePotionsMap.get(Integer.valueOf(par1PotionEffect.getPotionID()))).combine(par1PotionEffect);
    2109                    this.onChangedPotionEffect((PotionEffect)this.activePotionsMap.get(Integer.valueOf(par1PotionEffect.getPotionID())));
    2110                }
    2111                else
    2112                {
    2113                    this.activePotionsMap.put(Integer.valueOf(par1PotionEffect.getPotionID()), par1PotionEffect);
    2114                    this.onNewPotionEffect(par1PotionEffect);
    2115                }
    2116            }
    2117        }
    2118
    2119        public boolean isPotionApplicable(PotionEffect par1PotionEffect)
    2120        {
    2121            if (this.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD)
    2122            {
    2123                int var2 = par1PotionEffect.getPotionID();
    2124
    2125                if (var2 == Potion.regeneration.id || var2 == Potion.poison.id)
    2126                {
    2127                    return false;
    2128                }
    2129            }
    2130
    2131            return true;
    2132        }
    2133
    2134        /**
    2135         * Returns true if this entity is undead.
    2136         */
    2137        public boolean isEntityUndead()
    2138        {
    2139            return this.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD;
    2140        }
    2141
    2142        /**
    2143         * input is the potion id to remove from the current active potion effects
    2144         */
    2145        public void removePotionEffect(int par1)
    2146        {
    2147            this.activePotionsMap.remove(Integer.valueOf(par1));
    2148        }
    2149
    2150        protected void onNewPotionEffect(PotionEffect par1PotionEffect)
    2151        {
    2152            this.potionsNeedUpdate = true;
    2153        }
    2154
    2155        protected void onChangedPotionEffect(PotionEffect par1PotionEffect)
    2156        {
    2157            this.potionsNeedUpdate = true;
    2158        }
    2159
    2160        protected void onFinishedPotionEffect(PotionEffect par1PotionEffect)
    2161        {
    2162            this.potionsNeedUpdate = true;
    2163        }
    2164
    2165        /**
    2166         * This method returns a value to be applied directly to entity speed, this factor is less than 1 when a slowdown
    2167         * potion effect is applied, more than 1 when a haste potion effect is applied and 2 for fleeing entities.
    2168         */
    2169        protected float getSpeedModifier()
    2170        {
    2171            float var1 = 1.0F;
    2172
    2173            if (this.isPotionActive(Potion.moveSpeed))
    2174            {
    2175                var1 *= 1.0F + 0.2F * (float)(this.getActivePotionEffect(Potion.moveSpeed).getAmplifier() + 1);
    2176            }
    2177
    2178            if (this.isPotionActive(Potion.moveSlowdown))
    2179            {
    2180                var1 *= 1.0F - 0.15F * (float)(this.getActivePotionEffect(Potion.moveSlowdown).getAmplifier() + 1);
    2181            }
    2182
    2183            return var1;
    2184        }
    2185
    2186        /**
    2187         * Move the entity to the coordinates informed, but keep yaw/pitch values.
    2188         */
    2189        public void setPositionAndUpdate(double par1, double par3, double par5)
    2190        {
    2191            this.setLocationAndAngles(par1, par3, par5, this.rotationYaw, this.rotationPitch);
    2192        }
    2193
    2194        /**
    2195         * If Animal, checks if the age timer is negative
    2196         */
    2197        public boolean isChild()
    2198        {
    2199            return false;
    2200        }
    2201
    2202        /**
    2203         * Get this Entity's EnumCreatureAttribute
    2204         */
    2205        public EnumCreatureAttribute getCreatureAttribute()
    2206        {
    2207            return EnumCreatureAttribute.UNDEFINED;
    2208        }
    2209
    2210        /**
    2211         * Renders broken item particles using the given ItemStack
    2212         */
    2213        public void renderBrokenItemStack(ItemStack par1ItemStack)
    2214        {
    2215            this.worldObj.playSoundAtEntity(this, "random.break", 0.8F, 0.8F + this.worldObj.rand.nextFloat() * 0.4F);
    2216
    2217            for (int var2 = 0; var2 < 5; ++var2)
    2218            {
    2219                Vec3 var3 = Vec3.getVec3Pool().getVecFromPool(((double)this.rand.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D);
    2220                var3.rotateAroundX(-this.rotationPitch * (float)Math.PI / 180.0F);
    2221                var3.rotateAroundY(-this.rotationYaw * (float)Math.PI / 180.0F);
    2222                Vec3 var4 = Vec3.getVec3Pool().getVecFromPool(((double)this.rand.nextFloat() - 0.5D) * 0.3D, (double)(-this.rand.nextFloat()) * 0.6D - 0.3D, 0.6D);
    2223                var4.rotateAroundX(-this.rotationPitch * (float)Math.PI / 180.0F);
    2224                var4.rotateAroundY(-this.rotationYaw * (float)Math.PI / 180.0F);
    2225                var4 = var4.addVector(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ);
    2226                this.worldObj.spawnParticle("iconcrack_" + par1ItemStack.getItem().shiftedIndex, var4.xCoord, var4.yCoord, var4.zCoord, var3.xCoord, var3.yCoord + 0.05D, var3.zCoord);
    2227            }
    2228        }
    2229
    2230        /***
    2231         * Removes all potion effects that have curativeItem as a curative item for its effect
    2232         * @param curativeItem The itemstack we are using to cure potion effects
    2233         */
    2234        public void curePotionEffects(ItemStack curativeItem)
    2235        {
    2236            Iterator<Integer> potionKey = activePotionsMap.keySet().iterator();
    2237
    2238            if (worldObj.isRemote)
    2239            {
    2240                return;
    2241            }
    2242
    2243            while (potionKey.hasNext())
    2244            {
    2245                Integer key = potionKey.next();
    2246                PotionEffect effect = (PotionEffect)activePotionsMap.get(key);
    2247
    2248                if (effect.isCurativeItem(curativeItem))
    2249                {
    2250                    potionKey.remove();
    2251                    onFinishedPotionEffect(effect);
    2252                }
    2253            }
    2254        }
    2255    }