diff --git a/Barotrauma/BarotraumaClient/Source/Events/Missions/Mission.cs b/Barotrauma/BarotraumaClient/Source/Events/Missions/Mission.cs index 9375f6ca7..6a204e249 100644 --- a/Barotrauma/BarotraumaClient/Source/Events/Missions/Mission.cs +++ b/Barotrauma/BarotraumaClient/Source/Events/Missions/Mission.cs @@ -6,10 +6,10 @@ namespace Barotrauma { public void ShowMessage(int index) { - if (index >= headers.Count && index >= messages.Count) return; + if (index >= Headers.Count && index >= Messages.Count) return; - string header = index < headers.Count ? headers[index] : ""; - string message = index < messages.Count ? messages[index] : ""; + string header = index < Headers.Count ? Headers[index] : ""; + string message = index < Messages.Count ? Messages[index] : ""; GameServer.Log(TextManager.Get("MissionInfo") + ": " + header + " - " + message, ServerLog.MessageType.ServerMessage); diff --git a/Barotrauma/BarotraumaClient/Source/GameMain.cs b/Barotrauma/BarotraumaClient/Source/GameMain.cs index 1227f15d0..9680c1e2c 100644 --- a/Barotrauma/BarotraumaClient/Source/GameMain.cs +++ b/Barotrauma/BarotraumaClient/Source/GameMain.cs @@ -256,7 +256,7 @@ namespace Barotrauma TitleScreen.LoadState = 2.0f; yield return CoroutineStatus.Running; - Mission.Init(); + MissionPrefab.Init(); MapEntityPrefab.Init(); LevelGenerationParams.LoadPresets(); TitleScreen.LoadState = 10.0f; diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs index 79174cdae..020657672 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs @@ -691,6 +691,7 @@ namespace Barotrauma.Networking string shuttleHash = inc.ReadString(); string modeName = inc.ReadString(); + int missionIndex = inc.ReadInt16(); bool respawnAllowed = inc.ReadBoolean(); bool loadSecondSub = inc.ReadBoolean(); @@ -750,7 +751,7 @@ namespace Barotrauma.Networking if (campaign == null) { - GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, Mission.MissionTypes[missionTypeIndex]); + GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, missionIndex < 0 ? null : MissionPrefab.List[missionIndex]); GameMain.GameSession.StartRound(levelSeed, loadSecondSub); } else @@ -883,7 +884,7 @@ namespace Barotrauma.Networking bool allowSpectating = inc.ReadBoolean(); YesNoMaybe traitorsEnabled = (YesNoMaybe)inc.ReadRangedInteger(0, 2); - int missionTypeIndex = inc.ReadRangedInteger(0, Mission.MissionTypes.Count - 1); + int missionTypeIndex = inc.ReadRangedInteger(0, MissionPrefab.MissionTypes.Count - 1); int modeIndex = inc.ReadByte(); string levelSeed = inc.ReadString(); diff --git a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs index e7ab7c100..3946e7ea4 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs @@ -688,9 +688,9 @@ namespace Barotrauma public void SetMissionType(int missionTypeIndex) { - if (missionTypeIndex < 0 || missionTypeIndex >= Mission.MissionTypes.Count) return; + if (missionTypeIndex < 0 || missionTypeIndex >= MissionPrefab.MissionTypes.Count) return; - missionTypeBlock.GetChild().Text = Mission.MissionTypes[missionTypeIndex]; + missionTypeBlock.GetChild().Text = MissionPrefab.MissionTypes[missionTypeIndex]; missionTypeBlock.UserData = missionTypeIndex; } @@ -701,8 +701,8 @@ namespace Barotrauma int missionTypeIndex = (int)missionTypeBlock.UserData; missionTypeIndex += (int)userData; - if (missionTypeIndex < 0) missionTypeIndex = Mission.MissionTypes.Count - 1; - if (missionTypeIndex >= Mission.MissionTypes.Count) missionTypeIndex = 0; + if (missionTypeIndex < 0) missionTypeIndex = MissionPrefab.MissionTypes.Count - 1; + if (missionTypeIndex >= MissionPrefab.MissionTypes.Count) missionTypeIndex = 0; SetMissionType(missionTypeIndex); diff --git a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems index c3dc92f32..4dfec9011 100644 --- a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems +++ b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems @@ -1471,6 +1471,7 @@ + diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/CargoMission.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/CargoMission.cs index 7f6c8006c..6f2fd6199 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/Missions/CargoMission.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/CargoMission.cs @@ -13,12 +13,12 @@ namespace Barotrauma private int requiredDeliveryAmount; - public CargoMission(XElement element, Location[] locations) - : base(element, locations) + public CargoMission(MissionPrefab prefab, Location[] locations) + : base(prefab, locations) { - itemConfig = element.Element("Items"); + itemConfig = prefab.ConfigElement.Element("Items"); - requiredDeliveryAmount = element.GetAttributeInt("requireddeliveryamount", 0); + requiredDeliveryAmount = prefab.ConfigElement.GetAttributeInt("requireddeliveryamount", 0); } private void InitItems() diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/CombatMission.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/CombatMission.cs index 3ed0593b2..be9829597 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/Missions/CombatMission.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/CombatMission.cs @@ -47,20 +47,20 @@ namespace Barotrauma { if (winner == -1) return ""; - return successMessage + return SuccessMessage .Replace("[loser]", teamNames[1 - winner]) .Replace("[winner]", teamNames[winner]); } } - public CombatMission(XElement element, Location[] locations) - : base(element, locations) + public CombatMission(MissionPrefab prefab, Location[] locations) + : base(prefab, locations) { descriptions = new string[] { - element.GetAttributeString("descriptionneutral", ""), - element.GetAttributeString("description1", ""), - element.GetAttributeString("description2", "") + prefab.ConfigElement.GetAttributeString("descriptionneutral", ""), + prefab.ConfigElement.GetAttributeString("description1", ""), + prefab.ConfigElement.GetAttributeString("description2", "") }; for (int i = 0; i < descriptions.Length; i++) @@ -73,8 +73,8 @@ namespace Barotrauma teamNames = new string[] { - element.GetAttributeString("teamname1", "Team A"), - element.GetAttributeString("teamname2", "Team B") + prefab.ConfigElement.GetAttributeString("teamname1", "Team A"), + prefab.ConfigElement.GetAttributeString("teamname2", "Team B") }; } diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/Mission.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/Mission.cs index c8d8b2b23..499c5c7f0 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/Missions/Mission.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/Mission.cs @@ -1,45 +1,18 @@ using Microsoft.Xna.Framework; -using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; -using System.Xml.Linq; namespace Barotrauma { partial class Mission - { - public static List MissionTypes = new List() { "Random" }; - - private string name; - - private string description; - + { protected bool completed; - protected string successMessage; - protected string failureMessage; + private readonly MissionPrefab prefab; - protected string radarLabel; - - protected List headers; - protected List messages; - - private int reward; - public string Name { - get { return name; } - } - - public virtual string Description - { - get { return description; } - } - - public int Reward - { - get { return reward; } + get { return prefab.Name; } } public bool Completed @@ -48,109 +21,101 @@ namespace Barotrauma set { completed = value; } } + public int Reward + { + get { return prefab.Reward; } + } + public virtual bool AllowRespawn { get { return true; } } - public virtual string RadarLabel - { - get { return radarLabel; } - } - public virtual Vector2 RadarPosition { get { return Vector2.Zero; } } - virtual public string SuccessMessage + public string RadarLabel { - get { return successMessage; } + get { return prefab.RadarLabel; } + } + + public List Headers + { + get; private set; + } + + public List Messages + { + get; private set; + } + + public virtual string SuccessMessage + { + get; + protected set; } public string FailureMessage { - get { return failureMessage; } + get; + protected set; } - public static void Init() + public virtual string Description { - var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.Missions); - foreach (string file in files) - { - XDocument doc = XMLExtensions.TryLoadXml(file); - if (doc == null || doc.Root == null) continue; - - foreach (XElement element in doc.Root.Elements()) - { - string missionTypeName = element.Name.ToString(); - missionTypeName = missionTypeName.Replace("Mission", ""); - - if (!MissionTypes.Contains(missionTypeName)) MissionTypes.Add(missionTypeName); - } - - } + get; + protected set; } - public Mission(XElement element, Location[] locations) + public MissionPrefab Prefab { - name = element.GetAttributeString("name", ""); + get { return prefab; } + } + + public Mission(MissionPrefab prefab, Location[] locations) + { + System.Diagnostics.Debug.Assert(locations.Length == 2); - description = element.GetAttributeString("description", ""); + this.prefab = prefab; - reward = element.GetAttributeInt("reward", 1); - - successMessage = element.GetAttributeString("successmessage", - "Mission completed successfully"); - failureMessage = element.GetAttributeString("failuremessage", - "Mission failed"); - - radarLabel = element.GetAttributeString("radarlabel", ""); - - messages = new List(); - headers = new List(); - foreach (XElement subElement in element.Elements()) - { - if (subElement.Name.ToString().ToLowerInvariant() != "message") continue; - headers.Add(subElement.GetAttributeString("header", "")); - messages.Add(subElement.GetAttributeString("text", "")); - } + Description = prefab.Description; + SuccessMessage = prefab.SuccessMessage; + FailureMessage = prefab.FailureMessage; + Headers = new List(prefab.Headers); + Messages = new List(prefab.Messages); for (int n = 0; n < 2; n++) { - description = description.Replace("[location" + (n + 1) + "]", locations[n].Name); - - successMessage = successMessage.Replace("[location" + (n + 1) + "]", locations[n].Name); - failureMessage = failureMessage.Replace("[location" + (n + 1) + "]", locations[n].Name); - - for (int m = 0; m < messages.Count; m++) + Description = Description.Replace("[location" + (n + 1) + "]", locations[n].Name); + SuccessMessage = SuccessMessage.Replace("[location" + (n + 1) + "]", locations[n].Name); + FailureMessage = FailureMessage.Replace("[location" + (n + 1) + "]", locations[n].Name); + for (int m = 0; m < Messages.Count; m++) { - messages[m] = messages[m].Replace("[location" + (n + 1) + "]", locations[n].Name); + Messages[m] = Messages[m].Replace("[location" + (n + 1) + "]", locations[n].Name); } } } + public static Mission LoadRandom(Location[] locations, string seed, string missionType = "", bool isSinglePlayer = false) + { + return LoadRandom(locations, new MTRandom(ToolBox.StringToInt(seed)), missionType, isSinglePlayer); + } + public static Mission LoadRandom(Location[] locations, MTRandom rand, string missionType = "", bool isSinglePlayer = false) { + //todo: use something else than strings to define the mission type missionType = missionType.ToLowerInvariant(); - var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.Missions); - string configFile = files[rand.Next(files.Count)]; - - XDocument doc = XMLExtensions.TryLoadXml(configFile); - if (doc == null) return null; - - int eventCount = doc.Root.Elements().Count(); - //int[] commonness = new int[eventCount]; - float[] eventProbability = new float[eventCount]; - - float probabilitySum = 0.0f; - - List matchingElements = new List(); - + List allowedMissions = new List(); if (missionType == "random") { - matchingElements = doc.Root.Elements().ToList(); + allowedMissions.AddRange(MissionPrefab.List); + if (GameMain.Server != null) + { + allowedMissions.RemoveAll(mission => !GameMain.Server.AllowedRandomMissionTypes.Any(a => mission.TypeMatches(a))); + } } else if (missionType == "none") { @@ -158,68 +123,31 @@ namespace Barotrauma } else if (string.IsNullOrWhiteSpace(missionType)) { - matchingElements = doc.Root.Elements().ToList(); + allowedMissions.AddRange(MissionPrefab.List); } else { - matchingElements = doc.Root.Elements().ToList().FindAll(m => m.Name.ToString().ToLowerInvariant().Replace("mission", "") == missionType); + allowedMissions = MissionPrefab.List.FindAll(m => m.Name.ToString().ToLowerInvariant().Replace("mission", "") == missionType); } if (isSinglePlayer) { - matchingElements.RemoveAll(m => m.GetAttributeBool("multiplayeronly", false)); + allowedMissions.RemoveAll(m => m.MultiplayerOnly); } else { - matchingElements.RemoveAll(m => m.GetAttributeBool("singleplayeronly", false)); + allowedMissions.RemoveAll(m => m.SingleplayerOnly); } - int i = 0; - foreach (XElement element in matchingElements) - { - eventProbability[i] = element.GetAttributeInt("commonness", 1); - - probabilitySum += eventProbability[i]; - - i++; - } - + float probabilitySum = allowedMissions.Sum(m => m.Commonness); float randomNumber = (float)rand.NextDouble() * probabilitySum; - - i = 0; - foreach (XElement element in matchingElements) + foreach (MissionPrefab missionPrefab in allowedMissions) { - if (randomNumber <= eventProbability[i]) + if (randomNumber <= missionPrefab.Commonness) { - Type t; - string type = element.Name.ToString(); - - try - { - t = Type.GetType("Barotrauma." + type, true, true); - if (t == null) - { - DebugConsole.ThrowError("Error in " + configFile + "! Could not find a mission class of the type \"" + type + "\"."); - continue; - } - } - catch - { - DebugConsole.ThrowError("Error in " + configFile + "! Could not find a mission class of the type \"" + type + "\"."); - continue; - } - - ConstructorInfo constructor = t.GetConstructor(new[] { typeof(XElement), typeof(Location[]) }); - - object instance = constructor.Invoke(new object[] { element, locations }); - - Mission mission = (Mission)instance; - - return mission; + return missionPrefab.Instantiate(locations); } - - randomNumber -= eventProbability[i]; - i++; + randomNumber -= missionPrefab.Commonness; } return null; @@ -251,7 +179,7 @@ namespace Barotrauma var mode = GameMain.GameSession.GameMode as CampaignMode; if (mode == null) return; - mode.Money += reward; + mode.Money += Reward; } } } diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/MissionPrefab.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/MissionPrefab.cs new file mode 100644 index 000000000..169105c9a --- /dev/null +++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/MissionPrefab.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Xml.Linq; + +namespace Barotrauma +{ + class MissionPrefab + { + public static List List = new List(); + public static List MissionTypes = new List() { "Random" }; + + private string name; + + public string Name + { + get { return name; } + } + + private Type missionType; + private ConstructorInfo constructor; + + public virtual string Description { get; private set; } + + public bool MultiplayerOnly { get; private set; } + public bool SingleplayerOnly { get; private set; } + + public float Commonness { get; private set; } + + public int Reward { get; private set; } + + public string RadarLabel { get; private set; } + + public List Headers { get; private set; } + public List Messages { get; private set; } + + public string SuccessMessage { get; private set; } + public string FailureMessage { get; private set; } + + public XElement ConfigElement { get; private set; } + + public static void Init() + { + var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.Missions); + foreach (string file in files) + { + XDocument doc = XMLExtensions.TryLoadXml(file); + if (doc?.Root == null) continue; + + foreach (XElement element in doc.Root.Elements()) + { + string missionTypeName = element.Name.ToString(); + missionTypeName = missionTypeName.Replace("Mission", ""); + + List.Add(new MissionPrefab(element)); + if (!MissionTypes.Contains(missionTypeName)) MissionTypes.Add(missionTypeName); + } + + } + } + + public MissionPrefab(XElement element) + { + ConfigElement = element; + + name = element.GetAttributeString("name", ""); + Description = element.GetAttributeString("description", ""); + Commonness = element.GetAttributeFloat("commonness", 1.0f); + SingleplayerOnly = element.GetAttributeBool("singleplayeronly", false); + MultiplayerOnly = element.GetAttributeBool("multiplayeronly", false); + + Reward = element.GetAttributeInt("reward", 1); + + SuccessMessage = element.GetAttributeString("successmessage", "Mission completed successfully"); + FailureMessage = element.GetAttributeString("failuremessage", "Mission failed"); + RadarLabel = element.GetAttributeString("radarlabel", ""); + + Messages = new List(); + Headers = new List(); + foreach (XElement subElement in element.Elements()) + { + if (subElement.Name.ToString().ToLowerInvariant() != "message") continue; + Headers.Add(subElement.GetAttributeString("header", "")); + Messages.Add(subElement.GetAttributeString("text", "")); + } + + string type = element.Name.ToString(); + + try + { + missionType = Type.GetType("Barotrauma." + type, true, true); + if (missionType == null) + { + DebugConsole.ThrowError("Error in mission prefab " + Name + "! Could not find a mission class of the type \"" + type + "\"."); + return; + } + } + catch + { + DebugConsole.ThrowError("Error in mission prefab " + Name + "! Could not find a mission class of the type \"" + type + "\"."); + return; + } + constructor = missionType.GetConstructor(new[] { typeof(MissionPrefab), typeof(Location[]) }); + } + + public Mission Instantiate(Location[] locations) + { + return constructor?.Invoke(new object[] { this, locations }) as Mission; + } + + public bool TypeMatches(string typeName) + { + //TODO: use enums instead of strings? + typeName = typeName.ToLowerInvariant(); + return missionType.Name.ToString().Replace("Mission", "").ToLowerInvariant() == typeName; + } + } +} diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs index bb2b00e00..71259e252 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs @@ -18,10 +18,10 @@ namespace Barotrauma get { return monster != null && !monster.IsDead ? radarPosition : Vector2.Zero; } } - public MonsterMission(XElement element, Location[] locations) - : base(element, locations) + public MonsterMission(MissionPrefab prefab, Location[] locations) + : base(prefab, locations) { - monsterFile = element.GetAttributeString("monsterfile", ""); + monsterFile = prefab.ConfigElement.GetAttributeString("monsterfile", ""); } diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/SalvageMission.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/SalvageMission.cs index 5ae148b83..b9fc7bb10 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/Missions/SalvageMission.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/SalvageMission.cs @@ -1,7 +1,6 @@ using FarseerPhysics; using Microsoft.Xna.Framework; using System; -using System.Xml.Linq; namespace Barotrauma { @@ -23,10 +22,10 @@ namespace Barotrauma } } - public SalvageMission(XElement element, Location[] locations) - : base(element, locations) + public SalvageMission(MissionPrefab prefab, Location[] locations) + : base(prefab, locations) { - string itemName = element.GetAttributeString("itemname", ""); + string itemName = prefab.ConfigElement.GetAttributeString("itemname", ""); itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab; if (itemPrefab == null) @@ -35,10 +34,10 @@ namespace Barotrauma return; } - string spawnPositionTypeStr = element.GetAttributeString("spawntype", ""); + string spawnPositionTypeStr = prefab.ConfigElement.GetAttributeString("spawntype", ""); if (string.IsNullOrWhiteSpace(spawnPositionTypeStr) || - !Enum.TryParse(spawnPositionTypeStr, true, out spawnPositionType)) + !Enum.TryParse(spawnPositionTypeStr, true, out spawnPositionType)) { spawnPositionType = Level.PositionType.Cave | Level.PositionType.Ruin; } diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/MissionMode.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/MissionMode.cs index 77a49fbc3..57fae1264 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/MissionMode.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/MissionMode.cs @@ -16,9 +16,22 @@ : base(preset, param) { Location[] locations = { GameMain.GameSession.StartLocation, GameMain.GameSession.EndLocation }; - - MTRandom rand = new MTRandom(ToolBox.StringToInt(GameMain.NetLobbyScreen.LevelSeed)); - mission = Mission.LoadRandom(locations, rand, param as string); + if (param is string) + { + mission = Mission.LoadRandom(locations, GameMain.NetLobbyScreen.LevelSeed, (string)param); + } + else if (param is MissionPrefab) + { + mission = ((MissionPrefab)param).Instantiate(locations); + } + else if (param is Mission) + { + mission = (Mission)param; + } + else + { + throw new System.ArgumentException("Unrecognized MissionMode parameter \"" + param + "\""); + } } } } diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameSession.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameSession.cs index d0ad84284..7d4fdbde3 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/GameSession.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameSession.cs @@ -91,27 +91,35 @@ namespace Barotrauma set { savePath = value; } } - public GameSession(Submarine submarine, string savePath, GameModePreset gameModePreset = null, string missionType = "") + + public GameSession(Submarine submarine, string savePath, GameModePreset gameModePreset, string missionType = "") + : this(submarine, savePath) + { + GameMode = gameModePreset.Instantiate(missionType); + } + + public GameSession(Submarine submarine, string savePath, GameModePreset gameModePreset, MissionPrefab missionPrefab) + : this(submarine, savePath) + { + GameMode = gameModePreset.Instantiate(missionPrefab); + } + + private GameSession(Submarine submarine, string savePath) { Submarine.MainSub = submarine; - + this.submarine = submarine; GameMain.GameSession = this; - EventManager = new EventManager(this); - this.savePath = savePath; - #if CLIENT CrewManager = new CrewManager(); infoButton = new GUIButton(new Rectangle(10, 10, 100, 20), "Info", "", null); infoButton.OnClicked = ToggleInfoFrame; #endif - - if (gameModePreset != null) GameMode = gameModePreset.Instantiate(missionType); - this.submarine = submarine; } - + + public GameSession(Submarine selectedSub, string saveFile, XDocument doc) : this(selectedSub, saveFile) { diff --git a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs index 44683fc11..e42686a6f 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs @@ -993,7 +993,7 @@ namespace Barotrauma.Networking outmsg.WriteRangedInteger(0, 2, (int)TraitorsEnabled); - outmsg.WriteRangedInteger(0, Mission.MissionTypes.Count - 1, (GameMain.NetLobbyScreen.MissionTypeIndex)); + outmsg.WriteRangedInteger(0, MissionPrefab.MissionTypes.Count - 1, (GameMain.NetLobbyScreen.MissionTypeIndex)); outmsg.Write((byte)GameMain.NetLobbyScreen.SelectedModeIndex); outmsg.Write(GameMain.NetLobbyScreen.LevelSeed); @@ -1213,7 +1213,7 @@ namespace Barotrauma.Networking //don't instantiate a new gamesession if we're playing a campaign if (campaign == null || GameMain.GameSession == null) { - GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, Mission.MissionTypes[GameMain.NetLobbyScreen.MissionTypeIndex]); + GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, MissionPrefab.MissionTypes[GameMain.NetLobbyScreen.MissionTypeIndex]); } if (GameMain.GameSession.GameMode.Mission != null && @@ -1402,6 +1402,8 @@ namespace Barotrauma.Networking msg.Write(GameMain.NetLobbyScreen.SelectedShuttle.MD5Hash.Hash); msg.Write(selectedMode.Name); + msg.Write((short)(GameMain.GameSession.GameMode?.Mission == null ? + -1 : MissionPrefab.List.IndexOf(GameMain.GameSession.GameMode.Mission.Prefab))); MultiPlayerCampaign campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign; diff --git a/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs b/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs index a148dde48..63af136a5 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs @@ -254,6 +254,12 @@ namespace Barotrauma.Networking set; } + public List AllowedRandomMissionTypes + { + get; + set; + } + [Serialize(60f, true)] public float AutoBanTime { @@ -287,6 +293,8 @@ namespace Barotrauma.Networking doc.Root.SetAttributeValue("TraitorsEnabled", TraitorsEnabled.ToString()); + doc.Root.SetAttributeValue("AllowedRandomMissionTypes", string.Join(",", AllowedRandomMissionTypes)); + #if SERVER doc.Root.SetAttributeValue("password", password); #endif @@ -334,18 +342,22 @@ namespace Barotrauma.Networking #endif subSelectionMode = SelectionMode.Manual; - Enum.TryParse(doc.Root.GetAttributeString("SubSelection", "Manual"), out subSelectionMode); + Enum.TryParse(doc.Root.GetAttributeString("SubSelection", "Manual"), out subSelectionMode); Voting.AllowSubVoting = subSelectionMode == SelectionMode.Vote; modeSelectionMode = SelectionMode.Manual; - Enum.TryParse(doc.Root.GetAttributeString("ModeSelection", "Manual"), out modeSelectionMode); + Enum.TryParse(doc.Root.GetAttributeString("ModeSelection", "Manual"), out modeSelectionMode); Voting.AllowModeVoting = modeSelectionMode == SelectionMode.Vote; var traitorsEnabled = TraitorsEnabled; - Enum.TryParse(doc.Root.GetAttributeString("TraitorsEnabled", "No"), out traitorsEnabled); + Enum.TryParse(doc.Root.GetAttributeString("TraitorsEnabled", "No"), out traitorsEnabled); TraitorsEnabled = traitorsEnabled; GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled); + AllowedRandomMissionTypes = doc.Root.GetAttributeStringArray( + "AllowedRandomMissionTypes", + MissionPrefab.MissionTypes.ToArray()).ToList(); + if (GameMain.NetLobbyScreen != null #if CLIENT && GameMain.NetLobbyScreen.ServerMessage != null