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