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