From 52a52cdfc7476306f7010882f69e0aa4f4d41610 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Tue, 15 Aug 2017 22:43:14 +0300 Subject: [PATCH] Level biomes (basically a way of categorizing level generation parameters). The single player map is now divided into biomes, meaning that specific types of levels are generated at different areas of the map. TODO: more variety between biomes, assign the map biomes in a less random way (e.g. splotches of easier biomes connected by more dangerous ones, very dangerous biomes at the edges of the map...), option to select the biome in MP? --- .../BarotraumaClient/BarotraumaClient.csproj | 2 +- .../Source/Map/{ => Map}/Map.cs | 7 ++ .../Content/Map/LevelGenerationParameters.xml | 20 ++++ .../Source/Map/Levels/Level.cs | 2 +- .../Map/Levels/LevelGenerationParams.cs | 100 ++++++++++++++++-- .../BarotraumaShared/Source/Map/Map/Map.cs | 40 +++++++ 6 files changed, 161 insertions(+), 10 deletions(-) rename Barotrauma/BarotraumaClient/Source/Map/{ => Map}/Map.cs (97%) diff --git a/Barotrauma/BarotraumaClient/BarotraumaClient.csproj b/Barotrauma/BarotraumaClient/BarotraumaClient.csproj index f133ac605..b9cdec336 100644 --- a/Barotrauma/BarotraumaClient/BarotraumaClient.csproj +++ b/Barotrauma/BarotraumaClient/BarotraumaClient.csproj @@ -164,7 +164,7 @@ - + diff --git a/Barotrauma/BarotraumaClient/Source/Map/Map.cs b/Barotrauma/BarotraumaClient/Source/Map/Map/Map.cs similarity index 97% rename from Barotrauma/BarotraumaClient/Source/Map/Map.cs rename to Barotrauma/BarotraumaClient/Source/Map/Map/Map.cs index 595528af4..2e97ba120 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Map.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Map/Map.cs @@ -62,6 +62,7 @@ namespace Barotrauma foreach (LocationConnection connection in connections) { Color crackColor = Color.White * Math.Max(connection.Difficulty / 100.0f, 1.5f); + if (selectedLocation != currentLocation && (connection.Locations.Contains(selectedLocation) && connection.Locations.Contains(currentLocation))) @@ -113,6 +114,12 @@ namespace Barotrauma new Rectangle((int)start.X, (int)start.Y, (int)dist + 2, width), new Rectangle(0, 0, iceCrack.Width, 60), crackColor, MathUtils.VectorToAngle(end - start), new Vector2(0, 30), SpriteEffects.None, 0.01f); + + if (i == 0) + { + + GUI.DrawString(spriteBatch, start, connection.Biome.Name, Color.White); + } } } diff --git a/Barotrauma/BarotraumaShared/Content/Map/LevelGenerationParameters.xml b/Barotrauma/BarotraumaShared/Content/Map/LevelGenerationParameters.xml index 911976c9c..83dbd38d9 100644 --- a/Barotrauma/BarotraumaShared/Content/Map/LevelGenerationParameters.xml +++ b/Barotrauma/BarotraumaShared/Content/Map/LevelGenerationParameters.xml @@ -1,6 +1,22 @@  + + + + + + + + + presets; + private static List levelParams; + private static List biomes; + public string Name { @@ -47,6 +67,9 @@ namespace Barotrauma private int ruinCount; + //which biomes can this type of level appear in + private List allowedBiomes = new List(); + public Color BackgroundColor { get; @@ -196,22 +219,39 @@ namespace Barotrauma set { bottomHoleProbability = MathHelper.Clamp(value, 0.0f, 1.0f); } } - public static LevelGenerationParams GetRandom(string seed) + public static List GetBiomes() + { + return biomes; + } + + public static LevelGenerationParams GetRandom(string seed, Biome biome = null) { Rand.SetSyncedSeed(ToolBox.StringToInt(seed)); - if (presets == null || !presets.Any()) + if (levelParams == null || !levelParams.Any()) { DebugConsole.ThrowError("Level generation presets not found - using default presets"); return new LevelGenerationParams(null); } - return presets[Rand.Range(0, presets.Count, Rand.RandSync.Server)]; + if (biome == null) + { + return levelParams[Rand.Range(0, levelParams.Count, Rand.RandSync.Server)]; + } + + var matchingLevelParams = levelParams.FindAll(lp => lp.allowedBiomes.Contains(biome)); + if (matchingLevelParams.Count == 0) + { + DebugConsole.ThrowError("Level generation presets not found for the biome \"" + biome.Name + "\"!"); + return new LevelGenerationParams(null); + } + + return matchingLevelParams[Rand.Range(0, matchingLevelParams.Count, Rand.RandSync.Server)]; } private LevelGenerationParams(XElement element) { - Name = element==null ? "default" : element.Name.ToString(); + Name = element == null ? "default" : element.Name.ToString(); ObjectProperties = ObjectProperty.InitProperties(this, element); Vector3 colorVector = ToolBox.GetAttributeVector3(element, "BackgroundColor", new Vector3(50, 46, 20)); @@ -224,18 +264,45 @@ namespace Barotrauma MainPathNodeIntervalRange = ToolBox.GetAttributeVector2(element, "MainPathNodeIntervalRange", new Vector2(5000.0f, 10000.0f)); SmallTunnelLengthRange = ToolBox.GetAttributeVector2(element, "SmallTunnelLengthRange", new Vector2(5000.0f, 10000.0f)); + + string biomeStr = ToolBox.GetAttributeString(element, "biomes", ""); + + if (string.IsNullOrWhiteSpace(biomeStr)) + { + allowedBiomes = new List(biomes); + } + else + { + string[] biomeNames = biomeStr.Split(','); + for (int i = 0; i < biomeNames.Length; i++) + { + string biomeName = biomeNames[i].Trim().ToLowerInvariant(); + Biome matchingBiome = biomes.Find(b => b.Name.ToLowerInvariant() == biomeName); + if (matchingBiome == null) + { + DebugConsole.ThrowError("Error in level generation parameters: biome \"" + biomeName + "\" not found."); + continue; + } + + allowedBiomes.Add(matchingBiome); + } + } } public static void LoadPresets() { - presets = new List(); + levelParams = new List(); + biomes = new List(); var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.LevelGenerationParameters); if (!files.Any()) { files.Add("Content/Map/LevelGenerationParameters.xml"); } - + + List biomeElements = new List(); + List levelParamElements = new List(); + foreach (string file in files) { XDocument doc = ToolBox.TryLoadXml(file); @@ -243,9 +310,26 @@ namespace Barotrauma foreach (XElement element in doc.Root.Elements()) { - presets.Add(new LevelGenerationParams(element)); + if (element.Name.ToString().ToLowerInvariant() == "biomes") + { + biomeElements.AddRange(element.Elements()); + } + else + { + levelParamElements.Add(element); + } } } + + foreach (XElement biomeElement in biomeElements) + { + biomes.Add(new Biome(biomeElement)); + } + + foreach (XElement levelParamElement in levelParamElements) + { + levelParams.Add(new LevelGenerationParams(levelParamElement)); + } } } } diff --git a/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs b/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs index d48927ddb..7bcf8a74b 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs @@ -209,8 +209,46 @@ namespace Barotrauma connection.CrackSegments = MathUtils.GenerateJaggedLine(start, end, generations, 5.0f); } + List biomeSeeds = new List(); + foreach (Biome biome in LevelGenerationParams.GetBiomes()) + { + LocationConnection seed = connections[0]; + while (biomeSeeds.Contains(seed)) + { + seed = connections[Rand.Range(0, connections.Count, Rand.RandSync.Server)]; + } + seed.Biome = biome; + biomeSeeds.Add(seed); + } + + ExpandBiomes(biomeSeeds); } + private void ExpandBiomes(List seeds) + { + List nextSeeds = new List(); + foreach (LocationConnection connection in seeds) + { + foreach (Location location in connection.Locations) + { + foreach (LocationConnection otherConnection in location.Connections) + { + if (otherConnection == connection) continue; + if (otherConnection.Biome != null) continue; //already assigned + + otherConnection.Biome = connection.Biome; + nextSeeds.Add(otherConnection); + } + } + } + + if (nextSeeds.Count > 0) + { + ExpandBiomes(nextSeeds); + } + } + + private void GenerateDifficulties(Location start, List locations, float currDifficulty) { //start.Difficulty = currDifficulty; @@ -258,6 +296,8 @@ namespace Barotrauma private Location[] locations; private Level level; + public Biome Biome; + public float Difficulty; public List CrackSegments;