public void GenerateCaves(VoxelChunk chunk, WorldManager world) { Vector3 origin = chunk.Origin; int chunkSizeX = chunk.SizeX; int chunkSizeY = chunk.SizeY; int chunkSizeZ = chunk.SizeZ; BiomeData biome = BiomeLibrary.Biomes[Overworld.Biome.Cave]; List <Voxel> neighbors = new List <Voxel>(); Voxel vUnder = chunk.MakeVoxel(0, 0, 0); for (int x = 0; x < chunkSizeX; x++) { for (int z = 0; z < chunkSizeZ; z++) { int h = chunk.GetFilledVoxelGridHeightAt(x, chunk.SizeY - 1, z); for (int i = 0; i < CaveLevels.Count; i++) { int y = CaveLevels[i]; if (y <= 0 || y >= h - 1) { continue; } Vector3 vec = new Vector3(x, y, z) + chunk.Origin; double caveNoise = CaveNoise.GetValue((x + origin.X) * CaveNoiseScale * CaveFrequencies[i], (y + origin.Y) * CaveNoiseScale * 3.0f, (z + origin.Z) * CaveNoiseScale * CaveFrequencies[i]); double heightnoise = NoiseGenerator.Noise((x + origin.X) * NoiseScale * CaveFrequencies[i], (y + origin.Y) * NoiseScale * 3.0f, (z + origin.Z) * NoiseScale * CaveFrequencies[i]); int caveHeight = Math.Min(Math.Max((int)(heightnoise * 5), 1), 3); if (caveNoise > CaveSize) { bool waterFound = false; for (int dy = 0; dy < caveHeight; dy++) { int index = chunk.Data.IndexAt(x, y - dy, z); chunk.GetNeighborsManhattan(x, y - dy, z, neighbors); if (neighbors.Any(v => v != null && v.WaterLevel > 0)) { waterFound = true; } if (waterFound) { break; } chunk.Data.Types[index] = 0; } if (!waterFound && caveNoise > CaveSize * 1.8f && y - caveHeight > 0) { int indexunder = chunk.Data.IndexAt(x, y - caveHeight, z); chunk.Data.Types[indexunder] = (byte)VoxelLibrary.GetVoxelType(biome.GrassLayer.VoxelType).ID; chunk.Data.Health[indexunder] = (byte)VoxelLibrary.GetVoxelType(biome.GrassLayer.VoxelType).StartingHealth; chunk.Data.IsExplored[indexunder] = false; foreach (VegetationData veg in biome.Vegetation) { if (!MathFunctions.RandEvent(veg.SpawnProbability)) { continue; } if (NoiseGenerator.Noise(vec.X / veg.ClumpSize, veg.NoiseOffset, vec.Y / veg.ClumpSize) < veg.ClumpThreshold) { continue; } vUnder.GridPosition = new Vector3(x, y - 1, z); if (!vUnder.IsEmpty && vUnder.TypeName == biome.GrassLayer.VoxelType) { vUnder.Type = VoxelLibrary.GetVoxelType(biome.SoilLayer.VoxelType); float offset = veg.VerticalOffset; if (vUnder.RampType != RampType.None) { offset -= 0.25f; } float treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize; GameComponent entity = EntityFactory.CreateEntity <GameComponent>(veg.Name, chunk.Origin + new Vector3(x, y, z) + new Vector3(0, treeSize * offset, 0), Blackboard.Create("Scale", treeSize)); entity.GetEntityRootComponent().SetActiveRecursive(false); entity.GetEntityRootComponent().SetVisibleRecursive(false); if (GameSettings.Default.FogofWar) { ExploredListener listener = new ExploredListener( world.ComponentManager, entity, world.ChunkManager, vUnder); } } } } foreach (FaunaData animal in biome.Fauna) { if (y <= 0 || !(MathFunctions.Random.NextDouble() < animal.SpawnProbability)) { continue; } var entity = EntityFactory.CreateEntity <GameComponent>(animal.Name, chunk.Origin + new Vector3(x, y, z) + Vector3.Up * 1.0f); if (GameSettings.Default.FogofWar) { entity.GetEntityRootComponent().SetActiveRecursive(false); entity.GetEntityRootComponent().SetVisibleRecursive(false); ExploredListener listener = new ExploredListener (world.ComponentManager, entity, world.ChunkManager, chunk.MakeVoxel(x, y, z)); } break; } } } } } }