public void GenerateWater(VoxelChunk chunk, float maxHeight) { int waterHeight = Math.Min((int)(VoxelConstants.ChunkSizeY * NormalizeHeight(SeaLevel + 1.0f / VoxelConstants.ChunkSizeY, maxHeight)), VoxelConstants.ChunkSizeY - 1); var iceID = VoxelLibrary.GetVoxelType("Ice"); for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x) { for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z) { var biome = Overworld.GetBiomeAt(new Vector3(x, 0, z) + chunk.Origin, chunk.Manager.World.WorldScale, chunk.Manager.World.WorldOrigin); var topVoxel = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle( chunk, new LocalVoxelCoordinate(x, VoxelConstants.ChunkSizeY - 1, z))); for (var y = 0; y <= waterHeight; ++y) { var vox = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y, z)); if (vox.IsEmpty && y > topVoxel.Coordinate.Y) { if (biome.WaterSurfaceIce && y == waterHeight) { vox.RawSetType(iceID); } else { vox.QuickSetLiquid(biome.WaterIsLava ? LiquidType.Lava : LiquidType.Water, WaterManager.maxWaterLevel); } } } } } }
public void GenerateWater(VoxelChunk chunk) { int waterHeight = (int)(SeaLevel * VoxelConstants.ChunkSizeY) + 1; var iceID = VoxelLibrary.GetVoxelType("Ice"); for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x) { for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z) { var biome = GetBiomeAt(new Vector2(x, z) + new Vector2(chunk.Origin.X, chunk.Origin.Z)); var topVoxel = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle( chunk, new LocalVoxelCoordinate(x, VoxelConstants.ChunkSizeY - 1, z))); for (var y = 0; y <= waterHeight; ++y) { var vox = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y, z)); if (vox.IsEmpty && y > topVoxel.Coordinate.Y) { if (biome.WaterSurfaceIce && y == waterHeight) { vox.RawSetType(iceID); } else { vox.WaterCell = new WaterCell { Type = LiquidType.Water, WaterLevel = WaterManager.maxWaterLevel }; } } } Vector2 vec = new Vector2(x + chunk.Origin.X, z + chunk.Origin.Z) / WorldScale; if (topVoxel.Coordinate.Y < VoxelConstants.ChunkSizeY - 1 && Overworld.GetWater(Overworld.Map, vec) == Overworld.WaterType.Volcano) { var localCoord = topVoxel.Coordinate.GetLocalVoxelCoordinate(); topVoxel = new VoxelHandle(topVoxel.Chunk, new LocalVoxelCoordinate( localCoord.X, localCoord.Y + 1, localCoord.Z)); if (topVoxel.IsEmpty) { topVoxel.WaterCell = new WaterCell { Type = LiquidType.Lava, WaterLevel = WaterManager.maxWaterLevel }; } } } } }
public void GenerateCluster(OreCluster cluster, ChunkData chunks) { for (float x = -cluster.Size.X * 0.5f; x < cluster.Size.X * 0.5f; x += 1.0f) { for (float y = -cluster.Size.Y * 0.5f; y < cluster.Size.Y * 0.5f; y += 1.0f) { for (float z = -cluster.Size.Z * 0.5f; z < cluster.Size.Z * 0.5f; z += 1.0f) { float radius = (float)(Math.Pow(x / cluster.Size.X, 2.0f) + Math.Pow(y / cluster.Size.Y, 2.0f) + Math.Pow(z / cluster.Size.Z, 2.0f)); if (radius > 1.0f + MathFunctions.Rand(0.0f, 0.25f)) { continue; } Vector3 locPosition = new Vector3(x, y, z); Vector3 globalPosition = Vector3.Transform(locPosition, cluster.Transform); if (globalPosition.Y > cluster.Type.MaxSpawnHeight || globalPosition.Y < cluster.Type.MinSpawnHeight || globalPosition.Y <= 1) { continue; } var vox = new VoxelHandle(chunks, GlobalVoxelCoordinate.FromVector3(globalPosition)); if (!vox.IsValid || vox.IsEmpty) { continue; } if (!cluster.Type.SpawnOnSurface && (vox.Type.IsSurface || vox.Type.IsSoil)) { continue; } if (!MathFunctions.RandEvent(cluster.Type.SpawnProbability)) { continue; } vox.RawSetType(cluster.Type); } } } }
public void GenerateVein(OreVein vein, ChunkData chunks) { Vector3 curr = vein.Start; Vector3 directionBias = MathFunctions.RandVector3Box(-1, 1, -0.1f, 0.1f, -1, 1); for (float t = 0; t < vein.Length; t++) { if (curr.Y > vein.Type.MaxSpawnHeight || curr.Y < vein.Type.MinSpawnHeight || curr.Y <= 1) { continue; } Vector3 p = new Vector3(curr.X, curr.Y, curr.Z); var vox = new VoxelHandle(chunks, GlobalVoxelCoordinate.FromVector3(p)); if (!vox.IsValid || vox.IsEmpty) { continue; } if (!MathFunctions.RandEvent(vein.Type.SpawnProbability)) { continue; } if (!vein.Type.SpawnOnSurface && (vox.Type.IsSurface || vox.Type.IsSoil)) { continue; } vox.RawSetType(vein.Type); Vector3 step = directionBias + MathFunctions.RandVector3Box(-1, 1, -1, 1, -1, 1) * 0.25f; step.Normalize(); curr += step; } }
public VoxelChunk GenerateChunk(Vector3 origin, WorldManager World, float maxHeight) { float waterHeight = NormalizeHeight(SeaLevel + 1.0f / VoxelConstants.ChunkSizeY, maxHeight); VoxelChunk c = new VoxelChunk(Manager, origin, GlobalVoxelCoordinate.FromVector3(origin).GetGlobalChunkCoordinate()); for (int x = 0; x < VoxelConstants.ChunkSizeX; x++) { for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++) { Vector2 v = Overworld.WorldToOverworld(new Vector2(x + origin.X, z + origin.Z), World.WorldScale, World.WorldOrigin); var biome = Overworld.Map[(int)MathFunctions.Clamp(v.X, 0, Overworld.Map.GetLength(0) - 1), (int)MathFunctions.Clamp(v.Y, 0, Overworld.Map.GetLength(1) - 1)].Biome; BiomeData biomeData = BiomeLibrary.Biomes[biome]; Vector2 pos = Overworld.WorldToOverworld(new Vector2(x + origin.X, z + origin.Z), World.WorldScale, World.WorldOrigin); float hNorm = NormalizeHeight(Overworld.LinearInterpolate(pos, Overworld.Map, Overworld.ScalarFieldType.Height), maxHeight); float h = MathFunctions.Clamp(hNorm * VoxelConstants.ChunkSizeY, 0.0f, VoxelConstants.ChunkSizeY - 2); int stoneHeight = (int)(MathFunctions.Clamp((int)(h - (biomeData.SoilLayer.Depth + (Math.Sin(v.X) + Math.Cos(v.Y)))), 1, h)); int currentSubsurfaceLayer = 0; int depthWithinSubsurface = 0; for (int y = VoxelConstants.ChunkSizeY - 1; y >= 0; y--) { var voxel = new VoxelHandle(c, new LocalVoxelCoordinate(x, y, z)); if (y == 0) { voxel.RawSetType(VoxelLibrary.GetVoxelType("Bedrock")); continue; } if (y <= stoneHeight && stoneHeight > 1) { voxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.SubsurfaceLayers[currentSubsurfaceLayer].VoxelType)); depthWithinSubsurface++; if (depthWithinSubsurface > biomeData.SubsurfaceLayers[currentSubsurfaceLayer].Depth) { depthWithinSubsurface = 0; currentSubsurfaceLayer++; if (currentSubsurfaceLayer > biomeData.SubsurfaceLayers.Count - 1) { currentSubsurfaceLayer = biomeData.SubsurfaceLayers.Count - 1; } } } else if ((y == (int)h || y == stoneHeight) && hNorm > waterHeight) { if (biomeData.ClumpGrass && NoiseGenerator.Noise(pos.X / biomeData.ClumpSize, 0, pos.Y / biomeData.ClumpSize) > biomeData.ClumpTreshold) { voxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.SoilLayer.VoxelType)); if (!String.IsNullOrEmpty(biomeData.GrassDecal)) { var decal = GrassLibrary.GetGrassType(biomeData.GrassDecal); voxel.RawSetGrass(decal.ID); } } else if (!biomeData.ClumpGrass) { voxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.SoilLayer.VoxelType)); if (!String.IsNullOrEmpty(biomeData.GrassDecal)) { var decal = GrassLibrary.GetGrassType(biomeData.GrassDecal); voxel.RawSetGrass(decal.ID); } } else { voxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.SoilLayer.VoxelType)); } } else if (y > h && y > 0) { voxel.RawSetType(VoxelLibrary.emptyType); } else if (hNorm <= waterHeight) { voxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.ShoreVoxel)); } else { voxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.SoilLayer.VoxelType)); } } } } return(c); }
public static void GenerateCaveVegetation(VoxelChunk chunk, int x, int y, int z, int caveHeight, BiomeData biome, Vector3 vec, WorldManager world, Perlin NoiseGenerator) { var vUnder = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y - 1, z)); var wayUnder = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y - caveHeight, z)); wayUnder.RawSetType(VoxelLibrary.GetVoxelType(biome.SoilLayer.VoxelType)); var grassType = GrassLibrary.GetGrassType(biome.GrassDecal); if (grassType != null) { wayUnder.RawSetGrass(grassType.ID); } 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; } if (!vUnder.IsEmpty && vUnder.Type.Name == biome.SoilLayer.VoxelType) { vUnder.RawSetType(VoxelLibrary.GetVoxelType(biome.SoilLayer.VoxelType)); vUnder.RawSetGrass(0); float treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize; WorldManager.DoLazy(() => { if (!GameSettings.Default.FogofWar) { GameComponent entity = EntityFactory.CreateEntity <GameComponent>(veg.Name, vUnder.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f), Blackboard.Create("Scale", treeSize)); } else { world.ComponentManager.RootComponent.AddChild(new ExploredListener( world.ComponentManager, vUnder) { EntityToSpawn = veg.Name, SpawnLocation = vUnder.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f), BlackboardData = Blackboard.Create("Scale", treeSize) }); } }); } } float spawnLikelihood = (world.InitialEmbark.Difficulty + 0.1f); foreach (FaunaData animal in biome.Fauna) { if (y <= 0 || !(MathFunctions.Random.NextDouble() < animal.SpawnProbability * spawnLikelihood)) { continue; } FaunaData animal1 = animal; WorldManager.DoLazy(() => { if (!GameSettings.Default.FogofWar) { var entity = EntityFactory.CreateEntity <GameComponent>(animal1.Name, wayUnder.WorldPosition + Vector3.Up * 1.5f); } else { world.ComponentManager.RootComponent.AddChild(new ExploredListener (world.ComponentManager, new VoxelHandle(chunk, wayUnder.Coordinate.GetLocalVoxelCoordinate())) { EntityToSpawn = animal1.Name, SpawnLocation = wayUnder.WorldPosition + Vector3.Up * 1.5f }); } }); break; } }
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); * } * } * } * } */ }
/// <summary> /// Creates a flat, wooden balloon port for the balloon to land on, and Dwarves to sit on. /// </summary> /// <param name="roomDes">The player's BuildRoom designator (so that we can create a balloon port)</param> /// <param name="chunkManager">The terrain handler</param> /// <param name="x">The position of the center of the balloon port</param> /// <param name="z">The position of the center of the balloon port</param> /// <param name="size">The size of the (square) balloon port in voxels on a side</param> public Room GenerateInitialBalloonPort(RoomBuilder roomDes, ChunkManager chunkManager, float x, float z, int size) { var centerCoordinate = GlobalVoxelCoordinate.FromVector3(new Vector3(x, VoxelConstants.ChunkSizeY - 1, z)); var accumulator = 0; var count = 0; for (var offsetX = -size; offsetX <= size; ++offsetX) { for (var offsetY = -size; offsetY <= size; ++offsetY) { var topVoxel = VoxelHelpers.FindFirstVoxelBelowIncludeWater( new VoxelHandle(chunkManager.ChunkData, centerCoordinate + new GlobalVoxelOffset(offsetX, 0, offsetY))); if (topVoxel.Coordinate.Y > 0) { accumulator += topVoxel.Coordinate.Y + 1; count += 1; } } } var averageHeight = (int)Math.Round(((float)accumulator / (float)count)); if (StartUnderground) { accumulator = 0; count = 0; List <string> illegalTypes = new List <string>() { "Sand", "Dirt", "DarkDirt", "Ice" }; for (var offsetX = -size; offsetX <= size; ++offsetX) { for (var offsetY = -size; offsetY <= size; ++offsetY) { var topVoxel = VoxelHelpers.FindFirstVoxelBelow( new VoxelHandle(chunkManager.ChunkData, centerCoordinate + new GlobalVoxelOffset(offsetX, 0, offsetY))); if (topVoxel.Coordinate.Y > 0) { var vox = topVoxel; for (int dy = topVoxel.Coordinate.Y; dy > 0; dy--) { vox = new VoxelHandle(chunkManager.ChunkData, new GlobalVoxelCoordinate(topVoxel.Coordinate.X, dy, topVoxel.Coordinate.Z)); if (vox.IsValid && !vox.IsEmpty && !illegalTypes.Contains(vox.Type.Name)) { break; } } accumulator += vox.Coordinate.Y + 1; count += 1; } } } averageHeight = Math.Max((int)Math.Round(((float)accumulator / (float)count)) - 5, 0); } // Next, create the balloon port by deciding which voxels to fill. var balloonPortDesignations = new List <VoxelHandle>(); var treasuryDesignations = new List <VoxelHandle>(); for (int dx = -size; dx <= size; dx++) { for (int dz = -size; dz <= size; dz++) { Vector3 worldPos = new Vector3(centerCoordinate.X + dx, centerCoordinate.Y, centerCoordinate.Z + dz); var baseVoxel = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle( chunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(worldPos))); if (!baseVoxel.IsValid) { continue; } var h = baseVoxel.Coordinate.Y + 1; var localCoord = baseVoxel.Coordinate.GetLocalVoxelCoordinate(); for (int y = averageHeight; y < (StartUnderground ? averageHeight + 2 : h); y++) { var v = new VoxelHandle(baseVoxel.Chunk, new LocalVoxelCoordinate((int)localCoord.X, y, (int)localCoord.Z)); v.RawSetType(VoxelLibrary.GetVoxelType(0)); v.RawSetIsExplored(); v.QuickSetLiquid(LiquidType.None, 0); } if (averageHeight < h) { h = averageHeight; } bool isPosX = (dx == size && dz == 0); bool isPosZ = (dz == size & dx == 0); bool isNegX = (dx == -size && dz == 0); bool isNegZ = (dz == -size && dz == 0); bool isSide = (isPosX || isNegX || isPosZ || isNegZ); Vector3 offset = Vector3.Zero; if (isSide) { if (isPosX) { offset = Vector3.UnitX; } else if (isPosZ) { offset = Vector3.UnitZ; } else if (isNegX) { offset = -Vector3.UnitX; } else if (isNegZ) { offset = -Vector3.UnitZ; } } bool encounteredFilled = false; // Fill from the top height down to the bottom. for (int y = Math.Min(0, h - 1); y < averageHeight && y < VoxelConstants.ChunkSizeY; y++) { var v = new VoxelHandle(baseVoxel.Chunk, new LocalVoxelCoordinate((int)localCoord.X, y, (int)localCoord.Z)); if (!v.IsValid) { throw new InvalidProgramException("Voxel was invalid while creating a new game's initial zones. This should not happen."); } v.RawSetType(VoxelLibrary.GetVoxelType("Scaffold")); v.IsPlayerBuilt = true; v.QuickSetLiquid(LiquidType.None, 0); if (y == averageHeight - 1) { v.RawSetIsExplored(); if (dz >= 0) { balloonPortDesignations.Add(v); } else { treasuryDesignations.Add(v); } } if (isSide && !encounteredFilled) { var ladderPos = new Vector3(worldPos.X, y, worldPos.Z) + offset + Vector3.One * 0.5f; var ladderVox = new VoxelHandle(chunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(ladderPos)); if (ladderVox.IsValid && ladderVox.IsEmpty) { var ladder = EntityFactory.CreateEntity <Ladder>("Ladder", ladderPos); Master.Faction.OwnedObjects.Add(ladder); ladder.Tags.Add("Moveable"); ladder.Tags.Add("Deconstructable"); } else { encounteredFilled = true; } } } } } // Actually create the BuildRoom. var toBuild = RoomLibrary.CreateRoom(PlayerFaction, "Balloon Port", this); roomDes.DesignatedRooms.Add(toBuild); RoomLibrary.CompleteRoomImmediately(toBuild, balloonPortDesignations); // Also add a treasury var treasury = RoomLibrary.CreateRoom(PlayerFaction, "Treasury", this); roomDes.DesignatedRooms.Add(treasury); RoomLibrary.CompleteRoomImmediately(treasury, treasuryDesignations); return(toBuild); }
/// <summary> /// Creates a flat, wooden balloon port for the balloon to land on, and Dwarves to sit on. /// </summary> /// <param name="roomDes">The player's BuildRoom designator (so that we can create a balloon port)</param> /// <param name="chunkManager">The terrain handler</param> /// <param name="x">The position of the center of the balloon port</param> /// <param name="z">The position of the center of the balloon port</param> /// <param name="size">The size of the (square) balloon port in voxels on a side</param> public BalloonPort GenerateInitialBalloonPort(RoomBuilder roomDes, ChunkManager chunkManager, float x, float z, int size) { var centerCoordinate = GlobalVoxelCoordinate.FromVector3(new Vector3(x, VoxelConstants.ChunkSizeY - 1, z)); var accumulator = 0; var count = 0; for (var offsetX = -size; offsetX <= size; ++offsetX) { for (var offsetY = -size; offsetY <= size; ++offsetY) { var topVoxel = VoxelHelpers.FindFirstVoxelBelowIncludeWater( new VoxelHandle(chunkManager.ChunkData, centerCoordinate + new GlobalVoxelOffset(offsetX, 0, offsetY))); if (topVoxel.Coordinate.Y > 0) { accumulator += topVoxel.Coordinate.Y + 1; count += 1; } } } var averageHeight = (int)Math.Round(((float)accumulator / (float)count)); // Next, create the balloon port by deciding which voxels to fill. var balloonPortDesignations = new List <VoxelHandle>(); var treasuryDesignations = new List <VoxelHandle>(); for (int dx = -size; dx <= size; dx++) { for (int dz = -size; dz <= size; dz++) { Vector3 worldPos = new Vector3(centerCoordinate.X + dx, centerCoordinate.Y, centerCoordinate.Z + dz); var baseVoxel = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle( chunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(worldPos))); if (!baseVoxel.IsValid) { continue; } var h = baseVoxel.Coordinate.Y + 1; var localCoord = baseVoxel.Coordinate.GetLocalVoxelCoordinate(); for (int y = averageHeight; y < h; y++) { var v = new VoxelHandle(baseVoxel.Chunk, new LocalVoxelCoordinate((int)localCoord.X, y, (int)localCoord.Z)); v.RawSetType(VoxelLibrary.GetVoxelType(0)); v.QuickSetLiquid(LiquidType.None, 0); } if (averageHeight < h) { h = averageHeight; } bool isPosX = (dx == size && dz == 0); bool isPosZ = (dz == size & dx == 0); bool isNegX = (dx == -size && dz == 0); bool isNegZ = (dz == -size && dz == 0); bool isSide = (isPosX || isNegX || isPosZ || isNegZ); Vector3 offset = Vector3.Zero; if (isSide) { if (isPosX) { offset = Vector3.UnitX; } else if (isPosZ) { offset = Vector3.UnitZ; } else if (isNegX) { offset = -Vector3.UnitX; } else if (isNegZ) { offset = -Vector3.UnitZ; } } // Fill from the top height down to the bottom. for (int y = h - 1; y < averageHeight; y++) { var v = new VoxelHandle(baseVoxel.Chunk, new LocalVoxelCoordinate((int)localCoord.X, y, (int)localCoord.Z)); v.RawSetType(VoxelLibrary.GetVoxelType("Scaffold")); v.QuickSetLiquid(LiquidType.None, 0); if (y == averageHeight - 1) { if (dz >= 0) { balloonPortDesignations.Add(v); } else { treasuryDesignations.Add(v); } } if (isSide) { var ladderPos = new Vector3(worldPos.X, y, worldPos.Z) + offset + Vector3.One * 0.5f; var ladderVox = new VoxelHandle(chunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(ladderPos)); if (ladderVox.IsValid && ladderVox.IsEmpty) { var ladder = EntityFactory.CreateEntity <Ladder>("Ladder", ladderPos); Master.Faction.OwnedObjects.Add(ladder); ladder.Tags.Add("Moveable"); ladder.Tags.Add("Deconstructable"); } } } } } // Actually create the BuildRoom. BalloonPort toBuild = new BalloonPort(PlayerFaction, balloonPortDesignations, this); BuildRoomOrder buildDes = new BuildRoomOrder(toBuild, roomDes.Faction, this); buildDes.Build(true); roomDes.DesignatedRooms.Add(toBuild); // Also add a treasury Treasury treasury = new Treasury(PlayerFaction, treasuryDesignations, this); treasury.OnBuilt(); roomDes.DesignatedRooms.Add(treasury); return(toBuild); }
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); * } * } * } * } */ }