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