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