Faction Test v1.0.1.0

This commit is contained in:
Regalis11
2023-02-16 15:01:28 +02:00
parent caa5a2f762
commit 2c5a7923b0
309 changed files with 7502 additions and 4335 deletions
@@ -70,13 +70,13 @@ namespace Barotrauma
public List<Location> Locations { get; private set; }
private readonly List<Location> locationsDiscovered = new List<Location>();
private readonly List<Location> outpostsVisited = new List<Location>();
private readonly List<Location> locationsVisited = new List<Location>();
public List<LocationConnection> Connections { get; private set; }
public Radiation Radiation;
private bool wasLocationDiscoveryOrderTracked = true;
private bool trackedLocationDiscoveryAndVisitOrder = true;
public Map(CampaignSettings settings)
{
@@ -939,6 +939,12 @@ namespace Barotrauma
public void MoveToNextLocation()
{
if (SelectedLocation == null && Level.Loaded?.EndLocation != null)
{
//force the location at the end of the level to be selected, even if it's been deselect on the map
//(e.g. due to returning to an empty location the beginning of the level during the round)
SelectLocation(Level.Loaded.EndLocation);
}
if (SelectedConnection == null)
{
if (!endLocations.Contains(CurrentLocation))
@@ -1043,12 +1049,24 @@ namespace Barotrauma
Location prevSelected = SelectedLocation;
SelectedLocation = Locations[index];
var currentDisplayLocation = GameMain.GameSession?.Campaign?.GetCurrentDisplayLocation();
SelectedConnection =
Connections.Find(c => c.Locations.Contains(currentDisplayLocation) && c.Locations.Contains(SelectedLocation)) ??
Connections.Find(c => c.Locations.Contains(CurrentLocation) && c.Locations.Contains(SelectedLocation));
if (currentDisplayLocation == SelectedLocation)
{
SelectedConnection = Connections.Find(c => c.Locations.Contains(CurrentLocation) && c.Locations.Contains(SelectedLocation));
}
else
{
SelectedConnection =
Connections.Find(c => c.Locations.Contains(currentDisplayLocation) && c.Locations.Contains(SelectedLocation)) ??
Connections.Find(c => c.Locations.Contains(CurrentLocation) && c.Locations.Contains(SelectedLocation));
}
if (SelectedConnection?.Locked ?? false)
{
DebugConsole.ThrowError("A locked connection was selected - this should not be possible.\n" + Environment.StackTrace.CleanupStackTrace());
string errorMsg =
$"A locked connection was selected ({SelectedConnection.Locations[0].Name} -> {SelectedConnection.Locations[1].Name}." +
$" Current location: {CurrentLocation}, current display location: {currentDisplayLocation}).\n"
+ Environment.StackTrace.CleanupStackTrace();
GameAnalyticsManager.AddErrorEventOnce("MapSelectLocation:LockedConnectionSelected", GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
DebugConsole.ThrowError(errorMsg);
}
if (prevSelected != SelectedLocation)
{
@@ -1266,51 +1284,6 @@ namespace Barotrauma
return false;
}
public int DistanceToClosestLocationWithOutpost(Location startingLocation, out Location endingLocation)
{
if (startingLocation.Type.HasOutpost)
{
endingLocation = startingLocation;
return 0;
}
int iterations = 0;
int distance = 0;
endingLocation = null;
List<Location> testedLocations = new List<Location>();
List<Location> locationsToTest = new List<Location> { startingLocation };
while (endingLocation == null && iterations < 100)
{
List<Location> nextTestingBatch = new List<Location>();
for (int i = 0; i < locationsToTest.Count; i++)
{
Location testLocation = locationsToTest[i];
for (int j = 0; j < testLocation.Connections.Count; j++)
{
Location potentialOutpost = testLocation.Connections[j].OtherLocation(testLocation);
if (potentialOutpost.Type.HasOutpost)
{
distance = iterations + 1;
endingLocation = potentialOutpost;
}
else if (!testedLocations.Contains(potentialOutpost))
{
nextTestingBatch.Add(potentialOutpost);
}
}
testedLocations.Add(testLocation);
}
locationsToTest = nextTestingBatch;
iterations++;
}
return distance;
}
private bool ChangeLocationType(CampaignMode campaign, Location location, LocationTypeChange change)
{
string prevName = location.Name;
@@ -1321,6 +1294,8 @@ namespace Barotrauma
return false;
}
if (location.LocationTypeChangesBlocked) { return false; }
if (newType.OutpostTeam != location.Type.OutpostTeam ||
newType.HasOutpost != location.Type.HasOutpost)
{
@@ -1338,6 +1313,50 @@ namespace Barotrauma
return true;
}
public static bool LocationOrConnectionWithinDistance(Location startLocation, int maxDistance, Func<Location, bool> criteria, Func<LocationConnection, bool> connectionCriteria = null)
{
return GetDistanceToClosestLocationOrConnection(startLocation, maxDistance, criteria, connectionCriteria) <= maxDistance;
}
/// <summary>
/// Get the shortest distance from the start location to another location that satisfies the specified criteria.
/// </summary>
/// <returns>The distance to a matching location, or int.MaxValue if none are found.</returns>
public static int GetDistanceToClosestLocationOrConnection(Location startLocation, int maxDistance, Func<Location, bool> criteria, Func<LocationConnection, bool> connectionCriteria = null)
{
int distance = 0;
var locationsToTest = new List<Location>() { startLocation };
var nextBatchToTest = new HashSet<Location>();
var checkedLocations = new HashSet<Location>();
while (locationsToTest.Any())
{
foreach (var location in locationsToTest)
{
checkedLocations.Add(location);
if (criteria(location)) { return distance; }
foreach (var connection in location.Connections)
{
if (connectionCriteria != null && connectionCriteria(connection))
{
return distance;
}
var otherLocation = connection.OtherLocation(location);
if (!checkedLocations.Contains(otherLocation))
{
nextBatchToTest.Add(otherLocation);
}
}
if (distance > maxDistance) { return int.MaxValue; }
}
distance++;
locationsToTest.Clear();
locationsToTest.AddRange(nextBatchToTest);
nextBatchToTest.Clear();
}
return int.MaxValue;
}
partial void ChangeLocationTypeProjSpecific(Location location, string prevName, LocationTypeChange change);
partial void ClearAnimQueue();
@@ -1356,29 +1375,38 @@ namespace Barotrauma
public void Visit(Location location)
{
if (location is null) { return; }
if (!location.HasOutpost()) { return; }
if (outpostsVisited.Contains(location)) { return; }
outpostsVisited.Add(location);
if (locationsVisited.Contains(location)) { return; }
locationsVisited.Add(location);
RemoveFogOfWarProjSpecific(location);
}
public void ClearLocationHistory()
{
locationsDiscovered.Clear();
outpostsVisited.Clear();
locationsVisited.Clear();
}
public int? GetDiscoveryIndex(Location location)
{
if (!wasLocationDiscoveryOrderTracked) { return null; }
if (!trackedLocationDiscoveryAndVisitOrder) { return null; }
if (location is null) { return -1; }
return locationsDiscovered.IndexOf(location);
}
public int? GetVisitIndex(Location location)
public int? GetVisitIndex(Location location, bool includeLocationsWithoutOutpost = false)
{
if (!wasLocationDiscoveryOrderTracked) { return null; }
if (!trackedLocationDiscoveryAndVisitOrder) { return null; }
if (location is null) { return -1; }
return outpostsVisited.IndexOf(location);
int index = locationsVisited.IndexOf(location);
if (includeLocationsWithoutOutpost) { return index; }
int noOutpostLocations = 0;
for (int i = 0; i < index; i++)
{
if (locationsVisited[i] is not Location l) { continue; }
if (l.HasOutpost()) { continue; }
noOutpostLocations++;
}
return index - noOutpostLocations;
}
public bool IsDiscovered(Location location)
@@ -1387,6 +1415,14 @@ namespace Barotrauma
return locationsDiscovered.Contains(location);
}
public bool IsVisited(Location location)
{
if (location is null) { return false; }
return locationsVisited.Contains(location);
}
partial void RemoveFogOfWarProjSpecific(Location location);
/// <summary>
/// Load a previously saved map from an xml element
/// </summary>
@@ -1431,11 +1467,13 @@ namespace Barotrauma
}
location.LoadLocationTypeChange(subElement);
// Backwards compatibility
// Backwards compatibility: if the discovery status is defined in the location element,
// the game was saved using when the discovery order still wasn't being tracked
if (subElement.GetAttributeBool("discovered", false))
{
Discover(location);
wasLocationDiscoveryOrderTracked = false;
Visit(location);
trackedLocationDiscoveryAndVisitOrder = false;
}
Identifier locationType = subElement.GetAttributeIdentifier("type", Identifier.Empty);
@@ -1472,32 +1510,45 @@ namespace Barotrauma
Radiation = new Radiation(this, generationParams.RadiationParams, subElement);
break;
case "discovered":
bool trackedVisitedEmptyLocations = subElement.GetAttributeBool("trackedvisitedemptylocations", false);
foreach (var childElement in subElement.GetChildElements("location"))
{
int index = childElement.GetAttributeInt("i", -1);
if (index < 0) { continue; }
if (Locations[index] is not Location l) { continue; }
Discover(l);
if (GetLocation(childElement) is Location l)
{
Discover(l);
if (!trackedVisitedEmptyLocations)
{
if (!l.HasOutpost())
{
Visit(l);
}
trackedLocationDiscoveryAndVisitOrder = false;
}
}
}
break;
case "visited":
foreach (var childElement in subElement.GetChildElements("location"))
{
int index = childElement.GetAttributeInt("i", -1);
if (index < 0) { continue; }
if (Locations[index] is not Location l) { continue; }
Visit(l);
if (GetLocation(childElement) is Location l)
{
Visit(l);
}
}
break;
}
Location GetLocation(XElement element)
{
int index = element.GetAttributeInt("i", -1);
if (index < 0) { return null; }
return Locations[index];
}
}
void Discover(Location location)
{
this.Discover(location, checkTalents: false);
#if CLIENT
RemoveFogOfWar(location);
#endif
if (furthestDiscoveredLocation == null || location.MapPosition.X > furthestDiscoveredLocation.MapPosition.X)
{
furthestDiscoveredLocation = location;
@@ -1509,9 +1560,6 @@ namespace Barotrauma
location?.InstantiateLoadedMissions(this);
}
#if RELEASE
TODO: MAKE SURE THE VERSION NUMBER BELOW IS CORRECT FOR THE FULL RELEASE (OR WHICHEVER UPDATE WE ADD THE FACTIONS IN)
#endif
//backwards compatibility:
//if the save is from a version prior to the addition of faction-specific outposts, assign factions
if (version < new Version(1, 0) && Locations.None(l => l.Faction != null || l.SecondaryFaction != null))
@@ -1599,7 +1647,8 @@ namespace Barotrauma
if (locationsDiscovered.Any())
{
var discoveryElement = new XElement("discovered");
var discoveryElement = new XElement("discovered",
new XAttribute("trackedvisitedemptylocations", true));
foreach (Location location in locationsDiscovered)
{
int index = Locations.IndexOf(location);
@@ -1609,10 +1658,10 @@ namespace Barotrauma
mapElement.Add(discoveryElement);
}
if (outpostsVisited.Any())
if (locationsVisited.Any())
{
var visitElement = new XElement("visited");
foreach (Location location in outpostsVisited)
foreach (Location location in locationsVisited)
{
int index = Locations.IndexOf(location);
var locationElement = new XElement("location", new XAttribute("i", index));