v1.6.17.0 (Unto the Breach update)

This commit is contained in:
Regalis11
2024-10-22 17:29:04 +03:00
parent e74b3cdb17
commit 6e6c17e100
417 changed files with 17166 additions and 5870 deletions
@@ -103,6 +103,9 @@ namespace Barotrauma
get { return map; }
}
/// <summary>
/// Which missions have been selected for the current round?
/// </summary>
public override IEnumerable<Mission> Missions
{
get
@@ -112,10 +115,13 @@ namespace Barotrauma
{
if (Map.CurrentLocation != null)
{
var currentLevelData = Level.Loaded?.LevelData ?? GameMain.GameSession?.LevelData;
foreach (Mission mission in map.CurrentLocation.SelectedMissions)
{
if (mission.Locations[0] == mission.Locations[1] ||
mission.Locations.Contains(Map.SelectedLocation))
if (//mission takes place in current location
mission.Locations[0] == mission.Locations[1] ||
//mission takes place between two locations, and we're in the level between those locations
mission.Locations.Contains(Map.SelectedLocation) && currentLevelData is { Type: LevelData.LevelType.LocationConnection })
{
yield return mission;
}
@@ -170,6 +176,7 @@ namespace Barotrauma
protected CampaignMode(GameModePreset preset, CampaignSettings settings)
: base(preset)
{
Settings = settings;
Bank = new Wallet(Option<Character>.None())
{
Balance = settings.InitialMoney
@@ -246,7 +253,7 @@ namespace Barotrauma
sub != leavingSub &&
!leavingSub.DockedTo.Contains(sub) &&
sub.Info.Type == SubmarineType.Player && sub.TeamID == CharacterTeamType.Team1 && // pirate subs are currently tagged as player subs as well
sub != GameMain.NetworkMember?.RespawnManager?.RespawnShuttle &&
!sub.IsRespawnShuttle &&
(sub.AtEndExit != leavingSub.AtEndExit || sub.AtStartExit != leavingSub.AtStartExit));
}
@@ -401,9 +408,9 @@ namespace Barotrauma
currentLocation.DeselectMission(mission);
}
}
if (levelData.HasBeaconStation && !levelData.IsBeaconActive && Missions.None(m => m.Prefab.Type == MissionType.Beacon))
if (levelData.HasBeaconStation && !levelData.IsBeaconActive && Missions.None(m => m.Prefab.Type == Tags.MissionTypeBeacon))
{
var beaconMissionPrefabs = MissionPrefab.Prefabs.Where(m => m.IsSideObjective && m.Type == MissionType.Beacon);
var beaconMissionPrefabs = MissionPrefab.Prefabs.Where(m => m.IsSideObjective && m.Type == Tags.MissionTypeBeacon);
if (beaconMissionPrefabs.Any())
{
var filteredMissions = beaconMissionPrefabs.Where(m => levelData.Difficulty >= m.MinLevelDifficulty && levelData.Difficulty <= m.MaxLevelDifficulty);
@@ -490,7 +497,7 @@ namespace Barotrauma
if (missionPrefabs.Any())
{
var missionPrefab = ToolBox.SelectWeightedRandom(missionPrefabs, p => p.Commonness, rand);
if (missionPrefab.Type == MissionType.Pirate && Missions.Any(m => m.Prefab.Type == MissionType.Pirate))
if (missionPrefab.Type == Tags.MissionTypePirate && Missions.Any(m => m.Prefab.Type == Tags.MissionTypePirate))
{
continue;
}
@@ -769,7 +776,7 @@ namespace Barotrauma
{
foreach (var dockedSub in Level.Loaded.StartOutpost.DockedTo)
{
if (dockedSub == GameMain.NetworkMember?.RespawnManager?.RespawnShuttle || dockedSub.TeamID != submarineTeam) { continue; }
if (dockedSub.IsRespawnShuttle || dockedSub.TeamID != submarineTeam) { continue; }
return dockedSub.DockedTo.Contains(Submarine.MainSub) ? Submarine.MainSub : dockedSub;
}
}
@@ -809,7 +816,7 @@ namespace Barotrauma
{
foreach (var dockedSub in Level.Loaded.EndOutpost.DockedTo)
{
if (dockedSub == GameMain.NetworkMember?.RespawnManager?.RespawnShuttle || dockedSub.TeamID != submarineTeam) { continue; }
if (dockedSub.IsRespawnShuttle || dockedSub.TeamID != submarineTeam) { continue; }
return dockedSub.DockedTo.Contains(Submarine.MainSub) ? Submarine.MainSub : dockedSub;
}
}
@@ -1287,7 +1294,7 @@ namespace Barotrauma
return Faction.GetPlayerAffiliationStatus(faction);
}
public abstract void Save(XElement element);
public abstract void Save(XElement element, bool isSavingOnLoading);
protected void LoadStats(XElement element)
{
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
namespace Barotrauma
{
@@ -7,6 +6,6 @@ namespace Barotrauma
{
public CoOpMode(GameModePreset preset, IEnumerable<MissionPrefab> missionPrefabs) : base(preset, ValidateMissionPrefabs(missionPrefabs, MissionPrefab.CoOpMissionClasses)) { }
public CoOpMode(GameModePreset preset, MissionType missionType, string seed) : base(preset, ValidateMissionType(missionType, MissionPrefab.CoOpMissionClasses), seed) { }
public CoOpMode(GameModePreset preset, IEnumerable<Identifier> missionTypes, string seed) : base(preset, ValidateMissionTypes(missionTypes, MissionPrefab.CoOpMissionClasses), seed) { }
}
}
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma
{
@@ -25,42 +26,37 @@ namespace Barotrauma
}
}
public MissionMode(GameModePreset preset, MissionType missionType, string seed)
public MissionMode(GameModePreset preset, IEnumerable<Identifier> missionTypes, string seed)
: base(preset)
{
Location[] locations = { GameMain.GameSession.StartLocation, GameMain.GameSession.EndLocation };
var mission = Mission.LoadRandom(locations, seed, requireCorrectLocationType: false, missionType, difficultyLevel: GameMain.NetworkMember.ServerSettings.SelectedLevelDifficulty);
var mission = Mission.LoadRandom(locations, seed, requireCorrectLocationType: false, missionTypes, difficultyLevel: GameMain.NetworkMember.ServerSettings.SelectedLevelDifficulty);
if (mission != null)
{
missions.Add(mission);
}
}
protected static IEnumerable<MissionPrefab> ValidateMissionPrefabs(IEnumerable<MissionPrefab> missionPrefabs, Dictionary<MissionType, Type> missionClasses)
protected static IEnumerable<MissionPrefab> ValidateMissionPrefabs(IEnumerable<MissionPrefab> missionPrefabs, Dictionary<Identifier, Type> missionClasses)
{
foreach (MissionPrefab missionPrefab in missionPrefabs)
{
if (ValidateMissionType(missionPrefab.Type, missionClasses) != missionPrefab.Type)
if (!missionClasses.ContainsValue(missionPrefab.MissionClass))
{
throw new InvalidOperationException("Cannot start gamemode with mission type " + missionPrefab.Type);
throw new InvalidOperationException($"Cannot start gamemode with a {missionPrefab.MissionClass} mission.");
}
}
return missionPrefabs;
}
protected static MissionType ValidateMissionType(MissionType missionType, Dictionary<MissionType, Type> missionClasses)
/// <summary>
/// Returns the mission types that are valid for the given mission classes (e.g. all mission types suitable for the PvP mission classes).
/// </summary>
public static IEnumerable<Identifier> ValidateMissionTypes(IEnumerable<Identifier> missionTypes, Dictionary<Identifier, Type> missionClasses)
{
var missionTypes = (MissionType[])Enum.GetValues(typeof(MissionType));
for (int i = 0; i < missionTypes.Length; i++)
{
var type = missionTypes[i];
if (type == MissionType.None || type == MissionType.All) { continue; }
if (!missionClasses.ContainsKey(type))
{
missionType &= ~(type);
}
}
return missionType;
return missionTypes.Where(type =>
MissionPrefab.Prefabs.OrderBy(missionPrefab => missionPrefab.UintIdentifier)
.Any(missionPrefab => missionPrefab.Type == type && missionClasses.ContainsValue(missionPrefab.MissionClass)));
}
}
}
@@ -116,7 +116,6 @@ namespace Barotrauma
//only the server generates the map, the clients load it from a save file
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
{
campaign.Settings = settings;
campaign.map = new Map(campaign, mapSeed);
}
campaign.InitProjSpecific();
@@ -133,16 +132,24 @@ namespace Barotrauma
}
partial void InitProjSpecific();
public static string GetCharacterDataSavePath(string savePath)
public static string GetCharacterDataSavePath(string loadPath)
{
return Path.Combine(Path.GetDirectoryName(savePath), Path.GetFileNameWithoutExtension(savePath) + "_CharacterData.xml");
string directory = Path.GetDirectoryName(loadPath);
string fileName = Path.GetFileNameWithoutExtension(loadPath);
if (CampaignDataPath.IsBackupPath(loadPath, out uint backupIndex))
{
string trimmedFileName = Path.GetFileNameWithoutExtension(fileName);
return Path.Combine(directory, $"{trimmedFileName}_CharacterData{SaveUtil.BackupCharacterDataExtensionStart}{backupIndex}");
}
return Path.Combine(directory, $"{fileName}_CharacterData.xml");
}
public static string GetCharacterDataSavePath()
{
return GetCharacterDataSavePath(GameMain.GameSession.SavePath);
}
public static string GetCharacterDataPathForLoading()
=> GetCharacterDataSavePath(GameMain.GameSession.DataPath.LoadPath);
public static string GetCharacterDataPathForSaving()
=> GetCharacterDataSavePath(GameMain.GameSession.DataPath.SavePath);
/// <summary>
/// Loads the campaign from an XML element. Creates the map if it hasn't been created yet, otherwise updates the state of the map.
@@ -254,7 +261,7 @@ namespace Barotrauma
#if SERVER
characterData.Clear();
string characterDataPath = GetCharacterDataSavePath();
string characterDataPath = GetCharacterDataPathForLoading();
if (!File.Exists(characterDataPath))
{
DebugConsole.ThrowError($"Failed to load the character data for the campaign. Could not find the file \"{characterDataPath}\".");
@@ -1,50 +1,27 @@
using Barotrauma.Extensions;
using Barotrauma.Extensions;
using Barotrauma.Networking;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma
{
class PvPMode : MissionMode
partial class PvPMode : MissionMode
{
public PvPMode(GameModePreset preset, IEnumerable<MissionPrefab> missionPrefabs) : base(preset, ValidateMissionPrefabs(missionPrefabs, MissionPrefab.PvPMissionClasses)) { }
public PvPMode(GameModePreset preset, MissionType missionType, string seed) : base(preset, ValidateMissionType(missionType, MissionPrefab.PvPMissionClasses), seed) { }
public void AssignTeamIDs(IEnumerable<Client> clients)
public PvPMode(GameModePreset preset, IEnumerable<MissionPrefab> missionPrefabs) :
base(preset, ValidateMissionPrefabs(missionPrefabs, MissionPrefab.PvPMissionClasses))
{
int team1Count = 0, team2Count = 0;
//if a client has a preference, assign them to that team
List<Client> unassignedClients = new List<Client>(clients);
for (int i = 0; i < unassignedClients.Count; i++)
if (Missions.None())
{
if (unassignedClients[i].PreferredTeam == CharacterTeamType.Team1 ||
unassignedClients[i].PreferredTeam == CharacterTeamType.Team2)
{
assignTeam(unassignedClients[i], unassignedClients[i].PreferredTeam);
i--;
}
}
//assign the rest of the clients to the team that has the least players
while (unassignedClients.Any())
{
var randomClient = unassignedClients.GetRandom(Rand.RandSync.Unsynced);
assignTeam(randomClient, team1Count < team2Count ? CharacterTeamType.Team1 : CharacterTeamType.Team2);
throw new System.Exception($"Attempted to start {nameof(PvPMode)} without a mission.");
}
}
void assignTeam(Client client, CharacterTeamType team)
public PvPMode(GameModePreset preset, IEnumerable<Identifier> missionTypes, string seed) :
base(preset, ValidateMissionTypes(missionTypes, MissionPrefab.PvPMissionClasses), seed)
{
if (Missions.None())
{
client.TeamID = team;
unassignedClients.Remove(client);
if (team == CharacterTeamType.Team1)
{
team1Count++;
}
else
{
team2Count++;
}
throw new System.Exception($"Attempted to start {nameof(PvPMode)} without a mission.");
}
}
}
@@ -0,0 +1,19 @@
using System.Linq;
namespace Barotrauma
{
partial class TestGameMode : GameMode
{
public TestGameMode(GameModePreset preset) : base(preset)
{
foreach (JobPrefab jobPrefab in JobPrefab.Prefabs.OrderBy(p => p.Identifier))
{
for (int i = 0; i < jobPrefab.InitialCount; i++)
{
var variant = Rand.Range(0, jobPrefab.Variants);
CrewManager.AddCharacterInfo(new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: jobPrefab, variant: variant));
}
}
}
}
}