(965c31410a) Unstable v0.10.4.0
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,164 @@
|
||||
using Barotrauma.Extensions;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class LevelData
|
||||
{
|
||||
public enum LevelType
|
||||
{
|
||||
LocationConnection,
|
||||
Outpost
|
||||
}
|
||||
|
||||
public readonly LevelType Type;
|
||||
|
||||
public readonly string Seed;
|
||||
|
||||
public float Difficulty;
|
||||
|
||||
public readonly Biome Biome;
|
||||
|
||||
public readonly LevelGenerationParams GenerationParams;
|
||||
|
||||
public OutpostGenerationParams ForceOutpostGenerationParams;
|
||||
|
||||
public readonly Point Size;
|
||||
|
||||
public readonly List<EventPrefab> EventHistory = new List<EventPrefab>();
|
||||
|
||||
public LevelData(string seed, float difficulty, float sizeFactor, LevelGenerationParams generationParams, Biome biome)
|
||||
{
|
||||
Seed = seed ?? throw new ArgumentException("Seed was null");
|
||||
Biome = biome ?? throw new ArgumentException("Biome was null");
|
||||
GenerationParams = generationParams ?? throw new ArgumentException("Level generation parameters were null");
|
||||
Type = GenerationParams.Type;
|
||||
Difficulty = difficulty;
|
||||
|
||||
sizeFactor = MathHelper.Clamp(sizeFactor, 0.0f, 1.0f);
|
||||
int width = (int)MathHelper.Lerp(generationParams.MinWidth, generationParams.MaxWidth, sizeFactor);
|
||||
|
||||
Size = new Point(
|
||||
(int)MathUtils.Round(width, Level.GridCellSize),
|
||||
(int)MathUtils.Round(generationParams.Height, Level.GridCellSize));
|
||||
}
|
||||
|
||||
public LevelData(XElement element)
|
||||
{
|
||||
Seed = element.GetAttributeString("seed", "");
|
||||
Difficulty = element.GetAttributeFloat("difficulty", 0.0f);
|
||||
Size = element.GetAttributePoint("size", new Point(1000));
|
||||
Enum.TryParse(element.GetAttributeString("type", "LocationConnection"), out Type);
|
||||
|
||||
string generationParamsId = element.GetAttributeString("generationparams", "");
|
||||
GenerationParams = LevelGenerationParams.LevelParams.Find(l => l.Identifier == generationParamsId);
|
||||
if (GenerationParams == null)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error while loading a level. Could not find level generation params with the ID \"{generationParamsId}\".");
|
||||
GenerationParams = LevelGenerationParams.LevelParams.FirstOrDefault(l => l.Type == Type);
|
||||
if (GenerationParams == null)
|
||||
{
|
||||
GenerationParams = LevelGenerationParams.LevelParams.First();
|
||||
}
|
||||
}
|
||||
|
||||
string biomeIdentifier = element.GetAttributeString("biome", "");
|
||||
Biome = LevelGenerationParams.GetBiomes().FirstOrDefault(b => b.Identifier == biomeIdentifier);
|
||||
if (Biome == null)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in level data: could not find the biome \"{biomeIdentifier}\".");
|
||||
Biome = LevelGenerationParams.GetBiomes().First();
|
||||
}
|
||||
|
||||
string[] prefabNames = element.GetAttributeStringArray("eventhistory", new string[] { });
|
||||
EventHistory.AddRange(EventSet.PrefabList.Where(p => prefabNames.Any(n => p.Identifier.Equals(n, StringComparison.InvariantCultureIgnoreCase))));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates level data using the properties of the connection (seed, size, difficulty)
|
||||
/// </summary>
|
||||
public LevelData(LocationConnection locationConnection)
|
||||
{
|
||||
Seed = locationConnection.Locations[0].BaseName + locationConnection.Locations[1].BaseName;
|
||||
Biome = locationConnection.Biome;
|
||||
Type = LevelType.LocationConnection;
|
||||
GenerationParams = LevelGenerationParams.GetRandom(Seed, LevelType.LocationConnection, Biome);
|
||||
Difficulty = locationConnection.Difficulty;
|
||||
|
||||
float sizeFactor = MathUtils.InverseLerp(
|
||||
MapGenerationParams.Instance.SmallLevelConnectionLength,
|
||||
MapGenerationParams.Instance.LargeLevelConnectionLength,
|
||||
locationConnection.Length);
|
||||
int width = (int)MathHelper.Lerp(GenerationParams.MinWidth, GenerationParams.MaxWidth, sizeFactor);
|
||||
Size = new Point(
|
||||
(int)MathUtils.Round(width, Level.GridCellSize),
|
||||
(int)MathUtils.Round(GenerationParams.Height, Level.GridCellSize));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates level data using the properties of the location
|
||||
/// </summary>
|
||||
public LevelData(Location location)
|
||||
{
|
||||
Seed = location.BaseName;
|
||||
Biome = location.Biome;
|
||||
Type = LevelType.Outpost;
|
||||
GenerationParams = LevelGenerationParams.GetRandom(Seed, LevelType.Outpost, Biome);
|
||||
Difficulty = 0.0f;
|
||||
|
||||
var rand = new MTRandom(ToolBox.StringToInt(Seed));
|
||||
int width = (int)MathHelper.Lerp(GenerationParams.MinWidth, GenerationParams.MaxWidth, (float)rand.NextDouble());
|
||||
Size = new Point(
|
||||
(int)MathUtils.Round(width, Level.GridCellSize),
|
||||
(int)MathUtils.Round(GenerationParams.Height, Level.GridCellSize));
|
||||
}
|
||||
|
||||
public static LevelData CreateRandom(string seed = "", float? difficulty = null, LevelGenerationParams generationParams = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(seed))
|
||||
{
|
||||
seed = Rand.Range(0, int.MaxValue, Rand.RandSync.Server).ToString();
|
||||
}
|
||||
|
||||
Rand.SetSyncedSeed(ToolBox.StringToInt(seed));
|
||||
|
||||
LevelType type = generationParams == null ? LevelData.LevelType.LocationConnection : generationParams.Type;
|
||||
|
||||
if (generationParams == null) { generationParams = LevelGenerationParams.GetRandom(seed, type); }
|
||||
var biome =
|
||||
LevelGenerationParams.GetBiomes().FirstOrDefault(b => generationParams.AllowedBiomes.Contains(b)) ??
|
||||
LevelGenerationParams.GetBiomes().GetRandom(Rand.RandSync.Server);
|
||||
|
||||
return new LevelData(
|
||||
seed,
|
||||
difficulty ?? Rand.Range(30.0f, 80.0f, Rand.RandSync.Server),
|
||||
Rand.Range(0.0f, 1.0f, Rand.RandSync.Server),
|
||||
generationParams,
|
||||
biome);
|
||||
}
|
||||
|
||||
public void Save(XElement parentElement)
|
||||
{
|
||||
var newElement = new XElement("Level",
|
||||
new XAttribute("seed", Seed),
|
||||
new XAttribute("biome", Biome.Identifier),
|
||||
new XAttribute("type", Type.ToString()),
|
||||
new XAttribute("difficulty", Difficulty.ToString("G", CultureInfo.InvariantCulture)),
|
||||
new XAttribute("size", XMLExtensions.PointToString(Size)),
|
||||
new XAttribute("generationparams", GenerationParams.Identifier));
|
||||
|
||||
if (Type == LevelType.Outpost && EventHistory.Any())
|
||||
{
|
||||
newElement.Add(new XAttribute("eventhistory", string.Join(',', EventHistory.Select(p => p.Identifier))));
|
||||
}
|
||||
|
||||
parentElement.Add(newElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,8 @@ namespace Barotrauma
|
||||
public readonly string DisplayName;
|
||||
public readonly string Description;
|
||||
|
||||
public readonly bool IsEndBiome;
|
||||
|
||||
public readonly List<int> AllowedZones = new List<int>();
|
||||
|
||||
public Biome(string name, string description)
|
||||
@@ -40,37 +42,25 @@ namespace Barotrauma
|
||||
element.GetAttributeString("description", "") ??
|
||||
TextManager.Get("biomedescription." + Identifier);
|
||||
|
||||
string allowedZonesStr = element.GetAttributeString("AllowedZones", "1,2,3,4,5,6,7,8,9");
|
||||
string[] zoneIndices = allowedZonesStr.Split(',');
|
||||
for (int i = 0; i < zoneIndices.Length; i++)
|
||||
{
|
||||
int zoneIndex = -1;
|
||||
if (!int.TryParse(zoneIndices[i].Trim(), out zoneIndex))
|
||||
{
|
||||
DebugConsole.ThrowError("Error in biome config \"" + Identifier + "\" - \"" + zoneIndices[i] + "\" is not a valid zone index.");
|
||||
continue;
|
||||
}
|
||||
AllowedZones.Add(zoneIndex);
|
||||
}
|
||||
IsEndBiome = element.GetAttributeBool("endbiome", false);
|
||||
|
||||
AllowedZones.AddRange(element.GetAttributeIntArray("AllowedZones", new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }));
|
||||
}
|
||||
}
|
||||
|
||||
class LevelGenerationParams : ISerializableEntity
|
||||
{
|
||||
public static List<LevelGenerationParams> LevelParams
|
||||
{
|
||||
get { return levelParams; }
|
||||
}
|
||||
public static List<LevelGenerationParams> LevelParams { get; private set; }
|
||||
|
||||
private static List<LevelGenerationParams> levelParams;
|
||||
private static List<Biome> biomes;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
get { return Identifier; }
|
||||
}
|
||||
|
||||
public readonly string Identifier;
|
||||
|
||||
private int minWidth, maxWidth, height;
|
||||
|
||||
private Point voronoiSiteInterval;
|
||||
@@ -107,7 +97,7 @@ namespace Barotrauma
|
||||
private float waterParticleScale;
|
||||
|
||||
//which biomes can this type of level appear in
|
||||
private List<Biome> allowedBiomes = new List<Biome>();
|
||||
private readonly List<Biome> allowedBiomes = new List<Biome>();
|
||||
|
||||
public IEnumerable<Biome> AllowedBiomes
|
||||
{
|
||||
@@ -120,6 +110,13 @@ namespace Barotrauma
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(LevelData.LevelType.LocationConnection, true), Editable]
|
||||
public LevelData.LevelType Type
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize("27,30,36", true), Editable]
|
||||
public Color AmbientLightColor
|
||||
{
|
||||
@@ -148,6 +145,39 @@ namespace Barotrauma
|
||||
set;
|
||||
}
|
||||
|
||||
private Vector2 startPosition;
|
||||
[Serialize("0,0", true, "Start position of the level (relative to the size of the level. 0,0 = top left corner, 1,1 = bottom right corner)"), Editable]
|
||||
public Vector2 StartPosition
|
||||
{
|
||||
get { return startPosition; }
|
||||
set
|
||||
{
|
||||
startPosition = new Vector2(
|
||||
MathHelper.Clamp(value.X, 0.0f, 1.0f),
|
||||
MathHelper.Clamp(value.Y, 0.0f, 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2 endPosition;
|
||||
[Serialize("1,0", true, "End position of the level (relative to the size of the level. 0,0 = top left corner, 1,1 = bottom right corner)"), Editable]
|
||||
public Vector2 EndPosition
|
||||
{
|
||||
get { return endPosition; }
|
||||
set
|
||||
{
|
||||
endPosition = new Vector2(
|
||||
MathHelper.Clamp(value.X, 0.0f, 1.0f),
|
||||
MathHelper.Clamp(value.Y, 0.0f, 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(true, true, "Should there be a hole in the wall next to the end outpost (can be used to prevent players from having to backtrack if they approach the outpost from the wrong side of the main path's walls)."), Editable]
|
||||
public bool CreateHoleNextToEnd
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(1000, true, description: "The total number of level objects (vegetation, vents, etc) in the level."), Editable(MinValueInt = 0, MaxValueInt = 100000)]
|
||||
public int LevelObjectAmount
|
||||
{
|
||||
@@ -176,6 +206,13 @@ namespace Barotrauma
|
||||
set { height = Math.Max(value, 2000); }
|
||||
}
|
||||
|
||||
[Serialize(6500, true), Editable(MinValueInt = 5000, MaxValueInt = 1000000)]
|
||||
public int MinTunnelRadius
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize("3000, 3000", true, description: "How far from each other voronoi sites are placed. " +
|
||||
"Sites determine shape of the voronoi graph which the level walls are generated from. " +
|
||||
"(Decreasing this value causes the number of sites, and the complexity of the level, to increase exponentially - be careful when adjusting)")]
|
||||
@@ -386,31 +423,43 @@ namespace Barotrauma
|
||||
public Sprite WallEdgeSpriteSpecular { get; private set; }
|
||||
public Sprite WaterParticles { get; private set; }
|
||||
|
||||
public static List<Biome> GetBiomes()
|
||||
public static IEnumerable<Biome> GetBiomes()
|
||||
{
|
||||
return biomes;
|
||||
}
|
||||
|
||||
public static LevelGenerationParams GetRandom(string seed, Biome biome = null)
|
||||
public static LevelGenerationParams GetRandom(string seed, LevelData.LevelType type, Biome biome = null)
|
||||
{
|
||||
Rand.SetSyncedSeed(ToolBox.StringToInt(seed));
|
||||
|
||||
if (levelParams == null || !levelParams.Any())
|
||||
if (LevelParams == null || !LevelParams.Any())
|
||||
{
|
||||
DebugConsole.ThrowError("Level generation presets not found - using default presets");
|
||||
return new LevelGenerationParams(null);
|
||||
}
|
||||
|
||||
var matchingLevelParams = LevelParams.FindAll(lp => lp.Type == type && lp.allowedBiomes.Any());
|
||||
if (biome == null)
|
||||
{
|
||||
return levelParams.GetRandom(lp => lp.allowedBiomes.Count > 0, Rand.RandSync.Server);
|
||||
matchingLevelParams = matchingLevelParams.FindAll(lp => !lp.allowedBiomes.Any(b => b.IsEndBiome));
|
||||
}
|
||||
else
|
||||
{
|
||||
matchingLevelParams = matchingLevelParams.FindAll(lp => lp.allowedBiomes.Contains(biome));
|
||||
}
|
||||
|
||||
var matchingLevelParams = levelParams.FindAll(lp => lp.allowedBiomes.Contains(biome));
|
||||
if (matchingLevelParams.Count == 0)
|
||||
{
|
||||
DebugConsole.ThrowError("Level generation presets not found for the biome \"" + biome.Identifier + "\"!");
|
||||
return new LevelGenerationParams(null);
|
||||
DebugConsole.ThrowError($"Suitable level generation presets not found (biome \"{(biome?.Identifier ?? "null")}\", type: \"{type}\"!");
|
||||
if (biome != null)
|
||||
{
|
||||
//try to find params that at least have a suitable type
|
||||
matchingLevelParams = LevelParams.FindAll(lp => lp.Type == type);
|
||||
if (matchingLevelParams.Count == 0)
|
||||
{
|
||||
//still not found, give up and choose some params randomly
|
||||
matchingLevelParams = LevelParams;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matchingLevelParams[Rand.Range(0, matchingLevelParams.Count, Rand.RandSync.Server)];
|
||||
@@ -418,11 +467,14 @@ namespace Barotrauma
|
||||
|
||||
private LevelGenerationParams(XElement element)
|
||||
{
|
||||
Name = element == null ? "default" : element.Name.ToString();
|
||||
Identifier = element == null ? "default" :
|
||||
element.GetAttributeString("identifier", null) ?? element.Name.ToString();
|
||||
SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
|
||||
|
||||
if (element == null) { return; }
|
||||
|
||||
string biomeStr = element.GetAttributeString("biomes", "");
|
||||
if (string.IsNullOrWhiteSpace(biomeStr))
|
||||
if (string.IsNullOrWhiteSpace(biomeStr) || biomeStr.Equals("any", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
allowedBiomes = new List<Biome>(biomes);
|
||||
}
|
||||
@@ -445,7 +497,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.NewMessage("Please use biome identifiers instead of names in level generation parameter \"" + Name + "\".", Color.Orange);
|
||||
DebugConsole.NewMessage("Please use biome identifiers instead of names in level generation parameter \"" + Identifier + "\".", Color.Orange);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -484,7 +536,7 @@ namespace Barotrauma
|
||||
|
||||
public static void LoadPresets()
|
||||
{
|
||||
levelParams = new List<LevelGenerationParams>();
|
||||
LevelParams = new List<LevelGenerationParams>();
|
||||
biomes = new List<Biome>();
|
||||
|
||||
var files = GameMain.Instance.GetFilesOfType(ContentType.LevelGenerationParameters);
|
||||
@@ -549,7 +601,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (XElement levelParamElement in levelParamElements)
|
||||
{
|
||||
levelParams.Add(new LevelGenerationParams(levelParamElement));
|
||||
LevelParams.Add(new LevelGenerationParams(levelParamElement));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class LevelObject
|
||||
partial class LevelObject : ISpatialEntity
|
||||
{
|
||||
public readonly LevelObjectPrefab Prefab;
|
||||
public Vector3 Position;
|
||||
@@ -50,6 +50,14 @@ namespace Barotrauma
|
||||
get { return spriteIndex < 0 || Prefab.SpecularSprites.Count == 0 ? null : Prefab.SpecularSprites[spriteIndex % Prefab.SpecularSprites.Count]; }
|
||||
}
|
||||
|
||||
Vector2 ISpatialEntity.Position => new Vector2(Position.X, Position.Y);
|
||||
|
||||
public Vector2 WorldPosition => new Vector2(Position.X, Position.Y);
|
||||
|
||||
public Vector2 SimPosition => ConvertUnits.ToSimUnits(WorldPosition);
|
||||
|
||||
public Submarine Submarine => null;
|
||||
|
||||
public LevelObject(LevelObjectPrefab prefab, Vector3 position, float scale, float rotation = 0.0f)
|
||||
{
|
||||
Triggers = new List<LevelTrigger>();
|
||||
|
||||
+45
-25
@@ -31,6 +31,8 @@ namespace Barotrauma
|
||||
public readonly Alignment Alignment;
|
||||
public readonly float Length;
|
||||
|
||||
private readonly float noiseVal;
|
||||
|
||||
public SpawnPosition(GraphEdge graphEdge, Vector2 normal, LevelObjectPrefab.SpawnPosType spawnPosType, Alignment alignment)
|
||||
{
|
||||
GraphEdge = graphEdge;
|
||||
@@ -39,16 +41,16 @@ namespace Barotrauma
|
||||
Alignment = alignment;
|
||||
|
||||
Length = Vector2.Distance(graphEdge.Point1, graphEdge.Point2);
|
||||
|
||||
noiseVal =
|
||||
(float)(PerlinNoise.CalculatePerlin(GraphEdge.Point1.X / 10000.0f, GraphEdge.Point1.Y / 10000.0f, 0.5f) +
|
||||
PerlinNoise.CalculatePerlin(GraphEdge.Point1.X / 20000.0f, GraphEdge.Point1.Y / 20000.0f, 0.5f));
|
||||
}
|
||||
|
||||
public float GetSpawnProbability(LevelObjectPrefab prefab)
|
||||
{
|
||||
if (prefab.ClusteringAmount <= 0.0f) return Length;
|
||||
|
||||
float noise = (float)(
|
||||
PerlinNoise.CalculatePerlin(GraphEdge.Point1.X / 10000.0f, GraphEdge.Point1.Y / 10000.0f, prefab.ClusteringGroup) +
|
||||
PerlinNoise.CalculatePerlin(GraphEdge.Point1.X / 20000.0f, GraphEdge.Point1.Y / 20000.0f, prefab.ClusteringGroup));
|
||||
|
||||
if (prefab.ClusteringAmount <= 0.0f) { return Length; }
|
||||
float noise = (noiseVal + PerlinNoise.GetPerlin(prefab.ClusteringGroup, prefab.ClusteringGroup * 0.3f)) % 1.0f;
|
||||
return Length * (float)Math.Pow(noise, prefab.ClusteringAmount);
|
||||
}
|
||||
}
|
||||
@@ -90,15 +92,33 @@ namespace Barotrauma
|
||||
Alignment.Top));
|
||||
}
|
||||
|
||||
availableSpawnPositions.Add(new SpawnPosition(
|
||||
new GraphEdge(level.StartPosition - Vector2.UnitX, level.StartPosition + Vector2.UnitX),
|
||||
-Vector2.UnitY, LevelObjectPrefab.SpawnPosType.LevelStart, Alignment.Top));
|
||||
availableSpawnPositions.Add(new SpawnPosition(
|
||||
new GraphEdge(level.EndPosition - Vector2.UnitX, level.EndPosition + Vector2.UnitX),
|
||||
-Vector2.UnitY, LevelObjectPrefab.SpawnPosType.LevelEnd, Alignment.Top));
|
||||
|
||||
var availablePrefabs = new List<LevelObjectPrefab>(LevelObjectPrefab.List);
|
||||
objects = new List<LevelObject>();
|
||||
|
||||
Dictionary<LevelObjectPrefab, List<SpawnPosition>> suitableSpawnPositions = new Dictionary<LevelObjectPrefab, List<SpawnPosition>>();
|
||||
Dictionary<LevelObjectPrefab, List<float>> spawnPositionWeights = new Dictionary<LevelObjectPrefab, List<float>>();
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
//get a random prefab and find a place to spawn it
|
||||
LevelObjectPrefab prefab = GetRandomPrefab(level.GenerationParams.Name);
|
||||
|
||||
SpawnPosition spawnPosition = FindObjectPosition(availableSpawnPositions, level, prefab);
|
||||
LevelObjectPrefab prefab = GetRandomPrefab(level.GenerationParams.Identifier, availablePrefabs);
|
||||
if (prefab == null) { continue; }
|
||||
if (!suitableSpawnPositions.ContainsKey(prefab))
|
||||
{
|
||||
suitableSpawnPositions.Add(prefab, availableSpawnPositions.Where(sp =>
|
||||
prefab.SpawnPos.HasFlag(sp.SpawnPosType) && (sp.Length >= prefab.MinSurfaceWidth && prefab.Alignment.HasFlag(sp.Alignment) || sp.SpawnPosType == LevelObjectPrefab.SpawnPosType.LevelEnd || sp.SpawnPosType == LevelObjectPrefab.SpawnPosType.LevelStart)).ToList());
|
||||
spawnPositionWeights.Add(prefab,
|
||||
suitableSpawnPositions[prefab].Select(sp => sp.GetSpawnProbability(prefab)).ToList());
|
||||
}
|
||||
|
||||
if (spawnPosition == null && prefab.SpawnPos != LevelObjectPrefab.SpawnPosType.None) continue;
|
||||
SpawnPosition spawnPosition = ToolBox.SelectWeightedRandom(suitableSpawnPositions[prefab], spawnPositionWeights[prefab], Rand.RandSync.Server);
|
||||
if (spawnPosition == null && prefab.SpawnPos != LevelObjectPrefab.SpawnPosType.None) { continue; }
|
||||
|
||||
float rotation = 0.0f;
|
||||
if (prefab.AlignWithSurface && spawnPosition != null)
|
||||
@@ -124,6 +144,13 @@ namespace Barotrauma
|
||||
var newObject = new LevelObject(prefab,
|
||||
new Vector3(position, Rand.Range(prefab.DepthRange.X, prefab.DepthRange.Y, Rand.RandSync.Server)), Rand.Range(prefab.MinSize, prefab.MaxSize, Rand.RandSync.Server), rotation);
|
||||
AddObject(newObject, level);
|
||||
if (prefab.MaxCount < amount)
|
||||
{
|
||||
if (objects.Count(o => o.Prefab == prefab) >= prefab.MaxCount)
|
||||
{
|
||||
availablePrefabs.Remove(prefab);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (LevelObjectPrefab.ChildObject child in prefab.ChildObjects)
|
||||
{
|
||||
@@ -145,9 +172,7 @@ namespace Barotrauma
|
||||
AddObject(childObject, level);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void AddObject(LevelObject newObject, Level level)
|
||||
@@ -321,16 +346,6 @@ namespace Barotrauma
|
||||
return availableSpawnPositions;
|
||||
}
|
||||
|
||||
private SpawnPosition FindObjectPosition(List<SpawnPosition> availableSpawnPositions, Level level, LevelObjectPrefab prefab)
|
||||
{
|
||||
if (prefab.SpawnPos == LevelObjectPrefab.SpawnPosType.None) return null;
|
||||
|
||||
var suitableSpawnPositions = availableSpawnPositions.Where(sp =>
|
||||
prefab.SpawnPos.HasFlag(sp.SpawnPosType) && sp.Length >= prefab.MinSurfaceWidth && prefab.Alignment.HasFlag(sp.Alignment)).ToList();
|
||||
|
||||
return ToolBox.SelectWeightedRandom(suitableSpawnPositions, suitableSpawnPositions.Select(sp => sp.GetSpawnProbability(prefab)).ToList(), Rand.RandSync.Server);
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
foreach (LevelObject obj in objects)
|
||||
@@ -383,10 +398,15 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
private LevelObjectPrefab GetRandomPrefab(string levelType)
|
||||
{
|
||||
return GetRandomPrefab(levelType, LevelObjectPrefab.List);
|
||||
}
|
||||
|
||||
private LevelObjectPrefab GetRandomPrefab(string levelType, IList<LevelObjectPrefab> availablePrefabs)
|
||||
{
|
||||
return ToolBox.SelectWeightedRandom(
|
||||
LevelObjectPrefab.List,
|
||||
LevelObjectPrefab.List.Select(p => p.GetCommonness(levelType)).ToList(), Rand.RandSync.Server);
|
||||
availablePrefabs,
|
||||
availablePrefabs.Select(p => p.GetCommonness(levelType)).ToList(), Rand.RandSync.Server);
|
||||
}
|
||||
|
||||
public override void Remove()
|
||||
|
||||
+11
-1
@@ -41,7 +41,9 @@ namespace Barotrauma
|
||||
Wall = 1,
|
||||
RuinWall = 2,
|
||||
SeaFloor = 4,
|
||||
MainPath = 8
|
||||
MainPath = 8,
|
||||
LevelStart = 16,
|
||||
LevelEnd = 32,
|
||||
}
|
||||
|
||||
public List<Sprite> Sprites
|
||||
@@ -117,6 +119,14 @@ namespace Barotrauma
|
||||
private set;
|
||||
}
|
||||
|
||||
|
||||
[Serialize(10000, false, description: "Maximum number of this specific object per level."), Editable(MinValueFloat = 0.01f, MaxValueFloat = 10.0f)]
|
||||
public int MaxCount
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize("0.0,1.0", true), Editable]
|
||||
public Vector2 DepthRange
|
||||
{
|
||||
|
||||
@@ -152,11 +152,11 @@ namespace Barotrauma.RuinGeneration
|
||||
{
|
||||
mainElement = doc.Root.FirstElement();
|
||||
paramsList.Clear();
|
||||
DebugConsole.NewMessage($"Overriding all ruin configuration parameters using the file {configFile.Path}.", Color.Yellow);
|
||||
DebugConsole.NewMessage($"Overriding all ruin generation parameters using the file {configFile.Path}.", Color.Yellow);
|
||||
}
|
||||
else if (paramsList.Any())
|
||||
{
|
||||
DebugConsole.NewMessage($"Adding additional ruin configuration parameters from file '{configFile.Path}'");
|
||||
DebugConsole.NewMessage($"Adding additional ruin generation parameters from file '{configFile.Path}'");
|
||||
}
|
||||
var newParams = new RuinGenerationParams(mainElement)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user