diff --git a/anvil-loader/src/main/java/mc/world/anvil/AnvilBlock.java b/anvil-loader/src/main/java/mc/world/anvil/AnvilBlock.java index 255ba79..12748a3 100644 --- a/anvil-loader/src/main/java/mc/world/anvil/AnvilBlock.java +++ b/anvil-loader/src/main/java/mc/world/anvil/AnvilBlock.java @@ -20,9 +20,7 @@ public class AnvilBlock implements Block { @Override public int getLight() { - final int idx = (location.getY() << 8 | location.getZ() << 4 | location.getX()) >> 1; - final int value = chunkSection.getBlockLight().get(idx); - return (idx & 1) == 0 ? value & 15 : value >> 4 & 15; + return chunkSection.getBlockLight().get(location); } @Override @@ -32,8 +30,9 @@ public class AnvilBlock implements Block { @Override public BlockType getBlockType() { - byte id = chunkSection.getBlocks().get((location.getY() * 256) + (location.getZ() * 16) + location.getX()); - return BlockType.getByIdMeta(id, 0/*FIXME*/); + final byte id = chunkSection.getBlocks().get((location.getY() * 256) + (location.getZ() * 16) + location.getX()); + final int meta = chunkSection.getBlocksMeta().get(location); + return BlockType.getByIdMeta(id, meta); } @Override diff --git a/anvil-loader/src/main/java/mc/world/anvil/AnvilChunk.java b/anvil-loader/src/main/java/mc/world/anvil/AnvilChunk.java index 69664ec..2e5415e 100644 --- a/anvil-loader/src/main/java/mc/world/anvil/AnvilChunk.java +++ b/anvil-loader/src/main/java/mc/world/anvil/AnvilChunk.java @@ -39,9 +39,10 @@ public class AnvilChunk implements Chunk { chunkSection.setParent(this); chunkSection.setY(((ByteTag) sectionTagValue.get("Y")).getValue()); - chunkSection.getBlockLight().add(((ByteArrayTag) sectionTagValue.get("BlockLight")).getValue()); - chunkSection.getSkyLight().add(((ByteArrayTag) sectionTagValue.get("SkyLight")).getValue()); + chunkSection.setBlockLight(new NibbleArray(((ByteArrayTag) sectionTagValue.get("BlockLight")).getValue())); + chunkSection.setSkyLight(new NibbleArray(((ByteArrayTag) sectionTagValue.get("SkyLight")).getValue())); chunkSection.getBlocks().add(((ByteArrayTag) sectionTagValue.get("Blocks")).getValue()); + chunkSection.setBlocksMeta(new NibbleArray(((ByteArrayTag) sectionTagValue.get("Data")).getValue())); this.sections.add(chunkSection); } diff --git a/anvil-loader/src/main/java/mc/world/anvil/AnvilChunkSection.java b/anvil-loader/src/main/java/mc/world/anvil/AnvilChunkSection.java index cdeb281..754223d 100644 --- a/anvil-loader/src/main/java/mc/world/anvil/AnvilChunkSection.java +++ b/anvil-loader/src/main/java/mc/world/anvil/AnvilChunkSection.java @@ -17,8 +17,12 @@ public class AnvilChunkSection implements ChunkSection { private int y; private TByteList blocks = new TByteLinkedList(); - private TByteList blockLight = new TByteLinkedList(); - private TByteList skyLight = new TByteLinkedList(); + @Setter + private NibbleArray blocksMeta; + @Setter + private NibbleArray blockLight; + @Setter + private NibbleArray skyLight; @Override public int getX() { @@ -42,9 +46,7 @@ public class AnvilChunkSection implements ChunkSection { @Override public int getSkyLight(int x, int y, int z) { - final int idx = (y << 8 | z << 4 | x) >> 1; - final int value = skyLight.get(idx); - return (idx & 1) == 0 ? value & 15 : value >> 4 & 15; + return skyLight.get(x, y, z); } @Override diff --git a/anvil-loader/src/main/java/mc/world/anvil/NibbleArray.java b/anvil-loader/src/main/java/mc/world/anvil/NibbleArray.java new file mode 100644 index 0000000..2b8b593 --- /dev/null +++ b/anvil-loader/src/main/java/mc/world/anvil/NibbleArray.java @@ -0,0 +1,32 @@ +package mc.world.anvil; + +import lombok.RequiredArgsConstructor; +import mc.core.world.block.BlockLocation; + +@RequiredArgsConstructor +public class NibbleArray { + private final byte[] data; + + private int coordsToIndex(int x, int y, int z) { + return y << 8 | z << 4 | x; + } + + private int nibbleIndex(int index) { + return index >> 1; + } + + private boolean isLowerNibble(int index) { + return (index & 1) == 0; + } + + public int get(BlockLocation location) { + return get(location.getX(), location.getY(), location.getZ()); + } + + public int get(int x, int y, int z) { + final int idx = coordsToIndex(x, y, z); + + final int ni = nibbleIndex(idx); + return isLowerNibble(idx) ? this.data[ni] & 15 : this.data[ni] >> 4 & 15; + } +}