protected void GenerateCircle(ChunkColumn chunk, Vector3 location, int radius, Block block) { for (var I = -radius; I <= radius; I = (I + 1)) { for (var j = -radius; j <= radius; j = (j + 1)) { var max = (int) Math.Sqrt((I*I) + (j*j)); if (max <= radius) { var X = location.X + I; var Z = location.Z + j; if (X < 0 || X >= 16 || Z < 0 || Z >= 256) continue; var x = (int) X; var y = (int) location.Y; var z = (int) Z; if (chunk.GetBlock(x, y, z).Equals(0)) { chunk.SetBlock(x, y, z, block); } } } } }
public override void Decorate(ChunkColumn chunk, BiomeBase biome) { /* var trees = ExperimentalV2Generator.GetRandomNumber(3, 8); var treeBasePositions = new int[trees, 2]; for (var t = 0; t < trees; t++) { var x = ExperimentalV2Generator.GetRandomNumber(1, 16); var z = ExperimentalV2Generator.GetRandomNumber(1, 16); treeBasePositions[t, 0] = x; treeBasePositions[t, 1] = z; } for (int y = ExperimentalV2Generator.WaterLevel; y < 256; y++) { for (var pos = 0; pos < trees; pos++) { if (chunk.GetBlock(treeBasePositions[pos, 0], y, treeBasePositions[pos, 1]) == biome.TopBlock.Id) { var meta = ExperimentalV2Generator.GetRandomNumber(0, 8); chunk.SetBlock(treeBasePositions[pos, 0], y + 1, treeBasePositions[pos, 1], new Block(38) {Metadata = (ushort) meta}); } } }*/ }
public override void Decorate(ChunkColumn chunk, BiomeBase biome) { for (var x = 0; x < 16; x++) { for (var z = 0; z < 16; z++) { //Check for temperature. for (var y = 0; y < StandardWorldProvider.WaterLevel; y++) { //Lake generation if (y < StandardWorldProvider.WaterLevel) { if (chunk.GetBlock(x, y, z) == 2 || chunk.GetBlock(x, y, z) == 3) //Grass or Dirt? { if (StandardWorldProvider.GetRandomNumber(1, 40) == 1 && y < StandardWorldProvider.WaterLevel - 4) chunk.SetBlock(x, y, z, BlockFactory.GetBlockById(82)); //Clay else { chunk.SetBlock(x, y, z, new BlockSand()); //Sand chunk.BiomeId[x*16 + z] = 16; //Beach } } if (chunk.GetBlock(x, y + 1, z) == 0) { if (y < StandardWorldProvider.WaterLevel - 3) { chunk.SetBlock(x, y + 1, z, new BlockFlowingWater()); //Water chunk.BiomeId[x*16 + z] = 0; //Ocean } } } } } } }
public static ChunkColumn DecocedChunkColumn(byte[] buffer) { return null; MemoryStream stream = new MemoryStream(buffer); { NbtBinaryReader defStream = new NbtBinaryReader(stream, true); ChunkColumn chunk = new ChunkColumn(); chunk.x = IPAddress.NetworkToHostOrder(defStream.ReadInt32()); chunk.z = IPAddress.NetworkToHostOrder(defStream.ReadInt32()); int chunkSize = 16*16*128; defStream.Read(chunk.blocks, 0, chunkSize); defStream.Read(chunk.metadata.Data, 0, chunkSize/2); defStream.Read(chunk.skylight.Data, 0, chunkSize/2); defStream.Read(chunk.blocklight.Data, 0, chunkSize/2); defStream.Read(chunk.height, 0, 256); byte[] ints = new byte[256*4]; defStream.Read(ints, 0, ints.Length); int j = 0; for (int i = 0; i < ints.Length; i = i + 4) { chunk.biomeColor[j++] = BitConverter.ToInt32(new[] {ints[i], ints[i + 1], ints[i + 2], ints[i + 3]}, 0); } return chunk; } }
private void DecorateTrees(ChunkColumn chunk, BiomeBase biome) { var trees = StandardWorldProvider.GetRandomNumber(biome.MinTrees, biome.MaxTrees); var treeBasePositions = new int[trees, 2]; for (var t = 0; t < trees; t++) { var x = new Random().Next(1, 16); var z = new Random().Next(1, 16); treeBasePositions[t, 0] = x; treeBasePositions[t, 1] = z; } for (var y = StandardWorldProvider.WaterLevel + 2; y < 256; y++) { for (var 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]) == biome.TopBlock.Id) { GenerateTree(chunk, treeBasePositions[pos, 0], y + 1, treeBasePositions[pos, 1], biome); } } } } }
private void GenerateTree(ChunkColumn chunk, int x, int treebase, int z, BiomeBase biome) { if (biome.TreeStructures.Length > 0) { var value = StandardWorldProvider.GetRandomNumber(0, biome.TreeStructures.Length); biome.TreeStructures[value].Create(chunk, x, treebase, z); } }
public virtual void Create(ChunkColumn chunk, int x, int y, int z) { if (chunk.GetBlock(x, y + Height, z) == 0) { foreach (var b in Blocks) { chunk.SetBlock(x + (int) b.Coordinates.X, y + (int) b.Coordinates.Y, z + (int) b.Coordinates.Z, b); } } }
public override void Decorate(ChunkColumn chunk, BiomeBase biome, int x, int z) { for (var y = 1; y < 6; y++) { if (StandardWorldProvider.GetRandomNumber(0, 5) == 1) { chunk.SetBlock(x, y, z, BlockFactory.GetBlockById(7)); } } }
public static void GenerateColumn(ChunkColumn chunk, Vector3 location, int height, Block block) { for (var o = 0; o < height; o++) { var x = (int) location.X; var y = (int) location.Y + o; var z = (int) location.Z; chunk.SetBlock(x, y, z, block); } }
public void Create(ChunkColumn chunk, int x, int y, int z) { if (chunk.GetBlock(x, y + MaxHeight, z) == (byte) Material.Air) { foreach (Block b in Blocks) { chunk.SetBlock(x + b.Coordinates.X, y + b.Coordinates.Y, z + b.Coordinates.Z, b.Id); chunk.SetMetadata(x + b.Coordinates.X, y + b.Coordinates.Y, z + b.Coordinates.Z, b.Metadata); } } }
public override void Decorate(ChunkColumn chunk, BiomeBase biome, int x, int z) { for (var y = StandardWorldProvider.WaterLevel; y < 256; y++) { if (StandardWorldProvider.GetRandomNumber(0, 10) == 5) { if (chunk.GetBlock(x, y, z) == biome.TopBlock.Id) { chunk.SetBlock(x, y + 1, z, new Block(31) {Metadata = 1}); } } } }
public ChunkColumn GenerateChunkColumn(ChunkCoordinates chunkCoordinates) { ChunkColumn cachedChunk; if (_chunkCache.TryGetValue(chunkCoordinates, out cachedChunk)) return cachedChunk; ChunkColumn chunk = new ChunkColumn(); chunk.x = chunkCoordinates.X; chunk.z = chunkCoordinates.Z; PopulateChunk(chunk); _chunkCache[chunkCoordinates] = chunk; return chunk; }
public override void Decorate(ChunkColumn chunk, BiomeBase biome, int x, int z) { if (x < 15 && x > 3 && z < 15 && z > 3) { for (var y = StandardWorldProvider.WaterLevel; y < 256; y++) { if (StandardWorldProvider.GetRandomNumber(0, 30) == 5) { if (chunk.GetBlock(x, y + 1, z) == biome.TopBlock.Id) { GenerateTree(chunk, x, y + 1, z, biome); } } } } }
public void GenerateCave(ChunkColumn chunk) { _gcRandom = new GcRandom(chunk, _seedi); for (var x = 0; x < 16; x++) { for (var z = 0; z < 16; z++) { for (var y = 50; y >= 6; y--) { if (_gcRandom.IsInCave(x, y, z)) { chunk.SetBlock(x, y, z, new BlockAir()); } } } } }
public override void Decorate(ChunkColumn chunk, BiomeBase biome, int x, int z) { _chunke = chunk; for (var y = 1 /*No need to check first layer :p*/; y < 128 /*Nothing above this*/; y++) { if (chunk.GetBlock(x, y, z) == 1) { if (y < 128) { GenerateCoal(x, y, z); } if (y < 64) { GenerateIron(x, y, z); } if (y < 29) { GenerateGold(x, y, z); } if (y < 23) { GenerateLapis(x, y, z); } if (y < 16) { if (y > 12) { if (StandardWorldProvider.GetRandomNumber(0, 3) == 2) { GenerateDiamond(x, y, z); } } else { GenerateDiamond(x, y, z); } } } } }
public override void Create(ChunkColumn chunk, int x, int y, int z) { var location = new Vector3(x, y, z); if (!ValidLocation(new Vector3(x, y, z))) return; var r = new Random(); var height = r.Next(7, 8); GenerateColumn(chunk, location, height, new Block(17) {Metadata = 1}); for (var Y = 1; Y < height; Y++) { if (Y%2 == 0) { GenerateVanillaCircle(chunk, location + new Vector3(0, Y + 1, 0), _leafRadius - 1, new Block(18) {Metadata = 1}); continue; } GenerateVanillaCircle(chunk, location + new Vector3(0, Y + 1, 0), _leafRadius, new Block(18) {Metadata = 1}); } GenerateTopper(chunk, location + new Vector3(0, height, 0), 0x1); }
internal GcRandom(ChunkColumn chunki, int seed) { Chunk = chunki; _subtractForLessThanCutoff = _amplitude1 - _cutOff; _f1Xz = 1.0/_sxz; _f1Y = 1.0/_sy; if (_maxCaveHeight - _minCaveHeight > 128) { _caveBandBuffer = 32; } else { _caveBandBuffer = 16; } _noiseGen1 = new SimplexPerlin(seed, NoiseQuality.Fast); _noiseGen2 = new SimplexPerlin((int) _noiseGen1.GetValue(Chunk.X, Chunk.Z), NoiseQuality.Fast); _noiseGen3 = new SimplexPerlin((int) _noiseGen1.GetValue(Chunk.X, Chunk.Z), NoiseQuality.Fast); }
public override void Decorate(ChunkColumn chunk, BiomeBase biome) { for (var x = 0; x < 16; x++) { for (var z = 0; z < 16; z++) { for (var y = 0; y < LavaLevel; y++) { //Lake generation if (y < LavaLevel) { if (chunk.GetBlock(x, y + 1, z) == 0) { chunk.SetBlock(x, y + 1, z, BlockFactory.GetBlockById(10)); //Lava } } } } } }
public void Calculate(ChunkColumn chunk, ChunkCoordinates chunkCoordinates) { var cx = (chunkCoordinates.X << 4); var cz = (chunkCoordinates.Z << 4); for (int x = 0; x < 16; x++) { var rx = cx + x; for (int z = 0; z < 16; z++) { var rz = cz + z; int height = chunk.GetHeight(x, z); for (int y = height; y < 255; y++) { Process(chunk, rx, height, rz); //Process(chunk, x, y, z); } } } }
public Awaiter Load(out IChunkColumn column, Guid universeGuid, IPlanet planet, Index2 columnIndex) { var package = new Package((ushort)OfficialCommand.LoadColumn, 0); using (var memoryStream = new MemoryStream()) using (var binaryWriter = new BinaryWriter(memoryStream)) { binaryWriter.Write(universeGuid.ToByteArray()); binaryWriter.Write(planet.Id); binaryWriter.Write(columnIndex.X); binaryWriter.Write(columnIndex.Y); package.Payload = memoryStream.ToArray(); } column = new ChunkColumn(); var awaiter = GetAwaiter(column, package.UId); client.SendPackage(package); return(awaiter); }
private bool IsValidSugarCaneLocation(ChunkColumn chunk, int x, int y, int z) { if (y - 1 <= 0) { return(false); } if (x - 1 >= 0 && x + 1 < 16) { if (z - 1 >= 0 && z + 1 < 16) { if (chunk.GetBlock(x + 1, y, z) == 8 || chunk.GetBlock(x - 1, y, z) == 8 || chunk.GetBlock(x, y, z + 1) == 8 || chunk.GetBlock(x, y, z - 1) == 8) { return(true); } } } return(false); }
public override ChunkColumn LoadChunk(int x, int z) { var u = Globals.Decompress(File.ReadAllBytes(Folder + "/" + x + "." + z + ".cfile")); var reader = new MSGBuffer(u); var blockLength = reader.ReadInt(); var block = reader.ReadUShortLocal(blockLength); var metalength = reader.ReadInt(); var blockmeta = reader.ReadShortLocal(metalength); //var blockies = new Block[block.Length]; //for (var i = 0; i < block.Length; i++) //{ // blockies[i] = new Block(block[i]) { Metadata = (byte) blockmeta[i] }; //} var skyLength = reader.ReadInt(); var skylight = reader.Read(skyLength); var lightLength = reader.ReadInt(); var blocklight = reader.Read(lightLength); var biomeIdLength = reader.ReadInt(); var biomeId = reader.Read(biomeIdLength); var cc = new ChunkColumn { Blocks = block, Metadata = blockmeta, Blocklight = { Data = blocklight }, Skylight = { Data = skylight }, BiomeId = biomeId, X = x, Z = z }; Debug.WriteLine("We should have loaded " + x + ", " + z); return(cc); }
public IChunkColumn GenerateColumn(IEnumerable <IBlockDefinition> blockDefinitions, IPlanet planet, Index2 index) { IBlockDefinition sandDefinition = blockDefinitions.FirstOrDefault(d => typeof(SandBlockDefinition) == d.GetType()); ushort sandIndex = (ushort)(Array.IndexOf(blockDefinitions.ToArray(), sandDefinition) + 1); IChunk[] result = new IChunk[planet.Size.Z]; ChunkColumn column = new ChunkColumn(result, planet.Id, index); for (int layer = 0; layer < planet.Size.Z; layer++) { result[layer] = new Chunk(new Index3(index.X, index.Y, layer), planet.Id); } int part = (planet.Size.Z * Chunk.CHUNKSIZE_Z) / 4; for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++) { float heightY = (float)Math.Sin((float)(y * Math.PI) / 15f); for (int x = 0; x < Chunk.CHUNKSIZE_X; x++) { float heightX = (float)Math.Sin((float)(x * Math.PI) / 18f); float height = ((heightX + heightY + 2) / 4) * (2 * part); for (int z = 0; z < planet.Size.Z * Chunk.CHUNKSIZE_Z; z++) { if (z < (int)(height + part)) { int block = z % (Chunk.CHUNKSIZE_Z); int layer = (int)(z / Chunk.CHUNKSIZE_Z); result[layer].SetBlock(x, y, block, sandIndex); } } } } column.CalculateHeights(); return(column); }
public static ChunkColumn ReadColumnData(byte[] data, int chunkX, int chunkZ, bool chunksContinuous, bool hasSkyLight, int chunkMask) { using (MemoryStream memstream = new MemoryStream(data, false)) { InputBuffer input = new InputBuffer(memstream); ChunkColumn column = new ChunkColumn(chunkX, chunkZ); for (int chunkY = 0; chunkY < 16; chunkY++) { if ((chunkMask & (1 << chunkY)) != 0) { BlockStorage blocks = new BlockStorage(input); input.ReadData(2048); if (hasSkyLight) { input.ReadData(2048); } column[chunkY] = new ChunkData(blocks); } } return(column); } }
private void NotifyNeighbours() { for (int x = -1; x <= 1; x++) { for (int z = -1; z <= 1; z++) { // Current chunk if (x == 0 && z == 0) { continue; } ChunkColumn aNeighbourChunk = World.GetColumn(colCoord.GetRelativePos(x, z)); // If we find a chunk without data, we don't generate if (aNeighbourChunk != null) { aNeighbourChunk.IncrementNeighbourDataCount(); } } } }
protected void GenerateVanillaLeaves(ChunkColumn chunk, Vector3 location, int radius, byte id, byte meta) { if (location.X > 16 || location.X < 0 || location.Z > 16 || location.Z < 0) { return; } var radiusOffset = radius; for (var yOffset = -radius; yOffset <= radius; yOffset = (yOffset + 1)) { var y = location.Y + yOffset; if (y > 255) { continue; } GenerateVanillaCircle(chunk, new Vector3(location.X, y, location.Z), radiusOffset, id, meta); if (yOffset != -radius && yOffset % 2 == 0) { radiusOffset--; } } }
public ChunkSection(ChunkColumn owner, int y, bool storeSkylight, int sections = 2) { Owner = owner; if (sections <= 0) { sections = 1; } this._yBase = y; //Data = new BlockStorage(); _blockStorages = new BlockStorage[sections]; for (int i = 0; i < sections; i++) { _blockStorages[i] = new BlockStorage(); } this.BlockLight = new NibbleArray(ArrayPool <byte> .Shared.Rent(2048)); MiNET.Worlds.ChunkColumn.Fill <byte>(BlockLight.Data, 0); if (storeSkylight) { this.SkyLight = new NibbleArray(ArrayPool <byte> .Shared.Rent(2048)); MiNET.Worlds.ChunkColumn.Fill <byte>(SkyLight.Data, 0xff); } //System.Collections.BitArray a = new System.Collections.BitArray(new byte[(16 * 16 * 16) / 8]); TransparentBlocks = new System.Collections.BitArray(new byte[(16 * 16 * 16) / 8]); SolidBlocks = new System.Collections.BitArray(new byte[(16 * 16 * 16) / 8]); ScheduledUpdates = new System.Collections.BitArray(new byte[(16 * 16 * 16) / 8]); ScheduledSkylightUpdates = new System.Collections.BitArray(new byte[(16 * 16 * 16) / 8]); ScheduledBlocklightUpdates = new System.Collections.BitArray(new byte[(16 * 16 * 16) / 8]); RenderedBlocks = new System.Collections.BitArray(new byte[(16 * 16 * 16) / 8]); for (int i = 0; i < TransparentBlocks.Length; i++) { TransparentBlocks[i] = true; SolidBlocks[i] = false; } }
public static byte GetBlock(int x, int y, int z) { ColumnCoord colCoord = GetColumnCoord(x, z); try { ChunkColumn chunkCol = null; if (columns.TryGetValue(colCoord, out chunkCol)) { if (chunkCol.hasMapData) { return(chunkCol.GetBlock(x - colCoord.x * ChunkColumn.chunkSize, y, z - colCoord.z * ChunkColumn.chunkSize)); } } } catch (Exception e) { Debug.Log("Chunk error!! " + e); } return(0); }
protected void GenerateVanillaCircle(ChunkColumn chunk, Vector3 location, int radius, byte id, byte meta, double corner = 0) { for (var I = -radius; I <= radius; I = (I + 1)) { for (var j = -radius; j <= radius; j = (j + 1)) { var max = (int)Math.Sqrt((I * I) + (j * j)); if (max <= radius) { if (I.Equals(-radius) && j.Equals(-radius) || I.Equals(-radius) && j.Equals(radius) || I.Equals(radius) && j.Equals(-radius) || I.Equals(radius) && j.Equals(radius)) { if (corner + radius * 0.2 < 0.4 || corner + radius * 0.2 > 0.7 || corner.Equals(0)) { continue; } } var x = location.X + I; var z = location.Z + j; if (x < 0 || z > 16) { continue; } if (z < 0 || z > 16) { continue; } if (chunk.GetBlock((int)x, (int)location.Y, (int)z) == 0) { chunk.SetBlock((int)x, (int)location.Y, (int)z, id); chunk.SetMetadata((int)x, (int)location.Y, (int)z, meta); } } } } }
public override void Create(ChunkColumn chunk, int x, int y, int z) { var block = chunk.GetBlock(x, y - 1, z); if (block != 2 && block != 3) { return; } var location = new Vector3(x, y, z); if (!ValidLocation(location, LeafRadius)) { return; } int height = Rnd.Next(4, MaxHeight); GenerateColumn(chunk, location, height, 17, 2); Vector3 leafLocation = location + new Vector3(0, height, 0); GenerateVanillaLeaves(chunk, leafLocation, LeafRadius, 18, 2); }
private void DecorateTrees(ChunkColumn chunk, BiomeBase biome) { for (var x = 0; x < 16; x++) { for (var z = 0; z < 16; z++) { for (var y = StandardWorldProvider.WaterLevel; y < 256; y++) { if (StandardWorldProvider.GetRandomNumber(0, 13) == 5) { //The if is so we don't have 'f****d up' trees xD if (x < 15 && x > 3 && z < 15 && z > 3) { if (chunk.GetBlock(x, y + 1, z) == biome.TopBlock.Id) { GenerateTree(chunk, x, y + 1, z, biome); } } } } } } }
private void SetBiomeBlocks(ChunkColumn chunk, ChunkLandscape landscape) { int worldX = chunk.X * 16; int worldZ = chunk.Z * 16; var coords = new BlockCoordinates(worldX, 0, worldZ); for (int x = 0; x < 16; x++) { coords.X = worldX + x; for (int z = 0; z < 16; z++) { coords.Z = worldZ + z; var index = NoiseMap.GetIndex(x, z); var river = landscape.River[index]; int depth = -1; landscape.Biome[index].Replace(chunk, coords, x, z, depth, this, landscape.Noise, river, landscape.Biome); chunk.biomeId[index] = (byte)landscape.Biome[index].Id; } } }
public override void Decorate(ChunkColumn chunk, BiomeBase biome) { for (var x = 0; x < 16; x++) { for (var z = 0; z < 16; z++) { //Check for temperature. for (var y = 0; y < StandardWorldProvider.WaterLevel; y++) { //Lake generation if (y < StandardWorldProvider.WaterLevel) { if (chunk.GetBlock(x, y, z) == 2 || chunk.GetBlock(x, y, z) == 3) //Grass or Dirt? { if (StandardWorldProvider.GetRandomNumber(1, 40) == 1 && y < StandardWorldProvider.WaterLevel - 4) { chunk.SetBlock(x, y, z, BlockFactory.GetBlockById(82)); //Clay } else { chunk.SetBlock(x, y, z, new BlockSand()); //Sand chunk.BiomeId[x * 16 + z] = 16; //Beach } } if (chunk.GetBlock(x, y + 1, z) == 0) { if (y < StandardWorldProvider.WaterLevel - 3) { chunk.SetBlock(x, y + 1, z, new BlockFlowingWater()); //Water chunk.BiomeId[x * 16 + z] = 0; //Ocean } } } } } } }
public bool RecalcSkyLight(ChunkColumn chunk, World level) { if (chunk == null) { return(false); } for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { if (chunk.isAllAir && !IsOnChunkBorder(x, z)) { continue; } int height = GetHigestSurrounding(x, z, chunk, level); if (height == 0) { continue; } //var skyLight = chunk.GetSkyLight(x, height, z); //if (skyLight == 15) { Block block = level.GetConvertedBlock(new BlockCoordinates(x + (chunk.x * 16), height, z + (chunk.z * 16))); Calculate(level, block); } //else //{ // Log.Error($"Block with wrong light level. Expected 15 but was {skyLight}"); //} } } return(true); }
public IChunkColumn GenerateColumn(IEnumerable<IBlockDefinition> blockDefinitions, IPlanet planet, Index2 index) { IBlockDefinition sandDefinition = blockDefinitions.FirstOrDefault(d => typeof(SandBlockDefinition) == d.GetType()); ushort sandIndex = (ushort)(Array.IndexOf(blockDefinitions.ToArray(), sandDefinition) + 1); IChunk[] result = new IChunk[planet.Size.Z]; ChunkColumn column = new ChunkColumn(result, planet.Id, index); for (int layer = 0; layer < planet.Size.Z; layer++) result[layer] = new Chunk(new Index3(index.X, index.Y, layer), planet.Id); int part = (planet.Size.Z * Chunk.CHUNKSIZE_Z) / 4; for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++) { float heightY = (float)Math.Sin((float)(y * Math.PI) / 15f); for (int x = 0; x < Chunk.CHUNKSIZE_X; x++) { float heightX = (float)Math.Sin((float)(x * Math.PI) / 18f); float height = ((heightX + heightY + 2) / 4) * (2 * part); for (int z = 0; z < planet.Size.Z * Chunk.CHUNKSIZE_Z; z++) { if (z < (int)(height + part)) { int block = z % (Chunk.CHUNKSIZE_Z); int layer = (int)(z / Chunk.CHUNKSIZE_Z); result[layer].SetBlock(x, y, block, sandIndex); } } } } column.CalculateHeights(); return column; }
public override void OnPacket(ChunkDataPacket chunkData) { byte[] data = chunkData.Data; var chunkId = new Int2(chunkData.ChunkX, chunkData.ChunkZ); ChunkColumn chunkColumn; if (chunkData.Fullchunk) { chunkColumn = new ChunkColumn(); } else { chunkColumn = world.Chunks[chunkId]; } try { chunkColumn.Parse(ref data, chunkData.PrimaryBitMask); } catch (Exception e) { var guid = Guid.NewGuid(); Console.WriteLine($"Error: Chunk column read error on chunk {guid}) with {e.StackTrace}"); File.WriteAllText($"{guid}.txt", Convert.ToBase64String(chunkData.Data)); } lock (chunkData) { if (chunkData.Fullchunk) { if (world.Chunks.ContainsKey(chunkId)) { world.Chunks.Remove(chunkId); } world.Chunks.Add(chunkId, chunkColumn); } } }
public ChunkColumn GenerateChunkColumn(ChunkCoordinates chunkCoordinates) { return(_cache.GetOrAdd( chunkCoordinates, (cc) => { ChunkColumn chunk = new ChunkColumn() { X = chunkCoordinates.X, Z = chunkCoordinates.Z }; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { int rx = (chunkCoordinates.X * 16) + x; int rz = (chunkCoordinates.Z * 16) + z; BlockState iblockstate = GetBlockStateFor(rx, rz); if (iblockstate != null) { chunk.SetBlockState(x, 1, z, iblockstate); //chunk.Height[((z << 4) + (x))] = 70; } // chunk.SetSkyLight(x, 70, z, 15); // chunk.SetSkyLight(x, 71, z, 15); // chunk.SetSkyLight(x, 69, z, 15); } } //chunk.CalculateHeight(); return chunk; })); }
private BlockColumnMeta GetColumnMeta(ChunkColumn chunk, int x, int z) { var pos = new BlockPosition((chunk.x << 4) + x, (chunk.z << 4) + z); var y = chunk.GetHeight(x, z); //var highestBlock = Level.GetBlock(pos.X, y, pos.Z); var highestBlock = GetHighestBlock(pos.X, pos.Z); if (highestBlock == null) { return(new BlockColumnMeta() { Position = pos, Height = 0, BiomeId = 0, BlockId = 0, LightLevel = 0 }); } //_skyLightCalculations.Calculate(Level, highestBlock); //if (highestBlock.LightLevel > 0) //{ // BlockLightCalculations.Calculate(Level, highestBlock); //} return(new BlockColumnMeta() { Position = pos, Height = (byte)highestBlock.Coordinates.Y, BiomeId = highestBlock.BiomeId, BlockId = highestBlock.Id, LightLevel = chunk.GetSkylight(x, y, z) }); }
public override void Decorate(ChunkColumn chunk, BiomeBase biome) { for (var x = 0; x < 16; x++) { for (var z = 0; z < 16; z++) { //Check for temperature. for (var y = 0; y < NetherWorldProvider.WaterLevel; y++) { //Lake generation if (y < NetherWorldProvider.WaterLevel) { if (chunk.GetBlock(x, y + 1, z) == 0) { if (y < NetherWorldProvider.WaterLevel - 3) { chunk.SetBlock(x, y + 1, z, new BlockStationaryLava()); //Water } } } } } } }
public override void HandleMcpeLevelChunk(McpeLevelChunk message) { if (!Client._chunks.ContainsKey(new Tuple <int, int>(message.chunkX, message.chunkZ))) { //Log.Debug($"Chunk X={message.chunkX}, Z={message.chunkZ}, size={message.chunkData.Length}, Count={Client._chunks.Count}"); try { ChunkColumn chunk = ClientUtils.DecodeChunkColumn((int)message.subChunkCount, message.chunkData, _blockPallet, _internalStates); if (chunk != null) { chunk.x = message.chunkX; chunk.z = message.chunkZ; chunk.RecalcHeight(); Client._chunks.TryAdd(new Tuple <int, int>(message.chunkX, message.chunkZ), chunk); //Log.Debug($"Added parsed bedrock chunk X={chunk.x}, Z={chunk.z}"); } } catch (Exception e) { Log.Error("Reading chunk", e); } } }
public override void HandleMcpeLevelChunk(McpeLevelChunk message) { // TODO doesn't work anymore I guess if (Client.IsEmulator) { return; } Client.Chunks.GetOrAdd(new ChunkCoordinates(message.chunkX, message.chunkZ), coordinates => { Log.Debug($"Chunk X={message.chunkX}, Z={message.chunkZ}, size={message.chunkData.Length}, Count={Client.Chunks.Count}"); ChunkColumn chunk = null; try { chunk = ClientUtils.DecodeChunkColumn((int)message.subChunkCount, message.chunkData); if (chunk != null) { chunk.X = coordinates.X; chunk.Z = coordinates.Z; chunk.RecalcHeight(); Log.DebugFormat("Chunk X={0}, Z={1}", chunk.X, chunk.Z); foreach (KeyValuePair <BlockCoordinates, NbtCompound> blockEntity in chunk.BlockEntities) { Log.Debug($"Blockentity: {blockEntity.Value}"); } } } catch (Exception e) { Log.Error("Reading chunk", e); } return(chunk); }); }
private void GenerateTree(ChunkColumn chunk, int x, int treebase, int z, WoodType woodType) { new OakTree().Create(chunk, x, treebase, z); }
private void GenerateTree(ChunkColumn chunk, int x, int treebase, int z) { int treeheight = GetRandomNumber(4, 5); chunk.SetBlock(x, treebase + treeheight + 2, z, 18); //Top leave chunk.SetBlock(x, treebase + treeheight + 1, z + 1, 18); chunk.SetBlock(x, treebase + treeheight + 1, z - 1, 18); chunk.SetBlock(x + 1, treebase + treeheight + 1, z, 18); chunk.SetBlock(x - 1, treebase + treeheight + 1, z, 18); chunk.SetBlock(x, treebase + treeheight, z + 1, 18); chunk.SetBlock(x, treebase + treeheight, z - 1, 18); chunk.SetBlock(x + 1, treebase + treeheight, z, 18); chunk.SetBlock(x - 1, treebase + treeheight, z, 18); chunk.SetBlock(x + 1, treebase + treeheight, z + 1, 18); chunk.SetBlock(x - 1, treebase + treeheight, z - 1, 18); chunk.SetBlock(x + 1, treebase + treeheight, z - 1, 18); chunk.SetBlock(x - 1, treebase + treeheight, z + 1, 18); for (int i = 0; i <= treeheight; i++) { chunk.SetBlock(x, treebase + i, z, 17); } }
private bool SaveChunk(ChunkColumn chunk) { File.WriteAllBytes(_folder + "/" + chunk.X + "." + chunk.Z + ".cfile", Globals.Compress(chunk.Export())); return(true); }
public ChunkColumn GetChunk(int X, int Z) { var width = 32; var depth = 32; var rx = X >> 5; var rz = Z >> 5; var filePath = Path.Combine(_basePath, string.Format(@"region\r.{0}.{1}.mca", rx, rz)); if (!File.Exists(filePath)) { return(_backEndGenerator.GenerateChunkColumn(new Vector2(X, Z))); } using (var regionFile = File.OpenRead(filePath)) { var buffer = new byte[8192]; regionFile.Read(buffer, 0, 8192); var xi = (X % width); if (xi < 0) { xi += 32; } var zi = (Z % depth); if (zi < 0) { zi += 32; } var tableOffset = (xi + zi * width) * 4; regionFile.Seek(tableOffset, SeekOrigin.Begin); var offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); var offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; var length = regionFile.ReadByte(); //if (offset == 0 || length == 0) return _backEndGenerator.GenerateChunkColumn(new Vector2(X, Z)); if (offset == 0 || length == 0) { return(_backEndGenerator.GenerateChunkColumn(new Vector2(X, Z))); } regionFile.Seek(offset, SeekOrigin.Begin); var waste = new byte[4]; regionFile.Read(waste, 0, 4); var compressionMode = regionFile.ReadByte(); var nbt = new NbtFile(); nbt.LoadFromStream(regionFile, NbtCompression.ZLib); var dataTag = nbt.RootTag["Level"]; var sections = dataTag["Sections"] as NbtList; var chunk = new ChunkColumn { X = X, Z = Z, BiomeId = dataTag["Biomes"].ByteArrayValue }; for (var 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 (var sectionTag in sections) { var sy = sectionTag["Y"].ByteValue * 16; var blocks = sectionTag["Blocks"].ByteArrayValue; var data = sectionTag["Data"].ByteArrayValue; var addTag = sectionTag["Add"]; var adddata = new byte[2048]; if (addTag != null) { adddata = addTag.ByteArrayValue; } var blockLight = sectionTag["BlockLight"].ByteArrayValue; var skyLight = sectionTag["SkyLight"].ByteArrayValue; for (var x = 0; x < 16; x++) { for (var z = 0; z < 16; z++) { for (var y = 0; y < 16; y++) { var yi = sy + y - _waterOffsetY; if (yi < 0 || yi >= 256) { continue; } var anvilIndex = y * 16 * 16 + z * 16 + x; var blockId = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8); var b = BlockFactory.GetBlockById((ushort)blockId); b.Metadata = Nibble4(data, anvilIndex); chunk.SetBlock(x, yi, z, b); chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex)); chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex)); } } } } var entities = dataTag["Entities"] as NbtList; var tileEntities = dataTag["TileEntities"] as NbtList; if (tileEntities != null) { foreach (var nbtTag in tileEntities) { var blockEntityTag = (NbtCompound)nbtTag; string entityId = blockEntityTag["id"].StringValue; int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue - _waterOffsetY; int z = blockEntityTag["z"].IntValue; blockEntityTag["y"] = new NbtInt("y", y); TileEntity blockEntity = TileEntityFactory.GetBlockEntityById(entityId); if (blockEntity != null) { blockEntityTag.Name = string.Empty; chunk.SetBlockEntity(new Vector3(x, y, z), blockEntityTag); } } } var tileTicks = dataTag["TileTicks"] as NbtList; chunk.IsDirty = false; 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; } 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 < 128; 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 < 127; y++) { //the overhang byte thisblock = chunk.GetBlock(x, y, z); byte 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 < 127; y++) { byte thisblock = chunk.GetBlock(x, y, z); byte 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); } } } } } } } }
private bool SaveChunk(ChunkColumn chunk) { File.WriteAllBytes(_folder + "/" + chunk.X + "." + chunk.Z + ".cfile", Globals.Compress(chunk.Export())); return true; }
private void PopulateChunk(ChunkColumn chunk) { var bottom = new SimplexOctaveGenerator(ServerSettings.Seed.GetHashCode(), 8); var overhang = new SimplexOctaveGenerator(ServerSettings.Seed.GetHashCode(), 8); overhang.SetScale(1/OverhangScale); bottom.SetScale(1/Groundscale); for (var x = 0; x < 16; x++) { for (var z = 0; z < 16; z++) { float ox = x + chunk.X*16; float oz = z + chunk.Z*16; var cBiome = _biomeManager.GetBiome((int) ox, (int) oz); chunk.BiomeId[x*16 + z] = cBiome.MinecraftBiomeId; var bottomHeight = (int) ((bottom.Noise(ox, oz, BottomsFrequency, BottomsAmplitude)*BottomsMagnitude) + BottomOffset + cBiome.BaseHeight); var maxHeight = (int) ((overhang.Noise(ox, oz, OverhangFrequency, OverhangAmplitude)*OverhangsMagnitude) + bottomHeight + OverhangOffset); maxHeight = Math.Max(1, maxHeight); for (var y = 0; y < maxHeight && y < 256; y++) { if (y == 0) { chunk.SetBlock(x, y, z, BlockFactory.GetBlockById(7)); continue; } if (y > bottomHeight) { //part where we do the overhangs if (EnableOverhang) { var density = overhang.Noise(ox, y, oz, OverhangFrequency, OverhangAmplitude); if (density > Threshold) chunk.SetBlock(x, y, z, BlockFactory.GetBlockById(1)); } } else { chunk.SetBlock(x, y, z, BlockFactory.GetBlockById(1)); } } //Turn the blocks ontop into the correct material for (var y = 0; y < 256; y++) { if (chunk.GetBlock(x, y + 1, z) == 0 && chunk.GetBlock(x, y, z) == 1) { chunk.SetBlock(x, y, z, cBiome.TopBlock); chunk.SetBlock(x, y - 1, z, cBiome.Filling); chunk.SetBlock(x, y - 2, z, cBiome.Filling); } } foreach (var decorator in cBiome.Decorators) { decorator.Decorate(chunk, cBiome, x, z); } new OreDecorator().Decorate(chunk, cBiome, x, z); //Ores :) new BedrockDecorator().Decorate(chunk, cBiome, x, z); //Random bedrock :) } } new WaterDecorator().Decorate(chunk, new PlainsBiome()); //For now, ALWAYS use the water decorator on all chunks... _cavegen.GenerateCave(chunk); new LavaDecorator().Decorate(chunk, new PlainsBiome()); }
public override ChunkColumn LoadChunk(int x, int z) { var u = Globals.Decompress(File.ReadAllBytes(_folder + "/" + x + "." + z + ".cfile")); var reader = new DataBuffer(u); var blockLength = reader.ReadInt(); var block = reader.ReadUShortLocal(blockLength); var metalength = reader.ReadInt(); var blockmeta = reader.ReadUShortLocal(metalength); var skyLength = reader.ReadInt(); var skylight = reader.Read(skyLength); var lightLength = reader.ReadInt(); var blocklight = reader.Read(lightLength); var biomeIdLength = reader.ReadInt(); var biomeId = reader.Read(biomeIdLength); var cc = new ChunkColumn { Blocks = block, Metadata = blockmeta, Blocklight = {Data = blocklight}, Skylight = {Data = skylight}, BiomeId = biomeId, X = x, Z = z }; Debug.WriteLine("We should have loaded " + x + ", " + z); return cc; }
public override ChunkColumn GenerateChunkColumn(Vector2 chunkCoordinates) { ChunkColumn c; if (ChunkCache.TryGetValue(new Tuple<int, int>(chunkCoordinates.X, chunkCoordinates.Z), out c)) return c; if (File.Exists((_folder + "/" + chunkCoordinates.X + "." + chunkCoordinates.Z + ".cfile"))) { var cd = LoadChunk(chunkCoordinates.X, chunkCoordinates.Z); lock (ChunkCache) { if (!ChunkCache.ContainsKey(new Tuple<int, int>(cd.X, cd.Z))) ChunkCache.Add(new Tuple<int, int>(cd.X, cd.Z), cd); } return cd; } var chunk = new ChunkColumn {X = chunkCoordinates.X, Z = chunkCoordinates.Z}; PopulateChunk(chunk); if (!ChunkCache.ContainsKey(new Tuple<int, int>(chunkCoordinates.X, chunkCoordinates.Z))) ChunkCache.Add(new Tuple<int, int>(chunkCoordinates.X, chunkCoordinates.Z), 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 static void SaveChunk(ChunkColumn chunk, string basePath, int yoffset) { var coordinates = new ChunkCoordinates(chunk.X, chunk.Z); var width = 32; var depth = 32; var rx = coordinates.X >> 5; var rz = coordinates.Z >> 5; var filePath = Path.Combine(basePath, string.Format(@"region\r.{0}.{1}.mca", rx, rz)); if (!File.Exists(filePath)) { // Make sure directory exist Directory.CreateDirectory(Path.Combine(basePath, "region")); // Create empty region file using (var regionFile = File.Open(filePath, FileMode.CreateNew)) { var buffer = new byte[8192]; regionFile.Write(buffer, 0, buffer.Length); } return; } using (var regionFile = File.Open(filePath, FileMode.Open)) { var buffer = new byte[8192]; regionFile.Read(buffer, 0, buffer.Length); var xi = (coordinates.X % width); if (xi < 0) { xi += 32; } var zi = (coordinates.Z % depth); if (zi < 0) { zi += 32; } var tableOffset = (xi + zi * width) * 4; regionFile.Seek(tableOffset, SeekOrigin.Begin); var offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); var offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; var length = regionFile.ReadByte(); if (offset == 0 || length == 0) { regionFile.Seek(0, SeekOrigin.End); offset = (int)regionFile.Position; regionFile.Seek(tableOffset, SeekOrigin.Begin); var bytes = BitConverter.GetBytes(offset >> 4); Array.Reverse(bytes); regionFile.Write(bytes, 0, 3); regionFile.WriteByte(1); } regionFile.Seek(offset, SeekOrigin.Begin); var waste = new byte[4]; regionFile.Write(waste, 0, 4); // Lenght regionFile.WriteByte(0x02); // Compression mode // Write NBT var nbt = CreateNbtFromChunkColumn(chunk, yoffset); var nbtBuf = nbt.SaveToBuffer(NbtCompression.ZLib); regionFile.Write(nbtBuf, 0, nbtBuf.Length); var lenght = nbtBuf.Length + 5; int reminder; Math.DivRem(lenght, 4096, out reminder); var padding = new byte[4096 - reminder]; if (padding.Length > 0) { regionFile.Write(padding, 0, padding.Length); } } }
private static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk, int yoffset) { var nbt = new NbtFile(); var 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)); var sectionsTag = new NbtList("Sections"); levelTag.Add(sectionsTag); for (var i = 0; i < 8; i++) { var sectionTag = new NbtCompound(); sectionsTag.Add(sectionTag); sectionTag.Add(new NbtByte("Y", (byte)i)); var sy = i * 16; var blocks = new byte[4096]; var data = new byte[2048]; var blockLight = new byte[2048]; var skyLight = new byte[2048]; for (var x = 0; x < 16; x++) { for (var z = 0; z < 16; z++) { for (var y = 0; y < 16; y++) { var yi = sy + y; if (yi < 0 || yi >= 256) { continue; // ? } var anvilIndex = (y + yoffset) * 16 * 16 + z * 16 + x; var blockId = chunk.GetBlock(x, yi, z); blocks[anvilIndex] = (byte)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)); } levelTag.Add(new NbtList("Entities", NbtTagType.Compound)); levelTag.Add(new NbtList("TileEntities", NbtTagType.Compound)); levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound)); return(nbt); }
public static void SaveChunkToAnvil(ChunkColumn chunk) { AnvilWorldProvider.SaveChunk(chunk, _basePath, 0); }
public ChunkMeshData[] GenerateChunkMeshData(ChunkColumn chunkCol, int yIndex) { ChunkMeshData[] chunkMeshData = new ChunkMeshData[2]; // Initializing mesh data's for (int i = 0; i < chunkMeshData.Length; i++) { chunkMeshData[i] = new ChunkMeshData(); } int yOffset = yIndex * ChunkColumn.chunkSize; Color32 currentColor; int currentFaceCount; int meshBufferIndex; for (int z = 0; z < ChunkColumn.chunkSize; z++) { for (int y = 0; y < ChunkColumn.chunkSize; y++) { for (int x = 0; x < ChunkColumn.chunkSize; x++) { byte currentBlockID = chunkCol.GetBlock(x, y + yOffset, z); if (currentBlockID == 0) { // Block is air, don't generate a mesh continue; } // Block is not air, generate a mesh currentFaceCount = 0; // Assume block is solid meshBufferIndex = 0; // Compare ID to transparent blockID's if (IsTransparentBlock(currentBlockID)) { // It's a transparent block, use transparent mesh buffer meshBufferIndex = 1; } // Block above if (ShouldDrawFace(currentBlockID, chunkCol.GetBlock(x, y + yOffset + 1, z), meshBufferIndex)) { chunkMeshData[meshBufferIndex].AddCubeFace(x, y, z, Faces.Top); currentFaceCount++; } // North block if (ShouldDrawFace(currentBlockID, chunkCol.GetBlock(x, y + yOffset, z + 1), meshBufferIndex)) { chunkMeshData[meshBufferIndex].AddCubeFace(x, y, z, Faces.North); currentFaceCount++; } // East block if (ShouldDrawFace(currentBlockID, chunkCol.GetBlock(x + 1, y + yOffset, z), meshBufferIndex)) { chunkMeshData[meshBufferIndex].AddCubeFace(x, y, z, Faces.East); currentFaceCount++; } // South block if (ShouldDrawFace(currentBlockID, chunkCol.GetBlock(x, y + yOffset, z - 1), meshBufferIndex)) { chunkMeshData[meshBufferIndex].AddCubeFace(x, y, z, Faces.South); currentFaceCount++; } // West block if (ShouldDrawFace(currentBlockID, chunkCol.GetBlock(x - 1, y + yOffset, z), meshBufferIndex)) { chunkMeshData[meshBufferIndex].AddCubeFace(x, y, z, Faces.West); currentFaceCount++; } // Bottom block if (ShouldDrawFace(currentBlockID, chunkCol.GetBlock(x, y + yOffset - 1, z), meshBufferIndex)) { chunkMeshData[meshBufferIndex].AddCubeFace(x, y, z, Faces.Bottom); currentFaceCount++; } if (currentFaceCount > 0) { // Block is visible (has faces) currentColor = EvaluateColor(chunkCol.colCoord.x * ChunkColumn.chunkSize + x, yIndex * ChunkColumn.chunkSize + y, chunkCol.colCoord.z * ChunkColumn.chunkSize + z, currentBlockID); chunkMeshData[meshBufferIndex].AddColor(currentColor, currentFaceCount); } } } } return(chunkMeshData); }
private static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk) { 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 + _waterOffsetY) * 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)); } levelTag.Add(new NbtList("Entities", NbtTagType.Compound)); levelTag.Add(new NbtList("TileEntities", NbtTagType.Compound)); levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound)); return(nbt); }
private void PopulateChunk(ChunkColumn chunk) { var bottom = new SimplexOctaveGenerator(ServerSettings.Seed.GetHashCode(), 8); var overhang = new SimplexOctaveGenerator(ServerSettings.Seed.GetHashCode(), 8); overhang.SetScale(1 / OverhangScale); bottom.SetScale(1 / Groundscale); for (var x = 0; x < 16; x++) { for (var z = 0; z < 16; z++) { float ox = x + chunk.X * 16; float oz = z + chunk.Z * 16; var cBiome = _biomeManager.GetBiome((int)ox, (int)oz); chunk.BiomeId[x * 16 + z] = cBiome.MinecraftBiomeId; var bottomHeight = (int) ((bottom.Noise(ox, oz, BottomsFrequency, BottomsAmplitude) * BottomsMagnitude) + BottomOffset + cBiome.BaseHeight); var maxHeight = (int) ((overhang.Noise(ox, oz, OverhangFrequency, OverhangAmplitude) * OverhangsMagnitude) + bottomHeight + OverhangOffset); maxHeight = Math.Max(1, maxHeight); for (var y = 0; y < maxHeight && y < 256; y++) { if (y == 0) { chunk.SetBlock(x, y, z, BlockFactory.GetBlockById(7)); continue; } if (y > bottomHeight) { //part where we do the overhangs if (EnableOverhang) { var density = overhang.Noise(ox, y, oz, OverhangFrequency, OverhangAmplitude); if (density > Threshold) { chunk.SetBlock(x, y, z, BlockFactory.GetBlockById(1)); } } } else { chunk.SetBlock(x, y, z, BlockFactory.GetBlockById(1)); } } //Turn the blocks ontop into the correct material for (var y = 0; y < 256; y++) { if (chunk.GetBlock(x, y + 1, z) == 0 && chunk.GetBlock(x, y, z) == 1) { chunk.SetBlock(x, y, z, cBiome.TopBlock); chunk.SetBlock(x, y - 1, z, cBiome.Filling); chunk.SetBlock(x, y - 2, z, cBiome.Filling); } } foreach (var decorator in cBiome.Decorators) { decorator.Decorate(chunk, cBiome, x, z); } new OreDecorator().Decorate(chunk, cBiome, x, z); //Ores :) new BedrockDecorator().Decorate(chunk, cBiome, x, z); //Random bedrock :) } } new WaterDecorator().Decorate(chunk, new PlainsBiome()); //For now, ALWAYS use the water decorator on all chunks... _cavegen.GenerateCave(chunk); new LavaDecorator().Decorate(chunk, new PlainsBiome()); }
public override void Decorate(ChunkColumn chunk, BiomeBase biome) { }