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