using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Xml.Serialization; using TransportGame.Business; using TransportGame.Model; using TransportGame.Noise; using TransportGame.Utils; using TransportGame.Utils.Algorithms; using UnityEngine; namespace TransportGame.Generator { public class TerrainGenerator { /// /// Gets or sets the underlying noise generator /// public NoiseGenerator Noise { get; set; } private System.Random random = new System.Random(); public TerrainGenerator() { Noise = new PerlinNoiseGenerator(); if (ConfigurationManager.TerrGenConfig == null) throw new Exception("WTF?"); Noise.Octaves = ConfigurationManager.TerrGenConfig.NoiseOctaves; Noise.NonLinearPower = ConfigurationManager.TerrGenConfig.NoiseNonLinearPower; Noise.Scale = ConfigurationManager.TerrGenConfig.ElevationScale; } public Map Generate(int width, int height) { // Create map Map map = new Map(width, height); // Pick a random biome map.Biome = PickBiome(); Logger.Info("Picked biome: {0}", map.Biome.Name); // Generate elevation GenerateElevation(map); // Generate water level float waterAmount = random.NextSingle(map.Biome.Moisture.Minimum, map.Biome.Moisture.Maximum); map.WaterLevel = Mathf.Pow(waterAmount, ConfigurationManager.TerrGenConfig.WaterNonLinearPower) * map.Biome.Height; DumpData(map, "1generated.map"); // Simulate water erosion new TerrainEroder(map).Erode(); DumpData(map, "2eroded.map"); return map; } private Biome PickBiome() { int biomeCount = BiomeManager.Biomes.Count(); int biome = random.Next(biomeCount); return BiomeManager.Biomes.ElementAt(biome); } private void GenerateElevation(Map map) { for (int x = 0; x < map.Width; ++x) for (int y = 0; y < map.Height; ++y) map.Heights[x, y] = Noise.Generate(x, y, 0, 1); } private void DumpData(Map map, string filename) { XmlSerializer serializer = new XmlSerializer(typeof(Map)); using (StreamWriter writer = new StreamWriter(Path.Combine(Logger.LogsDirectory, filename))) { serializer.Serialize(writer, map); writer.Close(); } } } }