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