private BlockDistribution GenerateBlockDistribution(ChunkPos pos) { var rnd = new System.Random(persistor.GetSeed() - pos.x * 31 - pos.z * 23); double height; BlockDistribution blocks = new BlockDistribution(); bool hasTree = false; for (int x = 0; x < TerrainChunk.CHUNK_SIZE + 2; x++) { for (int z = 0; z < TerrainChunk.CHUNK_SIZE + 2; z++) { height = Math.Floor(ComputeHeightAt(pos.x + x - 1, pos.z + z - 1)); for (int y = 0; y < TerrainChunk.CHUNK_HEIGHT; y++) { blocks[x, y, z] = GetForHeight(y, height); } if (!hasTree && x > 4 && x < 12 && z > 4 && z < 12) { int r = rnd.Next(1, 115 + (int)Math.Pow(height, height / 65.0)); if (r == 2) { hasTree = true; GenerateTree(rnd, blocks, x, (int)height + 1, z); } } } } return(blocks); }
private Action <Stream> BlocksToBytes(BlockDistribution blocks) => str => { foreach (BlockType b in blocks) { str.WriteByte((byte)b); } str.Flush(); };
private void CacheChunk(ChunkPos pos, BlockDistribution blocks) { cache.AddFirst(pos); chunkBlocks.Add(pos, blocks); if (cache.Count > CACHE_SIZE) { SaveChunk(pos, chunkBlocks[pos]); var toRemove = cache.Last.Value; chunkBlocks.Remove(toRemove); cache.RemoveLast(); } }
private void SaveChunk(ChunkPos pos, BlockDistribution blocks) { if (blocks == null) { throw new ApplicationException("Chunk not loaded"); } if (!blocks.Dirty) { return; } blocks.Dirty = false; Save(GetChunkFile(pos), BlocksToBytes(blocks)); }
private BlockDistribution BytesToBlocks(byte[] bytes) { BlockDistribution blocks = new BlockDistribution(); long i = 0; for (int x = 1; x < BlockDistribution.SIDE - 1; x++) { for (int z = 1; z < BlockDistribution.SIDE - 1; z++) { for (int y = 0; y < BlockDistribution.HEIGHT; y++) { blocks[x, y, z] = (BlockType)bytes[i++]; } } } return(blocks); }
private void GenerateTree(System.Random r, BlockDistribution blocks, int x, int y, int z) { int t = r.Next(2, 5); int h = r.Next(4, 6); int w = r.Next(1, 4); int w2 = r.Next(1, 4); int hh = w + w2 >= 4 ? 1 : 0; for (int k = y + 2 + hh; k <= y + h + hh; k++) { if (k == y + h) { w2 -= Math.Min(1, r.Next(3)); w -= r.Next(2); } else if (k == y + h - 1 && r.Next(3) < 2) { w2 -= Math.Max(0, r.Next(-1, 2)); w -= Math.Max(0, r.Next(-1, 2)); } for (int i = x - w2; i <= x + w; i++) { for (int j = z - w; j <= z + w2; j++) { blocks[i, k, j] = BlockType.Leaves; } } } for (int i = 0; i < t + hh; i++) { blocks[x - 1, y + i, z] = BlockType.Log; } }