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.func_82145_z();
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.func_82147_ab();
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.travelToTheEnd(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        public int func_82145_z()
573        {
574            return 0;
575        }
576    
577        /**
578         * Called whenever the entity is walking inside of lava.
579         */
580        protected void setOnFireFromLava()
581        {
582            if (!this.isImmuneToFire)
583            {
584                this.attackEntityFrom(DamageSource.lava, 4);
585                this.setFire(15);
586            }
587        }
588    
589        /**
590         * Sets entity to burn for x amount of seconds, cannot lower amount of existing fire.
591         */
592        public void setFire(int par1)
593        {
594            int var2 = par1 * 20;
595    
596            if (this.fire < var2)
597            {
598                this.fire = var2;
599            }
600        }
601    
602        /**
603         * Removes fire from entity.
604         */
605        public void extinguish()
606        {
607            this.fire = 0;
608        }
609    
610        /**
611         * sets the dead flag. Used when you fall off the bottom of the world.
612         */
613        protected void kill()
614        {
615            this.setDead();
616        }
617    
618        /**
619         * Checks if the offset position from the entity's current position is inside of liquid. Args: x, y, z
620         */
621        public boolean isOffsetPositionInLiquid(double par1, double par3, double par5)
622        {
623            AxisAlignedBB var7 = this.boundingBox.getOffsetBoundingBox(par1, par3, par5);
624            List var8 = this.worldObj.getCollidingBoundingBoxes(this, var7);
625            return !var8.isEmpty() ? false : !this.worldObj.isAnyLiquid(var7);
626        }
627    
628        /**
629         * Tries to moves the entity by the passed in displacement. Args: x, y, z
630         */
631        public void moveEntity(double par1, double par3, double par5)
632        {
633            if (this.noClip)
634            {
635                this.boundingBox.offset(par1, par3, par5);
636                this.posX = (this.boundingBox.minX + this.boundingBox.maxX) / 2.0D;
637                this.posY = this.boundingBox.minY + (double)this.yOffset - (double)this.ySize;
638                this.posZ = (this.boundingBox.minZ + this.boundingBox.maxZ) / 2.0D;
639            }
640            else
641            {
642                this.worldObj.theProfiler.startSection("move");
643                this.ySize *= 0.4F;
644                double var7 = this.posX;
645                double var9 = this.posY;
646                double var11 = this.posZ;
647    
648                if (this.isInWeb)
649                {
650                    this.isInWeb = false;
651                    par1 *= 0.25D;
652                    par3 *= 0.05000000074505806D;
653                    par5 *= 0.25D;
654                    this.motionX = 0.0D;
655                    this.motionY = 0.0D;
656                    this.motionZ = 0.0D;
657                }
658    
659                double var13 = par1;
660                double var15 = par3;
661                double var17 = par5;
662                AxisAlignedBB var19 = this.boundingBox.copy();
663                boolean var20 = this.onGround && this.isSneaking() && this instanceof EntityPlayer;
664    
665                if (var20)
666                {
667                    double var21;
668    
669                    for (var21 = 0.05D; par1 != 0.0D && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.getOffsetBoundingBox(par1, -1.0D, 0.0D)).isEmpty(); var13 = par1)
670                    {
671                        if (par1 < var21 && par1 >= -var21)
672                        {
673                            par1 = 0.0D;
674                        }
675                        else if (par1 > 0.0D)
676                        {
677                            par1 -= var21;
678                        }
679                        else
680                        {
681                            par1 += var21;
682                        }
683                    }
684    
685                    for (; par5 != 0.0D && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.getOffsetBoundingBox(0.0D, -1.0D, par5)).isEmpty(); var17 = par5)
686                    {
687                        if (par5 < var21 && par5 >= -var21)
688                        {
689                            par5 = 0.0D;
690                        }
691                        else if (par5 > 0.0D)
692                        {
693                            par5 -= var21;
694                        }
695                        else
696                        {
697                            par5 += var21;
698                        }
699                    }
700    
701                    while (par1 != 0.0D && par5 != 0.0D && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.getOffsetBoundingBox(par1, -1.0D, par5)).isEmpty())
702                    {
703                        if (par1 < var21 && par1 >= -var21)
704                        {
705                            par1 = 0.0D;
706                        }
707                        else if (par1 > 0.0D)
708                        {
709                            par1 -= var21;
710                        }
711                        else
712                        {
713                            par1 += var21;
714                        }
715    
716                        if (par5 < var21 && par5 >= -var21)
717                        {
718                            par5 = 0.0D;
719                        }
720                        else if (par5 > 0.0D)
721                        {
722                            par5 -= var21;
723                        }
724                        else
725                        {
726                            par5 += var21;
727                        }
728    
729                        var13 = par1;
730                        var17 = par5;
731                    }
732                }
733    
734                List var36 = this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.addCoord(par1, par3, par5));
735                AxisAlignedBB var23;
736    
737                for (Iterator var22 = var36.iterator(); var22.hasNext(); par3 = var23.calculateYOffset(this.boundingBox, par3))
738                {
739                    var23 = (AxisAlignedBB)var22.next();
740                }
741    
742                this.boundingBox.offset(0.0D, par3, 0.0D);
743    
744                if (!this.field_70135_K && var15 != par3)
745                {
746                    par5 = 0.0D;
747                    par3 = 0.0D;
748                    par1 = 0.0D;
749                }
750    
751                boolean var34 = this.onGround || var15 != par3 && var15 < 0.0D;
752                AxisAlignedBB var24;
753                Iterator var35;
754    
755                for (var35 = var36.iterator(); var35.hasNext(); par1 = var24.calculateXOffset(this.boundingBox, par1))
756                {
757                    var24 = (AxisAlignedBB)var35.next();
758                }
759    
760                this.boundingBox.offset(par1, 0.0D, 0.0D);
761    
762                if (!this.field_70135_K && var13 != par1)
763                {
764                    par5 = 0.0D;
765                    par3 = 0.0D;
766                    par1 = 0.0D;
767                }
768    
769                for (var35 = var36.iterator(); var35.hasNext(); par5 = var24.calculateZOffset(this.boundingBox, par5))
770                {
771                    var24 = (AxisAlignedBB)var35.next();
772                }
773    
774                this.boundingBox.offset(0.0D, 0.0D, par5);
775    
776                if (!this.field_70135_K && var17 != par5)
777                {
778                    par5 = 0.0D;
779                    par3 = 0.0D;
780                    par1 = 0.0D;
781                }
782    
783                double var25;
784                double var27;
785                double var37;
786    
787                if (this.stepHeight > 0.0F && var34 && (var20 || this.ySize < 0.05F) && (var13 != par1 || var17 != par5))
788                {
789                    var37 = par1;
790                    var25 = par3;
791                    var27 = par5;
792                    par1 = var13;
793                    par3 = (double)this.stepHeight;
794                    par5 = var17;
795                    AxisAlignedBB var29 = this.boundingBox.copy();
796                    this.boundingBox.setBB(var19);
797                    var36 = this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.addCoord(var13, par3, var17));
798                    AxisAlignedBB var31;
799                    Iterator var30;
800    
801                    for (var30 = var36.iterator(); var30.hasNext(); par3 = var31.calculateYOffset(this.boundingBox, par3))
802                    {
803                        var31 = (AxisAlignedBB)var30.next();
804                    }
805    
806                    this.boundingBox.offset(0.0D, par3, 0.0D);
807    
808                    if (!this.field_70135_K && var15 != par3)
809                    {
810                        par5 = 0.0D;
811                        par3 = 0.0D;
812                        par1 = 0.0D;
813                    }
814    
815                    for (var30 = var36.iterator(); var30.hasNext(); par1 = var31.calculateXOffset(this.boundingBox, par1))
816                    {
817                        var31 = (AxisAlignedBB)var30.next();
818                    }
819    
820                    this.boundingBox.offset(par1, 0.0D, 0.0D);
821    
822                    if (!this.field_70135_K && var13 != par1)
823                    {
824                        par5 = 0.0D;
825                        par3 = 0.0D;
826                        par1 = 0.0D;
827                    }
828    
829                    for (var30 = var36.iterator(); var30.hasNext(); par5 = var31.calculateZOffset(this.boundingBox, par5))
830                    {
831                        var31 = (AxisAlignedBB)var30.next();
832                    }
833    
834                    this.boundingBox.offset(0.0D, 0.0D, par5);
835    
836                    if (!this.field_70135_K && var17 != par5)
837                    {
838                        par5 = 0.0D;
839                        par3 = 0.0D;
840                        par1 = 0.0D;
841                    }
842    
843                    if (!this.field_70135_K && var15 != par3)
844                    {
845                        par5 = 0.0D;
846                        par3 = 0.0D;
847                        par1 = 0.0D;
848                    }
849                    else
850                    {
851                        par3 = (double)(-this.stepHeight);
852    
853                        for (var30 = var36.iterator(); var30.hasNext(); par3 = var31.calculateYOffset(this.boundingBox, par3))
854                        {
855                            var31 = (AxisAlignedBB)var30.next();
856                        }
857    
858                        this.boundingBox.offset(0.0D, par3, 0.0D);
859                    }
860    
861                    if (var37 * var37 + var27 * var27 >= par1 * par1 + par5 * par5)
862                    {
863                        par1 = var37;
864                        par3 = var25;
865                        par5 = var27;
866                        this.boundingBox.setBB(var29);
867                    }
868                    else
869                    {
870                        double var38 = this.boundingBox.minY - (double)((int)this.boundingBox.minY);
871    
872                        if (var38 > 0.0D)
873                        {
874                            this.ySize = (float)((double)this.ySize + var38 + 0.01D);
875                        }
876                    }
877                }
878    
879                this.worldObj.theProfiler.endSection();
880                this.worldObj.theProfiler.startSection("rest");
881                this.posX = (this.boundingBox.minX + this.boundingBox.maxX) / 2.0D;
882                this.posY = this.boundingBox.minY + (double)this.yOffset - (double)this.ySize;
883                this.posZ = (this.boundingBox.minZ + this.boundingBox.maxZ) / 2.0D;
884                this.isCollidedHorizontally = var13 != par1 || var17 != par5;
885                this.isCollidedVertically = var15 != par3;
886                this.onGround = var15 != par3 && var15 < 0.0D;
887                this.isCollided = this.isCollidedHorizontally || this.isCollidedVertically;
888                this.updateFallState(par3, this.onGround);
889    
890                if (var13 != par1)
891                {
892                    this.motionX = 0.0D;
893                }
894    
895                if (var15 != par3)
896                {
897                    this.motionY = 0.0D;
898                }
899    
900                if (var17 != par5)
901                {
902                    this.motionZ = 0.0D;
903                }
904    
905                var37 = this.posX - var7;
906                var25 = this.posY - var9;
907                var27 = this.posZ - var11;
908    
909                if (this.canTriggerWalking() && !var20 && this.ridingEntity == null)
910                {
911                    int var39 = MathHelper.floor_double(this.posX);
912                    int var42 = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double)this.yOffset);
913                    int var41 = MathHelper.floor_double(this.posZ);
914                    int var32 = this.worldObj.getBlockId(var39, var42, var41);
915    
916                    if (var32 == 0 && this.worldObj.getBlockId(var39, var42 - 1, var41) == Block.fence.blockID)
917                    {
918                        var32 = this.worldObj.getBlockId(var39, var42 - 1, var41);
919                    }
920    
921                    if (var32 != Block.ladder.blockID)
922                    {
923                        var25 = 0.0D;
924                    }
925    
926                    this.distanceWalkedModified = (float)((double)this.distanceWalkedModified + (double)MathHelper.sqrt_double(var37 * var37 + var27 * var27) * 0.6D);
927                    this.field_82151_R = (float)((double)this.field_82151_R + (double)MathHelper.sqrt_double(var37 * var37 + var25 * var25 + var27 * var27) * 0.6D);
928    
929                    if (this.field_82151_R > (float)this.nextStepDistance && var32 > 0)
930                    {
931                        this.nextStepDistance = (int)this.field_82151_R + 1;
932    
933                        if (this.isInWater())
934                        {
935                            float var33 = MathHelper.sqrt_double(this.motionX * this.motionX * 0.20000000298023224D + this.motionY * this.motionY + this.motionZ * this.motionZ * 0.20000000298023224D) * 0.35F;
936    
937                            if (var33 > 1.0F)
938                            {
939                                var33 = 1.0F;
940                            }
941    
942                            this.worldObj.playSoundAtEntity(this, "liquid.swim", var33, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F);
943                        }
944    
945                        this.playStepSound(var39, var42, var41, var32);
946                        Block.blocksList[var32].onEntityWalking(this.worldObj, var39, var42, var41, this);
947                    }
948                }
949    
950                this.doBlockCollisions();
951                boolean var40 = this.isWet();
952    
953                if (this.worldObj.isBoundingBoxBurning(this.boundingBox.contract(0.001D, 0.001D, 0.001D)))
954                {
955                    this.dealFireDamage(1);
956    
957                    if (!var40)
958                    {
959                        ++this.fire;
960    
961                        if (this.fire == 0)
962                        {
963                            this.setFire(8);
964                        }
965                    }
966                }
967                else if (this.fire <= 0)
968                {
969                    this.fire = -this.fireResistance;
970                }
971    
972                if (var40 && this.fire > 0)
973                {
974                    this.worldObj.playSoundAtEntity(this, "random.fizz", 0.7F, 1.6F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F);
975                    this.fire = -this.fireResistance;
976                }
977    
978                this.worldObj.theProfiler.endSection();
979            }
980        }
981    
982        /**
983         * Checks for block collisions, and calls the associated onBlockCollided method for the collided block.
984         */
985        protected void doBlockCollisions()
986        {
987            int var1 = MathHelper.floor_double(this.boundingBox.minX + 0.001D);
988            int var2 = MathHelper.floor_double(this.boundingBox.minY + 0.001D);
989            int var3 = MathHelper.floor_double(this.boundingBox.minZ + 0.001D);
990            int var4 = MathHelper.floor_double(this.boundingBox.maxX - 0.001D);
991            int var5 = MathHelper.floor_double(this.boundingBox.maxY - 0.001D);
992            int var6 = MathHelper.floor_double(this.boundingBox.maxZ - 0.001D);
993    
994            if (this.worldObj.checkChunksExist(var1, var2, var3, var4, var5, var6))
995            {
996                for (int var7 = var1; var7 <= var4; ++var7)
997                {
998                    for (int var8 = var2; var8 <= var5; ++var8)
999                    {
1000                        for (int var9 = var3; var9 <= var6; ++var9)
1001                        {
1002                            int var10 = this.worldObj.getBlockId(var7, var8, var9);
1003    
1004                            if (var10 > 0)
1005                            {
1006                                Block.blocksList[var10].onEntityCollidedWithBlock(this.worldObj, var7, var8, var9, this);
1007                            }
1008                        }
1009                    }
1010                }
1011            }
1012        }
1013    
1014        /**
1015         * Plays step sound at given x, y, z for the entity
1016         */
1017        protected void playStepSound(int par1, int par2, int par3, int par4)
1018        {
1019            StepSound var5 = Block.blocksList[par4].stepSound;
1020    
1021            if (this.worldObj.getBlockId(par1, par2 + 1, par3) == Block.snow.blockID)
1022            {
1023                var5 = Block.snow.stepSound;
1024                this.worldObj.playSoundAtEntity(this, var5.getStepSound(), var5.getVolume() * 0.15F, var5.getPitch());
1025            }
1026            else if (!Block.blocksList[par4].blockMaterial.isLiquid())
1027            {
1028                this.worldObj.playSoundAtEntity(this, var5.getStepSound(), var5.getVolume() * 0.15F, var5.getPitch());
1029            }
1030        }
1031    
1032        /**
1033         * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
1034         * prevent them from trampling crops
1035         */
1036        protected boolean canTriggerWalking()
1037        {
1038            return true;
1039        }
1040    
1041        /**
1042         * Takes in the distance the entity has fallen this tick and whether its on the ground to update the fall distance
1043         * and deal fall damage if landing on the ground.  Args: distanceFallenThisTick, onGround
1044         */
1045        protected void updateFallState(double par1, boolean par3)
1046        {
1047            if (par3)
1048            {
1049                if (this.fallDistance > 0.0F)
1050                {
1051                    this.fall(this.fallDistance);
1052                    this.fallDistance = 0.0F;
1053                }
1054            }
1055            else if (par1 < 0.0D)
1056            {
1057                this.fallDistance = (float)((double)this.fallDistance - par1);
1058            }
1059        }
1060    
1061        /**
1062         * returns the bounding box for this entity
1063         */
1064        public AxisAlignedBB getBoundingBox()
1065        {
1066            return null;
1067        }
1068    
1069        /**
1070         * Will deal the specified amount of damage to the entity if the entity isn't immune to fire damage. Args:
1071         * amountDamage
1072         */
1073        protected void dealFireDamage(int par1)
1074        {
1075            if (!this.isImmuneToFire)
1076            {
1077                this.attackEntityFrom(DamageSource.inFire, par1);
1078            }
1079        }
1080    
1081        public final boolean isImmuneToFire()
1082        {
1083            return this.isImmuneToFire;
1084        }
1085    
1086        /**
1087         * Called when the mob is falling. Calculates and applies fall damage.
1088         */
1089        protected void fall(float par1)
1090        {
1091            if (this.riddenByEntity != null)
1092            {
1093                this.riddenByEntity.fall(par1);
1094            }
1095        }
1096    
1097        /**
1098         * Checks if this entity is either in water or on an open air block in rain (used in wolves).
1099         */
1100        public boolean isWet()
1101        {
1102            return this.inWater || this.worldObj.canLightningStrikeAt(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ));
1103        }
1104    
1105        /**
1106         * Checks if this entity is inside water (if inWater field is true as a result of handleWaterMovement() returning
1107         * true)
1108         */
1109        public boolean isInWater()
1110        {
1111            return this.inWater;
1112        }
1113    
1114        /**
1115         * Returns if this entity is in water and will end up adding the waters velocity to the entity
1116         */
1117        public boolean handleWaterMovement()
1118        {
1119            return this.worldObj.handleMaterialAcceleration(this.boundingBox.expand(0.0D, -0.4000000059604645D, 0.0D).contract(0.001D, 0.001D, 0.001D), Material.water, this);
1120        }
1121    
1122        /**
1123         * Checks if the current block the entity is within of the specified material type
1124         */
1125        public boolean isInsideOfMaterial(Material par1Material)
1126        {
1127            double var2 = this.posY + (double)this.getEyeHeight();
1128            int var4 = MathHelper.floor_double(this.posX);
1129            int var5 = MathHelper.floor_float((float)MathHelper.floor_double(var2));
1130            int var6 = MathHelper.floor_double(this.posZ);
1131            int var7 = this.worldObj.getBlockId(var4, var5, var6);
1132    
1133            if (var7 != 0 && Block.blocksList[var7].blockMaterial == par1Material)
1134            {
1135                float var8 = BlockFluid.getFluidHeightPercent(this.worldObj.getBlockMetadata(var4, var5, var6)) - 0.11111111F;
1136                float var9 = (float)(var5 + 1) - var8;
1137                return var2 < (double)var9;
1138            }
1139            else
1140            {
1141                return false;
1142            }
1143        }
1144    
1145        public float getEyeHeight()
1146        {
1147            return 0.0F;
1148        }
1149    
1150        /**
1151         * Whether or not the current entity is in lava
1152         */
1153        public boolean handleLavaMovement()
1154        {
1155            return this.worldObj.isMaterialInBB(this.boundingBox.expand(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), Material.lava);
1156        }
1157    
1158        /**
1159         * Used in both water and by flying objects
1160         */
1161        public void moveFlying(float par1, float par2, float par3)
1162        {
1163            float var4 = par1 * par1 + par2 * par2;
1164    
1165            if (var4 >= 1.0E-4F)
1166            {
1167                var4 = MathHelper.sqrt_float(var4);
1168    
1169                if (var4 < 1.0F)
1170                {
1171                    var4 = 1.0F;
1172                }
1173    
1174                var4 = par3 / var4;
1175                par1 *= var4;
1176                par2 *= var4;
1177                float var5 = MathHelper.sin(this.rotationYaw * (float)Math.PI / 180.0F);
1178                float var6 = MathHelper.cos(this.rotationYaw * (float)Math.PI / 180.0F);
1179                this.motionX += (double)(par1 * var6 - par2 * var5);
1180                this.motionZ += (double)(par2 * var6 + par1 * var5);
1181            }
1182        }
1183    
1184        @SideOnly(Side.CLIENT)
1185        public int getBrightnessForRender(float par1)
1186        {
1187            int var2 = MathHelper.floor_double(this.posX);
1188            int var3 = MathHelper.floor_double(this.posZ);
1189    
1190            if (this.worldObj.blockExists(var2, 0, var3))
1191            {
1192                double var4 = (this.boundingBox.maxY - this.boundingBox.minY) * 0.66D;
1193                int var6 = MathHelper.floor_double(this.posY - (double)this.yOffset + var4);
1194                return this.worldObj.getLightBrightnessForSkyBlocks(var2, var6, var3, 0);
1195            }
1196            else
1197            {
1198                return 0;
1199            }
1200        }
1201    
1202        /**
1203         * Gets how bright this entity is.
1204         */
1205        public float getBrightness(float par1)
1206        {
1207            int var2 = MathHelper.floor_double(this.posX);
1208            int var3 = MathHelper.floor_double(this.posZ);
1209    
1210            if (this.worldObj.blockExists(var2, 0, var3))
1211            {
1212                double var4 = (this.boundingBox.maxY - this.boundingBox.minY) * 0.66D;
1213                int var6 = MathHelper.floor_double(this.posY - (double)this.yOffset + var4);
1214                return this.worldObj.getLightBrightness(var2, var6, var3);
1215            }
1216            else
1217            {
1218                return 0.0F;
1219            }
1220        }
1221    
1222        /**
1223         * Sets the reference to the World object.
1224         */
1225        public void setWorld(World par1World)
1226        {
1227            this.worldObj = par1World;
1228        }
1229    
1230        /**
1231         * Sets the entity's position and rotation. Args: posX, posY, posZ, yaw, pitch
1232         */
1233        public void setPositionAndRotation(double par1, double par3, double par5, float par7, float par8)
1234        {
1235            this.prevPosX = this.posX = par1;
1236            this.prevPosY = this.posY = par3;
1237            this.prevPosZ = this.posZ = par5;
1238            this.prevRotationYaw = this.rotationYaw = par7;
1239            this.prevRotationPitch = this.rotationPitch = par8;
1240            this.ySize = 0.0F;
1241            double var9 = (double)(this.prevRotationYaw - par7);
1242    
1243            if (var9 < -180.0D)
1244            {
1245                this.prevRotationYaw += 360.0F;
1246            }
1247    
1248            if (var9 >= 180.0D)
1249            {
1250                this.prevRotationYaw -= 360.0F;
1251            }
1252    
1253            this.setPosition(this.posX, this.posY, this.posZ);
1254            this.setRotation(par7, par8);
1255        }
1256    
1257        /**
1258         * Sets the location and Yaw/Pitch of an entity in the world
1259         */
1260        public void setLocationAndAngles(double par1, double par3, double par5, float par7, float par8)
1261        {
1262            this.lastTickPosX = this.prevPosX = this.posX = par1;
1263            this.lastTickPosY = this.prevPosY = this.posY = par3 + (double)this.yOffset;
1264            this.lastTickPosZ = this.prevPosZ = this.posZ = par5;
1265            this.rotationYaw = par7;
1266            this.rotationPitch = par8;
1267            this.setPosition(this.posX, this.posY, this.posZ);
1268        }
1269    
1270        /**
1271         * Returns the distance to the entity. Args: entity
1272         */
1273        public float getDistanceToEntity(Entity par1Entity)
1274        {
1275            float var2 = (float)(this.posX - par1Entity.posX);
1276            float var3 = (float)(this.posY - par1Entity.posY);
1277            float var4 = (float)(this.posZ - par1Entity.posZ);
1278            return MathHelper.sqrt_float(var2 * var2 + var3 * var3 + var4 * var4);
1279        }
1280    
1281        /**
1282         * Gets the squared distance to the position. Args: x, y, z
1283         */
1284        public double getDistanceSq(double par1, double par3, double par5)
1285        {
1286            double var7 = this.posX - par1;
1287            double var9 = this.posY - par3;
1288            double var11 = this.posZ - par5;
1289            return var7 * var7 + var9 * var9 + var11 * var11;
1290        }
1291    
1292        /**
1293         * Gets the distance to the position. Args: x, y, z
1294         */
1295        public double getDistance(double par1, double par3, double par5)
1296        {
1297            double var7 = this.posX - par1;
1298            double var9 = this.posY - par3;
1299            double var11 = this.posZ - par5;
1300            return (double)MathHelper.sqrt_double(var7 * var7 + var9 * var9 + var11 * var11);
1301        }
1302    
1303        /**
1304         * Returns the squared distance to the entity. Args: entity
1305         */
1306        public double getDistanceSqToEntity(Entity par1Entity)
1307        {
1308            double var2 = this.posX - par1Entity.posX;
1309            double var4 = this.posY - par1Entity.posY;
1310            double var6 = this.posZ - par1Entity.posZ;
1311            return var2 * var2 + var4 * var4 + var6 * var6;
1312        }
1313    
1314        /**
1315         * Called by a player entity when they collide with an entity
1316         */
1317        public void onCollideWithPlayer(EntityPlayer par1EntityPlayer) {}
1318    
1319        /**
1320         * Applies a velocity to each of the entities pushing them away from each other. Args: entity
1321         */
1322        public void applyEntityCollision(Entity par1Entity)
1323        {
1324            if (par1Entity.riddenByEntity != this && par1Entity.ridingEntity != this)
1325            {
1326                double var2 = par1Entity.posX - this.posX;
1327                double var4 = par1Entity.posZ - this.posZ;
1328                double var6 = MathHelper.abs_max(var2, var4);
1329    
1330                if (var6 >= 0.009999999776482582D)
1331                {
1332                    var6 = (double)MathHelper.sqrt_double(var6);
1333                    var2 /= var6;
1334                    var4 /= var6;
1335                    double var8 = 1.0D / var6;
1336    
1337                    if (var8 > 1.0D)
1338                    {
1339                        var8 = 1.0D;
1340                    }
1341    
1342                    var2 *= var8;
1343                    var4 *= var8;
1344                    var2 *= 0.05000000074505806D;
1345                    var4 *= 0.05000000074505806D;
1346                    var2 *= (double)(1.0F - this.entityCollisionReduction);
1347                    var4 *= (double)(1.0F - this.entityCollisionReduction);
1348                    this.addVelocity(-var2, 0.0D, -var4);
1349                    par1Entity.addVelocity(var2, 0.0D, var4);
1350                }
1351            }
1352        }
1353    
1354        /**
1355         * Adds to the current velocity of the entity. Args: x, y, z
1356         */
1357        public void addVelocity(double par1, double par3, double par5)
1358        {
1359            this.motionX += par1;
1360            this.motionY += par3;
1361            this.motionZ += par5;
1362            this.isAirBorne = true;
1363        }
1364    
1365        /**
1366         * Sets that this entity has been attacked.
1367         */
1368        protected void setBeenAttacked()
1369        {
1370            this.velocityChanged = true;
1371        }
1372    
1373        /**
1374         * Called when the entity is attacked.
1375         */
1376        public boolean attackEntityFrom(DamageSource par1DamageSource, int par2)
1377        {
1378            this.setBeenAttacked();
1379            return false;
1380        }
1381    
1382        /**
1383         * Returns true if other Entities should be prevented from moving through this Entity.
1384         */
1385        public boolean canBeCollidedWith()
1386        {
1387            return false;
1388        }
1389    
1390        /**
1391         * Returns true if this entity should push and be pushed by other entities when colliding.
1392         */
1393        public boolean canBePushed()
1394        {
1395            return false;
1396        }
1397    
1398        /**
1399         * Adds a value to the player score. Currently not actually used and the entity passed in does nothing. Args:
1400         * entity, scoreToAdd
1401         */
1402        public void addToPlayerScore(Entity par1Entity, int par2) {}
1403    
1404        /**
1405         * adds the ID of this entity to the NBT given
1406         */
1407        public boolean addEntityID(NBTTagCompound par1NBTTagCompound)
1408        {
1409            String var2 = this.getEntityString();
1410    
1411            if (!this.isDead && var2 != null)
1412            {
1413                par1NBTTagCompound.setString("id", var2);
1414                this.writeToNBT(par1NBTTagCompound);
1415                return true;
1416            }
1417            else
1418            {
1419                return false;
1420            }
1421        }
1422    
1423        @SideOnly(Side.CLIENT)
1424    
1425        /**
1426         * Checks using a Vec3d to determine if this entity is within range of that vector to be rendered. Args: vec3D
1427         */
1428        public boolean isInRangeToRenderVec3D(Vec3 par1Vec3)
1429        {
1430            double var2 = this.posX - par1Vec3.xCoord;
1431            double var4 = this.posY - par1Vec3.yCoord;
1432            double var6 = this.posZ - par1Vec3.zCoord;
1433            double var8 = var2 * var2 + var4 * var4 + var6 * var6;
1434            return this.isInRangeToRenderDist(var8);
1435        }
1436    
1437        @SideOnly(Side.CLIENT)
1438    
1439        /**
1440         * Checks if the entity is in range to render by using the past in distance and comparing it to its average edge
1441         * length * 64 * renderDistanceWeight Args: distance
1442         */
1443        public boolean isInRangeToRenderDist(double par1)
1444        {
1445            double var3 = this.boundingBox.getAverageEdgeLength();
1446            var3 *= 64.0D * this.renderDistanceWeight;
1447            return par1 < var3 * var3;
1448        }
1449    
1450        @SideOnly(Side.CLIENT)
1451    
1452        /**
1453         * Returns the texture's file path as a String.
1454         */
1455        public String getTexture()
1456        {
1457            return null;
1458        }
1459    
1460        /**
1461         * Save the entity to NBT (calls an abstract helper method to write extra data)
1462         */
1463        public void writeToNBT(NBTTagCompound par1NBTTagCompound)
1464        {
1465            par1NBTTagCompound.setTag("Pos", this.newDoubleNBTList(new double[] {this.posX, this.posY + (double)this.ySize, this.posZ}));
1466            par1NBTTagCompound.setTag("Motion", this.newDoubleNBTList(new double[] {this.motionX, this.motionY, this.motionZ}));
1467            par1NBTTagCompound.setTag("Rotation", this.newFloatNBTList(new float[] {this.rotationYaw, this.rotationPitch}));
1468            par1NBTTagCompound.setFloat("FallDistance", this.fallDistance);
1469            par1NBTTagCompound.setShort("Fire", (short)this.fire);
1470            par1NBTTagCompound.setShort("Air", (short)this.getAir());
1471            par1NBTTagCompound.setBoolean("OnGround", this.onGround);
1472            par1NBTTagCompound.setInteger("Dimension", this.dimension);
1473            if (persistentID != null)
1474            {
1475                par1NBTTagCompound.setLong("PersistentIDMSB", persistentID.getMostSignificantBits());
1476                par1NBTTagCompound.setLong("PersistentIDLSB", persistentID.getLeastSignificantBits());
1477            }
1478            if (customEntityData != null)
1479            {
1480                par1NBTTagCompound.setCompoundTag("ForgeData", customEntityData);
1481            }
1482            this.writeEntityToNBT(par1NBTTagCompound);
1483        }
1484    
1485        /**
1486         * Reads the entity from NBT (calls an abstract helper method to read specialized data)
1487         */
1488        public void readFromNBT(NBTTagCompound par1NBTTagCompound)
1489        {
1490            NBTTagList var2 = par1NBTTagCompound.getTagList("Pos");
1491            NBTTagList var3 = par1NBTTagCompound.getTagList("Motion");
1492            NBTTagList var4 = par1NBTTagCompound.getTagList("Rotation");
1493            this.motionX = ((NBTTagDouble)var3.tagAt(0)).data;
1494            this.motionY = ((NBTTagDouble)var3.tagAt(1)).data;
1495            this.motionZ = ((NBTTagDouble)var3.tagAt(2)).data;
1496    
1497            if (Math.abs(this.motionX) > 10.0D)
1498            {
1499                this.motionX = 0.0D;
1500            }
1501    
1502            if (Math.abs(this.motionY) > 10.0D)
1503            {
1504                this.motionY = 0.0D;
1505            }
1506    
1507            if (Math.abs(this.motionZ) > 10.0D)
1508            {
1509                this.motionZ = 0.0D;
1510            }
1511    
1512            this.prevPosX = this.lastTickPosX = this.posX = ((NBTTagDouble)var2.tagAt(0)).data;
1513            this.prevPosY = this.lastTickPosY = this.posY = ((NBTTagDouble)var2.tagAt(1)).data;
1514            this.prevPosZ = this.lastTickPosZ = this.posZ = ((NBTTagDouble)var2.tagAt(2)).data;
1515            this.prevRotationYaw = this.rotationYaw = ((NBTTagFloat)var4.tagAt(0)).data;
1516            this.prevRotationPitch = this.rotationPitch = ((NBTTagFloat)var4.tagAt(1)).data;
1517            this.fallDistance = par1NBTTagCompound.getFloat("FallDistance");
1518            this.fire = par1NBTTagCompound.getShort("Fire");
1519            this.setAir(par1NBTTagCompound.getShort("Air"));
1520            this.onGround = par1NBTTagCompound.getBoolean("OnGround");
1521            this.dimension = par1NBTTagCompound.getInteger("Dimension");
1522            this.setPosition(this.posX, this.posY, this.posZ);
1523            this.setRotation(this.rotationYaw, this.rotationPitch);
1524            if (par1NBTTagCompound.hasKey("ForgeData"))
1525            {
1526                customEntityData = par1NBTTagCompound.getCompoundTag("ForgeData");
1527            }
1528            if (par1NBTTagCompound.hasKey("PersistentIDMSB") && par1NBTTagCompound.hasKey("PersistentIDLSB"))
1529            {
1530                persistentID = new UUID(par1NBTTagCompound.getLong("PersistentIDMSB"), par1NBTTagCompound.getLong("PersistentIDLSB"));
1531            }
1532            this.readEntityFromNBT(par1NBTTagCompound);
1533        }
1534    
1535        /**
1536         * Returns the string that identifies this Entity's class
1537         */
1538        protected final String getEntityString()
1539        {
1540            return EntityList.getEntityString(this);
1541        }
1542    
1543        /**
1544         * (abstract) Protected helper method to read subclass entity data from NBT.
1545         */
1546        protected abstract void readEntityFromNBT(NBTTagCompound var1);
1547    
1548        /**
1549         * (abstract) Protected helper method to write subclass entity data to NBT.
1550         */
1551        protected abstract void writeEntityToNBT(NBTTagCompound var1);
1552    
1553        /**
1554         * creates a NBT list from the array of doubles passed to this function
1555         */
1556        protected NBTTagList newDoubleNBTList(double ... par1ArrayOfDouble)
1557        {
1558            NBTTagList var2 = new NBTTagList();
1559            double[] var3 = par1ArrayOfDouble;
1560            int var4 = par1ArrayOfDouble.length;
1561    
1562            for (int var5 = 0; var5 < var4; ++var5)
1563            {
1564                double var6 = var3[var5];
1565                var2.appendTag(new NBTTagDouble((String)null, var6));
1566            }
1567    
1568            return var2;
1569        }
1570    
1571        /**
1572         * Returns a new NBTTagList filled with the specified floats
1573         */
1574        protected NBTTagList newFloatNBTList(float ... par1ArrayOfFloat)
1575        {
1576            NBTTagList var2 = new NBTTagList();
1577            float[] var3 = par1ArrayOfFloat;
1578            int var4 = par1ArrayOfFloat.length;
1579    
1580            for (int var5 = 0; var5 < var4; ++var5)
1581            {
1582                float var6 = var3[var5];
1583                var2.appendTag(new NBTTagFloat((String)null, var6));
1584            }
1585    
1586            return var2;
1587        }
1588    
1589        @SideOnly(Side.CLIENT)
1590        public float getShadowSize()
1591        {
1592            return this.height / 2.0F;
1593        }
1594    
1595        /**
1596         * Drops an item stack at the entity's position. Args: itemID, count
1597         */
1598        public EntityItem dropItem(int par1, int par2)
1599        {
1600            return this.dropItemWithOffset(par1, par2, 0.0F);
1601        }
1602    
1603        /**
1604         * Drops an item stack with a specified y offset. Args: itemID, count, yOffset
1605         */
1606        public EntityItem dropItemWithOffset(int par1, int par2, float par3)
1607        {
1608            return this.entityDropItem(new ItemStack(par1, par2, 0), par3);
1609        }
1610    
1611        /**
1612         * Drops an item at the position of the entity.
1613         */
1614        public EntityItem entityDropItem(ItemStack par1ItemStack, float par2)
1615        {
1616            EntityItem var3 = new EntityItem(this.worldObj, this.posX, this.posY + (double)par2, this.posZ, par1ItemStack);
1617            var3.delayBeforeCanPickup = 10;
1618            if (captureDrops)
1619            {
1620                capturedDrops.add(var3);
1621            }
1622            else
1623            {
1624                this.worldObj.spawnEntityInWorld(var3);
1625            }
1626            return var3;
1627        }
1628    
1629        /**
1630         * Checks whether target entity is alive.
1631         */
1632        public boolean isEntityAlive()
1633        {
1634            return !this.isDead;
1635        }
1636    
1637        /**
1638         * Checks if this entity is inside of an opaque block
1639         */
1640        public boolean isEntityInsideOpaqueBlock()
1641        {
1642            for (int var1 = 0; var1 < 8; ++var1)
1643            {
1644                float var2 = ((float)((var1 >> 0) % 2) - 0.5F) * this.width * 0.8F;
1645                float var3 = ((float)((var1 >> 1) % 2) - 0.5F) * 0.1F;
1646                float var4 = ((float)((var1 >> 2) % 2) - 0.5F) * this.width * 0.8F;
1647                int var5 = MathHelper.floor_double(this.posX + (double)var2);
1648                int var6 = MathHelper.floor_double(this.posY + (double)this.getEyeHeight() + (double)var3);
1649                int var7 = MathHelper.floor_double(this.posZ + (double)var4);
1650    
1651                if (this.worldObj.isBlockNormalCube(var5, var6, var7))
1652                {
1653                    return true;
1654                }
1655            }
1656    
1657            return false;
1658        }
1659    
1660        /**
1661         * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
1662         */
1663        public boolean interact(EntityPlayer par1EntityPlayer)
1664        {
1665            return false;
1666        }
1667    
1668        /**
1669         * Returns a boundingBox used to collide the entity with other entities and blocks. This enables the entity to be
1670         * pushable on contact, like boats or minecarts.
1671         */
1672        public AxisAlignedBB getCollisionBox(Entity par1Entity)
1673        {
1674            return null;
1675        }
1676    
1677        /**
1678         * Handles updating while being ridden by an entity
1679         */
1680        public void updateRidden()
1681        {
1682            if (this.ridingEntity.isDead)
1683            {
1684                this.ridingEntity = null;
1685            }
1686            else
1687            {
1688                this.motionX = 0.0D;
1689                this.motionY = 0.0D;
1690                this.motionZ = 0.0D;
1691                this.onUpdate();
1692    
1693                if (this.ridingEntity != null)
1694                {
1695                    this.ridingEntity.updateRiderPosition();
1696                    this.entityRiderYawDelta += (double)(this.ridingEntity.rotationYaw - this.ridingEntity.prevRotationYaw);
1697    
1698                    for (this.entityRiderPitchDelta += (double)(this.ridingEntity.rotationPitch - this.ridingEntity.prevRotationPitch); this.entityRiderYawDelta >= 180.0D; this.entityRiderYawDelta -= 360.0D)
1699                    {
1700                        ;
1701                    }
1702    
1703                    while (this.entityRiderYawDelta < -180.0D)
1704                    {
1705                        this.entityRiderYawDelta += 360.0D;
1706                    }
1707    
1708                    while (this.entityRiderPitchDelta >= 180.0D)
1709                    {
1710                        this.entityRiderPitchDelta -= 360.0D;
1711                    }
1712    
1713                    while (this.entityRiderPitchDelta < -180.0D)
1714                    {
1715                        this.entityRiderPitchDelta += 360.0D;
1716                    }
1717    
1718                    double var1 = this.entityRiderYawDelta * 0.5D;
1719                    double var3 = this.entityRiderPitchDelta * 0.5D;
1720                    float var5 = 10.0F;
1721    
1722                    if (var1 > (double)var5)
1723                    {
1724                        var1 = (double)var5;
1725                    }
1726    
1727                    if (var1 < (double)(-var5))
1728                    {
1729                        var1 = (double)(-var5);
1730                    }
1731    
1732                    if (var3 > (double)var5)
1733                    {
1734                        var3 = (double)var5;
1735                    }
1736    
1737                    if (var3 < (double)(-var5))
1738                    {
1739                        var3 = (double)(-var5);
1740                    }
1741    
1742                    this.entityRiderYawDelta -= var1;
1743                    this.entityRiderPitchDelta -= var3;
1744                    this.rotationYaw = (float)((double)this.rotationYaw + var1);
1745                    this.rotationPitch = (float)((double)this.rotationPitch + var3);
1746                }
1747            }
1748        }
1749    
1750        public void updateRiderPosition()
1751        {
1752            if (!(this.riddenByEntity instanceof EntityPlayer) || !((EntityPlayer)this.riddenByEntity).func_71066_bF())
1753            {
1754                this.riddenByEntity.lastTickPosX = this.lastTickPosX;
1755                this.riddenByEntity.lastTickPosY = this.lastTickPosY + this.getMountedYOffset() + this.riddenByEntity.getYOffset();
1756                this.riddenByEntity.lastTickPosZ = this.lastTickPosZ;
1757            }
1758    
1759            this.riddenByEntity.setPosition(this.posX, this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ);
1760        }
1761    
1762        /**
1763         * Returns the Y Offset of this entity.
1764         */
1765        public double getYOffset()
1766        {
1767            return (double)this.yOffset;
1768        }
1769    
1770        /**
1771         * Returns the Y offset from the entity's position for any entity riding this one.
1772         */
1773        public double getMountedYOffset()
1774        {
1775            return (double)this.height * 0.75D;
1776        }
1777    
1778        /**
1779         * Called when a player mounts an entity. e.g. mounts a pig, mounts a boat.
1780         */
1781        public void mountEntity(Entity par1Entity)
1782        {
1783            this.entityRiderPitchDelta = 0.0D;
1784            this.entityRiderYawDelta = 0.0D;
1785    
1786            if (par1Entity == null)
1787            {
1788                if (this.ridingEntity != null)
1789                {
1790                    this.setLocationAndAngles(this.ridingEntity.posX, this.ridingEntity.boundingBox.minY + (double)this.ridingEntity.height, this.ridingEntity.posZ, this.rotationYaw, this.rotationPitch);
1791                    this.ridingEntity.riddenByEntity = null;
1792                }
1793    
1794                this.ridingEntity = null;
1795            }
1796            else if (this.ridingEntity == par1Entity)
1797            {
1798                this.unmountEntity(par1Entity);
1799                this.ridingEntity.riddenByEntity = null;
1800                this.ridingEntity = null;
1801            }
1802            else
1803            {
1804                if (this.ridingEntity != null)
1805                {
1806                    this.ridingEntity.riddenByEntity = null;
1807                }
1808    
1809                if (par1Entity.riddenByEntity != null)
1810                {
1811                    par1Entity.riddenByEntity.ridingEntity = null;
1812                }
1813    
1814                this.ridingEntity = par1Entity;
1815                par1Entity.riddenByEntity = this;
1816            }
1817        }
1818    
1819        /**
1820         * Called when a player unounts an entity.
1821         */
1822        public void unmountEntity(Entity par1Entity)
1823        {
1824            double var3 = par1Entity.posX;
1825            double var5 = par1Entity.boundingBox.minY + (double)par1Entity.height;
1826            double var7 = par1Entity.posZ;
1827    
1828            for (double var9 = -1.5D; var9 < 2.0D; ++var9)
1829            {
1830                for (double var11 = -1.5D; var11 < 2.0D; ++var11)
1831                {
1832                    if (var9 != 0.0D || var11 != 0.0D)
1833                    {
1834                        int var13 = (int)(this.posX + var9);
1835                        int var14 = (int)(this.posZ + var11);
1836                        AxisAlignedBB var2 = this.boundingBox.getOffsetBoundingBox(var9, 1.0D, var11);
1837    
1838                        if (this.worldObj.getAllCollidingBoundingBoxes(var2).isEmpty())
1839                        {
1840                            if (this.worldObj.doesBlockHaveSolidTopSurface(var13, (int)this.posY, var14))
1841                            {
1842                                this.setLocationAndAngles(this.posX + var9, this.posY + 1.0D, this.posZ + var11, this.rotationYaw, this.rotationPitch);
1843                                return;
1844                            }
1845    
1846                            if (this.worldObj.doesBlockHaveSolidTopSurface(var13, (int)this.posY - 1, var14) || this.worldObj.getBlockMaterial(var13, (int)this.posY - 1, var14) == Material.water)
1847                            {
1848                                var3 = this.posX + var9;
1849                                var5 = this.posY + 1.0D;
1850                                var7 = this.posZ + var11;
1851                            }
1852                        }
1853                    }
1854                }
1855            }
1856    
1857            this.setLocationAndAngles(var3, var5, var7, this.rotationYaw, this.rotationPitch);
1858        }
1859    
1860        @SideOnly(Side.CLIENT)
1861    
1862        /**
1863         * Sets the position and rotation. Only difference from the other one is no bounding on the rotation. Args: posX,
1864         * posY, posZ, yaw, pitch
1865         */
1866        public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9)
1867        {
1868            this.setPosition(par1, par3, par5);
1869            this.setRotation(par7, par8);
1870            List var10 = this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.contract(0.03125D, 0.0D, 0.03125D));
1871    
1872            if (!var10.isEmpty())
1873            {
1874                double var11 = 0.0D;
1875                Iterator var13 = var10.iterator();
1876    
1877                while (var13.hasNext())
1878                {
1879                    AxisAlignedBB var14 = (AxisAlignedBB)var13.next();
1880    
1881                    if (var14.maxY > var11)
1882                    {
1883                        var11 = var14.maxY;
1884                    }
1885                }
1886    
1887                par3 += var11 - this.boundingBox.minY;
1888                this.setPosition(par1, par3, par5);
1889            }
1890        }
1891    
1892        public float getCollisionBorderSize()
1893        {
1894            return 0.1F;
1895        }
1896    
1897        /**
1898         * returns a (normalized) vector of where this entity is looking
1899         */
1900        public Vec3 getLookVec()
1901        {
1902            return null;
1903        }
1904    
1905        /**
1906         * Called by portal blocks when an entity is within it.
1907         */
1908        public void setInPortal()
1909        {
1910            if (this.timeUntilPortal > 0)
1911            {
1912                this.timeUntilPortal = this.func_82147_ab();
1913            }
1914            else
1915            {
1916                double var1 = this.prevPosX - this.posX;
1917                double var3 = this.prevPosZ - this.posZ;
1918    
1919                if (!this.worldObj.isRemote && !this.inPortal)
1920                {
1921                    this.field_82152_aq = Direction.func_82372_a(var1, var3);
1922                }
1923    
1924                this.inPortal = true;
1925            }
1926        }
1927    
1928        public int func_82147_ab()
1929        {
1930            return 500;
1931        }
1932    
1933        @SideOnly(Side.CLIENT)
1934    
1935        /**
1936         * Sets the velocity to the args. Args: x, y, z
1937         */
1938        public void setVelocity(double par1, double par3, double par5)
1939        {
1940            this.motionX = par1;
1941            this.motionY = par3;
1942            this.motionZ = par5;
1943        }
1944    
1945        @SideOnly(Side.CLIENT)
1946        public void handleHealthUpdate(byte par1) {}
1947    
1948        @SideOnly(Side.CLIENT)
1949    
1950        /**
1951         * Setups the entity to do the hurt animation. Only used by packets in multiplayer.
1952         */
1953        public void performHurtAnimation() {}
1954    
1955        @SideOnly(Side.CLIENT)
1956        public void updateCloak() {}
1957    
1958        public ItemStack[] getLastActiveItems()
1959        {
1960            return null;
1961        }
1962    
1963        public void func_70062_b(int par1, ItemStack par2ItemStack) {}
1964    
1965        /**
1966         * Returns true if the entity is on fire. Used by render to add the fire effect on rendering.
1967         */
1968        public boolean isBurning()
1969        {
1970            return this.fire > 0 || this.getFlag(0);
1971        }
1972    
1973        /**
1974         * Returns true if the entity is riding another entity, used by render to rotate the legs to be in 'sit' position
1975         * for players.
1976         */
1977        public boolean isRiding()
1978        {
1979            return (this.ridingEntity != null && ridingEntity.shouldRiderSit()) || this.getFlag(2);
1980        }
1981    
1982        /**
1983         * Returns if this entity is sneaking.
1984         */
1985        public boolean isSneaking()
1986        {
1987            return this.getFlag(1);
1988        }
1989    
1990        /**
1991         * Sets the sneaking flag.
1992         */
1993        public void setSneaking(boolean par1)
1994        {
1995            this.setFlag(1, par1);
1996        }
1997    
1998        /**
1999         * Get if the Entity is sprinting.
2000         */
2001        public boolean isSprinting()
2002        {
2003            return this.getFlag(3);
2004        }
2005    
2006        /**
2007         * Set sprinting switch for Entity.
2008         */
2009        public void setSprinting(boolean par1)
2010        {
2011            this.setFlag(3, par1);
2012        }
2013    
2014        public boolean func_82150_aj()
2015        {
2016            return this.getFlag(5);
2017        }
2018    
2019        public void func_82142_c(boolean par1)
2020        {
2021            this.setFlag(5, par1);
2022        }
2023    
2024        @SideOnly(Side.CLIENT)
2025        public boolean isEating()
2026        {
2027            return this.getFlag(4);
2028        }
2029    
2030        public void setEating(boolean par1)
2031        {
2032            this.setFlag(4, par1);
2033        }
2034    
2035        /**
2036         * Returns true if the flag is active for the entity. Known flags: 0) is burning; 1) is sneaking; 2) is riding
2037         * something; 3) is sprinting; 4) is eating
2038         */
2039        protected boolean getFlag(int par1)
2040        {
2041            return (this.dataWatcher.getWatchableObjectByte(0) & 1 << par1) != 0;
2042        }
2043    
2044        /**
2045         * Enable or disable a entity flag, see getEntityFlag to read the know flags.
2046         */
2047        protected void setFlag(int par1, boolean par2)
2048        {
2049            byte var3 = this.dataWatcher.getWatchableObjectByte(0);
2050    
2051            if (par2)
2052            {
2053                this.dataWatcher.updateObject(0, Byte.valueOf((byte)(var3 | 1 << par1)));
2054            }
2055            else
2056            {
2057                this.dataWatcher.updateObject(0, Byte.valueOf((byte)(var3 & ~(1 << par1))));
2058            }
2059        }
2060    
2061        public int getAir()
2062        {
2063            return this.dataWatcher.getWatchableObjectShort(1);
2064        }
2065    
2066        public void setAir(int par1)
2067        {
2068            this.dataWatcher.updateObject(1, Short.valueOf((short)par1));
2069        }
2070    
2071        /**
2072         * Called when a lightning bolt hits the entity.
2073         */
2074        public void onStruckByLightning(EntityLightningBolt par1EntityLightningBolt)
2075        {
2076            this.dealFireDamage(5);
2077            ++this.fire;
2078    
2079            if (this.fire == 0)
2080            {
2081                this.setFire(8);
2082            }
2083        }
2084    
2085        /**
2086         * This method gets called when the entity kills another one.
2087         */
2088        public void onKillEntity(EntityLiving par1EntityLiving) {}
2089    
2090        /**
2091         * Adds velocity to push the entity out of blocks at the specified x, y, z position Args: x, y, z
2092         */
2093        protected boolean pushOutOfBlocks(double par1, double par3, double par5)
2094        {
2095            int var7 = MathHelper.floor_double(par1);
2096            int var8 = MathHelper.floor_double(par3);
2097            int var9 = MathHelper.floor_double(par5);
2098            double var10 = par1 - (double)var7;
2099            double var12 = par3 - (double)var8;
2100            double var14 = par5 - (double)var9;
2101    
2102            if (this.worldObj.isBlockNormalCube(var7, var8, var9))
2103            {
2104                boolean var16 = !this.worldObj.isBlockNormalCube(var7 - 1, var8, var9);
2105                boolean var17 = !this.worldObj.isBlockNormalCube(var7 + 1, var8, var9);
2106                boolean var18 = !this.worldObj.isBlockNormalCube(var7, var8 - 1, var9);
2107                boolean var19 = !this.worldObj.isBlockNormalCube(var7, var8 + 1, var9);
2108                boolean var20 = !this.worldObj.isBlockNormalCube(var7, var8, var9 - 1);
2109                boolean var21 = !this.worldObj.isBlockNormalCube(var7, var8, var9 + 1);
2110                byte var22 = -1;
2111                double var23 = 9999.0D;
2112    
2113                if (var16 && var10 < var23)
2114                {
2115                    var23 = var10;
2116                    var22 = 0;
2117                }
2118    
2119                if (var17 && 1.0D - var10 < var23)
2120                {
2121                    var23 = 1.0D - var10;
2122                    var22 = 1;
2123                }
2124    
2125                if (var18 && var12 < var23)
2126                {
2127                    var23 = var12;
2128                    var22 = 2;
2129                }
2130    
2131                if (var19 && 1.0D - var12 < var23)
2132                {
2133                    var23 = 1.0D - var12;
2134                    var22 = 3;
2135                }
2136    
2137                if (var20 && var14 < var23)
2138                {
2139                    var23 = var14;
2140                    var22 = 4;
2141                }
2142    
2143                if (var21 && 1.0D - var14 < var23)
2144                {
2145                    var23 = 1.0D - var14;
2146                    var22 = 5;
2147                }
2148    
2149                float var25 = this.rand.nextFloat() * 0.2F + 0.1F;
2150    
2151                if (var22 == 0)
2152                {
2153                    this.motionX = (double)(-var25);
2154                }
2155    
2156                if (var22 == 1)
2157                {
2158                    this.motionX = (double)var25;
2159                }
2160    
2161                if (var22 == 2)
2162                {
2163                    this.motionY = (double)(-var25);
2164                }
2165    
2166                if (var22 == 3)
2167                {
2168                    this.motionY = (double)var25;
2169                }
2170    
2171                if (var22 == 4)
2172                {
2173                    this.motionZ = (double)(-var25);
2174                }
2175    
2176                if (var22 == 5)
2177                {
2178                    this.motionZ = (double)var25;
2179                }
2180    
2181                return true;
2182            }
2183            else
2184            {
2185                return false;
2186            }
2187        }
2188    
2189        /**
2190         * Sets the Entity inside a web block.
2191         */
2192        public void setInWeb()
2193        {
2194            this.isInWeb = true;
2195            this.fallDistance = 0.0F;
2196        }
2197    
2198        /**
2199         * Gets the username of the entity.
2200         */
2201        public String getEntityName()
2202        {
2203            String var1 = EntityList.getEntityString(this);
2204    
2205            if (var1 == null)
2206            {
2207                var1 = "generic";
2208            }
2209    
2210            return StatCollector.translateToLocal("entity." + var1 + ".name");
2211        }
2212    
2213        /**
2214         * Return the Entity parts making up this Entity (currently only for dragons)
2215         */
2216        public Entity[] getParts()
2217        {
2218            return null;
2219        }
2220    
2221        /**
2222         * Returns true if Entity argument is equal to this Entity
2223         */
2224        public boolean isEntityEqual(Entity par1Entity)
2225        {
2226            return this == par1Entity;
2227        }
2228    
2229        public float func_70079_am()
2230        {
2231            return 0.0F;
2232        }
2233    
2234        @SideOnly(Side.CLIENT)
2235    
2236        /**
2237         * Sets the head's yaw rotation of the entity.
2238         */
2239        public void setHeadRotationYaw(float par1) {}
2240    
2241        /**
2242         * If returns false, the item will not inflict any damage against entities.
2243         */
2244        public boolean canAttackWithItem()
2245        {
2246            return true;
2247        }
2248    
2249        public String toString()
2250        {
2251            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)});
2252        }
2253    
2254        public void func_82149_j(Entity par1Entity)
2255        {
2256            this.setLocationAndAngles(par1Entity.posX, par1Entity.posY, par1Entity.posZ, par1Entity.rotationYaw, par1Entity.rotationPitch);
2257        }
2258    
2259        public void func_82141_a(Entity par1Entity, boolean par2)
2260        {
2261            NBTTagCompound var3 = new NBTTagCompound();
2262            par1Entity.writeToNBT(var3);
2263            this.readFromNBT(var3);
2264            this.timeUntilPortal = par1Entity.timeUntilPortal;
2265            this.field_82152_aq = par1Entity.field_82152_aq;
2266        }
2267    
2268        public void travelToTheEnd(int par1)
2269        {
2270            if (!this.worldObj.isRemote && !this.isDead)
2271            {
2272                MinecraftServer var2 = MinecraftServer.getServer();
2273                int var3 = this.dimension;
2274                WorldServer var4 = var2.worldServerForDimension(var3);
2275                WorldServer var5 = var2.worldServerForDimension(par1);
2276                this.dimension = par1;
2277                this.worldObj.setEntityDead(this);
2278                this.isDead = false;
2279                var2.getConfigurationManager().func_82448_a(this, var3, var4, var5);
2280                Entity var6 = EntityList.createEntityByName(EntityList.getEntityString(this), var5);
2281    
2282                if (var6 != null)
2283                {
2284                    var6.func_82141_a(this, true);
2285                    var5.spawnEntityInWorld(var6);
2286                }
2287    
2288                this.isDead = true;
2289                var4.func_82742_i();
2290                var5.func_82742_i();
2291            }
2292        }
2293    
2294        public float func_82146_a(Explosion par1Explosion, Block par2Block, int par3, int par4, int par5)
2295        {
2296            return par2Block.getExplosionResistance(this, worldObj, par3, par4, par5, posX, posY + (double)getEyeHeight(), posZ);
2297        }
2298    
2299        public int func_82143_as()
2300        {
2301            return 3;
2302        }
2303    
2304        public int func_82148_at()
2305        {
2306            return this.field_82152_aq;
2307        }
2308    
2309        public boolean func_82144_au()
2310        {
2311            return false;
2312        }
2313    
2314        /* ================================== Forge Start =====================================*/
2315        /**
2316         * Returns a NBTTagCompound that can be used to store custom data for this entity.
2317         * It will be written, and read from disc, so it persists over world saves.
2318         * @return A NBTTagCompound
2319         */
2320        public NBTTagCompound getEntityData()
2321        {
2322            if (customEntityData == null)
2323            {
2324                customEntityData = new NBTTagCompound();
2325            }
2326            return customEntityData;
2327        }
2328    
2329        /**
2330         * Used in model rendering to determine if the entity riding this entity should be in the 'sitting' position.
2331         * @return false to prevent an entity that is mounted to this entity from displaying the 'sitting' animation.
2332         */
2333        public boolean shouldRiderSit()
2334        {
2335            return true;
2336        }
2337    
2338        /**
2339         * Called when a user uses the creative pick block button on this entity.
2340         *
2341         * @param target The full target the player is looking at
2342         * @return A ItemStack to add to the player's inventory, Null if nothing should be added.
2343         */
2344        public ItemStack getPickedResult(MovingObjectPosition target)
2345        {
2346            if (this instanceof EntityPainting)
2347            {
2348                return new ItemStack(Item.painting);
2349            }
2350            else if (this instanceof EntityMinecart)
2351            {
2352                return ((EntityMinecart)this).getCartItem();
2353            }
2354            else if (this instanceof EntityBoat)
2355            {
2356                return new ItemStack(Item.boat);
2357            }
2358            else if (this instanceof EntityItemFrame)
2359            {
2360                ItemStack held = ((EntityItemFrame)this).func_82335_i();
2361                if (held == null)
2362                {
2363                    return new ItemStack(Item.field_82802_bI);
2364                }
2365                else
2366                {
2367                    return held.copy();
2368                }
2369            }
2370            else
2371            {
2372                int id = EntityList.getEntityID(this);
2373                if (id > 0 && EntityList.entityEggs.containsKey(id))
2374                {
2375                    return new ItemStack(Item.monsterPlacer, 1, id);
2376                }
2377            }
2378            return null;
2379        }
2380    
2381        public UUID getPersistentID()
2382        {
2383            return persistentID;
2384        }
2385    
2386        public synchronized void generatePersistentID()
2387        {
2388            if (persistentID == null)
2389            {
2390                persistentID = UUID.randomUUID();
2391            }
2392        }
2393    }