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