Faction Test 100.13.0.0

This commit is contained in:
Markus Isberg
2023-01-11 15:36:23 +02:00
parent 1650735468
commit caa5a2f762
145 changed files with 2100 additions and 1111 deletions
@@ -867,6 +867,7 @@ namespace Barotrauma
(endPath != null && GetDistToTunnel(cell.Center, endPath) < minMainPathWidth) ||
(endHole != null && GetDistToTunnel(cell.Center, endHole) < minMainPathWidth)) { continue; }
if (cell.Edges.Any(e => e.AdjacentCell(cell)?.CellType != CellType.Path || e.NextToCave)) { continue; }
if (PositionsOfInterest.Any(p => cell.IsPointInside(p.Position.ToVector2()))) { continue; }
potentialIslands.Add(cell);
}
for (int i = 0; i < GenerationParams.IslandCount; i++)
@@ -1112,6 +1113,7 @@ namespace Barotrauma
caveCells.AddRange(cave.Tunnels.SelectMany(t => t.Cells));
foreach (var caveCell in caveCells)
{
if (PositionsOfInterest.Any(p => caveCell.IsPointInside(p.Position.ToVector2()))) { continue; }
if (Rand.Range(0.0f, 1.0f, Rand.RandSync.ServerAndClient) < destructibleWallRatio * cave.CaveGenerationParams.DestructibleWallRatio)
{
var chunk = CreateIceChunk(caveCell.Edges, caveCell.Center, health: 50.0f);
@@ -3189,7 +3191,7 @@ namespace Barotrauma
TryGetInterestingPosition(true, spawnPosType, minDistFromSubs, out Vector2 startPos, filter);
Vector2 offset = Rand.Vector(Rand.Range(0.0f, randomSpread, Rand.RandSync.ServerAndClient), Rand.RandSync.ServerAndClient);
if (!cells.Any(c => c.IsPointInside(startPos + offset)))
if (!IsPositionInsideWall(startPos + offset))
{
startPos += offset;
}
@@ -3245,10 +3247,9 @@ namespace Barotrauma
{
suitablePositions.RemoveAll(p => !filter(p));
}
//avoid floating ice chunks on the main path
if (positionType.HasFlag(PositionType.MainPath) || positionType.HasFlag(PositionType.SidePath))
{
suitablePositions.RemoveAll(p => ExtraWalls.Any(w => w.Cells.Any(c => c.IsPointInside(p.Position.ToVector2()))));
suitablePositions.RemoveAll(p => IsPositionInsideWall(p.Position.ToVector2()));
}
if (!suitablePositions.Any())
{
@@ -3301,10 +3302,16 @@ namespace Barotrauma
return false;
}
position = farEnoughPositions[Rand.Int(farEnoughPositions.Count, (useSyncedRand ? Rand.RandSync.ServerAndClient : Rand.RandSync.Unsynced))].Position;
position = farEnoughPositions[Rand.Int(farEnoughPositions.Count, useSyncedRand ? Rand.RandSync.ServerAndClient : Rand.RandSync.Unsynced)].Position;
return true;
}
public bool IsPositionInsideWall(Vector2 worldPosition)
{
var closestCell = GetClosestCell(worldPosition);
return closestCell != null && closestCell.IsPointInside(worldPosition);
}
public void Update(float deltaTime, Camera cam)
{
LevelObjectManager.Update(deltaTime);
@@ -3347,14 +3354,13 @@ namespace Barotrauma
public Vector2 GetBottomPosition(float xPosition)
{
int index = (int)Math.Floor(xPosition / Size.X * (bottomPositions.Count - 1));
float interval = Size.X / (bottomPositions.Count - 1);
int index = (int)Math.Floor(xPosition / interval);
if (index < 0 || index >= bottomPositions.Count - 1) { return new Vector2(xPosition, BottomPos); }
float t = (xPosition - bottomPositions[index].X) / (bottomPositions[index + 1].X - bottomPositions[index].X);
//t can go slightly outside the 0-1 due to rounding, safe to ignore
Debug.Assert(t <= 1.001f && t >= -0.001f);
float t = (xPosition - bottomPositions[index].X) / interval;
t = MathHelper.Clamp(t, 0.0f, 1.0f);
float yPos = MathHelper.Lerp(bottomPositions[index].Y, bottomPositions[index + 1].Y, t);
return new Vector2(xPosition, yPos);
@@ -161,7 +161,7 @@ namespace Barotrauma
/// </summary>
public LevelData(LocationConnection locationConnection)
{
Seed = locationConnection.Locations[0].BaseName + locationConnection.Locations[1].BaseName;
Seed = locationConnection.Locations[0].LevelData.Seed + locationConnection.Locations[1].LevelData.Seed;
Biome = locationConnection.Biome;
Type = LevelType.LocationConnection;
Difficulty = locationConnection.Difficulty;
@@ -194,9 +194,9 @@ namespace Barotrauma
/// <summary>
/// Instantiates level data using the properties of the location
/// </summary>
public LevelData(Location location, float difficulty)
public LevelData(Location location, Map map, float difficulty)
{
Seed = location.BaseName;
Seed = location.BaseName + map.Locations.IndexOf(location);
Biome = location.Biome;
Type = LevelType.Outpost;
Difficulty = difficulty;
@@ -646,7 +646,7 @@ namespace Barotrauma
}
}
public static LevelGenerationParams GetRandom(string seed, LevelData.LevelType type, float difficulty, Identifier biome = default)
public static LevelGenerationParams GetRandom(string seed, LevelData.LevelType type, float difficulty, Identifier biomeId = default)
{
Rand.SetSyncedSeed(ToolBox.StringToInt(seed));
@@ -661,14 +661,29 @@ namespace Barotrauma
lp.Type == type &&
(lp.AnyBiomeAllowed || lp.AllowedBiomeIdentifiers.Any()) &&
!lp.AllowedBiomeIdentifiers.Contains("None".ToIdentifier()));
matchingLevelParams = biome.IsEmpty
? matchingLevelParams.Where(lp => lp.AnyBiomeAllowed || !lp.AllowedBiomeIdentifiers.All(b => Biome.Prefabs[b].IsEndBiome))
: matchingLevelParams.Where(lp => lp.AnyBiomeAllowed || lp.AllowedBiomeIdentifiers.Contains(biome));
if (biomeId.IsEmpty)
{
//we don't want end levels when generating a completely random level (e.g. in mission mode)
matchingLevelParams = matchingLevelParams.Where(lp => lp.AnyBiomeAllowed || !lp.AllowedBiomeIdentifiers.All(b => Biome.Prefabs[b].IsEndBiome));
}
else
{
bool isEndBiome = Biome.Prefabs.TryGet(biomeId, out Biome biome) && biome.IsEndBiome;
if (isEndBiome && matchingLevelParams.Any(lp => lp.AllowedBiomeIdentifiers.Contains(biomeId)))
{
//in the end biome, we must choose level parameters meant specifically for the end levels
matchingLevelParams = matchingLevelParams.Where(lp => lp.AllowedBiomeIdentifiers.Contains(biomeId));
}
else
{
matchingLevelParams = matchingLevelParams.Where(lp => lp.AnyBiomeAllowed || lp.AllowedBiomeIdentifiers.Contains(biomeId));
}
}
if (!matchingLevelParams.Any())
{
DebugConsole.ThrowError($"Suitable level generation presets not found (biome \"{biome.IfEmpty("null".ToIdentifier())}\", type: \"{type}\")");
if (!biome.IsEmpty)
DebugConsole.ThrowError($"Suitable level generation presets not found (biome \"{biomeId.IfEmpty("null".ToIdentifier())}\", type: \"{type}\")");
if (!biomeId.IsEmpty)
{
//try to find params that at least have a suitable type
matchingLevelParams = levelParamsOrdered.Where(lp => lp.Type == type);
@@ -682,7 +697,7 @@ namespace Barotrauma
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})");
DebugConsole.ThrowError($"Suitable level generation presets not found (biome \"{biomeId.IfEmpty("null".ToIdentifier())}\", type: \"{type}\", difficulty: {difficulty})");
}
else
{
@@ -457,12 +457,14 @@ namespace Barotrauma
private struct LoadedMission
{
public MissionPrefab MissionPrefab { get; }
public int OriginLocationIndex { get; }
public int DestinationIndex { get; }
public bool SelectedMission { get; }
public LoadedMission(MissionPrefab prefab, int destinationIndex, bool selectedMission)
public LoadedMission(MissionPrefab prefab, int originLocationIndex, int destinationIndex, bool selectedMission)
{
MissionPrefab = prefab;
OriginLocationIndex = originLocationIndex;
DestinationIndex = destinationIndex;
SelectedMission = selectedMission;
}
@@ -663,9 +665,10 @@ namespace Barotrauma
if (string.IsNullOrWhiteSpace(id)) { continue; }
var prefab = MissionPrefab.Prefabs.Find(p => p.Identifier == id);
if (prefab == null) { continue; }
var origin = childElement.GetAttributeInt("origin", -1);
var destination = childElement.GetAttributeInt("destinationindex", -1);
var selected = childElement.GetAttributeBool("selected", false);
loadedMissions.Add(new LoadedMission(prefab, destination, selected));
loadedMissions.Add(new LoadedMission(prefab, origin, destination, selected));
}
}
}
@@ -926,6 +929,10 @@ namespace Barotrauma
destination = Connections.First().OtherLocation(this);
}
var mission = loadedMission.MissionPrefab.Instantiate(new Location[] { this, destination }, Submarine.MainSub);
if (loadedMission.OriginLocationIndex >= 0 && loadedMission.OriginLocationIndex < map.Locations.Count)
{
mission.OriginLocation = map.Locations[loadedMission.OriginLocationIndex];
}
availableMissions.Add(mission);
if (loadedMission.SelectedMission) { selectedMissions.Add(mission); }
}
@@ -1520,10 +1527,12 @@ namespace Barotrauma
foreach (Mission mission in missions)
{
var location = mission.Locations.All(l => l == this) ? this : mission.Locations.FirstOrDefault(l => l != this);
var i = map.Locations.IndexOf(location);
var destinationIndex = map.Locations.IndexOf(location);
var originIndex = map.Locations.IndexOf(mission.OriginLocation);
missionsElement.Add(new XElement("mission",
new XAttribute("prefabid", mission.Prefab.Identifier),
new XAttribute("destinationindex", i),
new XAttribute("destinationindex", destinationIndex),
new XAttribute("origin", originIndex),
new XAttribute("selected", selectedMissions.Contains(mission))));
}
locationElement.Add(missionsElement);
@@ -167,7 +167,7 @@ namespace Barotrauma
}
int startLocationindex = element.GetAttributeInt("startlocation", -1);
if (startLocationindex > 0 && startLocationindex < Locations.Count)
if (startLocationindex >= 0 && startLocationindex < Locations.Count)
{
StartLocation = Locations[startLocationindex];
}
@@ -188,10 +188,9 @@ namespace Barotrauma
{
//backwards compatibility
int endLocationIndex = element.GetAttributeInt("endlocation", -1);
if (endLocationIndex > 0 && endLocationIndex < Locations.Count)
if (endLocationIndex >= 0 && endLocationIndex < Locations.Count)
{
endLocations.Add(Locations[endLocationIndex]);
Locations[endLocationIndex].LevelData.ReassignGenerationParams(Seed);
}
else
{
@@ -203,7 +202,7 @@ namespace Barotrauma
int[] endLocationindices = element.GetAttributeIntArray("endlocations", Array.Empty<int>());
foreach (int endLocationIndex in endLocationindices)
{
if (endLocationIndex > 0 && endLocationIndex < Locations.Count)
if (endLocationIndex >= 0 && endLocationIndex < Locations.Count)
{
endLocations.Add(Locations[endLocationIndex]);
}
@@ -245,7 +244,7 @@ namespace Barotrauma
{
Biome = endLocations.First().Biome
};
newEndLocation.LevelData = new LevelData(newEndLocation, difficulty: 100.0f);
newEndLocation.LevelData = new LevelData(newEndLocation, this, difficulty: 100.0f);
Locations.Add(newEndLocation);
endLocations.Add(newEndLocation);
}
@@ -339,7 +338,7 @@ namespace Barotrauma
{
if (StartLocation != null)
{
StartLocation.LevelData = new LevelData(StartLocation, 0);
StartLocation.LevelData = new LevelData(StartLocation, this, 0);
}
//ensure all paths from the starting location have 0 difficulty to make the 1st campaign round very easy
@@ -701,7 +700,7 @@ namespace Barotrauma
foreach (Location location in Locations)
{
location.LevelData = new LevelData(location, CalculateDifficulty(location.MapPosition.X, location.Biome));
location.LevelData = new LevelData(location, this, CalculateDifficulty(location.MapPosition.X, location.Biome));
if (location.Type.HasOutpost && campaign != null && location.Type.OutpostTeam == CharacterTeamType.FriendlyNPC)
{
location.Faction ??= campaign.GetRandomFaction(Rand.RandSync.ServerAndClient);
@@ -902,6 +901,7 @@ namespace Barotrauma
{
for (int i = 0; i < endLocations.Count; i++)
{
endLocations[i].LevelData.ReassignGenerationParams(Seed);
var outpostParams = OutpostGenerationParams.OutpostParams.FirstOrDefault(p => p.ForceToEndLocationIndex == i);
if (outpostParams != null)
{
@@ -124,9 +124,18 @@ namespace Barotrauma
int eventCount = GameMain.Server.EntityEventManager.Events.Count();
int uniqueEventCount = GameMain.Server.EntityEventManager.UniqueEvents.Count();
#endif
List<MapEntity> entities = MapEntity.mapEntityList.FindAll(e => e.Submarine == sub);
HashSet<Submarine> connectedSubs = new HashSet<Submarine>() { sub };
foreach (Submarine otherSub in Submarine.Loaded)
{
//remove linked subs too
if (otherSub.Submarine == sub) { connectedSubs.Add(otherSub); }
}
List<MapEntity> entities = MapEntity.mapEntityList.FindAll(e => connectedSubs.Contains(e.Submarine));
entities.ForEach(e => e.Remove());
sub.Remove();
foreach (Submarine otherSub in connectedSubs)
{
otherSub.Remove();
}
#if SERVER
//remove any events created during the removal of the entities
GameMain.Server.EntityEventManager.Events.RemoveRange(eventCount, GameMain.Server.EntityEventManager.Events.Count - eventCount);
@@ -543,12 +552,8 @@ namespace Barotrauma
foreach (OutpostModuleInfo.GapPosition gapPosition in GapPositions.Randomize(Rand.RandSync.ServerAndClient))
{
if (currentModule.UsedGapPositions.HasFlag(gapPosition)) { continue; }
if (!allowExtendBelowInitialModule)
{
//don't continue downwards if it'd extend below the airlock
if (gapPosition == OutpostModuleInfo.GapPosition.Bottom && currentModule.Offset.Y <= 1) { continue; }
}
if (DisallowBelowAirlock(allowExtendBelowInitialModule, gapPosition, currentModule)) { continue; }
PlacedModule newModule = null;
//try appending to the current module if possible
if (currentModule.Info.OutpostModuleInfo.GapPositions.HasFlag(gapPosition))
@@ -569,6 +574,7 @@ namespace Barotrauma
foreach (OutpostModuleInfo.GapPosition otherGapPosition in
GapPositions.Where(g => !otherModule.UsedGapPositions.HasFlag(g) && otherModule.Info.OutpostModuleInfo.GapPositions.HasFlag(g)))
{
if (DisallowBelowAirlock(allowExtendBelowInitialModule, otherGapPosition, otherModule)) { continue; }
newModule = AppendModule(otherModule, GetOpposingGapPosition(otherGapPosition), availableModules, pendingModuleFlags, selectedModules, locationType, allowDifferentLocationType);
if (newModule != null)
{
@@ -617,6 +623,16 @@ namespace Barotrauma
{
System.Diagnostics.Debug.Assert(selectedModules.All(m => m.PreviousModule == null || selectedModules.Contains(m.PreviousModule)));
}
static bool DisallowBelowAirlock(bool allowExtendBelowInitialModule, OutpostModuleInfo.GapPosition gapPosition, PlacedModule currentModule)
{
if (!allowExtendBelowInitialModule)
{
//don't continue downwards if it'd extend below the airlock
if (gapPosition == OutpostModuleInfo.GapPosition.Bottom && currentModule.Offset.Y <= 1) { return true; }
}
return false;
}
}
/// <summary>
@@ -1367,7 +1367,7 @@ namespace Barotrauma
return new Rectangle((int)bounds.X, (int)bounds.Y, (int)(bounds.Z - bounds.X), (int)(bounds.Y - bounds.W));
}
public Submarine(SubmarineInfo info, bool showWarningMessages = true, Func<Submarine, List<MapEntity>> loadEntities = null, IdRemap linkedRemap = null) : base(null, Entity.NullEntityID)
public Submarine(SubmarineInfo info, bool showErrorMessages = true, Func<Submarine, List<MapEntity>> loadEntities = null, IdRemap linkedRemap = null) : base(null, Entity.NullEntityID)
{
upgradeEventIdentifier = new Identifier($"Submarine{ID}");
Loading = true;
@@ -1438,64 +1438,65 @@ namespace Barotrauma
center.Y -= center.Y % GridSize.Y;
RepositionEntities(-center, MapEntity.mapEntityList.Where(me => me.Submarine == this));
}
subBody = new SubmarineBody(this, showWarningMessages);
Vector2 pos = ConvertUnits.ToSimUnits(HiddenSubPosition);
subBody.Body.FarseerBody.SetTransformIgnoreContacts(ref pos, 0.0f);
subBody = new SubmarineBody(this, showErrorMessages);
Vector2 pos = ConvertUnits.ToSimUnits(HiddenSubPosition);
subBody.Body.FarseerBody.SetTransformIgnoreContacts(ref pos, 0.0f);
if (info.IsOutpost)
if (info.IsOutpost)
{
ShowSonarMarker = false;
PhysicsBody.FarseerBody.BodyType = BodyType.Static;
TeamID = CharacterTeamType.FriendlyNPC;
bool indestructible =
GameMain.NetworkMember != null &&
!GameMain.NetworkMember.ServerSettings.DestructibleOutposts &&
!(info.OutpostGenerationParams?.AlwaysDestructible ?? false);
foreach (MapEntity me in MapEntity.mapEntityList)
{
ShowSonarMarker = false;
TeamID = CharacterTeamType.FriendlyNPC;
bool indestructible =
GameMain.NetworkMember != null &&
!GameMain.NetworkMember.ServerSettings.DestructibleOutposts &&
!(info.OutpostGenerationParams?.AlwaysDestructible ?? false);
foreach (MapEntity me in MapEntity.mapEntityList)
if (me.Submarine != this) { continue; }
if (me is Item item)
{
if (me.Submarine != this) { continue; }
if (me is Item item)
item.SpawnedInCurrentOutpost = info.OutpostGenerationParams != null;
item.AllowStealing = info.OutpostGenerationParams?.AllowStealing ?? true;
if (item.GetComponent<Repairable>() != null && indestructible)
{
item.SpawnedInCurrentOutpost = info.OutpostGenerationParams != null;
item.AllowStealing = info.OutpostGenerationParams?.AllowStealing ?? true;
if (item.GetComponent<Repairable>() != null && indestructible)
item.Indestructible = true;
}
foreach (ItemComponent ic in item.Components)
{
if (ic is ConnectionPanel connectionPanel)
{
item.Indestructible = true;
}
foreach (ItemComponent ic in item.Components)
{
if (ic is ConnectionPanel connectionPanel)
//prevent rewiring
if (info.OutpostGenerationParams != null && !info.OutpostGenerationParams.AlwaysRewireable)
{
//prevent rewiring
if (info.OutpostGenerationParams != null && !info.OutpostGenerationParams.AlwaysRewireable)
{
connectionPanel.Locked = true;
}
connectionPanel.Locked = true;
}
else if (ic is Holdable holdable && holdable.Attached && item.GetComponent<LevelResource>() == null)
{
//prevent deattaching items from walls
}
else if (ic is Holdable holdable && holdable.Attached && item.GetComponent<LevelResource>() == null)
{
//prevent deattaching items from walls
#if CLIENT
if (GameMain.GameSession?.GameMode is TutorialMode) { continue; }
#endif
holdable.CanBePicked = false;
holdable.CanBeSelected = false;
}
holdable.CanBePicked = false;
holdable.CanBeSelected = false;
}
}
else if (me is Structure structure && structure.Prefab.IndestructibleInOutposts && indestructible)
{
structure.Indestructible = true;
}
}
else if (me is Structure structure && structure.Prefab.IndestructibleInOutposts && indestructible)
{
structure.Indestructible = true;
}
}
else if (info.IsRuin)
{
ShowSonarMarker = false;
PhysicsBody.FarseerBody.BodyType = BodyType.Static;
}
}
else if (info.IsRuin)
{
ShowSonarMarker = false;
PhysicsBody.FarseerBody.BodyType = BodyType.Static;
}
if (entityGrid != null)
@@ -1542,7 +1543,7 @@ namespace Barotrauma
#endif
//if the sub was made using an older version,
//halve the brightness of the lights to make them look (almost) right on the new lighting formula
if (showWarningMessages &&
if (showErrorMessages &&
!string.IsNullOrEmpty(Info.FilePath) &&
Screen.Selected != GameMain.SubEditorScreen &&
(Info.GameVersion == null || Info.GameVersion < new Version("0.8.9.0")))
@@ -116,7 +116,7 @@ namespace Barotrauma
get { return submarine; }
}
public SubmarineBody(Submarine sub, bool showWarningMessages = true)
public SubmarineBody(Submarine sub, bool showErrorMessages = true)
{
this.submarine = sub;
@@ -126,9 +126,9 @@ namespace Barotrauma
if (!Hull.HullList.Any(h => h.Submarine == sub))
{
farseerBody = GameMain.World.CreateRectangle(1.0f, 1.0f, 1.0f);
if (showWarningMessages)
if (showErrorMessages)
{
DebugConsole.ThrowError("WARNING: no hulls found, generating a physics body for the submarine failed.");
DebugConsole.ThrowError($"No hulls found in the submarine \"{sub.Info.Name}\". Generating a physics body for the submarine failed.");
}
}
else