    001    package net.minecraft.entity;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.util.ArrayList;
    006    import java.util.List;
    007    import java.util.Random;
    008    import java.util.UUID;
    009    import net.minecraft.block.Block;
    010    import net.minecraft.block.BlockFluid;
    011    import net.minecraft.block.StepSound;
    012    import net.minecraft.block.material.Material;
    013    import net.minecraft.crash.CrashReport;
    014    import net.minecraft.crash.CrashReportCategory;
    015    import net.minecraft.entity.effect.EntityLightningBolt;
    016    import net.minecraft.entity.item.EntityBoat;
    017    import net.minecraft.entity.item.EntityItem;
    018    import net.minecraft.entity.item.EntityItemFrame;
    019    import net.minecraft.entity.item.EntityMinecart;
    020    import net.minecraft.entity.item.EntityPainting;
    021    import net.minecraft.entity.player.EntityPlayer;
    022    import net.minecraft.item.Item;
    023    import net.minecraft.item.ItemStack;
    024    import net.minecraft.nbt.NBTTagCompound;
    025    import net.minecraft.nbt.NBTTagDouble;
    026    import net.minecraft.nbt.NBTTagFloat;
    027    import net.minecraft.nbt.NBTTagList;
    028    import net.minecraft.server.MinecraftServer;
    029    import net.minecraft.util.AxisAlignedBB;
    030    import net.minecraft.util.DamageSource;
    031    import net.minecraft.util.Direction;
    032    import net.minecraft.util.MathHelper;
    033    import net.minecraft.util.MovingObjectPosition;
    034    import net.minecraft.util.ReportedException;
    035    import net.minecraft.util.StatCollector;
    036    import net.minecraft.util.Vec3;
    037    import net.minecraft.world.Explosion;
    038    import net.minecraft.world.World;
    039    import net.minecraft.world.WorldServer;
    040
    041    public abstract class Entity
    042    {
    043        private static int nextEntityID = 0;
    044        public int entityId;
    045        public double renderDistanceWeight;
    046
    047        /**
    048         * Blocks entities from spawning when they do their AABB check to make sure the spot is clear of entities that can
    049         * prevent spawning.
    050         */
    051        public boolean preventEntitySpawning;
    052
    053        /** The entity that is riding this entity */
    054        public Entity riddenByEntity;
    055
    056        /** The entity we are currently riding */
    057        public Entity ridingEntity;
    058
    059        /** Reference to the World object. */
    060        public World worldObj;
    061        public double prevPosX;
    062        public double prevPosY;
    063        public double prevPosZ;
    064
    065        /** Entity position X */
    066        public double posX;
    067
    068        /** Entity position Y */
    069        public double posY;
    070
    071        /** Entity position Z */
    072        public double posZ;
    073
    074        /** Entity motion X */
    075        public double motionX;
    076
    077        /** Entity motion Y */
    078        public double motionY;
    079
    080        /** Entity motion Z */
    081        public double motionZ;
    082
    083        /** Entity rotation Yaw */
    084        public float rotationYaw;
    085
    086        /** Entity rotation Pitch */
    087        public float rotationPitch;
    088        public float prevRotationYaw;
    089        public float prevRotationPitch;
    090
    091        /** Axis aligned bounding box. */
    092        public final AxisAlignedBB boundingBox;
    093        public boolean onGround;
    094
    095        /**
    096         * True if after a move this entity has collided with something on X- or Z-axis
    097         */
    098        public boolean isCollidedHorizontally;
    099
    100        /**
    101         * True if after a move this entity has collided with something on Y-axis
    102         */
    103        public boolean isCollidedVertically;
    104
    105        /**
    106         * True if after a move this entity has collided with something either vertically or horizontally
    107         */
    108        public boolean isCollided;
    109        public boolean velocityChanged;
    110        protected boolean isInWeb;
    111        public boolean field_70135_K;
    112
    113        /**
    114         * Gets set by setDead, so this must be the flag whether an Entity is dead (inactive may be better term)
    115         */
    116        public boolean isDead;
    117        public float yOffset;
    118
    119        /** How wide this entity is considered to be */
    120        public float width;
    121
    122        /** How high this entity is considered to be */
    123        public float height;
    124
    125        /** The previous ticks distance walked multiplied by 0.6 */
    126        public float prevDistanceWalkedModified;
    127
    128        /** The distance walked multiplied by 0.6 */
    129        public float distanceWalkedModified;
    130        public float field_82151_R;
    131        public float fallDistance;
    132
    133        /**
    134         * The distance that has to be exceeded in order to triger a new step sound and an onEntityWalking event on a block
    135         */
    136        private int nextStepDistance;
    137
    138        /**
    139         * The entity's X coordinate at the previous tick, used to calculate position during rendering routines
    140         */
    141        public double lastTickPosX;
    142
    143        /**
    144         * The entity's Y coordinate at the previous tick, used to calculate position during rendering routines
    145         */
    146        public double lastTickPosY;
    147
    148        /**
    149         * The entity's Z coordinate at the previous tick, used to calculate position during rendering routines
    150         */
    151        public double lastTickPosZ;
    152        public float ySize;
    153
    154        /**
    155         * How high this entity can step up when running into a block to try to get over it (currently make note the entity
    156         * will always step up this amount and not just the amount needed)
    157         */
    158        public float stepHeight;
    159
    160        /**
    161         * Whether this entity won't clip with collision or not (make note it won't disable gravity)
    162         */
    163        public boolean noClip;
    164
    165        /**
    166         * Reduces the velocity applied by entity collisions by the specified percent.
    167         */
    168        public float entityCollisionReduction;
    169        protected Random rand;
    170
    171        /** How many ticks has this entity had ran since being alive */
    172        public int ticksExisted;
    173
    174        /**
    175         * The amount of ticks you have to stand inside of fire before be set on fire
    176         */
    177        public int fireResistance;
    178        private int fire;
    179
    180        /**
    181         * Whether this entity is currently inside of water (if it handles water movement that is)
    182         */
    183        protected boolean inWater;
    184
    185        /**
    186         * Remaining time an entity will be "immune" to further damage after being hurt.
    187         */
    188        public int hurtResistantTime;
    189        private boolean firstUpdate;
    190        @SideOnly(Side.CLIENT)
    191
    192        /** downloadable location of player's skin */
    193        public String skinUrl;
    194        @SideOnly(Side.CLIENT)
    195
    196        /** downloadable location of player's cloak */
    197        public String cloakUrl;
    198        protected boolean isImmuneToFire;
    199        protected DataWatcher dataWatcher;
    200        private double entityRiderPitchDelta;
    201        private double entityRiderYawDelta;
    202
    203        /** Has this entity been added to the chunk its within */
    204        public boolean addedToChunk;
    205        public int chunkCoordX;
    206        public int chunkCoordY;
    207        public int chunkCoordZ;
    208        @SideOnly(Side.CLIENT)
    209        public int serverPosX;
    210        @SideOnly(Side.CLIENT)
    211        public int serverPosY;
    212        @SideOnly(Side.CLIENT)
    213        public int serverPosZ;
    214
    215        /**
    216         * Render entity even if it is outside the camera frustum. Only true in EntityFish for now. Used in RenderGlobal:
    217         * render if ignoreFrustumCheck or in frustum.
    218         */
    219        public boolean ignoreFrustumCheck;
    220        public boolean isAirBorne;
    221        public int timeUntilPortal;
    222
    223        /** Whether the entity is inside a Portal */
    224        protected boolean inPortal;
    225        private int field_82153_h;
    226
    227        /** Which dimension the player is in (-1 = the Nether, 0 = normal world) */
    228        public int dimension;
    229        protected int field_82152_aq;
    230        private boolean field_83001_bt;
    231        public EnumEntitySize myEntitySize;
    232        /** Forge: Used to store custom data for each entity. */
    233        private NBTTagCompound customEntityData;
    234        public boolean captureDrops = false;
    235        public ArrayList<EntityItem> capturedDrops = new ArrayList<EntityItem>();
    236        private UUID persistentID;
    237
    238        public Entity(World par1World)
    239        {
    240            this.entityId = nextEntityID++;
    241            this.renderDistanceWeight = 1.0D;
    242            this.preventEntitySpawning = false;
    243            this.boundingBox = AxisAlignedBB.getBoundingBox(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D);
    244            this.onGround = false;
    245            this.isCollided = false;
    246            this.velocityChanged = false;
    247            this.field_70135_K = true;
    248            this.isDead = false;
    249            this.yOffset = 0.0F;
    250            this.width = 0.6F;
    251            this.height = 1.8F;
    252            this.prevDistanceWalkedModified = 0.0F;
    253            this.distanceWalkedModified = 0.0F;
    254            this.field_82151_R = 0.0F;
    255            this.fallDistance = 0.0F;
    256            this.nextStepDistance = 1;
    257            this.ySize = 0.0F;
    258            this.stepHeight = 0.0F;
    259            this.noClip = false;
    260            this.entityCollisionReduction = 0.0F;
    261            this.rand = new Random();
    262            this.ticksExisted = 0;
    263            this.fireResistance = 1;
    264            this.fire = 0;
    265            this.inWater = false;
    266            this.hurtResistantTime = 0;
    267            this.firstUpdate = true;
    268            this.isImmuneToFire = false;
    269            this.dataWatcher = new DataWatcher();
    270            this.addedToChunk = false;
    271            this.field_82152_aq = 0;
    272            this.field_83001_bt = false;
    273            this.myEntitySize = EnumEntitySize.SIZE_2;
    274            this.worldObj = par1World;
    275            this.setPosition(0.0D, 0.0D, 0.0D);
    276
    277            if (par1World != null)
    278            {
    279                this.dimension = par1World.provider.dimensionId;
    280            }
    281
    282            this.dataWatcher.addObject(0, Byte.valueOf((byte)0));
    283            this.dataWatcher.addObject(1, Short.valueOf((short)300));
    284            this.entityInit();
    285        }
    286
    287        protected abstract void entityInit();
    288
    289        public DataWatcher getDataWatcher()
    290        {
    291            return this.dataWatcher;
    292        }
    293
    294        public boolean equals(Object par1Obj)
    295        {
    296            return par1Obj instanceof Entity ? ((Entity)par1Obj).entityId == this.entityId : false;
    297        }
    298
    299        public int hashCode()
    300        {
    301            return this.entityId;
    302        }
    303
    304        @SideOnly(Side.CLIENT)
    305
    306        /**
    307         * Keeps moving the entity up so it isn't colliding with blocks and other requirements for this entity to be spawned
    308         * (only actually used on players though its also on Entity)
    309         */
    310        protected void preparePlayerToSpawn()
    311        {
    312            if (this.worldObj != null)
    313            {
    314                while (this.posY > 0.0D)
    315                {
    316                    this.setPosition(this.posX, this.posY, this.posZ);
    317
    318                    if (this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty())
    319                    {
    320                        break;
    321                    }
    322
    323                    ++this.posY;
    324                }
    325
    326                this.motionX = this.motionY = this.motionZ = 0.0D;
    327                this.rotationPitch = 0.0F;
    328            }
    329        }
    330
    331        /**
    332         * Will get destroyed next tick.
    333         */
    334        public void setDead()
    335        {
    336            this.isDead = true;
    337        }
    338
    339        /**
    340         * Sets the width and height of the entity. Args: width, height
    341         */
    342        protected void setSize(float par1, float par2)
    343        {
    344            this.width = par1;
    345            this.height = par2;
    346            float var3 = par1 % 2.0F;
    347
    348            if ((double)var3 < 0.375D)
    349            {
    350                this.myEntitySize = EnumEntitySize.SIZE_1;
    351            }
    352            else if ((double)var3 < 0.75D)
    353            {
    354                this.myEntitySize = EnumEntitySize.SIZE_2;
    355            }
    356            else if ((double)var3 < 1.0D)
    357            {
    358                this.myEntitySize = EnumEntitySize.SIZE_3;
    359            }
    360            else if ((double)var3 < 1.375D)
    361            {
    362                this.myEntitySize = EnumEntitySize.SIZE_4;
    363            }
    364            else if ((double)var3 < 1.75D)
    365            {
    366                this.myEntitySize = EnumEntitySize.SIZE_5;
    367            }
    368            else
    369            {
    370                this.myEntitySize = EnumEntitySize.SIZE_6;
    371            }
    372        }
    373
    374        /**
    375         * Sets the rotation of the entity
    376         */
    377        protected void setRotation(float par1, float par2)
    378        {
    379            this.rotationYaw = par1 % 360.0F;
    380            this.rotationPitch = par2 % 360.0F;
    381        }
    382
    383        /**
    384         * Sets the x,y,z of the entity from the given parameters. Also seems to set up a bounding box.
    385         */
    386        public void setPosition(double par1, double par3, double par5)
    387        {
    388            this.posX = par1;
    389            this.posY = par3;
    390            this.posZ = par5;
    391            float var7 = this.width / 2.0F;
    392            float var8 = this.height;
    393            this.boundingBox.setBounds(par1 - (double)var7, par3 - (double)this.yOffset + (double)this.ySize, par5 - (double)var7, par1 + (double)var7, par3 - (double)this.yOffset + (double)this.ySize + (double)var8, par5 + (double)var7);
    394        }
    395
    396        @SideOnly(Side.CLIENT)
    397
    398        /**
    399         * Adds par1*0.15 to the entity's yaw, and *subtracts* par2*0.15 from the pitch. Clamps pitch from -90 to 90. Both
    400         * arguments in degrees.
    401         */
    402        public void setAngles(float par1, float par2)
    403        {
    404            float var3 = this.rotationPitch;
    405            float var4 = this.rotationYaw;
    406            this.rotationYaw = (float)((double)this.rotationYaw + (double)par1 * 0.15D);
    407            this.rotationPitch = (float)((double)this.rotationPitch - (double)par2 * 0.15D);
    408
    409            if (this.rotationPitch < -90.0F)
    410            {
    411                this.rotationPitch = -90.0F;
    412            }
    413
    414            if (this.rotationPitch > 90.0F)
    415            {
    416                this.rotationPitch = 90.0F;
    417            }
    418
    419            this.prevRotationPitch += this.rotationPitch - var3;
    420            this.prevRotationYaw += this.rotationYaw - var4;
    421        }
    422
    423        /**
    424         * Called to update the entity's position/logic.
    425         */
    426        public void onUpdate()
    427        {
    428            this.onEntityUpdate();
    429        }
    430
    431        /**
    432         * Gets called every tick from main Entity class
    433         */
    434        public void onEntityUpdate()
    435        {
    436            this.worldObj.theProfiler.startSection("entityBaseTick");
    437
    438            if (this.ridingEntity != null && this.ridingEntity.isDead)
    439            {
    440                this.ridingEntity = null;
    441            }
    442
    443            ++this.ticksExisted;
    444            this.prevDistanceWalkedModified = this.distanceWalkedModified;
    445            this.prevPosX = this.posX;
    446            this.prevPosY = this.posY;
    447            this.prevPosZ = this.posZ;
    448            this.prevRotationPitch = this.rotationPitch;
    449            this.prevRotationYaw = this.rotationYaw;
    450            int var2;
    451
    452            if (!this.worldObj.isRemote && this.worldObj instanceof WorldServer)
    453            {
    454                this.worldObj.theProfiler.startSection("portal");
    455                MinecraftServer var1 = ((WorldServer)this.worldObj).getMinecraftServer();
    456                var2 = this.getMaxInPortalTime();
    457
    458                if (this.inPortal)
    459                {
    460                    if (var1.getAllowNether())
    461                    {
    462                        if (this.ridingEntity == null && this.field_82153_h++ >= var2)
    463                        {
    464                            this.field_82153_h = var2;
    465                            this.timeUntilPortal = this.getPortalCooldown();
    466                            byte var3;
    467
    468                            if (this.worldObj.provider.dimensionId == -1)
    469                            {
    470                                var3 = 0;
    471                            }
    472                            else
    473                            {
    474                                var3 = -1;
    475                            }
    476
    477                            this.travelToDimension(var3);
    478                        }
    479
    480                        this.inPortal = false;
    481                    }
    482                }
    483                else
    484                {
    485                    if (this.field_82153_h > 0)
    486                    {
    487                        this.field_82153_h -= 4;
    488                    }
    489
    490                    if (this.field_82153_h < 0)
    491                    {
    492                        this.field_82153_h = 0;
    493                    }
    494                }
    495
    496                if (this.timeUntilPortal > 0)
    497                {
    498                    --this.timeUntilPortal;
    499                }
    500
    501                this.worldObj.theProfiler.endSection();
    502            }
    503
    504            if (this.isSprinting() && !this.isInWater())
    505            {
    506                int var5 = MathHelper.floor_double(this.posX);
    507                var2 = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double)this.yOffset);
    508                int var6 = MathHelper.floor_double(this.posZ);
    509                int var4 = this.worldObj.getBlockId(var5, var2, var6);
    510
    511                if (var4 > 0)
    512                {
    513                    this.worldObj.spawnParticle("tilecrack_" + var4 + "_" + this.worldObj.getBlockMetadata(var5, var2, var6), this.posX + ((double)this.rand.nextFloat() - 0.5D) * (double)this.width, this.boundingBox.minY + 0.1D, this.posZ + ((double)this.rand.nextFloat() - 0.5D) * (double)this.width, -this.motionX * 4.0D, 1.5D, -this.motionZ * 4.0D);
    514                }
    515            }
    516
    517            this.handleWaterMovement();
    518
    519            if (this.worldObj.isRemote)
    520            {
    521                this.fire = 0;
    522            }
    523            else if (this.fire > 0)
    524            {
    525                if (this.isImmuneToFire)
    526                {
    527                    this.fire -= 4;
    528
    529                    if (this.fire < 0)
    530                    {
    531                        this.fire = 0;
    532                    }
    533                }
    534                else
    535                {
    536                    if (this.fire % 20 == 0)
    537                    {
    538                        this.attackEntityFrom(DamageSource.onFire, 1);
    539                    }
    540
    541                    --this.fire;
    542                }
    543            }
    544
    545            if (this.handleLavaMovement())
    546            {
    547                this.setOnFireFromLava();
    548                this.fallDistance *= 0.5F;
    549            }
    550
    551            if (this.posY < -64.0D)
    552            {
    553                this.kill();
    554            }
    555
    556            if (!this.worldObj.isRemote)
    557            {
    558                this.setFlag(0, this.fire > 0);
    559                this.setFlag(2, this.ridingEntity != null && ridingEntity.shouldRiderSit());
    560            }
    561
    562            this.firstUpdate = false;
    563            this.worldObj.theProfiler.endSection();
    564        }
    565
    566        /**
    567         * Return the amount of time this entity should stay in a portal before being transported.
    568         */
    569        public int getMaxInPortalTime()
    570        {
    571            return 0;
    572        }
    573
    574        /**
    575         * Called whenever the entity is walking inside of lava.
    576         */
    577        protected void setOnFireFromLava()
    578        {
    579            if (!this.isImmuneToFire)
    580            {
    581                this.attackEntityFrom(DamageSource.lava, 4);
    582                this.setFire(15);
    583            }
    584        }
    585
    586        /**
    587         * Sets entity to burn for x amount of seconds, cannot lower amount of existing fire.
    588         */
    589        public void setFire(int par1)
    590        {
    591            int var2 = par1 * 20;
    592
    593            if (this.fire < var2)
    594            {
    595                this.fire = var2;
    596            }
    597        }
    598
    599        /**
    600         * Removes fire from entity.
    601         */
    602        public void extinguish()
    603        {
    604            this.fire = 0;
    605        }
    606
    607        /**
    608         * sets the dead flag. Used when you fall off the bottom of the world.
    609         */
    610        protected void kill()
    611        {
    612            this.setDead();
    613        }
    614
    615        /**
    616         * Checks if the offset position from the entity's current position is inside of liquid. Args: x, y, z
    617         */
    618        public boolean isOffsetPositionInLiquid(double par1, double par3, double par5)
    619        {
    620            AxisAlignedBB var7 = this.boundingBox.getOffsetBoundingBox(par1, par3, par5);
    621            List var8 = this.worldObj.getCollidingBoundingBoxes(this, var7);
    622            return !var8.isEmpty() ? false : !this.worldObj.isAnyLiquid(var7);
    623        }
    624
    625        /**
    626         * Tries to moves the entity by the passed in displacement. Args: x, y, z
    627         */
    628        public void moveEntity(double par1, double par3, double par5)
    629        {
    630            if (this.noClip)
    631            {
    632                this.boundingBox.offset(par1, par3, par5);
    633                this.posX = (this.boundingBox.minX + this.boundingBox.maxX) / 2.0D;
    634                this.posY = this.boundingBox.minY + (double)this.yOffset - (double)this.ySize;
    635                this.posZ = (this.boundingBox.minZ + this.boundingBox.maxZ) / 2.0D;
    636            }
    637            else
    638            {
    639                this.worldObj.theProfiler.startSection("move");
    640                this.ySize *= 0.4F;
    641                double var7 = this.posX;
    642                double var9 = this.posY;
    643                double var11 = this.posZ;
    644
    645                if (this.isInWeb)
    646                {
    647                    this.isInWeb = false;
    648                    par1 *= 0.25D;
    649                    par3 *= 0.05000000074505806D;
    650                    par5 *= 0.25D;
    651                    this.motionX = 0.0D;
    652                    this.motionY = 0.0D;
    653                    this.motionZ = 0.0D;
    654                }
    655
    656                double var13 = par1;
    657                double var15 = par3;
    658                double var17 = par5;
    659                AxisAlignedBB var19 = this.boundingBox.copy();
    660                boolean var20 = this.onGround && this.isSneaking() && this instanceof EntityPlayer;
    661
    662                if (var20)
    663                {
    664                    double var21;
    665
    666                    for (var21 = 0.05D; par1 != 0.0D && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.getOffsetBoundingBox(par1, -1.0D, 0.0D)).isEmpty(); var13 = par1)
    667                    {
    668                        if (par1 < var21 && par1 >= -var21)
    669                        {
    670                            par1 = 0.0D;
    671                        }
    672                        else if (par1 > 0.0D)
    673                        {
    674                            par1 -= var21;
    675                        }
    676                        else
    677                        {
    678                            par1 += var21;
    679                        }
    680                    }
    681
    682                    for (; par5 != 0.0D && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.getOffsetBoundingBox(0.0D, -1.0D, par5)).isEmpty(); var17 = par5)
    683                    {
    684                        if (par5 < var21 && par5 >= -var21)
    685                        {
    686                            par5 = 0.0D;
    687                        }
    688                        else if (par5 > 0.0D)
    689                        {
    690                            par5 -= var21;
    691                        }
    692                        else
    693                        {
    694                            par5 += var21;
    695                        }
    696                    }
    697
    698                    while (par1 != 0.0D && par5 != 0.0D && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.getOffsetBoundingBox(par1, -1.0D, par5)).isEmpty())
    699                    {
    700                        if (par1 < var21 && par1 >= -var21)
    701                        {
    702                            par1 = 0.0D;
    703                        }
    704                        else if (par1 > 0.0D)
    705                        {
    706                            par1 -= var21;
    707                        }
    708                        else
    709                        {
    710                            par1 += var21;
    711                        }
    712
    713                        if (par5 < var21 && par5 >= -var21)
    714                        {
    715                            par5 = 0.0D;
    716                        }
    717                        else if (par5 > 0.0D)
    718                        {
    719                            par5 -= var21;
    720                        }
    721                        else
    722                        {
    723                            par5 += var21;
    724                        }
    725
    726                        var13 = par1;
    727                        var17 = par5;
    728                    }
    729                }
    730
    731                List var35 = this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.addCoord(par1, par3, par5));
    732
    733                for (int var22 = 0; var22 < var35.size(); ++var22)
    734                {
    735                    par3 = ((AxisAlignedBB)var35.get(var22)).calculateYOffset(this.boundingBox, par3);
    736                }
    737
    738                this.boundingBox.offset(0.0D, par3, 0.0D);
    739
    740                if (!this.field_70135_K && var15 != par3)
    741                {
    742                    par5 = 0.0D;
    743                    par3 = 0.0D;
    744                    par1 = 0.0D;
    745                }
    746
    747                boolean var34 = this.onGround || var15 != par3 && var15 < 0.0D;
    748                int var23;
    749
    750                for (var23 = 0; var23 < var35.size(); ++var23)
    751                {
    752                    par1 = ((AxisAlignedBB)var35.get(var23)).calculateXOffset(this.boundingBox, par1);
    753                }
    754
    755                this.boundingBox.offset(par1, 0.0D, 0.0D);
    756
    757                if (!this.field_70135_K && var13 != par1)
    758                {
    759                    par5 = 0.0D;
    760                    par3 = 0.0D;
    761                    par1 = 0.0D;
    762                }
    763
    764                for (var23 = 0; var23 < var35.size(); ++var23)
    765                {
    766                    par5 = ((AxisAlignedBB)var35.get(var23)).calculateZOffset(this.boundingBox, par5);
    767                }
    768
    769                this.boundingBox.offset(0.0D, 0.0D, par5);
    770
    771                if (!this.field_70135_K && var17 != par5)
    772                {
    773                    par5 = 0.0D;
    774                    par3 = 0.0D;
    775                    par1 = 0.0D;
    776                }
    777
    778                double var25;
    779                double var27;
    780                int var30;
    781                double var36;
    782
    783                if (this.stepHeight > 0.0F && var34 && (var20 || this.ySize < 0.05F) && (var13 != par1 || var17 != par5))
    784                {
    785                    var36 = par1;
    786                    var25 = par3;
    787                    var27 = par5;
    788                    par1 = var13;
    789                    par3 = (double)this.stepHeight;
    790                    par5 = var17;
    791                    AxisAlignedBB var29 = this.boundingBox.copy();
    792                    this.boundingBox.setBB(var19);
    793                    var35 = this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.addCoord(var13, par3, var17));
    794
    795                    for (var30 = 0; var30 < var35.size(); ++var30)
    796                    {
    797                        par3 = ((AxisAlignedBB)var35.get(var30)).calculateYOffset(this.boundingBox, par3);
    798                    }
    799
    800                    this.boundingBox.offset(0.0D, par3, 0.0D);
    801
    802                    if (!this.field_70135_K && var15 != par3)
    803                    {
    804                        par5 = 0.0D;
    805                        par3 = 0.0D;
    806                        par1 = 0.0D;
    807                    }
    808
    809                    for (var30 = 0; var30 < var35.size(); ++var30)
    810                    {
    811                        par1 = ((AxisAlignedBB)var35.get(var30)).calculateXOffset(this.boundingBox, par1);
    812                    }
    813
    814                    this.boundingBox.offset(par1, 0.0D, 0.0D);
    815
    816                    if (!this.field_70135_K && var13 != par1)
    817                    {
    818                        par5 = 0.0D;
    819                        par3 = 0.0D;
    820                        par1 = 0.0D;
    821                    }
    822
    823                    for (var30 = 0; var30 < var35.size(); ++var30)
    824                    {
    825                        par5 = ((AxisAlignedBB)var35.get(var30)).calculateZOffset(this.boundingBox, par5);
    826                    }
    827
    828                    this.boundingBox.offset(0.0D, 0.0D, par5);
    829
    830                    if (!this.field_70135_K && var17 != par5)
    831                    {
    832                        par5 = 0.0D;
    833                        par3 = 0.0D;
    834                        par1 = 0.0D;
    835                    }
    836
    837                    if (!this.field_70135_K && var15 != par3)
    838                    {
    839                        par5 = 0.0D;
    840                        par3 = 0.0D;
    841                        par1 = 0.0D;
    842                    }
    843                    else
    844                    {
    845                        par3 = (double)(-this.stepHeight);
    846
    847                        for (var30 = 0; var30 < var35.size(); ++var30)
    848                        {
    849                            par3 = ((AxisAlignedBB)var35.get(var30)).calculateYOffset(this.boundingBox, par3);
    850                        }
    851
    852                        this.boundingBox.offset(0.0D, par3, 0.0D);
    853                    }
    854
    855                    if (var36 * var36 + var27 * var27 >= par1 * par1 + par5 * par5)
    856                    {
    857                        par1 = var36;
    858                        par3 = var25;
    859                        par5 = var27;
    860                        this.boundingBox.setBB(var29);
    861                    }
    862                    else
    863                    {
    864                        double var40 = this.boundingBox.minY - (double)((int)this.boundingBox.minY);
    865
    866                        if (var40 > 0.0D)
    867                        {
    868                            this.ySize = (float)((double)this.ySize + var40 + 0.01D);
    869                        }
    870                    }
    871                }
    872
    873                this.worldObj.theProfiler.endSection();
    874                this.worldObj.theProfiler.startSection("rest");
    875                this.posX = (this.boundingBox.minX + this.boundingBox.maxX) / 2.0D;
    876                this.posY = this.boundingBox.minY + (double)this.yOffset - (double)this.ySize;
    877                this.posZ = (this.boundingBox.minZ + this.boundingBox.maxZ) / 2.0D;
    878                this.isCollidedHorizontally = var13 != par1 || var17 != par5;
    879                this.isCollidedVertically = var15 != par3;
    880                this.onGround = var15 != par3 && var15 < 0.0D;
    881                this.isCollided = this.isCollidedHorizontally || this.isCollidedVertically;
    882                this.updateFallState(par3, this.onGround);
    883
    884                if (var13 != par1)
    885                {
    886                    this.motionX = 0.0D;
    887                }
    888
    889                if (var15 != par3)
    890                {
    891                    this.motionY = 0.0D;
    892                }
    893
    894                if (var17 != par5)
    895                {
    896                    this.motionZ = 0.0D;
    897                }
    898
    899                var36 = this.posX - var7;
    900                var25 = this.posY - var9;
    901                var27 = this.posZ - var11;
    902
    903                if (this.canTriggerWalking() && !var20 && this.ridingEntity == null)
    904                {
    905                    int var37 = MathHelper.floor_double(this.posX);
    906                    var30 = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double)this.yOffset);
    907                    int var31 = MathHelper.floor_double(this.posZ);
    908                    int var32 = this.worldObj.getBlockId(var37, var30, var31);
    909
    910                    if (var32 == 0)
    911                    {
    912                        int var33 = this.worldObj.func_85175_e(var37, var30 - 1, var31);
    913
    914                        if (var33 == 11 || var33 == 32 || var33 == 21)
    915                        {
    916                            var32 = this.worldObj.getBlockId(var37, var30 - 1, var31);
    917                        }
    918                    }
    919
    920                    if (var32 != Block.ladder.blockID)
    921                    {
    922                        var25 = 0.0D;
    923                    }
    924
    925                    this.distanceWalkedModified = (float)((double)this.distanceWalkedModified + (double)MathHelper.sqrt_double(var36 * var36 + var27 * var27) * 0.6D);
    926                    this.field_82151_R = (float)((double)this.field_82151_R + (double)MathHelper.sqrt_double(var36 * var36 + var25 * var25 + var27 * var27) * 0.6D);
    927
    928                    if (this.field_82151_R > (float)this.nextStepDistance && var32 > 0)
    929                    {
    930                        this.nextStepDistance = (int)this.field_82151_R + 1;
    931
    932                        if (this.isInWater())
    933                        {
    934                            float var39 = MathHelper.sqrt_double(this.motionX * this.motionX * 0.20000000298023224D + this.motionY * this.motionY + this.motionZ * this.motionZ * 0.20000000298023224D) * 0.35F;
    935
    936                            if (var39 > 1.0F)
    937                            {
    938                                var39 = 1.0F;
    939                            }
    940
    941                            this.func_85030_a("liquid.swim", var39, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F);
    942                        }
    943
    944                        this.playStepSound(var37, var30, var31, var32);
    945                        Block.blocksList[var32].onEntityWalking(this.worldObj, var37, var30, var31, this);
    946                    }
    947                }
    948
    949                this.doBlockCollisions();
    950                boolean var38 = this.isWet();
    951
    952                if (this.worldObj.isBoundingBoxBurning(this.boundingBox.contract(0.001D, 0.001D, 0.001D)))
    953                {
    954                    this.dealFireDamage(1);
    955
    956                    if (!var38)
    957                    {
    958                        ++this.fire;
    959
    960                        if (this.fire == 0)
    961                        {
    962                            this.setFire(8);
    963                        }
    964                    }
    965                }
    966                else if (this.fire <= 0)
    967                {
    968                    this.fire = -this.fireResistance;
    969                }
    970
    971                if (var38 && this.fire > 0)
    972                {
    973                    this.func_85030_a("random.fizz", 0.7F, 1.6F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F);
    974                    this.fire = -this.fireResistance;
    975                }
    976
    977                this.worldObj.theProfiler.endSection();
    978            }
    979        }
    980
    981        /**
    982         * Checks for block collisions, and calls the associated onBlockCollided method for the collided block.
    983         */
    984        protected void doBlockCollisions()
    985        {
    986            int var1 = MathHelper.floor_double(this.boundingBox.minX + 0.001D);
    987            int var2 = MathHelper.floor_double(this.boundingBox.minY + 0.001D);
    988            int var3 = MathHelper.floor_double(this.boundingBox.minZ + 0.001D);
    989            int var4 = MathHelper.floor_double(this.boundingBox.maxX - 0.001D);
    990            int var5 = MathHelper.floor_double(this.boundingBox.maxY - 0.001D);
    991            int var6 = MathHelper.floor_double(this.boundingBox.maxZ - 0.001D);
    992
    993            if (this.worldObj.checkChunksExist(var1, var2, var3, var4, var5, var6))
    994            {
    995                for (int var7 = var1; var7 <= var4; ++var7)
    996                {
    997                    for (int var8 = var2; var8 <= var5; ++var8)
    998                    {
    999                        for (int var9 = var3; var9 <= var6; ++var9)
    1000                        {
    1001                            int var10 = this.worldObj.getBlockId(var7, var8, var9);
    1002
    1003                            if (var10 > 0)
    1004                            {
    1005                                Block.blocksList[var10].onEntityCollidedWithBlock(this.worldObj, var7, var8, var9, this);
    1006                            }
    1007                        }
    1008                    }
    1009                }
    1010            }
    1011        }
    1012
    1013        /**
    1014         * Plays step sound at given x, y, z for the entity
    1015         */
    1016        protected void playStepSound(int par1, int par2, int par3, int par4)
    1017        {
    1018            StepSound var5 = Block.blocksList[par4].stepSound;
    1019
    1020            if (this.worldObj.getBlockId(par1, par2 + 1, par3) == Block.snow.blockID)
    1021            {
    1022                var5 = Block.snow.stepSound;
    1023                this.func_85030_a(var5.getStepSound(), var5.getVolume() * 0.15F, var5.getPitch());
    1024            }
    1025            else if (!Block.blocksList[par4].blockMaterial.isLiquid())
    1026            {
    1027                this.func_85030_a(var5.getStepSound(), var5.getVolume() * 0.15F, var5.getPitch());
    1028            }
    1029        }
    1030
    1031        protected void func_85030_a(String par1Str, float par2, float par3)
    1032        {
    1033            this.worldObj.playSoundAtEntity(this, par1Str, par2, par3);
    1034        }
    1035
    1036        /**
    1037         * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
    1038         * prevent them from trampling crops
    1039         */
    1040        protected boolean canTriggerWalking()
    1041        {
    1042            return true;
    1043        }
    1044
    1045        /**
    1046         * Takes in the distance the entity has fallen this tick and whether its on the ground to update the fall distance
    1047         * and deal fall damage if landing on the ground.  Args: distanceFallenThisTick, onGround
    1048         */
    1049        protected void updateFallState(double par1, boolean par3)
    1050        {
    1051            if (par3)
    1052            {
    1053                if (this.fallDistance > 0.0F)
    1054                {
    1055                    this.fall(this.fallDistance);
    1056                    this.fallDistance = 0.0F;
    1057                }
    1058            }
    1059            else if (par1 < 0.0D)
    1060            {
    1061                this.fallDistance = (float)((double)this.fallDistance - par1);
    1062            }
    1063        }
    1064
    1065        /**
    1066         * returns the bounding box for this entity
    1067         */
    1068        public AxisAlignedBB getBoundingBox()
    1069        {
    1070            return null;
    1071        }
    1072
    1073        /**
    1074         * Will deal the specified amount of damage to the entity if the entity isn't immune to fire damage. Args:
    1075         * amountDamage
    1076         */
    1077        protected void dealFireDamage(int par1)
    1078        {
    1079            if (!this.isImmuneToFire)
    1080            {
    1081                this.attackEntityFrom(DamageSource.inFire, par1);
    1082            }
    1083        }
    1084
    1085        public final boolean isImmuneToFire()
    1086        {
    1087            return this.isImmuneToFire;
    1088        }
    1089
    1090        /**
    1091         * Called when the mob is falling. Calculates and applies fall damage.
    1092         */
    1093        protected void fall(float par1)
    1094        {
    1095            if (this.riddenByEntity != null)
    1096            {
    1097                this.riddenByEntity.fall(par1);
    1098            }
    1099        }
    1100
    1101        /**
    1102         * Checks if this entity is either in water or on an open air block in rain (used in wolves).
    1103         */
    1104        public boolean isWet()
    1105        {
    1106            return this.inWater || this.worldObj.canLightningStrikeAt(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) || this.worldObj.canLightningStrikeAt(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY + (double)this.height), MathHelper.floor_double(this.posZ));
    1107        }
    1108
    1109        /**
    1110         * Checks if this entity is inside water (if inWater field is true as a result of handleWaterMovement() returning
    1111         * true)
    1112         */
    1113        public boolean isInWater()
    1114        {
    1115            return this.inWater;
    1116        }
    1117
    1118        /**
    1119         * Returns if this entity is in water and will end up adding the waters velocity to the entity
    1120         */
    1121        public boolean handleWaterMovement()
    1122        {
    1123            if (this.worldObj.handleMaterialAcceleration(this.boundingBox.expand(0.0D, -0.4000000059604645D, 0.0D).contract(0.001D, 0.001D, 0.001D), Material.water, this))
    1124            {
    1125                if (!this.inWater && !this.firstUpdate)
    1126                {
    1127                    float var1 = MathHelper.sqrt_double(this.motionX * this.motionX * 0.20000000298023224D + this.motionY * this.motionY + this.motionZ * this.motionZ * 0.20000000298023224D) * 0.2F;
    1128
    1129                    if (var1 > 1.0F)
    1130                    {
    1131                        var1 = 1.0F;
    1132                    }
    1133
    1134                    this.func_85030_a("liquid.splash", var1, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F);
    1135                    float var2 = (float)MathHelper.floor_double(this.boundingBox.minY);
    1136                    int var3;
    1137                    float var4;
    1138                    float var5;
    1139
    1140                    for (var3 = 0; (float)var3 < 1.0F + this.width * 20.0F; ++var3)
    1141                    {
    1142                        var4 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width;
    1143                        var5 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width;
    1144                        this.worldObj.spawnParticle("bubble", this.posX + (double)var4, (double)(var2 + 1.0F), this.posZ + (double)var5, this.motionX, this.motionY - (double)(this.rand.nextFloat() * 0.2F), this.motionZ);
    1145                    }
    1146
    1147                    for (var3 = 0; (float)var3 < 1.0F + this.width * 20.0F; ++var3)
    1148                    {
    1149                        var4 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width;
    1150                        var5 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width;
    1151                        this.worldObj.spawnParticle("splash", this.posX + (double)var4, (double)(var2 + 1.0F), this.posZ + (double)var5, this.motionX, this.motionY, this.motionZ);
    1152                    }
    1153                }
    1154
    1155                this.fallDistance = 0.0F;
    1156                this.inWater = true;
    1157                this.fire = 0;
    1158            }
    1159            else
    1160            {
    1161                this.inWater = false;
    1162            }
    1163
    1164            return this.inWater;
    1165        }
    1166
    1167        /**
    1168         * Checks if the current block the entity is within of the specified material type
    1169         */
    1170        public boolean isInsideOfMaterial(Material par1Material)
    1171        {
    1172            double var2 = this.posY + (double)this.getEyeHeight();
    1173            int var4 = MathHelper.floor_double(this.posX);
    1174            int var5 = MathHelper.floor_float((float)MathHelper.floor_double(var2));
    1175            int var6 = MathHelper.floor_double(this.posZ);
    1176            int var7 = this.worldObj.getBlockId(var4, var5, var6);
    1177
    1178            if (var7 != 0 && Block.blocksList[var7].blockMaterial == par1Material)
    1179            {
    1180                float var8 = BlockFluid.getFluidHeightPercent(this.worldObj.getBlockMetadata(var4, var5, var6)) - 0.11111111F;
    1181                float var9 = (float)(var5 + 1) - var8;
    1182                return var2 < (double)var9;
    1183            }
    1184            else
    1185            {
    1186                return false;
    1187            }
    1188        }
    1189
    1190        public float getEyeHeight()
    1191        {
    1192            return 0.0F;
    1193        }
    1194
    1195        /**
    1196         * Whether or not the current entity is in lava
    1197         */
    1198        public boolean handleLavaMovement()
    1199        {
    1200            return this.worldObj.isMaterialInBB(this.boundingBox.expand(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), Material.lava);
    1201        }
    1202
    1203        /**
    1204         * Used in both water and by flying objects
    1205         */
    1206        public void moveFlying(float par1, float par2, float par3)
    1207        {
    1208            float var4 = par1 * par1 + par2 * par2;
    1209
    1210            if (var4 >= 1.0E-4F)
    1211            {
    1212                var4 = MathHelper.sqrt_float(var4);
    1213
    1214                if (var4 < 1.0F)
    1215                {
    1216                    var4 = 1.0F;
    1217                }
    1218
    1219                var4 = par3 / var4;
    1220                par1 *= var4;
    1221                par2 *= var4;
    1222                float var5 = MathHelper.sin(this.rotationYaw * (float)Math.PI / 180.0F);
    1223                float var6 = MathHelper.cos(this.rotationYaw * (float)Math.PI / 180.0F);
    1224                this.motionX += (double)(par1 * var6 - par2 * var5);
    1225                this.motionZ += (double)(par2 * var6 + par1 * var5);
    1226            }
    1227        }
    1228
    1229        @SideOnly(Side.CLIENT)
    1230        public int getBrightnessForRender(float par1)
    1231        {
    1232            int var2 = MathHelper.floor_double(this.posX);
    1233            int var3 = MathHelper.floor_double(this.posZ);
    1234
    1235            if (this.worldObj.blockExists(var2, 0, var3))
    1236            {
    1237                double var4 = (this.boundingBox.maxY - this.boundingBox.minY) * 0.66D;
    1238                int var6 = MathHelper.floor_double(this.posY - (double)this.yOffset + var4);
    1239                return this.worldObj.getLightBrightnessForSkyBlocks(var2, var6, var3, 0);
    1240            }
    1241            else
    1242            {
    1243                return 0;
    1244            }
    1245        }
    1246
    1247        /**
    1248         * Gets how bright this entity is.
    1249         */
    1250        public float getBrightness(float par1)
    1251        {
    1252            int var2 = MathHelper.floor_double(this.posX);
    1253            int var3 = MathHelper.floor_double(this.posZ);
    1254
    1255            if (this.worldObj.blockExists(var2, 0, var3))
    1256            {
    1257                double var4 = (this.boundingBox.maxY - this.boundingBox.minY) * 0.66D;
    1258                int var6 = MathHelper.floor_double(this.posY - (double)this.yOffset + var4);
    1259                return this.worldObj.getLightBrightness(var2, var6, var3);
    1260            }
    1261            else
    1262            {
    1263                return 0.0F;
    1264            }
    1265        }
    1266
    1267        /**
    1268         * Sets the reference to the World object.
    1269         */
    1270        public void setWorld(World par1World)
    1271        {
    1272            this.worldObj = par1World;
    1273        }
    1274
    1275        /**
    1276         * Sets the entity's position and rotation. Args: posX, posY, posZ, yaw, pitch
    1277         */
    1278        public void setPositionAndRotation(double par1, double par3, double par5, float par7, float par8)
    1279        {
    1280            this.prevPosX = this.posX = par1;
    1281            this.prevPosY = this.posY = par3;
    1282            this.prevPosZ = this.posZ = par5;
    1283            this.prevRotationYaw = this.rotationYaw = par7;
    1284            this.prevRotationPitch = this.rotationPitch = par8;
    1285            this.ySize = 0.0F;
    1286            double var9 = (double)(this.prevRotationYaw - par7);
    1287
    1288            if (var9 < -180.0D)
    1289            {
    1290                this.prevRotationYaw += 360.0F;
    1291            }
    1292
    1293            if (var9 >= 180.0D)
    1294            {
    1295                this.prevRotationYaw -= 360.0F;
    1296            }
    1297
    1298            this.setPosition(this.posX, this.posY, this.posZ);
    1299            this.setRotation(par7, par8);
    1300        }
    1301
    1302        /**
    1303         * Sets the location and Yaw/Pitch of an entity in the world
    1304         */
    1305        public void setLocationAndAngles(double par1, double par3, double par5, float par7, float par8)
    1306        {
    1307            this.lastTickPosX = this.prevPosX = this.posX = par1;
    1308            this.lastTickPosY = this.prevPosY = this.posY = par3 + (double)this.yOffset;
    1309            this.lastTickPosZ = this.prevPosZ = this.posZ = par5;
    1310            this.rotationYaw = par7;
    1311            this.rotationPitch = par8;
    1312            this.setPosition(this.posX, this.posY, this.posZ);
    1313        }
    1314
    1315        /**
    1316         * Returns the distance to the entity. Args: entity
    1317         */
    1318        public float getDistanceToEntity(Entity par1Entity)
    1319        {
    1320            float var2 = (float)(this.posX - par1Entity.posX);
    1321            float var3 = (float)(this.posY - par1Entity.posY);
    1322            float var4 = (float)(this.posZ - par1Entity.posZ);
    1323            return MathHelper.sqrt_float(var2 * var2 + var3 * var3 + var4 * var4);
    1324        }
    1325
    1326        /**
    1327         * Gets the squared distance to the position. Args: x, y, z
    1328         */
    1329        public double getDistanceSq(double par1, double par3, double par5)
    1330        {
    1331            double var7 = this.posX - par1;
    1332            double var9 = this.posY - par3;
    1333            double var11 = this.posZ - par5;
    1334            return var7 * var7 + var9 * var9 + var11 * var11;
    1335        }
    1336
    1337        /**
    1338         * Gets the distance to the position. Args: x, y, z
    1339         */
    1340        public double getDistance(double par1, double par3, double par5)
    1341        {
    1342            double var7 = this.posX - par1;
    1343            double var9 = this.posY - par3;
    1344            double var11 = this.posZ - par5;
    1345            return (double)MathHelper.sqrt_double(var7 * var7 + var9 * var9 + var11 * var11);
    1346        }
    1347
    1348        /**
    1349         * Returns the squared distance to the entity. Args: entity
    1350         */
    1351        public double getDistanceSqToEntity(Entity par1Entity)
    1352        {
    1353            double var2 = this.posX - par1Entity.posX;
    1354            double var4 = this.posY - par1Entity.posY;
    1355            double var6 = this.posZ - par1Entity.posZ;
    1356            return var2 * var2 + var4 * var4 + var6 * var6;
    1357        }
    1358
    1359        /**
    1360         * Called by a player entity when they collide with an entity
    1361         */
    1362        public void onCollideWithPlayer(EntityPlayer par1EntityPlayer) {}
    1363
    1364        /**
    1365         * Applies a velocity to each of the entities pushing them away from each other. Args: entity
    1366         */
    1367        public void applyEntityCollision(Entity par1Entity)
    1368        {
    1369            if (par1Entity.riddenByEntity != this && par1Entity.ridingEntity != this)
    1370            {
    1371                double var2 = par1Entity.posX - this.posX;
    1372                double var4 = par1Entity.posZ - this.posZ;
    1373                double var6 = MathHelper.abs_max(var2, var4);
    1374
    1375                if (var6 >= 0.009999999776482582D)
    1376                {
    1377                    var6 = (double)MathHelper.sqrt_double(var6);
    1378                    var2 /= var6;
    1379                    var4 /= var6;
    1380                    double var8 = 1.0D / var6;
    1381
    1382                    if (var8 > 1.0D)
    1383                    {
    1384                        var8 = 1.0D;
    1385                    }
    1386
    1387                    var2 *= var8;
    1388                    var4 *= var8;
    1389                    var2 *= 0.05000000074505806D;
    1390                    var4 *= 0.05000000074505806D;
    1391                    var2 *= (double)(1.0F - this.entityCollisionReduction);
    1392                    var4 *= (double)(1.0F - this.entityCollisionReduction);
    1393                    this.addVelocity(-var2, 0.0D, -var4);
    1394                    par1Entity.addVelocity(var2, 0.0D, var4);
    1395                }
    1396            }
    1397        }
    1398
    1399        /**
    1400         * Adds to the current velocity of the entity. Args: x, y, z
    1401         */
    1402        public void addVelocity(double par1, double par3, double par5)
    1403        {
    1404            this.motionX += par1;
    1405            this.motionY += par3;
    1406            this.motionZ += par5;
    1407            this.isAirBorne = true;
    1408        }
    1409
    1410        /**
    1411         * Sets that this entity has been attacked.
    1412         */
    1413        protected void setBeenAttacked()
    1414        {
    1415            this.velocityChanged = true;
    1416        }
    1417
    1418        /**
    1419         * Called when the entity is attacked.
    1420         */
    1421        public boolean attackEntityFrom(DamageSource par1DamageSource, int par2)
    1422        {
    1423            if (this.func_85032_ar())
    1424            {
    1425                return false;
    1426            }
    1427            else
    1428            {
    1429                this.setBeenAttacked();
    1430                return false;
    1431            }
    1432        }
    1433
    1434        /**
    1435         * Returns true if other Entities should be prevented from moving through this Entity.
    1436         */
    1437        public boolean canBeCollidedWith()
    1438        {
    1439            return false;
    1440        }
    1441
    1442        /**
    1443         * Returns true if this entity should push and be pushed by other entities when colliding.
    1444         */
    1445        public boolean canBePushed()
    1446        {
    1447            return false;
    1448        }
    1449
    1450        /**
    1451         * Adds a value to the player score. Currently not actually used and the entity passed in does nothing. Args:
    1452         * entity, scoreToAdd
    1453         */
    1454        public void addToPlayerScore(Entity par1Entity, int par2) {}
    1455
    1456        /**
    1457         * adds the ID of this entity to the NBT given
    1458         */
    1459        public boolean addEntityID(NBTTagCompound par1NBTTagCompound)
    1460        {
    1461            String var2 = this.getEntityString();
    1462
    1463            if (!this.isDead && var2 != null)
    1464            {
    1465                par1NBTTagCompound.setString("id", var2);
    1466                this.writeToNBT(par1NBTTagCompound);
    1467                return true;
    1468            }
    1469            else
    1470            {
    1471                return false;
    1472            }
    1473        }
    1474
    1475        @SideOnly(Side.CLIENT)
    1476
    1477        /**
    1478         * Checks using a Vec3d to determine if this entity is within range of that vector to be rendered. Args: vec3D
    1479         */
    1480        public boolean isInRangeToRenderVec3D(Vec3 par1Vec3)
    1481        {
    1482            double var2 = this.posX - par1Vec3.xCoord;
    1483            double var4 = this.posY - par1Vec3.yCoord;
    1484            double var6 = this.posZ - par1Vec3.zCoord;
    1485            double var8 = var2 * var2 + var4 * var4 + var6 * var6;
    1486            return this.isInRangeToRenderDist(var8);
    1487        }
    1488
    1489        @SideOnly(Side.CLIENT)
    1490
    1491        /**
    1492         * Checks if the entity is in range to render by using the past in distance and comparing it to its average edge
    1493         * length * 64 * renderDistanceWeight Args: distance
    1494         */
    1495        public boolean isInRangeToRenderDist(double par1)
    1496        {
    1497            double var3 = this.boundingBox.getAverageEdgeLength();
    1498            var3 *= 64.0D * this.renderDistanceWeight;
    1499            return par1 < var3 * var3;
    1500        }
    1501
    1502        @SideOnly(Side.CLIENT)
    1503
    1504        /**
    1505         * Returns the texture's file path as a String.
    1506         */
    1507        public String getTexture()
    1508        {
    1509            return null;
    1510        }
    1511
    1512        /**
    1513         * Save the entity to NBT (calls an abstract helper method to write extra data)
    1514         */
    1515        public void writeToNBT(NBTTagCompound par1NBTTagCompound)
    1516        {
    1517            try
    1518            {
    1519                par1NBTTagCompound.setTag("Pos", this.newDoubleNBTList(new double[] {this.posX, this.posY + (double)this.ySize, this.posZ}));
    1520                par1NBTTagCompound.setTag("Motion", this.newDoubleNBTList(new double[] {this.motionX, this.motionY, this.motionZ}));
    1521                par1NBTTagCompound.setTag("Rotation", this.newFloatNBTList(new float[] {this.rotationYaw, this.rotationPitch}));
    1522                par1NBTTagCompound.setFloat("FallDistance", this.fallDistance);
    1523                par1NBTTagCompound.setShort("Fire", (short)this.fire);
    1524                par1NBTTagCompound.setShort("Air", (short)this.getAir());
    1525                par1NBTTagCompound.setBoolean("OnGround", this.onGround);
    1526                par1NBTTagCompound.setInteger("Dimension", this.dimension);
    1527                par1NBTTagCompound.setBoolean("Invulnerable", this.field_83001_bt);
    1528                par1NBTTagCompound.setInteger("PortalCooldown", this.timeUntilPortal);
    1529                if (persistentID != null)
    1530                {
    1531                    par1NBTTagCompound.setLong("PersistentIDMSB", persistentID.getMostSignificantBits());
    1532                    par1NBTTagCompound.setLong("PersistentIDLSB", persistentID.getLeastSignificantBits());
    1533                }
    1534                if (customEntityData != null)
    1535                {
    1536                    par1NBTTagCompound.setCompoundTag("ForgeData", customEntityData);
    1537                }
    1538                this.writeEntityToNBT(par1NBTTagCompound);
    1539            }
    1540            catch (Throwable var5)
    1541            {
    1542                CrashReport var3 = CrashReport.func_85055_a(var5, "Saving entity NBT");
    1543                CrashReportCategory var4 = var3.func_85058_a("Entity being saved");
    1544                this.func_85029_a(var4);
    1545                throw new ReportedException(var3);
    1546            }
    1547        }
    1548
    1549        /**
    1550         * Reads the entity from NBT (calls an abstract helper method to read specialized data)
    1551         */
    1552        public void readFromNBT(NBTTagCompound par1NBTTagCompound)
    1553        {
    1554            try
    1555            {
    1556                NBTTagList var2 = par1NBTTagCompound.getTagList("Pos");
    1557                NBTTagList var6 = par1NBTTagCompound.getTagList("Motion");
    1558                NBTTagList var7 = par1NBTTagCompound.getTagList("Rotation");
    1559                this.motionX = ((NBTTagDouble)var6.tagAt(0)).data;
    1560                this.motionY = ((NBTTagDouble)var6.tagAt(1)).data;
    1561                this.motionZ = ((NBTTagDouble)var6.tagAt(2)).data;
    1562
    1563                if (Math.abs(this.motionX) > 10.0D)
    1564                {
    1565                    this.motionX = 0.0D;
    1566                }
    1567
    1568                if (Math.abs(this.motionY) > 10.0D)
    1569                {
    1570                    this.motionY = 0.0D;
    1571                }
    1572
    1573                if (Math.abs(this.motionZ) > 10.0D)
    1574                {
    1575                    this.motionZ = 0.0D;
    1576                }
    1577
    1578                this.prevPosX = this.lastTickPosX = this.posX = ((NBTTagDouble)var2.tagAt(0)).data;
    1579                this.prevPosY = this.lastTickPosY = this.posY = ((NBTTagDouble)var2.tagAt(1)).data;
    1580                this.prevPosZ = this.lastTickPosZ = this.posZ = ((NBTTagDouble)var2.tagAt(2)).data;
    1581                this.prevRotationYaw = this.rotationYaw = ((NBTTagFloat)var7.tagAt(0)).data;
    1582                this.prevRotationPitch = this.rotationPitch = ((NBTTagFloat)var7.tagAt(1)).data;
    1583                this.fallDistance = par1NBTTagCompound.getFloat("FallDistance");
    1584                this.fire = par1NBTTagCompound.getShort("Fire");
    1585                this.setAir(par1NBTTagCompound.getShort("Air"));
    1586                this.onGround = par1NBTTagCompound.getBoolean("OnGround");
    1587                this.dimension = par1NBTTagCompound.getInteger("Dimension");
    1588                this.field_83001_bt = par1NBTTagCompound.getBoolean("Invulnerable");
    1589                this.timeUntilPortal = par1NBTTagCompound.getInteger("PortalCooldown");
    1590                this.setPosition(this.posX, this.posY, this.posZ);
    1591                this.setRotation(this.rotationYaw, this.rotationPitch);
    1592                if (par1NBTTagCompound.hasKey("ForgeData"))
    1593                {
    1594                    customEntityData = par1NBTTagCompound.getCompoundTag("ForgeData");
    1595                }
    1596                if (par1NBTTagCompound.hasKey("PersistentIDMSB") && par1NBTTagCompound.hasKey("PersistentIDLSB"))
    1597                {
    1598                    persistentID = new UUID(par1NBTTagCompound.getLong("PersistentIDMSB"), par1NBTTagCompound.getLong("PersistentIDLSB"));
    1599                }
    1600                this.readEntityFromNBT(par1NBTTagCompound);
    1601            }
    1602            catch (Throwable var5)
    1603            {
    1604                CrashReport var3 = CrashReport.func_85055_a(var5, "Loading entity NBT");
    1605                CrashReportCategory var4 = var3.func_85058_a("Entity being loaded");
    1606                this.func_85029_a(var4);
    1607                throw new ReportedException(var3);
    1608            }
    1609        }
    1610
    1611        /**
    1612         * Returns the string that identifies this Entity's class
    1613         */
    1614        protected final String getEntityString()
    1615        {
    1616            return EntityList.getEntityString(this);
    1617        }
    1618
    1619        /**
    1620         * (abstract) Protected helper method to read subclass entity data from NBT.
    1621         */
    1622        protected abstract void readEntityFromNBT(NBTTagCompound var1);
    1623
    1624        /**
    1625         * (abstract) Protected helper method to write subclass entity data to NBT.
    1626         */
    1627        protected abstract void writeEntityToNBT(NBTTagCompound var1);
    1628
    1629        /**
    1630         * creates a NBT list from the array of doubles passed to this function
    1631         */
    1632        protected NBTTagList newDoubleNBTList(double ... par1ArrayOfDouble)
    1633        {
    1634            NBTTagList var2 = new NBTTagList();
    1635            double[] var3 = par1ArrayOfDouble;
    1636            int var4 = par1ArrayOfDouble.length;
    1637
    1638            for (int var5 = 0; var5 < var4; ++var5)
    1639            {
    1640                double var6 = var3[var5];
    1641                var2.appendTag(new NBTTagDouble((String)null, var6));
    1642            }
    1643
    1644            return var2;
    1645        }
    1646
    1647        /**
    1648         * Returns a new NBTTagList filled with the specified floats
    1649         */
    1650        protected NBTTagList newFloatNBTList(float ... par1ArrayOfFloat)
    1651        {
    1652            NBTTagList var2 = new NBTTagList();
    1653            float[] var3 = par1ArrayOfFloat;
    1654            int var4 = par1ArrayOfFloat.length;
    1655
    1656            for (int var5 = 0; var5 < var4; ++var5)
    1657            {
    1658                float var6 = var3[var5];
    1659                var2.appendTag(new NBTTagFloat((String)null, var6));
    1660            }
    1661
    1662            return var2;
    1663        }
    1664
    1665        @SideOnly(Side.CLIENT)
    1666        public float getShadowSize()
    1667        {
    1668            return this.height / 2.0F;
    1669        }
    1670
    1671        /**
    1672         * Drops an item stack at the entity's position. Args: itemID, count
    1673         */
    1674        public EntityItem dropItem(int par1, int par2)
    1675        {
    1676            return this.dropItemWithOffset(par1, par2, 0.0F);
    1677        }
    1678
    1679        /**
    1680         * Drops an item stack with a specified y offset. Args: itemID, count, yOffset
    1681         */
    1682        public EntityItem dropItemWithOffset(int par1, int par2, float par3)
    1683        {
    1684            return this.entityDropItem(new ItemStack(par1, par2, 0), par3);
    1685        }
    1686
    1687        /**
    1688         * Drops an item at the position of the entity.
    1689         */
    1690        public EntityItem entityDropItem(ItemStack par1ItemStack, float par2)
    1691        {
    1692            EntityItem var3 = new EntityItem(this.worldObj, this.posX, this.posY + (double)par2, this.posZ, par1ItemStack);
    1693            var3.delayBeforeCanPickup = 10;
    1694            if (captureDrops)
    1695            {
    1696                capturedDrops.add(var3);
    1697            }
    1698            else
    1699            {
    1700                this.worldObj.spawnEntityInWorld(var3);
    1701            }
    1702            return var3;
    1703        }
    1704
    1705        /**
    1706         * Checks whether target entity is alive.
    1707         */
    1708        public boolean isEntityAlive()
    1709        {
    1710            return !this.isDead;
    1711        }
    1712
    1713        /**
    1714         * Checks if this entity is inside of an opaque block
    1715         */
    1716        public boolean isEntityInsideOpaqueBlock()
    1717        {
    1718            for (int var1 = 0; var1 < 8; ++var1)
    1719            {
    1720                float var2 = ((float)((var1 >> 0) % 2) - 0.5F) * this.width * 0.8F;
    1721                float var3 = ((float)((var1 >> 1) % 2) - 0.5F) * 0.1F;
    1722                float var4 = ((float)((var1 >> 2) % 2) - 0.5F) * this.width * 0.8F;
    1723                int var5 = MathHelper.floor_double(this.posX + (double)var2);
    1724                int var6 = MathHelper.floor_double(this.posY + (double)this.getEyeHeight() + (double)var3);
    1725                int var7 = MathHelper.floor_double(this.posZ + (double)var4);
    1726
    1727                if (this.worldObj.isBlockNormalCube(var5, var6, var7))
    1728                {
    1729                    return true;
    1730                }
    1731            }
    1732
    1733            return false;
    1734        }
    1735
    1736        /**
    1737         * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
    1738         */
    1739        public boolean interact(EntityPlayer par1EntityPlayer)
    1740        {
    1741            return false;
    1742        }
    1743
    1744        /**
    1745         * Returns a boundingBox used to collide the entity with other entities and blocks. This enables the entity to be
    1746         * pushable on contact, like boats or minecarts.
    1747         */
    1748        public AxisAlignedBB getCollisionBox(Entity par1Entity)
    1749        {
    1750            return null;
    1751        }
    1752
    1753        /**
    1754         * Handles updating while being ridden by an entity
    1755         */
    1756        public void updateRidden()
    1757        {
    1758            if (this.ridingEntity.isDead)
    1759            {
    1760                this.ridingEntity = null;
    1761            }
    1762            else
    1763            {
    1764                this.motionX = 0.0D;
    1765                this.motionY = 0.0D;
    1766                this.motionZ = 0.0D;
    1767                this.onUpdate();
    1768
    1769                if (this.ridingEntity != null)
    1770                {
    1771                    this.ridingEntity.updateRiderPosition();
    1772                    this.entityRiderYawDelta += (double)(this.ridingEntity.rotationYaw - this.ridingEntity.prevRotationYaw);
    1773
    1774                    for (this.entityRiderPitchDelta += (double)(this.ridingEntity.rotationPitch - this.ridingEntity.prevRotationPitch); this.entityRiderYawDelta >= 180.0D; this.entityRiderYawDelta -= 360.0D)
    1775                    {
    1776                        ;
    1777                    }
    1778
    1779                    while (this.entityRiderYawDelta < -180.0D)
    1780                    {
    1781                        this.entityRiderYawDelta += 360.0D;
    1782                    }
    1783
    1784                    while (this.entityRiderPitchDelta >= 180.0D)
    1785                    {
    1786                        this.entityRiderPitchDelta -= 360.0D;
    1787                    }
    1788
    1789                    while (this.entityRiderPitchDelta < -180.0D)
    1790                    {
    1791                        this.entityRiderPitchDelta += 360.0D;
    1792                    }
    1793
    1794                    double var1 = this.entityRiderYawDelta * 0.5D;
    1795                    double var3 = this.entityRiderPitchDelta * 0.5D;
    1796                    float var5 = 10.0F;
    1797
    1798                    if (var1 > (double)var5)
    1799                    {
    1800                        var1 = (double)var5;
    1801                    }
    1802
    1803                    if (var1 < (double)(-var5))
    1804                    {
    1805                        var1 = (double)(-var5);
    1806                    }
    1807
    1808                    if (var3 > (double)var5)
    1809                    {
    1810                        var3 = (double)var5;
    1811                    }
    1812
    1813                    if (var3 < (double)(-var5))
    1814                    {
    1815                        var3 = (double)(-var5);
    1816                    }
    1817
    1818                    this.entityRiderYawDelta -= var1;
    1819                    this.entityRiderPitchDelta -= var3;
    1820                    this.rotationYaw = (float)((double)this.rotationYaw + var1);
    1821                    this.rotationPitch = (float)((double)this.rotationPitch + var3);
    1822                }
    1823            }
    1824        }
    1825
    1826        public void updateRiderPosition()
    1827        {
    1828            if (!(this.riddenByEntity instanceof EntityPlayer) || !((EntityPlayer)this.riddenByEntity).func_71066_bF())
    1829            {
    1830                this.riddenByEntity.lastTickPosX = this.lastTickPosX;
    1831                this.riddenByEntity.lastTickPosY = this.lastTickPosY + this.getMountedYOffset() + this.riddenByEntity.getYOffset();
    1832                this.riddenByEntity.lastTickPosZ = this.lastTickPosZ;
    1833            }
    1834
    1835            this.riddenByEntity.setPosition(this.posX, this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ);
    1836        }
    1837
    1838        /**
    1839         * Returns the Y Offset of this entity.
    1840         */
    1841        public double getYOffset()
    1842        {
    1843            return (double)this.yOffset;
    1844        }
    1845
    1846        /**
    1847         * Returns the Y offset from the entity's position for any entity riding this one.
    1848         */
    1849        public double getMountedYOffset()
    1850        {
    1851            return (double)this.height * 0.75D;
    1852        }
    1853
    1854        /**
    1855         * Called when a player mounts an entity. e.g. mounts a pig, mounts a boat.
    1856         */
    1857        public void mountEntity(Entity par1Entity)
    1858        {
    1859            this.entityRiderPitchDelta = 0.0D;
    1860            this.entityRiderYawDelta = 0.0D;
    1861
    1862            if (par1Entity == null)
    1863            {
    1864                if (this.ridingEntity != null)
    1865                {
    1866                    this.setLocationAndAngles(this.ridingEntity.posX, this.ridingEntity.boundingBox.minY + (double)this.ridingEntity.height, this.ridingEntity.posZ, this.rotationYaw, this.rotationPitch);
    1867                    this.ridingEntity.riddenByEntity = null;
    1868                }
    1869
    1870                this.ridingEntity = null;
    1871            }
    1872            else if (this.ridingEntity == par1Entity)
    1873            {
    1874                this.unmountEntity(par1Entity);
    1875                this.ridingEntity.riddenByEntity = null;
    1876                this.ridingEntity = null;
    1877            }
    1878            else
    1879            {
    1880                if (this.ridingEntity != null)
    1881                {
    1882                    this.ridingEntity.riddenByEntity = null;
    1883                }
    1884
    1885                if (par1Entity.riddenByEntity != null)
    1886                {
    1887                    par1Entity.riddenByEntity.ridingEntity = null;
    1888                }
    1889
    1890                this.ridingEntity = par1Entity;
    1891                par1Entity.riddenByEntity = this;
    1892            }
    1893        }
    1894
    1895        /**
    1896         * Called when a player unounts an entity.
    1897         */
    1898        public void unmountEntity(Entity par1Entity)
    1899        {
    1900            double var3 = par1Entity.posX;
    1901            double var5 = par1Entity.boundingBox.minY + (double)par1Entity.height;
    1902            double var7 = par1Entity.posZ;
    1903
    1904            for (double var9 = -1.5D; var9 < 2.0D; ++var9)
    1905            {
    1906                for (double var11 = -1.5D; var11 < 2.0D; ++var11)
    1907                {
    1908                    if (var9 != 0.0D || var11 != 0.0D)
    1909                    {
    1910                        int var13 = (int)(this.posX + var9);
    1911                        int var14 = (int)(this.posZ + var11);
    1912                        AxisAlignedBB var2 = this.boundingBox.getOffsetBoundingBox(var9, 1.0D, var11);
    1913
    1914                        if (this.worldObj.getAllCollidingBoundingBoxes(var2).isEmpty())
    1915                        {
    1916                            if (this.worldObj.doesBlockHaveSolidTopSurface(var13, (int)this.posY, var14))
    1917                            {
    1918                                this.setLocationAndAngles(this.posX + var9, this.posY + 1.0D, this.posZ + var11, this.rotationYaw, this.rotationPitch);
    1919                                return;
    1920                            }
    1921
    1922                            if (this.worldObj.doesBlockHaveSolidTopSurface(var13, (int)this.posY - 1, var14) || this.worldObj.getBlockMaterial(var13, (int)this.posY - 1, var14) == Material.water)
    1923                            {
    1924                                var3 = this.posX + var9;
    1925                                var5 = this.posY + 1.0D;
    1926                                var7 = this.posZ + var11;
    1927                            }
    1928                        }
    1929                    }
    1930                }
    1931            }
    1932
    1933            this.setLocationAndAngles(var3, var5, var7, this.rotationYaw, this.rotationPitch);
    1934        }
    1935
    1936        @SideOnly(Side.CLIENT)
    1937
    1938        /**
    1939         * Sets the position and rotation. Only difference from the other one is no bounding on the rotation. Args: posX,
    1940         * posY, posZ, yaw, pitch
    1941         */
    1942        public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9)
    1943        {
    1944            this.setPosition(par1, par3, par5);
    1945            this.setRotation(par7, par8);
    1946            List var10 = this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.contract(0.03125D, 0.0D, 0.03125D));
    1947
    1948            if (!var10.isEmpty())
    1949            {
    1950                double var11 = 0.0D;
    1951
    1952                for (int var13 = 0; var13 < var10.size(); ++var13)
    1953                {
    1954                    AxisAlignedBB var14 = (AxisAlignedBB)var10.get(var13);
    1955
    1956                    if (var14.maxY > var11)
    1957                    {
    1958                        var11 = var14.maxY;
    1959                    }
    1960                }
    1961
    1962                par3 += var11 - this.boundingBox.minY;
    1963                this.setPosition(par1, par3, par5);
    1964            }
    1965        }
    1966
    1967        public float getCollisionBorderSize()
    1968        {
    1969            return 0.1F;
    1970        }
    1971
    1972        /**
    1973         * returns a (normalized) vector of where this entity is looking
    1974         */
    1975        public Vec3 getLookVec()
    1976        {
    1977            return null;
    1978        }
    1979
    1980        /**
    1981         * Called by portal blocks when an entity is within it.
    1982         */
    1983        public void setInPortal()
    1984        {
    1985            if (this.timeUntilPortal > 0)
    1986            {
    1987                this.timeUntilPortal = this.getPortalCooldown();
    1988            }
    1989            else
    1990            {
    1991                double var1 = this.prevPosX - this.posX;
    1992                double var3 = this.prevPosZ - this.posZ;
    1993
    1994                if (!this.worldObj.isRemote && !this.inPortal)
    1995                {
    1996                    this.field_82152_aq = Direction.func_82372_a(var1, var3);
    1997                }
    1998
    1999                this.inPortal = true;
    2000            }
    2001        }
    2002
    2003        /**
    2004         * Return the amount of cooldown before this entity can use a portal again.
    2005         */
    2006        public int getPortalCooldown()
    2007        {
    2008            return 900;
    2009        }
    2010
    2011        @SideOnly(Side.CLIENT)
    2012
    2013        /**
    2014         * Sets the velocity to the args. Args: x, y, z
    2015         */
    2016        public void setVelocity(double par1, double par3, double par5)
    2017        {
    2018            this.motionX = par1;
    2019            this.motionY = par3;
    2020            this.motionZ = par5;
    2021        }
    2022
    2023        @SideOnly(Side.CLIENT)
    2024        public void handleHealthUpdate(byte par1) {}
    2025
    2026        @SideOnly(Side.CLIENT)
    2027
    2028        /**
    2029         * Setups the entity to do the hurt animation. Only used by packets in multiplayer.
    2030         */
    2031        public void performHurtAnimation() {}
    2032
    2033        @SideOnly(Side.CLIENT)
    2034        public void updateCloak() {}
    2035
    2036        public ItemStack[] getLastActiveItems()
    2037        {
    2038            return null;
    2039        }
    2040
    2041        /**
    2042         * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. Params: Item, slot
    2043         */
    2044        public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) {}
    2045
    2046        /**
    2047         * Returns true if the entity is on fire. Used by render to add the fire effect on rendering.
    2048         */
    2049        public boolean isBurning()
    2050        {
    2051            return this.fire > 0 || this.getFlag(0);
    2052        }
    2053
    2054        /**
    2055         * Returns true if the entity is riding another entity, used by render to rotate the legs to be in 'sit' position
    2056         * for players.
    2057         */
    2058        public boolean isRiding()
    2059        {
    2060            return (this.ridingEntity != null && ridingEntity.shouldRiderSit()) || this.getFlag(2);
    2061        }
    2062
    2063        /**
    2064         * Returns if this entity is sneaking.
    2065         */
    2066        public boolean isSneaking()
    2067        {
    2068            return this.getFlag(1);
    2069        }
    2070
    2071        /**
    2072         * Sets the sneaking flag.
    2073         */
    2074        public void setSneaking(boolean par1)
    2075        {
    2076            this.setFlag(1, par1);
    2077        }
    2078
    2079        /**
    2080         * Get if the Entity is sprinting.
    2081         */
    2082        public boolean isSprinting()
    2083        {
    2084            return this.getFlag(3);
    2085        }
    2086
    2087        /**
    2088         * Set sprinting switch for Entity.
    2089         */
    2090        public void setSprinting(boolean par1)
    2091        {
    2092            this.setFlag(3, par1);
    2093        }
    2094
    2095        public boolean getHasActivePotion()
    2096        {
    2097            return this.getFlag(5);
    2098        }
    2099
    2100        public void setHasActivePotion(boolean par1)
    2101        {
    2102            this.setFlag(5, par1);
    2103        }
    2104
    2105        @SideOnly(Side.CLIENT)
    2106        public boolean isEating()
    2107        {
    2108            return this.getFlag(4);
    2109        }
    2110
    2111        public void setEating(boolean par1)
    2112        {
    2113            this.setFlag(4, par1);
    2114        }
    2115
    2116        /**
    2117         * Returns true if the flag is active for the entity. Known flags: 0) is burning; 1) is sneaking; 2) is riding
    2118         * something; 3) is sprinting; 4) is eating
    2119         */
    2120        protected boolean getFlag(int par1)
    2121        {
    2122            return (this.dataWatcher.getWatchableObjectByte(0) & 1 << par1) != 0;
    2123        }
    2124
    2125        /**
    2126         * Enable or disable a entity flag, see getEntityFlag to read the know flags.
    2127         */
    2128        protected void setFlag(int par1, boolean par2)
    2129        {
    2130            byte var3 = this.dataWatcher.getWatchableObjectByte(0);
    2131
    2132            if (par2)
    2133            {
    2134                this.dataWatcher.updateObject(0, Byte.valueOf((byte)(var3 | 1 << par1)));
    2135            }
    2136            else
    2137            {
    2138                this.dataWatcher.updateObject(0, Byte.valueOf((byte)(var3 & ~(1 << par1))));
    2139            }
    2140        }
    2141
    2142        public int getAir()
    2143        {
    2144            return this.dataWatcher.getWatchableObjectShort(1);
    2145        }
    2146
    2147        public void setAir(int par1)
    2148        {
    2149            this.dataWatcher.updateObject(1, Short.valueOf((short)par1));
    2150        }
    2151
    2152        /**
    2153         * Called when a lightning bolt hits the entity.
    2154         */
    2155        public void onStruckByLightning(EntityLightningBolt par1EntityLightningBolt)
    2156        {
    2157            this.dealFireDamage(5);
    2158            ++this.fire;
    2159
    2160            if (this.fire == 0)
    2161            {
    2162                this.setFire(8);
    2163            }
    2164        }
    2165
    2166        /**
    2167         * This method gets called when the entity kills another one.
    2168         */
    2169        public void onKillEntity(EntityLiving par1EntityLiving) {}
    2170
    2171        /**
    2172         * Adds velocity to push the entity out of blocks at the specified x, y, z position Args: x, y, z
    2173         */
    2174        protected boolean pushOutOfBlocks(double par1, double par3, double par5)
    2175        {
    2176            int var7 = MathHelper.floor_double(par1);
    2177            int var8 = MathHelper.floor_double(par3);
    2178            int var9 = MathHelper.floor_double(par5);
    2179            double var10 = par1 - (double)var7;
    2180            double var12 = par3 - (double)var8;
    2181            double var14 = par5 - (double)var9;
    2182            List var16 = this.worldObj.getAllCollidingBoundingBoxes(this.boundingBox);
    2183
    2184            if (var16.isEmpty() && !this.worldObj.func_85174_u(var7, var8, var9))
    2185            {
    2186                return false;
    2187            }
    2188            else
    2189            {
    2190                boolean var17 = !this.worldObj.func_85174_u(var7 - 1, var8, var9);
    2191                boolean var18 = !this.worldObj.func_85174_u(var7 + 1, var8, var9);
    2192                boolean var19 = !this.worldObj.func_85174_u(var7, var8 - 1, var9);
    2193                boolean var20 = !this.worldObj.func_85174_u(var7, var8 + 1, var9);
    2194                boolean var21 = !this.worldObj.func_85174_u(var7, var8, var9 - 1);
    2195                boolean var22 = !this.worldObj.func_85174_u(var7, var8, var9 + 1);
    2196                byte var23 = 3;
    2197                double var24 = 9999.0D;
    2198
    2199                if (var17 && var10 < var24)
    2200                {
    2201                    var24 = var10;
    2202                    var23 = 0;
    2203                }
    2204
    2205                if (var18 && 1.0D - var10 < var24)
    2206                {
    2207                    var24 = 1.0D - var10;
    2208                    var23 = 1;
    2209                }
    2210
    2211                if (var20 && 1.0D - var12 < var24)
    2212                {
    2213                    var24 = 1.0D - var12;
    2214                    var23 = 3;
    2215                }
    2216
    2217                if (var21 && var14 < var24)
    2218                {
    2219                    var24 = var14;
    2220                    var23 = 4;
    2221                }
    2222
    2223                if (var22 && 1.0D - var14 < var24)
    2224                {
    2225                    var24 = 1.0D - var14;
    2226                    var23 = 5;
    2227                }
    2228
    2229                float var26 = this.rand.nextFloat() * 0.2F + 0.1F;
    2230
    2231                if (var23 == 0)
    2232                {
    2233                    this.motionX = (double)(-var26);
    2234                }
    2235
    2236                if (var23 == 1)
    2237                {
    2238                    this.motionX = (double)var26;
    2239                }
    2240
    2241                if (var23 == 2)
    2242                {
    2243                    this.motionY = (double)(-var26);
    2244                }
    2245
    2246                if (var23 == 3)
    2247                {
    2248                    this.motionY = (double)var26;
    2249                }
    2250
    2251                if (var23 == 4)
    2252                {
    2253                    this.motionZ = (double)(-var26);
    2254                }
    2255
    2256                if (var23 == 5)
    2257                {
    2258                    this.motionZ = (double)var26;
    2259                }
    2260
    2261                return true;
    2262            }
    2263        }
    2264
    2265        /**
    2266         * Sets the Entity inside a web block.
    2267         */
    2268        public void setInWeb()
    2269        {
    2270            this.isInWeb = true;
    2271            this.fallDistance = 0.0F;
    2272        }
    2273
    2274        /**
    2275         * Gets the username of the entity.
    2276         */
    2277        public String getEntityName()
    2278        {
    2279            String var1 = EntityList.getEntityString(this);
    2280
    2281            if (var1 == null)
    2282            {
    2283                var1 = "generic";
    2284            }
    2285
    2286            return StatCollector.translateToLocal("entity." + var1 + ".name");
    2287        }
    2288
    2289        /**
    2290         * Return the Entity parts making up this Entity (currently only for dragons)
    2291         */
    2292        public Entity[] getParts()
    2293        {
    2294            return null;
    2295        }
    2296
    2297        /**
    2298         * Returns true if Entity argument is equal to this Entity
    2299         */
    2300        public boolean isEntityEqual(Entity par1Entity)
    2301        {
    2302            return this == par1Entity;
    2303        }
    2304
    2305        public float setRotationYawHead()
    2306        {
    2307            return 0.0F;
    2308        }
    2309
    2310        @SideOnly(Side.CLIENT)
    2311
    2312        /**
    2313         * Sets the head's yaw rotation of the entity.
    2314         */
    2315        public void setHeadRotationYaw(float par1) {}
    2316
    2317        /**
    2318         * If returns false, the item will not inflict any damage against entities.
    2319         */
    2320        public boolean canAttackWithItem()
    2321        {
    2322            return true;
    2323        }
    2324
    2325        public boolean func_85031_j(Entity par1Entity)
    2326        {
    2327            return false;
    2328        }
    2329
    2330        public String toString()
    2331        {
    2332            return String.format("%s[\'%s\'/%d, l=\'%s\', x=%.2f, y=%.2f, z=%.2f]", new Object[] {this.getClass().getSimpleName(), this.getEntityName(), Integer.valueOf(this.entityId), this.worldObj == null ? "~NULL~" : this.worldObj.getWorldInfo().getWorldName(), Double.valueOf(this.posX), Double.valueOf(this.posY), Double.valueOf(this.posZ)});
    2333        }
    2334
    2335        public boolean func_85032_ar()
    2336        {
    2337            return this.field_83001_bt;
    2338        }
    2339
    2340        public void func_82149_j(Entity par1Entity)
    2341        {
    2342            this.setLocationAndAngles(par1Entity.posX, par1Entity.posY, par1Entity.posZ, par1Entity.rotationYaw, par1Entity.rotationPitch);
    2343        }
    2344
    2345        /**
    2346         * Copies important data from another entity to this entity. Used when teleporting entities between worlds, as this
    2347         * actually deletes the teleporting entity and re-creates it on the other side. Params: Entity to copy from, unused
    2348         * (always true)
    2349         */
    2350        public void copyDataFrom(Entity par1Entity, boolean par2)
    2351        {
    2352            NBTTagCompound var3 = new NBTTagCompound();
    2353            par1Entity.writeToNBT(var3);
    2354            this.readFromNBT(var3);
    2355            this.timeUntilPortal = par1Entity.timeUntilPortal;
    2356            this.field_82152_aq = par1Entity.field_82152_aq;
    2357        }
    2358
    2359        /**
    2360         * Teleports the entity to another dimension. Params: Dimension number to teleport to
    2361         */
    2362        public void travelToDimension(int par1)
    2363        {
    2364            if (!this.worldObj.isRemote && !this.isDead)
    2365            {
    2366                this.worldObj.theProfiler.startSection("changeDimension");
    2367                MinecraftServer var2 = MinecraftServer.getServer();
    2368                int var3 = this.dimension;
    2369                WorldServer var4 = var2.worldServerForDimension(var3);
    2370                WorldServer var5 = var2.worldServerForDimension(par1);
    2371                this.dimension = par1;
    2372                this.worldObj.setEntityDead(this);
    2373                this.isDead = false;
    2374                this.worldObj.theProfiler.startSection("reposition");
    2375                var2.getConfigurationManager().transferEntityToWorld(this, var3, var4, var5);
    2376                this.worldObj.theProfiler.endStartSection("reloading");
    2377                Entity var6 = EntityList.createEntityByName(EntityList.getEntityString(this), var5);
    2378
    2379                if (var6 != null)
    2380                {
    2381                    var6.copyDataFrom(this, true);
    2382                    var5.spawnEntityInWorld(var6);
    2383                }
    2384
    2385                this.isDead = true;
    2386                this.worldObj.theProfiler.endSection();
    2387                var4.resetUpdateEntityTick();
    2388                var5.resetUpdateEntityTick();
    2389                this.worldObj.theProfiler.endSection();
    2390            }
    2391        }
    2392
    2393        public float func_82146_a(Explosion par1Explosion, Block par2Block, int par3, int par4, int par5)
    2394        {
    2395            return par2Block.getExplosionResistance(this, worldObj, par3, par4, par5, posX, posY + (double)getEyeHeight(), posZ);
    2396        }
    2397
    2398        public int func_82143_as()
    2399        {
    2400            return 3;
    2401        }
    2402
    2403        public int func_82148_at()
    2404        {
    2405            return this.field_82152_aq;
    2406        }
    2407
    2408        /**
    2409         * Return whether this entity should NOT trigger a pressure plate or a tripwire.
    2410         */
    2411        public boolean doesEntityNotTriggerPressurePlate()
    2412        {
    2413            return false;
    2414        }
    2415
    2416        public void func_85029_a(CrashReportCategory par1CrashReportCategory)
    2417        {
    2418            par1CrashReportCategory.addCrashSectionCallable("Entity Type", new CallableEntityType(this));
    2419            par1CrashReportCategory.addCrashSection("Entity ID", Integer.valueOf(this.entityId));
    2420            par1CrashReportCategory.addCrashSection("Name", this.getEntityName());
    2421            par1CrashReportCategory.addCrashSection("Exact location", String.format("%.2f, %.2f, %.2f", new Object[] {Double.valueOf(this.posX), Double.valueOf(this.posY), Double.valueOf(this.posZ)}));
    2422            par1CrashReportCategory.addCrashSection("Block location", CrashReportCategory.func_85071_a(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)));
    2423            par1CrashReportCategory.addCrashSection("Momentum", String.format("%.2f, %.2f, %.2f", new Object[] {Double.valueOf(this.motionX), Double.valueOf(this.motionY), Double.valueOf(this.motionZ)}));
    2424        }
    2425
    2426        @SideOnly(Side.CLIENT)
    2427        public boolean func_90999_ad()
    2428        {
    2429            return this.isBurning();
    2430        }
    2431
    2432        /* ================================== Forge Start =====================================*/
    2433        /**
    2434         * Returns a NBTTagCompound that can be used to store custom data for this entity.
    2435         * It will be written, and read from disc, so it persists over world saves.
    2436         * @return A NBTTagCompound
    2437         */
    2438        public NBTTagCompound getEntityData()
    2439        {
    2440            if (customEntityData == null)
    2441            {
    2442                customEntityData = new NBTTagCompound();
    2443            }
    2444            return customEntityData;
    2445        }
    2446
    2447        /**
    2448         * Used in model rendering to determine if the entity riding this entity should be in the 'sitting' position.
    2449         * @return false to prevent an entity that is mounted to this entity from displaying the 'sitting' animation.
    2450         */
    2451        public boolean shouldRiderSit()
    2452        {
    2453            return true;
    2454        }
    2455
    2456        /**
    2457         * Called when a user uses the creative pick block button on this entity.
    2458         *
    2459         * @param target The full target the player is looking at
    2460         * @return A ItemStack to add to the player's inventory, Null if nothing should be added.
    2461         */
    2462        public ItemStack getPickedResult(MovingObjectPosition target)
    2463        {
    2464            if (this instanceof EntityPainting)
    2465            {
    2466                return new ItemStack(Item.painting);
    2467            }
    2468            else if (this instanceof EntityMinecart)
    2469            {
    2470                return ((EntityMinecart)this).getCartItem();
    2471            }
    2472            else if (this instanceof EntityBoat)
    2473            {
    2474                return new ItemStack(Item.boat);
    2475            }
    2476            else if (this instanceof EntityItemFrame)
    2477            {
    2478                ItemStack held = ((EntityItemFrame)this).getDisplayedItem();
    2479                if (held == null)
    2480                {
    2481                    return new ItemStack(Item.itemFrame);
    2482                }
    2483                else
    2484                {
    2485                    return held.copy();
    2486                }
    2487            }
    2488            else
    2489            {
    2490                int id = EntityList.getEntityID(this);
    2491                if (id > 0 && EntityList.entityEggs.containsKey(id))
    2492                {
    2493                    return new ItemStack(Item.monsterPlacer, 1, id);
    2494                }
    2495            }
    2496            return null;
    2497        }
    2498
    2499        public UUID getPersistentID()
    2500        {
    2501            return persistentID;
    2502        }
    2503
    2504        public synchronized void generatePersistentID()
    2505        {
    2506            if (persistentID == null)
    2507            {
    2508                persistentID = UUID.randomUUID();
    2509            }
    2510        }
    2511    }