package speedytools.serverside.worldmanipulation; import java.util.HashMap; /** * User: The Grey Ghost * Date: 20/07/2014 * Stores the Block Data (ID, metadata, lightvalue) as arrays */ public class BlockDataStoreSparse implements BlockDataStore { public BlockDataStoreSparse(int i_xcount, int i_ycount, int i_zcount, int estimatedElementsUsed) { xCount = i_xcount; yCount = i_ycount; zCount = i_zcount; sparseData = new HashMap<Integer, Integer>(estimatedElementsUsed); } /** * gets the blockID at a particular location. * error if the location is not stored in this fragment * * @param x x position relative to the block origin [0,0,0] * @param y y position relative to the block origin [0,0,0] * @param z z position relative to the block origin [0,0,0] */ @Override public int getBlockID(int x, int y, int z) { assert (x >= 0 && x < xCount); assert (y >= 0 && y < yCount); assert (z >= 0 && z < zCount); final int offset = y * xCount * zCount + z * xCount + x; Integer data = sparseData.get(offset); return data == null ? 0 : (data & 0xfff); } /** * sets the BlockID at a particular location * * @param x x position relative to the block origin [0,0,0] * @param y y position relative to the block origin [0,0,0] * @param z z position relative to the block origin [0,0,0] * @param blockID */ @Override public void setBlockID(int x, int y, int z, int blockID) { assert (x >= 0 && x < xCount); assert (y >= 0 && y < yCount); assert (z >= 0 && z < zCount); final int offset = y * xCount * zCount + z * xCount + x; Integer data = sparseData.get(offset); sparseData.put(offset, (blockID | (data == null ? 0 : (data & ~0xfff))) ); } /** * gets the metadata at a particular location * error if the location is not stored in this fragment * * @param x x position relative to the block origin [0,0,0] * @param y y position relative to the block origin [0,0,0] * @param z z position relative to the block origin [0,0,0] */ @Override public int getMetadata(int x, int y, int z) { assert (x >= 0 && x < xCount); assert (y >= 0 && y < yCount); assert (z >= 0 && z < zCount); final int offset = y * xCount * zCount + z * xCount + x; Integer data = sparseData.get(offset); return data == null ? 0 : ((data >> 12) & 0x0f); } /** * sets the metadata at a particular location * * @param x x position relative to the block origin [0,0,0] * @param y y position relative to the block origin [0,0,0] * @param z z position relative to the block origin [0,0,0] * @param metadata */ @Override public void setMetadata(int x, int y, int z, int metadata) { assert (x >= 0 && x < xCount); assert (y >= 0 && y < yCount); assert (z >= 0 && z < zCount); final int offset = y * xCount * zCount + z * xCount + x; Integer data = sparseData.get(offset); sparseData.put(offset, (metadata << 12) | (data == null ? 0 : (data & ~0xf000)) ); } /** * gets the light value at a particular location. * error if the location is not stored in this fragment * * @param x x position relative to the block origin [0,0,0] * @param y y position relative to the block origin [0,0,0] * @param z z position relative to the block origin [0,0,0] * @return lightvalue (sky << 4 | block) */ @Override public byte getLightValue(int x, int y, int z) { assert (x >= 0 && x < xCount); assert (y >= 0 && y < yCount); assert (z >= 0 && z < zCount); final int offset = y * xCount * zCount + z * xCount + x; Integer data = sparseData.get(offset); return data == null ? 0 : (byte)(data >> 16); } /** * sets the light value at a particular location * * @param x x position relative to the block origin [0,0,0] * @param y y position relative to the block origin [0,0,0] * @param z z position relative to the block origin [0,0,0] * @param lightValue lightvalue (sky << 4 | block) */ @Override public void setLightValue(int x, int y, int z, byte lightValue) { assert (x >= 0 && x < xCount); assert (y >= 0 && y < yCount); assert (z >= 0 && z < zCount); final int offset = y * xCount * zCount + z * xCount + x; Integer data = sparseData.get(offset); sparseData.put(offset, (lightValue << 16) | (data == null ? 0 : data & ~0xff0000)); } private HashMap<Integer, Integer> sparseData; private int xCount; private int yCount; private int zCount; }