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