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