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