private static ushort[] Populate(Vector2I chunkCoords, ushort[] indices, Vector3I[] surfaces) { double treeDensity = 0.005D; int chunkHash = chunkCoords.GetHashCode() * Seed.Value; Random treeRandom = new Random(chunkHash); Structure tree = Structure.Get("Tree"); ushort dirtID = ItemCache.GetIndex("winecrash:dirt"); ushort grassID = ItemCache.GetIndex("winecrash:grass"); ushort debugID = ItemCache.GetIndex("winecrash:direction"); // do trees for (int i = 0; i < surfaces.Length; i++) { int flatten = WMath.Flatten3D(surfaces[i].X, surfaces[i].Y, surfaces[i].Z, Chunk.Width, Chunk.Height); bool doTree = treeRandom.NextDouble() < treeDensity; if ((indices[flatten] == dirtID || indices[flatten] == grassID) && doTree) { indices[flatten] = dirtID; PlaceStructure(tree, LocalToGlobal(chunkCoords, new Vector3D(surfaces[i].X, surfaces[i].Y + 1, surfaces[i].Z)), false); } } return(indices); }
private static ushort[] PaintLandmass(Vector2I chunkCoords, ushort[] indices, out Vector3I[] surfaces) { ushort airID = ItemCache.GetIndex("winecrash:air"); ushort stoneID = ItemCache.GetIndex("winecrash:stone"); ushort grassID = ItemCache.GetIndex("winecrash:grass"); ushort dirtID = ItemCache.GetIndex("winecrash:dirt"); ushort sandID = ItemCache.GetIndex("winecrash:sand"); ushort waterID = ItemCache.GetIndex("winecrash:water"); ushort bedrockID = ItemCache.GetIndex("winecrash:bedrock"); //ushort[] indices = new ushort[Chunk.Width * Chunk.Height * Chunk.Depth]; Vector3F shift = Vector3F.Zero; Vector3F basePos = new Vector3F((chunkCoords.X * Chunk.Width) + shift.X, shift.Y, (chunkCoords.Y * Chunk.Depth) + shift.Z); ConcurrentBag <Vector3I> allSurfaces = new ConcurrentBag <Vector3I>(); // for each x and z, for y from top to bottom: for (int i = 0; i < Chunk.Width * Chunk.Depth; i++) { //Parallel.For(0, Chunk.Width /** Chunk.Height*/ * Chunk.Depth, i => //{ // get the x / z position WMath.FlatTo2D(i, Chunk.Width, out int x, out int z); int surfaceHeight = Chunk.Height - 1; bool heightFound = false; for (int y = Chunk.Height - 1; y > -1; y--) { int idx = WMath.Flatten3D(x, y, z, Chunk.Width, Chunk.Height); // if height already have been found, check back if // there is a surface or not (3D terrain, like grass under arches or so) if (heightFound) { if (indices[idx] == airID) // if air found, reset height { surfaceHeight = y; heightFound = false; } } else { surfaceHeight = y; if (indices[idx] != airID) { heightFound = true; allSurfaces.Add(new Vector3I(x, y, z)); } } // second pass: check the difference between surface and // the current block height. if (heightFound) { int deltaHeight = surfaceHeight - y; bool ocean = surfaceHeight < 64; // surface => grass if (deltaHeight == 0) { indices[idx] = ocean ? sandID : grassID; } // dirt, under the grass else if (deltaHeight < 3) { indices[idx] = ocean ? sandID : dirtID; } } if (y < 64 && indices[idx] == airID) { indices[idx] = waterID; } if (y < 3) { double chance = Winecrash.Random.NextDouble(); if (y == 2 && chance < 0.33) { indices[idx] = bedrockID; } else if (y == 1 && chance < 0.66) { indices[idx] = bedrockID; } else if (y == 0) { indices[idx] = bedrockID; } } } //Vector3F finalPos = new Vector3F((basePos.X + x) * baseLandmassScale, basePos.Y + y, // (basePos.Z + z) * baseLandmassScale) * globalScale; //}); } surfaces = allSurfaces.ToArray(); return(indices); }