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