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