Paper/src/main/java/net/minecraft/server/Chunk.java

932 Zeilen
27 KiB
Java

2011-02-01 23:49:28 +01:00
package net.minecraft.server;
2012-07-29 09:33:13 +02:00
import java.util.ArrayList;
2011-09-15 02:23:52 +02:00
import java.util.Arrays;
2011-02-01 23:49:28 +01:00
import java.util.HashMap;
2011-06-30 00:02:25 +02:00
import java.util.Iterator;
2011-02-01 23:49:28 +01:00
import java.util.List;
import java.util.Map;
import java.util.Random;
// CraftBukkit start
import org.bukkit.Bukkit;
import org.bukkit.Location;
// CraftBukkit end
2011-02-01 23:49:28 +01:00
public class Chunk {
public static boolean a;
2012-03-01 11:49:23 +01:00
private ChunkSection[] sections;
private byte[] r;
2012-03-01 11:49:23 +01:00
public int[] b;
public boolean[] c;
public boolean d;
public World world;
2012-03-01 11:49:23 +01:00
public int[] heightMap;
public final int x;
public final int z;
private boolean s;
public Map tileEntities;
public List[] entitySlices;
public boolean done;
2012-03-01 11:49:23 +01:00
public boolean l;
public boolean m;
public long n;
public boolean seenByPlayer;
private int t;
boolean p;
2011-02-01 23:49:28 +01:00
public Chunk(World world, int i, int j) {
2012-03-01 11:49:23 +01:00
this.sections = new ChunkSection[16];
this.r = new byte[256];
2012-03-01 11:49:23 +01:00
this.b = new int[256];
this.c = new boolean[256];
this.s = false;
this.tileEntities = new HashMap();
this.done = false;
2012-03-01 11:49:23 +01:00
this.l = false;
this.m = false;
this.n = 0L;
this.seenByPlayer = false;
this.t = 4096;
this.p = false;
2012-03-01 11:49:23 +01:00
this.entitySlices = new List[16];
this.world = world;
this.x = i;
this.z = j;
2012-03-01 11:49:23 +01:00
this.heightMap = new int[256];
2011-02-01 23:49:28 +01:00
for (int k = 0; k < this.entitySlices.length; ++k) {
2012-07-29 09:33:13 +02:00
this.entitySlices[k] = new ArrayList();
2011-02-01 23:49:28 +01:00
}
2012-03-01 11:49:23 +01:00
Arrays.fill(this.b, -999);
Arrays.fill(this.r, (byte) -1);
2011-09-15 02:23:52 +02:00
2011-02-01 23:49:28 +01:00
// CraftBukkit start
if (!(this instanceof EmptyChunk)) {
this.bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this);
}
2011-02-01 23:49:28 +01:00
}
public org.bukkit.Chunk bukkitChunk;
// CraftBukkit end
public Chunk(World world, byte[] abyte, int i, int j) {
this(world, i, j);
2012-03-01 11:49:23 +01:00
int k = abyte.length / 256;
for (int l = 0; l < 16; ++l) {
for (int i1 = 0; i1 < 16; ++i1) {
for (int j1 = 0; j1 < k; ++j1) {
byte b0 = abyte[l << 11 | i1 << 7 | j1];
if (b0 != 0) {
int k1 = j1 >> 4;
if (this.sections[k1] == null) {
this.sections[k1] = new ChunkSection(k1 << 4);
}
this.sections[k1].a(l, j1 & 15, i1, b0);
}
}
}
}
2011-02-01 23:49:28 +01:00
}
public boolean a(int i, int j) {
return i == this.x && j == this.z;
2011-02-01 23:49:28 +01:00
}
public int b(int i, int j) {
2012-03-01 11:49:23 +01:00
return this.heightMap[j << 4 | i];
2011-02-01 23:49:28 +01:00
}
2012-07-29 09:33:13 +02:00
public int h() {
2012-03-01 11:49:23 +01:00
for (int i = this.sections.length - 1; i >= 0; --i) {
if (this.sections[i] != null) {
2012-07-29 09:33:13 +02:00
return this.sections[i].d();
2012-03-01 11:49:23 +01:00
}
}
return 0;
}
2012-07-29 09:33:13 +02:00
public ChunkSection[] i() {
2012-03-01 11:49:23 +01:00
return this.sections;
}
2011-02-01 23:49:28 +01:00
public void initLighting() {
2012-07-29 09:33:13 +02:00
int i = this.h();
2011-02-01 23:49:28 +01:00
int j;
int k;
for (j = 0; j < 16; ++j) {
2012-03-01 11:49:23 +01:00
k = 0;
2011-09-15 05:13:14 +02:00
2012-03-01 11:49:23 +01:00
while (k < 16) {
this.b[j + (k << 4)] = -999;
int l = i + 16 - 1;
2011-02-01 23:49:28 +01:00
2012-03-01 11:49:23 +01:00
while (true) {
if (l > 0) {
if (this.b(j, l - 1, k) == 0) {
--l;
continue;
}
2011-02-01 23:49:28 +01:00
2012-03-01 11:49:23 +01:00
this.heightMap[k << 4 | j] = l;
}
2011-02-01 23:49:28 +01:00
2012-03-01 11:49:23 +01:00
if (!this.world.worldProvider.e) {
l = 15;
int i1 = i + 16 - 1;
2011-02-01 23:49:28 +01:00
2012-03-01 11:49:23 +01:00
do {
l -= this.b(j, i1, k);
if (l > 0) {
ChunkSection chunksection = this.sections[i1 >> 4];
2011-02-01 23:49:28 +01:00
2012-03-01 11:49:23 +01:00
if (chunksection != null) {
chunksection.c(j, i1 & 15, k, l);
2012-07-29 09:33:13 +02:00
this.world.n((this.x << 4) + j, i1, (this.z << 4) + k);
2012-03-01 11:49:23 +01:00
}
}
--i1;
} while (i1 > 0 && l > 0);
}
++k;
break;
2011-02-01 23:49:28 +01:00
}
}
}
2012-03-01 11:49:23 +01:00
this.l = true;
2011-02-01 23:49:28 +01:00
for (j = 0; j < 16; ++j) {
for (k = 0; k < 16; ++k) {
2012-03-01 11:49:23 +01:00
this.e(j, k);
2011-02-01 23:49:28 +01:00
}
}
}
2012-03-01 11:49:23 +01:00
private void e(int i, int j) {
this.c[i + j * 16] = true;
this.s = true;
2011-11-20 09:01:14 +01:00
}
2012-07-29 09:33:13 +02:00
private void q() {
this.world.methodProfiler.a("recheckGaps");
2012-03-01 11:49:23 +01:00
if (this.world.areChunksLoaded(this.x * 16 + 8, 0, this.z * 16 + 8, 16)) {
2011-11-20 09:01:14 +01:00
for (int i = 0; i < 16; ++i) {
for (int j = 0; j < 16; ++j) {
2012-03-01 11:49:23 +01:00
if (this.c[i + j * 16]) {
this.c[i + j * 16] = false;
2011-11-20 09:01:14 +01:00
int k = this.b(i, j);
int l = this.x * 16 + i;
int i1 = this.z * 16 + j;
int j1 = this.world.getHighestBlockYAt(l - 1, i1);
int k1 = this.world.getHighestBlockYAt(l + 1, i1);
int l1 = this.world.getHighestBlockYAt(l, i1 - 1);
int i2 = this.world.getHighestBlockYAt(l, i1 + 1);
if (k1 < j1) {
j1 = k1;
2011-09-15 02:23:52 +02:00
}
2011-11-20 09:01:14 +01:00
if (l1 < j1) {
j1 = l1;
2011-09-15 02:23:52 +02:00
}
2011-11-20 09:01:14 +01:00
if (i2 < j1) {
j1 = i2;
2011-09-15 02:23:52 +02:00
}
2011-02-01 23:49:28 +01:00
2012-03-01 11:49:23 +01:00
this.g(l, i1, j1);
this.g(l - 1, i1, k);
this.g(l + 1, i1, k);
this.g(l, i1 - 1, k);
this.g(l, i1 + 1, k);
2011-09-15 02:23:52 +02:00
}
}
}
2012-03-01 11:49:23 +01:00
this.s = false;
2011-09-15 02:23:52 +02:00
}
2012-03-01 11:49:23 +01:00
2012-07-29 09:33:13 +02:00
this.world.methodProfiler.b();
2011-02-01 23:49:28 +01:00
}
2012-03-01 11:49:23 +01:00
private void g(int i, int j, int k) {
int l = this.world.getHighestBlockYAt(i, j);
2011-02-01 23:49:28 +01:00
if (l > k) {
2011-09-15 02:23:52 +02:00
this.d(i, j, k, l + 1);
2011-02-01 23:49:28 +01:00
} else if (l < k) {
2011-09-15 02:23:52 +02:00
this.d(i, j, l, k + 1);
}
}
private void d(int i, int j, int k, int l) {
2012-03-01 11:49:23 +01:00
if (l > k && this.world.areChunksLoaded(i, 0, j, 16)) {
2011-11-20 09:01:14 +01:00
for (int i1 = k; i1 < l; ++i1) {
2012-07-29 09:33:13 +02:00
this.world.c(EnumSkyBlock.SKY, i, i1, j);
2011-09-15 02:23:52 +02:00
}
2011-11-20 09:01:14 +01:00
2012-03-01 11:49:23 +01:00
this.l = true;
2011-02-01 23:49:28 +01:00
}
}
2012-03-01 11:49:23 +01:00
private void h(int i, int j, int k) {
int l = this.heightMap[k << 4 | i] & 255;
2011-02-01 23:49:28 +01:00
int i1 = l;
if (j > l) {
i1 = j;
}
2011-09-15 02:23:52 +02:00
2012-03-01 11:49:23 +01:00
while (i1 > 0 && this.b(i, i1 - 1, k) == 0) {
--i1;
2011-02-01 23:49:28 +01:00
}
if (i1 != l) {
this.world.g(i, k, i1, l);
2012-03-01 11:49:23 +01:00
this.heightMap[k << 4 | i] = i1;
int j1 = this.x * 16 + i;
int k1 = this.z * 16 + k;
2011-02-01 23:49:28 +01:00
int l1;
int i2;
2012-03-01 11:49:23 +01:00
if (!this.world.worldProvider.e) {
ChunkSection chunksection;
2011-02-01 23:49:28 +01:00
2011-11-20 09:01:14 +01:00
if (i1 < l) {
2012-03-01 11:49:23 +01:00
for (l1 = i1; l1 < l; ++l1) {
chunksection = this.sections[l1 >> 4];
if (chunksection != null) {
chunksection.c(i, l1 & 15, k, 15);
2012-07-29 09:33:13 +02:00
this.world.n((this.x << 4) + i, l1, (this.z << 4) + k);
2012-03-01 11:49:23 +01:00
}
2011-11-20 09:01:14 +01:00
}
} else {
2012-03-01 11:49:23 +01:00
for (l1 = l; l1 < i1; ++l1) {
chunksection = this.sections[l1 >> 4];
if (chunksection != null) {
chunksection.c(i, l1 & 15, k, 0);
2012-07-29 09:33:13 +02:00
this.world.n((this.x << 4) + i, l1, (this.z << 4) + k);
2012-03-01 11:49:23 +01:00
}
2011-11-20 09:01:14 +01:00
}
2011-02-01 23:49:28 +01:00
}
2012-03-01 11:49:23 +01:00
l1 = 15;
while (i1 > 0 && l1 > 0) {
2011-11-20 09:01:14 +01:00
--i1;
2012-03-01 11:49:23 +01:00
i2 = this.b(i, i1, k);
if (i2 == 0) {
i2 = 1;
}
l1 -= i2;
if (l1 < 0) {
l1 = 0;
2011-11-20 09:01:14 +01:00
}
2012-03-01 11:49:23 +01:00
ChunkSection chunksection1 = this.sections[i1 >> 4];
if (chunksection1 != null) {
chunksection1.c(i, i1 & 15, k, l1);
2011-11-20 09:01:14 +01:00
}
2011-02-01 23:49:28 +01:00
}
}
2012-03-01 11:49:23 +01:00
l1 = this.heightMap[k << 4 | i];
i2 = l;
int j2 = l1;
2011-02-01 23:49:28 +01:00
2012-03-01 11:49:23 +01:00
if (l1 < l) {
i2 = l1;
j2 = l;
2011-11-20 09:01:14 +01:00
}
2012-03-01 11:49:23 +01:00
if (!this.world.worldProvider.e) {
this.d(j1 - 1, k1, i2, j2);
this.d(j1 + 1, k1, i2, j2);
this.d(j1, k1 - 1, i2, j2);
this.d(j1, k1 + 1, i2, j2);
this.d(j1, k1, i2, j2);
2011-02-01 23:49:28 +01:00
}
2012-03-01 11:49:23 +01:00
this.l = true;
2011-02-01 23:49:28 +01:00
}
}
2012-03-01 11:49:23 +01:00
public int b(int i, int j, int k) {
return Block.lightBlock[this.getTypeId(i, j, k)];
}
public int getTypeId(int i, int j, int k) {
if (j >> 4 >= this.sections.length) {
return 0;
} else {
ChunkSection chunksection = this.sections[j >> 4];
2012-03-01 11:49:23 +01:00
return chunksection != null ? chunksection.a(i, j & 15, k) : 0;
}
2012-03-01 11:49:23 +01:00
}
public int getData(int i, int j, int k) {
if (j >> 4 >= this.sections.length) {
return 0;
} else {
ChunkSection chunksection = this.sections[j >> 4];
2012-03-01 11:49:23 +01:00
return chunksection != null ? chunksection.b(i, j & 15, k) : 0;
}
2012-03-01 11:49:23 +01:00
}
public boolean a(int i, int j, int k, int l) {
return this.a(i, j, k, l, 0);
2011-02-01 23:49:28 +01:00
}
public boolean a(int i, int j, int k, int l, int i1) {
2011-09-15 02:23:52 +02:00
int j1 = k << 4 | i;
2012-03-01 11:49:23 +01:00
if (j >= this.b[j1] - 1) {
this.b[j1] = -999;
2011-09-15 02:23:52 +02:00
}
2012-03-01 11:49:23 +01:00
int k1 = this.heightMap[j1];
int l1 = this.getTypeId(i, j, k);
2012-07-29 09:33:13 +02:00
int i2 = this.getData(i, j, k);
2011-02-01 23:49:28 +01:00
2012-07-29 09:33:13 +02:00
if (l1 == l && i2 == i1) {
2011-02-01 23:49:28 +01:00
return false;
} else {
2012-03-01 11:49:23 +01:00
ChunkSection chunksection = this.sections[j >> 4];
boolean flag = false;
if (chunksection == null) {
if (l == 0) {
return false;
}
chunksection = this.sections[j >> 4] = new ChunkSection(j >> 4 << 4);
flag = j >= k1;
}
2012-07-29 09:33:13 +02:00
int j2 = this.x * 16 + i;
int k2 = this.z * 16 + k;
if (l1 != 0 && !this.world.isStatic) {
Block.byId[l1].h(this.world, j2, j, k2, i2);
}
2011-09-15 05:13:14 +02:00
2012-07-29 09:33:13 +02:00
chunksection.a(i, j & 15, k, l);
2011-11-20 09:01:14 +01:00
if (l1 != 0) {
if (!this.world.isStatic) {
2012-07-29 09:33:13 +02:00
Block.byId[l1].remove(this.world, j2, j, k2, l1, i2);
} else if (Block.byId[l1] instanceof BlockContainer && l1 != l) {
2012-07-29 09:33:13 +02:00
this.world.q(j2, j, k2);
2011-11-20 09:01:14 +01:00
}
2011-02-01 23:49:28 +01:00
}
if (chunksection.a(i, j & 15, k) != l) {
return false;
2012-03-01 11:49:23 +01:00
} else {
chunksection.b(i, j & 15, k, i1);
if (flag) {
this.initLighting();
} else {
if (Block.lightBlock[l & 4095] > 0) {
if (j >= k1) {
this.h(i, j + 1, k);
}
} else if (j == k1 - 1) {
this.h(i, j, k);
2011-02-01 23:49:28 +01:00
}
this.e(i, k);
2011-02-01 23:49:28 +01:00
}
TileEntity tileentity;
2011-02-01 23:49:28 +01:00
if (l != 0) {
if (!this.world.isStatic) {
2012-07-29 09:33:13 +02:00
Block.byId[l].onPlace(this.world, j2, j, k2);
}
2011-09-15 02:23:52 +02:00
if (Block.byId[l] instanceof BlockContainer) {
tileentity = this.e(i, j, k);
if (tileentity == null) {
2012-07-29 09:33:13 +02:00
tileentity = ((BlockContainer) Block.byId[l]).a(this.world);
this.world.setTileEntity(j2, j, k2, tileentity);
}
2011-09-15 02:23:52 +02:00
if (tileentity != null) {
tileentity.h();
}
2011-09-15 02:23:52 +02:00
}
} else if (l1 > 0 && Block.byId[l1] instanceof BlockContainer) {
tileentity = this.e(i, j, k);
2011-09-15 02:23:52 +02:00
if (tileentity != null) {
2012-03-01 11:49:23 +01:00
tileentity.h();
2011-09-15 02:23:52 +02:00
}
}
2011-02-01 23:49:28 +01:00
this.l = true;
return true;
}
2011-02-01 23:49:28 +01:00
}
}
2012-03-01 11:49:23 +01:00
public boolean b(int i, int j, int k, int l) {
ChunkSection chunksection = this.sections[j >> 4];
2011-09-15 02:23:52 +02:00
2012-03-01 11:49:23 +01:00
if (chunksection == null) {
2011-02-01 23:49:28 +01:00
return false;
} else {
2012-03-01 11:49:23 +01:00
int i1 = chunksection.b(i, j & 15, k);
2011-09-15 02:23:52 +02:00
2012-03-01 11:49:23 +01:00
if (i1 == l) {
return false;
} else {
this.l = true;
chunksection.b(i, j & 15, k, l);
int j1 = chunksection.a(i, j & 15, k);
2011-09-15 02:23:52 +02:00
2012-03-01 11:49:23 +01:00
if (j1 > 0 && Block.byId[j1] instanceof BlockContainer) {
TileEntity tileentity = this.e(i, j, k);
2011-09-15 02:23:52 +02:00
if (tileentity != null) {
2012-03-01 11:49:23 +01:00
tileentity.h();
tileentity.p = l;
2011-09-15 02:23:52 +02:00
}
}
2011-02-01 23:49:28 +01:00
2012-03-01 11:49:23 +01:00
return true;
2011-09-15 02:23:52 +02:00
}
}
2011-02-01 23:49:28 +01:00
}
2012-02-29 22:31:04 +01:00
public int getBrightness(EnumSkyBlock enumskyblock, int i, int j, int k) {
2012-03-01 11:49:23 +01:00
ChunkSection chunksection = this.sections[j >> 4];
2012-07-29 09:33:13 +02:00
return chunksection == null ? (this.d(i, j, k) ? enumskyblock.c : 0) : (enumskyblock == EnumSkyBlock.SKY ? chunksection.c(i, j & 15, k) : (enumskyblock == EnumSkyBlock.BLOCK ? chunksection.d(i, j & 15, k) : enumskyblock.c));
2011-02-01 23:49:28 +01:00
}
public void a(EnumSkyBlock enumskyblock, int i, int j, int k, int l) {
2012-03-01 11:49:23 +01:00
ChunkSection chunksection = this.sections[j >> 4];
if (chunksection == null) {
chunksection = this.sections[j >> 4] = new ChunkSection(j >> 4 << 4);
this.initLighting();
}
this.l = true;
2011-02-01 23:49:28 +01:00
if (enumskyblock == EnumSkyBlock.SKY) {
2012-03-01 11:49:23 +01:00
if (!this.world.worldProvider.e) {
chunksection.c(i, j & 15, k, l);
2011-11-20 09:01:14 +01:00
}
2012-07-29 09:33:13 +02:00
} else if (enumskyblock == EnumSkyBlock.BLOCK) {
2012-03-01 11:49:23 +01:00
chunksection.d(i, j & 15, k, l);
2011-02-01 23:49:28 +01:00
}
}
public int c(int i, int j, int k, int l) {
2012-03-01 11:49:23 +01:00
ChunkSection chunksection = this.sections[j >> 4];
2011-02-01 23:49:28 +01:00
2012-03-01 11:49:23 +01:00
if (chunksection == null) {
return !this.world.worldProvider.e && l < EnumSkyBlock.SKY.c ? EnumSkyBlock.SKY.c - l : 0;
} else {
int i1 = this.world.worldProvider.e ? 0 : chunksection.c(i, j & 15, k);
if (i1 > 0) {
a = true;
}
2011-02-01 23:49:28 +01:00
2012-03-01 11:49:23 +01:00
i1 -= l;
int j1 = chunksection.d(i, j & 15, k);
2011-02-01 23:49:28 +01:00
2012-03-01 11:49:23 +01:00
if (j1 > i1) {
i1 = j1;
}
2011-02-01 23:49:28 +01:00
2012-03-01 11:49:23 +01:00
return i1;
}
2011-02-01 23:49:28 +01:00
}
public void a(Entity entity) {
2012-03-01 11:49:23 +01:00
this.m = true;
int i = MathHelper.floor(entity.locX / 16.0D);
int j = MathHelper.floor(entity.locZ / 16.0D);
2011-02-01 23:49:28 +01:00
if (i != this.x || j != this.z) {
// CraftBukkit start
Bukkit.getLogger().warning("Wrong location for " + entity + " in world '" + world.getWorld().getName() + "'!");
// Thread.dumpStack();
Bukkit.getLogger().warning("Entity is at " + entity.locX + "," + entity.locZ + " (chunk " + i + "," + j + ") but was stored in chunk " + this.x + "," + this.z);
// CraftBukkit end
2011-02-01 23:49:28 +01:00
}
int k = MathHelper.floor(entity.locY / 16.0D);
2011-02-01 23:49:28 +01:00
if (k < 0) {
k = 0;
}
if (k >= this.entitySlices.length) {
k = this.entitySlices.length - 1;
2011-02-01 23:49:28 +01:00
}
2012-07-29 09:33:13 +02:00
entity.ag = true;
entity.ah = this.x;
entity.ai = k;
entity.aj = this.z;
this.entitySlices[k].add(entity);
2011-02-01 23:49:28 +01:00
}
public void b(Entity entity) {
2012-07-29 09:33:13 +02:00
this.a(entity, entity.ai);
2011-02-01 23:49:28 +01:00
}
public void a(Entity entity, int i) {
if (i < 0) {
i = 0;
}
if (i >= this.entitySlices.length) {
i = this.entitySlices.length - 1;
2011-02-01 23:49:28 +01:00
}
this.entitySlices[i].remove(entity);
2011-02-01 23:49:28 +01:00
}
2012-03-01 11:49:23 +01:00
public boolean d(int i, int j, int k) {
return j >= this.heightMap[k << 4 | i];
2011-02-01 23:49:28 +01:00
}
2012-03-01 11:49:23 +01:00
public TileEntity e(int i, int j, int k) {
2011-02-01 23:49:28 +01:00
ChunkPosition chunkposition = new ChunkPosition(i, j, k);
TileEntity tileentity = (TileEntity) this.tileEntities.get(chunkposition);
2011-02-01 23:49:28 +01:00
if (tileentity == null) {
int l = this.getTypeId(i, j, k);
2011-02-01 23:49:28 +01:00
2012-07-29 09:33:13 +02:00
if (l <= 0 || !Block.byId[l].s()) {
2011-02-01 23:49:28 +01:00
return null;
}
2011-09-15 02:23:52 +02:00
if (tileentity == null) {
2012-07-29 09:33:13 +02:00
tileentity = ((BlockContainer) Block.byId[l]).a(this.world);
2011-09-15 02:23:52 +02:00
this.world.setTileEntity(this.x * 16 + i, j, this.z * 16 + k, tileentity);
}
2011-02-01 23:49:28 +01:00
tileentity = (TileEntity) this.tileEntities.get(chunkposition);
2011-02-01 23:49:28 +01:00
}
2012-07-29 09:33:13 +02:00
if (tileentity != null && tileentity.p()) {
2011-06-30 00:02:25 +02:00
this.tileEntities.remove(chunkposition);
return null;
} else {
return tileentity;
}
2011-02-01 23:49:28 +01:00
}
public void a(TileEntity tileentity) {
int i = tileentity.x - this.x * 16;
int j = tileentity.y;
int k = tileentity.z - this.z * 16;
2011-02-01 23:49:28 +01:00
this.a(i, j, k, tileentity);
2012-03-01 11:49:23 +01:00
if (this.d) {
this.world.tileEntityList.add(tileentity);
2011-06-30 00:02:25 +02:00
}
2011-02-01 23:49:28 +01:00
}
public void a(int i, int j, int k, TileEntity tileentity) {
ChunkPosition chunkposition = new ChunkPosition(i, j, k);
2012-07-29 09:33:13 +02:00
tileentity.a(this.world);
tileentity.x = this.x * 16 + i;
tileentity.y = j;
tileentity.z = this.z * 16 + k;
if (this.getTypeId(i, j, k) != 0 && Block.byId[this.getTypeId(i, j, k)] instanceof BlockContainer) {
2012-07-29 09:33:13 +02:00
tileentity.q();
this.tileEntities.put(chunkposition, tileentity);
2011-11-20 09:01:14 +01:00
// CraftBukkit start
2011-02-01 23:49:28 +01:00
} else {
System.out.println("Attempted to place a tile entity (" + tileentity + ") at " + tileentity.x + "," + tileentity.y + "," + tileentity.z
+ " (" + org.bukkit.Material.getMaterial(getTypeId(i, j, k)) + ") where there was no entity tile!");
System.out.println("Chunk coordinates: " + (this.x * 16) + "," + (this.z * 16));
new Exception().printStackTrace();
// CraftBukkit end
2011-02-01 23:49:28 +01:00
}
}
2012-03-01 11:49:23 +01:00
public void f(int i, int j, int k) {
2011-02-01 23:49:28 +01:00
ChunkPosition chunkposition = new ChunkPosition(i, j, k);
2012-03-01 11:49:23 +01:00
if (this.d) {
2011-06-30 00:02:25 +02:00
TileEntity tileentity = (TileEntity) this.tileEntities.remove(chunkposition);
if (tileentity != null) {
2012-03-01 11:49:23 +01:00
tileentity.j();
2011-06-30 00:02:25 +02:00
}
2011-02-01 23:49:28 +01:00
}
}
public void addEntities() {
2012-03-01 11:49:23 +01:00
this.d = true;
2011-06-30 00:02:25 +02:00
this.world.a(this.tileEntities.values());
2012-07-29 09:33:13 +02:00
List[] alist = this.entitySlices;
int i = alist.length;
2011-02-01 23:49:28 +01:00
2012-07-29 09:33:13 +02:00
for (int j = 0; j < i; ++j) {
List list = alist[j];
this.world.a(list);
2011-02-01 23:49:28 +01:00
}
}
public void removeEntities() {
2012-03-01 11:49:23 +01:00
this.d = false;
2011-06-30 00:02:25 +02:00
Iterator iterator = this.tileEntities.values().iterator();
while (iterator.hasNext()) {
TileEntity tileentity = (TileEntity) iterator.next();
2011-09-15 02:23:52 +02:00
this.world.a(tileentity);
2011-06-30 00:02:25 +02:00
}
2012-07-29 09:33:13 +02:00
List[] alist = this.entitySlices;
int i = alist.length;
for (int j = 0; j < i; ++j) {
2011-05-14 16:29:42 +02:00
// CraftBukkit start
2012-07-29 09:33:13 +02:00
java.util.Iterator<Object> iter = this.entitySlices[j].iterator();
while (iter.hasNext()) {
Entity entity = (Entity) iter.next();
int cx = Location.locToBlock(entity.locX) >> 4;
int cz = Location.locToBlock(entity.locZ) >> 4;
2011-05-14 16:29:42 +02:00
// Do not pass along players, as doing so can get them stuck outside of time.
// (which for example disables inventory icon updates and prevents block breaking)
if (entity instanceof EntityPlayer && (cx != this.x || cz != this.z)) {
iter.remove();
}
}
2011-05-14 16:29:42 +02:00
// CraftBukkit end
2012-07-29 09:33:13 +02:00
List list = alist[j];
this.world.b(list);
2011-02-01 23:49:28 +01:00
}
}
2012-03-01 11:49:23 +01:00
public void e() {
this.l = true;
2011-02-01 23:49:28 +01:00
}
public void a(Entity entity, AxisAlignedBB axisalignedbb, List list) {
int i = MathHelper.floor((axisalignedbb.b - 2.0D) / 16.0D);
int j = MathHelper.floor((axisalignedbb.e + 2.0D) / 16.0D);
2011-02-01 23:49:28 +01:00
if (i < 0) {
i = 0;
}
if (j >= this.entitySlices.length) {
j = this.entitySlices.length - 1;
2011-02-01 23:49:28 +01:00
}
for (int k = i; k <= j; ++k) {
2012-07-29 09:33:13 +02:00
List list1 = this.entitySlices[k];
Iterator iterator = list1.iterator();
2011-02-01 23:49:28 +01:00
2012-07-29 09:33:13 +02:00
while (iterator.hasNext()) {
Entity entity1 = (Entity) iterator.next();
2011-02-01 23:49:28 +01:00
if (entity1 != entity && entity1.boundingBox.a(axisalignedbb)) {
list.add(entity1);
2012-07-29 09:33:13 +02:00
Entity[] aentity = entity1.al();
2011-11-20 09:01:14 +01:00
if (aentity != null) {
2012-07-29 09:33:13 +02:00
for (int l = 0; l < aentity.length; ++l) {
entity1 = aentity[l];
2011-11-20 09:01:14 +01:00
if (entity1 != entity && entity1.boundingBox.a(axisalignedbb)) {
list.add(entity1);
}
}
}
2011-02-01 23:49:28 +01:00
}
}
}
}
public void a(Class oclass, AxisAlignedBB axisalignedbb, List list) {
int i = MathHelper.floor((axisalignedbb.b - 2.0D) / 16.0D);
int j = MathHelper.floor((axisalignedbb.e + 2.0D) / 16.0D);
2011-02-01 23:49:28 +01:00
if (i < 0) {
i = 0;
2011-11-20 09:01:14 +01:00
} else if (i >= this.entitySlices.length) {
i = this.entitySlices.length - 1;
2011-02-01 23:49:28 +01:00
}
if (j >= this.entitySlices.length) {
j = this.entitySlices.length - 1;
2011-11-20 09:01:14 +01:00
} else if (j < 0) {
j = 0;
2011-02-01 23:49:28 +01:00
}
for (int k = i; k <= j; ++k) {
2012-07-29 09:33:13 +02:00
List list1 = this.entitySlices[k];
Iterator iterator = list1.iterator();
2011-02-01 23:49:28 +01:00
2012-07-29 09:33:13 +02:00
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
2011-02-01 23:49:28 +01:00
if (oclass.isAssignableFrom(entity.getClass()) && entity.boundingBox.a(axisalignedbb)) {
list.add(entity);
}
}
}
}
public boolean a(boolean flag) {
2012-03-01 11:49:23 +01:00
if (flag) {
if (this.m && this.world.getTime() != this.n) {
2011-02-01 23:49:28 +01:00
return true;
}
2012-03-01 11:49:23 +01:00
} else if (this.m && this.world.getTime() >= this.n + 600L) {
return true;
2011-02-01 23:49:28 +01:00
}
2012-03-01 11:49:23 +01:00
return this.l;
2011-02-01 23:49:28 +01:00
}
public Random a(long i) {
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);
2011-02-01 23:49:28 +01:00
}
2011-11-20 09:01:14 +01:00
public boolean isEmpty() {
return false;
}
2011-09-15 02:23:52 +02:00
public void a(IChunkProvider ichunkprovider, IChunkProvider ichunkprovider1, int i, int j) {
if (!this.done && ichunkprovider.isChunkLoaded(i + 1, j + 1) && ichunkprovider.isChunkLoaded(i, j + 1) && ichunkprovider.isChunkLoaded(i + 1, j)) {
ichunkprovider.getChunkAt(ichunkprovider1, i, j);
}
if (ichunkprovider.isChunkLoaded(i - 1, j) && !ichunkprovider.getOrCreateChunk(i - 1, j).done && ichunkprovider.isChunkLoaded(i - 1, j + 1) && ichunkprovider.isChunkLoaded(i, j + 1) && ichunkprovider.isChunkLoaded(i - 1, j + 1)) {
ichunkprovider.getChunkAt(ichunkprovider1, i - 1, j);
}
if (ichunkprovider.isChunkLoaded(i, j - 1) && !ichunkprovider.getOrCreateChunk(i, j - 1).done && ichunkprovider.isChunkLoaded(i + 1, j - 1) && ichunkprovider.isChunkLoaded(i + 1, j - 1) && ichunkprovider.isChunkLoaded(i + 1, j)) {
ichunkprovider.getChunkAt(ichunkprovider1, i, j - 1);
}
if (ichunkprovider.isChunkLoaded(i - 1, j - 1) && !ichunkprovider.getOrCreateChunk(i - 1, j - 1).done && ichunkprovider.isChunkLoaded(i, j - 1) && ichunkprovider.isChunkLoaded(i - 1, j)) {
ichunkprovider.getChunkAt(ichunkprovider1, i - 1, j - 1);
}
}
2012-03-01 11:49:23 +01:00
public int d(int i, int j) {
2011-09-15 02:23:52 +02:00
int k = i | j << 4;
2012-03-01 11:49:23 +01:00
int l = this.b[k];
2011-09-15 02:23:52 +02:00
if (l == -999) {
2012-07-29 09:33:13 +02:00
int i1 = this.h() + 15;
2011-09-15 02:23:52 +02:00
l = -1;
while (i1 > 0 && l == -1) {
int j1 = this.getTypeId(i, i1, j);
Material material = j1 == 0 ? Material.AIR : Block.byId[j1].material;
if (!material.isSolid() && !material.isLiquid()) {
--i1;
} else {
l = i1 + 1;
}
}
2012-03-01 11:49:23 +01:00
this.b[k] = l;
2011-09-15 02:23:52 +02:00
}
return l;
2011-02-01 23:49:28 +01:00
}
2011-03-31 22:40:00 +02:00
2012-07-29 09:33:13 +02:00
public void k() {
if (this.s && !this.world.worldProvider.e) {
2012-07-29 09:33:13 +02:00
this.q();
2011-11-20 09:01:14 +01:00
}
}
2012-07-29 09:33:13 +02:00
public ChunkCoordIntPair l() {
2011-11-20 09:01:14 +01:00
return new ChunkCoordIntPair(this.x, this.z);
2011-03-31 22:40:00 +02:00
}
2012-03-01 11:49:23 +01:00
public boolean c(int i, int j) {
if (i < 0) {
i = 0;
}
if (j >= 256) {
j = 255;
}
for (int k = i; k <= j; k += 16) {
ChunkSection chunksection = this.sections[k >> 4];
if (chunksection != null && !chunksection.a()) {
return false;
}
}
return true;
}
public void a(ChunkSection[] achunksection) {
this.sections = achunksection;
}
public BiomeBase a(int i, int j, WorldChunkManager worldchunkmanager) {
int k = this.r[j << 4 | i] & 255;
2012-03-01 11:49:23 +01:00
if (k == 255) {
BiomeBase biomebase = worldchunkmanager.getBiome((this.x << 4) + i, (this.z << 4) + j);
k = biomebase.id;
this.r[j << 4 | i] = (byte) (k & 255);
2012-03-01 11:49:23 +01:00
}
return BiomeBase.biomes[k] == null ? BiomeBase.PLAINS : BiomeBase.biomes[k];
}
2012-07-29 09:33:13 +02:00
public byte[] m() {
return this.r;
2012-03-01 11:49:23 +01:00
}
public void a(byte[] abyte) {
this.r = abyte;
2012-03-01 11:49:23 +01:00
}
2012-07-29 09:33:13 +02:00
public void n() {
this.t = 0;
2012-03-01 11:49:23 +01:00
}
2012-07-29 09:33:13 +02:00
public void o() {
2012-03-01 11:49:23 +01:00
for (int i = 0; i < 8; ++i) {
if (this.t >= 4096) {
2012-03-01 11:49:23 +01:00
return;
}
int j = this.t % 16;
int k = this.t / 16 % 16;
int l = this.t / 256;
2012-03-01 11:49:23 +01:00
++this.t;
2012-03-01 11:49:23 +01:00
int i1 = (this.x << 4) + k;
int j1 = (this.z << 4) + l;
for (int k1 = 0; k1 < 16; ++k1) {
int l1 = (j << 4) + k1;
if (this.sections[j] == null && (k1 == 0 || k1 == 15 || k == 0 || k == 15 || l == 0 || l == 15) || this.sections[j] != null && this.sections[j].a(k, k1, l) == 0) {
if (Block.lightEmission[this.world.getTypeId(i1, l1 - 1, j1)] > 0) {
2012-07-29 09:33:13 +02:00
this.world.x(i1, l1 - 1, j1);
2012-03-01 11:49:23 +01:00
}
if (Block.lightEmission[this.world.getTypeId(i1, l1 + 1, j1)] > 0) {
2012-07-29 09:33:13 +02:00
this.world.x(i1, l1 + 1, j1);
2012-03-01 11:49:23 +01:00
}
if (Block.lightEmission[this.world.getTypeId(i1 - 1, l1, j1)] > 0) {
2012-07-29 09:33:13 +02:00
this.world.x(i1 - 1, l1, j1);
2012-03-01 11:49:23 +01:00
}
if (Block.lightEmission[this.world.getTypeId(i1 + 1, l1, j1)] > 0) {
2012-07-29 09:33:13 +02:00
this.world.x(i1 + 1, l1, j1);
2012-03-01 11:49:23 +01:00
}
if (Block.lightEmission[this.world.getTypeId(i1, l1, j1 - 1)] > 0) {
2012-07-29 09:33:13 +02:00
this.world.x(i1, l1, j1 - 1);
2012-03-01 11:49:23 +01:00
}
if (Block.lightEmission[this.world.getTypeId(i1, l1, j1 + 1)] > 0) {
2012-07-29 09:33:13 +02:00
this.world.x(i1, l1, j1 + 1);
2012-03-01 11:49:23 +01:00
}
2012-07-29 09:33:13 +02:00
this.world.x(i1, l1, j1);
2012-03-01 11:49:23 +01:00
}
}
}
}
2011-02-01 23:49:28 +01:00
}