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