public Block GetBlock(BlockCoordinates blockCoordinates) { ChunkColumn chunk = _worldProvider.GenerateChunkColumn(new ChunkCoordinates(blockCoordinates.X >> 4, blockCoordinates.Z >> 4)); if (chunk == null) { return new Air() { Coordinates = blockCoordinates, SkyLight = 15 } } ; byte bid = chunk.GetBlock(blockCoordinates.X & 0x0f, blockCoordinates.Y & 0xff, blockCoordinates.Z & 0x0f); byte metadata = chunk.GetMetadata(blockCoordinates.X & 0x0f, blockCoordinates.Y & 0xff, blockCoordinates.Z & 0x0f); byte blockLight = chunk.GetBlocklight(blockCoordinates.X & 0x0f, blockCoordinates.Y & 0xff, blockCoordinates.Z & 0x0f); byte skyLight = chunk.GetSkylight(blockCoordinates.X & 0x0f, blockCoordinates.Y & 0xff, blockCoordinates.Z & 0x0f); Block block = BlockFactory.GetBlockById(bid); block.Coordinates = blockCoordinates; block.Metadata = metadata; block.BlockLight = blockLight; block.SkyLight = skyLight; return(block); }
private static void Test(Level level, BlockCoordinates coord, BlockCoordinates newCoord, Queue <BlockCoordinates> lightBfsQueue, ChunkColumn chunk, int lightLevel) { //Interlocked.Add(ref touches, 1); var newChunkCoord = (ChunkCoordinates)newCoord; if (chunk.x != newChunkCoord.X || chunk.z != newChunkCoord.Z) { chunk = GetChunk(level, newCoord); } if (chunk == null) { return; } if (chunk.GetBlock(newCoord.X & 0x0f, newCoord.Y & 0xff, newCoord.Z & 0x0f) == 0) { SetLightLevel(chunk, lightBfsQueue, newCoord, lightLevel); } else { //if (BlockFactory.LuminousBlocks.ContainsKey(chunk.GetBlocklight(newCoord.X & 0x0f, newCoord.Y & 0xff, newCoord.Z & 0x0f))) //{ //} //else { SetLightLevel(chunk, lightBfsQueue, level.GetBlock(newCoord, chunk), lightLevel); } } }
public static bool IsNotBlockingSkylight(BlockCoordinates blockCoordinates, ChunkColumn chunk) { if (chunk == null) { return(true); } byte bid = chunk.GetBlock(blockCoordinates.X & 0x0f, blockCoordinates.Y & 0xff, blockCoordinates.Z & 0x0f); return(bid == 0 || (BlockFactory.TransparentBlocks[bid] == 1 && bid != 18 && bid != 30 && bid != 8 && bid != 9)); }
public bool IsTransparent(BlockCoordinates blockCoordinates) { ChunkColumn chunk = GetChunk(blockCoordinates); if (chunk == null) { return(true); } byte bid = chunk.GetBlock(blockCoordinates.X & 0x0f, blockCoordinates.Y & 0xff, blockCoordinates.Z & 0x0f); return(BlockFactory.TransparentBlocks.Contains(bid)); }
public bool IsAir(BlockCoordinates blockCoordinates) { ChunkColumn chunk = GetChunk(blockCoordinates); if (chunk == null) { return(true); } byte bid = chunk.GetBlock(blockCoordinates.X & 0x0f, blockCoordinates.Y & 0xff, blockCoordinates.Z & 0x0f); return(bid == 0); }
public Block GetBlock(BlockCoordinates blockCoordinates) { ChunkColumn chunk = _worldProvider.GenerateChunkColumn(new ChunkCoordinates(blockCoordinates.X >> 4, blockCoordinates.Z >> 4)); byte bid = chunk.GetBlock(blockCoordinates.X & 0x0f, blockCoordinates.Y & 0x7f, blockCoordinates.Z & 0x0f); byte metadata = chunk.GetMetadata(blockCoordinates.X & 0x0f, blockCoordinates.Y & 0x7f, blockCoordinates.Z & 0x0f); Block block = BlockFactory.GetBlockById(bid); block.Coordinates = blockCoordinates; block.Metadata = metadata; return(block); }
private void PopulateChunk(ChunkColumn chunk) { int trees = new Random().Next(0, 10); int[,] treeBasePositions = new int[trees, 2]; for (int t = 0; t < trees; t++) { int x = new Random().Next(1, 16); int z = new Random().Next(1, 16); treeBasePositions[t, 0] = x; treeBasePositions[t, 1] = z; } var bottom = new SimplexOctaveGenerator(_seed.GetHashCode(), 8); var overhang = new SimplexOctaveGenerator(_seed.GetHashCode(), 8); overhang.SetScale(1 / 64.0); bottom.SetScale(1 / 128.0); double overhangsMagnitude = 16; double bottomsMagnitude = 32; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { float ox = x + chunk.x * 16; float oz = z + chunk.z * 16; int bottomHeight = (int)((bottom.Noise(ox, oz, 0.5, 0.5) * bottomsMagnitude) + 64.0); int maxHeight = (int)((overhang.Noise(ox, oz, 0.5, 0.5) * overhangsMagnitude) + bottomHeight + 32.0); double threshold = 0.0; maxHeight = Math.Max(1, maxHeight); for (int y = 0; y < maxHeight && y < 255; y++) { if (y <= 1) { chunk.SetBlock(x, y, z, 7); continue; } if (y > bottomHeight) { //part where we do the overhangs double density = overhang.Noise(ox, y, oz, 0.5, 0.5); if (density > threshold) { chunk.SetBlock(x, y, z, (byte)Material.Stone); } } else { chunk.SetBlock(x, y, z, (byte)Material.Stone); } } //turn the tops into grass chunk.SetBlock(x, bottomHeight, z, (byte)Material.Grass); //the top of the base hills chunk.SetBlock(x, bottomHeight - 1, z, (byte)Material.Dirt); chunk.SetBlock(x, bottomHeight - 2, z, (byte)Material.Dirt); for (int y = bottomHeight + 1; y > bottomHeight && y < maxHeight && y < 255; y++) { //the overhang int thisblock = chunk.GetBlock(x, y, z); int blockabove = chunk.GetBlock(x, y + 1, z); if (thisblock != (decimal)Material.Air && blockabove == (decimal)Material.Air) { if (chunk.GetBlock(x, y, z) == (byte)Material.Dirt || chunk.GetBlock(x, y, z) == (byte)Material.Air || chunk.GetBlock(x, y, z) == (byte)Material.Stone) { chunk.SetBlock(x, y, z, (byte)Material.Grass); } if (chunk.GetBlock(x, y - 1, z) != (decimal)Material.Air) { chunk.SetBlock(x, y - 1, z, (byte)Material.Dirt); } if (chunk.GetBlock(x, y - 2, z) != (decimal)Material.Air) { chunk.SetBlock(x, y - 2, z, (byte)Material.Dirt); } } } for (int y = 0; y < WaterLevel; y++) { //Lake generation if (y < WaterLevel) { if (chunk.GetBlock(x, y, z) == (decimal)Material.Grass || chunk.GetBlock(x, y, z) == (decimal)Material.Dirt) //Grass or Dirt? { if (GetRandomNumber(1, 40) == 1 && y < WaterLevel - 4) { chunk.SetBlock(x, y, z, 82); //Clay } else { chunk.SetBlock(x, y, z, 12); //Sand } } if (chunk.GetBlock(x, y + 1, z) == (decimal)Material.Air) { if (y < WaterLevel - 3) { chunk.SetBlock(x, y + 1, z, 8); //FlowingWater } } } } for (int y = 0; y < 255; y++) { int thisblock = chunk.GetBlock(x, y, z); int blockabove = chunk.GetBlock(x, y + 1, z); if (thisblock == (decimal)Material.Grass && blockabove == (decimal)Material.Air && y > WaterLevel) { //Grass if (GetRandomNumber(0, 5) == 1) { chunk.SetBlock(x, y + 1, z, 31); chunk.SetMetadata(x, y + 1, z, 1); } //Flowers if (GetRandomNumber(0, 65) == 1) { int meta = GetRandomNumber(0, 8); chunk.SetBlock(x, y + 1, z, 38); chunk.SetMetadata(x, y + 1, z, (byte)meta); } //Trees for (int pos = 0; pos < trees; pos++) { if (treeBasePositions[pos, 0] < 14 && treeBasePositions[pos, 0] > 4 && treeBasePositions[pos, 1] < 14 && treeBasePositions[pos, 1] > 4) { if (chunk.GetBlock(treeBasePositions[pos, 0], y + 1, treeBasePositions[pos, 1]) == 2) { if (y >= bottomHeight) { GenerateTree(chunk, treeBasePositions[pos, 0], y + 1, treeBasePositions[pos, 1], WoodType.Oak); } } } } } } } } }
public static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk, int yoffset) { var nbt = new NbtFile(); NbtCompound levelTag = new NbtCompound("Level"); nbt.RootTag.Add(levelTag); levelTag.Add(new NbtInt("xPos", chunk.x)); levelTag.Add(new NbtInt("zPos", chunk.z)); levelTag.Add(new NbtByteArray("Biomes", chunk.biomeId)); NbtList sectionsTag = new NbtList("Sections"); levelTag.Add(sectionsTag); for (int i = 0; i < 8; i++) { NbtCompound sectionTag = new NbtCompound(); sectionsTag.Add(sectionTag); sectionTag.Add(new NbtByte("Y", (byte)i)); int sy = i * 16; byte[] blocks = new byte[4096]; byte[] data = new byte[2048]; byte[] blockLight = new byte[2048]; byte[] skyLight = new byte[2048]; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int yi = sy + y; if (yi < 0 || yi >= 256) { continue; // ? } int anvilIndex = (y + yoffset) * 16 * 16 + z * 16 + x; byte blockId = chunk.GetBlock(x, yi, z); // PE to Anvil friendly converstion if (blockId == 5) { blockId = 125; } else if (blockId == 158) { blockId = 126; } else if (blockId == 50) { blockId = 75; } else if (blockId == 50) { blockId = 76; } else if (blockId == 89) { blockId = 123; } else if (blockId == 89) { blockId = 124; } else if (blockId == 73) { blockId = 152; } blocks[anvilIndex] = blockId; SetNibble4(data, anvilIndex, chunk.GetMetadata(x, yi, z)); SetNibble4(blockLight, anvilIndex, chunk.GetBlocklight(x, yi, z)); SetNibble4(skyLight, anvilIndex, chunk.GetSkylight(x, yi, z)); } } } sectionTag.Add(new NbtByteArray("Blocks", blocks)); sectionTag.Add(new NbtByteArray("Data", data)); sectionTag.Add(new NbtByteArray("BlockLight", blockLight)); sectionTag.Add(new NbtByteArray("SkyLight", skyLight)); } // TODO: Save entities NbtList entitiesTag = new NbtList("Entities", NbtTagType.Compound); levelTag.Add(entitiesTag); NbtList blockEntitiesTag = new NbtList("TileEntities", NbtTagType.Compound); levelTag.Add(blockEntitiesTag); foreach (NbtCompound blockEntityNbt in chunk.BlockEntities.Values) { NbtCompound nbtClone = (NbtCompound)blockEntityNbt.Clone(); nbtClone.Name = null; blockEntitiesTag.Add(nbtClone); } levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound)); return(nbt); }
private void ReadSection(int yoffset, NbtTag sectionTag, ChunkColumn chunk) { int sy = sectionTag["Y"].ByteValue * 16; byte[] blocks = sectionTag["Blocks"].ByteArrayValue; byte[] data = sectionTag["Data"].ByteArrayValue; NbtTag addTag = sectionTag["Add"]; byte[] adddata = new byte[2048]; if (addTag != null) { adddata = addTag.ByteArrayValue; } byte[] blockLight = sectionTag["BlockLight"].ByteArrayValue; byte[] skyLight = sectionTag["SkyLight"].ByteArrayValue; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int yi = sy + y - yoffset; if (yi < 0 || yi >= 256) { continue; } int anvilIndex = y * 16 * 16 + z * 16 + x; int blockId = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8); // Anvil to PE friendly converstion Func <int, byte, byte> dataConverter = (i, b) => b; // Default no-op converter if (Convert.ContainsKey(blockId)) { dataConverter = Convert[blockId].Item2; blockId = Convert[blockId].Item1; } else { if (BlockFactory.GetBlockById((byte)blockId).GetType() == typeof(Block)) { Log.Warn($"No block implemented for block ID={blockId}, Meta={data}"); //blockId = 57; } } chunk.isAllAir = chunk.isAllAir && blockId == 0; if (blockId > 255) { Log.Warn($"Failed mapping for block ID={blockId}, Meta={data}"); blockId = 41; } //if (yi == 127 && blockId != 0) blockId = 30; if (yi == 0 && (blockId == 8 || blockId == 9)) { blockId = 7; } chunk.SetBlock(x, yi, z, (byte)blockId); byte metadata = Nibble4(data, anvilIndex); metadata = dataConverter(blockId, metadata); chunk.SetMetadata(x, yi, z, metadata); chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex)); chunk.SetSkyLight(x, yi, z, Nibble4(skyLight, anvilIndex)); //if (block is BlockStairs || block is StoneSlab || block is WoodSlab) //{ // chunk.SetSkylight(x, yi, z, 0xff); //} if (blockId == 43 && chunk.GetMetadata(x, yi, z) == 7) { chunk.SetMetadata(x, yi, z, 6); } else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 7) { chunk.SetMetadata(x, yi, z, 6); } else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 15) { chunk.SetMetadata(x, yi, z, 14); } else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 1) { // Dirt Course => (Grass Path) chunk.SetBlock(x, yi, z, 198); chunk.SetMetadata(x, yi, z, 0); } else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 2) { // Dirt Podzol => (Podzol) chunk.SetBlock(x, yi, z, 243); chunk.SetMetadata(x, yi, z, 0); } var block = BlockFactory.GetBlockById(chunk.GetBlock(x, yi, z)); if (block.LightLevel > 0) { block.Coordinates = new BlockCoordinates(x + (16 * chunk.x), yi, z + (16 * chunk.z)); LightSources.Enqueue(block); } } } } }
public static ChunkColumn GetChunk(ChunkCoordinates coordinates, string basePath, IWorldProvider generator, int yoffset) { int width = 32; int depth = 32; int rx = coordinates.X >> 5; int rz = coordinates.Z >> 5; string filePath = Path.Combine(basePath, string.Format(@"region{2}r.{0}.{1}.mca", rx, rz, Path.DirectorySeparatorChar)); if (!File.Exists(filePath)) { return(generator.GenerateChunkColumn(coordinates)); } using (var regionFile = File.OpenRead(filePath)) { byte[] buffer = new byte[8192]; regionFile.Read(buffer, 0, 8192); int xi = (coordinates.X % width); if (xi < 0) { xi += 32; } int zi = (coordinates.Z % depth); if (zi < 0) { zi += 32; } int tableOffset = (xi + zi * width) * 4; regionFile.Seek(tableOffset, SeekOrigin.Begin); byte[] offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); int offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; int length = regionFile.ReadByte(); if (offset == 0 || length == 0) { return(generator.GenerateChunkColumn(coordinates)); } regionFile.Seek(offset, SeekOrigin.Begin); byte[] waste = new byte[4]; regionFile.Read(waste, 0, 4); int compressionMode = regionFile.ReadByte(); var nbt = new NbtFile(); nbt.LoadFromStream(regionFile, NbtCompression.ZLib); NbtTag dataTag = nbt.RootTag["Level"]; NbtList sections = dataTag["Sections"] as NbtList; ChunkColumn chunk = new ChunkColumn { x = coordinates.X, z = coordinates.Z, biomeId = dataTag["Biomes"].ByteArrayValue }; for (int i = 0; i < chunk.biomeId.Length; i++) { if (chunk.biomeId[i] > 22) { chunk.biomeId[i] = 0; } } if (chunk.biomeId.Length > 256) { throw new Exception(); } // This will turn into a full chunk column foreach (NbtTag sectionTag in sections) { int sy = sectionTag["Y"].ByteValue * 16; byte[] blocks = sectionTag["Blocks"].ByteArrayValue; byte[] data = sectionTag["Data"].ByteArrayValue; NbtTag addTag = sectionTag["Add"]; byte[] adddata = new byte[2048]; if (addTag != null) { adddata = addTag.ByteArrayValue; } byte[] blockLight = sectionTag["BlockLight"].ByteArrayValue; byte[] skyLight = sectionTag["SkyLight"].ByteArrayValue; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int yi = sy + y - yoffset; if (yi < 0 || yi >= 128) { continue; } int anvilIndex = y * 16 * 16 + z * 16 + x; int blockId = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8); Func <int, byte, byte> dataConverter = (i, b) => b; // Anvil to PE friendly converstion if (Convert.ContainsKey(blockId)) { dataConverter = Convert[blockId].Item2; blockId = Convert[blockId].Item1; } else if (Ignore.BinarySearch(blockId) >= 0) { blockId = 0; } else if (Gaps.BinarySearch(blockId) >= 0) { Log.WarnFormat("Missing material on convert: {0}", blockId); blockId = 133; } if (blockId > 255) { blockId = 41; } //if (yi == 127 && blockId != 0) blockId = 30; if (yi == 0 && (blockId == 8 || blockId == 9)) { blockId = 7; } chunk.SetBlock(x, yi, z, (byte)blockId); byte metadata = Nibble4(data, anvilIndex); metadata = dataConverter(blockId, metadata); chunk.SetMetadata(x, yi, z, metadata); chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex)); chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex)); var block = BlockFactory.GetBlockById(chunk.GetBlock(x, yi, z)); if (block is BlockStairs || block is StoneSlab || block is WoodSlab) { chunk.SetSkylight(x, yi, z, 0xff); } if (blockId == 43 && chunk.GetMetadata(x, yi, z) == 7) { chunk.SetMetadata(x, yi, z, 6); } else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 7) { chunk.SetMetadata(x, yi, z, 6); } else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 15) { chunk.SetMetadata(x, yi, z, 14); } else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 1) { chunk.SetBlock(x, yi, z, 198); chunk.SetMetadata(x, yi, z, 0); } else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 2) { chunk.SetBlock(x, yi, z, 143); //Coarse Dirt => Pat chunk.SetMetadata(x, yi, z, 0); // Podzol => (Podzol) } } } } } NbtList entities = dataTag["Entities"] as NbtList; NbtList blockEntities = dataTag["TileEntities"] as NbtList; if (blockEntities != null) { foreach (var nbtTag in blockEntities) { var blockEntityTag = (NbtCompound)nbtTag; string entityId = blockEntityTag["id"].StringValue; int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue - yoffset; int z = blockEntityTag["z"].IntValue; blockEntityTag["y"] = new NbtInt("y", y); BlockEntity blockEntity = BlockEntityFactory.GetBlockEntityById(entityId); if (blockEntity != null) { blockEntityTag.Name = string.Empty; chunk.SetBlockEntity(new BlockCoordinates(x, y, z), blockEntityTag); } } } //NbtList tileTicks = dataTag["TileTicks"] as NbtList; chunk.isDirty = false; return(chunk); } }
public static ChunkColumn GetChunk(ChunkCoordinates coordinates, string basePath, IWorldProvider generator, int yoffset) { int width = 32; int depth = 32; int rx = coordinates.X >> 5; int rz = coordinates.Z >> 5; string filePath = Path.Combine(basePath, string.Format(@"region{2}r.{0}.{1}.mca", rx, rz, Path.DirectorySeparatorChar)); if (!File.Exists(filePath)) { return(generator?.GenerateChunkColumn(coordinates)); //return new ChunkColumn //{ // x = coordinates.X, // z = coordinates.Z, //}; } using (var regionFile = File.OpenRead(filePath)) { byte[] buffer = new byte[8192]; regionFile.Read(buffer, 0, 8192); int xi = (coordinates.X % width); if (xi < 0) { xi += 32; } int zi = (coordinates.Z % depth); if (zi < 0) { zi += 32; } int tableOffset = (xi + zi * width) * 4; regionFile.Seek(tableOffset, SeekOrigin.Begin); byte[] offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); int offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; int length = regionFile.ReadByte(); if (offset == 0 || length == 0) { return(generator?.GenerateChunkColumn(coordinates)); //return new ChunkColumn //{ // x = coordinates.X, // z = coordinates.Z, //}; } regionFile.Seek(offset, SeekOrigin.Begin); byte[] waste = new byte[4]; regionFile.Read(waste, 0, 4); int compressionMode = regionFile.ReadByte(); var nbt = new NbtFile(); nbt.LoadFromStream(regionFile, NbtCompression.ZLib); NbtTag dataTag = nbt.RootTag["Level"]; NbtList sections = dataTag["Sections"] as NbtList; ChunkColumn chunk = new ChunkColumn { x = coordinates.X, z = coordinates.Z, biomeId = dataTag["Biomes"].ByteArrayValue }; if (chunk.biomeId.Length > 256) { throw new Exception(); } // This will turn into a full chunk column foreach (NbtTag sectionTag in sections) { int sy = sectionTag["Y"].ByteValue * 16; byte[] blocks = sectionTag["Blocks"].ByteArrayValue; byte[] data = sectionTag["Data"].ByteArrayValue; NbtTag addTag = sectionTag["Add"]; byte[] adddata = new byte[2048]; if (addTag != null) { adddata = addTag.ByteArrayValue; } byte[] blockLight = sectionTag["BlockLight"].ByteArrayValue; byte[] skyLight = sectionTag["SkyLight"].ByteArrayValue; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int yi = sy + y - yoffset; if (yi < 0 || yi >= 128) { continue; } int anvilIndex = y * 16 * 16 + z * 16 + x; int blockId = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8); // Anvil to PE friendly converstion Func <int, byte, byte> dataConverter = (i, b) => b; // Default no-op converter if (Convert.ContainsKey(blockId)) { dataConverter = Convert[blockId].Item2; blockId = Convert[blockId].Item1; } if (blockId > 255) { blockId = 41; } //if (yi == 127 && blockId != 0) blockId = 30; if (yi == 0 && (blockId == 8 || blockId == 9)) { blockId = 7; } chunk.SetBlock(x, yi, z, (byte)blockId); byte metadata = Nibble4(data, anvilIndex); metadata = dataConverter(blockId, metadata); chunk.SetMetadata(x, yi, z, metadata); chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex)); chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex)); var block = BlockFactory.GetBlockById(chunk.GetBlock(x, yi, z)); if (block is BlockStairs || block is StoneSlab || block is WoodSlab) { chunk.SetSkylight(x, yi, z, 0xff); } if (blockId == 43 && chunk.GetMetadata(x, yi, z) == 7) { chunk.SetMetadata(x, yi, z, 6); } else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 7) { chunk.SetMetadata(x, yi, z, 6); } else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 15) { chunk.SetMetadata(x, yi, z, 14); } else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 1) { // Dirt Course => (Grass Path) chunk.SetBlock(x, yi, z, 198); chunk.SetMetadata(x, yi, z, 0); } else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 2) { // Dirt Podzol => (Podzol) chunk.SetBlock(x, yi, z, 243); chunk.SetMetadata(x, yi, z, 0); } } } } } NbtList entities = dataTag["Entities"] as NbtList; NbtList blockEntities = dataTag["TileEntities"] as NbtList; if (blockEntities != null) { foreach (var nbtTag in blockEntities) { var blockEntityTag = (NbtCompound)nbtTag.Clone(); string entityId = blockEntityTag["id"].StringValue; int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue - yoffset; int z = blockEntityTag["z"].IntValue; blockEntityTag["y"] = new NbtInt("y", y); BlockEntity blockEntity = BlockEntityFactory.GetBlockEntityById(entityId); if (blockEntity != null) { blockEntityTag.Name = string.Empty; if (blockEntity is Sign) { // Remove the JSON stuff and get the text out of extra data. // TAG_String("Text2"): "{"extra":["10c a loaf!"],"text":""}" CleanSignText(blockEntityTag, "Text1"); CleanSignText(blockEntityTag, "Text2"); CleanSignText(blockEntityTag, "Text3"); CleanSignText(blockEntityTag, "Text4"); } else if (blockEntity is ChestBlockEntity) { NbtList items = (NbtList)blockEntityTag["Items"]; for (byte i = 0; i < items.Count; i++) { NbtCompound item = (NbtCompound)items[i]; item.Add(new NbtShort("OriginalDamage", item["Damage"].ShortValue)); byte metadata = (byte)(item["Damage"].ShortValue & 0xff); item.Remove("Damage"); item.Add(new NbtByte("Damage", metadata)); } } chunk.SetBlockEntity(new BlockCoordinates(x, y, z), blockEntityTag); } } } //NbtList tileTicks = dataTag["TileTicks"] as NbtList; chunk.isDirty = false; return(chunk); } }
public ChunkColumn GenerateChunkColumn(ChunkCoordinates chunkCoordinates) { lock (_chunkCache) { ChunkColumn cachedChunk; if (_chunkCache.TryGetValue(chunkCoordinates, out cachedChunk)) { return(cachedChunk); } ChunkColumn chunk = new ChunkColumn(); chunk.x = chunkCoordinates.X; chunk.z = chunkCoordinates.Z; int h = PopulateChunk(chunk); chunk.SetBlock(0, h + 1, 0, 7); chunk.SetBlock(1, h + 1, 0, 41); chunk.SetBlock(2, h + 1, 0, 41); chunk.SetBlock(3, h + 1, 0, 41); chunk.SetBlock(3, h + 1, 0, 41); //chunk.SetBlock(6, h + 1, 6, 57); chunk.SetBlock(6, h, 9, 63); chunk.SetMetadata(6, h, 9, 12); var blockEntity = GetBlockEntity((chunkCoordinates.X * 16) + 6, h, (chunkCoordinates.Z * 16) + 9); chunk.SetBlockEntity(blockEntity.Coordinates, blockEntity.GetCompound()); if (chunkCoordinates.X == 1 && chunkCoordinates.Z == 1) { for (int x = 0; x < 10; x++) { for (int z = 0; z < 10; z++) { for (int y = h - 2; y < h; y++) { chunk.SetBlock(x, y, z, 8); } } } } if (chunkCoordinates.X == 3 && chunkCoordinates.Z == 1) { for (int x = 0; x < 10; x++) { for (int z = 0; z < 10; z++) { for (int y = h - 1; y < h; y++) { chunk.SetBlock(x, y, z, 10); } } } } for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 127; y != 0; y--) { if (chunk.GetBlock(x, y, z) == 0x00) { chunk.SetSkylight(x, y, z, 0xff); } else { chunk.SetSkylight(x, y, z, 0x00); } } } } // Cache chunk.GetBatch(); _chunkCache[chunkCoordinates] = chunk; return(chunk); } }
private void PopulateChunk(ChunkColumn chunk) { int trees = new Random().Next(0, 10); int[,] treeBasePositions = new int[trees, 2]; for (int t = 0; t < trees; t++) { int x = new Random().Next(1, 16); int z = new Random().Next(1, 16); treeBasePositions[t, 0] = x; treeBasePositions[t, 1] = z; } for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { int stoneHeight = (int)Math.Floor(stoneBaseHeight); stoneHeight += GetNoise(chunk.x * 16 + x, chunk.z * 16 + z, stoneMountainFrequency, (int)Math.Floor(stoneMountainHeight)); if (stoneHeight < stoneMinHeight) { stoneHeight = (int)Math.Floor(stoneMinHeight); } stoneHeight += GetNoise(chunk.x * 16 + x, chunk.z * 16 + z, stoneBaseNoise, (int)Math.Floor(stoneBaseNoiseHeight)); int dirtHeight = stoneHeight + (int)Math.Floor(dirtBaseHeight); dirtHeight += GetNoise(chunk.x * 16 + x, chunk.z * 16 + z, dirtNoise, (int)Math.Floor(dirtNoiseHeight)); for (int y = 0; y < 256; y++) { //float y2 = Get3DNoise(chunk.X*16, y, chunk.Z*16, stoneBaseNoise, (int) Math.Floor(stoneBaseNoiseHeight)); if (y <= stoneHeight) { chunk.SetBlock(x, y, z, 1); //Diamond ore if (GetRandomNumber(0, 2500) < 5) { chunk.SetBlock(x, y, z, 56); } //Coal Ore if (GetRandomNumber(0, 1500) < 50) { chunk.SetBlock(x, y, z, 16); } //Iron Ore if (GetRandomNumber(0, 2500) < 30) { chunk.SetBlock(x, y, z, 15); } //Gold Ore if (GetRandomNumber(0, 2500) < 20) { chunk.SetBlock(x, y, z, 14); } } if (y < waterLevel) //FlowingWater :) { if (chunk.GetBlock(x, y, z) == 2 || chunk.GetBlock(x, y, z) == 3) //Grass or Dirt? { if (GetRandomNumber(1, 40) == 5 && y < waterLevel - 4) { chunk.SetBlock(x, y, z, 82); //Clay } else { chunk.SetBlock(x, y, z, 12); //Sand } } if (y < waterLevel - 3) { chunk.SetBlock(x, y + 1, z, 8); //FlowingWater } } if (y <= dirtHeight && y >= stoneHeight) { chunk.SetBlock(x, y, z, 3); //Dirt chunk.SetBlock(x, y + 1, z, 2); //Grass Block if (y > waterLevel) { //Grass if (GetRandomNumber(0, 5) == 2) { chunk.SetBlock(x, y + 2, z, 31); chunk.SetMetadata(x, y + 2, z, 1); } //flower if (GetRandomNumber(0, 65) == 8) { int meta = GetRandomNumber(0, 8); chunk.SetBlock(x, y + 2, z, 38); chunk.SetMetadata(x, y + 2, z, (byte)meta); } for (int pos = 0; pos < trees; pos++) { if (treeBasePositions[pos, 0] < 14 && treeBasePositions[pos, 0] > 4 && treeBasePositions[pos, 1] < 14 && treeBasePositions[pos, 1] > 4) { if (y < waterLevel + 2) { break; } if (chunk.GetBlock(treeBasePositions[pos, 0], y + 1, treeBasePositions[pos, 1]) == 2) { if (y == dirtHeight) { GenerateTree(chunk, treeBasePositions[pos, 0], y + 1, treeBasePositions[pos, 1]); } } } } } } if (y == 0) { chunk.SetBlock(x, y, z, 7); } } } } }
public ChunkColumn GenerateChunkColumn(ChunkCoordinates chunkCoordinates) { lock (_chunkCache) { ChunkColumn cachedChunk; if (_chunkCache.TryGetValue(chunkCoordinates, out cachedChunk)) { return(cachedChunk); } ChunkColumn chunk = new ChunkColumn(); chunk.x = chunkCoordinates.X; chunk.z = chunkCoordinates.Z; //chunk.biomeId = ArrayOf<byte>.Create(256, (byte) rand.Next(0, 37)); int h = PopulateChunk(chunk); //chunk.SetBlock(0, h + 1, 0, 7); //chunk.SetBlock(1, h + 1, 0, 41); //chunk.SetBlock(2, h + 1, 0, 41); //chunk.SetBlock(3, h + 1, 0, 41); //chunk.SetBlock(3, h + 1, 0, 41); ////chunk.SetBlock(6, h + 1, 6, 57); //chunk.SetBlock(9, h, 3, 31); //chunk.SetBiome(9, 3, 30); //chunk.SetBlock(0, h, 1, 161); //chunk.SetBlock(0, h, 2, 18); //chunk.SetBlock(0, h, 15, 31); //chunk.SetBlock(0, h, 14, 161); //chunk.SetBlock(5, h, 13, 18); //chunk.SetBiome(5, 13, 30); //chunk.SetBlock(6, h, 9, 63); //chunk.SetMetadata(6, h, 9, 12); //var blockEntity = GetBlockEntity((chunkCoordinates.X*16) + 6, h, (chunkCoordinates.Z*16) + 9); //chunk.SetBlockEntity(blockEntity.Coordinates, blockEntity.GetCompound()); if (chunkCoordinates.X == 1 && chunkCoordinates.Z == 1) { for (int x = 0; x < 10; x++) { for (int z = 0; z < 10; z++) { for (int y = h - 2; y < h; y++) { chunk.SetBlock(x, y, z, 8); } } } } if (chunkCoordinates.X == 3 && chunkCoordinates.Z == 1) { for (int x = 0; x < 10; x++) { for (int z = 0; z < 10; z++) { for (int y = h - 1; y < h; y++) { chunk.SetBlock(x, y, z, 10); } } } } for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 127; y > 0; y--) { if (chunk.GetBlock(x, y, z) == 0x00) { chunk.SetSkylight(x, y, z, 0xff); } else { chunk.SetSkylight(x, y, z, 0x00); } } } } // Cache chunk.GetBatch(); _chunkCache[chunkCoordinates] = chunk; return(chunk); } }