private static void GenerateCaveFlora(VoxelHandle CaveFloor, BiomeData Biome, ChunkGeneratorSettings Settings) { foreach (var floraType in Biome.Vegetation) { if (!MathFunctions.RandEvent(floraType.SpawnProbability)) continue; if (Settings.NoiseGenerator.Noise(CaveFloor.Coordinate.X / floraType.ClumpSize, floraType.NoiseOffset, CaveFloor.Coordinate.Z / floraType.ClumpSize) < floraType.ClumpThreshold) continue; var plantSize = MathFunctions.Rand() * floraType.SizeVariance + floraType.MeanSize; var lambdaFloraType = floraType; if (!GameSettings.Default.FogofWar) EntityFactory.CreateEntity<GameComponent>( lambdaFloraType.Name, CaveFloor.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f), Blackboard.Create("Scale", plantSize)); else Settings.World.ComponentManager.RootComponent.AddChild(new SpawnOnExploredTrigger(Settings.World.ComponentManager, CaveFloor) { EntityToSpawn = lambdaFloraType.Name, SpawnLocation = CaveFloor.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f), BlackboardData = Blackboard.Create("Scale", plantSize) }); break; // Don't risk spawning multiple plants in the same spot. } }
public static void GenerateSurfaceLife(VoxelChunk TopChunk, ChunkGeneratorSettings Settings) { var creatureCounts = new Dictionary <string, Dictionary <string, int> >(); var worldDepth = Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY; for (var x = TopChunk.Origin.X; x < TopChunk.Origin.X + VoxelConstants.ChunkSizeX; x++) { for (var z = TopChunk.Origin.Z; z < TopChunk.Origin.Z + VoxelConstants.ChunkSizeZ; z++) { var overworldPosition = OverworldMap.WorldToOverworld(new Vector2(x, z), Settings.Overworld.InstanceSettings.Origin); if (Settings.Overworld.Map.GetBiomeAt(new Vector3(x, 0, z), Settings.Overworld.InstanceSettings.Origin).HasValue(out var biome)) { var normalizedHeight = NormalizeHeight(Settings.Overworld.Map.LinearInterpolate(overworldPosition, OverworldField.Height)); var height = (int)MathFunctions.Clamp(normalizedHeight * worldDepth, 0.0f, worldDepth - 2); var voxel = Settings.World.ChunkManager.CreateVoxelHandle(new GlobalVoxelCoordinate(x, height, z)); if (!voxel.IsValid || voxel.Coordinate.Y == 0 || voxel.Coordinate.Y >= worldDepth - Settings.TreeLine) { continue; } if (voxel.LiquidLevel != 0) { continue; } var above = VoxelHelpers.GetVoxelAbove(voxel); if (above.IsValid && (above.LiquidLevel != 0 || !above.IsEmpty)) { continue; } foreach (var animal in biome.Fauna) { if (MathFunctions.RandEvent(animal.SpawnProbability)) { if (!creatureCounts.ContainsKey(biome.Name)) { creatureCounts[biome.Name] = new Dictionary <string, int>(); } var dict = creatureCounts[biome.Name]; if (!dict.ContainsKey(animal.Name)) { dict[animal.Name] = 0; } if (dict[animal.Name] < animal.MaxPopulation) { EntityFactory.CreateEntity <GameComponent>(animal.Name, voxel.WorldPosition + Vector3.Up * 1.5f); } break; } } if (voxel.Type.Name != biome.SoilLayer.VoxelType) { continue; } foreach (VegetationData veg in biome.Vegetation) { if (voxel.GrassType == 0) { continue; } if (MathFunctions.RandEvent(veg.SpawnProbability) && Settings.NoiseGenerator.Noise(voxel.Coordinate.X / veg.ClumpSize, veg.NoiseOffset, voxel.Coordinate.Z / veg.ClumpSize) >= veg.ClumpThreshold) { var treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize; EntityFactory.CreateEntity <Plant>(veg.Name, voxel.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f), Blackboard.Create("Scale", treeSize)); break; } } } } } }