public static float GetValueAt(Vector3 worldPosition, Overworld.ScalarFieldType T) { Vector2 vec = new Vector2(worldPosition.X, worldPosition.Z) / PlayState.WorldScale; return(Overworld.GetValue(Overworld.Map, new Vector2(MathFunctions.Clamp(vec.X, 0, Overworld.Map.GetLength(0) - 1), MathFunctions.Clamp(vec.Y, 0, Overworld.Map.GetLength(1) - 1)), T)); }
public static void CreateOceanLand(GraphicsDevice graphicsDevice) { PlayState.SeaLevel = 0.17f; int size = 512; Map = new MapData[size, size]; for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { Map[x, y].Biome = Biome.Grassland; Map[x, y].Erosion = 1.0f; Map[x, y].Weathering = 0; Map[x, y].Faults = 1.0f; Map[x, y].Temperature = size; Map[x, y].Rainfall = size; Map[x, y].Height = 0.05f; //ComputeHeight(x, y, size0, size0, 5.0f, false); } } Color[] worldData = new Color[size * size]; WorldGeneratorState.worldMap = new Texture2D(graphicsDevice, size, size); Overworld.TextureFromHeightMap("Height", Overworld.Map, Overworld.ScalarFieldType.Height, Overworld.Map.GetLength(0), Overworld.Map.GetLength(1), null, worldData, WorldGeneratorState.worldMap, PlayState.SeaLevel); Overworld.Name = "flat"; }
override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { base.Update(gameTime, chunks, camera); if (CachedBiome == null) { var biome = Overworld.GetBiomeAt(LocalPosition, chunks.World.WorldScale, chunks.World.WorldOrigin); CachedBiome = biome.Name; } var factor = 1.0f; if (GoodBiomes.Contains(CachedBiome)) { factor = 1.5f; } if (BadBiomes.Contains(CachedBiome)) { factor = 0.5f; } GrowthTime += gameTime.ElapsedGameTime.TotalMinutes * factor; var scale = (float)(MinSize + (MaxSize - MinSize) * (GrowthTime / GrowthHours)); ReScale(scale); if (GrowthTime >= GrowthHours) { CreateAdult(); } }
public static List <Storm> CreateForecast(DateTime date, BoundingBox bounds, WorldManager world, int days) { List <Storm> foreCast = new List <Storm>(); for (int i = 0; i < days; i++) { // Each day, a storm could originate from a randomly selected biome Vector3 randomSample = MathFunctions.RandVector3Box(bounds); float rain = Overworld.GetValueAt(randomSample, Overworld.ScalarFieldType.Rainfall, world.WorldScale, world.WorldOrigin); float temperature = Overworld.GetValueAt(randomSample, Overworld.ScalarFieldType.Temperature, world.WorldScale, world.WorldOrigin); // Generate storms according to the rainfall in the biome. Up to 4 storms per day. int numStorms = (int)MathFunctions.Rand(0, rain * 4); // Space out the storms by a few hours int stormHour = MathFunctions.RandInt(0, 6); for (int j = 0; j < numStorms; j++) { bool isSnow = MathFunctions.RandEvent(1.0f - temperature); Storm storm = new Storm(world) { WindSpeed = MathFunctions.RandVector3Cube() * 5, Intensity = MathFunctions.Rand(rain, rain * 2), Date = date + new TimeSpan(i, stormHour, 0, 0), TypeofStorm = isSnow ? StormType.SnowStorm : StormType.RainStorm }; storm.WindSpeed = new Vector3(storm.WindSpeed.X, 0, storm.WindSpeed.Z); stormHour += MathFunctions.RandInt(1, 12); foreCast.Add(storm); } } return(foreCast); }
public static void CreateCliffsLand(GraphicsDevice graphicsDevice) { PlayState.SeaLevel = 0.17f; int size = 512; Map = new MapData[size, size]; for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { float height = ComputeHeight(x * 1.0f, y * 2.0f, size, size, 1.0f, false); float level = (int)(height / 0.15f) * 0.15f + 0.08f; Map[x, y].Height = level; Map[x, y].Biome = Biome.Forest; Map[x, y].Erosion = 1.0f; Map[x, y].Weathering = 0; Map[x, y].Faults = 1.0f; Map[x, y].Temperature = 0.6f; Map[x, y].Rainfall = 0.6f; } } Color[] worldData = new Color[size * size]; WorldGeneratorState.worldMap = new Texture2D(graphicsDevice, size, size); Overworld.TextureFromHeightMap("Height", Overworld.Map, Overworld.ScalarFieldType.Height, Overworld.Map.GetLength(0), Overworld.Map.GetLength(1), null, worldData, WorldGeneratorState.worldMap, PlayState.SeaLevel); Overworld.Name = "Cliffs_" + PlayState.Random.Next(9999); }
public static void CreateHillsLand(GraphicsDevice graphics) { PlayState.SeaLevel = 0.17f; int size = 512; Map = new MapData[size, size]; for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { float temp = ComputeHeight(x, y, size, size, 3.0f, false); float rain = ComputeHeight(x, y, size, size, 2.0f, false); float height = ComputeHeight(x, y, size, size, 1.6f, false); Map[x, y].Erosion = 1.0f; Map[x, y].Weathering = 0; Map[x, y].Faults = 1.0f; Map[x, y].Temperature = (float)(temp * 1.0f); Map[x, y].Rainfall = (float)(rain * 1.0f); Map[x, y].Biome = GetBiome(temp, rain, height); Map[x, y].Height = height; } } Color[] worldData = new Color[size * size]; WorldGeneratorState.worldMap = new Texture2D(graphics, size, size); Overworld.TextureFromHeightMap("Height", Overworld.Map, Overworld.ScalarFieldType.Height, Overworld.Map.GetLength(0), Overworld.Map.GetLength(1), null, worldData, WorldGeneratorState.worldMap, PlayState.SeaLevel); Overworld.Name = "hills" + PlayState.Random.Next(9999); }
public static void CreateUniformLand(GraphicsDevice graphics) { int size = 512; Map = new MapData[size, size]; for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { Map[x, y].Biome = Biome.Desert; Map[x, y].Erosion = 1.0f; Map[x, y].Weathering = 0.0f; Map[x, y].Faults = 1.0f; Map[x, y].Temperature = size; Map[x, y].Rainfall = size; Map[x, y].Height = 0.3f; //ComputeHeight(x, y, size0, size0, 5.0f, false); } } Color[] worldData = new Color[size * size]; WorldGeneratorState.worldMap = new Texture2D(graphics, size, size); Overworld.TextureFromHeightMap("Height", Overworld.Map, Overworld.ScalarFieldType.Height, Overworld.Map.GetLength(0), Overworld.Map.GetLength(1), null, worldData, WorldGeneratorState.worldMap, 0.17f); Overworld.Name = "flat_" + MathFunctions.Random.Next(9999); }
public OverworldMetaData(GraphicsDevice device, Overworld Overworld) { this.Overworld = Overworld; BiomeTypeMap = Library.GetBiomeTypeMap(); // This may need to be saved in branch meta data. Resources = Library.EnumerateResourceTypes().Where(r => r.Generated).ToList(); }
public Texture2D CreateSaveTexture(GraphicsDevice Device, int Width, int Height) { var r = new Texture2D(Device, Width, Height, false, SurfaceFormat.Color); var data = new Color[Width * Height]; Overworld.GenerateSaveTexture(Data, Width, Height, data); r.SetData(data); return(r); }
public void LoadFromTexture(Texture2D Texture) { Data = new Overworld.MapData[Texture.Width, Texture.Height]; var colorData = new Color[Texture.Width * Texture.Height]; GameState.Game.GraphicsDevice.BlendState = BlendState.NonPremultiplied; Texture.GetData(colorData); Overworld.DecodeSaveTexture(Data, Texture.Width, Texture.Height, colorData); }
public NewOverworldFile(GraphicsDevice device, Overworld Settings) { this.Settings = Settings; var worldFilePath = Settings.Name + System.IO.Path.DirectorySeparatorChar + "world.png"; var metaFilePath = Settings.Name + System.IO.Path.DirectorySeparatorChar + "meta.txt"; MetaData = new OverworldMetaData(device, Settings); }
private void GenerateInitialObjects() { float maxHeight = Overworld.GetMaxHeight(SpawnRect); Dictionary <string, Dictionary <string, int> > creatures = new Dictionary <string, Dictionary <string, int> >(); foreach (var chunk in ChunkManager.ChunkData.GetChunkEnumerator()) { ChunkManager.ChunkGen.GenerateSurfaceLife(creatures, chunk, maxHeight); } }
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 BiomeData(Overworld.Biome biome) { Biome = biome; Vegetation = new List<VegetationData>(); Motes = new List<DetailMoteData>(); Fauna = new List<FaunaData>(); ClumpGrass = false; ClumpSize = 30.0f; ClumpTreshold = 0.75f; MapColor = Color.White; }
public void GenerateWater(VoxelChunk chunk) { int waterHeight = (int)(SeaLevel * chunk.SizeY); Voxel voxel = chunk.MakeVoxel(0, 0, 0); for (int x = 0; x < chunk.SizeX; x++) { for (int z = 0; z < chunk.SizeZ; z++) { int h; for (int y = 0; y < waterHeight; y++) { h = chunk.GetFilledVoxelGridHeightAt(x, chunk.SizeY - 1, z); int index = chunk.Data.IndexAt(x, y, z); voxel.GridPosition = new Vector3(x, y, z); if (voxel.IsEmpty && y >= h) { chunk.Data.Water[index].WaterLevel = 255; chunk.Data.Water[index].Type = LiquidType.Water; } } Vector2 vec = new Vector2(x + chunk.Origin.X, z + chunk.Origin.Z) / PlayState.WorldScale; if (Overworld.GetWater(Overworld.Map, vec) != Overworld.WaterType.Volcano) { continue; } h = chunk.GetFilledVoxelGridHeightAt(x, chunk.SizeY - 1, z); if (h <= 0) { continue; } chunk.Data.Water[chunk.Data.IndexAt(x, h, z)].WaterLevel = 255; chunk.Data.Water[chunk.Data.IndexAt(x, h, z)].Type = LiquidType.Lava; /* * for (int y = h - 1; y >= 0; y--) * { * voxel.Chunk = chunk; * voxel.GridPosition = new Vector3(x, y, z); * chunk.Data.Water[voxel.Index].Type = LiquidType.None; * chunk.Data.Water[voxel.Index].WaterLevel = 0; * voxel.Type = VoxelLibrary.GetVoxelType("Stone"); * voxel.Chunk.NotifyTotalRebuild(!voxel.IsInterior); * } */ } } }
public Texture2D CreateTexture(GraphicsDevice device, int width, int height) { Texture2D toReturn = null; Overworld.MapData[,] mapData = CreateMap(); toReturn = new Texture2D(device, width, height); System.Threading.Mutex imageMutex = new System.Threading.Mutex(); Color[] worldData = new Color[width * height]; Overworld.TextureFromHeightMap("Height", mapData, Overworld.ScalarFieldType.Height, width, height, imageMutex, worldData, toReturn, PlayState.SeaLevel); return(toReturn); }
public OverworldFaction GenerateOverworldFaction(Overworld Settings, int idx, int n) { var race = Library.GetRandomIntelligentRace(); var fact = new OverworldFaction() { Race = race.Name, Name = TextGenerator.ToTitleCase(TextGenerator.GenerateRandom(Datastructures.SelectRandom(race.FactionNameTemplates).ToArray())), PrimaryColor = new HSLColor(idx * (255.0f / n), 255.0, MathFunctions.Rand(100.0f, 200.0f)), GoodWill = MathFunctions.Rand(-1, 1), InteractiveFaction = true }; return(fact); }
// Todo: Move to ChunkGenerator public void GenerateInitialChunks(Rectangle spawnRect, GlobalChunkCoordinate origin, Action <String> SetLoadingMessage) { var initialChunkCoordinates = new List <GlobalChunkCoordinate>(); for (int dx = 0; dx < WorldSize.X; dx++) { for (int dz = 0; dz < WorldSize.Z; dz++) { initialChunkCoordinates.Add(new GlobalChunkCoordinate(dx, 0, dz)); } } SetLoadingMessage("Generating Chunks..."); float maxHeight = Math.Max(Overworld.GetMaxHeight(spawnRect), 0.17f); foreach (var box in initialChunkCoordinates) { Vector3 worldPos = new Vector3( box.X * VoxelConstants.ChunkSizeX, box.Y * VoxelConstants.ChunkSizeY, box.Z * VoxelConstants.ChunkSizeZ); VoxelChunk chunk = ChunkGen.GenerateChunk(worldPos, World, maxHeight); ChunkData.AddChunk(chunk); } // This is critical at the beginning to allow trees to spawn on ramps correctly, // and also to ensure no inconsistencies in chunk geometry due to ramps. foreach (var chunk in ChunkData.ChunkMap) { ChunkGen.GenerateChunkData(chunk, World, maxHeight); for (var i = 0; i < VoxelConstants.ChunkSizeY; ++i) { chunk.InvalidateSlice(i); } } RecalculateBounds(); SetLoadingMessage("Generating Ores..."); GenerateOres(); NeedsMinimapUpdate = true; }
public void GenerateWater(VoxelChunk chunk) { int waterHeight = (int)(SeaLevel * chunk.SizeY); Voxel voxel = chunk.MakeVoxel(0, 0, 0); for (int x = 0; x < chunk.SizeX; x++) { for (int z = 0; z < chunk.SizeZ; z++) { int h; for (int y = 0; y <= waterHeight; y++) { h = chunk.GetFilledVoxelGridHeightAt(x, chunk.SizeY - 1, z); int index = chunk.Data.IndexAt(x, y, z); voxel.GridPosition = new Vector3(x, y, z); if (voxel.IsEmpty && y >= h) { chunk.Data.Water[index].WaterLevel = 8; chunk.Data.Water[index].Type = LiquidType.Water; } } Vector2 vec = new Vector2(x + chunk.Origin.X, z + chunk.Origin.Z) / PlayState.WorldScale; if (Overworld.GetWater(Overworld.Map, vec) != Overworld.WaterType.Volcano) { continue; } h = chunk.GetFilledVoxelGridHeightAt(x, chunk.SizeY - 1, z); if (h <= 0) { continue; } chunk.Data.Water[chunk.Data.IndexAt(x, h, z)].WaterLevel = 8; chunk.Data.Water[chunk.Data.IndexAt(x, h, z)].Type = LiquidType.Lava; } } }
public void CreateMigration() { int tries = 0; float padding = 2.0f; while (tries < 10) { int side = MathFunctions.Random.Next(4); BoundingBox bounds = World.ChunkManager.Bounds; Vector3 pos = Vector3.Zero; switch (side) { case 0: pos = new Vector3(bounds.Min.X + padding, bounds.Max.Y - padding, MathFunctions.Rand(bounds.Min.Z + padding, bounds.Max.Z - padding)); break; case 1: pos = new Vector3(bounds.Max.X - padding, bounds.Max.Y - padding, MathFunctions.Rand(bounds.Min.Z + padding, bounds.Max.Z - padding)); break; case 2: pos = new Vector3(MathFunctions.Rand(bounds.Min.X + padding, bounds.Max.X - padding), bounds.Max.Y - padding, bounds.Min.Z + padding); break; case 3: pos = new Vector3(MathFunctions.Rand(bounds.Min.X + padding, bounds.Max.X - padding), bounds.Max.Y - padding, bounds.Max.Z - padding); break; } var biome = Overworld.GetBiomeAt(pos); if (biome.Fauna.Count == 0) { tries++; continue; } var randomFauna = Datastructures.SelectRandom(biome.Fauna); var testCreature = EntityFactory.CreateEntity <GameComponent>(randomFauna.Name, Vector3.Zero); if (testCreature == null) { tries++; continue; } var testCreatureAI = testCreature.GetRoot().GetComponent <CreatureAI>(); if (testCreatureAI == null || testCreatureAI.Movement.IsSessile) { testCreature.GetRoot().Delete(); tries++; continue; } var count = Creature.GetNumSpecies(testCreatureAI.Creature.Species); testCreature.GetRoot().Delete(); if (count < 30) { var randomNum = Math.Min(MathFunctions.RandInt(1, 3), 30 - count); for (int i = 0; i < randomNum; i++) { var randompos = MathFunctions.Clamp(pos + MathFunctions.RandVector3Cube() * 2, World.ChunkManager.Bounds); var vox = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle(World.ChunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(pos))); if (!vox.IsValid) { continue; } EntityFactory.CreateEntity <GameComponent>(randomFauna.Name, vox.GetBoundingBox().Center() + Vector3.Up * 1.5f); } } break; } }
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 void GenerateSurfaceLife(Dictionary <string, Dictionary <string, int> > creatureCounts, VoxelChunk Chunk, float maxHeight) { //int waterHeight = (int)(VoxelConstants.ChunkSizeY * NormalizeHeight(SeaLevel + 1.0f / VoxelConstants.ChunkSizeY, maxHeight)); for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x) { for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z) { var biomeData = Overworld.GetBiomeAt(new Vector3(x + Chunk.Origin.X, 0, z + Chunk.Origin.Z), Chunk.Manager.World.WorldScale, Chunk.Manager.World.WorldOrigin); var topVoxel = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle( Chunk, new LocalVoxelCoordinate(x, VoxelConstants.ChunkSizeY - 1, z))); if (!topVoxel.IsValid || topVoxel.Coordinate.Y == 0 || topVoxel.Coordinate.Y >= 60) // Lift to some kind of generator settings? { continue; } var above = VoxelHelpers.GetVoxelAbove(topVoxel); if (above.IsValid && above.LiquidLevel != 0) { continue; } foreach (var animal in biomeData.Fauna) { if (MathFunctions.RandEvent(animal.SpawnProbability)) { if (!creatureCounts.ContainsKey(biomeData.Name)) { creatureCounts[biomeData.Name] = new Dictionary <string, int>(); } var dict = creatureCounts[biomeData.Name]; if (!dict.ContainsKey(animal.Name)) { dict[animal.Name] = 0; } if (dict[animal.Name] < animal.MaxPopulation) { EntityFactory.CreateEntity <Body>(animal.Name, topVoxel.WorldPosition + Vector3.Up * 1.5f); } break; } } if (topVoxel.Type.Name != biomeData.SoilLayer.VoxelType) { continue; } foreach (VegetationData veg in biomeData.Vegetation) { if (topVoxel.GrassType == 0) { continue; } if (MathFunctions.RandEvent(veg.SpawnProbability) && NoiseGenerator.Noise(topVoxel.Coordinate.X / veg.ClumpSize, veg.NoiseOffset, topVoxel.Coordinate.Z / veg.ClumpSize) >= veg.ClumpThreshold) { topVoxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.SoilLayer.VoxelType)); var treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize; var tree = EntityFactory.CreateEntity <Plant>(veg.Name, topVoxel.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f), Blackboard.Create("Scale", treeSize)); break; } } } } }
public void BuildGrassMotes(Overworld.Biome biome) { BiomeData biomeData = BiomeLibrary.Biomes[biome]; string grassType = biomeData.GrassVoxel; for(int i = 0; i < biomeData.Motes.Count; i++) { List<Vector3> grassPositions = new List<Vector3>(); List<Color> grassColors = new List<Color>(); List<float> grassScales = new List<float>(); DetailMoteData moteData = biomeData.Motes[i]; Voxel v = MakeVoxel(0, 0, 0); Voxel voxelBelow = MakeVoxel(0, 0, 0); for(int x = 0; x < SizeX; x++) { for(int y = 1; y < Math.Min(Manager.ChunkData.MaxViewingLevel + 1, SizeY - 1); y++) { for(int z = 0; z < SizeZ; z++) { v.GridPosition = new Vector3(x, y, z); voxelBelow.GridPosition = new Vector3(x, y - 1, z); if(v.IsEmpty || voxelBelow.IsEmpty || v.Type.Name != grassType || !v.IsVisible || voxelBelow.WaterLevel != 0) { continue; } float vOffset = 0.0f; if(v.RampType != RampType.None) { vOffset = -0.5f; } float value = MoteNoise.Noise(v.Position.X * moteData.RegionScale, v.Position.Y * moteData.RegionScale, v.Position.Z * moteData.RegionScale); float s = MoteScaleNoise.Noise(v.Position.X * moteData.RegionScale, v.Position.Y * moteData.RegionScale, v.Position.Z * moteData.RegionScale) * moteData.MoteScale; if(!(Math.Abs(value) > moteData.SpawnThreshold)) { continue; } Vector3 smallNoise = ClampVector(VertexNoise.GetRandomNoiseVector(v.Position * moteData.RegionScale * 20.0f) * 20.0f, 0.4f); smallNoise.Y = 0.0f; grassPositions.Add(v.Position + new Vector3(0.5f, 1.0f + s * 0.5f + vOffset, 0.5f) + smallNoise); grassScales.Add(s); grassColors.Add(new Color(v.SunColor, 128, 0)); } } } if (Motes == null) { Motes = new Dictionary<string, List<InstanceData>>(); } if(Motes.Count < i + 1) { Motes[moteData.Name] = new List<InstanceData>(); } Motes[moteData.Name] = EntityFactory.GenerateGrassMotes(grassPositions, grassColors, grassScales, Manager.Components, Manager.Content, Manager.Graphics, Motes[moteData.Name], moteData.Asset, moteData.Name); } }
private static void UpdateChunk(VoxelChunk chunk) { var addGrassToThese = new List <Tuple <VoxelHandle, byte> >(); for (var y = 0; y < VoxelConstants.ChunkSizeY; ++y) { // Skip empty slices. if (chunk.Data.VoxelsPresentInSlice[y] == 0) { continue; } for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x) { for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z) { var voxel = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y, z)); // Allow grass to decay if (voxel.GrassType != 0) { var decal = GrassLibrary.GetGrassType(voxel.GrassType); if (decal.NeedsSunlight && !voxel.Sunlight) { voxel.GrassType = 0; } else if (decal.Decay) { voxel.GrassDecay -= 1; if (voxel.GrassDecay == 0) { var newDecal = GrassLibrary.GetGrassType(decal.BecomeWhenDecays); if (newDecal != null) { voxel.GrassType = newDecal.ID; } else { voxel.GrassType = 0; } } } } //#if false else if (voxel.Type.GrassSpreadsHere) { // Spread grass onto this tile - but only from the same biome. // Don't spread if there's an entity here. var entityPresent = chunk.Manager.World.EnumerateIntersectingObjects( new BoundingBox(voxel.WorldPosition + new Vector3(0.1f, 1.1f, 0.1f), voxel.WorldPosition + new Vector3(0.9f, 1.9f, 0.9f)), CollisionType.Static).Any(); if (entityPresent) { continue; } var biome = Overworld.GetBiomeAt(voxel.Coordinate.ToVector3(), chunk.Manager.World.WorldScale, chunk.Manager.World.WorldOrigin); var grassyNeighbors = VoxelHelpers.EnumerateManhattanNeighbors2D(voxel.Coordinate) .Select(c => new VoxelHandle(voxel.Chunk.Manager.ChunkData, c)) .Where(v => v.IsValid && v.GrassType != 0) .Where(v => biome == Overworld.GetBiomeAt(v.Coordinate.ToVector3(), chunk.Manager.World.WorldScale, chunk.Manager.World.WorldOrigin)) .ToList(); if (grassyNeighbors.Count > 0) { if (MathFunctions.RandEvent(0.1f)) { addGrassToThese.Add(Tuple.Create(voxel, grassyNeighbors[MathFunctions.RandInt(0, grassyNeighbors.Count)].GrassType)); } } } //#endif } } } foreach (var v in addGrassToThese) { var l = v.Item1; var grassType = GrassLibrary.GetGrassType(v.Item2); if (grassType.NeedsSunlight && !l.Sunlight) { continue; } l.GrassType = v.Item2; } }
public OverworldMetaData(GraphicsDevice device, Overworld Overworld) { this.Overworld = Overworld; BiomeTypeMap = Library.GetBiomeTypeMap(); // This may need to be saved in branch meta data. }
public OverworldFile(Overworld.MapData[,] map, string name) { Data = new OverworldData(map, name); }
public static void Initialize(Overworld Overworld) { foreach (var otherFaction in Overworld.Natives) { foreach (var thisFaction in Overworld.Natives) { if (thisFaction.Name == otherFaction.Name) { var politics = new Politics() { OwnerFaction = thisFaction, OtherFaction = otherFaction, HasMet = true }; politics.AddEvent(new PoliticalEvent() { Change = 1.0f, Description = "we are of the same faction", }); thisFaction.Politics[otherFaction.Name] = politics; } else { Politics politics = new Politics() { OwnerFaction = thisFaction, OtherFaction = otherFaction, HasMet = false, }; if (thisFaction.Race == otherFaction.Race) { politics.AddEvent(new PoliticalEvent() { Change = 0.5f, Description = "we are of the same people", }); } var thisFactionRace = Library.GetRace(thisFaction.Race); var otherRace = Library.GetRace(otherFaction.Race); if (thisFactionRace.NaturalEnemies.Any(name => name == otherRace.Name)) { if (!politics.HasEvent("we are taught to hate your kind")) { politics.AddEvent(new PoliticalEvent() { Change = -10.0f, // Make this negative and we get an instant war party rush. Description = "we are taught to hate your kind", }); } } if (thisFactionRace.IsIntelligent && otherRace.IsIntelligent) { float trustingness = thisFaction.GoodWill; if (trustingness < -0.8f) { if (!politics.HasEvent("we just don't trust you")) { politics.AddEvent(new PoliticalEvent() { Change = -10.0f, // Make this negative and we get an instant war party rush. Description = "we just don't trust you", }); politics.IsAtWar = true; } } else if (trustingness > 0.8f) { if (!politics.HasEvent("we just trust you")) { politics.AddEvent(new PoliticalEvent() { Change = 10.0f, Description = "we just trust you", }); } } } thisFaction.Politics[otherFaction.Name] = politics; } } } }
private void LoadThreaded() { // Ensure we're using the invariant culture. Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; LoadStatus = LoadingStatus.Loading; SetLoadingMessage("Initializing ..."); while (GraphicsDevice == null) { Thread.Sleep(100); } Thread.Sleep(1000); #if CREATE_CRASH_LOGS try #endif #if !DEBUG try { #endif bool fileExists = !string.IsNullOrEmpty(ExistingFile); SetLoadingMessage("Creating Sky..."); Sky = new SkyRenderer( TextureManager.GetTexture(ContentPaths.Sky.moon), TextureManager.GetTexture(ContentPaths.Sky.sun), Content.Load <TextureCube>(ContentPaths.Sky.day_sky), Content.Load <TextureCube>(ContentPaths.Sky.night_sky), TextureManager.GetTexture(ContentPaths.Gradients.skygradient), Content.Load <Model>(ContentPaths.Models.sphereLowPoly), Content.Load <Effect>(ContentPaths.Shaders.SkySphere), Content.Load <Effect>(ContentPaths.Shaders.Background)); #region Reading game file if (fileExists) { SetLoadingMessage("Loading " + ExistingFile); gameFile = SaveGame.CreateFromDirectory(ExistingFile); if (gameFile == null) { throw new InvalidOperationException("Game File does not exist."); } // Todo: REMOVE THIS WHEN THE NEW SAVE SYSTEM IS COMPLETE. if (gameFile.Metadata.Version != Program.Version && !Program.CompatibleVersions.Contains(gameFile.Metadata.Version)) { throw new InvalidOperationException(String.Format("Game file is from version {0}. Compatible versions are {1}.", gameFile.Metadata.Version, TextGenerator.GetListString(Program.CompatibleVersions))); } Sky.TimeOfDay = gameFile.Metadata.TimeOfDay; Time = gameFile.Metadata.Time; WorldOrigin = gameFile.Metadata.WorldOrigin; WorldScale = gameFile.Metadata.WorldScale; WorldSize = gameFile.Metadata.NumChunks; GameID = gameFile.Metadata.GameID; if (gameFile.Metadata.OverworldFile != null && gameFile.Metadata.OverworldFile != "flat") { SetLoadingMessage("Loading world " + gameFile.Metadata.OverworldFile); Overworld.Name = gameFile.Metadata.OverworldFile; DirectoryInfo worldDirectory = Directory.CreateDirectory(DwarfGame.GetWorldDirectory() + ProgramData.DirChar + Overworld.Name); var overWorldFile = new NewOverworldFile(worldDirectory.FullName); Overworld.Map = overWorldFile.Data.Data; Overworld.Name = overWorldFile.Data.Name; } else { SetLoadingMessage("Generating flat world.."); Overworld.CreateUniformLand(GraphicsDevice); } } #endregion #region Initialize static data { Vector3 origin = new Vector3(WorldOrigin.X, 0, WorldOrigin.Y); Vector3 extents = new Vector3(1500, 1500, 1500); CollisionManager = new CollisionManager(new BoundingBox(origin - extents, origin + extents)); CraftLibrary = new CraftLibrary(); new PrimitiveLibrary(GraphicsDevice, Content); NewInstanceManager = new NewInstanceManager(GraphicsDevice, new BoundingBox(origin - extents, origin + extents), Content); Color[] white = new Color[1]; white[0] = Color.White; pixel = new Texture2D(GraphicsDevice, 1, 1); pixel.SetData(white); Tilesheet = TextureManager.GetTexture(ContentPaths.Terrain.terrain_tiles); AspectRatio = GraphicsDevice.Viewport.AspectRatio; DefaultShader = new Shader(Content.Load <Effect>(ContentPaths.Shaders.TexturedShaders), true); DefaultShader.ScreenWidth = GraphicsDevice.Viewport.Width; DefaultShader.ScreenHeight = GraphicsDevice.Viewport.Height; VoxelLibrary.InitializeDefaultLibrary(GraphicsDevice, Tilesheet); GrassLibrary.InitializeDefaultLibrary(); DecalLibrary.InitializeDefaultLibrary(); bloom = new BloomComponent(Game) { Settings = BloomSettings.PresetSettings[5] }; bloom.Initialize(); fxaa = new FXAA(); fxaa.Initialize(); SoundManager.Content = Content; if (PlanService != null) { PlanService.Restart(); } JobLibrary.Initialize(); MonsterSpawner = new MonsterSpawner(this); EntityFactory.Initialize(this); } #endregion SetLoadingMessage("Creating Planner ..."); PlanService = new PlanService(); SetLoadingMessage("Creating Shadows..."); Shadows = new ShadowRenderer(GraphicsDevice, 1024, 1024); SetLoadingMessage("Creating Liquids ..."); #region liquids WaterRenderer = new WaterRenderer(GraphicsDevice); LiquidAsset waterAsset = new LiquidAsset { Type = LiquidType.Water, Opactiy = 0.8f, Reflection = 1.0f, WaveHeight = 0.1f, WaveLength = 0.05f, WindForce = 0.001f, BumpTexture = TextureManager.GetTexture(ContentPaths.Terrain.water_normal), BaseTexture = TextureManager.GetTexture(ContentPaths.Terrain.cartoon_water), MinOpacity = 0.4f, RippleColor = new Vector4(0.6f, 0.6f, 0.6f, 0.0f), FlatColor = new Vector4(0.3f, 0.3f, 0.9f, 1.0f) }; WaterRenderer.AddLiquidAsset(waterAsset); LiquidAsset lavaAsset = new LiquidAsset { Type = LiquidType.Lava, Opactiy = 0.95f, Reflection = 0.0f, WaveHeight = 0.1f, WaveLength = 0.05f, WindForce = 0.001f, MinOpacity = 0.8f, BumpTexture = TextureManager.GetTexture(ContentPaths.Terrain.water_normal), BaseTexture = TextureManager.GetTexture(ContentPaths.Terrain.lava), RippleColor = new Vector4(0.5f, 0.4f, 0.04f, 0.0f), FlatColor = new Vector4(0.9f, 0.7f, 0.2f, 1.0f) }; WaterRenderer.AddLiquidAsset(lavaAsset); #endregion SetLoadingMessage("Generating Initial Terrain Chunks ..."); if (!fileExists) { GameID = MathFunctions.Random.Next(0, 1024); } ChunkGenerator = new ChunkGenerator(VoxelLibrary, Seed, 0.02f, this.WorldScale) { SeaLevel = SeaLevel }; #region Load Components if (fileExists) { ChunkManager = new ChunkManager(Content, this, Camera, GraphicsDevice, ChunkGenerator, WorldSize.X, WorldSize.Y, WorldSize.Z); ChunkRenderer = new ChunkRenderer(this, Camera, GraphicsDevice, ChunkManager.ChunkData); SetLoadingMessage("Loading Terrain..."); gameFile.ReadChunks(ExistingFile); ChunkManager.ChunkData.LoadFromFile(gameFile, SetLoadingMessage); ChunkManager.ChunkData.SetMaxViewingLevel(gameFile.Metadata.Slice > 0 ? gameFile.Metadata.Slice : ChunkManager.ChunkData.MaxViewingLevel, ChunkManager.SliceMode.Y); SetLoadingMessage("Loading Entities..."); gameFile.LoadPlayData(ExistingFile, this); Camera = gameFile.PlayData.Camera; ChunkManager.camera = Camera; ChunkRenderer.camera = Camera; DesignationDrawer = gameFile.PlayData.Designations; Vector3 origin = new Vector3(WorldOrigin.X, 0, WorldOrigin.Y); Vector3 extents = new Vector3(1500, 1500, 1500); CollisionManager = new CollisionManager(new BoundingBox(origin - extents, origin + extents)); if (gameFile.PlayData.Resources != null) { foreach (var resource in gameFile.PlayData.Resources) { if (!ResourceLibrary.Resources.ContainsKey(resource.Key)) { ResourceLibrary.Add(resource.Value); } } } ComponentManager = new ComponentManager(gameFile.PlayData.Components, this); foreach (var component in gameFile.PlayData.Components.SaveableComponents) { if (!ComponentManager.HasComponent(component.GlobalID) && ComponentManager.HasComponent(component.Parent.GlobalID)) { // Logically impossible. throw new InvalidOperationException("Component exists in save data but not in manager."); } } Factions = gameFile.PlayData.Factions; ComponentManager.World = this; Sky.TimeOfDay = gameFile.Metadata.TimeOfDay; Time = gameFile.Metadata.Time; WorldOrigin = gameFile.Metadata.WorldOrigin; WorldScale = gameFile.Metadata.WorldScale; // Restore native factions from deserialized data. Natives = new List <Faction>(); foreach (Faction faction in Factions.Factions.Values) { if (faction.Race.IsNative && faction.Race.IsIntelligent && !faction.IsRaceFaction) { Natives.Add(faction); } } Diplomacy = gameFile.PlayData.Diplomacy; GoalManager = new Goals.GoalManager(); GoalManager.Initialize(gameFile.PlayData.Goals); TutorialManager = new Tutorial.TutorialManager(Program.CreatePath("Content", "tutorial.txt")); TutorialManager.SetFromSaveData(gameFile.PlayData.TutorialSaveData); } else { Time = new WorldTime(); // WorldOrigin is in "map" units. Convert to voxels var globalOffset = new Vector3(WorldOrigin.X, 0, WorldOrigin.Y) * WorldScale; Camera = new OrbitCamera(this, new Vector3(VoxelConstants.ChunkSizeX, VoxelConstants.ChunkSizeY - 1.0f, VoxelConstants.ChunkSizeZ) + new Vector3(WorldOrigin.X, 0, WorldOrigin.Y) * WorldScale, new Vector3(VoxelConstants.ChunkSizeY, VoxelConstants.ChunkSizeY - 1.0f, VoxelConstants.ChunkSizeZ) + new Vector3(WorldOrigin.X, 0, WorldOrigin.Y) * WorldScale + Vector3.Up * 10.0f + Vector3.Backward * 10, MathHelper.PiOver4, AspectRatio, 0.1f, GameSettings.Default.VertexCullDistance); ChunkManager = new ChunkManager(Content, this, Camera, GraphicsDevice, ChunkGenerator, WorldSize.X, WorldSize.Y, WorldSize.Z); ChunkRenderer = new ChunkRenderer(this, Camera, GraphicsDevice, ChunkManager.ChunkData); var chunkOffset = GlobalVoxelCoordinate.FromVector3(globalOffset).GetGlobalChunkCoordinate(); //var chunkOffset = ChunkManager.ChunkData.RoundToChunkCoords(globalOffset); //globalOffset.X = chunkOffset.X * VoxelConstants.ChunkSizeX; //globalOffset.Y = chunkOffset.Y * VoxelConstants.ChunkSizeY; //globalOffset.Z = chunkOffset.Z * VoxelConstants.ChunkSizeZ; WorldOrigin = new Vector2(globalOffset.X, globalOffset.Z); Camera.Position = new Vector3(0, 10, 0) + globalOffset; Camera.Target = new Vector3(0, 10, 1) + globalOffset; // If there's no file, we have to initialize the first chunk coordinate if (gameFile == null) // Todo: Always true? { ChunkManager.GenerateInitialChunks( GlobalVoxelCoordinate.FromVector3(globalOffset).GetGlobalChunkCoordinate(), SetLoadingMessage); } ComponentManager = new ComponentManager(this); ComponentManager.SetRootComponent(new Body(ComponentManager, "root", Matrix.Identity, Vector3.Zero, Vector3.Zero, false)); if (Natives == null) // Todo: Always true?? { FactionLibrary library = new FactionLibrary(); library.Initialize(this, CompanyMakerState.CompanyInformation); Natives = new List <Faction>(); for (int i = 0; i < 10; i++) { Natives.Add(library.GenerateFaction(this, i, 10)); } } #region Prepare Factions foreach (Faction faction in Natives) { faction.World = this; if (faction.RoomBuilder == null) { faction.RoomBuilder = new RoomBuilder(faction, this); } if (faction.CraftBuilder == null) { faction.CraftBuilder = new CraftBuilder(faction, this); } } Factions = new FactionLibrary(); if (Natives != null && Natives.Count > 0) { Factions.AddFactions(this, Natives); } Factions.Initialize(this, CompanyMakerState.CompanyInformation); Point playerOrigin = new Point((int)(WorldOrigin.X), (int)(WorldOrigin.Y)); Factions.Factions["Player"].Center = playerOrigin; Factions.Factions["The Motherland"].Center = new Point(playerOrigin.X + 50, playerOrigin.Y + 50); #endregion Diplomacy = new Diplomacy(this); Diplomacy.Initialize(Time.CurrentDate); // Initialize goal manager here. GoalManager = new Goals.GoalManager(); GoalManager.Initialize(new List <Goals.Goal>()); TutorialManager = new Tutorial.TutorialManager(Program.CreatePath("Content", "tutorial.txt")); TutorialManager.TutorialEnabled = !GameSettings.Default.TutorialDisabledGlobally; Tutorial("new game start"); } Camera.World = this; //Drawer3D.Camera = Camera; #endregion ChunkManager.camera = Camera; SetLoadingMessage("Creating Particles ..."); ParticleManager = new ParticleManager(GraphicsDevice, ComponentManager); SetLoadingMessage("Creating GameMaster ..."); Master = new GameMaster(Factions.Factions["Player"], Game, ComponentManager, ChunkManager, Camera, GraphicsDevice); if (gameFile != null) { if (gameFile.PlayData.Spells != null) { Master.Spells = gameFile.PlayData.Spells; } if (gameFile.PlayData.Tasks != null) { Master.TaskManager = gameFile.PlayData.Tasks; } } if (Master.Faction.Economy.Company.Information == null) { Master.Faction.Economy.Company.Information = new CompanyInformation(); } CreateInitialEmbarkment(); foreach (var chunk in ChunkManager.ChunkData.ChunkMap) { chunk.CalculateInitialSunlight(); } VoxelHelpers.InitialReveal(ChunkManager.ChunkData, new VoxelHandle( ChunkManager.ChunkData.GetChunkEnumerator().FirstOrDefault(), new LocalVoxelCoordinate(0, VoxelConstants.ChunkSizeY - 1, 0))); foreach (var chunk in ChunkManager.ChunkData.ChunkMap) { ChunkManager.InvalidateChunk(chunk); } ChunkManager.StartThreads(); SetLoadingMessage("Presimulating ..."); ShowingWorld = false; OnLoadedEvent(); Thread.Sleep(1000); ShowingWorld = true; SetLoadingMessage("Complete."); // GameFile is no longer needed. gameFile = null; LoadStatus = LoadingStatus.Success; #if !DEBUG } catch (Exception exception) { Game.CaptureException(exception); LoadingException = exception; LoadStatus = LoadingStatus.Failure; } #endif }
private void LoadFromFile() { SetLoadingMessage("Creating Sky..."); Renderer.Sky = new SkyRenderer(); #region Reading game file SetLoadingMessage("Loading " + Overworld.GetInstancePath()); var gameFile = SaveGame.LoadMetaFromDirectory(Overworld.GetInstancePath()); if (gameFile == null) { throw new InvalidOperationException("Game File does not exist."); } if (gameFile.Metadata.Version != Program.Version && !Program.CompatibleVersions.Contains(gameFile.Metadata.Version)) { throw new InvalidOperationException(String.Format("Game file is from version {0}. Compatible versions are {1}.", gameFile.Metadata.Version, TextGenerator.GetListString(Program.CompatibleVersions))); } Renderer.Sky.TimeOfDay = gameFile.Metadata.TimeOfDay; Renderer.PersistentSettings = gameFile.Metadata.RendererSettings; Time = gameFile.Metadata.Time; WorldSizeInChunks = new Point3(Overworld.InstanceSettings.Cell.Bounds.Width, Overworld.zLevels, Overworld.InstanceSettings.Cell.Bounds.Height); #endregion #region Initialize static data bool actionComplete = false; Game.DoLazyAction(new Action(() => { Renderer.InstanceRenderer = new InstanceRenderer(); Renderer.bloom = new BloomComponent(Game) { Settings = BloomSettings.PresetSettings[5] }; Renderer.bloom.Initialize(); SoundManager.Content = Content; if (PlanService != null) { PlanService.Restart(); } MonsterSpawner = new MonsterSpawner(this); EntityFactory.Initialize(this); }), () => { actionComplete = true; return(true); }); while (!actionComplete) { Thread.Sleep(10); } #endregion PlanService = new PlanService(); SetLoadingMessage("Creating Liquids ..."); #region liquids Renderer.WaterRenderer = new WaterRenderer(GraphicsDevice); #endregion #region Load Components // Create updateable systems. foreach (var updateSystemFactory in AssetManager.EnumerateModHooks(typeof(UpdateSystemFactoryAttribute), typeof(EngineModule), new Type[] { typeof(WorldManager) })) { UpdateSystems.Add(updateSystemFactory.Invoke(null, new Object[] { this }) as EngineModule); } ChunkManager = new ChunkManager(Content, this); Splasher = new Splasher(ChunkManager); Renderer.ChunkRenderer = new ChunkRenderer(ChunkManager); SetLoadingMessage("Loading Terrain..."); ChunkManager.LoadChunks(gameFile.LoadChunks(), ChunkManager); SetLoadingMessage("Loading Entities..."); gameFile.LoadPlayData(Overworld.GetInstancePath(), this); PersistentData = gameFile.PlayData.PersistentData; Renderer.Camera = gameFile.PlayData.Camera; if (gameFile.PlayData.Stats != null) { Stats = gameFile.PlayData.Stats; } ComponentManager = new ComponentManager(gameFile.PlayData.Components, this); foreach (var component in gameFile.PlayData.Components.SaveableComponents) { if (!ComponentManager.HasComponent(component.GlobalID) && ComponentManager.HasComponent(component.Parent.GlobalID)) { // Logically impossible. throw new InvalidOperationException("Component exists in save data but not in manager."); } } ConversationMemory = gameFile.PlayData.ConversationMemory; Factions = gameFile.PlayData.Factions; ComponentManager.World = this; Renderer.Sky.TimeOfDay = gameFile.Metadata.TimeOfDay; Time = gameFile.Metadata.Time; PlayerFaction = Factions.Factions["Player"]; EventScheduler = new Events.Scheduler(); TutorialManager = new Tutorial.TutorialManager(); TutorialManager.SetFromSaveData(gameFile.PlayData.TutorialSaveData); Renderer.Camera.World = this; #endregion SetLoadingMessage("Creating Particles ..."); Game.DoLazyAction(new Action(() => ParticleManager = new ParticleManager(ComponentManager))); SetLoadingMessage("Creating GameMaster ..."); TaskManager = new TaskManager(); TaskManager.World = this; Time.NewDay += (time) => PayEmployees(); DwarfGame.LogSentryBreadcrumb("Loading", "Started new game with an existing file."); if (gameFile.PlayData.Tasks != null) { TaskManager = gameFile.PlayData.Tasks; TaskManager.World = this; } if (PlayerFaction.Economy.Information == null) { throw new InvalidProgramException(); } if (MathFunctions.RandEvent(0.01f)) { SetLoadingMessage("Reticulating Splines..."); } ChunkManager.NeedsMinimapUpdate = true; ChunkManager.StartThreads(); SetLoadingMessage("Presimulating ..."); ShowingWorld = false; OnLoadedEvent(); Thread.Sleep(1000); ShowingWorld = true; SetLoadingMessage("Complete."); // GameFile is no longer needed. gameFile = null; LoadStatus = LoadingStatus.Success; }
public VoxelChunk GenerateChunk(Vector3 origin, int chunkSizeX, int chunkSizeY, int chunkSizeZ, ComponentManager components, ContentManager content, GraphicsDevice graphics) { float waterHeight = SeaLevel; VoxelChunk c = new VoxelChunk(Manager, origin, 1, Manager.ChunkData.GetChunkID(origin + new Vector3(0.5f, 0.5f, 0.5f)), chunkSizeX, chunkSizeY, chunkSizeZ) { ShouldRebuild = true, ShouldRecalculateLighting = true }; Voxel voxel = c.MakeVoxel(0, 0, 0); for (int x = 0; x < chunkSizeX; x++) { for (int z = 0; z < chunkSizeZ; z++) { Vector2 v = new Vector2(x + origin.X, z + origin.Z) / PlayState.WorldScale; Overworld.Biome 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 = new Vector2(x + origin.X, z + origin.Z) / PlayState.WorldScale; float hNorm = Overworld.GetValue(Overworld.Map, pos, Overworld.ScalarFieldType.Height); float h = MathFunctions.Clamp(hNorm * chunkSizeY, 0.0f, chunkSizeY - 2); int stoneHeight = (int)Math.Max(h - 2, 1); for (int y = 0; y < chunkSizeY; y++) { voxel.GridPosition = new Vector3(x, y, z); if (y == 0) { voxel.Type = VoxelLibrary.GetVoxelType("Bedrock"); voxel.Health = 255; continue; } if (y <= stoneHeight && stoneHeight > 1) { voxel.Type = VoxelLibrary.GetVoxelType(biomeData.SubsurfVoxel); voxel.Health = VoxelLibrary.GetVoxelType(biomeData.SubsurfVoxel).StartingHealth; } 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.Type = VoxelLibrary.GetVoxelType(biomeData.GrassVoxel); voxel.Health = VoxelLibrary.GetVoxelType(biomeData.GrassVoxel).StartingHealth; } else if (!biomeData.ClumpGrass) { voxel.Type = VoxelLibrary.GetVoxelType(biomeData.GrassVoxel); voxel.Health = VoxelLibrary.GetVoxelType(biomeData.GrassVoxel).StartingHealth; } else { voxel.Type = VoxelLibrary.GetVoxelType(biomeData.SoilVoxel); voxel.Health = VoxelLibrary.GetVoxelType(biomeData.SoilVoxel).StartingHealth; } } else if (y > h && y > 0) { voxel.Type = VoxelLibrary.GetVoxelType("empty"); } else if (hNorm < waterHeight) { voxel.Type = VoxelLibrary.GetVoxelType(biomeData.ShoreVoxel); voxel.Health = VoxelLibrary.GetVoxelType(biomeData.ShoreVoxel).StartingHealth; } else { voxel.Type = VoxelLibrary.GetVoxelType(biomeData.SoilVoxel); voxel.Health = VoxelLibrary.GetVoxelType(biomeData.SoilVoxel).StartingHealth; } } } } GenerateCaves(c); GenerateWater(c); GenerateLava(c); c.ShouldRebuildWater = true; return(c); }
public OverworldData(Overworld.MapData[,] map, string name) { int sizeX = map.GetLength(0); int sizeY = map.GetLength(1); Biomes = new int[sizeX, sizeY]; Erosion = new float[sizeX, sizeY]; Faults = new float[sizeX, sizeY]; Rainfall = new float[sizeX, sizeY]; Temperature = new float[sizeX, sizeY]; Water = new int[sizeX, sizeY]; Weathering = new float[sizeX, sizeY]; Height = new float[sizeX, sizeY]; Name = name; for(int x = 0; x < sizeX; x++) { for(int y = 0; y < sizeY; y++) { Overworld.MapData data = map[x, y]; Biomes[x, y] = (int)data.Biome; Erosion[x, y] = (data.Erosion); Faults[x, y] = (data.Faults); Height[x, y] = (data.Height); Rainfall[x, y] = (data.Rainfall); Temperature[x, y] = (data.Temperature); Water[x, y] = (int)(data.Water); Weathering[x, y] = (data.Weathering); } } Screenshot = CreateTexture(PlayState.Game.GraphicsDevice, sizeX, sizeY); }
private void LoadThreaded() { DwarfGame.ExitGame = false; // Ensure we're using the invariant culture. Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; LoadStatus = LoadingStatus.Loading; SetLoadingMessage("Initializing ..."); while (GraphicsDevice == null) { Thread.Sleep(100); } Thread.Sleep(1000); #if !DEBUG try { #endif bool fileExists = !string.IsNullOrEmpty(ExistingFile); SetLoadingMessage("Creating Sky..."); Sky = new SkyRenderer(); #region Reading game file if (fileExists) { SetLoadingMessage("Loading " + ExistingFile); gameFile = SaveGame.CreateFromDirectory(ExistingFile); if (gameFile == null) { throw new InvalidOperationException("Game File does not exist."); } // Todo: REMOVE THIS WHEN THE NEW SAVE SYSTEM IS COMPLETE. if (gameFile.Metadata.Version != Program.Version && !Program.CompatibleVersions.Contains(gameFile.Metadata.Version)) { throw new InvalidOperationException(String.Format("Game file is from version {0}. Compatible versions are {1}.", gameFile.Metadata.Version, TextGenerator.GetListString(Program.CompatibleVersions))); } Sky.TimeOfDay = gameFile.Metadata.TimeOfDay; Time = gameFile.Metadata.Time; WorldOrigin = gameFile.Metadata.WorldOrigin; WorldScale = gameFile.Metadata.WorldScale; WorldSize = gameFile.Metadata.NumChunks; GameID = gameFile.Metadata.GameID; if (gameFile.Metadata.OverworldFile != null && gameFile.Metadata.OverworldFile != "flat") { SetLoadingMessage("Loading world " + gameFile.Metadata.OverworldFile); Overworld.Name = gameFile.Metadata.OverworldFile; DirectoryInfo worldDirectory = Directory.CreateDirectory(DwarfGame.GetWorldDirectory() + Path.DirectorySeparatorChar + Overworld.Name); var overWorldFile = new NewOverworldFile(worldDirectory.FullName); Overworld.Map = overWorldFile.Data.Data; Overworld.Name = overWorldFile.Data.Name; } else { SetLoadingMessage("Generating flat world.."); Overworld.CreateUniformLand(GraphicsDevice); } } #endregion #region Initialize static data { Vector3 origin = new Vector3(0, 0, 0); Vector3 extents = new Vector3(1500, 1500, 1500); OctTree = new OctTreeNode <Body>(origin - extents, origin + extents); PrimitiveLibrary.Initialize(GraphicsDevice, Content); InstanceRenderer = new InstanceRenderer(GraphicsDevice, Content); Color[] white = new Color[1]; white[0] = Color.White; pixel = new Texture2D(GraphicsDevice, 1, 1); pixel.SetData(white); Tilesheet = AssetManager.GetContentTexture(ContentPaths.Terrain.terrain_tiles); AspectRatio = GraphicsDevice.Viewport.AspectRatio; DefaultShader = new Shader(Content.Load <Effect>(ContentPaths.Shaders.TexturedShaders), true); DefaultShader.ScreenWidth = GraphicsDevice.Viewport.Width; DefaultShader.ScreenHeight = GraphicsDevice.Viewport.Height; CraftLibrary.InitializeDefaultLibrary(); PotionLibrary.Initialize(); VoxelLibrary.InitializeDefaultLibrary(GraphicsDevice); GrassLibrary.InitializeDefaultLibrary(); DecalLibrary.InitializeDefaultLibrary(); bloom = new BloomComponent(Game) { Settings = BloomSettings.PresetSettings[5] }; bloom.Initialize(); SoundManager.Content = Content; if (PlanService != null) { PlanService.Restart(); } JobLibrary.Initialize(); MonsterSpawner = new MonsterSpawner(this); EntityFactory.Initialize(this); } #endregion SetLoadingMessage("Creating Planner ..."); PlanService = new PlanService(); SetLoadingMessage("Creating Shadows..."); Shadows = new ShadowRenderer(GraphicsDevice, 1024, 1024); SetLoadingMessage("Creating Liquids ..."); #region liquids WaterRenderer = new WaterRenderer(GraphicsDevice); #endregion SetLoadingMessage("Generating Initial Terrain Chunks ..."); if (!fileExists) { GameID = MathFunctions.Random.Next(0, 1024); } ChunkGenerator = new ChunkGenerator(VoxelLibrary, Seed, 0.02f) { SeaLevel = SeaLevel }; #region Load Components if (fileExists) { ChunkManager = new ChunkManager(Content, this, ChunkGenerator, WorldSize.X, WorldSize.Y, WorldSize.Z); Splasher = new Splasher(ChunkManager); ChunkRenderer = new ChunkRenderer(ChunkManager.ChunkData); SetLoadingMessage("Loading Terrain..."); gameFile.ReadChunks(ExistingFile); ChunkManager.ChunkData.LoadFromFile(ChunkManager, gameFile, SetLoadingMessage); SetLoadingMessage("Loading Entities..."); gameFile.LoadPlayData(ExistingFile, this); Camera = gameFile.PlayData.Camera; DesignationDrawer = gameFile.PlayData.Designations; Vector3 origin = new Vector3(WorldOrigin.X, 0, WorldOrigin.Y); Vector3 extents = new Vector3(1500, 1500, 1500); if (gameFile.PlayData.Stats != null) { Stats = gameFile.PlayData.Stats; } if (gameFile.PlayData.Resources != null) { foreach (var resource in gameFile.PlayData.Resources) { if (!ResourceLibrary.Resources.ContainsKey(resource.Key)) { ResourceLibrary.Add(resource.Value); } } } ComponentManager = new ComponentManager(gameFile.PlayData.Components, this); foreach (var component in gameFile.PlayData.Components.SaveableComponents) { if (!ComponentManager.HasComponent(component.GlobalID) && ComponentManager.HasComponent(component.Parent.GlobalID)) { // Logically impossible. throw new InvalidOperationException("Component exists in save data but not in manager."); } } ConversationMemory = gameFile.PlayData.ConversationMemory; Factions = gameFile.PlayData.Factions; ComponentManager.World = this; Sky.TimeOfDay = gameFile.Metadata.TimeOfDay; Time = gameFile.Metadata.Time; WorldOrigin = gameFile.Metadata.WorldOrigin; WorldScale = gameFile.Metadata.WorldScale; // Restore native factions from deserialized data. Natives = new List <Faction>(); foreach (Faction faction in Factions.Factions.Values) { if (faction.Race.IsNative && faction.Race.IsIntelligent && !faction.IsRaceFaction) { Natives.Add(faction); } } Diplomacy = gameFile.PlayData.Diplomacy; GoalManager = new Goals.GoalManager(); GoalManager.Initialize(new List <Goals.Goal>());// gameFile.PlayData.Goals); TutorialManager = new Tutorial.TutorialManager(); TutorialManager.SetFromSaveData(gameFile.PlayData.TutorialSaveData); } else { Time = new WorldTime(); Camera = new OrbitCamera(this, new Vector3(VoxelConstants.ChunkSizeX, VoxelConstants.ChunkSizeY - 1.0f, VoxelConstants.ChunkSizeZ), new Vector3(VoxelConstants.ChunkSizeY, VoxelConstants.ChunkSizeY - 1.0f, VoxelConstants.ChunkSizeZ) + Vector3.Up * 10.0f + Vector3.Backward * 10, MathHelper.PiOver4, AspectRatio, 0.1f, GameSettings.Default.VertexCullDistance); ChunkManager = new ChunkManager(Content, this, ChunkGenerator, WorldSize.X, WorldSize.Y, WorldSize.Z); Splasher = new Splasher(ChunkManager); ChunkRenderer = new ChunkRenderer(ChunkManager.ChunkData); Camera.Position = new Vector3(0, 10, 0) + new Vector3(WorldSize.X * VoxelConstants.ChunkSizeX, 0, WorldSize.Z * VoxelConstants.ChunkSizeZ) * 0.5f; Camera.Target = new Vector3(0, 10, 1) + new Vector3(WorldSize.X * VoxelConstants.ChunkSizeX, 0, WorldSize.Z * VoxelConstants.ChunkSizeZ) * 0.5f; ComponentManager = new ComponentManager(this); ComponentManager.SetRootComponent(new Body(ComponentManager, "root", Matrix.Identity, Vector3.Zero, Vector3.Zero)); if (Natives == null) // Todo: Always true?? { FactionLibrary library = new FactionLibrary(); library.Initialize(this, CompanyMakerState.CompanyInformation); Natives = new List <Faction>(); for (int i = 0; i < 10; i++) { Natives.Add(library.GenerateFaction(this, i, 10)); } } #region Prepare Factions foreach (Faction faction in Natives) { faction.World = this; if (faction.RoomBuilder == null) { faction.RoomBuilder = new RoomBuilder(faction, this); } } Factions = new FactionLibrary(); if (Natives != null && Natives.Count > 0) { Factions.AddFactions(this, Natives); } Factions.Initialize(this, CompanyMakerState.CompanyInformation); Point playerOrigin = new Point((int)(WorldOrigin.X), (int)(WorldOrigin.Y)); Factions.Factions["Player"].Center = playerOrigin; Factions.Factions["The Motherland"].Center = new Point(playerOrigin.X + 50, playerOrigin.Y + 50); #endregion Diplomacy = new Diplomacy(this); Diplomacy.Initialize(Time.CurrentDate); // Initialize goal manager here. GoalManager = new Goals.GoalManager(); GoalManager.Initialize(new List <Goals.Goal>()); TutorialManager = new Tutorial.TutorialManager(); TutorialManager.TutorialEnabled = !GameSettings.Default.TutorialDisabledGlobally; Tutorial("new game start"); foreach (var item in CraftLibrary.EnumerateCraftables()) { if (!String.IsNullOrEmpty(item.Tutorial)) { TutorialManager.AddTutorial(item.Name, item.Tutorial, item.Icon); } } } Camera.World = this; //Drawer3D.Camera = Camera; #endregion SetLoadingMessage("Creating Particles ..."); ParticleManager = new ParticleManager(ComponentManager); SetLoadingMessage("Creating GameMaster ..."); Master = new GameMaster(Factions.Factions["Player"], Game, ComponentManager, ChunkManager, Camera, GraphicsDevice); // If there's no file, we have to initialize the first chunk coordinate if (gameFile == null) { ChunkManager.GenerateInitialChunks(SpawnRect, new GlobalChunkCoordinate(0, 0, 0), SetLoadingMessage); } if (gameFile != null) { if (gameFile.PlayData.Tasks != null) { Master.NewArrivals = gameFile.PlayData.NewArrivals ?? new List <GameMaster.ApplicantArrival>(); Master.TaskManager = gameFile.PlayData.Tasks; Master.TaskManager.Faction = Master.Faction; } if (gameFile.PlayData.InitialEmbark != null) { InitialEmbark = gameFile.PlayData.InitialEmbark; } ChunkManager.World.Master.SetMaxViewingLevel(gameFile.Metadata.Slice > 0 ? gameFile.Metadata.Slice : ChunkManager.World.Master.MaxViewingLevel); } if (Master.Faction.Economy.Company.Information == null) { Master.Faction.Economy.Company.Information = new CompanyInformation(); } CreateInitialEmbarkment(); foreach (var chunk in ChunkManager.ChunkData.ChunkMap) { chunk.CalculateInitialSunlight(); } if (RevealSurface) { VoxelHelpers.InitialReveal(ChunkManager, ChunkManager.ChunkData, new VoxelHandle( ChunkManager.ChunkData.GetChunkEnumerator().FirstOrDefault(), new LocalVoxelCoordinate(0, VoxelConstants.ChunkSizeY - 1, 0))); } foreach (var chunk in ChunkManager.ChunkData.ChunkMap) { ChunkManager.InvalidateChunk(chunk); } SetLoadingMessage("Creating Geometry..."); ChunkManager.GenerateAllGeometry(); ChunkManager.StartThreads(); SetLoadingMessage("Presimulating ..."); ShowingWorld = false; OnLoadedEvent(); Thread.Sleep(1000); ShowingWorld = true; SetLoadingMessage("Complete."); // GameFile is no longer needed. gameFile = null; LoadStatus = LoadingStatus.Success; #if !DEBUG } catch (Exception exception) { Game.CaptureException(exception); LoadingException = exception; LoadStatus = LoadingStatus.Failure; ProgramData.WriteExceptionLog(exception); } #endif }
public void HandleAmbientSound() { AmbienceTimer.Update(DwarfTime.LastTime); if (!AmbienceTimer.HasTriggered && !firstAmbience) { return; } firstAmbience = false; // Before doing anything, determine if there is a rain or snow storm. if (Weather.IsRaining()) { PlaySpecialAmbient("sfx_amb_rain_storm"); return; } if (Weather.IsSnowing()) { PlaySpecialAmbient("sfx_amb_snow_storm"); return; } // First check voxels to see if we're underground or underwater. var vox = VoxelHelpers.FindFirstVisibleVoxelOnScreenRay(ChunkManager.ChunkData, GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2, Camera, GraphicsDevice.Viewport, 100.0f, false, null); if (vox.IsValid) { float height = WaterRenderer.GetTotalWaterHeightCells(vox); if (height > 0) { PlaySpecialAmbient("sfx_amb_ocean"); return; } else { // Unexplored voxels assumed to be cave. if (vox.IsValid && !vox.IsExplored) { PlaySpecialAmbient("sfx_amb_cave"); return; } var above = VoxelHelpers.GetVoxelAbove(vox); // Underground, do the cave test. if (above.IsValid && above.IsEmpty && above.Sunlight == false) { PlaySpecialAmbient("sfx_amb_cave"); return; } } } else { return; } // Now check for biome ambience. var pos = vox.WorldPosition; var biome = Overworld.GetBiomeAt(pos, WorldScale, WorldOrigin); if (biome != null && !string.IsNullOrEmpty(biome.DayAmbience)) { if (prevAmbience[0] != biome.DayAmbience) { if (!string.IsNullOrEmpty(prevAmbience[0])) { SoundManager.StopAmbience(prevAmbience[0]); prevAmbience[0] = null; } if (!string.IsNullOrEmpty(prevAmbience[1])) { SoundManager.StopAmbience(prevAmbience[1]); prevAmbience[1] = null; } SoundManager.PlayAmbience(biome.DayAmbience); } prevAmbience[0] = biome.DayAmbience; } if (!string.IsNullOrEmpty(biome.NightAmbience) && prevAmbience[1] != biome.NightAmbience) { prevAmbience[1] = biome.NightAmbience; SoundManager.PlayAmbience(biome.NightAmbience); } }
public static void MinBlend(MapData[,] heightMap, Vector2 pos, float height, Overworld.ScalarFieldType type) { int x = Math.Max(Math.Min((int) pos.X, heightMap.GetLength(0) - 1), 0); int y = Math.Max(Math.Min((int) pos.Y, heightMap.GetLength(1) - 1), 0); float orig = heightMap[x, y].GetValue(type); heightMap[x, y].SetValue(type, Math.Min(orig, height)); }
public void RebuildMoteLayer(int Y) { var moteList = new List <NewInstanceData>(); // Enumerate voxels. for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x) { for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z) { // Don't generate motes if above is not empty if (Y < VoxelConstants.ChunkSizeY - 1) { var voxelAbove = new VoxelHandle(this, new LocalVoxelCoordinate(x, Y + 1, z)); if (!voxelAbove.IsEmpty || voxelAbove.LiquidLevel != 0) { continue; } } var v = new VoxelHandle(this, new LocalVoxelCoordinate(x, Y, z)); // Don't generate in empty voxels. if (v.IsEmpty) { continue; } if (!v.IsExplored) { continue; } // Find biome type. var biomeData = Overworld.GetBiomeAt(v.WorldPosition, Manager.World.WorldScale, Manager.World.WorldOrigin); // Don't generate if not on grass type. if (v.GrassType == 0 || GrassLibrary.GetGrassType(v.GrassType).Name != biomeData.GrassDecal) { continue; } // Biomes can contain multiple types of mote. foreach (var moteDetail in biomeData.Motes) { // Lower mote if voxel is ramped. float vOffset = 0.0f; if (v.RampType != RampType.None) { vOffset = -0.5f; } var vPos = v.WorldPosition * moteDetail.RegionScale; float value = MoteNoise.Noise(vPos.X, vPos.Y, vPos.Z); if (!(Math.Abs(value) > moteDetail.SpawnThreshold)) { continue; } float s = MoteScaleNoise.Noise(vPos.X, vPos.Y, vPos.Z) * moteDetail.MoteScale; var smallNoise = ClampVector(VertexNoise.GetRandomNoiseVector(vPos * 20.0f) * 20.0f, 0.4f); smallNoise.Y = 0.0f; var mote = GenerateGrassMote( Manager.World, v.WorldPosition + new Vector3(0.5f, 1.0f + s * 0.5f + vOffset, 0.5f) + smallNoise, new Color(v.Sunlight ? 255 : 0, 128, 0), s, moteDetail.Name); moteList.Add(mote); } } } MoteRecords[Y] = moteList; }