Update chunk handling.
Dieser Commit ist enthalten in:
Ursprung
21b8ef4435
Commit
1dac92a766
636
src/main/java/net/minecraft/server/Chunk.java
Normale Datei
636
src/main/java/net/minecraft/server/Chunk.java
Normale Datei
@ -0,0 +1,636 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class Chunk {
|
||||
|
||||
public static boolean a;
|
||||
public byte[] b;
|
||||
public boolean c;
|
||||
public World d;
|
||||
public NibbleArray e;
|
||||
public NibbleArray f;
|
||||
public NibbleArray g;
|
||||
public byte[] h;
|
||||
public int i;
|
||||
public final int j;
|
||||
public final int k;
|
||||
public Map l;
|
||||
public List[] m;
|
||||
public boolean n;
|
||||
public boolean o;
|
||||
public boolean p;
|
||||
public boolean q;
|
||||
public long r;
|
||||
|
||||
public Chunk(World world, int i, int j) {
|
||||
this.l = new HashMap();
|
||||
this.m = new List[8];
|
||||
this.n = false;
|
||||
this.o = false;
|
||||
this.q = false;
|
||||
this.r = 0L;
|
||||
this.d = world;
|
||||
this.j = i;
|
||||
this.k = j;
|
||||
this.h = new byte[256];
|
||||
|
||||
for (int k = 0; k < this.m.length; ++k) {
|
||||
this.m[k] = new ArrayList();
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
bukkitChunk = new org.bukkit.craftbukkit.CraftChunk( this );
|
||||
}
|
||||
|
||||
public org.bukkit.Chunk bukkitChunk;
|
||||
// CraftBukkit end
|
||||
|
||||
public Chunk(World world, byte[] abyte, int i, int j) {
|
||||
this(world, i, j);
|
||||
this.b = abyte;
|
||||
this.e = new NibbleArray(abyte.length);
|
||||
this.f = new NibbleArray(abyte.length);
|
||||
this.g = new NibbleArray(abyte.length);
|
||||
}
|
||||
|
||||
public boolean a(int i, int j) {
|
||||
return i == this.j && j == this.k;
|
||||
}
|
||||
|
||||
public int b(int i, int j) {
|
||||
return this.h[j << 4 | i] & 255;
|
||||
}
|
||||
|
||||
public void a() {}
|
||||
|
||||
public void b() {
|
||||
int i = 127;
|
||||
|
||||
int j;
|
||||
int k;
|
||||
|
||||
for (j = 0; j < 16; ++j) {
|
||||
for (k = 0; k < 16; ++k) {
|
||||
int l = 127;
|
||||
|
||||
int i1;
|
||||
|
||||
for (i1 = j << 11 | k << 7; l > 0 && Block.q[this.b[i1 + l - 1]] == 0; --l) {
|
||||
;
|
||||
}
|
||||
|
||||
this.h[k << 4 | j] = (byte) l;
|
||||
if (l < i) {
|
||||
i = l;
|
||||
}
|
||||
|
||||
if (!this.d.q.e) {
|
||||
int j1 = 15;
|
||||
int k1 = 127;
|
||||
|
||||
do {
|
||||
j1 -= Block.q[this.b[i1 + k1]];
|
||||
if (j1 > 0) {
|
||||
this.f.a(j, k1, k, j1);
|
||||
}
|
||||
|
||||
--k1;
|
||||
} while (k1 > 0 && j1 > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.i = i;
|
||||
|
||||
for (j = 0; j < 16; ++j) {
|
||||
for (k = 0; k < 16; ++k) {
|
||||
this.c(j, k);
|
||||
}
|
||||
}
|
||||
|
||||
this.o = true;
|
||||
}
|
||||
|
||||
public void c() {
|
||||
byte b0 = 32;
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
int k = i << 11 | j << 7;
|
||||
|
||||
int l;
|
||||
int i1;
|
||||
|
||||
for (l = 0; l < 128; ++l) {
|
||||
i1 = Block.s[this.b[k + l]];
|
||||
if (i1 > 0) {
|
||||
this.g.a(i, l, j, i1);
|
||||
}
|
||||
}
|
||||
|
||||
l = 15;
|
||||
|
||||
for (i1 = b0 - 2; i1 < 128 && l > 0; this.g.a(i, i1, j, l)) {
|
||||
++i1;
|
||||
byte b1 = this.b[k + i1];
|
||||
int j1 = Block.q[b1];
|
||||
int k1 = Block.s[b1];
|
||||
|
||||
if (j1 == 0) {
|
||||
j1 = 1;
|
||||
}
|
||||
|
||||
l -= j1;
|
||||
if (k1 > l) {
|
||||
l = k1;
|
||||
}
|
||||
|
||||
if (l < 0) {
|
||||
l = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.d.a(EnumSkyBlock.BLOCK, this.j * 16, b0 - 1, this.k * 16, this.j * 16 + 16, b0 + 1, this.k * 16 + 16);
|
||||
this.o = true;
|
||||
}
|
||||
|
||||
private void c(int i, int j) {
|
||||
int k = this.b(i, j);
|
||||
int l = this.j * 16 + i;
|
||||
int i1 = this.k * 16 + j;
|
||||
|
||||
this.f(l - 1, i1, k);
|
||||
this.f(l + 1, i1, k);
|
||||
this.f(l, i1 - 1, k);
|
||||
this.f(l, i1 + 1, k);
|
||||
}
|
||||
|
||||
private void f(int i, int j, int k) {
|
||||
int l = this.d.d(i, j);
|
||||
|
||||
if (l > k) {
|
||||
this.d.a(EnumSkyBlock.SKY, i, k, j, i, l, j);
|
||||
this.o = true;
|
||||
} else if (l < k) {
|
||||
this.d.a(EnumSkyBlock.SKY, i, l, j, i, k, j);
|
||||
this.o = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void g(int i, int j, int k) {
|
||||
int l = this.h[k << 4 | i] & 255;
|
||||
int i1 = l;
|
||||
|
||||
if (j > l) {
|
||||
i1 = j;
|
||||
}
|
||||
|
||||
for (int j1 = i << 11 | k << 7; i1 > 0 && Block.q[this.b[j1 + i1 - 1]] == 0; --i1) {
|
||||
;
|
||||
}
|
||||
|
||||
if (i1 != l) {
|
||||
this.d.g(i, k, i1, l);
|
||||
this.h[k << 4 | i] = (byte) i1;
|
||||
int k1;
|
||||
int l1;
|
||||
int i2;
|
||||
|
||||
if (i1 < this.i) {
|
||||
this.i = i1;
|
||||
} else {
|
||||
k1 = 127;
|
||||
|
||||
for (l1 = 0; l1 < 16; ++l1) {
|
||||
for (i2 = 0; i2 < 16; ++i2) {
|
||||
if ((this.h[i2 << 4 | l1] & 255) < k1) {
|
||||
k1 = this.h[i2 << 4 | l1] & 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.i = k1;
|
||||
}
|
||||
|
||||
k1 = this.j * 16 + i;
|
||||
l1 = this.k * 16 + k;
|
||||
if (i1 < l) {
|
||||
for (i2 = i1; i2 < l; ++i2) {
|
||||
this.f.a(i, i2, k, 15);
|
||||
}
|
||||
} else {
|
||||
this.d.a(EnumSkyBlock.SKY, k1, l, l1, k1, i1, l1);
|
||||
|
||||
for (i2 = l; i2 < i1; ++i2) {
|
||||
this.f.a(i, i2, k, 0);
|
||||
}
|
||||
}
|
||||
|
||||
i2 = 15;
|
||||
|
||||
int j2;
|
||||
|
||||
for (j2 = i1; i1 > 0 && i2 > 0; this.f.a(i, i1, k, i2)) {
|
||||
--i1;
|
||||
int k2 = Block.q[this.a(i, i1, k)];
|
||||
|
||||
if (k2 == 0) {
|
||||
k2 = 1;
|
||||
}
|
||||
|
||||
i2 -= k2;
|
||||
if (i2 < 0) {
|
||||
i2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (i1 > 0 && Block.q[this.a(i, i1 - 1, k)] == 0) {
|
||||
--i1;
|
||||
}
|
||||
|
||||
if (i1 != j2) {
|
||||
this.d.a(EnumSkyBlock.SKY, k1 - 1, i1, l1 - 1, k1 + 1, j2, l1 + 1);
|
||||
}
|
||||
|
||||
this.o = true;
|
||||
}
|
||||
}
|
||||
|
||||
public int a(int i, int j, int k) {
|
||||
return this.b[i << 11 | k << 7 | j];
|
||||
}
|
||||
|
||||
public boolean a(int i, int j, int k, int l, int i1) {
|
||||
byte b0 = (byte) l;
|
||||
int j1 = this.h[k << 4 | i] & 255;
|
||||
int k1 = this.b[i << 11 | k << 7 | j] & 255;
|
||||
|
||||
if (k1 == l && this.e.a(i, j, k) == i1) {
|
||||
return false;
|
||||
} else {
|
||||
int l1 = this.j * 16 + i;
|
||||
int i2 = this.k * 16 + k;
|
||||
|
||||
this.b[i << 11 | k << 7 | j] = b0;
|
||||
if (k1 != 0 && !this.d.isStatic) {
|
||||
Block.byId[k1].b(this.d, l1, j, i2);
|
||||
}
|
||||
|
||||
this.e.a(i, j, k, i1);
|
||||
if (!this.d.q.e) {
|
||||
if (Block.q[b0] != 0) {
|
||||
if (j >= j1) {
|
||||
this.g(i, j + 1, k);
|
||||
}
|
||||
} else if (j == j1 - 1) {
|
||||
this.g(i, j, k);
|
||||
}
|
||||
|
||||
this.d.a(EnumSkyBlock.SKY, l1, j, i2, l1, j, i2);
|
||||
}
|
||||
|
||||
this.d.a(EnumSkyBlock.BLOCK, l1, j, i2, l1, j, i2);
|
||||
this.c(i, k);
|
||||
this.e.a(i, j, k, i1);
|
||||
if (l != 0) {
|
||||
Block.byId[l].e(this.d, l1, j, i2);
|
||||
}
|
||||
|
||||
this.o = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean a(int i, int j, int k, int l) {
|
||||
byte b0 = (byte) l;
|
||||
int i1 = this.h[k << 4 | i] & 255;
|
||||
int j1 = this.b[i << 11 | k << 7 | j] & 255;
|
||||
|
||||
if (j1 == l) {
|
||||
return false;
|
||||
} else {
|
||||
int k1 = this.j * 16 + i;
|
||||
int l1 = this.k * 16 + k;
|
||||
|
||||
this.b[i << 11 | k << 7 | j] = b0;
|
||||
if (j1 != 0) {
|
||||
Block.byId[j1].b(this.d, k1, j, l1);
|
||||
}
|
||||
|
||||
this.e.a(i, j, k, 0);
|
||||
if (Block.q[b0] != 0) {
|
||||
if (j >= i1) {
|
||||
this.g(i, j + 1, k);
|
||||
}
|
||||
} else if (j == i1 - 1) {
|
||||
this.g(i, j, k);
|
||||
}
|
||||
|
||||
this.d.a(EnumSkyBlock.SKY, k1, j, l1, k1, j, l1);
|
||||
this.d.a(EnumSkyBlock.BLOCK, k1, j, l1, k1, j, l1);
|
||||
this.c(i, k);
|
||||
if (l != 0 && !this.d.isStatic) {
|
||||
Block.byId[l].e(this.d, k1, j, l1);
|
||||
}
|
||||
|
||||
this.o = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public int b(int i, int j, int k) {
|
||||
return this.e.a(i, j, k);
|
||||
}
|
||||
|
||||
public void b(int i, int j, int k, int l) {
|
||||
this.o = true;
|
||||
this.e.a(i, j, k, l);
|
||||
}
|
||||
|
||||
public int a(EnumSkyBlock enumskyblock, int i, int j, int k) {
|
||||
return enumskyblock == EnumSkyBlock.SKY ? this.f.a(i, j, k) : (enumskyblock == EnumSkyBlock.BLOCK ? this.g.a(i, j, k) : 0);
|
||||
}
|
||||
|
||||
public void a(EnumSkyBlock enumskyblock, int i, int j, int k, int l) {
|
||||
this.o = true;
|
||||
if (enumskyblock == EnumSkyBlock.SKY) {
|
||||
this.f.a(i, j, k, l);
|
||||
} else {
|
||||
if (enumskyblock != EnumSkyBlock.BLOCK) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.g.a(i, j, k, l);
|
||||
}
|
||||
}
|
||||
|
||||
public int c(int i, int j, int k, int l) {
|
||||
int i1 = this.f.a(i, j, k);
|
||||
|
||||
if (i1 > 0) {
|
||||
a = true;
|
||||
}
|
||||
|
||||
i1 -= l;
|
||||
int j1 = this.g.a(i, j, k);
|
||||
|
||||
if (j1 > i1) {
|
||||
i1 = j1;
|
||||
}
|
||||
|
||||
return i1;
|
||||
}
|
||||
|
||||
public void a(Entity entity) {
|
||||
this.q = true;
|
||||
int i = MathHelper.b(entity.locX / 16.0D);
|
||||
int j = MathHelper.b(entity.locZ / 16.0D);
|
||||
|
||||
if (i != this.j || j != this.k) {
|
||||
System.out.println("Wrong location! " + entity);
|
||||
Thread.dumpStack();
|
||||
}
|
||||
|
||||
int k = MathHelper.b(entity.locY / 16.0D);
|
||||
|
||||
if (k < 0) {
|
||||
k = 0;
|
||||
}
|
||||
|
||||
if (k >= this.m.length) {
|
||||
k = this.m.length - 1;
|
||||
}
|
||||
|
||||
entity.ag = true;
|
||||
entity.chunkX = this.j;
|
||||
entity.ai = k;
|
||||
entity.chunkZ = this.k;
|
||||
this.m[k].add(entity);
|
||||
}
|
||||
|
||||
public void b(Entity entity) {
|
||||
this.a(entity, entity.ai);
|
||||
}
|
||||
|
||||
public void a(Entity entity, int i) {
|
||||
if (i < 0) {
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (i >= this.m.length) {
|
||||
i = this.m.length - 1;
|
||||
}
|
||||
|
||||
this.m[i].remove(entity);
|
||||
}
|
||||
|
||||
public boolean c(int i, int j, int k) {
|
||||
return j >= (this.h[k << 4 | i] & 255);
|
||||
}
|
||||
|
||||
public TileEntity d(int i, int j, int k) {
|
||||
ChunkPosition chunkposition = new ChunkPosition(i, j, k);
|
||||
TileEntity tileentity = (TileEntity) this.l.get(chunkposition);
|
||||
|
||||
if (tileentity == null) {
|
||||
int l = this.a(i, j, k);
|
||||
|
||||
if (!Block.p[l]) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BlockContainer blockcontainer = (BlockContainer) Block.byId[l];
|
||||
|
||||
blockcontainer.e(this.d, this.j * 16 + i, j, this.k * 16 + k);
|
||||
tileentity = (TileEntity) this.l.get(chunkposition);
|
||||
}
|
||||
|
||||
return tileentity;
|
||||
}
|
||||
|
||||
public void a(TileEntity tileentity) {
|
||||
int i = tileentity.b - this.j * 16;
|
||||
int j = tileentity.c;
|
||||
int k = tileentity.d - this.k * 16;
|
||||
|
||||
this.a(i, j, k, tileentity);
|
||||
}
|
||||
|
||||
public void a(int i, int j, int k, TileEntity tileentity) {
|
||||
ChunkPosition chunkposition = new ChunkPosition(i, j, k);
|
||||
|
||||
tileentity.a = this.d;
|
||||
tileentity.b = this.j * 16 + i;
|
||||
tileentity.c = j;
|
||||
tileentity.d = this.k * 16 + k;
|
||||
if (this.a(i, j, k) != 0 && Block.byId[this.a(i, j, k)] instanceof BlockContainer) {
|
||||
if (this.c) {
|
||||
if (this.l.get(chunkposition) != null) {
|
||||
this.d.c.remove(this.l.get(chunkposition));
|
||||
}
|
||||
|
||||
this.d.c.add(tileentity);
|
||||
}
|
||||
|
||||
this.l.put(chunkposition, tileentity);
|
||||
} else {
|
||||
System.out.println("Attempted to place a tile entity where there was no entity tile!");
|
||||
}
|
||||
}
|
||||
|
||||
public void e(int i, int j, int k) {
|
||||
ChunkPosition chunkposition = new ChunkPosition(i, j, k);
|
||||
|
||||
if (this.c) {
|
||||
this.d.c.remove(this.l.remove(chunkposition));
|
||||
}
|
||||
}
|
||||
|
||||
public void d() {
|
||||
this.c = true;
|
||||
this.d.c.addAll(this.l.values());
|
||||
|
||||
for (int i = 0; i < this.m.length; ++i) {
|
||||
this.d.a(this.m[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void e() {
|
||||
this.c = false;
|
||||
this.d.c.removeAll(this.l.values());
|
||||
|
||||
for (int i = 0; i < this.m.length; ++i) {
|
||||
this.d.b(this.m[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void f() {
|
||||
this.o = true;
|
||||
}
|
||||
|
||||
public void a(Entity entity, AxisAlignedBB axisalignedbb, List list) {
|
||||
int i = MathHelper.b((axisalignedbb.b - 2.0D) / 16.0D);
|
||||
int j = MathHelper.b((axisalignedbb.e + 2.0D) / 16.0D);
|
||||
|
||||
if (i < 0) {
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (j >= this.m.length) {
|
||||
j = this.m.length - 1;
|
||||
}
|
||||
|
||||
for (int k = i; k <= j; ++k) {
|
||||
List list1 = this.m[k];
|
||||
|
||||
for (int l = 0; l < list1.size(); ++l) {
|
||||
Entity entity1 = (Entity) list1.get(l);
|
||||
|
||||
if (entity1 != entity && entity1.boundingBox.a(axisalignedbb)) {
|
||||
list.add(entity1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void a(Class oclass, AxisAlignedBB axisalignedbb, List list) {
|
||||
int i = MathHelper.b((axisalignedbb.b - 2.0D) / 16.0D);
|
||||
int j = MathHelper.b((axisalignedbb.e + 2.0D) / 16.0D);
|
||||
|
||||
if (i < 0) {
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (j >= this.m.length) {
|
||||
j = this.m.length - 1;
|
||||
}
|
||||
|
||||
for (int k = i; k <= j; ++k) {
|
||||
List list1 = this.m[k];
|
||||
|
||||
for (int l = 0; l < list1.size(); ++l) {
|
||||
Entity entity = (Entity) list1.get(l);
|
||||
|
||||
if (oclass.isAssignableFrom(entity.getClass()) && entity.boundingBox.a(axisalignedbb)) {
|
||||
list.add(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean a(boolean flag) {
|
||||
if (this.p) {
|
||||
return false;
|
||||
} else {
|
||||
if (flag) {
|
||||
if (this.q && this.d.e != this.r) {
|
||||
return true;
|
||||
}
|
||||
} else if (this.q && this.d.e >= this.r + 600L) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.o;
|
||||
}
|
||||
}
|
||||
|
||||
public int a(byte[] abyte, int i, int j, int k, int l, int i1, int j1, int k1) {
|
||||
int l1;
|
||||
int i2;
|
||||
int j2;
|
||||
int k2;
|
||||
|
||||
for (l1 = i; l1 < l; ++l1) {
|
||||
for (i2 = k; i2 < j1; ++i2) {
|
||||
j2 = l1 << 11 | i2 << 7 | j;
|
||||
k2 = i1 - j;
|
||||
System.arraycopy(this.b, j2, abyte, k1, k2);
|
||||
k1 += k2;
|
||||
}
|
||||
}
|
||||
|
||||
for (l1 = i; l1 < l; ++l1) {
|
||||
for (i2 = k; i2 < j1; ++i2) {
|
||||
j2 = (l1 << 11 | i2 << 7 | j) >> 1;
|
||||
k2 = (i1 - j) / 2;
|
||||
System.arraycopy(this.e.a, j2, abyte, k1, k2);
|
||||
k1 += k2;
|
||||
}
|
||||
}
|
||||
|
||||
for (l1 = i; l1 < l; ++l1) {
|
||||
for (i2 = k; i2 < j1; ++i2) {
|
||||
j2 = (l1 << 11 | i2 << 7 | j) >> 1;
|
||||
k2 = (i1 - j) / 2;
|
||||
System.arraycopy(this.g.a, j2, abyte, k1, k2);
|
||||
k1 += k2;
|
||||
}
|
||||
}
|
||||
|
||||
for (l1 = i; l1 < l; ++l1) {
|
||||
for (i2 = k; i2 < j1; ++i2) {
|
||||
j2 = (l1 << 11 | i2 << 7 | j) >> 1;
|
||||
k2 = (i1 - j) / 2;
|
||||
System.arraycopy(this.f.a, j2, abyte, k1, k2);
|
||||
k1 += k2;
|
||||
}
|
||||
}
|
||||
|
||||
return k1;
|
||||
}
|
||||
|
||||
public Random a(long i) {
|
||||
return new Random(this.d.u + (long) (this.j * this.j * 4987142) + (long) (this.j * 5947611) + (long) (this.k * this.k) * 4392871L + (long) (this.k * 389711) ^ i);
|
||||
}
|
||||
|
||||
public boolean g() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -80,9 +80,7 @@ public class ChunkProviderServer implements IChunkProvider {
|
||||
* the World constructor. We can't reliably alter that, so we have
|
||||
* no way of creating a CraftWorld/CraftServer at that point.
|
||||
*/
|
||||
CraftWorld world = g.getWorld();
|
||||
CraftChunk cchunk = world.updateChunk(i, j);
|
||||
server.getPluginManager().callEvent(new ChunkLoadEvent(Type.CHUNK_LOADED, cchunk));
|
||||
server.getPluginManager().callEvent(new ChunkLoadEvent(Type.CHUNK_LOADED, chunk.bukkitChunk));
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
|
@ -35,35 +35,6 @@ public class WorldServer extends World implements BlockChangeDelegate {
|
||||
private final CraftWorld world;
|
||||
private final CraftServer server;
|
||||
|
||||
/**
|
||||
* setData
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param data (actually a byte!)
|
||||
*/
|
||||
@Override
|
||||
public boolean d(int x, int y, int z, int data) {
|
||||
boolean result = super.d(x, y, z, data);
|
||||
if ((result) && (world != null)) world.updateBlock(x, y, z, null, data);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTypeId(int x, int y, int z, int type) {
|
||||
boolean result = super.setTypeId(x, y, z, type);
|
||||
if ((result) && (world != null)) world.updateBlock(x, y, z, type, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTypeIdAndData(int x, int y, int z, int type, int data) {
|
||||
boolean result = super.setTypeIdAndData(x, y, z, type, data);
|
||||
if ((result) && (world != null)) world.updateBlock(x, y, z, type, data);
|
||||
return result;
|
||||
}
|
||||
|
||||
public CraftWorld getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
@ -1,49 +1,51 @@
|
||||
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import net.minecraft.server.WorldServer;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.block.CraftBlock;
|
||||
|
||||
public class CraftChunk implements Chunk {
|
||||
private final CraftWorld world;
|
||||
private final int x;
|
||||
private final int z;
|
||||
private final net.minecraft.server.Chunk chunk;
|
||||
private final HashMap<Integer, Block> cache = new HashMap<Integer, Block>();
|
||||
|
||||
protected CraftChunk(final CraftWorld world, final int x, final int z) {
|
||||
this.world = world;
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
public CraftChunk(net.minecraft.server.Chunk chunk) {
|
||||
this.chunk = chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world containing this chunk
|
||||
*
|
||||
* @return World
|
||||
*/
|
||||
public World getWorld() {
|
||||
return world;
|
||||
return ((WorldServer) chunk.d).getWorld();
|
||||
}
|
||||
|
||||
public net.minecraft.server.Chunk getHandle() {
|
||||
return chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the X-coordinate of this chunk
|
||||
*
|
||||
* @return X-coordinate
|
||||
*/
|
||||
public int getX() {
|
||||
return x;
|
||||
return chunk.j;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Z-coordinate of this chunk
|
||||
*
|
||||
* @return Z-coordinate
|
||||
*/
|
||||
public int getZ() {
|
||||
return z;
|
||||
return chunk.k;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftChunk{" + "x=" + x + "z=" + z + '}';
|
||||
return "CraftChunk{" + "x=" + getX() + "z=" + getZ() + '}';
|
||||
}
|
||||
|
||||
public Block getBlock(int x, int y, int z) {
|
||||
int pos = (x & 0xF) << 11 | (z & 0xF) << 7 | (y & 0x7F);
|
||||
Block block = this.cache.get( pos );
|
||||
if (block == null) {
|
||||
block = new CraftBlock( this, (getX() << 4) | (x & 0xF), y & 0x7F, (getZ() << 4) | (z & 0xF) );
|
||||
this.cache.put( pos, block );
|
||||
}
|
||||
return block;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import org.bukkit.craftbukkit.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.entity.*;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.entity.Entity;
|
||||
@ -24,8 +23,6 @@ import org.bukkit.TreeType;
|
||||
import org.bukkit.World;
|
||||
|
||||
public class CraftWorld implements World {
|
||||
private final Map<ChunkCoordinate, CraftChunk> chunkCache = new HashMap<ChunkCoordinate, CraftChunk>();
|
||||
private final Map<BlockCoordinate, CraftBlock> blockCache = new HashMap<BlockCoordinate, CraftBlock>();
|
||||
private final WorldServer world;
|
||||
|
||||
private static final Random rand = new Random();
|
||||
@ -35,17 +32,7 @@ public class CraftWorld implements World {
|
||||
}
|
||||
|
||||
public Block getBlockAt(int x, int y, int z) {
|
||||
BlockCoordinate loc = new BlockCoordinate(x, y, z);
|
||||
CraftBlock block = blockCache.get(loc);
|
||||
|
||||
if (block == null) {
|
||||
block = new CraftBlock(this, x, y, z, world.getTypeId(x, y, z), (byte)world.getData(x, y, z));
|
||||
blockCache.put(loc, block);
|
||||
} else {
|
||||
block.update();
|
||||
}
|
||||
|
||||
return block;
|
||||
return getChunkAt(x >> 4, z >> 4).getBlock(x & 0xF, y & 0x7F, z & 0xF);
|
||||
}
|
||||
|
||||
public int getBlockTypeIdAt(int x, int y, int z) {
|
||||
@ -61,66 +48,34 @@ public class CraftWorld implements World {
|
||||
}
|
||||
|
||||
public Chunk getChunkAt(int x, int z) {
|
||||
ChunkCoordinate loc = new ChunkCoordinate(x, z);
|
||||
CraftChunk chunk = chunkCache.get(loc);
|
||||
|
||||
if (chunk == null) {
|
||||
chunk = new CraftChunk(this, x, z);
|
||||
chunkCache.put(loc, chunk);
|
||||
}
|
||||
|
||||
return chunk;
|
||||
return this.world.A.d(x,z).bukkitChunk;
|
||||
}
|
||||
|
||||
public Chunk getChunkAt(Block block) {
|
||||
return getChunkAt(block.getX() >> 4, block.getZ() >> 4);
|
||||
}
|
||||
|
||||
public boolean isChunkLoaded(int x, int z) {
|
||||
return world.A.a( x, z );
|
||||
}
|
||||
|
||||
public void loadChunk(int x, int z) {
|
||||
world.A.d(x, z);
|
||||
}
|
||||
|
||||
public boolean isChunkLoaded(Chunk chunk) {
|
||||
return world.A.a(chunk.getX(), chunk.getZ());
|
||||
return isChunkLoaded(chunk.getX(), chunk.getZ());
|
||||
}
|
||||
|
||||
public void loadChunk(Chunk chunk) {
|
||||
world.A.d(chunk.getX(), chunk.getZ());
|
||||
}
|
||||
|
||||
|
||||
public void updateBlock(int x, int y, int z, Integer type, Integer data) {
|
||||
BlockCoordinate loc = new BlockCoordinate(x, y, z);
|
||||
CraftBlock block = (CraftBlock) blockCache.get(loc);
|
||||
|
||||
if (block == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == null) {
|
||||
type = world.getTypeId(x, y, z);
|
||||
}
|
||||
if (data == null) {
|
||||
data = world.getData(x, y, z);
|
||||
}
|
||||
|
||||
block.update(type, data.byteValue());
|
||||
}
|
||||
|
||||
public CraftChunk updateChunk(int x, int z) {
|
||||
ChunkCoordinate loc = new ChunkCoordinate(x, z);
|
||||
CraftChunk chunk = chunkCache.get(loc);
|
||||
|
||||
if (chunk == null) {
|
||||
chunk = new CraftChunk(this, x, z);
|
||||
chunkCache.put(loc, chunk);
|
||||
} else {
|
||||
// TODO: Chunk stuff
|
||||
}
|
||||
|
||||
return chunk;
|
||||
loadChunk(chunk.getX(), chunk.getZ());
|
||||
((CraftChunk) getChunkAt(chunk.getX(), chunk.getZ())).getHandle().bukkitChunk = chunk;
|
||||
}
|
||||
|
||||
public WorldServer getHandle() {
|
||||
return world;
|
||||
}
|
||||
|
||||
|
||||
public ItemDrop dropItem(Location loc, ItemStack item) {
|
||||
net.minecraft.server.ItemStack stack = new net.minecraft.server.ItemStack(
|
||||
item.getTypeId(),
|
||||
@ -299,48 +254,6 @@ public class CraftWorld implements World {
|
||||
}
|
||||
}
|
||||
|
||||
private final class BlockCoordinate {
|
||||
public final int x;
|
||||
public final int y;
|
||||
public final int z;
|
||||
|
||||
public BlockCoordinate(final int x, final int y, final int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final BlockCoordinate other = (BlockCoordinate) obj;
|
||||
if (this.x != other.x) {
|
||||
return false;
|
||||
}
|
||||
if (this.y != other.y) {
|
||||
return false;
|
||||
}
|
||||
if (this.z != other.z) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 37 * hash + this.x;
|
||||
hash = 37 * hash + this.y;
|
||||
hash = 37 * hash + this.z;
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Entity> getEntities() {
|
||||
List<Entity> list = new ArrayList<Entity>();
|
||||
|
||||
|
@ -10,41 +10,20 @@ import net.minecraft.server.BiomeBase;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.craftbukkit.CraftChunk;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockState;
|
||||
import org.bukkit.craftbukkit.block.CraftSign;
|
||||
|
||||
public class CraftBlock implements Block {
|
||||
private final CraftWorld world;
|
||||
private final CraftChunk chunk;
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int z;
|
||||
protected int type;
|
||||
protected byte data;
|
||||
protected byte light;
|
||||
|
||||
public CraftBlock(final CraftWorld world, final int x, final int y, final int z, final int type, final byte data) {
|
||||
this.world = world;
|
||||
public CraftBlock(CraftChunk chunk, int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
this.light = (byte)world.getHandle().j(x, y, z);
|
||||
this.chunk = (CraftChunk)world.getChunkAt(x >> 4, z >> 4);
|
||||
}
|
||||
|
||||
protected CraftBlock(final CraftWorld world, final int x, final int y,
|
||||
final int z, final int type, final byte data, final byte light) {
|
||||
this.world = world;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
this.light = light;
|
||||
this.chunk = (CraftChunk)world.getChunkAt(x >> 4, z >> 4);
|
||||
this.chunk = chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,7 +32,7 @@ public class CraftBlock implements Block {
|
||||
* @return World containing this block
|
||||
*/
|
||||
public World getWorld() {
|
||||
return world;
|
||||
return chunk.getWorld();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,7 +41,7 @@ public class CraftBlock implements Block {
|
||||
* @return Location of the block
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return new Location(world, x, y, z);
|
||||
return new Location(getWorld(), x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,8 +86,7 @@ public class CraftBlock implements Block {
|
||||
* @param data New block specific metadata
|
||||
*/
|
||||
public void setData(final byte data) {
|
||||
this.data = data;
|
||||
world.getHandle().c(x, y, z, data);
|
||||
chunk.getHandle().d.c(x, y, z, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -117,7 +95,7 @@ public class CraftBlock implements Block {
|
||||
* @return block specific metadata
|
||||
*/
|
||||
public byte getData() {
|
||||
return data;
|
||||
return (byte) chunk.getHandle().b(this.x & 0xF, this.y & 0x7F, this.z & 0xF);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -136,8 +114,7 @@ public class CraftBlock implements Block {
|
||||
* @return whether the block was changed
|
||||
*/
|
||||
public boolean setTypeId(final int type) {
|
||||
this.type = type;
|
||||
return world.getHandle().e(x, y, z, type);
|
||||
return chunk.getHandle().d.e(x, y, z, type);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -155,7 +132,7 @@ public class CraftBlock implements Block {
|
||||
* @return block type-id
|
||||
*/
|
||||
public int getTypeId() {
|
||||
return type;
|
||||
return chunk.getHandle().a(this.x & 0xF, this.y & 0x7F, this.z & 0xF);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,7 +141,7 @@ public class CraftBlock implements Block {
|
||||
* @return light level
|
||||
*/
|
||||
public byte getLightLevel() {
|
||||
return light;
|
||||
return (byte) chunk.getHandle().d.j(this.x, this.y, this.z);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -253,7 +230,7 @@ public class CraftBlock implements Block {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftBlock{" + "world=" + world + "x=" + x + "y=" + y + "z=" + z + "type=" + type + "data=" + data + '}';
|
||||
return "CraftBlock{" + "chunk=" + chunk + "x=" + x + "y=" + y + "z=" + z + '}';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -307,7 +284,7 @@ public class CraftBlock implements Block {
|
||||
|
||||
public Biome getBiome() {
|
||||
// TODO: This may not be 100% accurate; investigate into getting per-block instead of per-chunk
|
||||
BiomeBase base = world.getHandle().a().a(chunk.getX(), chunk.getZ());
|
||||
BiomeBase base = chunk.getHandle().d.a().a(chunk.getX(), chunk.getZ());
|
||||
|
||||
if (base == BiomeBase.RAINFOREST) {
|
||||
return Biome.RAINFOREST;
|
||||
@ -339,20 +316,15 @@ public class CraftBlock implements Block {
|
||||
}
|
||||
|
||||
public boolean isBlockPowered() {
|
||||
return world.getHandle().o(x, y, z);
|
||||
return chunk.getHandle().d.o(x, y, z);
|
||||
}
|
||||
|
||||
public boolean isBlockIndirectlyPowered() {
|
||||
return world.getHandle().p(x, y, z);
|
||||
return chunk.getHandle().d.p(x, y, z);
|
||||
}
|
||||
|
||||
public void update(int type, byte data) {
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
light = (byte)world.getHandle().j(x, y, z);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
this.update( world.getHandle().getTypeId(x, y, z), (byte)world.getHandle().getData(x, y, z));
|
||||
@Override
|
||||
public boolean equals( Object o ) {
|
||||
return this == o;
|
||||
}
|
||||
}
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren