Unstable 1.1.14.0

This commit is contained in:
Markus Isberg
2023-10-02 16:43:54 +03:00
parent 94f5a93a0c
commit cf8f0de659
606 changed files with 21906 additions and 11456 deletions
@@ -167,7 +167,7 @@ namespace Barotrauma
public Point StartPos, EndPos;
public bool DisplayOnSonar;
public readonly HashSet<Mission> MissionsToDisplayOnSonar = new HashSet<Mission>();
public readonly CaveGenerationParams CaveGenerationParams;
@@ -334,13 +334,15 @@ namespace Barotrauma
LevelGenParams,
Size,
GenStart,
TunnelGen,
TunnelGen1,
TunnelGen2,
AbyssGen,
CaveGen,
VoronoiGen,
VoronoiGen2,
VoronoiGen3,
Ruins,
Outposts,
FloatingIce,
LevelBodies,
IceSpires,
@@ -512,7 +514,6 @@ namespace Barotrauma
GenerateEqualityCheckValue(LevelGenStage.GenStart);
SetEqualityCheckValue(LevelGenStage.LevelGenParams, unchecked((int)GenerationParams.UintIdentifier));
SetEqualityCheckValue(LevelGenStage.Size, borders.Width ^ borders.Height << 16);
GenerateEqualityCheckValue(LevelGenStage.TunnelGen);
LevelObjectManager = new LevelObjectManager();
@@ -574,7 +575,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);
GenerateEqualityCheckValue(LevelGenStage.TunnelGen);
GenerateEqualityCheckValue(LevelGenStage.TunnelGen1);
//----------------------------------------------------------------------------------
//generate the initial nodes for the main path and smaller tunnels
@@ -670,15 +671,15 @@ namespace Barotrauma
CalculateTunnelDistanceField(null);
GenerateSeaFloorPositions();
GenerateEqualityCheckValue(LevelGenStage.AbyssGen);
GenerateEqualityCheckValue(LevelGenStage.TunnelGen2);
GenerateAbyssArea();
GenerateEqualityCheckValue(LevelGenStage.CaveGen);
GenerateEqualityCheckValue(LevelGenStage.AbyssGen);
GenerateCaves(mainPath);
GenerateEqualityCheckValue(LevelGenStage.VoronoiGen);
GenerateEqualityCheckValue(LevelGenStage.CaveGen);
//----------------------------------------------------------------------------------
//generate voronoi sites
@@ -784,7 +785,7 @@ namespace Barotrauma
}
}
GenerateEqualityCheckValue(LevelGenStage.VoronoiGen2);
GenerateEqualityCheckValue(LevelGenStage.VoronoiGen);
//----------------------------------------------------------------------------------
// construct the voronoi graph and cells
@@ -895,7 +896,7 @@ namespace Barotrauma
startPosition.X = (int)pathCells[0].Site.Coord.X;
startExitPosition.X = startPosition.X;
GenerateEqualityCheckValue(LevelGenStage.VoronoiGen3);
GenerateEqualityCheckValue(LevelGenStage.VoronoiGen2);
//----------------------------------------------------------------------------------
// remove unnecessary cells and create some holes at the bottom of the level
@@ -933,8 +934,12 @@ namespace Barotrauma
}
List<Point> ruinPositions = new List<Point>();
int ruinCount = GenerationParams.RuinCount;
if (GameMain.GameSession?.GameMode?.Missions.Any(m => m.Prefab.RequireRuin) ?? false)
int ruinCount = GenerationParams.UseRandomRuinCount()
? Rand.Range(GenerationParams.MinRuinCount, GenerationParams.MaxRuinCount + 1, Rand.RandSync.ServerAndClient)
: GenerationParams.RuinCount;
bool hasRuinMissions = GameMain.GameSession?.GameMode?.Missions.Any(m => m.Prefab.RequireRuin) ?? false;
if (hasRuinMissions)
{
ruinCount = Math.Max(ruinCount, 1);
}
@@ -1131,7 +1136,7 @@ namespace Barotrauma
}
}
GenerateEqualityCheckValue(LevelGenStage.Ruins);
GenerateEqualityCheckValue(LevelGenStage.VoronoiGen3);
//----------------------------------------------------------------------------------
// create some ruins
@@ -1141,10 +1146,10 @@ namespace Barotrauma
for (int i = 0; i < ruinPositions.Count; i++)
{
Rand.SetSyncedSeed(ToolBox.StringToInt(Seed) + i);
GenerateRuin(ruinPositions[i], mirror);
GenerateRuin(ruinPositions[i], mirror, hasRuinMissions);
}
GenerateEqualityCheckValue(LevelGenStage.FloatingIce);
GenerateEqualityCheckValue(LevelGenStage.Ruins);
//----------------------------------------------------------------------------------
// create floating ice chunks
@@ -1176,7 +1181,7 @@ namespace Barotrauma
}
}
GenerateEqualityCheckValue(LevelGenStage.LevelBodies);
GenerateEqualityCheckValue(LevelGenStage.FloatingIce);
//----------------------------------------------------------------------------------
// generate the bodies and rendered triangles of the cells
@@ -1281,7 +1286,7 @@ namespace Barotrauma
}
#endif
GenerateEqualityCheckValue(LevelGenStage.IceSpires);
GenerateEqualityCheckValue(LevelGenStage.LevelBodies);
//----------------------------------------------------------------------------------
// create ice spires
@@ -1294,6 +1299,8 @@ namespace Barotrauma
if (spire != null) { ExtraWalls.Add(spire); };
}
GenerateEqualityCheckValue(LevelGenStage.IceSpires);
//----------------------------------------------------------------------------------
// connect side paths and cave branches to their parents
//----------------------------------------------------------------------------------
@@ -1316,7 +1323,7 @@ namespace Barotrauma
CreateOutposts();
GenerateEqualityCheckValue(LevelGenStage.TopAndBottom);
GenerateEqualityCheckValue(LevelGenStage.Outposts);
//----------------------------------------------------------------------------------
// top barrier & sea floor
@@ -1325,7 +1332,8 @@ namespace Barotrauma
TopBarrier = GameMain.World.CreateEdge(
ConvertUnits.ToSimUnits(new Vector2(borders.X, 0)),
ConvertUnits.ToSimUnits(new Vector2(borders.Right, 0)));
//for debugging purposes
TopBarrier.UserData = "topbarrier";
TopBarrier.SetTransform(ConvertUnits.ToSimUnits(new Vector2(0.0f, borders.Height)), 0.0f);
TopBarrier.BodyType = BodyType.Static;
TopBarrier.CollisionCategories = Physics.CollisionLevel;
@@ -1358,15 +1366,23 @@ namespace Barotrauma
CreateWrecks();
CreateBeaconStation();
GenerateEqualityCheckValue(LevelGenStage.PlaceLevelObjects);
GenerateEqualityCheckValue(LevelGenStage.TopAndBottom);
LevelObjectManager.PlaceObjects(this, GenerationParams.LevelObjectAmount);
GenerateEqualityCheckValue(LevelGenStage.GenerateItems);
GenerateEqualityCheckValue(LevelGenStage.PlaceLevelObjects);
GenerateItems();
GenerateEqualityCheckValue(LevelGenStage.Finish);
foreach (Submarine sub in Submarine.Loaded)
{
if (sub.Info.IsOutpost)
{
OutpostGenerator.PowerUpOutpost(sub);
}
}
GenerateEqualityCheckValue(LevelGenStage.GenerateItems);
#if CLIENT
backgroundCreatureManager.SpawnCreatures(this, GenerationParams.BackgroundCreatureAmount);
@@ -1384,7 +1400,7 @@ namespace Barotrauma
}
//initialize MapEntities that aren't in any sub (e.g. items inside ruins)
MapEntity.MapLoaded(MapEntity.mapEntityList.FindAll(me => me.Submarine == null), false);
MapEntity.MapLoaded(MapEntity.MapEntityList.FindAll(me => me.Submarine == null), false);
Debug.WriteLine("Generatelevel: " + sw2.ElapsedMilliseconds + " ms");
sw2.Restart();
@@ -1409,6 +1425,7 @@ namespace Barotrauma
GameMain.Server.EntityEventManager.Clear();
#endif
GenerateEqualityCheckValue(LevelGenStage.Finish);
//assign an ID to make entity events work
//ID = FindFreeID();
Generating = false;
@@ -1949,7 +1966,8 @@ namespace Barotrauma
BottomBarrier = GameMain.World.CreateEdge(
ConvertUnits.ToSimUnits(new Vector2(borders.X, 0)),
ConvertUnits.ToSimUnits(new Vector2(borders.Right, 0)));
//for debugging purposes
BottomBarrier.UserData = "bottombarrier";
BottomBarrier.SetTransform(ConvertUnits.ToSimUnits(new Vector2(0.0f, BottomPos)), 0.0f);
BottomBarrier.BodyType = BodyType.Static;
BottomBarrier.CollisionCategories = Physics.CollisionLevel;
@@ -2055,23 +2073,56 @@ namespace Barotrauma
}
}
private void GenerateRuin(Point ruinPos, bool mirror)
private void GenerateRuin(Point ruinPos, bool mirror, bool requireMissionReadyRuin)
{
var ruinGenerationParams = RuinGenerationParams.RuinParams.GetRandom(Rand.RandSync.ServerAndClient);
float GetWeight(RuinGenerationParams p)
{
if (p.PreferredDifficulty == -1) { return 100; }
float diff = Math.Abs(Difficulty - p.PreferredDifficulty) / 100;
float weight = MathUtils.Pow(1 - diff, 10);
return Math.Max(weight, 0);
}
IEnumerable<RuinGenerationParams> possibleRuinGenerationParams = RuinGenerationParams.RuinParams;
if (requireMissionReadyRuin)
{
possibleRuinGenerationParams = possibleRuinGenerationParams.Where(p => p.IsMissionReady);
}
if (possibleRuinGenerationParams.Multiple())
{
// Sort by weight and choose from the closest 25% of the candidates.
// Prevents choosing from the "wrong" end, which would otherwise be possible (yet rare), because we use a weighted random for the pick.
possibleRuinGenerationParams = possibleRuinGenerationParams
/* the prefabs aren't in a consistent order, so we need to sort them first to ensure the clients and server choose the same one */
.OrderByDescending(p => p.UintIdentifier)
.OrderByDescending(GetWeight)
.Take((int)Math.Max(Math.Round(possibleRuinGenerationParams.Count() / 4f), 1));
}
var selectedRuinGenerationParams = possibleRuinGenerationParams.GetRandomByWeight(GetWeight, randSync: Rand.RandSync.ServerAndClient);
if (selectedRuinGenerationParams == null)
{
DebugConsole.ThrowError("Failed to generate alien ruins. Could not find any RuinGenerationParameters!");
return;
}
DebugConsole.NewMessage($"Creating alien ruins using {selectedRuinGenerationParams.Identifier} (preferred difficulty: {selectedRuinGenerationParams.PreferredDifficulty}, current difficulty {Difficulty})", color: Color.Yellow);
LocationType locationType = StartLocation?.Type;
if (locationType == null)
{
locationType = LocationType.Prefabs.GetRandom(Rand.RandSync.ServerAndClient);
if (ruinGenerationParams.AllowedLocationTypes.Any())
if (selectedRuinGenerationParams.AllowedLocationTypes.Any())
{
locationType = LocationType.Prefabs.Where(lt =>
ruinGenerationParams.AllowedLocationTypes.Any(allowedType =>
selectedRuinGenerationParams.AllowedLocationTypes.Any(allowedType =>
allowedType == "any" || lt.Identifier == allowedType)).GetRandom(Rand.RandSync.ServerAndClient);
}
}
var ruin = new Ruin(this, ruinGenerationParams, locationType, ruinPos, mirror);
var ruin = new Ruin(this, selectedRuinGenerationParams, locationType, ruinPos, mirror);
if (ruin.Submarine != null)
{
SetLinkedSubCrushDepth(ruin.Submarine);
}
Ruins.Add(ruin);
var tooClose = GetTooCloseCells(ruinPos.ToVector2(), Math.Max(ruin.Area.Width, ruin.Area.Height) * 4);
@@ -3671,7 +3722,7 @@ namespace Barotrauma
}
tempSW.Stop();
Debug.WriteLine($"Sub {sub.Info.Name} loaded in { tempSW.ElapsedMilliseconds} (ms)");
sub.SetPosition(spawnPoint);
sub.SetPosition(spawnPoint, forceUndockFromStaticSubmarines: false);
wreckPositions.Add(sub, positions);
blockedRects.Add(sub, rects);
return sub;
@@ -3985,11 +4036,13 @@ namespace Barotrauma
SubmarineInfo outpostInfo;
Submarine outpost = null;
if (i == 0 && preSelectedStartOutpost == null || i == 1 && preSelectedEndOutpost == null)
SubmarineInfo preSelectedOutpost = isStart ? preSelectedStartOutpost : preSelectedEndOutpost;
if (preSelectedOutpost == null)
{
if (LevelData.OutpostGenerationParamsExist)
{
Location location = i == 0 ? StartLocation : EndLocation;
Location location = isStart ? StartLocation : EndLocation;
OutpostGenerationParams outpostGenerationParams = null;
if (LevelData.ForceOutpostGenerationParams != null)
{
@@ -4027,7 +4080,7 @@ namespace Barotrauma
foreach (string categoryToHide in locationType.HideEntitySubcategories)
{
foreach (MapEntity entityToHide in MapEntity.mapEntityList.Where(me => me.Submarine == outpost && (me.Prefab?.HasSubCategory(categoryToHide) ?? false)))
foreach (MapEntity entityToHide in MapEntity.MapEntityList.Where(me => me.Submarine == outpost && (me.Prefab?.HasSubCategory(categoryToHide) ?? false)))
{
entityToHide.HiddenInGame = true;
}
@@ -4048,7 +4101,7 @@ namespace Barotrauma
else
{
DebugConsole.NewMessage($"Loading a pre-selected outpost for the {(isStart ? "start" : "end")} of the level...");
outpostInfo = (i == 0) ? preSelectedStartOutpost : preSelectedEndOutpost;
outpostInfo = preSelectedOutpost;
outpostInfo.Type = SubmarineType.Outpost;
outpost = new Submarine(outpostInfo);
}
@@ -4132,6 +4185,7 @@ namespace Barotrauma
}
outpost.SetPosition(spawnPos, forceUndockFromStaticSubmarines: false);
SetLinkedSubCrushDepth(outpost);
foreach (WayPoint wp in WayPoint.WayPointList)
{
@@ -4178,7 +4232,7 @@ namespace Barotrauma
ContentFile contentFile = null;
if (!string.IsNullOrEmpty(GenerationParams.ForceBeaconStation))
{
contentFile = beaconStationFiles.FirstOrDefault(f => f.Path == GenerationParams.ForceBeaconStation);
contentFile = beaconStationFiles.OrderBy(b => b.UintIdentifier).FirstOrDefault(f => f.Path == GenerationParams.ForceBeaconStation);
if (contentFile == null)
{
DebugConsole.ThrowError($"Failed to find the beacon station \"{GenerationParams.ForceBeaconStation}\". Using a random one instead...");
@@ -4266,77 +4320,75 @@ namespace Barotrauma
beaconSonar.Item.CreateServerEvent(beaconSonar);
#endif
}
else
else if (GameMain.NetworkMember is not { IsClient: true })
{
if (!(GameMain.NetworkMember?.IsClient ?? false))
bool allowDisconnectedWires = true;
bool allowDamagedWalls = true;
if (BeaconStation?.Info?.BeaconStationInfo is BeaconStationInfo info)
{
bool allowDisconnectedWires = true;
bool allowDamagedWalls = true;
if (BeaconStation?.Info?.BeaconStationInfo is BeaconStationInfo info)
{
allowDisconnectedWires = info.AllowDisconnectedWires;
allowDamagedWalls = info.AllowDamagedWalls;
}
allowDisconnectedWires = info.AllowDisconnectedWires;
allowDamagedWalls = info.AllowDamagedWalls;
}
//remove wires
float removeWireMinDifficulty = 20.0f;
float removeWireProbability = MathUtils.InverseLerp(removeWireMinDifficulty, 100.0f, LevelData.Difficulty) * 0.5f;
if (removeWireProbability > 0.0f && allowDisconnectedWires)
//remove wires
float removeWireMinDifficulty = 20.0f;
float removeWireProbability = MathUtils.InverseLerp(removeWireMinDifficulty, 100.0f, LevelData.Difficulty) * 0.5f;
if (removeWireProbability > 0.0f && allowDisconnectedWires)
{
foreach (Item item in beaconItems.Where(it => it.GetComponent<Wire>() != null).ToList())
{
foreach (Item item in beaconItems.Where(it => it.GetComponent<Wire>() != null).ToList())
if (item.NonInteractable || item.InvulnerableToDamage) { continue; }
Wire wire = item.GetComponent<Wire>();
if (wire.Locked) { continue; }
if (wire.Connections[0] != null && (wire.Connections[0].Item.NonInteractable || wire.Connections[0].Item.GetComponent<ConnectionPanel>().Locked))
{
if (item.NonInteractable || item.InvulnerableToDamage) { continue; }
Wire wire = item.GetComponent<Wire>();
if (wire.Locked) { continue; }
if (wire.Connections[0] != null && (wire.Connections[0].Item.NonInteractable || wire.Connections[0].Item.GetComponent<ConnectionPanel>().Locked))
continue;
}
if (wire.Connections[1] != null && (wire.Connections[1].Item.NonInteractable || wire.Connections[1].Item.GetComponent<ConnectionPanel>().Locked))
{
continue;
}
if (Rand.Range(0f, 1.0f, Rand.RandSync.Unsynced) < removeWireProbability)
{
foreach (Connection connection in wire.Connections)
{
continue;
}
if (wire.Connections[1] != null && (wire.Connections[1].Item.NonInteractable || wire.Connections[1].Item.GetComponent<ConnectionPanel>().Locked))
{
continue;
}
if (Rand.Range(0f, 1.0f, Rand.RandSync.Unsynced) < removeWireProbability)
{
foreach (Connection connection in wire.Connections)
if (connection != null)
{
if (connection != null)
{
connection.ConnectionPanel.DisconnectedWires.Add(wire);
wire.RemoveConnection(connection.Item);
connection.ConnectionPanel.DisconnectedWires.Add(wire);
wire.RemoveConnection(connection.Item);
#if SERVER
connection.ConnectionPanel.Item.CreateServerEvent(connection.ConnectionPanel);
wire.CreateNetworkEvent();
connection.ConnectionPanel.Item.CreateServerEvent(connection.ConnectionPanel);
wire.CreateNetworkEvent();
#endif
}
}
}
}
}
}
if (allowDamagedWalls)
if (allowDamagedWalls)
{
//break powered items
foreach (Item item in beaconItems.Where(it => it.Components.Any(c => c is Powered) && it.Components.Any(c => c is Repairable)))
{
//break powered items
foreach (Item item in beaconItems.Where(it => it.Components.Any(c => c is Powered) && it.Components.Any(c => c is Repairable)))
if (item.NonInteractable || item.InvulnerableToDamage) { continue; }
if (Rand.Range(0f, 1f, Rand.RandSync.Unsynced) < 0.5f)
{
if (item.NonInteractable || item.InvulnerableToDamage) { continue; }
if (Rand.Range(0f, 1f, Rand.RandSync.Unsynced) < 0.5f)
{
item.Condition *= Rand.Range(0.6f, 0.8f, Rand.RandSync.Unsynced);
}
item.Condition *= Rand.Range(0.6f, 0.8f, Rand.RandSync.Unsynced);
}
//poke holes in the walls
foreach (Structure structure in Structure.WallList.Where(s => s.Submarine == BeaconStation))
}
//poke holes in the walls
foreach (Structure structure in Structure.WallList.Where(s => s.Submarine == BeaconStation))
{
if (Rand.Range(0f, 1f, Rand.RandSync.Unsynced) < 0.25f)
{
if (Rand.Range(0f, 1f, Rand.RandSync.Unsynced) < 0.25f)
{
int sectionIndex = Rand.Range(0, structure.SectionCount - 1, Rand.RandSync.Unsynced);
structure.AddDamage(sectionIndex, Rand.Range(structure.MaxHealth * 0.2f, structure.MaxHealth, Rand.RandSync.Unsynced));
}
int sectionIndex = Rand.Range(0, structure.SectionCount - 1, Rand.RandSync.Unsynced);
structure.AddDamage(sectionIndex, Rand.Range(structure.MaxHealth * 0.2f, structure.MaxHealth, Rand.RandSync.Unsynced));
}
}
}
}
SetLinkedSubCrushDepth(BeaconStation);
}
public bool CheckBeaconActive()
@@ -4345,7 +4397,15 @@ namespace Barotrauma
return beaconSonar.Voltage > beaconSonar.MinVoltage && beaconSonar.CurrentMode == Sonar.Mode.Active;
}
private bool IsModeStartOutpostCompatible()
private void SetLinkedSubCrushDepth(Submarine parentSub)
{
foreach (var connectedSub in parentSub.GetConnectedSubs())
{
connectedSub.RealWorldCrushDepth = Math.Max(connectedSub.RealWorldCrushDepth, GetRealWorldDepth(0) + 1000);
}
}
private static bool IsModeStartOutpostCompatible()
{
#if CLIENT
return GameMain.GameSession?.GameMode is CampaignMode || GameMain.GameSession?.GameMode is TutorialMode || GameMain.GameSession?.GameMode is TestGameMode;
@@ -178,7 +178,7 @@ namespace Barotrauma
if (eventSet is null) { continue; }
int count = childElement.GetAttributeInt("count", 0);
if (count < 1) { continue; }
FinishedEvents.Add(eventSet, count);
FinishedEvents.TryAdd(eventSet, count);
}
static EventSet FindSetRecursive(EventSet parentSet, Identifier setIdentifier)
@@ -502,9 +502,19 @@ namespace Barotrauma
}
}
[Serialize(1, IsPropertySaveable.Yes, description: "The number of alien ruins in the level."), Editable(MinValueInt = 0, MaxValueInt = 10)]
public bool UseRandomRuinCount() => MinRuinCount >= 0 && MaxRuinCount > 0;
public int GetMaxRuinCount() => UseRandomRuinCount() ? MaxRuinCount : RuinCount;
[Serialize(1, IsPropertySaveable.Yes, description: "The number of alien ruins in the level. Ignored, if both MinRuinCount and MaxRuinCount are defined."), Editable(MinValueInt = 0, MaxValueInt = 10)]
public int RuinCount { get; set; }
[Serialize(0, IsPropertySaveable.Yes, description: "The minimum number of alien ruins in the level."), Editable(MinValueInt = 0, MaxValueInt = 10)]
public int MinRuinCount { get; set; }
[Serialize(0, IsPropertySaveable.Yes, description: "The maximum number of alien ruins in the level."), Editable(MinValueInt = 0, MaxValueInt = 10)]
public int MaxRuinCount { get; set; }
// TODO: Move the wreck parameters under a separate class?
#region Wreck parameters
[Serialize(1, IsPropertySaveable.Yes, description: "The minimum number of wrecks in the level. Note that this value cannot be higher than the amount of wreck prefabs (subs)."), Editable(MinValueInt = 0, MaxValueInt = 10)]
@@ -20,6 +20,8 @@ namespace Barotrauma
private List<LevelObject> updateableObjects;
private List<LevelObject>[,] objectGrid;
const float ParallaxStrength = 0.0001f;
public float GlobalForceDecreaseTimer
{
get;
@@ -237,7 +239,6 @@ namespace Barotrauma
PlaceObject(prefab, spawnPosition, level, cave);
if (amount > prefab.MaxCount && objects.Count > prefab.MaxCount)
{
bool maxReached = false;
int objectCount = 0;
for (int j = 0; j < objects.Count; j++)
{
@@ -406,11 +407,11 @@ namespace Barotrauma
}
}
float minX = spriteCorners.Min(c => c.X) - newObject.Position.Z / 10000.0f;
float maxX = spriteCorners.Max(c => c.X) + newObject.Position.Z / 10000.0f;
float minX = spriteCorners.Min(c => c.X) - newObject.Position.Z * ParallaxStrength;
float maxX = spriteCorners.Max(c => c.X) + newObject.Position.Z * ParallaxStrength;
float minY = spriteCorners.Min(c => c.Y) - newObject.Position.Z / 10000.0f - level.BottomPos;
float maxY = spriteCorners.Max(c => c.Y) + newObject.Position.Z / 10000.0f - level.BottomPos;
float minY = spriteCorners.Min(c => c.Y) - newObject.Position.Z * ParallaxStrength - level.BottomPos;
float maxY = spriteCorners.Max(c => c.Y) + newObject.Position.Z * ParallaxStrength - level.BottomPos;
if (newObject.Triggers != null)
{
@@ -465,7 +466,7 @@ namespace Barotrauma
for (int y = yStart; y <= yEnd; y++)
{
var list = objectGrid[x, y];
if (objectGrid[x, y] == null) { list = objectGrid[x, y] = new List<LevelObject>(); }
if (list == null) { objectGrid[x, y] = list = new List<LevelObject>(); }
//insertion sort in ascending order (= prefer rendering objects in front)
int drawOrderIndex = 0;
@@ -478,9 +479,9 @@ namespace Barotrauma
}
}
public static Microsoft.Xna.Framework.Point GetGridIndices(Vector2 worldPosition)
public static Point GetGridIndices(Vector2 worldPosition)
{
return new Microsoft.Xna.Framework.Point(
return new Point(
(int)Math.Floor(worldPosition.X / GridSize),
(int)Math.Floor((worldPosition.Y - Level.Loaded.BottomPos) / GridSize));
}
@@ -521,7 +522,7 @@ namespace Barotrauma
return objectsInRange;
}
private static List<SpawnPosition> GetAvailableSpawnPositions(IEnumerable<VoronoiCell> cells, LevelObjectPrefab.SpawnPosType spawnPosType, bool checkFlags = true)
private static List<SpawnPosition> GetAvailableSpawnPositions(IEnumerable<VoronoiCell> cells, LevelObjectPrefab.SpawnPosType spawnPosType)
{
List<LevelObjectPrefab.SpawnPosType> spawnPosTypes = new List<LevelObjectPrefab.SpawnPosType>(4);
List<SpawnPosition> availableSpawnPositions = new List<SpawnPosition>();
@@ -366,6 +366,7 @@ namespace Barotrauma
private void LoadElements(LevelObjectPrefabsFile file, ContentXElement element, int parentTriggerIndex)
{
int propertyOverrideCount = 0;
//load sprites first, OverrideProperties may need them (defaulting to the default sprite if no override is defined)
foreach (var subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
@@ -384,6 +385,12 @@ namespace Barotrauma
case "deformablesprite":
DeformableSprite = new DeformableSprite(subElement, lazyLoad: true);
break;
}
}
foreach (var subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "overridecommonness":
Identifier levelType = subElement.GetAttributeIdentifier("leveltype", Identifier.Empty);
if (!OverrideCommonness.ContainsKey(levelType))
@@ -27,6 +27,9 @@ namespace Barotrauma.RuinGeneration
public override string Name => "RuinGenerationParams";
[Serialize(true, IsPropertySaveable.Yes, description: "Are these params designed to be used for alien ruins targeted by missions. If false, the params are ignored when there's any missions targeting ruins."), Editable]
public bool IsMissionReady { get; set; }
public RuinGenerationParams(ContentXElement element, RuinConfigFile file) : base(element, file) { }
public static void SaveAll()
@@ -44,7 +44,7 @@ namespace Barotrauma.RuinGeneration
//prevent the ruin from extending above the level "ceiling"
position.Y = Math.Min(level.Size.Y - (Submarine.Borders.Height / 2) - 100, position.Y);
Submarine.SetPosition(position.ToVector2());
Submarine.SetPosition(position.ToVector2(), forceUndockFromStaticSubmarines: false);
if (mirror)
{