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