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