Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
at develop 1366 lines 44 kB view raw
1package net.minecraft.server; 2 3import org.bukkit.Bukkit; 4import org.bukkit.block.BlockFace; 5import org.bukkit.craftbukkit.entity.CraftPlayer; 6import org.bukkit.entity.LivingEntity; 7import org.bukkit.entity.Vehicle; 8import org.bukkit.event.entity.EntityCombustEvent; 9import org.bukkit.event.entity.EntityDamageByBlockEvent; 10import org.bukkit.event.entity.EntityDamageByEntityEvent; 11import org.bukkit.event.entity.EntityDamageEvent; 12import org.bukkit.event.vehicle.VehicleBlockCollisionEvent; 13import org.bukkit.event.vehicle.VehicleExitEvent; 14 15import uk.betacraft.uberbukkit.UberbukkitConfig; 16 17import java.util.List; 18import java.util.Random; 19import java.util.UUID; 20 21// CraftBukkit start 22// CraftBukkit end 23 24public abstract class Entity { 25 26 // Poseidon start - Backport of 0070-Use-a-Shared-Random-for-Entities.patch from PaperSpigot 27 public static Random SHARED_RANDOM = new Random() { 28 private boolean locked = false; 29 30 @Override 31 public synchronized void setSeed(long seed) { 32 if (locked) { 33 // Ignoring setSeed on Entity.SHARED_RANDOM 34 } else { 35 super.setSeed(seed); 36 locked = true; 37 } 38 } 39 }; 40 // Poseidon end 41 // uberbukkit 42 private static final boolean trampleFarmlandAboveFence = UberbukkitConfig.getInstance().getBoolean("mechanics.trample_farmland_above_fence", false); 43 44 private static int entityCount = 0; 45 public int id; 46 public double aH; 47 public boolean aI; 48 public Entity passenger; 49 public Entity vehicle; 50 public World world; 51 public double lastX; 52 public double lastY; 53 public double lastZ; 54 public double locX; 55 public double locY; 56 public double locZ; 57 public double motX; 58 public double motY; 59 public double motZ; 60 public float yaw; 61 public float pitch; 62 public float lastYaw; 63 public float lastPitch; 64 public final AxisAlignedBB boundingBox; 65 public boolean onGround; 66 public boolean positionChanged; 67 public boolean bc; 68 public boolean bd; 69 public boolean velocityChanged; 70 public boolean bf; 71 public boolean bg; 72 public boolean dead; 73 public float height; 74 public float length; 75 public float width; 76 public float bl; 77 public float bm; 78 public float fallDistance; // CraftBukkit - private -> public 79 private int b; 80 public double bo; 81 public double bp; 82 public double bq; 83 public float br; 84 public float bs; 85 public boolean bt; 86 public float bu; 87 protected Random random; 88 public int ticksLived; 89 public int maxFireTicks; 90 public int fireTicks; 91 public int maxAirTicks; // CraftBukkit - protected - >public 92 protected boolean bA; 93 public int noDamageTicks; 94 public int airTicks; 95 private boolean justCreated; 96 protected boolean fireProof; 97 protected DataWatcher datawatcher; 98 public float bF; 99 private double d; 100 private double e; 101 public boolean bG; 102 public int bH; 103 public int bI; 104 public int bJ; 105 public boolean bK; 106 public boolean airBorne; 107 public UUID uniqueId = UUID.randomUUID(); // CraftBukkit 108 109 public Entity(World world) { 110 this.id = entityCount++; 111 this.aH = 1.0D; 112 this.aI = false; 113 this.boundingBox = AxisAlignedBB.a(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D); 114 this.onGround = false; 115 this.bd = false; 116 this.velocityChanged = false; 117 this.bg = true; 118 this.dead = false; 119 this.height = 0.0F; 120 this.length = 0.6F; 121 this.width = 1.8F; 122 this.bl = 0.0F; 123 this.bm = 0.0F; 124 this.fallDistance = 0.0F; 125 this.b = 1; 126 this.br = 0.0F; 127 this.bs = 0.0F; 128 this.bt = false; 129 this.bu = 0.0F; 130 this.random = SHARED_RANDOM; 131 this.ticksLived = 0; 132 this.maxFireTicks = 1; 133 this.fireTicks = 0; 134 this.maxAirTicks = 300; 135 this.bA = false; 136 this.noDamageTicks = 0; 137 this.airTicks = 300; 138 this.justCreated = true; 139 this.fireProof = false; 140 this.datawatcher = new DataWatcher(); 141 this.bF = 0.0F; 142 this.bG = false; 143 this.world = world; 144 this.setPosition(0.0D, 0.0D, 0.0D); 145 this.datawatcher.a(0, Byte.valueOf((byte) 0)); 146 this.b(); 147 } 148 149 protected abstract void b(); 150 151 public DataWatcher aa() { 152 return this.datawatcher; 153 } 154 155 public boolean equals(Object object) { 156 return object instanceof Entity ? ((Entity) object).id == this.id : false; 157 } 158 159 public int hashCode() { 160 return this.id; 161 } 162 163 public void die() { 164 this.dead = true; 165 } 166 167 protected void b(float f, float f1) { 168 this.length = f; 169 this.width = f1; 170 } 171 172 protected void c(float f, float f1) { 173 // CraftBukkit start - yaw was sometimes set to NaN, so we need to set it back to 0. 174 if (Float.isNaN(f)) { 175 f = 0; 176 } 177 178 if ((f == Float.POSITIVE_INFINITY) || (f == Float.NEGATIVE_INFINITY)) { 179 if (this instanceof EntityPlayer) { 180 System.err.println(((CraftPlayer) this.getBukkitEntity()).getName() + " was caught trying to crash the server with an invalid yaw"); 181 ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Nope"); 182 } 183 f = 0; 184 } 185 186 // pitch was sometimes set to NaN, so we need to set it back to 0. 187 if (Float.isNaN(f1)) { 188 f1 = 0; 189 } 190 191 if ((f1 == Float.POSITIVE_INFINITY) || (f1 == Float.NEGATIVE_INFINITY)) { 192 if (this instanceof EntityPlayer) { 193 System.err.println(((CraftPlayer) this.getBukkitEntity()).getName() + " was caught trying to crash the server with an invalid pitch"); 194 ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Nope"); 195 } 196 f1 = 0; 197 } 198 // CraftBukkit end 199 200 this.yaw = f % 360.0F; 201 this.pitch = f1 % 360.0F; 202 } 203 204 public void setPosition(double d0, double d1, double d2) { 205 this.locX = d0; 206 this.locY = d1; 207 this.locZ = d2; 208 float f = this.length / 2.0F; 209 float f1 = this.width; 210 211 this.boundingBox.c(d0 - (double) f, d1 - (double) this.height + (double) this.br, d2 - (double) f, d0 + (double) f, d1 - (double) this.height + (double) this.br + (double) f1, d2 + (double) f); 212 } 213 214 public void m_() { 215 this.R(); 216 } 217 218 public void R() { 219 if (this.vehicle != null && this.vehicle.dead) { 220 this.vehicle = null; 221 } 222 223 ++this.ticksLived; 224 this.bl = this.bm; 225 this.lastX = this.locX; 226 this.lastY = this.locY; 227 this.lastZ = this.locZ; 228 this.lastPitch = this.pitch; 229 this.lastYaw = this.yaw; 230 if (this.f_()) { 231 if (!this.bA && !this.justCreated) { 232 float f = MathHelper.a(this.motX * this.motX * 0.20000000298023224D + this.motY * this.motY + this.motZ * this.motZ * 0.20000000298023224D) * 0.2F; 233 234 if (f > 1.0F) { 235 f = 1.0F; 236 } 237 238 this.world.makeSound(this, "random.splash", f, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); 239 float f1 = (float) MathHelper.floor(this.boundingBox.b); 240 241 int i; 242 float f2; 243 float f3; 244 245 for (i = 0; (float) i < 1.0F + this.length * 20.0F; ++i) { 246 f2 = (this.random.nextFloat() * 2.0F - 1.0F) * this.length; 247 f3 = (this.random.nextFloat() * 2.0F - 1.0F) * this.length; 248 this.world.a("bubble", this.locX + (double) f2, (double) (f1 + 1.0F), this.locZ + (double) f3, this.motX, this.motY - (double) (this.random.nextFloat() * 0.2F), this.motZ); 249 } 250 251 for (i = 0; (float) i < 1.0F + this.length * 20.0F; ++i) { 252 f2 = (this.random.nextFloat() * 2.0F - 1.0F) * this.length; 253 f3 = (this.random.nextFloat() * 2.0F - 1.0F) * this.length; 254 this.world.a("splash", this.locX + (double) f2, (double) (f1 + 1.0F), this.locZ + (double) f3, this.motX, this.motY, this.motZ); 255 } 256 } 257 258 this.fallDistance = 0.0F; 259 this.bA = true; 260 this.fireTicks = 0; 261 } else { 262 this.bA = false; 263 } 264 265 if (this.world.isStatic) { 266 this.fireTicks = 0; 267 } else if (this.fireTicks > 0) { 268 if (this.fireProof) { 269 this.fireTicks -= 4; 270 if (this.fireTicks < 0) { 271 this.fireTicks = 0; 272 } 273 } else { 274 if (this.fireTicks % 20 == 0) { 275 // CraftBukkit start - TODO: this event spams! 276 if (this instanceof EntityLiving) { 277 EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.FIRE_TICK, 1); 278 this.world.getServer().getPluginManager().callEvent(event); 279 280 if (!event.isCancelled()) { 281 this.damageEntity((Entity) null, event.getDamage()); 282 } 283 } else { 284 this.damageEntity((Entity) null, 1); 285 } 286 // CraftBukkit end 287 } 288 289 --this.fireTicks; 290 } 291 } 292 293 if (this.ae()) { 294 this.ab(); 295 } 296 297 if (this.locY < -64.0D) { 298 this.Y(); 299 } 300 301 if (!this.world.isStatic) { 302 this.a(0, this.fireTicks > 0); 303 this.a(2, this.vehicle != null); 304 } 305 306 this.justCreated = false; 307 } 308 309 protected void ab() { 310 if (!this.fireProof) { 311 // CraftBukkit start - TODO: this event spams! 312 if (this instanceof EntityLiving) { 313 org.bukkit.Server server = this.world.getServer(); 314 315 // TODO: shouldn't be sending null for the block. 316 org.bukkit.block.Block damager = null; // ((WorldServer) this.l).getWorld().getBlockAt(i, j, k); 317 org.bukkit.entity.Entity damagee = this.getBukkitEntity(); 318 319 EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagee, EntityDamageEvent.DamageCause.LAVA, 4); 320 server.getPluginManager().callEvent(event); 321 322 if (!event.isCancelled()) { 323 this.damageEntity((Entity) null, event.getDamage()); 324 } 325 326 if (this.fireTicks <= 0) { 327 // not on fire yet 328 EntityCombustEvent combustEvent = new EntityCombustEvent(damagee); 329 server.getPluginManager().callEvent(combustEvent); 330 331 if (!combustEvent.isCancelled()) { 332 this.fireTicks = 600; 333 } 334 } else { 335 // reset fire level back to max 336 this.fireTicks = 600; 337 } 338 return; 339 } 340 // CraftBukkit end 341 342 this.damageEntity((Entity) null, 4); 343 this.fireTicks = 600; 344 } 345 } 346 347 protected void Y() { 348 this.die(); 349 } 350 351 public boolean d(double d0, double d1, double d2) { 352 AxisAlignedBB axisalignedbb = this.boundingBox.c(d0, d1, d2); 353 List list = this.world.getEntities(this, axisalignedbb); 354 355 return list.size() > 0 ? false : !this.world.c(axisalignedbb); 356 } 357 358 public void move(double d0, double d1, double d2) { 359 if (this.bt) { 360 this.boundingBox.d(d0, d1, d2); 361 this.locX = (this.boundingBox.a + this.boundingBox.d) / 2.0D; 362 this.locY = this.boundingBox.b + (double) this.height - (double) this.br; 363 this.locZ = (this.boundingBox.c + this.boundingBox.f) / 2.0D; 364 } else { 365 this.br *= 0.4F; 366 double d3 = this.locX; 367 double d4 = this.locZ; 368 369 if (this.bf) { 370 this.bf = false; 371 d0 *= 0.25D; 372 d1 *= 0.05000000074505806D; 373 d2 *= 0.25D; 374 this.motX = 0.0D; 375 this.motY = 0.0D; 376 this.motZ = 0.0D; 377 } 378 379 double d5 = d0; 380 double d6 = d1; 381 double d7 = d2; 382 AxisAlignedBB axisalignedbb = this.boundingBox.clone(); 383 boolean flag = this.onGround && this.isSneaking(); 384 385 if (flag) { 386 double d8; 387 388 for (d8 = 0.05D; d0 != 0.0D && this.world.getEntities(this, this.boundingBox.c(d0, -1.0D, 0.0D)).size() == 0; d5 = d0) { 389 if (d0 < d8 && d0 >= -d8) { 390 d0 = 0.0D; 391 } else if (d0 > 0.0D) { 392 d0 -= d8; 393 } else { 394 d0 += d8; 395 } 396 } 397 398 for (; d2 != 0.0D && this.world.getEntities(this, this.boundingBox.c(0.0D, -1.0D, d2)).size() == 0; d7 = d2) { 399 if (d2 < d8 && d2 >= -d8) { 400 d2 = 0.0D; 401 } else if (d2 > 0.0D) { 402 d2 -= d8; 403 } else { 404 d2 += d8; 405 } 406 } 407 } 408 409 List list = this.world.getEntities(this, this.boundingBox.a(d0, d1, d2)); 410 411 for (int i = 0; i < list.size(); ++i) { 412 d1 = ((AxisAlignedBB) list.get(i)).b(this.boundingBox, d1); 413 } 414 415 this.boundingBox.d(0.0D, d1, 0.0D); 416 if (!this.bg && d6 != d1) { 417 d2 = 0.0D; 418 d1 = 0.0D; 419 d0 = 0.0D; 420 } 421 422 boolean flag1 = this.onGround || d6 != d1 && d6 < 0.0D; 423 424 int j; 425 426 for (j = 0; j < list.size(); ++j) { 427 d0 = ((AxisAlignedBB) list.get(j)).a(this.boundingBox, d0); 428 } 429 430 this.boundingBox.d(d0, 0.0D, 0.0D); 431 if (!this.bg && d5 != d0) { 432 d2 = 0.0D; 433 d1 = 0.0D; 434 d0 = 0.0D; 435 } 436 437 for (j = 0; j < list.size(); ++j) { 438 d2 = ((AxisAlignedBB) list.get(j)).c(this.boundingBox, d2); 439 } 440 441 this.boundingBox.d(0.0D, 0.0D, d2); 442 if (!this.bg && d7 != d2) { 443 d2 = 0.0D; 444 d1 = 0.0D; 445 d0 = 0.0D; 446 } 447 448 double d9; 449 double d10; 450 int k; 451 452 if (this.bs > 0.0F && flag1 && (flag || this.br < 0.05F) && (d5 != d0 || d7 != d2)) { 453 d9 = d0; 454 d10 = d1; 455 double d11 = d2; 456 457 d0 = d5; 458 d1 = (double) this.bs; 459 d2 = d7; 460 AxisAlignedBB axisalignedbb1 = this.boundingBox.clone(); 461 462 this.boundingBox.b(axisalignedbb); 463 list = this.world.getEntities(this, this.boundingBox.a(d5, d1, d7)); 464 465 for (k = 0; k < list.size(); ++k) { 466 d1 = ((AxisAlignedBB) list.get(k)).b(this.boundingBox, d1); 467 } 468 469 this.boundingBox.d(0.0D, d1, 0.0D); 470 if (!this.bg && d6 != d1) { 471 d2 = 0.0D; 472 d1 = 0.0D; 473 d0 = 0.0D; 474 } 475 476 for (k = 0; k < list.size(); ++k) { 477 d0 = ((AxisAlignedBB) list.get(k)).a(this.boundingBox, d0); 478 } 479 480 this.boundingBox.d(d0, 0.0D, 0.0D); 481 if (!this.bg && d5 != d0) { 482 d2 = 0.0D; 483 d1 = 0.0D; 484 d0 = 0.0D; 485 } 486 487 for (k = 0; k < list.size(); ++k) { 488 d2 = ((AxisAlignedBB) list.get(k)).c(this.boundingBox, d2); 489 } 490 491 this.boundingBox.d(0.0D, 0.0D, d2); 492 if (!this.bg && d7 != d2) { 493 d2 = 0.0D; 494 d1 = 0.0D; 495 d0 = 0.0D; 496 } 497 498 if (!this.bg && d6 != d1) { 499 d2 = 0.0D; 500 d1 = 0.0D; 501 d0 = 0.0D; 502 } else { 503 d1 = (double) (-this.bs); 504 505 for (k = 0; k < list.size(); ++k) { 506 d1 = ((AxisAlignedBB) list.get(k)).b(this.boundingBox, d1); 507 } 508 509 this.boundingBox.d(0.0D, d1, 0.0D); 510 } 511 512 if (d9 * d9 + d11 * d11 >= d0 * d0 + d2 * d2) { 513 d0 = d9; 514 d1 = d10; 515 d2 = d11; 516 this.boundingBox.b(axisalignedbb1); 517 } else { 518 double d12 = this.boundingBox.b - (double) ((int) this.boundingBox.b); 519 520 if (d12 > 0.0D) { 521 this.br = (float) ((double) this.br + d12 + 0.01D); 522 } 523 } 524 } 525 526 this.locX = (this.boundingBox.a + this.boundingBox.d) / 2.0D; 527 this.locY = this.boundingBox.b + (double) this.height - (double) this.br; 528 this.locZ = (this.boundingBox.c + this.boundingBox.f) / 2.0D; 529 this.positionChanged = d5 != d0 || d7 != d2; 530 this.bc = d6 != d1; 531 this.onGround = d6 != d1 && d6 < 0.0D; 532 this.bd = this.positionChanged || this.bc; 533 this.a(d1, this.onGround); 534 if (d5 != d0) { 535 this.motX = 0.0D; 536 } 537 538 if (d6 != d1) { 539 this.motY = 0.0D; 540 } 541 542 if (d7 != d2) { 543 this.motZ = 0.0D; 544 } 545 546 d9 = this.locX - d3; 547 d10 = this.locZ - d4; 548 int l; 549 int i1; 550 int j1; 551 552 // CraftBukkit start 553 if ((this.positionChanged) && (this.getBukkitEntity() instanceof Vehicle)) { 554 Vehicle vehicle = (Vehicle) this.getBukkitEntity(); 555 org.bukkit.block.Block block = this.world.getWorld().getBlockAt(MathHelper.floor(this.locX), MathHelper.floor(this.locY - 0.20000000298023224D - (double) this.height), MathHelper.floor(this.locZ)); 556 557 if (d5 > d0) { 558 block = block.getRelative(BlockFace.SOUTH); 559 } else if (d5 < d0) { 560 block = block.getRelative(BlockFace.NORTH); 561 } else if (d7 > d2) { 562 block = block.getRelative(BlockFace.WEST); 563 } else if (d7 < d2) { 564 block = block.getRelative(BlockFace.EAST); 565 } 566 567 VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, block); 568 this.world.getServer().getPluginManager().callEvent(event); 569 } 570 // CraftBukkit end 571 572 if (this.n() && !flag && this.vehicle == null) { 573 this.bm = (float) ((double) this.bm + (double) MathHelper.a(d9 * d9 + d10 * d10) * 0.6D); 574 l = MathHelper.floor(this.locX); 575 i1 = MathHelper.floor(this.locY - 0.20000000298023224D - (double) this.height); 576 j1 = MathHelper.floor(this.locZ); 577 k = this.world.getTypeId(l, i1, j1); 578 // uberbukkit 579 if (!trampleFarmlandAboveFence) { 580 if (this.world.getTypeId(l, i1 - 1, j1) == Block.FENCE.id) { 581 k = this.world.getTypeId(l, i1 - 1, j1); 582 } 583 } 584 585 if (this.bm > (float) this.b && k > 0) { 586 ++this.b; 587 StepSound stepsound = Block.byId[k].stepSound; 588 589 if (this.world.getTypeId(l, i1 + 1, j1) == Block.SNOW.id) { 590 stepsound = Block.SNOW.stepSound; 591 this.world.makeSound(this, stepsound.getName(), stepsound.getVolume1() * 0.15F, stepsound.getVolume2()); 592 } else if (!Block.byId[k].material.isLiquid()) { 593 this.world.makeSound(this, stepsound.getName(), stepsound.getVolume1() * 0.15F, stepsound.getVolume2()); 594 } 595 596 Block.byId[k].b(this.world, l, i1, j1, this); 597 } 598 } 599 600 l = MathHelper.floor(this.boundingBox.a + 0.0010D); 601 i1 = MathHelper.floor(this.boundingBox.b + 0.0010D); 602 j1 = MathHelper.floor(this.boundingBox.c + 0.0010D); 603 k = MathHelper.floor(this.boundingBox.d - 0.0010D); 604 int k1 = MathHelper.floor(this.boundingBox.e - 0.0010D); 605 int l1 = MathHelper.floor(this.boundingBox.f - 0.0010D); 606 607 if (this.world.a(l, i1, j1, k, k1, l1)) { 608 for (int i2 = l; i2 <= k; ++i2) { 609 for (int j2 = i1; j2 <= k1; ++j2) { 610 for (int k2 = j1; k2 <= l1; ++k2) { 611 int l2 = this.world.getTypeId(i2, j2, k2); 612 613 if (l2 > 0) { 614 Block.byId[l2].a(this.world, i2, j2, k2, this); 615 } 616 } 617 } 618 } 619 } 620 621 boolean flag2 = this.ac(); 622 623 if (this.world.d(this.boundingBox.shrink(0.0010D, 0.0010D, 0.0010D))) { 624 this.burn(1); 625 if (!flag2) { 626 ++this.fireTicks; 627 // CraftBukkit start - not on fire yet 628 if (this.fireTicks <= 0) { 629 EntityCombustEvent event = new EntityCombustEvent(this.getBukkitEntity()); 630 this.world.getServer().getPluginManager().callEvent(event); 631 632 if (!event.isCancelled()) { 633 this.fireTicks = 300; 634 } 635 } else { 636 // CraftBukkit end - reset fire level back to max 637 this.fireTicks = 300; 638 } 639 } 640 } else if (this.fireTicks <= 0) { 641 this.fireTicks = -this.maxFireTicks; 642 } 643 644 if (flag2 && this.fireTicks > 0) { 645 this.world.makeSound(this, "random.fizz", 0.7F, 1.6F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); 646 this.fireTicks = -this.maxFireTicks; 647 } 648 } 649 } 650 651 protected boolean n() { 652 return true; 653 } 654 655 protected void a(double d0, boolean flag) { 656 if (flag) { 657 if (this.fallDistance > 0.0F) { 658 this.a(this.fallDistance); 659 this.fallDistance = 0.0F; 660 } 661 } else if (d0 < 0.0D) { 662 this.fallDistance = (float) ((double) this.fallDistance - d0); 663 } 664 } 665 666 public AxisAlignedBB e_() { 667 return null; 668 } 669 670 protected void burn(int i) { 671 if (!this.fireProof) { 672 // CraftBukkit start 673 if (this instanceof EntityLiving) { 674 EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.FIRE, i); 675 this.world.getServer().getPluginManager().callEvent(event); 676 677 if (event.isCancelled()) { 678 return; 679 } 680 681 i = event.getDamage(); 682 } 683 // CraftBukkit end 684 this.damageEntity((Entity) null, i); 685 } 686 } 687 688 protected void a(float f) { 689 if (this.passenger != null) { 690 this.passenger.a(f); 691 } 692 } 693 694 public boolean ac() { 695 return this.bA || this.world.s(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ)); 696 } 697 698 public boolean ad() { 699 return this.bA; 700 } 701 702 public boolean f_() { 703 return this.world.a(this.boundingBox.b(0.0D, -0.4000000059604645D, 0.0D).shrink(0.0010D, 0.0010D, 0.0010D), Material.WATER, this); 704 } 705 706 public boolean a(Material material) { 707 double d0 = this.locY + (double) this.t(); 708 int i = MathHelper.floor(this.locX); 709 int j = MathHelper.d((float) MathHelper.floor(d0)); 710 int k = MathHelper.floor(this.locZ); 711 int l = this.world.getTypeId(i, j, k); 712 713 if (l != 0 && Block.byId[l].material == material) { 714 float f = BlockFluids.c(this.world.getData(i, j, k)) - 0.11111111F; 715 float f1 = (float) (j + 1) - f; 716 717 return d0 < (double) f1; 718 } else { 719 return false; 720 } 721 } 722 723 public float t() { 724 return 0.0F; 725 } 726 727 public boolean ae() { 728 return this.world.a(this.boundingBox.b(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), Material.LAVA); 729 } 730 731 public void a(float f, float f1, float f2) { 732 float f3 = MathHelper.c(f * f + f1 * f1); 733 734 if (f3 >= 0.01F) { 735 if (f3 < 1.0F) { 736 f3 = 1.0F; 737 } 738 739 f3 = f2 / f3; 740 f *= f3; 741 f1 *= f3; 742 float f4 = MathHelper.sin(this.yaw * 3.1415927F / 180.0F); 743 float f5 = MathHelper.cos(this.yaw * 3.1415927F / 180.0F); 744 745 this.motX += (double) (f * f5 - f1 * f4); 746 this.motZ += (double) (f1 * f5 + f * f4); 747 } 748 } 749 750 public float c(float f) { 751 int i = MathHelper.floor(this.locX); 752 double d0 = (this.boundingBox.e - this.boundingBox.b) * 0.66D; 753 int j = MathHelper.floor(this.locY - (double) this.height + d0); 754 int k = MathHelper.floor(this.locZ); 755 756 if (this.world.a(MathHelper.floor(this.boundingBox.a), MathHelper.floor(this.boundingBox.b), MathHelper.floor(this.boundingBox.c), MathHelper.floor(this.boundingBox.d), MathHelper.floor(this.boundingBox.e), MathHelper.floor(this.boundingBox.f))) { 757 float f1 = this.world.n(i, j, k); 758 759 if (f1 < this.bF) { 760 f1 = this.bF; 761 } 762 763 return f1; 764 } else { 765 return this.bF; 766 } 767 } 768 769 public void spawnIn(World world) { 770 // CraftBukkit start 771 if (world == null) { 772 this.die(); 773 this.world = ((org.bukkit.craftbukkit.CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle(); 774 return; 775 } 776 // CraftBukkit end 777 this.world = world; 778 } 779 780 public void setLocation(double d0, double d1, double d2, float f, float f1) { 781 this.lastX = this.locX = d0; 782 this.lastY = this.locY = d1; 783 this.lastZ = this.locZ = d2; 784 this.lastYaw = this.yaw = f; 785 this.lastPitch = this.pitch = f1; 786 this.br = 0.0F; 787 double d3 = (double) (this.lastYaw - f); 788 789 if (d3 < -180.0D) { 790 this.lastYaw += 360.0F; 791 } 792 793 if (d3 >= 180.0D) { 794 this.lastYaw -= 360.0F; 795 } 796 797 this.setPosition(this.locX, this.locY, this.locZ); 798 this.c(f, f1); 799 } 800 801 public void setPositionRotation(double d0, double d1, double d2, float f, float f1) { 802 this.bo = this.lastX = this.locX = d0; 803 this.bp = this.lastY = this.locY = d1 + (double) this.height; 804 this.bq = this.lastZ = this.locZ = d2; 805 this.yaw = f; 806 this.pitch = f1; 807 this.setPosition(this.locX, this.locY, this.locZ); 808 } 809 810 public float f(Entity entity) { 811 float f = (float) (this.locX - entity.locX); 812 float f1 = (float) (this.locY - entity.locY); 813 float f2 = (float) (this.locZ - entity.locZ); 814 815 return MathHelper.c(f * f + f1 * f1 + f2 * f2); 816 } 817 818 public double e(double d0, double d1, double d2) { 819 double d3 = this.locX - d0; 820 double d4 = this.locY - d1; 821 double d5 = this.locZ - d2; 822 823 return d3 * d3 + d4 * d4 + d5 * d5; 824 } 825 826 public double f(double d0, double d1, double d2) { 827 double d3 = this.locX - d0; 828 double d4 = this.locY - d1; 829 double d5 = this.locZ - d2; 830 831 return (double) MathHelper.a(d3 * d3 + d4 * d4 + d5 * d5); 832 } 833 834 public double g(Entity entity) { 835 double d0 = this.locX - entity.locX; 836 double d1 = this.locY - entity.locY; 837 double d2 = this.locZ - entity.locZ; 838 839 return d0 * d0 + d1 * d1 + d2 * d2; 840 } 841 842 public void b(EntityHuman entityhuman) { 843 } 844 845 public void collide(Entity entity) { 846 if (entity.passenger != this && entity.vehicle != this) { 847 double d0 = entity.locX - this.locX; 848 double d1 = entity.locZ - this.locZ; 849 double d2 = MathHelper.a(d0, d1); 850 851 if (d2 >= 0.009999999776482582D) { 852 d2 = (double) MathHelper.a(d2); 853 d0 /= d2; 854 d1 /= d2; 855 double d3 = 1.0D / d2; 856 857 if (d3 > 1.0D) { 858 d3 = 1.0D; 859 } 860 861 d0 *= d3; 862 d1 *= d3; 863 d0 *= 0.05000000074505806D; 864 d1 *= 0.05000000074505806D; 865 d0 *= (double) (1.0F - this.bu); 866 d1 *= (double) (1.0F - this.bu); 867 this.b(-d0, 0.0D, -d1); 868 entity.b(d0, 0.0D, d1); 869 } 870 } 871 } 872 873 public void b(double d0, double d1, double d2) { 874 this.motX += d0; 875 this.motY += d1; 876 this.motZ += d2; 877 this.airBorne = true; 878 } 879 880 protected void af() { 881 this.velocityChanged = true; 882 } 883 884 public boolean damageEntity(Entity entity, int i) { 885 this.af(); 886 return false; 887 } 888 889 public boolean l_() { 890 return false; 891 } 892 893 public boolean d_() { 894 return false; 895 } 896 897 public void c(Entity entity, int i) { 898 } 899 900 public boolean c(NBTTagCompound nbttagcompound) { 901 String s = this.ag(); 902 903 if (!this.dead && s != null) { 904 nbttagcompound.setString("id", s); 905 this.d(nbttagcompound); 906 return true; 907 } else { 908 return false; 909 } 910 } 911 912 public void d(NBTTagCompound nbttagcompound) { 913 nbttagcompound.a("Pos", (NBTBase) this.a(new double[] { this.locX, this.locY + (double) this.br, this.locZ })); 914 nbttagcompound.a("Motion", (NBTBase) this.a(new double[] { this.motX, this.motY, this.motZ })); 915 916 // CraftBukkit start - checking for NaN pitch/yaw and resetting to zero 917 // TODO: make sure this is the best way to address this. 918 if (Float.isNaN(this.yaw)) { 919 this.yaw = 0; 920 } 921 922 if (Float.isNaN(this.pitch)) { 923 this.pitch = 0; 924 } 925 // CraftBukkit end 926 927 nbttagcompound.a("Rotation", (NBTBase) this.a(new float[] { this.yaw, this.pitch })); 928 nbttagcompound.a("FallDistance", this.fallDistance); 929 nbttagcompound.a("Fire", (short) this.fireTicks); 930 nbttagcompound.a("Air", (short) this.airTicks); 931 nbttagcompound.a("OnGround", this.onGround); 932 // CraftBukkit start 933 nbttagcompound.setLong("WorldUUIDLeast", this.world.getUUID().getLeastSignificantBits()); 934 nbttagcompound.setLong("WorldUUIDMost", this.world.getUUID().getMostSignificantBits()); 935 nbttagcompound.setLong("UUIDLeast", this.uniqueId.getLeastSignificantBits()); 936 nbttagcompound.setLong("UUIDMost", this.uniqueId.getMostSignificantBits()); 937 // CraftBukkit end 938 this.b(nbttagcompound); 939 } 940 941 public void e(NBTTagCompound nbttagcompound) { 942 NBTTagList nbttaglist = nbttagcompound.l("Pos"); 943 NBTTagList nbttaglist1 = nbttagcompound.l("Motion"); 944 NBTTagList nbttaglist2 = nbttagcompound.l("Rotation"); 945 946 this.motX = ((NBTTagDouble) nbttaglist1.a(0)).a; 947 this.motY = ((NBTTagDouble) nbttaglist1.a(1)).a; 948 this.motZ = ((NBTTagDouble) nbttaglist1.a(2)).a; 949 /* CraftBukkit start - moved section down 950 if (Math.abs(this.motX) > 10.0D) { 951 this.motX = 0.0D; 952 } 953 954 if (Math.abs(this.motY) > 10.0D) { 955 this.motY = 0.0D; 956 } 957 958 if (Math.abs(this.motZ) > 10.0D) { 959 this.motZ = 0.0D; 960 } 961 // CraftBukkit end */ 962 963 this.lastX = this.bo = this.locX = ((NBTTagDouble) nbttaglist.a(0)).a; 964 this.lastY = this.bp = this.locY = ((NBTTagDouble) nbttaglist.a(1)).a; 965 this.lastZ = this.bq = this.locZ = ((NBTTagDouble) nbttaglist.a(2)).a; 966 this.lastYaw = this.yaw = ((NBTTagFloat) nbttaglist2.a(0)).a; 967 this.lastPitch = this.pitch = ((NBTTagFloat) nbttaglist2.a(1)).a; 968 this.fallDistance = nbttagcompound.g("FallDistance"); 969 this.fireTicks = nbttagcompound.d("Fire"); 970 this.airTicks = nbttagcompound.d("Air"); 971 this.onGround = nbttagcompound.m("OnGround"); 972 this.setPosition(this.locX, this.locY, this.locZ); 973 974 // CraftBukkit start 975 long least = nbttagcompound.getLong("UUIDLeast"); 976 long most = nbttagcompound.getLong("UUIDMost"); 977 978 if (least != 0L && most != 0L) { 979 this.uniqueId = new UUID(most, least); 980 } 981 // CraftBukkit end 982 983 this.c(this.yaw, this.pitch); 984 this.a(nbttagcompound); 985 986 // CraftBukkit start - Exempt Vehicles from notch's sanity check 987 if (!(this.getBukkitEntity() instanceof Vehicle)) { 988 if (Math.abs(this.motX) > 10.0D) { 989 this.motX = 0.0D; 990 } 991 992 if (Math.abs(this.motY) > 10.0D) { 993 this.motY = 0.0D; 994 } 995 996 if (Math.abs(this.motZ) > 10.0D) { 997 this.motZ = 0.0D; 998 } 999 } 1000 // CraftBukkit end 1001 1002 // CraftBukkit start - reset world 1003 if (this instanceof EntityPlayer) { 1004 org.bukkit.Server server = Bukkit.getServer(); 1005 org.bukkit.World bworld = null; 1006 1007 // TODO: Remove World related checks, replaced with WorldUID. 1008 String worldName = nbttagcompound.getString("World"); 1009 1010 if (nbttagcompound.hasKey("WorldUUIDMost") && nbttagcompound.hasKey("WorldUUIDLeast")) { 1011 UUID uid = new UUID(nbttagcompound.getLong("WorldUUIDMost"), nbttagcompound.getLong("WorldUUIDLeast")); 1012 bworld = server.getWorld(uid); 1013 } else { 1014 bworld = server.getWorld(worldName); 1015 } 1016 if (bworld == null) { 1017 EntityPlayer entityPlayer = (EntityPlayer) this; 1018 bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getWorldServer(entityPlayer.dimension).getWorld(); 1019 } 1020 1021 this.spawnIn(bworld == null ? null : ((org.bukkit.craftbukkit.CraftWorld) bworld).getHandle()); 1022 } 1023 // CraftBukkit end 1024 } 1025 1026 protected final String ag() { 1027 return EntityTypes.b(this); 1028 } 1029 1030 protected abstract void a(NBTTagCompound nbttagcompound); 1031 1032 protected abstract void b(NBTTagCompound nbttagcompound); 1033 1034 protected NBTTagList a(double... adouble) { 1035 NBTTagList nbttaglist = new NBTTagList(); 1036 double[] adouble1 = adouble; 1037 int i = adouble.length; 1038 1039 for (int j = 0; j < i; ++j) { 1040 double d0 = adouble1[j]; 1041 1042 nbttaglist.a((NBTBase) (new NBTTagDouble(d0))); 1043 } 1044 1045 return nbttaglist; 1046 } 1047 1048 protected NBTTagList a(float... afloat) { 1049 NBTTagList nbttaglist = new NBTTagList(); 1050 float[] afloat1 = afloat; 1051 int i = afloat.length; 1052 1053 for (int j = 0; j < i; ++j) { 1054 float f = afloat1[j]; 1055 1056 nbttaglist.a((NBTBase) (new NBTTagFloat(f))); 1057 } 1058 1059 return nbttaglist; 1060 } 1061 1062 public EntityItem b(int i, int j) { 1063 return this.a(i, j, 0.0F); 1064 } 1065 1066 public EntityItem a(int i, int j, float f) { 1067 return this.a(new ItemStack(i, j, 0), f); 1068 } 1069 1070 public EntityItem a(ItemStack itemstack, float f) { 1071 EntityItem entityitem = new EntityItem(this.world, this.locX, this.locY + (double) f, this.locZ, itemstack); 1072 1073 entityitem.pickupDelay = 10; 1074 this.world.addEntity(entityitem); 1075 return entityitem; 1076 } 1077 1078 public boolean T() { 1079 return !this.dead; 1080 } 1081 1082 public boolean K() { 1083 for (int i = 0; i < 8; ++i) { 1084 float f = ((float) ((i >> 0) % 2) - 0.5F) * this.length * 0.9F; 1085 float f1 = ((float) ((i >> 1) % 2) - 0.5F) * 0.1F; 1086 float f2 = ((float) ((i >> 2) % 2) - 0.5F) * this.length * 0.9F; 1087 int j = MathHelper.floor(this.locX + (double) f); 1088 int k = MathHelper.floor(this.locY + (double) this.t() + (double) f1); 1089 int l = MathHelper.floor(this.locZ + (double) f2); 1090 1091 if (this.world.e(j, k, l)) { 1092 return true; 1093 } 1094 } 1095 1096 return false; 1097 } 1098 1099 public boolean a(EntityHuman entityhuman) { 1100 return false; 1101 } 1102 1103 public AxisAlignedBB a_(Entity entity) { 1104 return null; 1105 } 1106 1107 public void E() { 1108 if (this.vehicle.dead) { 1109 this.vehicle = null; 1110 } else { 1111 this.motX = 0.0D; 1112 this.motY = 0.0D; 1113 this.motZ = 0.0D; 1114 this.m_(); 1115 if (this.vehicle != null) { 1116 this.vehicle.f(); 1117 this.e += (double) (this.vehicle.yaw - this.vehicle.lastYaw); 1118 1119 for (this.d += (double) (this.vehicle.pitch - this.vehicle.lastPitch); this.e >= 180.0D; this.e -= 360.0D) { 1120 ; 1121 } 1122 1123 while (this.e < -180.0D) { 1124 this.e += 360.0D; 1125 } 1126 1127 while (this.d >= 180.0D) { 1128 this.d -= 360.0D; 1129 } 1130 1131 while (this.d < -180.0D) { 1132 this.d += 360.0D; 1133 } 1134 1135 double d0 = this.e * 0.5D; 1136 double d1 = this.d * 0.5D; 1137 float f = 10.0F; 1138 1139 if (d0 > (double) f) { 1140 d0 = (double) f; 1141 } 1142 1143 if (d0 < (double) (-f)) { 1144 d0 = (double) (-f); 1145 } 1146 1147 if (d1 > (double) f) { 1148 d1 = (double) f; 1149 } 1150 1151 if (d1 < (double) (-f)) { 1152 d1 = (double) (-f); 1153 } 1154 1155 this.e -= d0; 1156 this.d -= d1; 1157 this.yaw = (float) ((double) this.yaw + d0); 1158 this.pitch = (float) ((double) this.pitch + d1); 1159 } 1160 } 1161 } 1162 1163 public void f() { 1164 this.passenger.setPosition(this.locX, this.locY + this.m() + this.passenger.I(), this.locZ); 1165 } 1166 1167 public double I() { 1168 return (double) this.height; 1169 } 1170 1171 public double m() { 1172 return (double) this.width * 0.75D; 1173 } 1174 1175 public void mount(Entity entity) { 1176 // CraftBukkit start 1177 this.setPassengerOf(entity); 1178 } 1179 1180 protected org.bukkit.entity.Entity bukkitEntity; 1181 1182 public org.bukkit.entity.Entity getBukkitEntity() { 1183 if (this.bukkitEntity == null) { 1184 this.bukkitEntity = org.bukkit.craftbukkit.entity.CraftEntity.getEntity(this.world.getServer(), this); 1185 } 1186 return this.bukkitEntity; 1187 } 1188 1189 public void setPassengerOf(Entity entity) { 1190 // b(null) doesn't really fly for overloaded methods, 1191 // so this method is needed 1192 1193 // CraftBukkit end 1194 this.d = 0.0D; 1195 this.e = 0.0D; 1196 if (entity == null) { 1197 if (this.vehicle != null) { 1198 // CraftBukkit start 1199 if ((this.getBukkitEntity() instanceof LivingEntity) && (this.vehicle.getBukkitEntity() instanceof Vehicle)) { 1200 VehicleExitEvent event = new VehicleExitEvent((Vehicle) this.vehicle.getBukkitEntity(), (LivingEntity) this.getBukkitEntity()); 1201 this.world.getServer().getPluginManager().callEvent(event); 1202 } 1203 // CraftBukkit end 1204 1205 this.setPositionRotation(this.vehicle.locX, this.vehicle.boundingBox.b + (double) this.vehicle.width, this.vehicle.locZ, this.yaw, this.pitch); 1206 this.vehicle.passenger = null; 1207 } 1208 1209 this.vehicle = null; 1210 } else if (this.vehicle == entity) { 1211 // CraftBukkit start 1212 if ((this.getBukkitEntity() instanceof LivingEntity) && (this.vehicle.getBukkitEntity() instanceof Vehicle)) { 1213 VehicleExitEvent event = new VehicleExitEvent((Vehicle) this.vehicle.getBukkitEntity(), (LivingEntity) this.getBukkitEntity()); 1214 this.world.getServer().getPluginManager().callEvent(event); 1215 } 1216 // CraftBukkit end 1217 1218 this.vehicle.passenger = null; 1219 this.vehicle = null; 1220 this.setPositionRotation(entity.locX, entity.boundingBox.b + (double) entity.width, entity.locZ, this.yaw, this.pitch); 1221 } else { 1222 if (this.vehicle != null) { 1223 this.vehicle.passenger = null; 1224 } 1225 1226 if (entity.passenger != null) { 1227 entity.passenger.vehicle = null; 1228 } 1229 1230 this.vehicle = entity; 1231 entity.passenger = this; 1232 } 1233 } 1234 1235 public Vec3D Z() { 1236 return null; 1237 } 1238 1239 public void P() { 1240 } 1241 1242 public ItemStack[] getEquipment() { 1243 return null; 1244 } 1245 1246 public boolean isSneaking() { 1247 return this.d(1); 1248 } 1249 1250 public void setSneak(boolean flag) { 1251 this.a(1, flag); 1252 } 1253 1254 protected boolean d(int i) { 1255 return (this.datawatcher.a(0) & 1 << i) != 0; 1256 } 1257 1258 protected void a(int i, boolean flag) { 1259 byte b0 = this.datawatcher.a(0); 1260 1261 if (flag) { 1262 this.datawatcher.watch(0, Byte.valueOf((byte) (b0 | 1 << i))); 1263 } else { 1264 this.datawatcher.watch(0, Byte.valueOf((byte) (b0 & ~(1 << i)))); 1265 } 1266 } 1267 1268 public void a(EntityWeatherStorm entityweatherstorm) { 1269 // CraftBukkit start 1270 EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(entityweatherstorm.getBukkitEntity(), this.getBukkitEntity(), EntityDamageEvent.DamageCause.LIGHTNING, 5); 1271 Bukkit.getServer().getPluginManager().callEvent(event); 1272 1273 if (event.isCancelled()) { 1274 return; 1275 } 1276 1277 this.burn(event.getDamage()); 1278 // CraftBukkit end 1279 1280 ++this.fireTicks; 1281 if (this.fireTicks == 0) { 1282 this.fireTicks = 300; 1283 } 1284 } 1285 1286 public void a(EntityLiving entityliving) { 1287 } 1288 1289 protected boolean g(double d0, double d1, double d2) { 1290 int i = MathHelper.floor(d0); 1291 int j = MathHelper.floor(d1); 1292 int k = MathHelper.floor(d2); 1293 double d3 = d0 - (double) i; 1294 double d4 = d1 - (double) j; 1295 double d5 = d2 - (double) k; 1296 1297 if (this.world.e(i, j, k)) { 1298 boolean flag = !this.world.e(i - 1, j, k); 1299 boolean flag1 = !this.world.e(i + 1, j, k); 1300 boolean flag2 = !this.world.e(i, j - 1, k); 1301 boolean flag3 = !this.world.e(i, j + 1, k); 1302 boolean flag4 = !this.world.e(i, j, k - 1); 1303 boolean flag5 = !this.world.e(i, j, k + 1); 1304 byte b0 = -1; 1305 double d6 = 9999.0D; 1306 1307 if (flag && d3 < d6) { 1308 d6 = d3; 1309 b0 = 0; 1310 } 1311 1312 if (flag1 && 1.0D - d3 < d6) { 1313 d6 = 1.0D - d3; 1314 b0 = 1; 1315 } 1316 1317 if (flag2 && d4 < d6) { 1318 d6 = d4; 1319 b0 = 2; 1320 } 1321 1322 if (flag3 && 1.0D - d4 < d6) { 1323 d6 = 1.0D - d4; 1324 b0 = 3; 1325 } 1326 1327 if (flag4 && d5 < d6) { 1328 d6 = d5; 1329 b0 = 4; 1330 } 1331 1332 if (flag5 && 1.0D - d5 < d6) { 1333 d6 = 1.0D - d5; 1334 b0 = 5; 1335 } 1336 1337 float f = this.random.nextFloat() * 0.2F + 0.1F; 1338 1339 if (b0 == 0) { 1340 this.motX = (double) (-f); 1341 } 1342 1343 if (b0 == 1) { 1344 this.motX = (double) f; 1345 } 1346 1347 if (b0 == 2) { 1348 this.motY = (double) (-f); 1349 } 1350 1351 if (b0 == 3) { 1352 this.motY = (double) f; 1353 } 1354 1355 if (b0 == 4) { 1356 this.motZ = (double) (-f); 1357 } 1358 1359 if (b0 == 5) { 1360 this.motZ = (double) f; 1361 } 1362 } 1363 1364 return false; 1365 } 1366}