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?
This commit is contained in:
Joonas Rikkonen
2017-08-15 22:43:14 +03:00
parent 9c372137bd
commit 52a52cdfc7
6 changed files with 161 additions and 10 deletions

View File

@@ -164,7 +164,7 @@
<Compile Include="Source\Map\Lights\LightSource.cs" />
<Compile Include="Source\Map\LinkedSubmarine.cs" />
<Compile Include="Source\Map\Map\Location.cs" />
<Compile Include="Source\Map\Map.cs" />
<Compile Include="Source\Map\Map\Map.cs" />
<Compile Include="Source\Map\MapEntity.cs" />
<Compile Include="Source\Map\MapEntityPrefab.cs" />
<Compile Include="Source\Map\Structure.cs" />

View File

@@ -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);
}
}
}

View File

@@ -1,6 +1,22 @@
<?xml version="1.0" encoding="utf-8" ?>
<LevelGenerationParameters>
<Biomes>
<Biome
name ="Cold Caverns"
description="asdgfdfg"/>
<Biome
name ="Volcanic Ridge"
description="asdgfdfg"/>
<Biome
name ="Great Sea"
description="asdgfdfg"/>
</Biomes>
<Default
biomes="Cold Caverns"
width="150000"
height="60000"
VoronoiSiteInterval="2000,2000"
@@ -20,6 +36,7 @@
/>
<Open
biomes="Great Sea"
width="200000"
height="50000"
VoronoiSiteInterval="2000,2000"
@@ -34,6 +51,7 @@
/>
<Pillars
biomes="Cold Caverns, Volcanic Ridge"
width="100000"
height="80000"
VoronoiSiteInterval="1000,8000"
@@ -54,6 +72,7 @@
/>
<Slabs
biomes="Cold Caverns"
width="150000"
height="50000"
VoronoiSiteInterval="8000,1000"
@@ -69,6 +88,7 @@
/>
<Maze
biomes="Cold Caverns"
width="100000"
height="70000"
VoronoiSiteInterval="1500,1500"

View File

@@ -161,7 +161,7 @@ namespace Barotrauma
{
string seed = locationConnection.Locations[0].Name + locationConnection.Locations[1].Name;
return new Level(seed, locationConnection.Difficulty, LevelGenerationParams.GetRandom(seed));
return new Level(seed, locationConnection.Difficulty, LevelGenerationParams.GetRandom(seed, locationConnection.Biome));
}
public static Level CreateRandom(string seed = "")

View File

@@ -6,9 +6,29 @@ using System.Xml.Linq;
namespace Barotrauma
{
class Biome
{
public readonly string Name;
public readonly string Description;
public Biome(string name, string description)
{
Name = name;
Description = description;
}
public Biome(XElement element)
{
Name = ToolBox.GetAttributeString(element, "name", "Biome");
Description = ToolBox.GetAttributeString(element, "description", "");
}
}
class LevelGenerationParams : IPropertyObject
{
private static List<LevelGenerationParams> presets;
private static List<LevelGenerationParams> levelParams;
private static List<Biome> biomes;
public string Name
{
@@ -47,6 +67,9 @@ namespace Barotrauma
private int ruinCount;
//which biomes can this type of level appear in
private List<Biome> allowedBiomes = new List<Biome>();
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<Biome> 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<Biome>(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<LevelGenerationParams>();
levelParams = new List<LevelGenerationParams>();
biomes = new List<Biome>();
var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.LevelGenerationParameters);
if (!files.Any())
{
files.Add("Content/Map/LevelGenerationParameters.xml");
}
List<XElement> biomeElements = new List<XElement>();
List<XElement> levelParamElements = new List<XElement>();
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));
}
}
}
}

View File

@@ -209,8 +209,46 @@ namespace Barotrauma
connection.CrackSegments = MathUtils.GenerateJaggedLine(start, end, generations, 5.0f);
}
List<LocationConnection> biomeSeeds = new List<LocationConnection>();
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<LocationConnection> seeds)
{
List<LocationConnection> nextSeeds = new List<LocationConnection>();
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<LocationConnection> 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<Vector2[]> CrackSegments;