public void GenerateCaves(VoxelChunk chunk, WorldManager world) { Vector3 origin = chunk.Origin; BiomeData biome = BiomeLibrary.GetBiome("Cave"); for (int x = 0; x < VoxelConstants.ChunkSizeX; x++) { for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++) { var topVoxel = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle( chunk, new LocalVoxelCoordinate(x, VoxelConstants.ChunkSizeY - 1, z))); for (int i = 0; i < CaveLevels.Count; i++) { int y = CaveLevels[i]; if (y <= 0 || y >= topVoxel.Coordinate.Y) { 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)) { continue; } bool invalidCave = false; for (int dy = 0; dy < caveHeight; dy++) { if (y - dy <= 0) { continue; } var voxel = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y - dy, z)); foreach (var coord in VoxelHelpers.EnumerateAllNeighbors(voxel.Coordinate)) { VoxelHandle v = new VoxelHandle(Manager.ChunkData, coord); if (v.IsValid && (v.LiquidLevel > 0 || v.Sunlight)) { invalidCave = true; break; } } if (!invalidCave) { voxel.RawSetType(VoxelLibrary.emptyType); } else { break; } } if (!invalidCave && caveNoise > CaveSize * 1.8f && y - caveHeight > 0) { GenerateCaveVegetation(chunk, x, y, z, caveHeight, biome, vec, world, NoiseGenerator); GenerateCaveFauna(chunk, world, biome, y - caveHeight, x, z); } } } } /* * // Second pass sets the caves to empty as needed * for (int x = 0; x < VoxelConstants.ChunkSizeX; x++) * { * for (int y = 0; y < VoxelConstants.ChunkSizeY; y++) * { * for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++) * { * VoxelHandle handle = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y, z)); * if (handle.Type == magicCube) * { * handle.RawSetType(VoxelLibrary.emptyType); * } * } * } * } */ }
public void GenerateCaves(VoxelChunk chunk, WorldManager world) { if (CaveLevels == null) { CaveLevels = new List <int>(); var caveStep = 48 / world.GenerationSettings.NumCaveLayers; for (var i = 0; i < world.GenerationSettings.NumCaveLayers; ++i) { CaveLevels.Add(4 + (caveStep * i)); } } Vector3 origin = chunk.Origin; BiomeData biome = BiomeLibrary.GetBiome("Cave"); var hellBiome = BiomeLibrary.GetBiome("Hell"); for (int x = 0; x < VoxelConstants.ChunkSizeX; x++) { for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++) { var topVoxel = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle( chunk, new LocalVoxelCoordinate(x, VoxelConstants.ChunkSizeY - 1, z))); for (int i = 0; i < CaveLevels.Count; i++) { int y = CaveLevels[i]; if (y <= 0 || y >= topVoxel.Coordinate.Y) { continue; } var frequency = i < CaveFrequencies.Count ? CaveFrequencies[i] : CaveFrequencies[CaveFrequencies.Count - 1]; var caveBiome = (y <= HellLevel) ? hellBiome : biome; Vector3 vec = new Vector3(x, y, z) + chunk.Origin; double caveNoise = CaveNoise.GetValue((x + origin.X) * CaveNoiseScale * frequency, (y + origin.Y) * CaveNoiseScale * 3.0f, (z + origin.Z) * CaveNoiseScale * frequency); double heightnoise = NoiseGenerator.Noise((x + origin.X) * NoiseScale * frequency, (y + origin.Y) * NoiseScale * 3.0f, (z + origin.Z) * NoiseScale * frequency); int caveHeight = Math.Min(Math.Max((int)(heightnoise * 5), 1), 3); if (!(caveNoise > CaveSize)) { continue; } bool invalidCave = false; for (int dy = 0; dy < caveHeight; dy++) { if (y - dy <= 0) { continue; } var voxel = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y - dy, z)); foreach (var coord in VoxelHelpers.EnumerateAllNeighbors(voxel.Coordinate)) { VoxelHandle v = new VoxelHandle(Manager.ChunkData, coord); if (!v.IsValid || (v.Sunlight)) { invalidCave = true; break; } } if (!invalidCave) { voxel.RawSetType(VoxelLibrary.emptyType); } else { break; } } if (!invalidCave && caveNoise > CaveSize * 1.8f && y - caveHeight > 0 && y > LavaLevel) { GenerateCaveVegetation(chunk, x, y, z, caveHeight, caveBiome, vec, world, NoiseGenerator); } } } } /* * // Second pass sets the caves to empty as needed * for (int x = 0; x < VoxelConstants.ChunkSizeX; x++) * { * for (int y = 0; y < VoxelConstants.ChunkSizeY; y++) * { * for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++) * { * VoxelHandle handle = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y, z)); * if (handle.Type == magicCube) * { * handle.RawSetType(VoxelLibrary.emptyType); * } * } * } * } */ }
public void GenerateCaves(VoxelChunk chunk) { 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.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.GrassVoxel).ID; chunk.Data.Health[indexunder] = (byte)VoxelLibrary.GetVoxelType(biome.GrassVoxel).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.GrassVoxel) { vUnder.Type = VoxelLibrary.GetVoxelType(biome.SoilVoxel); 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.GetRootComponent().SetActiveRecursive(false); entity.GetRootComponent().SetVisibleRecursive(false); if (GameSettings.Default.FogofWar) { ExploredListener listener = new ExploredListener( PlayState.ComponentManager, entity, PlayState.ChunkManager, vUnder); } } } } foreach (FaunaData animal in biome.Fauna) { if (y <= 0 || !(PlayState.Random.NextDouble() < animal.SpawnProbability)) { continue; } var entity = EntityFactory.CreateEntity <GameComponent>(animal.Name, chunk.Origin + new Vector3(x, y, z) + Vector3.Up * 1.0f); entity.GetRootComponent().SetActiveRecursive(false); entity.GetRootComponent().SetVisibleRecursive(false); if (GameSettings.Default.FogofWar) { ExploredListener listener = new ExploredListener(PlayState.ComponentManager, entity, PlayState.ChunkManager, chunk.MakeVoxel(x, y, z)); } break; } } } } } }