Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
at develop 652 lines 19 kB view raw
1package net.minecraft.server; 2 3import com.legacyminecraft.poseidon.PoseidonConfig; 4 5import java.util.*; 6 7public class Chunk { 8 9 public static boolean a; 10 public byte[] b; 11 public boolean c; 12 public World world; 13 public NibbleArray e; 14 public NibbleArray f; 15 public NibbleArray g; 16 public byte[] heightMap; 17 public int i; 18 public int x; // UBERBUKKIT non-final 19 public int z; // UBERBUKKIT non-final 20 public Map tileEntities; 21 public List[] entitySlices; 22 public boolean done; 23 public boolean o; 24 public boolean p; 25 public boolean q; 26 public long r; 27 28 public Chunk(World world, int i, int j) { 29 this.tileEntities = new HashMap(); 30 this.entitySlices = new List[8]; 31 this.done = false; 32 this.o = false; 33 this.q = false; 34 this.r = 0L; 35 this.world = world; 36 this.x = i; 37 this.z = j; 38 this.heightMap = new byte[256]; 39 40 for (int k = 0; k < this.entitySlices.length; ++k) { 41 this.entitySlices[k] = new ArrayList(); 42 } 43 44 // CraftBukkit start 45 org.bukkit.craftbukkit.CraftWorld cworld = this.world.getWorld(); 46 this.bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); 47 } 48 49 public org.bukkit.Chunk bukkitChunk; 50 // CraftBukkit end 51 52 public Chunk(World world, byte[] abyte, int i, int j) { 53 this(world, i, j); 54 this.b = abyte; 55 this.e = new NibbleArray(abyte.length); 56 this.f = new NibbleArray(abyte.length); 57 this.g = new NibbleArray(abyte.length); 58 } 59 60 public boolean a(int i, int j) { 61 return i == this.x && j == this.z; 62 } 63 64 public int b(int i, int j) { 65 return this.heightMap[j << 4 | i] & 255; 66 } 67 68 public void a() { 69 } 70 71 public void initLighting() { 72 int i = 127; 73 74 int j; 75 int k; 76 77 for (j = 0; j < 16; ++j) { 78 for (k = 0; k < 16; ++k) { 79 int l = 127; 80 81 int i1; 82 83 for (i1 = j << 11 | k << 7; l > 0 && Block.q[this.b[i1 + l - 1] & 255] == 0; --l) { 84 ; 85 } 86 87 this.heightMap[k << 4 | j] = (byte) l; 88 if (l < i) { 89 i = l; 90 } 91 92 if (!this.world.worldProvider.e) { 93 int j1 = 15; 94 int k1 = 127; 95 96 do { 97 j1 -= Block.q[this.b[i1 + k1] & 255]; 98 if (j1 > 0) { 99 this.f.a(j, k1, k, j1); 100 } 101 102 --k1; 103 } while (k1 > 0 && j1 > 0); 104 } 105 } 106 } 107 108 this.i = i; 109 110 for (j = 0; j < 16; ++j) { 111 for (k = 0; k < 16; ++k) { 112 this.c(j, k); 113 } 114 } 115 116 this.o = true; 117 } 118 119 public void loadNOP() { 120 } 121 122 private void c(int i, int j) { 123 int k = this.b(i, j); 124 int l = this.x * 16 + i; 125 int i1 = this.z * 16 + j; 126 127 this.f(l - 1, i1, k); 128 this.f(l + 1, i1, k); 129 this.f(l, i1 - 1, k); 130 this.f(l, i1 + 1, k); 131 } 132 133 private void f(int i, int j, int k) { 134 int l = this.world.getHighestBlockYAt(i, j); 135 136 if (l > k) { 137 this.world.a(EnumSkyBlock.SKY, i, k, j, i, l, j); 138 this.o = true; 139 } else if (l < k) { 140 this.world.a(EnumSkyBlock.SKY, i, l, j, i, k, j); 141 this.o = true; 142 } 143 } 144 145 private void g(int i, int j, int k) { 146 int l = this.heightMap[k << 4 | i] & 255; 147 int i1 = l; 148 149 if (j > l) { 150 i1 = j; 151 } 152 153 for (int j1 = i << 11 | k << 7; i1 > 0 && Block.q[this.b[j1 + i1 - 1] & 255] == 0; --i1) { 154 ; 155 } 156 157 if (i1 != l) { 158 this.world.g(i, k, i1, l); 159 this.heightMap[k << 4 | i] = (byte) i1; 160 int k1; 161 int l1; 162 int i2; 163 164 if (i1 < this.i) { 165 this.i = i1; 166 } else { 167 k1 = 127; 168 169 for (l1 = 0; l1 < 16; ++l1) { 170 for (i2 = 0; i2 < 16; ++i2) { 171 if ((this.heightMap[i2 << 4 | l1] & 255) < k1) { 172 k1 = this.heightMap[i2 << 4 | l1] & 255; 173 } 174 } 175 } 176 177 this.i = k1; 178 } 179 180 k1 = this.x * 16 + i; 181 l1 = this.z * 16 + k; 182 if (i1 < l) { 183 for (i2 = i1; i2 < l; ++i2) { 184 this.f.a(i, i2, k, 15); 185 } 186 } else { 187 this.world.a(EnumSkyBlock.SKY, k1, l, l1, k1, i1, l1); 188 189 for (i2 = l; i2 < i1; ++i2) { 190 this.f.a(i, i2, k, 0); 191 } 192 } 193 194 i2 = 15; 195 196 int j2; 197 198 for (j2 = i1; i1 > 0 && i2 > 0; this.f.a(i, i1, k, i2)) { 199 --i1; 200 int k2 = Block.q[this.getTypeId(i, i1, k)]; 201 202 if (k2 == 0) { 203 k2 = 1; 204 } 205 206 i2 -= k2; 207 if (i2 < 0) { 208 i2 = 0; 209 } 210 } 211 212 while (i1 > 0 && Block.q[this.getTypeId(i, i1 - 1, k)] == 0) { 213 --i1; 214 } 215 216 if (i1 != j2) { 217 this.world.a(EnumSkyBlock.SKY, k1 - 1, i1, l1 - 1, k1 + 1, j2, l1 + 1); 218 } 219 220 this.o = true; 221 } 222 } 223 224 public int getTypeId(int i, int j, int k) { 225 return this.b[i << 11 | k << 7 | j] & 255; 226 } 227 228 public boolean a(int i, int j, int k, int l, int i1) { 229 byte b0 = (byte) l; 230 int j1 = this.heightMap[k << 4 | i] & 255; 231 int k1 = this.b[i << 11 | k << 7 | j] & 255; 232 233 if (k1 == l && this.e.a(i, j, k) == i1) { 234 return false; 235 } else { 236 int l1 = this.x * 16 + i; 237 int i2 = this.z * 16 + k; 238 239 this.b[i << 11 | k << 7 | j] = (byte) (b0 & 255); 240 if (PoseidonConfig.getInstance().getConfigBoolean("world.settings.pistons.transmutation-fix.enabled", true)) { 241 this.e.a(i, j, k, i1); 242 if (k1 != 0 && !this.world.isStatic) { 243 Block.byId[k1].remove(this.world, l1, j, i2); 244 } 245 } else { 246 if (k1 != 0 && !this.world.isStatic) { 247 Block.byId[k1].remove(this.world, l1, j, i2); 248 } 249 this.e.a(i, j, k, i1); 250 } 251 252 if (!this.world.worldProvider.e) { 253 if (Block.q[b0 & 255] != 0) { 254 if (j >= j1) { 255 this.g(i, j + 1, k); 256 } 257 } else if (j == j1 - 1) { 258 this.g(i, j, k); 259 } 260 261 this.world.a(EnumSkyBlock.SKY, l1, j, i2, l1, j, i2); 262 } 263 264 this.world.a(EnumSkyBlock.BLOCK, l1, j, i2, l1, j, i2); 265 this.c(i, k); 266 if (l != 0) { 267 Block.byId[l].c(this.world, l1, j, i2); 268 } 269 270 this.o = true; 271 return true; 272 } 273 } 274 275 public boolean a(int i, int j, int k, int l) { 276 byte b0 = (byte) l; 277 int i1 = this.heightMap[k << 4 | i] & 255; 278 int j1 = this.b[i << 11 | k << 7 | j] & 255; 279 280 if (j1 == l) { 281 return false; 282 } else { 283 int k1 = this.x * 16 + i; 284 int l1 = this.z * 16 + k; 285 286 this.b[i << 11 | k << 7 | j] = (byte) (b0 & 255); 287 if (j1 != 0) { 288 Block.byId[j1].remove(this.world, k1, j, l1); 289 } 290 291 this.e.a(i, j, k, 0); 292 if (Block.q[b0 & 255] != 0) { 293 if (j >= i1) { 294 this.g(i, j + 1, k); 295 } 296 } else if (j == i1 - 1) { 297 this.g(i, j, k); 298 } 299 300 this.world.a(EnumSkyBlock.SKY, k1, j, l1, k1, j, l1); 301 this.world.a(EnumSkyBlock.BLOCK, k1, j, l1, k1, j, l1); 302 this.c(i, k); 303 if (l != 0 && !this.world.isStatic) { 304 Block.byId[l].c(this.world, k1, j, l1); 305 } 306 307 this.o = true; 308 return true; 309 } 310 } 311 312 public int getData(int i, int j, int k) { 313 return this.e.a(i, j, k); 314 } 315 316 public void b(int i, int j, int k, int l) { 317 this.o = true; 318 this.e.a(i, j, k, l); 319 } 320 321 public int a(EnumSkyBlock enumskyblock, int i, int j, int k) { 322 return enumskyblock == EnumSkyBlock.SKY ? this.f.a(i, j, k) : (enumskyblock == EnumSkyBlock.BLOCK ? this.g.a(i, j, k) : 0); 323 } 324 325 public void a(EnumSkyBlock enumskyblock, int i, int j, int k, int l) { 326 this.o = true; 327 if (enumskyblock == EnumSkyBlock.SKY) { 328 this.f.a(i, j, k, l); 329 } else { 330 if (enumskyblock != EnumSkyBlock.BLOCK) { 331 return; 332 } 333 334 this.g.a(i, j, k, l); 335 } 336 } 337 338 public int c(int i, int j, int k, int l) { 339 int i1 = this.f.a(i, j, k); 340 341 if (i1 > 0) { 342 a = true; 343 } 344 345 i1 -= l; 346 int j1 = this.g.a(i, j, k); 347 348 if (j1 > i1) { 349 i1 = j1; 350 } 351 352 return i1; 353 } 354 355 public void a(Entity entity) { 356 this.q = true; 357 int i = MathHelper.floor(entity.locX / 16.0D); 358 int j = MathHelper.floor(entity.locZ / 16.0D); 359 360 if (i != this.x || j != this.z) { 361 System.out.println("Wrong location! " + entity); 362 // Thread.dumpStack(); // CraftBukkit 363 // CraftBukkit 364 System.out.println("" + entity.locX + "," + entity.locZ + "(" + i + "," + j + ") vs " + this.x + "," + this.z); 365 } 366 367 int k = MathHelper.floor(entity.locY / 16.0D); 368 369 if (k < 0) { 370 k = 0; 371 } 372 373 if (k >= this.entitySlices.length) { 374 k = this.entitySlices.length - 1; 375 } 376 377 entity.bG = true; 378 entity.bH = this.x; 379 entity.bI = k; 380 entity.bJ = this.z; 381 this.entitySlices[k].add(entity); 382 } 383 384 public void b(Entity entity) { 385 this.a(entity, entity.bI); 386 } 387 388 public void a(Entity entity, int i) { 389 if (i < 0) { 390 i = 0; 391 } 392 393 if (i >= this.entitySlices.length) { 394 i = this.entitySlices.length - 1; 395 } 396 397 this.entitySlices[i].remove(entity); 398 } 399 400 public boolean c(int i, int j, int k) { 401 return j >= (this.heightMap[k << 4 | i] & 255); 402 } 403 404 public TileEntity d(int i, int j, int k) { 405 ChunkPosition chunkposition = new ChunkPosition(i, j, k); 406 TileEntity tileentity = (TileEntity) this.tileEntities.get(chunkposition); 407 408 if (tileentity == null) { 409 int l = this.getTypeId(i, j, k); 410 411 if (!Block.isTileEntity[l]) { 412 return null; 413 } 414 415 BlockContainer blockcontainer = (BlockContainer) Block.byId[l]; 416 417 blockcontainer.c(this.world, this.x * 16 + i, j, this.z * 16 + k); 418 tileentity = (TileEntity) this.tileEntities.get(chunkposition); 419 } 420 421 if (tileentity != null && tileentity.g()) { 422 this.tileEntities.remove(chunkposition); 423 return null; 424 } else { 425 return tileentity; 426 } 427 } 428 429 public void a(TileEntity tileentity) { 430 int i = tileentity.x - this.x * 16; 431 int j = tileentity.y; 432 int k = tileentity.z - this.z * 16; 433 434 this.placeTileEntity(i, j, k, tileentity); 435 if (this.c) { 436 this.world.c.add(tileentity); 437 } 438 } 439 440 public void placeTileEntity(int i, int j, int k, TileEntity tileentity) { 441 ChunkPosition chunkposition = new ChunkPosition(i, j, k); 442 443 tileentity.world = this.world; 444 tileentity.x = this.x * 16 + i; 445 tileentity.y = j; 446 tileentity.z = this.z * 16 + k; 447 if (this.getTypeId(i, j, k) != 0 && Block.byId[this.getTypeId(i, j, k)] instanceof BlockContainer) { 448 tileentity.j(); 449 this.tileEntities.put(chunkposition, tileentity); 450 // Poseidon start - Backport of 0021-Remove-invalid-mob-spawner-tile-entities.patch from PaperSpigot 451 } else if (tileentity instanceof TileEntityMobSpawner && !(Block.byId[this.getTypeId(i, j, k)] instanceof BlockMobSpawner)) { 452 this.tileEntities.remove(chunkposition); 453 // Poseidon end 454 } else { 455 System.out.println("Attempted to place a tile entity where there was no entity tile!"); 456 } 457 } 458 459 public void e(int i, int j, int k) { 460 ChunkPosition chunkposition = new ChunkPosition(i, j, k); 461 462 if (this.c) { 463 TileEntity tileentity = (TileEntity) this.tileEntities.remove(chunkposition); 464 465 if (tileentity != null) { 466 tileentity.h(); 467 } 468 } 469 } 470 471 public void addEntities() { 472 this.c = true; 473 this.world.a(this.tileEntities.values()); 474 475 for (int i = 0; i < this.entitySlices.length; ++i) { 476 this.world.a(this.entitySlices[i]); 477 } 478 } 479 480 public void removeEntities() { 481 this.c = false; 482 Iterator iterator = this.tileEntities.values().iterator(); 483 484 while (iterator.hasNext()) { 485 TileEntity tileentity = (TileEntity) iterator.next(); 486 487 world.markForRemoval(tileentity); // Craftbukkit 488 } 489 490 for (int i = 0; i < this.entitySlices.length; ++i) { 491 // CraftBukkit start 492 java.util.Iterator<Object> iter = this.entitySlices[i].iterator(); 493 while (iter.hasNext()) { 494 Entity entity = (Entity) iter.next(); 495 int cx = org.bukkit.Location.locToBlock(entity.locX) >> 4; 496 int cz = org.bukkit.Location.locToBlock(entity.locZ) >> 4; 497 498 // Do not pass along players, as doing so can get them stuck outside of time. 499 // (which for example disables inventory icon updates and prevents block breaking) 500 if (entity instanceof EntityPlayer && (cx != this.x || cz != this.z)) { 501 iter.remove(); 502 } 503 } 504 // CraftBukkit end 505 506 this.world.b(this.entitySlices[i]); 507 } 508 } 509 510 public void f() { 511 this.o = true; 512 } 513 514 public void a(Entity entity, AxisAlignedBB axisalignedbb, List list) { 515 int i = MathHelper.floor((axisalignedbb.b - 2.0D) / 16.0D); 516 int j = MathHelper.floor((axisalignedbb.e + 2.0D) / 16.0D); 517 518 if (i < 0) { 519 i = 0; 520 } 521 522 if (j >= this.entitySlices.length) { 523 j = this.entitySlices.length - 1; 524 } 525 526 for (int k = i; k <= j; ++k) { 527 List list1 = this.entitySlices[k]; 528 529 for (int l = 0; l < list1.size(); ++l) { 530 Entity entity1 = (Entity) list1.get(l); 531 532 if (entity1 != entity && entity1.boundingBox.a(axisalignedbb)) { 533 list.add(entity1); 534 } 535 } 536 } 537 } 538 539 public void a(Class oclass, AxisAlignedBB axisalignedbb, List list) { 540 int i = MathHelper.floor((axisalignedbb.b - 2.0D) / 16.0D); 541 int j = MathHelper.floor((axisalignedbb.e + 2.0D) / 16.0D); 542 543 if (i < 0) { 544 i = 0; 545 } 546 547 if (j >= this.entitySlices.length) { 548 j = this.entitySlices.length - 1; 549 } 550 551 for (int k = i; k <= j; ++k) { 552 List list1 = this.entitySlices[k]; 553 554 for (int l = 0; l < list1.size(); ++l) { 555 Entity entity = (Entity) list1.get(l); 556 557 if (oclass.isAssignableFrom(entity.getClass()) && entity.boundingBox.a(axisalignedbb)) { 558 list.add(entity); 559 } 560 } 561 } 562 } 563 564 public boolean a(boolean flag) { 565 if (this.p) { 566 return false; 567 } else { 568 if (flag) { 569 if (this.q && this.world.getTime() != this.r) { 570 return true; 571 } 572 } else if (this.q && this.world.getTime() >= this.r + 600L) { 573 return true; 574 } 575 576 return this.o; 577 } 578 } 579 580 public int getData(byte[] abyte, int i, int j, int k, int l, int i1, int j1, int k1) { 581 int l1 = l - i; 582 int i2 = i1 - j; 583 int j2 = j1 - k; 584 585 if (l1 * i2 * j2 == this.b.length) { 586 System.arraycopy(this.b, 0, abyte, k1, this.b.length); 587 k1 += this.b.length; 588 System.arraycopy(this.e.a, 0, abyte, k1, this.e.a.length); 589 k1 += this.e.a.length; 590 System.arraycopy(this.g.a, 0, abyte, k1, this.g.a.length); 591 k1 += this.g.a.length; 592 System.arraycopy(this.f.a, 0, abyte, k1, this.f.a.length); 593 k1 += this.f.a.length; 594 return k1; 595 } else { 596 int k2; 597 int l2; 598 int i3; 599 int j3; 600 601 for (k2 = i; k2 < l; ++k2) { 602 for (l2 = k; l2 < j1; ++l2) { 603 i3 = k2 << 11 | l2 << 7 | j; 604 j3 = i1 - j; 605 System.arraycopy(this.b, i3, abyte, k1, j3); 606 k1 += j3; 607 } 608 } 609 610 for (k2 = i; k2 < l; ++k2) { 611 for (l2 = k; l2 < j1; ++l2) { 612 i3 = (k2 << 11 | l2 << 7 | j) >> 1; 613 j3 = (i1 - j) / 2; 614 System.arraycopy(this.e.a, i3, abyte, k1, j3); 615 k1 += j3; 616 } 617 } 618 619 for (k2 = i; k2 < l; ++k2) { 620 for (l2 = k; l2 < j1; ++l2) { 621 i3 = (k2 << 11 | l2 << 7 | j) >> 1; 622 j3 = (i1 - j) / 2; 623 System.arraycopy(this.g.a, i3, abyte, k1, j3); 624 k1 += j3; 625 } 626 } 627 628 for (k2 = i; k2 < l; ++k2) { 629 for (l2 = k; l2 < j1; ++l2) { 630 i3 = (k2 << 11 | l2 << 7 | j) >> 1; 631 j3 = (i1 - j) / 2; 632 System.arraycopy(this.f.a, i3, abyte, k1, j3); 633 k1 += j3; 634 } 635 } 636 637 return k1; 638 } 639 } 640 641 public Random a(long i) { 642 return new Random(this.world.getSeed() + (long) (this.x * this.x * 4987142) + (long) (this.x * 5947611) + (long) (this.z * this.z) * 4392871L + (long) (this.z * 389711) ^ i); 643 } 644 645 public boolean isEmpty() { 646 return false; 647 } 648 649 public void h() { 650 BlockRegister.a(this.b); 651 } 652}