Build 0.18.0.0

This commit is contained in:
Markus Isberg
2022-05-13 00:55:52 +09:00
parent 15d18e6ff6
commit 7547a9b78a
218 changed files with 3881 additions and 2192 deletions
@@ -157,9 +157,6 @@ namespace Barotrauma
public static List<VoronoiCell> GeneratePath(List<VoronoiCell> targetCells, List<VoronoiCell> cells)
{
Stopwatch sw2 = new Stopwatch();
sw2.Start();
List<VoronoiCell> pathCells = new List<VoronoiCell>();
if (targetCells.Count == 0) { return pathCells; }
@@ -213,10 +210,6 @@ namespace Barotrauma
} while (currentCell != targetCells[targetCells.Count - 1] && iterationsLeft > 0);
Debug.WriteLine("gettooclose: " + sw2.ElapsedMilliseconds + " ms");
sw2.Restart();
return pathCells;
}
@@ -351,7 +344,7 @@ namespace Barotrauma
BodyType = BodyType.Static,
CollisionCategories = Physics.CollisionLevel
};
GameMain.World.Add(cellBody);
GameMain.World.Add(cellBody, findNewContacts: false);
for (int n = cells.Count - 1; n >= 0; n-- )
{
@@ -429,7 +422,9 @@ namespace Barotrauma
Vertices bodyVertices = new Vertices(triangles[i]);
PolygonShape polygon = new PolygonShape(bodyVertices, 5.0f);
Fixture fixture = new Fixture(polygon)
Fixture fixture = new Fixture(polygon,
Physics.CollisionLevel,
Physics.CollisionAll)
{
UserData = cell
};
@@ -446,8 +441,6 @@ namespace Barotrauma
}
cell.Body = cellBody;
}
cellBody.CollisionCategories = Physics.CollisionLevel;
cellBody.ResetMassData();
return cellBody;
@@ -299,11 +299,41 @@ namespace Barotrauma
/// Random integers generated during the level generation. If these values differ between clients/server,
/// it means the levels aren't identical for some reason and there will most likely be major ID mismatches.
/// </summary>
public List<int> EqualityCheckValues
public enum LevelGenStage
{
get;
private set;
} = new List<int>();
GenStart,
TunnelGen,
VoronoiGen,
VoronoiGen2,
VoronoiGen3,
Ruins,
FloatingIce,
LevelBodies,
IceSpires,
TopAndBottom,
PlaceLevelObjects,
GenerateItems,
Finish
}
private readonly Dictionary<LevelGenStage, int> equalityCheckValues = Enum.GetValues(typeof(LevelGenStage))
.Cast<LevelGenStage>()
.Select(k => (k, 0))
.ToDictionary();
public IReadOnlyDictionary<LevelGenStage, int> EqualityCheckValues => equalityCheckValues;
private void GenerateEqualityCheckValue(LevelGenStage stage)
{
equalityCheckValues[stage] = Rand.Int(int.MaxValue, Rand.RandSync.ServerAndClient);
}
private void ClearEqualityCheckValues()
{
foreach (LevelGenStage stage in Enum.GetValues(typeof(LevelGenStage)))
{
equalityCheckValues[stage] = 0;
}
}
public List<Entity> EntitiesBeforeGenerate { get; private set; } = new List<Entity>();
public int EntityCountBeforeGenerate { get; private set; }
@@ -404,7 +434,7 @@ namespace Barotrauma
Loaded = this;
Generating = true;
EqualityCheckValues.Clear();
ClearEqualityCheckValues();
EntitiesBeforeGenerate = GetEntities().ToList();
EntityCountBeforeGenerate = EntitiesBeforeGenerate.Count();
@@ -414,7 +444,7 @@ namespace Barotrauma
EndLocation = GameMain.GameSession?.EndLocation;
}
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.ServerAndClient));
GenerateEqualityCheckValue(LevelGenStage.GenStart);
LevelObjectManager = new LevelObjectManager();
@@ -477,7 +507,7 @@ namespace Barotrauma
(int)MathHelper.Lerp(borders.Bottom - Math.Max(minMainPathWidth, ExitDistance * 1.5f), borders.Y + minMainPathWidth, GenerationParams.EndPosition.Y));
endExitPosition = new Point(endPosition.X, borders.Bottom);
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.ServerAndClient));
GenerateEqualityCheckValue(LevelGenStage.TunnelGen);
//----------------------------------------------------------------------------------
//generate the initial nodes for the main path and smaller tunnels
@@ -573,7 +603,7 @@ namespace Barotrauma
GenerateAbyssArea();
GenerateCaves(mainPath);
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.ServerAndClient));
GenerateEqualityCheckValue(LevelGenStage.VoronoiGen);
//----------------------------------------------------------------------------------
//generate voronoi sites
@@ -678,7 +708,7 @@ namespace Barotrauma
}
}
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.ServerAndClient));
GenerateEqualityCheckValue(LevelGenStage.VoronoiGen2);
//----------------------------------------------------------------------------------
// construct the voronoi graph and cells
@@ -796,7 +826,7 @@ namespace Barotrauma
startPosition.X = (int)pathCells[0].Site.Coord.X;
startExitPosition.X = startPosition.X;
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.ServerAndClient));
GenerateEqualityCheckValue(LevelGenStage.VoronoiGen3);
//----------------------------------------------------------------------------------
// remove unnecessary cells and create some holes at the bottom of the level
@@ -1025,7 +1055,7 @@ namespace Barotrauma
}
}
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.ServerAndClient));
GenerateEqualityCheckValue(LevelGenStage.Ruins);
//----------------------------------------------------------------------------------
// create some ruins
@@ -1038,7 +1068,7 @@ namespace Barotrauma
GenerateRuin(ruinPositions[i], mirror);
}
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.ServerAndClient));
GenerateEqualityCheckValue(LevelGenStage.FloatingIce);
//----------------------------------------------------------------------------------
// create floating ice chunks
@@ -1070,7 +1100,7 @@ namespace Barotrauma
}
}
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.ServerAndClient));
GenerateEqualityCheckValue(LevelGenStage.LevelBodies);
//----------------------------------------------------------------------------------
// generate the bodies and rendered triangles of the cells
@@ -1175,7 +1205,7 @@ namespace Barotrauma
}
#endif
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.ServerAndClient));
GenerateEqualityCheckValue(LevelGenStage.IceSpires);
//----------------------------------------------------------------------------------
// create ice spires
@@ -1210,7 +1240,7 @@ namespace Barotrauma
CreateOutposts();
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.ServerAndClient));
GenerateEqualityCheckValue(LevelGenStage.TopAndBottom);
//----------------------------------------------------------------------------------
// top barrier & sea floor
@@ -1252,15 +1282,15 @@ namespace Barotrauma
CreateWrecks();
CreateBeaconStation();
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.ServerAndClient));
GenerateEqualityCheckValue(LevelGenStage.PlaceLevelObjects);
LevelObjectManager.PlaceObjects(this, GenerationParams.LevelObjectAmount);
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.ServerAndClient));
GenerateEqualityCheckValue(LevelGenStage.GenerateItems);
GenerateItems();
EqualityCheckValues.Add(Rand.Int(int.MaxValue, Rand.RandSync.ServerAndClient));
GenerateEqualityCheckValue(LevelGenStage.Finish);
#if CLIENT
backgroundCreatureManager.SpawnCreatures(this, GenerationParams.BackgroundCreatureAmount);
@@ -2606,7 +2636,7 @@ namespace Barotrauma
#if DEBUG
DebugConsole.NewMessage("Level resources spawned: " + itemCount + "\n" +
" Spawn points containing resources: " + PathPoints.Where(p => p.ClusterLocations.Any()).Count() + "/" + PathPoints.Count + "\n" +
" Total value: "+ PathPoints.Sum(p => p.ClusterLocations.Sum(c => c.Resources.Sum(r => r.Prefab.DefaultPrice?.Price ?? 0)))+" mk");
" Total value: " + PathPoints.Sum(p => p.ClusterLocations.Sum(c => c.Resources.Sum(r => r.Prefab.DefaultPrice?.Price ?? 0))) + " mk");
if (AbyssResources.Count > 0)
{
@@ -3688,6 +3718,7 @@ namespace Barotrauma
if (wreckFiles.None())
{
DebugConsole.ThrowError("No wreck files found in the selected content packages!");
Wrecks = new List<Submarine>();
return;
}
wreckFiles.Shuffle(Rand.RandSync.ServerAndClient);
@@ -4112,12 +4143,12 @@ namespace Barotrauma
int corpseCount = Rand.Range(Loaded.GenerationParams.MinCorpseCount, Loaded.GenerationParams.MaxCorpseCount + 1);
var allSpawnPoints = WayPoint.WayPointList.FindAll(wp => wp.Submarine == wreck && wp.CurrentHull != null);
var pathPoints = allSpawnPoints.FindAll(wp => wp.SpawnType == SpawnType.Path);
pathPoints.Shuffle(Rand.RandSync.Unsynced);
var corpsePoints = allSpawnPoints.FindAll(wp => wp.SpawnType == SpawnType.Corpse);
corpsePoints.Shuffle(Rand.RandSync.Unsynced);
if (!corpsePoints.Any() && !pathPoints.Any()) { continue; }
pathPoints.Shuffle(Rand.RandSync.Unsynced);
// Sort by job so that we first spawn those with a predefined job (might have special id cards)
corpsePoints = corpsePoints.OrderBy(p => p.AssignedJob == null).ThenBy(p => Rand.Value()).ToList();
var usedJobs = new HashSet<JobPrefab>();
int spawnCounter = 0;
for (int j = 0; j < corpseCount; j++)
{
@@ -4126,18 +4157,18 @@ namespace Barotrauma
CorpsePrefab selectedPrefab;
if (job == null)
{
selectedPrefab = GetCorpsePrefab(p => p.SpawnPosition == PositionType.Wreck);
selectedPrefab = GetCorpsePrefab(usedJobs);
}
else
{
selectedPrefab = GetCorpsePrefab(p => p.SpawnPosition == PositionType.Wreck && (p.Job == "any" || p.Job == job.Identifier));
selectedPrefab = GetCorpsePrefab(usedJobs, p => p.Job == "any" || p.Job == job.Identifier);
if (selectedPrefab == null)
{
corpsePoints.Remove(sp);
pathPoints.Remove(sp);
sp = corpsePoints.FirstOrDefault(sp => sp.AssignedJob == null) ?? pathPoints.FirstOrDefault(sp => sp.AssignedJob == null);
// Deduce the job from the selected prefab
selectedPrefab = GetCorpsePrefab(p => p.SpawnPosition == PositionType.Wreck);
selectedPrefab = GetCorpsePrefab(usedJobs);
}
}
if (selectedPrefab == null) { continue; }
@@ -4156,28 +4187,65 @@ namespace Barotrauma
pathPoints.Remove(sp);
}
job ??= selectedPrefab.GetJobPrefab();
job ??= selectedPrefab.GetJobPrefab(predicate: p => !usedJobs.Contains(p));
if (job == null) { continue; }
if (job.Identifier == "captain" || job.Identifier == "engineer" || job.Identifier == "medicaldoctor" || job.Identifier == "securityofficer")
{
// Only spawn one of these jobs per wreck
usedJobs.Add(job);
}
var characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: job, randSync: Rand.RandSync.ServerAndClient);
var corpse = Character.Create(CharacterPrefab.HumanSpeciesName, worldPos, ToolBox.RandomSeed(8), characterInfo, hasAi: true, createNetworkEvent: true);
corpse.AnimController.FindHull(worldPos, setSubmarine: true);
corpse.TeamID = CharacterTeamType.None;
corpse.EnableDespawn = false;
selectedPrefab.GiveItems(corpse, wreck);
corpse.CharacterHealth.ApplyAffliction(corpse.AnimController.MainLimb, AfflictionPrefab.OxygenLow.Instantiate(200));
bool applyBurns = Rand.Value() < 0.1f;
bool applyDamage = Rand.Value() < 0.3f;
foreach (var limb in corpse.AnimController.Limbs)
{
if (applyDamage && (limb.type == LimbType.Head || Rand.Value() < 0.5f))
{
var prefab = AfflictionPrefab.BiteWounds;
float max = prefab.MaxStrength / prefab.DamageOverlayAlpha;
corpse.CharacterHealth.ApplyAffliction(limb, prefab.Instantiate(GetStrength(limb, max)));
}
if (applyBurns)
{
var prefab = AfflictionPrefab.Burn;
float max = prefab.MaxStrength / prefab.BurnOverlayAlpha;
corpse.CharacterHealth.ApplyAffliction(limb, prefab.Instantiate(GetStrength(limb, max)));
}
static float GetStrength(Limb limb, float max)
{
float strength = Rand.Range(0, max);
if (limb.type != LimbType.Head)
{
strength = Math.Min(strength, Rand.Range(0, max));
}
return strength;
}
}
corpse.Kill(CauseOfDeathType.Unknown, causeOfDeathAffliction: null, log: false);
corpse.GiveIdCardTags(sp);
#if SERVER
if (selectedPrefab.MinMoney >= 0 && selectedPrefab.MaxMoney > 0)
bool isServerOrSingleplayer = GameMain.IsSingleplayer || GameMain.NetworkMember is { IsServer: true };
if (isServerOrSingleplayer && selectedPrefab.MinMoney >= 0 && selectedPrefab.MaxMoney > 0)
{
corpse.Wallet.Give(Rand.Range(selectedPrefab.MinMoney, selectedPrefab.MaxMoney, Rand.RandSync.Unsynced));
}
#endif
spawnCounter++;
static CorpsePrefab GetCorpsePrefab(Func<CorpsePrefab, bool> predicate)
static CorpsePrefab GetCorpsePrefab(HashSet<JobPrefab> usedJobs, Func<CorpsePrefab, bool> predicate = null)
{
IEnumerable<CorpsePrefab> filteredPrefabs = CorpsePrefab.Prefabs.Where(predicate);
IEnumerable<CorpsePrefab> filteredPrefabs = CorpsePrefab.Prefabs.Where(p =>
usedJobs.None(j => j.Identifier == p.Job.ToIdentifier()) &&
p.SpawnPosition == PositionType.Wreck &&
(predicate == null || predicate(p)));
return ToolBox.SelectWeightedRandom(filteredPrefabs.ToList(), filteredPrefabs.Select(p => p.Commonness).ToList(), Rand.RandSync.Unsynced);
}
}
@@ -4270,7 +4338,7 @@ namespace Barotrauma
blockedRects?.Clear();
EntitiesBeforeGenerate?.Clear();
EqualityCheckValues?.Clear();
ClearEqualityCheckValues();
if (Ruins != null)
{
@@ -20,7 +20,7 @@ namespace Barotrauma
public readonly string Seed;
public float Difficulty;
public readonly float Difficulty;
public readonly Biome Biome;
@@ -141,8 +141,8 @@ namespace Barotrauma
Seed = locationConnection.Locations[0].BaseName + locationConnection.Locations[1].BaseName;
Biome = locationConnection.Biome;
Type = LevelType.LocationConnection;
GenerationParams = LevelGenerationParams.GetRandom(Seed, LevelType.LocationConnection, Biome.Identifier);
Difficulty = locationConnection.Difficulty;
GenerationParams = LevelGenerationParams.GetRandom(Seed, LevelType.LocationConnection, Difficulty, Biome.Identifier);
float sizeFactor = MathUtils.InverseLerp(
MapGenerationParams.Instance.SmallLevelConnectionLength,
@@ -171,13 +171,13 @@ namespace Barotrauma
/// <summary>
/// Instantiates level data using the properties of the location
/// </summary>
public LevelData(Location location)
public LevelData(Location location, float difficulty)
{
Seed = location.BaseName;
Biome = location.Biome;
Type = LevelType.Outpost;
GenerationParams = LevelGenerationParams.GetRandom(Seed, LevelType.Outpost, Biome.Identifier);
Difficulty = 0.0f;
Difficulty = difficulty;
GenerationParams = LevelGenerationParams.GetRandom(Seed, LevelType.Outpost, Difficulty, Biome.Identifier);
var rand = new MTRandom(ToolBox.StringToInt(Seed));
int width = (int)MathHelper.Lerp(GenerationParams.MinWidth, GenerationParams.MaxWidth, (float)rand.NextDouble());
@@ -200,14 +200,16 @@ namespace Barotrauma
(requireOutpost ? LevelType.Outpost : LevelType.LocationConnection) :
generationParams.Type;
if (generationParams == null) { generationParams = LevelGenerationParams.GetRandom(seed, type); }
float selectedDifficulty = difficulty ?? Rand.Range(30.0f, 80.0f, Rand.RandSync.ServerAndClient);
if (generationParams == null) { generationParams = LevelGenerationParams.GetRandom(seed, type, selectedDifficulty); }
var biome =
Biome.Prefabs.FirstOrDefault(b => generationParams?.AllowedBiomeIdentifiers.Contains(b.Identifier) ?? false) ??
Biome.Prefabs.GetRandom(Rand.RandSync.ServerAndClient);
var levelData = new LevelData(
seed,
difficulty ?? Rand.Range(30.0f, 80.0f, Rand.RandSync.ServerAndClient),
selectedDifficulty,
Rand.Range(0.0f, 1.0f, Rand.RandSync.ServerAndClient),
generationParams,
biome);
@@ -4,7 +4,6 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
{
@@ -68,6 +67,27 @@ namespace Barotrauma
set;
}
[Serialize(1.0f, IsPropertySaveable.Yes, "If there are multiple level generation parameters available for a level in a given biome, their commonness determines how likely it is for one to get selected."), Editable(MinValueFloat = 0, MaxValueFloat = 100)]
public float Commonness
{
get;
set;
}
[Serialize(0.0f, IsPropertySaveable.Yes, "The difficulty of the level has to be above or equal to this for these parameters to get chosen for the level."), Editable(MinValueFloat = 0, MaxValueFloat = 100)]
public float MinLevelDifficulty
{
get;
set;
}
[Serialize(100.0f, IsPropertySaveable.Yes, "The difficulty of the level has to be below or equal to this for these parameters to get chosen for the level."), Editable(MinValueFloat = 0, MaxValueFloat = 100)]
public float MaxLevelDifficulty
{
get;
set;
}
[Serialize("27,30,36", IsPropertySaveable.Yes), Editable]
public Color AmbientLightColor
{
@@ -536,7 +556,26 @@ namespace Barotrauma
public Sprite WallSpriteDestroyed { get; private set; }
public Sprite WaterParticles { get; private set; }
public static LevelGenerationParams GetRandom(string seed, LevelData.LevelType type, Identifier biome = default)
#warning TODO: this should be in the unit test project (#3164)
public static void CheckValidity()
{
foreach (Biome biome in Biome.Prefabs)
{
for (float i = 0.0f; i <= 100.0f; i += 0.5f)
{
if (GetRandom("test", LevelData.LevelType.LocationConnection, i, biome.Identifier) == null)
{
DebugConsole.ThrowError($"No suitable level generation parameters found for a specific type of level (level type: LocationConnection, difficulty: {i}, biome: {biome.Identifier})");
}
if (GetRandom("test", LevelData.LevelType.Outpost, i, biome.Identifier) == null)
{
DebugConsole.ThrowError($"No suitable level generation parameters found for a specific type of level (level type: Outpost, difficulty: {i}, biome: {biome.Identifier})");
}
}
}
}
public static LevelGenerationParams GetRandom(string seed, LevelData.LevelType type, float difficulty, Identifier biome = default)
{
Rand.SetSyncedSeed(ToolBox.StringToInt(seed));
@@ -568,7 +607,16 @@ namespace Barotrauma
}
}
return matchingLevelParams.GetRandom(Rand.RandSync.ServerAndClient);
if (!matchingLevelParams.Any(lp => difficulty >= lp.MinLevelDifficulty && difficulty <= lp.MaxLevelDifficulty))
{
DebugConsole.ThrowError($"Suitable level generation presets not found (biome \"{biome.IfEmpty("null".ToIdentifier())}\", type: \"{type}\", difficulty: {difficulty})");
}
else
{
matchingLevelParams = matchingLevelParams.Where(lp => difficulty >= lp.MinLevelDifficulty && difficulty <= lp.MaxLevelDifficulty);
}
return ToolBox.SelectWeightedRandom(matchingLevelParams, p => p.Commonness, Rand.RandSync.ServerAndClient);
}
public LevelGenerationParams(ContentXElement element, LevelGenerationParametersFile file) : base(file, element.GetAttributeIdentifier("identifier", element.Name.LocalName))
@@ -102,32 +102,44 @@ namespace Barotrauma
foreach (Structure structure in Structure.WallList)
{
if (!structure.HasBody || structure.HiddenInGame) { continue; }
LevelObjectPrefab.SpawnPosType spawnPosType = LevelObjectPrefab.SpawnPosType.None;
if (level.Ruins.Any(r => r.Submarine == structure.Submarine))
{
if (structure.IsHorizontal)
{
bool topHull = Hull.FindHull(structure.WorldPosition + Vector2.UnitY * 64) != null;
bool bottomHull = Hull.FindHull(structure.WorldPosition - Vector2.UnitY * 64) != null;
if (topHull && bottomHull ) { continue; }
spawnPosType = LevelObjectPrefab.SpawnPosType.RuinWall;
}
else if (structure.Submarine?.Info?.Type == SubmarineType.Outpost)
{
spawnPosType = LevelObjectPrefab.SpawnPosType.OutpostWall;
}
else
{
continue;
}
availableSpawnPositions.Add(new SpawnPosition(
new GraphEdge(new Vector2(structure.WorldRect.X, structure.WorldPosition.Y), new Vector2(structure.WorldRect.Right, structure.WorldPosition.Y)),
bottomHull ? Vector2.UnitY : -Vector2.UnitY,
LevelObjectPrefab.SpawnPosType.RuinWall,
bottomHull ? Alignment.Bottom : Alignment.Top));
}
else
{
bool rightHull = Hull.FindHull(structure.WorldPosition + Vector2.UnitX * 64) != null;
bool leftHull = Hull.FindHull(structure.WorldPosition - Vector2.UnitX * 64) != null;
if (rightHull && leftHull) { continue; }
if (structure.IsHorizontal)
{
bool topHull = Hull.FindHull(structure.WorldPosition + Vector2.UnitY * 64) != null;
bool bottomHull = Hull.FindHull(structure.WorldPosition - Vector2.UnitY * 64) != null;
if (topHull && bottomHull) { continue; }
availableSpawnPositions.Add(new SpawnPosition(
new GraphEdge(new Vector2(structure.WorldPosition.X, structure.WorldRect.Y), new Vector2(structure.WorldPosition.X, structure.WorldRect.Y - structure.WorldRect.Height)),
leftHull ? Vector2.UnitX : -Vector2.UnitX,
LevelObjectPrefab.SpawnPosType.RuinWall,
leftHull ? Alignment.Left : Alignment.Right));
}
availableSpawnPositions.Add(new SpawnPosition(
new GraphEdge(new Vector2(structure.WorldRect.X, structure.WorldPosition.Y), new Vector2(structure.WorldRect.Right, structure.WorldPosition.Y)),
bottomHull ? Vector2.UnitY : -Vector2.UnitY,
spawnPosType,
bottomHull ? Alignment.Bottom : Alignment.Top));
}
else
{
bool rightHull = Hull.FindHull(structure.WorldPosition + Vector2.UnitX * 64) != null;
bool leftHull = Hull.FindHull(structure.WorldPosition - Vector2.UnitX * 64) != null;
if (rightHull && leftHull) { continue; }
availableSpawnPositions.Add(new SpawnPosition(
new GraphEdge(new Vector2(structure.WorldPosition.X, structure.WorldRect.Y), new Vector2(structure.WorldPosition.X, structure.WorldRect.Y - structure.WorldRect.Height)),
leftHull ? Vector2.UnitX : -Vector2.UnitX,
spawnPosType,
leftHull ? Alignment.Left : Alignment.Right));
}
}
@@ -44,6 +44,7 @@ namespace Barotrauma
MainPath = 64,
LevelStart = 128,
LevelEnd = 256,
OutpostWall = 512,
Wall = MainPathWall | SidePathWall | CaveWall,
}
@@ -6,7 +6,6 @@ using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
{