Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
at develop 2505 lines 80 kB view raw
1package net.minecraft.server; 2 3import java.util.ArrayList; 4import java.util.Collection; 5import java.util.HashMap; 6import java.util.HashSet; 7import java.util.Iterator; 8import java.util.List; 9import java.util.Map; 10import java.util.Random; 11import java.util.Set; 12import java.util.TreeSet; 13import java.util.UUID; 14 15import org.bukkit.Bukkit; 16import org.bukkit.Location; 17import org.bukkit.block.BlockState; 18import org.bukkit.craftbukkit.CraftServer; 19import org.bukkit.craftbukkit.CraftWorld; 20import org.bukkit.craftbukkit.event.CraftEventFactory; 21import org.bukkit.event.block.BlockBreakEvent; 22import org.bukkit.event.block.BlockCanBuildEvent; 23import org.bukkit.event.block.BlockFormEvent; 24import org.bukkit.event.block.BlockPhysicsEvent; 25import org.bukkit.event.entity.CreatureSpawnEvent; 26import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; 27import org.bukkit.event.entity.EntityDamageEvent; 28import org.bukkit.event.entity.ItemSpawnEvent; 29import org.bukkit.event.weather.ThunderChangeEvent; 30import org.bukkit.event.weather.WeatherChangeEvent; 31import org.bukkit.generator.ChunkGenerator; 32 33import uk.betacraft.uberbukkit.Uberbukkit; 34import uk.betacraft.uberbukkit.UberbukkitConfig; 35 36// CraftBukkit start 37// CraftBukkit end 38 39public class World implements IBlockAccess { 40 41 // uberbukkit 42 private static final boolean pre1_5_placement_rules = UberbukkitConfig.getInstance().getBoolean("mechanics.pre_b1_5_block_placement_rules", false); 43 44 public boolean a = false; 45 private List C = new ArrayList(); 46 public List entityList = new ArrayList(); 47 private List D = new ArrayList(); 48 private TreeSet E = new TreeSet(); 49 private Set F = new HashSet(); 50 public List c = new ArrayList(); 51 private List G = new ArrayList(); 52 public List players = new ArrayList(); 53 public List e = new ArrayList(); 54 private long H = 16777215L; 55 public int f = 0; 56 protected int g = (new Random()).nextInt(); 57 protected final int h = 1013904223; 58 protected float i; 59 protected float j; 60 protected float k; 61 protected float l; 62 protected int m = 0; 63 public int n = 0; 64 public boolean suppressPhysics = false; 65 private long I = System.currentTimeMillis(); 66 protected int p = 40; 67 public int spawnMonsters; 68 public Random random = new Random(); 69 public boolean s = false; 70 public WorldProvider worldProvider; // CraftBukkit - remove final 71 protected List u = new ArrayList(); 72 public IChunkProvider chunkProvider; // CraftBukkit - protected -> public 73 protected final IDataManager w; 74 public WorldData worldData; // CraftBukkit - protected -> public 75 public boolean isLoading; 76 private boolean J; 77 public WorldMapCollection worldMaps; 78 private ArrayList K = new ArrayList(); 79 private boolean L; 80 private int M = 0; 81 public boolean allowMonsters = true; // CraftBukkit - private -> public 82 public boolean allowAnimals = true; // CraftBukkit - private -> public 83 static int A = 0; 84 private Set P = new HashSet(); 85 private int Q; 86 private List R; 87 public boolean isStatic; 88 public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions 89 90 public WorldChunkManager getWorldChunkManager() { 91 return this.worldProvider.b; 92 } 93 94 // CraftBukkit start 95 private final CraftWorld world; 96 public boolean pvpMode; 97 public boolean keepSpawnInMemory = true; 98 public ChunkGenerator generator; 99 Chunk lastChunkAccessed; 100 int lastXAccessed = Integer.MIN_VALUE; 101 int lastZAccessed = Integer.MIN_VALUE; 102 final Object chunkLock = new Object(); 103 private List<TileEntity> tileEntitiesToUnload; 104 105 private boolean canSpawn(int x, int z) { 106 if (this.generator != null) { 107 return this.generator.canSpawn(this.getWorld(), x, z); 108 } else { 109 return this.worldProvider.canSpawn(x, z); 110 } 111 } 112 113 public CraftWorld getWorld() { 114 return this.world; 115 } 116 117 public CraftServer getServer() { 118 return (CraftServer) Bukkit.getServer(); 119 } 120 121 public void markForRemoval(TileEntity tileentity) { 122 tileEntitiesToUnload.add(tileentity); 123 } 124 125 // CraftBukkit - changed signature 126 public World(IDataManager idatamanager, String s, long i, WorldProvider worldprovider, ChunkGenerator gen, org.bukkit.World.Environment env) { 127 this.generator = gen; 128 this.world = new CraftWorld((WorldServer) this, gen, env); 129 tileEntitiesToUnload = new ArrayList<TileEntity>(); 130 // CraftBukkit end 131 132 this.Q = this.random.nextInt(12000); 133 this.R = new ArrayList(); 134 this.isStatic = false; 135 this.w = idatamanager; 136 this.worldMaps = new WorldMapCollection(idatamanager); 137 this.worldData = idatamanager.c(); 138 this.s = this.worldData == null; 139 if (worldprovider != null) { 140 this.worldProvider = worldprovider; 141 } else if (this.worldData != null && this.worldData.h() == -1) { 142 this.worldProvider = WorldProvider.byDimension(-1); 143 } else { 144 this.worldProvider = WorldProvider.byDimension(0); 145 } 146 147 boolean flag = false; 148 149 if (this.worldData == null) { 150 this.worldData = new WorldData(i, s); 151 flag = true; 152 } else { 153 this.worldData.a(s); 154 } 155 156 this.worldProvider.a(this); 157 this.chunkProvider = this.b(); 158 if (flag) { 159 this.c(); 160 } 161 162 this.g(); 163 this.x(); 164 165 this.getServer().addWorld(this.world); // CraftBukkit 166 } 167 168 protected IChunkProvider b() { 169 IChunkLoader ichunkloader = this.w.a(this.worldProvider); 170 171 return new ChunkProviderLoadOrGenerate(this, ichunkloader, this.worldProvider.getChunkProvider()); 172 } 173 174 protected void c() { 175 this.isLoading = true; 176 int i = 0; 177 byte b0 = 64; 178 179 int j; 180 181 // CraftBukkit start 182 if (this.generator != null) { 183 Random rand = new Random(this.getSeed()); 184 Location spawn = this.generator.getFixedSpawnLocation(((WorldServer) this).getWorld(), rand); 185 186 if (spawn != null) { 187 if (spawn.getWorld() != ((WorldServer) this).getWorld()) { 188 throw new IllegalStateException("Cannot set spawn point for " + this.worldData.name + " to be in another world (" + spawn.getWorld().getName() + ")"); 189 } else { 190 this.worldData.setSpawn(spawn.getBlockX(), spawn.getBlockY(), spawn.getBlockZ()); 191 this.isLoading = false; 192 return; 193 } 194 } 195 } 196 197 for (j = 0; !this.canSpawn(i, j); j += this.random.nextInt(64) - this.random.nextInt(64)) { 198 i += this.random.nextInt(64) - this.random.nextInt(64); 199 } 200 // CraftBukkit end 201 202 this.worldData.setSpawn(i, b0, j); 203 this.isLoading = false; 204 } 205 206 public int a(int i, int j) { 207 int k; 208 209 for (k = 63; !this.isEmpty(i, k + 1, j); ++k) { 210 ; 211 } 212 213 return this.getTypeId(i, k, j); 214 } 215 216 public void save(boolean flag, IProgressUpdate iprogressupdate) { 217 if (this.chunkProvider.canSave()) { 218 if (iprogressupdate != null) { 219 iprogressupdate.a("Saving level"); 220 } 221 222 this.w(); 223 if (iprogressupdate != null) { 224 iprogressupdate.b("Saving chunks"); 225 } 226 227 this.chunkProvider.saveChunks(flag, iprogressupdate); 228 } 229 } 230 231 private void w() { 232 this.k(); 233 this.w.a(this.worldData, this.players); 234 this.worldMaps.a(); 235 } 236 237 public int getTypeId(int i, int j, int k) { 238 return i >= -32000000 && k >= -32000000 && i < 32000000 && k <= 32000000 ? (j < 0 ? 0 : (j >= 128 ? 0 : this.getChunkAt(i >> 4, k >> 4).getTypeId(i & 15, j, k & 15))) : 0; 239 } 240 241 public boolean isEmpty(int i, int j, int k) { 242 return this.getTypeId(i, j, k) == 0; 243 } 244 245 public boolean isLoaded(int i, int j, int k) { 246 return j >= 0 && j < 128 ? this.isChunkLoaded(i >> 4, k >> 4) : false; 247 } 248 249 public boolean areChunksLoaded(int i, int j, int k, int l) { 250 return this.a(i - l, j - l, k - l, i + l, j + l, k + l); 251 } 252 253 public boolean a(int i, int j, int k, int l, int i1, int j1) { 254 if (i1 >= 0 && j < 128) { 255 i >>= 4; 256 j >>= 4; 257 k >>= 4; 258 l >>= 4; 259 i1 >>= 4; 260 j1 >>= 4; 261 262 for (int k1 = i; k1 <= l; ++k1) { 263 for (int l1 = k; l1 <= j1; ++l1) { 264 if (!this.isChunkLoaded(k1, l1)) { 265 return false; 266 } 267 } 268 } 269 270 return true; 271 } else { 272 return false; 273 } 274 } 275 276 private boolean isChunkLoaded(int i, int j) { 277 return this.chunkProvider.isChunkLoaded(i, j); 278 } 279 280 public Chunk getChunkAtWorldCoords(int i, int j) { 281 return this.getChunkAt(i >> 4, j >> 4); 282 } 283 284 // CraftBukkit start 285 public Chunk getChunkAt(int i, int j) { 286 Chunk result = null; 287 synchronized (this.chunkLock) { 288 if (this.lastChunkAccessed == null || this.lastXAccessed != i || this.lastZAccessed != j) { 289 this.lastXAccessed = i; 290 this.lastZAccessed = j; 291 this.lastChunkAccessed = this.chunkProvider.getOrCreateChunk(i, j); 292 } 293 result = this.lastChunkAccessed; 294 } 295 return result; 296 } 297 // CraftBukkit end 298 299 public boolean setRawTypeIdAndData(int i, int j, int k, int l, int i1) { 300 // uberbukkit 301 if (!Uberbukkit.getProtocolHandler().canReceiveBlockItem(l)) { 302 return false; 303 } 304 305 if (i >= -32000000 && k >= -32000000 && i < 32000000 && k <= 32000000) { 306 if (j < 0) { 307 return false; 308 } else if (j >= 128) { 309 return false; 310 } else { 311 Chunk chunk = this.getChunkAt(i >> 4, k >> 4); 312 313 return chunk.a(i & 15, j, k & 15, l, i1); 314 } 315 } else { 316 return false; 317 } 318 } 319 320 public boolean setRawTypeId(int i, int j, int k, int l) { 321 // uberbukkit 322 if (!Uberbukkit.getProtocolHandler().canReceiveBlockItem(l)) { 323 return false; 324 } 325 326 if (i >= -32000000 && k >= -32000000 && i < 32000000 && k <= 32000000) { 327 if (j < 0) { 328 return false; 329 } else if (j >= 128) { 330 return false; 331 } else { 332 Chunk chunk = this.getChunkAt(i >> 4, k >> 4); 333 334 return chunk.a(i & 15, j, k & 15, l); 335 } 336 } else { 337 return false; 338 } 339 } 340 341 public Material getMaterial(int i, int j, int k) { 342 int l = this.getTypeId(i, j, k); 343 344 return l == 0 ? Material.AIR : Block.byId[l].material; 345 } 346 347 public int getData(int i, int j, int k) { 348 if (i >= -32000000 && k >= -32000000 && i < 32000000 && k <= 32000000) { 349 if (j < 0) { 350 return 0; 351 } else if (j >= 128) { 352 return 0; 353 } else { 354 Chunk chunk = this.getChunkAt(i >> 4, k >> 4); 355 356 i &= 15; 357 k &= 15; 358 return chunk.getData(i, j, k); 359 } 360 } else { 361 return 0; 362 } 363 } 364 365 public void setData(int i, int j, int k, int l) { 366 if (this.setRawData(i, j, k, l)) { 367 int i1 = this.getTypeId(i, j, k); 368 369 if (Block.t[i1 & 255]) { 370 this.update(i, j, k, i1); 371 } else { 372 this.applyPhysics(i, j, k, i1); 373 } 374 } 375 } 376 377 public boolean setRawData(int i, int j, int k, int l) { 378 if (i >= -32000000 && k >= -32000000 && i < 32000000 && k <= 32000000) { 379 if (j < 0) { 380 return false; 381 } else if (j >= 128) { 382 return false; 383 } else { 384 Chunk chunk = this.getChunkAt(i >> 4, k >> 4); 385 386 i &= 15; 387 k &= 15; 388 chunk.b(i, j, k, l); 389 return true; 390 } 391 } else { 392 return false; 393 } 394 } 395 396 public boolean setTypeId(int i, int j, int k, int l) { 397 // CraftBukkit start 398 int old = this.getTypeId(i, j, k); 399 if (this.setRawTypeId(i, j, k, l)) { 400 this.update(i, j, k, l == 0 ? old : l); 401 return true; 402 } else { 403 return false; 404 } 405 // CraftBukkit end 406 } 407 408 public boolean setTypeIdAndData(int i, int j, int k, int l, int i1) { 409 // CraftBukkit start 410 int old = this.getTypeId(i, j, k); 411 if (this.setRawTypeIdAndData(i, j, k, l, i1)) { 412 this.update(i, j, k, l == 0 ? old : l); 413 return true; 414 } else { 415 return false; 416 } 417 // CraftBukkit end 418 } 419 420 public void notify(int i, int j, int k) { 421 for (int l = 0; l < this.u.size(); ++l) { 422 ((IWorldAccess) this.u.get(l)).a(i, j, k); 423 } 424 } 425 426 protected void update(int i, int j, int k, int l) { 427 this.notify(i, j, k); 428 this.applyPhysics(i, j, k, l); 429 } 430 431 public void g(int i, int j, int k, int l) { 432 if (k > l) { 433 int i1 = l; 434 435 l = k; 436 k = i1; 437 } 438 439 this.b(i, k, j, i, l, j); 440 } 441 442 public void i(int i, int j, int k) { 443 for (int l = 0; l < this.u.size(); ++l) { 444 ((IWorldAccess) this.u.get(l)).a(i, j, k, i, j, k); 445 } 446 } 447 448 public void b(int i, int j, int k, int l, int i1, int j1) { 449 for (int k1 = 0; k1 < this.u.size(); ++k1) { 450 ((IWorldAccess) this.u.get(k1)).a(i, j, k, l, i1, j1); 451 } 452 } 453 454 public void applyPhysics(int i, int j, int k, int l) { 455 this.k(i - 1, j, k, l); 456 this.k(i + 1, j, k, l); 457 this.k(i, j - 1, k, l); 458 this.k(i, j + 1, k, l); 459 this.k(i, j, k - 1, l); 460 this.k(i, j, k + 1, l); 461 } 462 463 private void k(int i, int j, int k, int l) { 464 if (!this.suppressPhysics && !this.isStatic) { 465 Block block = Block.byId[this.getTypeId(i, j, k)]; 466 467 if (block != null) { 468 // CraftBukkit start 469 CraftWorld world = ((WorldServer) this).getWorld(); 470 if (world != null) { 471 BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(i, j, k), l); 472 this.getServer().getPluginManager().callEvent(event); 473 474 if (event.isCancelled()) { 475 return; 476 } 477 } 478 // CraftBukkit end 479 480 block.doPhysics(this, i, j, k, l); 481 } 482 } 483 } 484 485 public boolean isChunkLoaded(int i, int j, int k) { 486 return this.getChunkAt(i >> 4, k >> 4).c(i & 15, j, k & 15); 487 } 488 489 public int k(int i, int j, int k) { 490 if (j < 0) { 491 return 0; 492 } else { 493 if (j >= 128) { 494 j = 127; 495 } 496 497 return this.getChunkAt(i >> 4, k >> 4).c(i & 15, j, k & 15, 0); 498 } 499 } 500 501 public int getLightLevel(int i, int j, int k) { 502 return this.a(i, j, k, true); 503 } 504 505 public int a(int i, int j, int k, boolean flag) { 506 if (i >= -32000000 && k >= -32000000 && i < 32000000 && k <= 32000000) { 507 if (flag) { 508 int l = this.getTypeId(i, j, k); 509 510 boolean check = false; 511 if (Uberbukkit.getTargetPVN() >= 12) { 512 check = l == Block.COBBLESTONE_STAIRS.id || l == Block.WOOD_STAIRS.id; 513 } 514 515 if (l == Block.STEP.id || l == Block.SOIL.id || check) { 516 int i1 = this.a(i, j + 1, k, false); 517 int j1 = this.a(i + 1, j, k, false); 518 int k1 = this.a(i - 1, j, k, false); 519 int l1 = this.a(i, j, k + 1, false); 520 int i2 = this.a(i, j, k - 1, false); 521 522 if (j1 > i1) { 523 i1 = j1; 524 } 525 526 if (k1 > i1) { 527 i1 = k1; 528 } 529 530 if (l1 > i1) { 531 i1 = l1; 532 } 533 534 if (i2 > i1) { 535 i1 = i2; 536 } 537 538 return i1; 539 } 540 } 541 542 if (j < 0) { 543 return 0; 544 } else { 545 if (j >= 128) { 546 j = 127; 547 } 548 549 Chunk chunk = this.getChunkAt(i >> 4, k >> 4); 550 551 i &= 15; 552 k &= 15; 553 return chunk.c(i, j, k, this.f); 554 } 555 } else { 556 return 15; 557 } 558 } 559 560 public boolean m(int i, int j, int k) { 561 if (i >= -32000000 && k >= -32000000 && i < 32000000 && k <= 32000000) { 562 if (j < 0) { 563 return false; 564 } else if (j >= 128) { 565 return true; 566 } else if (!this.isChunkLoaded(i >> 4, k >> 4)) { 567 return false; 568 } else { 569 Chunk chunk = this.getChunkAt(i >> 4, k >> 4); 570 571 i &= 15; 572 k &= 15; 573 return chunk.c(i, j, k); 574 } 575 } else { 576 return false; 577 } 578 } 579 580 public int getHighestBlockYAt(int i, int j) { 581 if (i >= -32000000 && j >= -32000000 && i < 32000000 && j <= 32000000) { 582 if (!this.isChunkLoaded(i >> 4, j >> 4)) { 583 return 0; 584 } else { 585 Chunk chunk = this.getChunkAt(i >> 4, j >> 4); 586 587 return chunk.b(i & 15, j & 15); 588 } 589 } else { 590 return 0; 591 } 592 } 593 594 public void a(EnumSkyBlock enumskyblock, int i, int j, int k, int l) { 595 if (!this.worldProvider.e || enumskyblock != EnumSkyBlock.SKY) { 596 if (this.isLoaded(i, j, k)) { 597 if (enumskyblock == EnumSkyBlock.SKY) { 598 if (this.m(i, j, k)) { 599 l = 15; 600 } 601 } else if (enumskyblock == EnumSkyBlock.BLOCK) { 602 int i1 = this.getTypeId(i, j, k); 603 604 if (Block.s[i1] > l) { 605 l = Block.s[i1]; 606 } 607 } 608 609 if (this.a(enumskyblock, i, j, k) != l) { 610 this.a(enumskyblock, i, j, k, i, j, k); 611 } 612 } 613 } 614 } 615 616 public int a(EnumSkyBlock enumskyblock, int i, int j, int k) { 617 if (j < 0) { 618 j = 0; 619 } 620 621 if (j >= 128) { 622 j = 127; 623 } 624 625 if (j >= 0 && j < 128 && i >= -32000000 && k >= -32000000 && i < 32000000 && k <= 32000000) { 626 int l = i >> 4; 627 int i1 = k >> 4; 628 629 if (!this.isChunkLoaded(l, i1)) { 630 return 0; 631 } else { 632 Chunk chunk = this.getChunkAt(l, i1); 633 634 return chunk.a(enumskyblock, i & 15, j, k & 15); 635 } 636 } else { 637 return enumskyblock.c; 638 } 639 } 640 641 public void b(EnumSkyBlock enumskyblock, int i, int j, int k, int l) { 642 if (i >= -32000000 && k >= -32000000 && i < 32000000 && k <= 32000000) { 643 if (j >= 0) { 644 if (j < 128) { 645 if (this.isChunkLoaded(i >> 4, k >> 4)) { 646 Chunk chunk = this.getChunkAt(i >> 4, k >> 4); 647 648 chunk.a(enumskyblock, i & 15, j, k & 15, l); 649 650 for (int i1 = 0; i1 < this.u.size(); ++i1) { 651 ((IWorldAccess) this.u.get(i1)).a(i, j, k); 652 } 653 } 654 } 655 } 656 } 657 } 658 659 public float n(int i, int j, int k) { 660 return this.worldProvider.f[this.getLightLevel(i, j, k)]; 661 } 662 663 public boolean d() { 664 return this.f < 4; 665 } 666 667 public MovingObjectPosition a(Vec3D vec3d, Vec3D vec3d1) { 668 return this.rayTrace(vec3d, vec3d1, false, false); 669 } 670 671 public MovingObjectPosition rayTrace(Vec3D vec3d, Vec3D vec3d1, boolean flag) { 672 return this.rayTrace(vec3d, vec3d1, flag, false); 673 } 674 675 public MovingObjectPosition rayTrace(Vec3D vec3d, Vec3D vec3d1, boolean flag, boolean flag1) { 676 if (!Double.isNaN(vec3d.a) && !Double.isNaN(vec3d.b) && !Double.isNaN(vec3d.c)) { 677 if (!Double.isNaN(vec3d1.a) && !Double.isNaN(vec3d1.b) && !Double.isNaN(vec3d1.c)) { 678 int i = MathHelper.floor(vec3d1.a); 679 int j = MathHelper.floor(vec3d1.b); 680 int k = MathHelper.floor(vec3d1.c); 681 int l = MathHelper.floor(vec3d.a); 682 int i1 = MathHelper.floor(vec3d.b); 683 int j1 = MathHelper.floor(vec3d.c); 684 int k1 = this.getTypeId(l, i1, j1); 685 int l1 = this.getData(l, i1, j1); 686 Block block = Block.byId[k1]; 687 688 if ((!flag1 || block == null || block.e(this, l, i1, j1) != null) && k1 > 0 && block.a(l1, flag)) { 689 MovingObjectPosition movingobjectposition = block.a(this, l, i1, j1, vec3d, vec3d1); 690 691 if (movingobjectposition != null) { 692 return movingobjectposition; 693 } 694 } 695 696 k1 = 200; 697 698 while (k1-- >= 0) { 699 if (Double.isNaN(vec3d.a) || Double.isNaN(vec3d.b) || Double.isNaN(vec3d.c)) { 700 return null; 701 } 702 703 if (l == i && i1 == j && j1 == k) { 704 return null; 705 } 706 707 boolean flag2 = true; 708 boolean flag3 = true; 709 boolean flag4 = true; 710 double d0 = 999.0D; 711 double d1 = 999.0D; 712 double d2 = 999.0D; 713 714 if (i > l) { 715 d0 = (double) l + 1.0D; 716 } else if (i < l) { 717 d0 = (double) l + 0.0D; 718 } else { 719 flag2 = false; 720 } 721 722 if (j > i1) { 723 d1 = (double) i1 + 1.0D; 724 } else if (j < i1) { 725 d1 = (double) i1 + 0.0D; 726 } else { 727 flag3 = false; 728 } 729 730 if (k > j1) { 731 d2 = (double) j1 + 1.0D; 732 } else if (k < j1) { 733 d2 = (double) j1 + 0.0D; 734 } else { 735 flag4 = false; 736 } 737 738 double d3 = 999.0D; 739 double d4 = 999.0D; 740 double d5 = 999.0D; 741 double d6 = vec3d1.a - vec3d.a; 742 double d7 = vec3d1.b - vec3d.b; 743 double d8 = vec3d1.c - vec3d.c; 744 745 if (flag2) { 746 d3 = (d0 - vec3d.a) / d6; 747 } 748 749 if (flag3) { 750 d4 = (d1 - vec3d.b) / d7; 751 } 752 753 if (flag4) { 754 d5 = (d2 - vec3d.c) / d8; 755 } 756 757 boolean flag5 = false; 758 byte b0; 759 760 if (d3 < d4 && d3 < d5) { 761 if (i > l) { 762 b0 = 4; 763 } else { 764 b0 = 5; 765 } 766 767 vec3d.a = d0; 768 vec3d.b += d7 * d3; 769 vec3d.c += d8 * d3; 770 } else if (d4 < d5) { 771 if (j > i1) { 772 b0 = 0; 773 } else { 774 b0 = 1; 775 } 776 777 vec3d.a += d6 * d4; 778 vec3d.b = d1; 779 vec3d.c += d8 * d4; 780 } else { 781 if (k > j1) { 782 b0 = 2; 783 } else { 784 b0 = 3; 785 } 786 787 vec3d.a += d6 * d5; 788 vec3d.b += d7 * d5; 789 vec3d.c = d2; 790 } 791 792 Vec3D vec3d2 = Vec3D.create(vec3d.a, vec3d.b, vec3d.c); 793 794 l = (int) (vec3d2.a = (double) MathHelper.floor(vec3d.a)); 795 if (b0 == 5) { 796 --l; 797 ++vec3d2.a; 798 } 799 800 i1 = (int) (vec3d2.b = (double) MathHelper.floor(vec3d.b)); 801 if (b0 == 1) { 802 --i1; 803 ++vec3d2.b; 804 } 805 806 j1 = (int) (vec3d2.c = (double) MathHelper.floor(vec3d.c)); 807 if (b0 == 3) { 808 --j1; 809 ++vec3d2.c; 810 } 811 812 int i2 = this.getTypeId(l, i1, j1); 813 int j2 = this.getData(l, i1, j1); 814 Block block1 = Block.byId[i2]; 815 816 if ((!flag1 || block1 == null || block1.e(this, l, i1, j1) != null) && i2 > 0 && block1.a(j2, flag)) { 817 MovingObjectPosition movingobjectposition1 = block1.a(this, l, i1, j1, vec3d, vec3d1); 818 819 if (movingobjectposition1 != null) { 820 return movingobjectposition1; 821 } 822 } 823 } 824 825 return null; 826 } else { 827 return null; 828 } 829 } else { 830 return null; 831 } 832 } 833 834 public void makeSound(Entity entity, String s, float f, float f1) { 835 for (int i = 0; i < this.u.size(); ++i) { 836 ((IWorldAccess) this.u.get(i)).a(s, entity.locX, entity.locY - (double) entity.height, entity.locZ, f, f1); 837 } 838 } 839 840 public void makeSound(double d0, double d1, double d2, String s, float f, float f1) { 841 for (int i = 0; i < this.u.size(); ++i) { 842 ((IWorldAccess) this.u.get(i)).a(s, d0, d1, d2, f, f1); 843 } 844 } 845 846 public void a(String s, int i, int j, int k) { 847 for (int l = 0; l < this.u.size(); ++l) { 848 ((IWorldAccess) this.u.get(l)).a(s, i, j, k); 849 } 850 } 851 852 public void a(String s, double d0, double d1, double d2, double d3, double d4, double d5) { 853 for (int i = 0; i < this.u.size(); ++i) { 854 ((IWorldAccess) this.u.get(i)).a(s, d0, d1, d2, d3, d4, d5); 855 } 856 } 857 858 public boolean strikeLightning(Entity entity) { 859 this.e.add(entity); 860 return true; 861 } 862 863 // CraftBukkit start - used for entities other than creatures 864 public boolean addEntity(Entity entity) { 865 return this.addEntity(entity, SpawnReason.CUSTOM); // Set reason as Custom by default 866 } 867 868 869 public boolean addEntity(Entity entity, SpawnReason spawnReason) { // Changed signature, added SpawnReason 870 // CraftBukkit end 871 int i = MathHelper.floor(entity.locX / 16.0D); 872 int j = MathHelper.floor(entity.locZ / 16.0D); 873 boolean flag = false; 874 875 if (entity instanceof EntityHuman) { 876 flag = true; 877 } 878 879 // CraftBukkit start 880 if (entity instanceof EntityLiving && !(entity instanceof EntityPlayer)) { 881 CreatureSpawnEvent event = CraftEventFactory.callCreatureSpawnEvent((EntityLiving) entity, spawnReason); 882 883 if (event.isCancelled()) { 884 return false; 885 } 886 } else if (entity instanceof EntityItem) { 887 ItemSpawnEvent event = CraftEventFactory.callItemSpawnEvent((EntityItem) entity); 888 if (event.isCancelled()) { 889 return false; 890 } 891 } 892 // CraftBukkit end 893 894 if (!flag && !this.isChunkLoaded(i, j)) { 895 return false; 896 } else { 897 if (entity instanceof EntityHuman) { 898 EntityHuman entityhuman = (EntityHuman) entity; 899 900 this.players.add(entityhuman); 901 this.everyoneSleeping(); 902 } 903 904 this.getChunkAt(i, j).a(entity); 905 this.entityList.add(entity); 906 this.c(entity); 907 return true; 908 } 909 } 910 911 protected void c(Entity entity) { 912 for (int i = 0; i < this.u.size(); ++i) { 913 ((IWorldAccess) this.u.get(i)).a(entity); 914 } 915 } 916 917 protected void d(Entity entity) { 918 for (int i = 0; i < this.u.size(); ++i) { 919 ((IWorldAccess) this.u.get(i)).b(entity); 920 } 921 } 922 923 public void kill(Entity entity) { 924 if (entity.passenger != null) { 925 entity.passenger.mount((Entity) null); 926 } 927 928 if (entity.vehicle != null) { 929 entity.mount((Entity) null); 930 } 931 932 entity.die(); 933 if (entity instanceof EntityHuman) { 934 this.players.remove((EntityHuman) entity); 935 this.everyoneSleeping(); 936 } 937 } 938 939 public void removeEntity(Entity entity) { 940 entity.die(); 941 if (entity instanceof EntityHuman) { 942 this.players.remove((EntityHuman) entity); 943 this.everyoneSleeping(); 944 } 945 946 int i = entity.bH; 947 int j = entity.bJ; 948 949 if (entity.bG && this.isChunkLoaded(i, j)) { 950 this.getChunkAt(i, j).b(entity); 951 } 952 953 this.entityList.remove(entity); 954 this.d(entity); 955 } 956 957 public void addIWorldAccess(IWorldAccess iworldaccess) { 958 this.u.add(iworldaccess); 959 } 960 961 public List getEntities(Entity entity, AxisAlignedBB axisalignedbb) { 962 this.K.clear(); 963 int i = MathHelper.floor(axisalignedbb.a); 964 int j = MathHelper.floor(axisalignedbb.d + 1.0D); 965 int k = MathHelper.floor(axisalignedbb.b); 966 int l = MathHelper.floor(axisalignedbb.e + 1.0D); 967 int i1 = MathHelper.floor(axisalignedbb.c); 968 int j1 = MathHelper.floor(axisalignedbb.f + 1.0D); 969 970 for (int k1 = i; k1 < j; ++k1) { 971 for (int l1 = i1; l1 < j1; ++l1) { 972 if (this.isLoaded(k1, 64, l1)) { 973 for (int i2 = k - 1; i2 < l; ++i2) { 974 Block block = Block.byId[this.getTypeId(k1, i2, l1)]; 975 976 if (block != null) { 977 block.a(this, k1, i2, l1, axisalignedbb, this.K); 978 } 979 } 980 } 981 } 982 } 983 984 double d0 = 0.25D; 985 List list = this.b(entity, axisalignedbb.b(d0, d0, d0)); 986 987 for (int j2 = 0; j2 < list.size(); ++j2) { 988 AxisAlignedBB axisalignedbb1 = ((Entity) list.get(j2)).e_(); 989 990 if (axisalignedbb1 != null && axisalignedbb1.a(axisalignedbb)) { 991 this.K.add(axisalignedbb1); 992 } 993 994 axisalignedbb1 = entity.a_((Entity) list.get(j2)); 995 if (axisalignedbb1 != null && axisalignedbb1.a(axisalignedbb)) { 996 this.K.add(axisalignedbb1); 997 } 998 } 999 1000 return this.K; 1001 } 1002 1003 public int a(float f) { 1004 float f1 = this.b(f); 1005 float f2 = 1.0F - (MathHelper.cos(f1 * 3.1415927F * 2.0F) * 2.0F + 0.5F); 1006 1007 if (f2 < 0.0F) { 1008 f2 = 0.0F; 1009 } 1010 1011 if (f2 > 1.0F) { 1012 f2 = 1.0F; 1013 } 1014 1015 f2 = 1.0F - f2; 1016 f2 = (float) ((double) f2 * (1.0D - (double) (this.d(f) * 5.0F) / 16.0D)); 1017 f2 = (float) ((double) f2 * (1.0D - (double) (this.c(f) * 5.0F) / 16.0D)); 1018 f2 = 1.0F - f2; 1019 return (int) (f2 * 11.0F); 1020 } 1021 1022 public float b(float f) { 1023 return this.worldProvider.a(this.worldData.f(), f); 1024 } 1025 1026 public int e(int i, int j) { 1027 Chunk chunk = this.getChunkAtWorldCoords(i, j); 1028 int k = 127; 1029 1030 i &= 15; 1031 1032 for (j &= 15; k > 0; --k) { 1033 int l = chunk.getTypeId(i, k, j); 1034 Material material = l == 0 ? Material.AIR : Block.byId[l].material; 1035 1036 if (material.isSolid() || material.isLiquid()) { 1037 return k + 1; 1038 } 1039 } 1040 1041 return -1; 1042 } 1043 1044 public int f(int i, int j) { 1045 Chunk chunk = this.getChunkAtWorldCoords(i, j); 1046 int k = 127; 1047 1048 i &= 15; 1049 1050 for (j &= 15; k > 0; --k) { 1051 int l = chunk.getTypeId(i, k, j); 1052 1053 if (l != 0 && Block.byId[l].material.isSolid()) { 1054 return k + 1; 1055 } 1056 } 1057 1058 return -1; 1059 } 1060 1061 public void c(int i, int j, int k, int l, int i1) { 1062 NextTickListEntry nextticklistentry = new NextTickListEntry(i, j, k, l); 1063 byte b0 = 8; 1064 1065 if (this.a) { 1066 if (this.a(nextticklistentry.a - b0, nextticklistentry.b - b0, nextticklistentry.c - b0, nextticklistentry.a + b0, nextticklistentry.b + b0, nextticklistentry.c + b0)) { 1067 int j1 = this.getTypeId(nextticklistentry.a, nextticklistentry.b, nextticklistentry.c); 1068 1069 if (j1 == nextticklistentry.d && j1 > 0) { 1070 Block.byId[j1].a(this, nextticklistentry.a, nextticklistentry.b, nextticklistentry.c, this.random); 1071 } 1072 } 1073 } else { 1074 if (this.a(i - b0, j - b0, k - b0, i + b0, j + b0, k + b0)) { 1075 if (l > 0) { 1076 nextticklistentry.a((long) i1 + this.worldData.f()); 1077 } 1078 1079 if (!this.F.contains(nextticklistentry)) { 1080 this.F.add(nextticklistentry); 1081 this.E.add(nextticklistentry); 1082 } 1083 } 1084 } 1085 } 1086 1087 public void cleanUp() { 1088 int i; 1089 Entity entity; 1090 1091 for (i = 0; i < this.e.size(); ++i) { 1092 entity = (Entity) this.e.get(i); 1093 // CraftBukkit start - fixed an NPE 1094 if (entity == null) { 1095 continue; 1096 } 1097 // CraftBukkit end 1098 entity.m_(); 1099 if (entity.dead) { 1100 this.e.remove(i--); 1101 } 1102 } 1103 1104 this.entityList.removeAll(this.D); 1105 1106 int j; 1107 int k; 1108 1109 for (i = 0; i < this.D.size(); ++i) { 1110 entity = (Entity) this.D.get(i); 1111 j = entity.bH; 1112 k = entity.bJ; 1113 if (entity.bG && this.isChunkLoaded(j, k)) { 1114 this.getChunkAt(j, k).b(entity); 1115 } 1116 } 1117 1118 for (i = 0; i < this.D.size(); ++i) { 1119 this.d((Entity) this.D.get(i)); 1120 } 1121 1122 this.D.clear(); 1123 1124 for (i = 0; i < this.entityList.size(); ++i) { 1125 entity = (Entity) this.entityList.get(i); 1126 if (entity.vehicle != null) { 1127 if (!entity.vehicle.dead && entity.vehicle.passenger == entity) { 1128 continue; 1129 } 1130 1131 entity.vehicle.passenger = null; 1132 entity.vehicle = null; 1133 } 1134 1135 if (!entity.dead) { 1136 this.playerJoinedWorld(entity); 1137 } 1138 1139 if (entity.dead) { 1140 j = entity.bH; 1141 k = entity.bJ; 1142 if (entity.bG && this.isChunkLoaded(j, k)) { 1143 this.getChunkAt(j, k).b(entity); 1144 } 1145 1146 this.entityList.remove(i--); 1147 this.d(entity); 1148 } 1149 } 1150 1151 this.L = true; 1152 Iterator iterator = this.c.iterator(); 1153 1154 while (iterator.hasNext()) { 1155 TileEntity tileentity = (TileEntity) iterator.next(); 1156 1157 if (!tileentity.g()) { 1158 tileentity.g_(); 1159 } 1160 1161 if (tileentity.g()) { 1162 iterator.remove(); 1163 Chunk chunk = this.getChunkAt(tileentity.x >> 4, tileentity.z >> 4); 1164 1165 if (chunk != null) { 1166 chunk.e(tileentity.x & 15, tileentity.y, tileentity.z & 15); 1167 } 1168 } 1169 } 1170 1171 this.L = false; 1172 1173 // Craftbukkit start 1174 if (!tileEntitiesToUnload.isEmpty()) { 1175 this.c.removeAll(tileEntitiesToUnload); 1176 this.tileEntitiesToUnload.clear(); 1177 } 1178 // Craftbukkit end 1179 1180 if (!this.G.isEmpty()) { 1181 Iterator iterator1 = this.G.iterator(); 1182 1183 while (iterator1.hasNext()) { 1184 TileEntity tileentity1 = (TileEntity) iterator1.next(); 1185 1186 if (!tileentity1.g()) { 1187 // CraftBukkit - order matters, moved down 1188 /* if (!this.c.contains(tileentity1)) { 1189 this.c.add(tileentity1); 1190 } */ 1191 1192 Chunk chunk1 = this.getChunkAt(tileentity1.x >> 4, tileentity1.z >> 4); 1193 1194 if (chunk1 != null) { 1195 chunk1.placeTileEntity(tileentity1.x & 15, tileentity1.y, tileentity1.z & 15, tileentity1); 1196 // CraftBukkit start - moved in from above 1197 if (!this.c.contains(tileentity1)) { 1198 this.c.add(tileentity1); 1199 } 1200 // CraftBukkit end 1201 } 1202 1203 this.notify(tileentity1.x, tileentity1.y, tileentity1.z); 1204 } 1205 } 1206 1207 this.G.clear(); 1208 } 1209 } 1210 1211 public void a(Collection collection) { 1212 if (this.L) { 1213 this.G.addAll(collection); 1214 } else { 1215 this.c.addAll(collection); 1216 } 1217 } 1218 1219 public void playerJoinedWorld(Entity entity) { 1220 this.entityJoinedWorld(entity, true); 1221 } 1222 1223 public void entityJoinedWorld(Entity entity, boolean flag) { 1224 int i = MathHelper.floor(entity.locX); 1225 int j = MathHelper.floor(entity.locZ); 1226 byte b0 = 32; 1227 1228 if (!flag || this.a(i - b0, 0, j - b0, i + b0, 128, j + b0)) { 1229 entity.bo = entity.locX; 1230 entity.bp = entity.locY; 1231 entity.bq = entity.locZ; 1232 entity.lastYaw = entity.yaw; 1233 entity.lastPitch = entity.pitch; 1234 if (flag && entity.bG) { 1235 if (entity.vehicle != null) { 1236 entity.E(); 1237 } else { 1238 entity.m_(); 1239 } 1240 } 1241 1242 if (Double.isNaN(entity.locX) || Double.isInfinite(entity.locX)) { 1243 entity.locX = entity.bo; 1244 } 1245 1246 if (Double.isNaN(entity.locY) || Double.isInfinite(entity.locY)) { 1247 entity.locY = entity.bp; 1248 } 1249 1250 if (Double.isNaN(entity.locZ) || Double.isInfinite(entity.locZ)) { 1251 entity.locZ = entity.bq; 1252 } 1253 1254 if (Double.isNaN((double) entity.pitch) || Double.isInfinite((double) entity.pitch)) { 1255 entity.pitch = entity.lastPitch; 1256 } 1257 1258 if (Double.isNaN((double) entity.yaw) || Double.isInfinite((double) entity.yaw)) { 1259 entity.yaw = entity.lastYaw; 1260 } 1261 1262 int k = MathHelper.floor(entity.locX / 16.0D); 1263 int l = MathHelper.floor(entity.locY / 16.0D); 1264 int i1 = MathHelper.floor(entity.locZ / 16.0D); 1265 1266 if (!entity.bG || entity.bH != k || entity.bI != l || entity.bJ != i1) { 1267 if (entity.bG && this.isChunkLoaded(entity.bH, entity.bJ)) { 1268 this.getChunkAt(entity.bH, entity.bJ).a(entity, entity.bI); 1269 } 1270 1271 if (this.isChunkLoaded(k, i1)) { 1272 entity.bG = true; 1273 this.getChunkAt(k, i1).a(entity); 1274 } else { 1275 entity.bG = false; 1276 } 1277 } 1278 1279 if (flag && entity.bG && entity.passenger != null) { 1280 if (!entity.passenger.dead && entity.passenger.vehicle == entity) { 1281 this.playerJoinedWorld(entity.passenger); 1282 } else { 1283 entity.passenger.vehicle = null; 1284 entity.passenger = null; 1285 } 1286 } 1287 } 1288 } 1289 1290 public boolean containsEntity(AxisAlignedBB axisalignedbb) { 1291 List list = this.b((Entity) null, axisalignedbb); 1292 1293 for (int i = 0; i < list.size(); ++i) { 1294 Entity entity = (Entity) list.get(i); 1295 1296 if (!entity.dead && entity.aI) { 1297 return false; 1298 } 1299 } 1300 1301 return true; 1302 } 1303 1304 public boolean b(AxisAlignedBB axisalignedbb) { 1305 int i = MathHelper.floor(axisalignedbb.a); 1306 int j = MathHelper.floor(axisalignedbb.d + 1.0D); 1307 int k = MathHelper.floor(axisalignedbb.b); 1308 int l = MathHelper.floor(axisalignedbb.e + 1.0D); 1309 int i1 = MathHelper.floor(axisalignedbb.c); 1310 int j1 = MathHelper.floor(axisalignedbb.f + 1.0D); 1311 1312 if (axisalignedbb.a < 0.0D) { 1313 --i; 1314 } 1315 1316 if (axisalignedbb.b < 0.0D) { 1317 --k; 1318 } 1319 1320 if (axisalignedbb.c < 0.0D) { 1321 --i1; 1322 } 1323 1324 for (int k1 = i; k1 < j; ++k1) { 1325 for (int l1 = k; l1 < l; ++l1) { 1326 for (int i2 = i1; i2 < j1; ++i2) { 1327 Block block = Block.byId[this.getTypeId(k1, l1, i2)]; 1328 1329 if (block != null) { 1330 return true; 1331 } 1332 } 1333 } 1334 } 1335 1336 return false; 1337 } 1338 1339 public boolean c(AxisAlignedBB axisalignedbb) { 1340 int i = MathHelper.floor(axisalignedbb.a); 1341 int j = MathHelper.floor(axisalignedbb.d + 1.0D); 1342 int k = MathHelper.floor(axisalignedbb.b); 1343 int l = MathHelper.floor(axisalignedbb.e + 1.0D); 1344 int i1 = MathHelper.floor(axisalignedbb.c); 1345 int j1 = MathHelper.floor(axisalignedbb.f + 1.0D); 1346 1347 if (axisalignedbb.a < 0.0D) { 1348 --i; 1349 } 1350 1351 if (axisalignedbb.b < 0.0D) { 1352 --k; 1353 } 1354 1355 if (axisalignedbb.c < 0.0D) { 1356 --i1; 1357 } 1358 1359 for (int k1 = i; k1 < j; ++k1) { 1360 for (int l1 = k; l1 < l; ++l1) { 1361 for (int i2 = i1; i2 < j1; ++i2) { 1362 Block block = Block.byId[this.getTypeId(k1, l1, i2)]; 1363 1364 if (block != null && block.material.isLiquid()) { 1365 return true; 1366 } 1367 } 1368 } 1369 } 1370 1371 return false; 1372 } 1373 1374 public boolean d(AxisAlignedBB axisalignedbb) { 1375 int i = MathHelper.floor(axisalignedbb.a); 1376 int j = MathHelper.floor(axisalignedbb.d + 1.0D); 1377 int k = MathHelper.floor(axisalignedbb.b); 1378 int l = MathHelper.floor(axisalignedbb.e + 1.0D); 1379 int i1 = MathHelper.floor(axisalignedbb.c); 1380 int j1 = MathHelper.floor(axisalignedbb.f + 1.0D); 1381 1382 if (this.a(i, k, i1, j, l, j1)) { 1383 for (int k1 = i; k1 < j; ++k1) { 1384 for (int l1 = k; l1 < l; ++l1) { 1385 for (int i2 = i1; i2 < j1; ++i2) { 1386 int j2 = this.getTypeId(k1, l1, i2); 1387 1388 if (j2 == Block.FIRE.id || j2 == Block.LAVA.id || j2 == Block.STATIONARY_LAVA.id) { 1389 return true; 1390 } 1391 } 1392 } 1393 } 1394 } 1395 1396 return false; 1397 } 1398 1399 public boolean a(AxisAlignedBB axisalignedbb, Material material, Entity entity) { 1400 int i = MathHelper.floor(axisalignedbb.a); 1401 int j = MathHelper.floor(axisalignedbb.d + 1.0D); 1402 int k = MathHelper.floor(axisalignedbb.b); 1403 int l = MathHelper.floor(axisalignedbb.e + 1.0D); 1404 int i1 = MathHelper.floor(axisalignedbb.c); 1405 int j1 = MathHelper.floor(axisalignedbb.f + 1.0D); 1406 1407 if (!this.a(i, k, i1, j, l, j1)) { 1408 return false; 1409 } else { 1410 boolean flag = false; 1411 Vec3D vec3d = Vec3D.create(0.0D, 0.0D, 0.0D); 1412 1413 for (int k1 = i; k1 < j; ++k1) { 1414 for (int l1 = k; l1 < l; ++l1) { 1415 for (int i2 = i1; i2 < j1; ++i2) { 1416 Block block = Block.byId[this.getTypeId(k1, l1, i2)]; 1417 1418 if (block != null && block.material == material) { 1419 double d0 = (double) ((float) (l1 + 1) - BlockFluids.c(this.getData(k1, l1, i2))); 1420 1421 if ((double) l >= d0) { 1422 flag = true; 1423 block.a(this, k1, l1, i2, entity, vec3d); 1424 } 1425 } 1426 } 1427 } 1428 } 1429 1430 if (vec3d.c() > 0.0D) { 1431 vec3d = vec3d.b(); 1432 double d1 = 0.014D; 1433 1434 entity.motX += vec3d.a * d1; 1435 entity.motY += vec3d.b * d1; 1436 entity.motZ += vec3d.c * d1; 1437 } 1438 1439 return flag; 1440 } 1441 } 1442 1443 public boolean a(AxisAlignedBB axisalignedbb, Material material) { 1444 int i = MathHelper.floor(axisalignedbb.a); 1445 int j = MathHelper.floor(axisalignedbb.d + 1.0D); 1446 int k = MathHelper.floor(axisalignedbb.b); 1447 int l = MathHelper.floor(axisalignedbb.e + 1.0D); 1448 int i1 = MathHelper.floor(axisalignedbb.c); 1449 int j1 = MathHelper.floor(axisalignedbb.f + 1.0D); 1450 1451 for (int k1 = i; k1 < j; ++k1) { 1452 for (int l1 = k; l1 < l; ++l1) { 1453 for (int i2 = i1; i2 < j1; ++i2) { 1454 Block block = Block.byId[this.getTypeId(k1, l1, i2)]; 1455 1456 if (block != null && block.material == material) { 1457 return true; 1458 } 1459 } 1460 } 1461 } 1462 1463 return false; 1464 } 1465 1466 public boolean b(AxisAlignedBB axisalignedbb, Material material) { 1467 int i = MathHelper.floor(axisalignedbb.a); 1468 int j = MathHelper.floor(axisalignedbb.d + 1.0D); 1469 int k = MathHelper.floor(axisalignedbb.b); 1470 int l = MathHelper.floor(axisalignedbb.e + 1.0D); 1471 int i1 = MathHelper.floor(axisalignedbb.c); 1472 int j1 = MathHelper.floor(axisalignedbb.f + 1.0D); 1473 1474 for (int k1 = i; k1 < j; ++k1) { 1475 for (int l1 = k; l1 < l; ++l1) { 1476 for (int i2 = i1; i2 < j1; ++i2) { 1477 Block block = Block.byId[this.getTypeId(k1, l1, i2)]; 1478 1479 if (block != null && block.material == material) { 1480 int j2 = this.getData(k1, l1, i2); 1481 double d0 = (double) (l1 + 1); 1482 1483 if (j2 < 8) { 1484 d0 = (double) (l1 + 1) - (double) j2 / 8.0D; 1485 } 1486 1487 if (d0 >= axisalignedbb.b) { 1488 return true; 1489 } 1490 } 1491 } 1492 } 1493 } 1494 1495 return false; 1496 } 1497 1498 public Explosion a(Entity entity, double d0, double d1, double d2, float f) { 1499 return this.createExplosion(entity, d0, d1, d2, f, false); 1500 } 1501 1502 //Project Poseidon Start 1503 public Explosion createExplosion(Entity entity, double d0, double d1, double d2, float f, boolean flag, EntityDamageEvent.DamageCause customDamageCause) { 1504 Explosion explosion = new Explosion(this, entity, d0, d1, d2, f); 1505 explosion.customDamageCause = customDamageCause; 1506 1507 explosion.setFire = flag; 1508 explosion.a(); 1509 explosion.a(true); 1510 return explosion; 1511 } 1512 //Project Poseidon End 1513 1514 public Explosion createExplosion(Entity entity, double d0, double d1, double d2, float f, boolean flag) { 1515 Explosion explosion = new Explosion(this, entity, d0, d1, d2, f); 1516 1517 explosion.setFire = flag; 1518 explosion.a(); 1519 explosion.a(true); 1520 return explosion; 1521 } 1522 1523 public float a(Vec3D vec3d, AxisAlignedBB axisalignedbb) { 1524 double d0 = 1.0D / ((axisalignedbb.d - axisalignedbb.a) * 2.0D + 1.0D); 1525 double d1 = 1.0D / ((axisalignedbb.e - axisalignedbb.b) * 2.0D + 1.0D); 1526 double d2 = 1.0D / ((axisalignedbb.f - axisalignedbb.c) * 2.0D + 1.0D); 1527 int i = 0; 1528 int j = 0; 1529 1530 for (float f = 0.0F; f <= 1.0F; f = (float) ((double) f + d0)) { 1531 for (float f1 = 0.0F; f1 <= 1.0F; f1 = (float) ((double) f1 + d1)) { 1532 for (float f2 = 0.0F; f2 <= 1.0F; f2 = (float) ((double) f2 + d2)) { 1533 double d3 = axisalignedbb.a + (axisalignedbb.d - axisalignedbb.a) * (double) f; 1534 double d4 = axisalignedbb.b + (axisalignedbb.e - axisalignedbb.b) * (double) f1; 1535 double d5 = axisalignedbb.c + (axisalignedbb.f - axisalignedbb.c) * (double) f2; 1536 1537 if (this.a(Vec3D.create(d3, d4, d5), vec3d) == null) { 1538 ++i; 1539 } 1540 1541 ++j; 1542 } 1543 } 1544 } 1545 1546 return (float) i / (float) j; 1547 } 1548 1549 public void douseFire(EntityHuman entityhuman, int i, int j, int k, int l) { 1550 if (l == 0) { 1551 --j; 1552 } 1553 1554 if (l == 1) { 1555 ++j; 1556 } 1557 1558 if (l == 2) { 1559 --k; 1560 } 1561 1562 if (l == 3) { 1563 ++k; 1564 } 1565 1566 if (l == 4) { 1567 --i; 1568 } 1569 1570 if (l == 5) { 1571 ++i; 1572 } 1573 1574 if (this.getTypeId(i, j, k) == Block.FIRE.id) { 1575 if (entityhuman != null) { 1576 BlockBreakEvent event = CraftEventFactory.callBlockBreakEvent(entityhuman, i, j, k); 1577 if (event.isCancelled()) return; 1578 } 1579 this.a(entityhuman, 1004, i, j, k, 0); 1580 this.setTypeId(i, j, k, 0); 1581 } 1582 } 1583 1584 public TileEntity getTileEntity(int i, int j, int k) { 1585 Chunk chunk = this.getChunkAt(i >> 4, k >> 4); 1586 1587 return chunk != null ? chunk.d(i & 15, j, k & 15) : null; 1588 } 1589 1590 public void setTileEntity(int i, int j, int k, TileEntity tileentity) { 1591 if (!tileentity.g()) { 1592 if (this.L) { 1593 tileentity.x = i; 1594 tileentity.y = j; 1595 tileentity.z = k; 1596 this.G.add(tileentity); 1597 } else { 1598 // CraftBukkit - order matters, moved down 1599 // this.c.add(tileentity); 1600 Chunk chunk = this.getChunkAt(i >> 4, k >> 4); 1601 1602 if (chunk != null) { 1603 chunk.placeTileEntity(i & 15, j, k & 15, tileentity); 1604 this.c.add(tileentity); // CraftBukkit - moved in from above 1605 } 1606 } 1607 } 1608 } 1609 1610 public void o(int i, int j, int k) { 1611 TileEntity tileentity = this.getTileEntity(i, j, k); 1612 1613 if (tileentity != null && this.L) { 1614 tileentity.h(); 1615 } else { 1616 if (tileentity != null) { 1617 this.c.remove(tileentity); 1618 } 1619 1620 Chunk chunk = this.getChunkAt(i >> 4, k >> 4); 1621 1622 if (chunk != null) { 1623 chunk.e(i & 15, j, k & 15); 1624 } 1625 } 1626 } 1627 1628 public boolean p(int i, int j, int k) { 1629 Block block = Block.byId[this.getTypeId(i, j, k)]; 1630 1631 return block == null ? false : block.a(); 1632 } 1633 1634 public boolean e(int i, int j, int k) { 1635 if (UberbukkitConfig.getInstance().getBoolean("mechanics.pre_b1_6_block_opacity", false)) { 1636 return this.p(i, j, k); 1637 } 1638 Block block = Block.byId[this.getTypeId(i, j, k)]; 1639 1640 return block == null ? false : block.material.h() && block.b(); 1641 } 1642 1643 public boolean doLighting() { 1644 if (this.M >= 50) { 1645 return false; 1646 } else { 1647 ++this.M; 1648 1649 boolean flag; 1650 1651 try { 1652 int i = 500; 1653 1654 while (this.C.size() > 0) { 1655 --i; 1656 if (i <= 0) { 1657 flag = true; 1658 return flag; 1659 } 1660 1661 ((MetadataChunkBlock) this.C.remove(this.C.size() - 1)).a(this); 1662 } 1663 1664 flag = false; 1665 } finally { 1666 --this.M; 1667 } 1668 1669 return flag; 1670 } 1671 } 1672 1673 public void a(EnumSkyBlock enumskyblock, int i, int j, int k, int l, int i1, int j1) { 1674 this.a(enumskyblock, i, j, k, l, i1, j1, true); 1675 } 1676 1677 public void a(EnumSkyBlock enumskyblock, int i, int j, int k, int l, int i1, int j1, boolean flag) { 1678 if (!this.worldProvider.e || enumskyblock != EnumSkyBlock.SKY) { 1679 ++A; 1680 1681 try { 1682 if (A == 50) { 1683 return; 1684 } 1685 1686 int k1 = (l + i) / 2; 1687 int l1 = (j1 + k) / 2; 1688 1689 if (this.isLoaded(k1, 64, l1)) { 1690 if (this.getChunkAtWorldCoords(k1, l1).isEmpty()) { 1691 return; 1692 } 1693 1694 int i2 = this.C.size(); 1695 int j2; 1696 1697 if (flag) { 1698 j2 = 5; 1699 if (j2 > i2) { 1700 j2 = i2; 1701 } 1702 1703 for (int k2 = 0; k2 < j2; ++k2) { 1704 MetadataChunkBlock metadatachunkblock = (MetadataChunkBlock) this.C.get(this.C.size() - k2 - 1); 1705 1706 if (metadatachunkblock.a == enumskyblock && metadatachunkblock.a(i, j, k, l, i1, j1)) { 1707 return; 1708 } 1709 } 1710 } 1711 1712 this.C.add(new MetadataChunkBlock(enumskyblock, i, j, k, l, i1, j1)); 1713 j2 = 1000000; 1714 if (this.C.size() > 1000000) { 1715 System.out.println("More than " + j2 + " updates, aborting lighting updates"); 1716 this.C.clear(); 1717 } 1718 1719 return; 1720 } 1721 } finally { 1722 --A; 1723 } 1724 } 1725 } 1726 1727 public void g() { 1728 int i = this.a(1.0F); 1729 1730 if (i != this.f) { 1731 this.f = i; 1732 } 1733 } 1734 1735 public void setSpawnFlags(boolean flag, boolean flag1) { 1736 this.allowMonsters = flag; 1737 this.allowAnimals = flag1; 1738 } 1739 1740 public void doTick() { 1741 this.i(); 1742 long i; 1743 1744 if (this.everyoneDeeplySleeping()) { 1745 boolean flag = false; 1746 1747 if (this.allowMonsters && this.spawnMonsters >= 1) { 1748 flag = SpawnerCreature.a(this, this.players); 1749 } 1750 1751 if (!flag) { 1752 i = this.worldData.f() + 24000L; 1753 this.worldData.a(i - i % 24000L); 1754 this.s(); 1755 } 1756 } 1757 1758 // CraftBukkit start - Only call spawner if we have players online and the world allows for mobs or animals 1759 if ((this.allowMonsters || this.allowAnimals) && (this instanceof WorldServer && this.getServer().getHandle().players.size() > 0)) { 1760 SpawnerCreature.spawnEntities(this, this.allowMonsters, this.allowAnimals); 1761 } 1762 // CraftBukkit end 1763 1764 this.chunkProvider.unloadChunks(); 1765 int j = this.a(1.0F); 1766 1767 if (j != this.f) { 1768 this.f = j; 1769 1770 for (int k = 0; k < this.u.size(); ++k) { 1771 ((IWorldAccess) this.u.get(k)).a(); 1772 } 1773 } 1774 1775 i = this.worldData.f() + 1L; 1776 if (i % (long) this.p == 0L) { 1777 this.save(false, (IProgressUpdate) null); 1778 } 1779 1780 // uberbukkit 1781 if (this.worldProvider instanceof WorldProviderHell && Uberbukkit.getTargetPVN() < 12) { 1782 this.worldData.a(18000); 1783 } else { 1784 this.worldData.a(i); 1785 } 1786 1787 this.a(false); 1788 this.j(); 1789 } 1790 1791 private void x() { 1792 if (this.worldData.hasStorm()) { 1793 this.j = 1.0F; 1794 if (this.worldData.isThundering()) { 1795 this.l = 1.0F; 1796 } 1797 } 1798 } 1799 1800 protected void i() { 1801 if (!this.worldProvider.e) { 1802 if (this.m > 0) { 1803 --this.m; 1804 } 1805 1806 int i = this.worldData.getThunderDuration(); 1807 1808 if (i <= 0) { 1809 if (this.worldData.isThundering()) { 1810 this.worldData.setThunderDuration(this.random.nextInt(12000) + 3600); 1811 } else { 1812 this.worldData.setThunderDuration(this.random.nextInt(168000) + 12000); 1813 } 1814 } else { 1815 --i; 1816 this.worldData.setThunderDuration(i); 1817 if (i <= 0) { 1818 // CraftBukkit start 1819 ThunderChangeEvent thunder = new ThunderChangeEvent(this.getWorld(), !this.worldData.isThundering()); 1820 this.getServer().getPluginManager().callEvent(thunder); 1821 if (!thunder.isCancelled()) { 1822 this.worldData.setThundering(!this.worldData.isThundering()); 1823 } 1824 // CraftBukkit end 1825 } 1826 } 1827 1828 int j = this.worldData.getWeatherDuration(); 1829 1830 if (j <= 0) { 1831 if (this.worldData.hasStorm()) { 1832 this.worldData.setWeatherDuration(this.random.nextInt(12000) + 12000); 1833 } else { 1834 this.worldData.setWeatherDuration(this.random.nextInt(168000) + 12000); 1835 } 1836 } else { 1837 --j; 1838 this.worldData.setWeatherDuration(j); 1839 if (j <= 0) { 1840 // CraftBukkit start 1841 WeatherChangeEvent weather = new WeatherChangeEvent(this.getWorld(), !this.worldData.hasStorm()); 1842 this.getServer().getPluginManager().callEvent(weather); 1843 1844 if (!weather.isCancelled()) { 1845 this.worldData.setStorm(!this.worldData.hasStorm()); 1846 } 1847 // CraftBukkit end 1848 } 1849 } 1850 1851 this.i = this.j; 1852 if (this.worldData.hasStorm()) { 1853 this.j = (float) ((double) this.j + 0.01D); 1854 } else { 1855 this.j = (float) ((double) this.j - 0.01D); 1856 } 1857 1858 if (this.j < 0.0F) { 1859 this.j = 0.0F; 1860 } 1861 1862 if (this.j > 1.0F) { 1863 this.j = 1.0F; 1864 } 1865 1866 this.k = this.l; 1867 if (this.worldData.isThundering()) { 1868 this.l = (float) ((double) this.l + 0.01D); 1869 } else { 1870 this.l = (float) ((double) this.l - 0.01D); 1871 } 1872 1873 if (this.l < 0.0F) { 1874 this.l = 0.0F; 1875 } 1876 1877 if (this.l > 1.0F) { 1878 this.l = 1.0F; 1879 } 1880 } 1881 } 1882 1883 private void y() { 1884 // CraftBukkit start 1885 WeatherChangeEvent weather = new WeatherChangeEvent(this.getWorld(), false); 1886 this.getServer().getPluginManager().callEvent(weather); 1887 1888 ThunderChangeEvent thunder = new ThunderChangeEvent(this.getWorld(), false); 1889 this.getServer().getPluginManager().callEvent(thunder); 1890 if (!weather.isCancelled()) { 1891 this.worldData.setWeatherDuration(0); 1892 this.worldData.setStorm(false); 1893 } 1894 if (!thunder.isCancelled()) { 1895 this.worldData.setThunderDuration(0); 1896 this.worldData.setThundering(false); 1897 } 1898 // CraftBukkit end 1899 } 1900 1901 protected void j() { 1902 this.P.clear(); 1903 1904 int i; 1905 int j; 1906 int k; 1907 int l; 1908 1909 for (int i1 = 0; i1 < this.players.size(); ++i1) { 1910 EntityHuman entityhuman = (EntityHuman) this.players.get(i1); 1911 1912 i = MathHelper.floor(entityhuman.locX / 16.0D); 1913 j = MathHelper.floor(entityhuman.locZ / 16.0D); 1914 byte b0 = 9; 1915 1916 for (k = -b0; k <= b0; ++k) { 1917 for (l = -b0; l <= b0; ++l) { 1918 this.P.add(new ChunkCoordIntPair(k + i, l + j)); 1919 } 1920 } 1921 } 1922 1923 if (this.Q > 0) { 1924 --this.Q; 1925 } 1926 1927 Iterator iterator = this.P.iterator(); 1928 1929 while (iterator.hasNext()) { 1930 ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next(); 1931 1932 i = chunkcoordintpair.x * 16; 1933 j = chunkcoordintpair.z * 16; 1934 Chunk chunk = this.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z); 1935 int j1; 1936 int k1; 1937 int l1; 1938 1939 if (this.Q == 0) { 1940 this.g = this.g * 3 + 1013904223; 1941 k = this.g >> 2; 1942 l = k & 15; 1943 j1 = k >> 8 & 15; 1944 k1 = k >> 16 & 127; 1945 l1 = chunk.getTypeId(l, k1, j1); 1946 l += i; 1947 j1 += j; 1948 if (l1 == 0 && this.k(l, k1, j1) <= this.random.nextInt(8) && this.a(EnumSkyBlock.SKY, l, k1, j1) <= 0) { 1949 EntityHuman entityhuman1 = this.a((double) l + 0.5D, (double) k1 + 0.5D, (double) j1 + 0.5D, 8.0D); 1950 1951 if (entityhuman1 != null && entityhuman1.e((double) l + 0.5D, (double) k1 + 0.5D, (double) j1 + 0.5D) > 4.0D) { 1952 this.makeSound((double) l + 0.5D, (double) k1 + 0.5D, (double) j1 + 0.5D, "ambient.cave.cave", 0.7F, 0.8F + this.random.nextFloat() * 0.2F); 1953 this.Q = this.random.nextInt(12000) + 6000; 1954 } 1955 } 1956 } 1957 1958 if (this.random.nextInt(100000) == 0 && this.v() && this.u()) { 1959 this.g = this.g * 3 + 1013904223; 1960 k = this.g >> 2; 1961 l = i + (k & 15); 1962 j1 = j + (k >> 8 & 15); 1963 k1 = this.e(l, j1); 1964 if (this.s(l, k1, j1)) { 1965 this.strikeLightning(new EntityWeatherStorm(this, (double) l, (double) k1, (double) j1)); 1966 this.m = 2; 1967 } 1968 } 1969 1970 int i2; 1971 1972 if (this.random.nextInt(16) == 0) { 1973 this.g = this.g * 3 + 1013904223; 1974 k = this.g >> 2; 1975 l = k & 15; 1976 j1 = k >> 8 & 15; 1977 k1 = this.e(l + i, j1 + j); 1978 if (this.getWorldChunkManager().getBiome(l + i, j1 + j).c() && k1 >= 0 && k1 < 128 && chunk.a(EnumSkyBlock.BLOCK, l, k1, j1) < 10) { 1979 l1 = chunk.getTypeId(l, k1 - 1, j1); 1980 i2 = chunk.getTypeId(l, k1, j1); 1981 if (this.v() && i2 == 0 && Block.SNOW.canPlace(this, l + i, k1, j1 + j) && l1 != 0 && l1 != Block.ICE.id && Block.byId[l1].material.isSolid()) { 1982 // CraftBukkit start 1983 BlockState blockState = this.getWorld().getBlockAt(l + i, k1, j1 + j).getState(); 1984 blockState.setTypeId(Block.SNOW.id); 1985 1986 BlockFormEvent snow = new BlockFormEvent(blockState.getBlock(), blockState); 1987 this.getServer().getPluginManager().callEvent(snow); 1988 if (!snow.isCancelled()) { 1989 blockState.update(true); 1990 } 1991 // CraftBukkit end 1992 } 1993 1994 // uberbukkit 1995 boolean blocked = UberbukkitConfig.getInstance().getBoolean("mechanics.ice_generate_only_when_snowing", false) && !this.v(); 1996 1997 // CraftBukkit start 1998 if (!blocked && l1 == Block.STATIONARY_WATER.id && chunk.getData(l, k1 - 1, j1) == 0) { 1999 BlockState blockState = this.getWorld().getBlockAt(l + i, k1 - 1, j1 + j).getState(); 2000 blockState.setTypeId(Block.ICE.id); 2001 2002 BlockFormEvent iceBlockForm = new BlockFormEvent(blockState.getBlock(), blockState); 2003 this.getServer().getPluginManager().callEvent(iceBlockForm); 2004 if (!iceBlockForm.isCancelled()) { 2005 blockState.update(true); 2006 } 2007 } 2008 // CraftBukkit end 2009 } 2010 } 2011 2012 for (k = 0; k < 80; ++k) { 2013 this.g = this.g * 3 + 1013904223; 2014 l = this.g >> 2; 2015 j1 = l & 15; 2016 k1 = l >> 8 & 15; 2017 l1 = l >> 16 & 127; 2018 i2 = chunk.b[j1 << 11 | k1 << 7 | l1] & 255; 2019 if (Block.n[i2]) { 2020 Block.byId[i2].a(this, j1 + i, l1, k1 + j, this.random); 2021 } 2022 } 2023 } 2024 } 2025 2026 public boolean a(boolean flag) { 2027 int i = this.E.size(); 2028 2029 if (i != this.F.size()) { 2030 throw new IllegalStateException("TickNextTick list out of synch"); 2031 } else { 2032 if (i > 1000) { 2033 i = 1000; 2034 } 2035 2036 for (int j = 0; j < i; ++j) { 2037 NextTickListEntry nextticklistentry = (NextTickListEntry) this.E.first(); 2038 2039 if (!flag && nextticklistentry.e > this.worldData.f()) { 2040 break; 2041 } 2042 2043 this.E.remove(nextticklistentry); 2044 this.F.remove(nextticklistentry); 2045 byte b0 = 8; 2046 2047 if (this.a(nextticklistentry.a - b0, nextticklistentry.b - b0, nextticklistentry.c - b0, nextticklistentry.a + b0, nextticklistentry.b + b0, nextticklistentry.c + b0)) { 2048 int k = this.getTypeId(nextticklistentry.a, nextticklistentry.b, nextticklistentry.c); 2049 2050 if (k == nextticklistentry.d && k > 0) { 2051 Block.byId[k].a(this, nextticklistentry.a, nextticklistentry.b, nextticklistentry.c, this.random); 2052 } 2053 } 2054 } 2055 2056 return this.E.size() != 0; 2057 } 2058 } 2059 2060 public List b(Entity entity, AxisAlignedBB axisalignedbb) { 2061 this.R.clear(); 2062 int i = MathHelper.floor((axisalignedbb.a - 2.0D) / 16.0D); 2063 int j = MathHelper.floor((axisalignedbb.d + 2.0D) / 16.0D); 2064 int k = MathHelper.floor((axisalignedbb.c - 2.0D) / 16.0D); 2065 int l = MathHelper.floor((axisalignedbb.f + 2.0D) / 16.0D); 2066 2067 for (int i1 = i; i1 <= j; ++i1) { 2068 for (int j1 = k; j1 <= l; ++j1) { 2069 if (this.isChunkLoaded(i1, j1)) { 2070 this.getChunkAt(i1, j1).a(entity, axisalignedbb, this.R); 2071 } 2072 } 2073 } 2074 2075 return this.R; 2076 } 2077 2078 public List a(Class oclass, AxisAlignedBB axisalignedbb) { 2079 int i = MathHelper.floor((axisalignedbb.a - 2.0D) / 16.0D); 2080 int j = MathHelper.floor((axisalignedbb.d + 2.0D) / 16.0D); 2081 int k = MathHelper.floor((axisalignedbb.c - 2.0D) / 16.0D); 2082 int l = MathHelper.floor((axisalignedbb.f + 2.0D) / 16.0D); 2083 ArrayList arraylist = new ArrayList(); 2084 2085 for (int i1 = i; i1 <= j; ++i1) { 2086 for (int j1 = k; j1 <= l; ++j1) { 2087 if (this.isChunkLoaded(i1, j1)) { 2088 this.getChunkAt(i1, j1).a(oclass, axisalignedbb, arraylist); 2089 } 2090 } 2091 } 2092 2093 return arraylist; 2094 } 2095 2096 public void b(int i, int j, int k, TileEntity tileentity) { 2097 if (this.isLoaded(i, j, k)) { 2098 this.getChunkAtWorldCoords(i, k).f(); 2099 } 2100 2101 for (int l = 0; l < this.u.size(); ++l) { 2102 ((IWorldAccess) this.u.get(l)).a(i, j, k, tileentity); 2103 } 2104 } 2105 2106 public int a(Class oclass) { 2107 int i = 0; 2108 2109 for (int j = 0; j < this.entityList.size(); ++j) { 2110 Entity entity = (Entity) this.entityList.get(j); 2111 2112 if (oclass.isAssignableFrom(entity.getClass())) { 2113 ++i; 2114 } 2115 } 2116 2117 return i; 2118 } 2119 2120 public void a(List list) { 2121 // CraftBukkit start 2122 Entity entity = null; 2123 for (int i = 0; i < list.size(); ++i) { 2124 entity = (Entity) list.get(i); 2125 // CraftBukkit start - fixed an NPE 2126 if (entity == null) { 2127 continue; 2128 } 2129 // CraftBukkit end 2130 this.entityList.add(entity); 2131 // CraftBukkit end 2132 this.c((Entity) list.get(i)); 2133 } 2134 } 2135 2136 public void b(List list) { 2137 this.D.addAll(list); 2138 } 2139 2140 public boolean a(int i, int j, int k, int l, boolean flag, int i1) { 2141 int j1 = this.getTypeId(j, k, l); 2142 Block block = Block.byId[j1]; 2143 Block block1 = Block.byId[i]; 2144 AxisAlignedBB axisalignedbb = block1.e(this, j, k, l); 2145 2146 if (flag) { 2147 axisalignedbb = null; 2148 } 2149 2150 boolean defaultReturn; // CraftBukkit - store the default action 2151 2152 if (axisalignedbb != null && !this.containsEntity(axisalignedbb)) { 2153 defaultReturn = false; // CraftBukkit 2154 } else { 2155 // uberbukkit - allow placing triple chests 2156 if (pre1_5_placement_rules) { 2157 defaultReturn = (block != Block.WATER && block != Block.STATIONARY_WATER && block != Block.LAVA && block != Block.STATIONARY_LAVA && block != Block.FIRE && block != Block.SNOW ? i > 0 && block == null && block1.canPlace(this, j, k, l) : true); 2158 } else { 2159 if (block == Block.WATER || block == Block.STATIONARY_WATER || block == Block.LAVA || block == Block.STATIONARY_LAVA || block == Block.FIRE || block == Block.SNOW) { 2160 block = null; 2161 } 2162 2163 defaultReturn = i > 0 && block == null && block1.canPlace(this, j, k, l, i1); // CraftBukkit 2164 } 2165 } 2166 2167 // CraftBukkit start 2168 BlockCanBuildEvent event = new BlockCanBuildEvent(this.getWorld().getBlockAt(j, k, l), i, defaultReturn); 2169 this.getServer().getPluginManager().callEvent(event); 2170 2171 return event.isBuildable(); 2172 // CraftBukkit end 2173 } 2174 2175 public PathEntity findPath(Entity entity, Entity entity1, float f) { 2176 int i = MathHelper.floor(entity.locX); 2177 int j = MathHelper.floor(entity.locY); 2178 int k = MathHelper.floor(entity.locZ); 2179 int l = (int) (f + 16.0F); 2180 int i1 = i - l; 2181 int j1 = j - l; 2182 int k1 = k - l; 2183 int l1 = i + l; 2184 int i2 = j + l; 2185 int j2 = k + l; 2186 ChunkCache chunkcache = new ChunkCache(this, i1, j1, k1, l1, i2, j2); 2187 2188 return (new Pathfinder(chunkcache)).a(entity, entity1, f); 2189 } 2190 2191 public PathEntity a(Entity entity, int i, int j, int k, float f) { 2192 int l = MathHelper.floor(entity.locX); 2193 int i1 = MathHelper.floor(entity.locY); 2194 int j1 = MathHelper.floor(entity.locZ); 2195 int k1 = (int) (f + 8.0F); 2196 int l1 = l - k1; 2197 int i2 = i1 - k1; 2198 int j2 = j1 - k1; 2199 int k2 = l + k1; 2200 int l2 = i1 + k1; 2201 int i3 = j1 + k1; 2202 ChunkCache chunkcache = new ChunkCache(this, l1, i2, j2, k2, l2, i3); 2203 2204 return (new Pathfinder(chunkcache)).a(entity, i, j, k, f); 2205 } 2206 2207 public boolean isBlockFacePowered(int i, int j, int k, int l) { 2208 int i1 = this.getTypeId(i, j, k); 2209 2210 return i1 == 0 ? false : Block.byId[i1].d(this, i, j, k, l); 2211 } 2212 2213 public boolean isBlockPowered(int i, int j, int k) { 2214 return this.isBlockFacePowered(i, j - 1, k, 0) ? true : (this.isBlockFacePowered(i, j + 1, k, 1) ? true : (this.isBlockFacePowered(i, j, k - 1, 2) ? true : (this.isBlockFacePowered(i, j, k + 1, 3) ? true : (this.isBlockFacePowered(i - 1, j, k, 4) ? true : this.isBlockFacePowered(i + 1, j, k, 5))))); 2215 } 2216 2217 public boolean isBlockFaceIndirectlyPowered(int i, int j, int k, int l) { 2218 if (this.e(i, j, k)) { 2219 return this.isBlockPowered(i, j, k); 2220 } else { 2221 int i1 = this.getTypeId(i, j, k); 2222 2223 return i1 == 0 ? false : Block.byId[i1].a(this, i, j, k, l); 2224 } 2225 } 2226 2227 public boolean isBlockIndirectlyPowered(int i, int j, int k) { 2228 return this.isBlockFaceIndirectlyPowered(i, j - 1, k, 0) ? true : (this.isBlockFaceIndirectlyPowered(i, j + 1, k, 1) ? true : (this.isBlockFaceIndirectlyPowered(i, j, k - 1, 2) ? true : (this.isBlockFaceIndirectlyPowered(i, j, k + 1, 3) ? true : (this.isBlockFaceIndirectlyPowered(i - 1, j, k, 4) ? true : this.isBlockFaceIndirectlyPowered(i + 1, j, k, 5))))); 2229 } 2230 2231 public EntityHuman findNearbyPlayer(Entity entity, double d0) { 2232 return this.a(entity.locX, entity.locY, entity.locZ, d0); 2233 } 2234 2235 public EntityHuman a(double d0, double d1, double d2, double d3) { 2236 double d4 = -1.0D; 2237 EntityHuman entityhuman = null; 2238 2239 for (int i = 0; i < this.players.size(); ++i) { 2240 EntityHuman entityhuman1 = (EntityHuman) this.players.get(i); 2241 // CraftBukkit start - fixed an NPE 2242 if (entityhuman1 == null || entityhuman1.dead) { 2243 continue; 2244 } 2245 // CraftBukkit end 2246 double d5 = entityhuman1.e(d0, d1, d2); 2247 2248 if ((d3 < 0.0D || d5 < d3 * d3) && (d4 == -1.0D || d5 < d4)) { 2249 d4 = d5; 2250 entityhuman = entityhuman1; 2251 } 2252 } 2253 2254 return entityhuman; 2255 } 2256 2257 public EntityHuman a(String s) { 2258 for (int i = 0; i < this.players.size(); ++i) { 2259 if (s.equals(((EntityHuman) this.players.get(i)).name)) { 2260 return (EntityHuman) this.players.get(i); 2261 } 2262 } 2263 2264 return null; 2265 } 2266 2267 public byte[] getMultiChunkData(int i, int j, int k, int l, int i1, int j1) { 2268 byte[] abyte = new byte[l * i1 * j1 * 5 / 2]; 2269 int k1 = i >> 4; 2270 int l1 = k >> 4; 2271 int i2 = i + l - 1 >> 4; 2272 int j2 = k + j1 - 1 >> 4; 2273 int k2 = 0; 2274 int l2 = j; 2275 int i3 = j + i1; 2276 2277 if (j < 0) { 2278 l2 = 0; 2279 } 2280 2281 if (i3 > 128) { 2282 i3 = 128; 2283 } 2284 2285 for (int j3 = k1; j3 <= i2; ++j3) { 2286 int k3 = i - j3 * 16; 2287 int l3 = i + l - j3 * 16; 2288 2289 if (k3 < 0) { 2290 k3 = 0; 2291 } 2292 2293 if (l3 > 16) { 2294 l3 = 16; 2295 } 2296 2297 for (int i4 = l1; i4 <= j2; ++i4) { 2298 int j4 = k - i4 * 16; 2299 int k4 = k + j1 - i4 * 16; 2300 2301 if (j4 < 0) { 2302 j4 = 0; 2303 } 2304 2305 if (k4 > 16) { 2306 k4 = 16; 2307 } 2308 2309 k2 = this.getChunkAt(j3, i4).getData(abyte, k3, l2, j4, l3, i3, k4, k2); 2310 } 2311 } 2312 2313 return abyte; 2314 } 2315 2316 public void k() { 2317 this.w.b(); 2318 } 2319 2320 public void setTime(long i) { 2321 this.worldData.a(i); 2322 } 2323 2324 public void setTimeAndFixTicklists(long i) { 2325 long j = i - this.worldData.f(); 2326 2327 NextTickListEntry nextticklistentry; 2328 2329 for (Iterator iterator = this.F.iterator(); iterator.hasNext(); nextticklistentry.e += j) { 2330 nextticklistentry = (NextTickListEntry) iterator.next(); 2331 } 2332 2333 this.setTime(i); 2334 } 2335 2336 public long getSeed() { 2337 return this.worldData.getSeed(); 2338 } 2339 2340 public long getTime() { 2341 return this.worldData.f(); 2342 } 2343 2344 public ChunkCoordinates getSpawn() { 2345 return new ChunkCoordinates(this.worldData.c(), this.worldData.d(), this.worldData.e()); 2346 } 2347 2348 public boolean a(EntityHuman entityhuman, int i, int j, int k) { 2349 return true; 2350 } 2351 2352 public void a(Entity entity, byte b0) { 2353 } 2354 2355 public IChunkProvider o() { 2356 return this.chunkProvider; 2357 } 2358 2359 public void playNote(int i, int j, int k, int l, int i1) { 2360 int j1 = this.getTypeId(i, j, k); 2361 2362 if (j1 > 0) { 2363 Block.byId[j1].a(this, i, j, k, l, i1); 2364 } 2365 } 2366 2367 public IDataManager p() { 2368 return this.w; 2369 } 2370 2371 public WorldData q() { 2372 return this.worldData; 2373 } 2374 2375 public void everyoneSleeping() { 2376 this.J = !this.players.isEmpty(); 2377 Iterator iterator = this.players.iterator(); 2378 2379 while (iterator.hasNext()) { 2380 EntityHuman entityhuman = (EntityHuman) iterator.next(); 2381 2382 // CraftBukkit 2383 if (!entityhuman.isSleeping() && !entityhuman.fauxSleeping) { 2384 this.J = false; 2385 break; 2386 } 2387 } 2388 } 2389 2390 // CraftBukkit start 2391 // Calls the method that checks to see if players are sleeping 2392 // Called by CraftPlayer.setPermanentSleeping() 2393 public void checkSleepStatus() { 2394 if (!this.isStatic) { 2395 this.everyoneSleeping(); 2396 } 2397 } 2398 // CraftBukkit end 2399 2400 protected void s() { 2401 this.J = false; 2402 Iterator iterator = this.players.iterator(); 2403 2404 while (iterator.hasNext()) { 2405 EntityHuman entityhuman = (EntityHuman) iterator.next(); 2406 2407 if (entityhuman.isSleeping()) { 2408 entityhuman.a(false, false, true); 2409 } 2410 } 2411 2412 this.y(); 2413 } 2414 2415 public boolean everyoneDeeplySleeping() { 2416 if (this.J && !this.isStatic) { 2417 Iterator iterator = this.players.iterator(); 2418 2419 // CraftBukkit - This allows us to assume that some people are in bed but not really, allowing time to pass in spite of AFKers 2420 boolean foundActualSleepers = false; 2421 2422 EntityHuman entityhuman; 2423 2424 do { 2425 if (!iterator.hasNext()) { 2426 // CraftBukkit 2427 return foundActualSleepers; 2428 } 2429 2430 entityhuman = (EntityHuman) iterator.next(); 2431 // CraftBukkit start 2432 if (entityhuman.isDeeplySleeping()) { 2433 foundActualSleepers = true; 2434 } 2435 } while (entityhuman.isDeeplySleeping() || entityhuman.fauxSleeping); 2436 // CraftBukkit end 2437 2438 return false; 2439 } else { 2440 return false; 2441 } 2442 } 2443 2444 public float c(float f) { 2445 return (this.k + (this.l - this.k) * f) * this.d(f); 2446 } 2447 2448 public float d(float f) { 2449 return this.i + (this.j - this.i) * f; 2450 } 2451 2452 public boolean u() { 2453 return (double) this.c(1.0F) > 0.9D; 2454 } 2455 2456 public boolean v() { 2457 // uberbukkit 2458 if (UberbukkitConfig.getInstance().getBoolean("mechanics.do_weather", true)) 2459 return (double) this.d(1.0F) > 0.2D; 2460 2461 return false; 2462 } 2463 2464 public boolean s(int i, int j, int k) { 2465 if (!this.v()) { 2466 return false; 2467 } else if (!this.isChunkLoaded(i, j, k)) { 2468 return false; 2469 } else if (this.e(i, k) > j) { 2470 return false; 2471 } else { 2472 BiomeBase biomebase = this.getWorldChunkManager().getBiome(i, k); 2473 2474 return biomebase.c() ? false : biomebase.d(); 2475 } 2476 } 2477 2478 public void a(String s, WorldMapBase worldmapbase) { 2479 this.worldMaps.a(s, worldmapbase); 2480 } 2481 2482 public WorldMapBase a(Class oclass, String s) { 2483 return this.worldMaps.a(oclass, s); 2484 } 2485 2486 public int b(String s) { 2487 return this.worldMaps.a(s); 2488 } 2489 2490 public void e(int i, int j, int k, int l, int i1) { 2491 this.a((EntityHuman) null, i, j, k, l, i1); 2492 } 2493 2494 public void a(EntityHuman entityhuman, int i, int j, int k, int l, int i1) { 2495 for (int j1 = 0; j1 < this.u.size(); ++j1) { 2496 ((IWorldAccess) this.u.get(j1)).a(entityhuman, i, j, k, l, i1); 2497 } 2498 } 2499 2500 // CraftBukkit start 2501 public UUID getUUID() { 2502 return this.w.getUUID(); 2503 } 2504 // CraftBukkit end 2505}