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