/// <summary> /// Process chunk column data from the server and (un)load the chunk from the Minecraft world /// </summary> /// <param name="chunkX">Chunk X location</param> /// <param name="chunkZ">Chunk Z location</param> /// <param name="chunkMask">Chunk mask for reading data</param> /// <param name="hasSkyLight">Contains skylight info</param> /// <param name="chunksContinuous">Are the chunk continuous</param> /// <param name="cache">Cache for reading chunk data</param> private void ProcessChunkColumnData(int chunkX, int chunkZ, ushort chunkMask, bool hasSkyLight, bool chunksContinuous, List<byte> cache) { if (protocolversion < MC19Version && chunksContinuous && chunkMask == 0) { //Unload the entire chunk column handler.GetWorld()[chunkX, chunkZ] = null; } else { //Load chunk data from the server for (int chunkY = 0; chunkY < ChunkColumn.ColumnSize; chunkY++) { if ((chunkMask & (1 << chunkY)) != 0) { Chunk chunk = new Chunk(); //Read chunk data, all at once for performance reasons, and build the chunk object Queue<ushort> queue = new Queue<ushort>(readNextUShortsLittleEndian(Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ, cache)); for (int blockY = 0; blockY < Chunk.SizeY; blockY++) for (int blockZ = 0; blockZ < Chunk.SizeZ; blockZ++) for (int blockX = 0; blockX < Chunk.SizeX; blockX++) chunk[blockX, blockY, blockZ] = new Block(queue.Dequeue()); //We have our chunk, save the chunk into the world if (handler.GetWorld()[chunkX, chunkZ] == null) handler.GetWorld()[chunkX, chunkZ] = new ChunkColumn(); handler.GetWorld()[chunkX, chunkZ][chunkY] = chunk; } } //Skip light information for (int chunkY = 0; chunkY < ChunkColumn.ColumnSize; chunkY++) { if ((chunkMask & (1 << chunkY)) != 0) { //Skip block light readData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ) / 2, cache); //Skip sky light if (hasSkyLight) readData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ) / 2, cache); } } //Skip biome metadata if (chunksContinuous) readData(Chunk.SizeX * Chunk.SizeZ, cache); } }
/// <summary> /// Set block at the specified location /// </summary> /// <param name="location">Location to set block to</param> /// <param name="block">Block to set</param> public void SetBlock(Location location, Block block) { ChunkColumn column = this[location.ChunkX, location.ChunkZ]; if (column != null) { Chunk chunk = column[location.ChunkY]; if (chunk == null) column[location.ChunkY] = chunk = new Chunk(); chunk[location.ChunkBlockX, location.ChunkBlockY, location.ChunkBlockZ] = block; } }