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