Faction Test 100.4.0.0
This commit is contained in:
@@ -39,7 +39,8 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public readonly NamedEvent<LocationChangeInfo> OnLocationChanged = new NamedEvent<LocationChangeInfo>();
|
||||
|
||||
public Location EndLocation { get; private set; }
|
||||
private List<Location> endLocations = new List<Location>();
|
||||
public IReadOnlyList<Location> EndLocations { get { return endLocations; } }
|
||||
|
||||
public Location StartLocation { get; private set; }
|
||||
|
||||
@@ -68,10 +69,15 @@ 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>();
|
||||
|
||||
public List<LocationConnection> Connections { get; private set; }
|
||||
|
||||
public Radiation Radiation;
|
||||
|
||||
private bool wasLocationDiscoveryOrderTracked = true;
|
||||
|
||||
public Map(CampaignSettings settings)
|
||||
{
|
||||
generationParams = MapGenerationParams.Instance;
|
||||
@@ -112,7 +118,7 @@ namespace Barotrauma
|
||||
Locations.Add(null);
|
||||
}
|
||||
lairsFound |= subElement.GetAttributeString("type", "").Equals("lair", StringComparison.OrdinalIgnoreCase);
|
||||
Locations[i] = new Location(subElement);
|
||||
Locations[i] = new Location(campaign, subElement);
|
||||
break;
|
||||
case "radiation":
|
||||
Radiation = new Radiation(this, generationParams.RadiationParams, subElement)
|
||||
@@ -122,11 +128,6 @@ namespace Barotrauma
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.Diagnostics.Debug.Assert(!Locations.Contains(null));
|
||||
for (int i = 0; i < Locations.Count; i++)
|
||||
{
|
||||
Locations[i].Reputation ??= new Reputation(campaign.CampaignMetadata, Locations[i], $"location.{i}".ToIdentifier(), -100, 100, Rand.Range(-10, 11, Rand.RandSync.ServerAndClient));
|
||||
}
|
||||
|
||||
List<XElement> connectionElements = new List<XElement>();
|
||||
foreach (var subElement in element.Elements())
|
||||
@@ -182,23 +183,73 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
int endLocationindex = element.GetAttributeInt("endlocation", -1);
|
||||
if (endLocationindex > 0 && endLocationindex < Locations.Count)
|
||||
|
||||
if (element.GetAttribute("endlocation") != null)
|
||||
{
|
||||
EndLocation = Locations[endLocationindex];
|
||||
//backwards compatibility
|
||||
int endLocationIndex = element.GetAttributeInt("endlocation", -1);
|
||||
if (endLocationIndex > 0 && endLocationIndex < Locations.Count)
|
||||
{
|
||||
endLocations.Add(Locations[endLocationIndex]);
|
||||
Locations[endLocationIndex].LevelData.ReassignGenerationParams(Seed);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.AddWarning($"Error while loading the map. End location index out of bounds (index: {endLocationIndex}, location count: {Locations.Count}).");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.AddWarning($"Error while loading the map. End location index out of bounds (index: {endLocationindex}, location count: {Locations.Count}).");
|
||||
foreach (Location location in Locations)
|
||||
int[] endLocationindices = element.GetAttributeIntArray("endlocations", Array.Empty<int>());
|
||||
foreach (int endLocationIndex in endLocationindices)
|
||||
{
|
||||
if (EndLocation == null || location.MapPosition.X > EndLocation.MapPosition.X)
|
||||
if (endLocationIndex > 0 && endLocationIndex < Locations.Count)
|
||||
{
|
||||
EndLocation = location;
|
||||
endLocations.Add(Locations[endLocationIndex]);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.AddWarning($"Error while loading the map. End location index out of bounds (index: {endLocationIndex}, location count: {Locations.Count}).");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!endLocations.Any())
|
||||
{
|
||||
DebugConsole.AddWarning($"Error while loading the map. No end location(s) found. Choosing the rightmost location as the end location...");
|
||||
Location endLocation = null;
|
||||
foreach (Location location in Locations)
|
||||
{
|
||||
if (endLocation == null || location.MapPosition.X > endLocation.MapPosition.X)
|
||||
{
|
||||
endLocation = location;
|
||||
}
|
||||
}
|
||||
endLocations.Add(endLocation);
|
||||
}
|
||||
|
||||
System.Diagnostics.Debug.Assert(endLocations.First().Biome != null, "End location biome was null.");
|
||||
System.Diagnostics.Debug.Assert(endLocations.First().Biome.IsEndBiome, "The biome of the end location isn't the end biome.");
|
||||
|
||||
//backwards compatibility (or support for loading maps created with mods that modify the end biome setup):
|
||||
//if there's too few end locations, create more
|
||||
int missingOutpostCount = endLocations.First().Biome.EndBiomeLocationCount - endLocations.Count;
|
||||
|
||||
Location firstEndLocation = EndLocations[0];
|
||||
for (int i = 0; i < missingOutpostCount; i++)
|
||||
{
|
||||
Vector2 mapPos = new Vector2(
|
||||
MathHelper.Lerp(firstEndLocation.MapPosition.X, Width, MathHelper.Lerp(0.2f, 0.8f, i / (float)missingOutpostCount)),
|
||||
Height * MathHelper.Lerp(0.2f, 1.0f, (float)rand.NextDouble()));
|
||||
var newEndLocation = new Location(mapPos, generationParams.DifficultyZones, rand, forceLocationType: firstEndLocation.Type, existingLocations: Locations)
|
||||
{
|
||||
Biome = endLocations.First().Biome
|
||||
};
|
||||
newEndLocation.LevelData = new LevelData(newEndLocation, difficulty: 100.0f);
|
||||
Locations.Add(newEndLocation);
|
||||
endLocations.Add(newEndLocation);
|
||||
}
|
||||
|
||||
//backwards compatibility: if the map contained the now-removed lairs and has no hunting grounds, create some hunting grounds
|
||||
if (lairsFound && !Connections.Any(c => c.LevelData.HasHuntingGrounds))
|
||||
{
|
||||
@@ -209,6 +260,17 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var endLocation in EndLocations)
|
||||
{
|
||||
if (endLocation.Type?.ForceLocationName != null &&
|
||||
!endLocation.Type.ForceLocationName.IsNullOrEmpty())
|
||||
{
|
||||
endLocation.ForceName(endLocation.Type.ForceLocationName.Value);
|
||||
}
|
||||
}
|
||||
|
||||
AssignEndLocationLevelData();
|
||||
|
||||
//backwards compatibility: if locations go out of bounds (map saved with different generation parameters before width/height were included in the xml)
|
||||
float maxX = Locations.Select(l => l.MapPosition.X).Max();
|
||||
if (maxX > Width) { Width = (int)(maxX + 10); }
|
||||
@@ -226,18 +288,13 @@ namespace Barotrauma
|
||||
Seed = seed;
|
||||
Rand.SetSyncedSeed(ToolBox.StringToInt(Seed));
|
||||
|
||||
Generate(campaign.Settings);
|
||||
Generate(campaign);
|
||||
|
||||
if (Locations.Count == 0)
|
||||
{
|
||||
throw new Exception($"Generating a campaign map failed (no locations created). Width: {Width}, height: {Height}");
|
||||
}
|
||||
|
||||
for (int i = 0; i < Locations.Count; i++)
|
||||
{
|
||||
Locations[i].Reputation ??= new Reputation(campaign.CampaignMetadata, Locations[i], $"location.{i}".ToIdentifier(), -100, 100, Rand.Range(-10, 11, Rand.RandSync.ServerAndClient));
|
||||
}
|
||||
|
||||
foreach (Location location in Locations)
|
||||
{
|
||||
if (location.Type.Identifier != "outpost") { continue; }
|
||||
@@ -258,6 +315,20 @@ namespace Barotrauma
|
||||
if (CurrentLocation == null || location.MapPosition.X < CurrentLocation.MapPosition.X)
|
||||
{
|
||||
CurrentLocation = StartLocation = furthestDiscoveredLocation = location;
|
||||
StartLocation.SecondaryFaction = null;
|
||||
var startOutpostFaction = campaign?.Factions.FirstOrDefault(f => f.Prefab.StartOutpost);
|
||||
if (startOutpostFaction != null)
|
||||
{
|
||||
StartLocation.Faction = startOutpostFaction;
|
||||
foreach (var connection in StartLocation.Connections)
|
||||
{
|
||||
var otherLocation = connection.OtherLocation(StartLocation);
|
||||
if (otherLocation.HasOutpost() && otherLocation.Type.OutpostTeam == CharacterTeamType.FriendlyNPC)
|
||||
{
|
||||
otherLocation.Faction = startOutpostFaction;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,7 +353,12 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
CurrentLocation.Discover(true);
|
||||
if (campaign.IsSinglePlayer && campaign.Settings.TutorialEnabled && LocationType.Prefabs.TryGet("tutorialoutpost", out var tutorialOutpost))
|
||||
{
|
||||
CurrentLocation.ChangeType(campaign, tutorialOutpost);
|
||||
}
|
||||
Discover(CurrentLocation);
|
||||
Visit(CurrentLocation);
|
||||
CurrentLocation.CreateStores();
|
||||
|
||||
foreach (var location in Locations)
|
||||
@@ -297,7 +373,7 @@ namespace Barotrauma
|
||||
|
||||
#region Generation
|
||||
|
||||
private void Generate(CampaignSettings settings)
|
||||
private void Generate(CampaignMode campaign)
|
||||
{
|
||||
Connections.Clear();
|
||||
Locations.Clear();
|
||||
@@ -515,12 +591,14 @@ namespace Barotrauma
|
||||
connectionsBetweenZones[zone1].Add(connection);
|
||||
}
|
||||
}
|
||||
else if (connectionsBetweenZones[zone1].Count() < generationParams.GateCount[zone1])
|
||||
else if (connectionsBetweenZones[zone1].Count() < generationParams.GateCount[zone1] &&
|
||||
connectionsBetweenZones[zone1].None(c => c.Locations.Contains(connection.Locations[0]) || c.Locations.Contains(connection.Locations[1])))
|
||||
{
|
||||
connectionsBetweenZones[zone1].Add(connection);
|
||||
}
|
||||
}
|
||||
|
||||
var gateFactions = campaign.Factions.Where(f => f.Prefab.ControlledOutpostPercentage > 0).OrderBy(f => f.Prefab.Identifier).ToList();
|
||||
for (int i = Connections.Count - 1; i >= 0; i--)
|
||||
{
|
||||
int zone1 = GetZoneIndex(Connections[i].Locations[0].MapPosition.X);
|
||||
@@ -528,9 +606,9 @@ namespace Barotrauma
|
||||
if (zone1 == zone2) { continue; }
|
||||
if (zone1 == generationParams.DifficultyZones || zone2 == generationParams.DifficultyZones) { continue; }
|
||||
|
||||
if (generationParams.GateCount[Math.Min(zone1, zone2)] == 0) { continue; }
|
||||
|
||||
if (!connectionsBetweenZones[Math.Min(zone1, zone2)].Contains(Connections[i]))
|
||||
int leftZone = Math.Min(zone1, zone2);
|
||||
if (generationParams.GateCount[leftZone] == 0) { continue; }
|
||||
if (!connectionsBetweenZones[leftZone].Contains(Connections[i]))
|
||||
{
|
||||
Connections.RemoveAt(i);
|
||||
}
|
||||
@@ -542,10 +620,17 @@ namespace Barotrauma
|
||||
Connections[i].Locations[1];
|
||||
if (!leftMostLocation.Type.HasOutpost || leftMostLocation.Type.Identifier == "abandoned")
|
||||
{
|
||||
leftMostLocation.ChangeType(LocationType.Prefabs.OrderBy(lt => lt.Identifier).First(lt => lt.HasOutpost && lt.Identifier != "abandoned"));
|
||||
leftMostLocation.ChangeType(
|
||||
campaign,
|
||||
LocationType.Prefabs.OrderBy(lt => lt.Identifier).First(lt => lt.HasOutpost && lt.Identifier != "abandoned"));
|
||||
}
|
||||
leftMostLocation.IsGateBetweenBiomes = true;
|
||||
Connections[i].Locked = true;
|
||||
|
||||
if (leftMostLocation.Type.HasOutpost && campaign != null && gateFactions.Any())
|
||||
{
|
||||
leftMostLocation.Faction = gateFactions[connectionsBetweenZones[leftZone].IndexOf(Connections[i]) % gateFactions.Count];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,20 +698,26 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
CreateEndLocation();
|
||||
|
||||
foreach (Location location in Locations)
|
||||
{
|
||||
location.LevelData = new LevelData(location, CalculateDifficulty(location.MapPosition.X, location.Biome));
|
||||
if (location.Type.HasOutpost && campaign != null && location.Type.OutpostTeam == CharacterTeamType.FriendlyNPC)
|
||||
{
|
||||
location.Faction ??= campaign.GetRandomFaction(Rand.RandSync.ServerAndClient);
|
||||
location.SecondaryFaction ??= campaign.GetRandomSecondaryFaction(Rand.RandSync.ServerAndClient);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (LocationConnection connection in Connections)
|
||||
{
|
||||
connection.LevelData = new LevelData(connection);
|
||||
}
|
||||
|
||||
CreateEndLocation(campaign);
|
||||
|
||||
float CalculateDifficulty(float mapPosition, Biome biome)
|
||||
{
|
||||
float settingsFactor = settings.LevelDifficultyMultiplier;
|
||||
float settingsFactor = campaign.Settings.LevelDifficultyMultiplier;
|
||||
float minDifficulty = 0;
|
||||
float maxDifficulty = 100;
|
||||
float difficulty = mapPosition / Width * 100;
|
||||
@@ -695,18 +786,18 @@ namespace Barotrauma
|
||||
System.Diagnostics.Debug.Assert(Connections.All(c => c.Biome != null));
|
||||
}
|
||||
|
||||
private void CreateEndLocation()
|
||||
private void CreateEndLocation(CampaignMode campaign)
|
||||
{
|
||||
float zoneWidth = Width / generationParams.DifficultyZones;
|
||||
Vector2 endPos = new Vector2(Width - zoneWidth / 2, Height / 2);
|
||||
Vector2 endPos = new Vector2(Width - zoneWidth * 0.7f, Height / 2);
|
||||
float closestDist = float.MaxValue;
|
||||
EndLocation = Locations.First();
|
||||
var endLocation = Locations.First();
|
||||
foreach (Location location in Locations)
|
||||
{
|
||||
float dist = Vector2.DistanceSquared(endPos, location.MapPosition);
|
||||
if (location.Biome.IsEndBiome && dist < closestDist)
|
||||
{
|
||||
EndLocation = location;
|
||||
endLocation = location;
|
||||
closestDist = dist;
|
||||
}
|
||||
}
|
||||
@@ -720,17 +811,39 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (EndLocation == null || previousToEndLocation == null) { return; }
|
||||
if (endLocation == null || previousToEndLocation == null) { return; }
|
||||
|
||||
endLocations = new List<Location>() { endLocation };
|
||||
if (endLocation.Biome.EndBiomeLocationCount > 1)
|
||||
{
|
||||
FindConnectedEndLocations(endLocation);
|
||||
|
||||
void FindConnectedEndLocations(Location currLocation)
|
||||
{
|
||||
if (endLocations.Count >= endLocation.Biome.EndBiomeLocationCount) { return; }
|
||||
foreach (var connection in currLocation.Connections)
|
||||
{
|
||||
if (connection.Biome != endLocation.Biome) { continue; }
|
||||
var otherLocation = connection.OtherLocation(currLocation);
|
||||
if (otherLocation != null && !endLocations.Contains(otherLocation))
|
||||
{
|
||||
if (endLocations.Count >= endLocation.Biome.EndBiomeLocationCount) { return; }
|
||||
endLocations.Add(otherLocation);
|
||||
FindConnectedEndLocations(otherLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (LocationType.Prefabs.TryGet("none", out LocationType locationType))
|
||||
{
|
||||
previousToEndLocation.ChangeType(locationType);
|
||||
previousToEndLocation.ChangeType(campaign, locationType);
|
||||
}
|
||||
|
||||
//remove all locations from the end biome except the end location
|
||||
for (int i = Locations.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (Locations[i].Biome.IsEndBiome && Locations[i] != EndLocation)
|
||||
if (Locations[i].Biome.IsEndBiome)
|
||||
{
|
||||
for (int j = Locations[i].Connections.Count - 1; j >= 0; j--)
|
||||
{
|
||||
@@ -741,7 +854,10 @@ namespace Barotrauma
|
||||
otherLocation?.Connections.Remove(connection);
|
||||
Connections.Remove(connection);
|
||||
}
|
||||
Locations.RemoveAt(i);
|
||||
if (!endLocations.Contains(Locations[i]))
|
||||
{
|
||||
Locations.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -758,22 +874,38 @@ namespace Barotrauma
|
||||
}
|
||||
var newConnection = new LocationConnection(previousToEndLocation, connectTo)
|
||||
{
|
||||
Biome = EndLocation.Biome,
|
||||
Biome = endLocation.Biome,
|
||||
Difficulty = 100.0f
|
||||
};
|
||||
newConnection.LevelData = new LevelData(newConnection);
|
||||
Connections.Add(newConnection);
|
||||
previousToEndLocation.Connections.Add(newConnection);
|
||||
connectTo.Connections.Add(newConnection);
|
||||
}
|
||||
|
||||
var endConnection = new LocationConnection(previousToEndLocation, EndLocation)
|
||||
var endConnection = new LocationConnection(previousToEndLocation, endLocation)
|
||||
{
|
||||
Biome = EndLocation.Biome,
|
||||
Biome = endLocation.Biome,
|
||||
Difficulty = 100.0f
|
||||
};
|
||||
endConnection.LevelData = new LevelData(endConnection);
|
||||
Connections.Add(endConnection);
|
||||
previousToEndLocation.Connections.Add(endConnection);
|
||||
EndLocation.Connections.Add(endConnection);
|
||||
endLocation.Connections.Add(endConnection);
|
||||
|
||||
AssignEndLocationLevelData();
|
||||
}
|
||||
|
||||
private void AssignEndLocationLevelData()
|
||||
{
|
||||
for (int i = 0; i < endLocations.Count; i++)
|
||||
{
|
||||
var outpostParams = OutpostGenerationParams.OutpostParams.FirstOrDefault(p => p.ForceToEndLocationIndex == i);
|
||||
if (outpostParams != null)
|
||||
{
|
||||
endLocations[i].LevelData.ForceOutpostGenerationParams = outpostParams;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ExpandBiomes(List<LocationConnection> seeds)
|
||||
@@ -807,20 +939,44 @@ namespace Barotrauma
|
||||
{
|
||||
if (SelectedConnection == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Could not move to the next location (no connection selected).\n"+Environment.StackTrace.CleanupStackTrace());
|
||||
return;
|
||||
if (!endLocations.Contains(CurrentLocation))
|
||||
{
|
||||
DebugConsole.ThrowError("Could not move to the next location (no connection selected).\n" + Environment.StackTrace.CleanupStackTrace());
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (SelectedLocation == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Could not move to the next location (no location selected).\n" + Environment.StackTrace.CleanupStackTrace());
|
||||
return;
|
||||
if (endLocations.Contains(CurrentLocation))
|
||||
{
|
||||
int currentEndLocationIndex = endLocations.IndexOf(CurrentLocation);
|
||||
if (currentEndLocationIndex < endLocations.Count - 1)
|
||||
{
|
||||
//more end locations to go, progress to the next one
|
||||
SelectedLocation = endLocations[currentEndLocationIndex + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
//at the last end location, end of campaign
|
||||
SelectedLocation = StartLocation;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError("Could not move to the next location (no connection selected).\n" + Environment.StackTrace.CleanupStackTrace());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Location prevLocation = CurrentLocation;
|
||||
SelectedConnection.Passed = true;
|
||||
if (SelectedConnection != null)
|
||||
{
|
||||
SelectedConnection.Passed = true;
|
||||
}
|
||||
|
||||
CurrentLocation = SelectedLocation;
|
||||
CurrentLocation.Discover();
|
||||
Discover(CurrentLocation);
|
||||
Visit(CurrentLocation);
|
||||
SelectedLocation = null;
|
||||
|
||||
CurrentLocation.CreateStores();
|
||||
@@ -851,7 +1007,7 @@ namespace Barotrauma
|
||||
|
||||
Location prevLocation = CurrentLocation;
|
||||
CurrentLocation = Locations[index];
|
||||
CurrentLocation.Discover();
|
||||
Discover(CurrentLocation);
|
||||
|
||||
CurrentLocation.CreateStores();
|
||||
if (prevLocation != CurrentLocation)
|
||||
@@ -966,7 +1122,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void ProgressWorld(CampaignMode.TransitionType transitionType, float roundDuration)
|
||||
public void ProgressWorld(CampaignMode campaign, CampaignMode.TransitionType transitionType, float roundDuration)
|
||||
{
|
||||
//one step per 10 minutes of play time
|
||||
int steps = (int)Math.Floor(roundDuration / (60.0f * 10.0f));
|
||||
@@ -979,13 +1135,23 @@ namespace Barotrauma
|
||||
steps = Math.Min(steps, 5);
|
||||
for (int i = 0; i < steps; i++)
|
||||
{
|
||||
ProgressWorld();
|
||||
ProgressWorld(campaign);
|
||||
}
|
||||
|
||||
// always update specials every step
|
||||
for (int i = 0; i < Math.Max(1, steps); i++)
|
||||
{
|
||||
foreach (Location location in Locations)
|
||||
{
|
||||
if (!location.Discovered) { continue; }
|
||||
location.UpdateSpecials();
|
||||
}
|
||||
}
|
||||
|
||||
Radiation?.OnStep(steps);
|
||||
}
|
||||
|
||||
private void ProgressWorld()
|
||||
private void ProgressWorld(CampaignMode campaign)
|
||||
{
|
||||
foreach (Location location in Locations)
|
||||
{
|
||||
@@ -1013,14 +1179,14 @@ namespace Barotrauma
|
||||
|
||||
if (location == CurrentLocation || location == SelectedLocation || location.IsGateBetweenBiomes) { continue; }
|
||||
|
||||
if (!ProgressLocationTypeChanges(location) && location.Discovered)
|
||||
if (!ProgressLocationTypeChanges(campaign, location) && location.Discovered)
|
||||
{
|
||||
location.UpdateStores();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ProgressLocationTypeChanges(Location location)
|
||||
private bool ProgressLocationTypeChanges(CampaignMode campaign, Location location)
|
||||
{
|
||||
location.TimeSinceLastTypeChange++;
|
||||
location.LocationTypeChangeCooldown--;
|
||||
@@ -1040,7 +1206,7 @@ namespace Barotrauma
|
||||
location.PendingLocationTypeChange.Value.parentMission);
|
||||
if (location.PendingLocationTypeChange.Value.delay <= 0)
|
||||
{
|
||||
return ChangeLocationType(location, location.PendingLocationTypeChange.Value.typeChange);
|
||||
return ChangeLocationType(campaign, location, location.PendingLocationTypeChange.Value.typeChange);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1073,7 +1239,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
return ChangeLocationType(location, selectedTypeChange);
|
||||
return ChangeLocationType(campaign, location, selectedTypeChange);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1143,7 +1309,7 @@ namespace Barotrauma
|
||||
return distance;
|
||||
}
|
||||
|
||||
private bool ChangeLocationType(Location location, LocationTypeChange change)
|
||||
private bool ChangeLocationType(CampaignMode campaign, Location location, LocationTypeChange change)
|
||||
{
|
||||
string prevName = location.Name;
|
||||
|
||||
@@ -1158,7 +1324,7 @@ namespace Barotrauma
|
||||
{
|
||||
location.ClearMissions();
|
||||
}
|
||||
location.ChangeType(newType);
|
||||
location.ChangeType(campaign, newType);
|
||||
ChangeLocationTypeProjSpecific(location, prevName, change);
|
||||
foreach (var requirement in change.Requirements)
|
||||
{
|
||||
@@ -1174,13 +1340,58 @@ namespace Barotrauma
|
||||
|
||||
partial void ClearAnimQueue();
|
||||
|
||||
public void Discover(Location location, bool checkTalents = true)
|
||||
{
|
||||
if (location is null) { return; }
|
||||
if (locationsDiscovered.Contains(location)) { return; }
|
||||
locationsDiscovered.Add(location);
|
||||
if (checkTalents)
|
||||
{
|
||||
GameSession.GetSessionCrewCharacters(CharacterType.Both).ForEach(c => c.CheckTalents(AbilityEffectType.OnLocationDiscovered, new Location.AbilityLocation(location)));
|
||||
}
|
||||
}
|
||||
|
||||
public void Visit(Location location)
|
||||
{
|
||||
if (location is null) { return; }
|
||||
if (!location.HasOutpost()) { return; }
|
||||
if (outpostsVisited.Contains(location)) { return; }
|
||||
outpostsVisited.Add(location);
|
||||
}
|
||||
|
||||
public void ClearLocationHistory()
|
||||
{
|
||||
locationsDiscovered.Clear();
|
||||
outpostsVisited.Clear();
|
||||
}
|
||||
|
||||
public int? GetDiscoveryIndex(Location location)
|
||||
{
|
||||
if (!wasLocationDiscoveryOrderTracked) { return null; }
|
||||
if (location is null) { return -1; }
|
||||
return locationsDiscovered.IndexOf(location);
|
||||
}
|
||||
|
||||
public int? GetVisitIndex(Location location)
|
||||
{
|
||||
if (!wasLocationDiscoveryOrderTracked) { return null; }
|
||||
if (location is null) { return -1; }
|
||||
return outpostsVisited.IndexOf(location);
|
||||
}
|
||||
|
||||
public bool IsDiscovered(Location location)
|
||||
{
|
||||
if (location is null) { return false; }
|
||||
return locationsDiscovered.Contains(location);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load a previously saved map from an xml element
|
||||
/// </summary>
|
||||
public static Map Load(CampaignMode campaign, XElement element)
|
||||
{
|
||||
Map map = new Map(campaign, element);
|
||||
map.LoadState(element, false);
|
||||
map.LoadState(campaign, element, false);
|
||||
#if CLIENT
|
||||
map.DrawOffset = -map.CurrentLocation.MapPosition;
|
||||
#endif
|
||||
@@ -1190,17 +1401,18 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Load the state of an existing map from xml (current state of locations, where the crew is now, etc).
|
||||
/// </summary>
|
||||
public void LoadState(XElement element, bool showNotifications)
|
||||
public void LoadState(CampaignMode campaign, XElement element, bool showNotifications)
|
||||
{
|
||||
ClearAnimQueue();
|
||||
SetLocation(element.GetAttributeInt("currentlocation", 0));
|
||||
|
||||
if (!Version.TryParse(element.GetAttributeString("version", ""), out _))
|
||||
if (!Version.TryParse(element.GetAttributeString("version", ""), out Version version))
|
||||
{
|
||||
DebugConsole.ThrowError("Incompatible map save file, loading the game failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
ClearLocationHistory();
|
||||
foreach (var subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
@@ -1216,26 +1428,19 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
location.LoadLocationTypeChange(subElement);
|
||||
|
||||
// Backwards compatibility
|
||||
if (subElement.GetAttributeBool("discovered", false))
|
||||
{
|
||||
location.Discover(checkTalents: false);
|
||||
}
|
||||
if (location.Discovered)
|
||||
{
|
||||
#if CLIENT
|
||||
RemoveFogOfWar(location);
|
||||
#endif
|
||||
if (furthestDiscoveredLocation == null || location.MapPosition.X > furthestDiscoveredLocation.MapPosition.X)
|
||||
{
|
||||
furthestDiscoveredLocation = location;
|
||||
}
|
||||
Discover(location);
|
||||
wasLocationDiscoveryOrderTracked = false;
|
||||
}
|
||||
|
||||
Identifier locationType = subElement.GetAttributeIdentifier("type", Identifier.Empty);
|
||||
string prevLocationName = location.Name;
|
||||
LocationType prevLocationType = location.Type;
|
||||
LocationType newLocationType = LocationType.Prefabs.Find(lt => lt.Identifier == locationType) ?? LocationType.Prefabs.First();
|
||||
location.ChangeType(newLocationType);
|
||||
location.ChangeType(campaign, newLocationType);
|
||||
if (showNotifications && prevLocationType != location.Type)
|
||||
{
|
||||
var change = prevLocationType.CanChangeTo.Find(c => c.ChangeToType == location.Type.Identifier);
|
||||
@@ -1246,6 +1451,12 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
var factionIdentifier = subElement.GetAttributeIdentifier("faction", Identifier.Empty);
|
||||
location.Faction = factionIdentifier.IsEmpty ? null : campaign.Factions.Find(f => f.Prefab.Identifier == factionIdentifier);
|
||||
|
||||
var secondaryFactionIdentifier = subElement.GetAttributeIdentifier("secondaryfaction", Identifier.Empty);
|
||||
location.SecondaryFaction = secondaryFactionIdentifier.IsEmpty ? null : campaign.Factions.Find(f => f.Prefab.Identifier == secondaryFactionIdentifier);
|
||||
|
||||
location.LoadStores(subElement);
|
||||
location.LoadMissions(subElement);
|
||||
|
||||
@@ -1258,6 +1469,36 @@ namespace Barotrauma
|
||||
case "radiation":
|
||||
Radiation = new Radiation(this, generationParams.RadiationParams, subElement);
|
||||
break;
|
||||
case "discovered":
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1266,6 +1507,27 @@ 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))
|
||||
{
|
||||
Rand.SetSyncedSeed(ToolBox.StringToInt(Seed));
|
||||
foreach (Location location in Locations)
|
||||
{
|
||||
if (location.Type.HasOutpost && campaign != null && location.Type.OutpostTeam == CharacterTeamType.FriendlyNPC)
|
||||
{
|
||||
location.Faction = campaign.GetRandomFaction(Rand.RandSync.ServerAndClient);
|
||||
if (location != StartLocation)
|
||||
{
|
||||
location.SecondaryFaction = campaign.GetRandomSecondaryFaction(Rand.RandSync.ServerAndClient);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int currentLocationConnection = element.GetAttributeInt("currentlocationconnection", -1);
|
||||
if (currentLocationConnection >= 0)
|
||||
{
|
||||
@@ -1304,7 +1566,7 @@ namespace Barotrauma
|
||||
mapElement.Add(new XAttribute("height", Height));
|
||||
mapElement.Add(new XAttribute("selectedlocation", SelectedLocationIndex));
|
||||
mapElement.Add(new XAttribute("startlocation", Locations.IndexOf(StartLocation)));
|
||||
mapElement.Add(new XAttribute("endlocation", Locations.IndexOf(EndLocation)));
|
||||
mapElement.Add(new XAttribute("endlocations", string.Join(',', EndLocations.Select(e => Locations.IndexOf(e)))));
|
||||
mapElement.Add(new XAttribute("seed", Seed));
|
||||
|
||||
for (int i = 0; i < Locations.Count; i++)
|
||||
@@ -1333,6 +1595,30 @@ namespace Barotrauma
|
||||
mapElement.Add(Radiation.Save());
|
||||
}
|
||||
|
||||
if (locationsDiscovered.Any())
|
||||
{
|
||||
var discoveryElement = new XElement("discovered");
|
||||
foreach (Location location in locationsDiscovered)
|
||||
{
|
||||
int index = Locations.IndexOf(location);
|
||||
var locationElement = new XElement("location", new XAttribute("i", index));
|
||||
discoveryElement.Add(locationElement);
|
||||
}
|
||||
mapElement.Add(discoveryElement);
|
||||
}
|
||||
|
||||
if (outpostsVisited.Any())
|
||||
{
|
||||
var visitElement = new XElement("visited");
|
||||
foreach (Location location in outpostsVisited)
|
||||
{
|
||||
int index = Locations.IndexOf(location);
|
||||
var locationElement = new XElement("location", new XAttribute("i", index));
|
||||
visitElement.Add(locationElement);
|
||||
}
|
||||
mapElement.Add(visitElement);
|
||||
}
|
||||
|
||||
element.Add(mapElement);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user