diff --git a/Launcher2/Launcher.csproj b/Launcher2/Launcher.csproj index 0149641f5..9aa7ec09b 100644 --- a/Launcher2/Launcher.csproj +++ b/Launcher2/Launcher.csproj @@ -72,7 +72,6 @@ - diff --git a/Subsurface/Source/Events/Missions/Mission.cs b/Subsurface/Source/Events/Missions/Mission.cs index 4f9d12ffb..1f59422fc 100644 --- a/Subsurface/Source/Events/Missions/Mission.cs +++ b/Subsurface/Source/Events/Missions/Mission.cs @@ -9,7 +9,7 @@ namespace Barotrauma { class Mission { - //private static List list = new List(); + public static List MissionTypes = new List() { "Random" }; private string name; @@ -67,6 +67,25 @@ namespace Barotrauma get { return failureMessage; } } + public static void Init() + { + var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.Missions); + foreach (string file in files) + { + XDocument doc = ToolBox.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); + } + + } + } + public Mission(XElement element) { name = ToolBox.GetAttributeString(element, "name", ""); @@ -92,8 +111,10 @@ namespace Barotrauma } } - public static Mission LoadRandom(Location[] locations, MTRandom rand) + public static Mission LoadRandom(Location[] locations, MTRandom rand, string missionType = "") { + missionType = missionType.ToLowerInvariant(); + var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.Missions); string configFile = files[rand.Next(files.Count)]; @@ -106,8 +127,25 @@ namespace Barotrauma float probabilitySum = 0.0f; + List matchingElements = new List(); + + if (missionType == "random") + { + matchingElements = doc.Root.Elements().ToList(); + } + else if (missionType == "none") + { + return null; + } + else + { + matchingElements = doc.Root.Elements().ToList().FindAll(m => m.Name.ToString().ToLowerInvariant().Replace("mission", "") == missionType); + } + + + int i = 0; - foreach (XElement element in doc.Root.Elements()) + foreach (XElement element in matchingElements) { eventProbability[i] = ToolBox.GetAttributeInt(element, "commonness", 1); @@ -119,7 +157,7 @@ namespace Barotrauma float randomNumber = (float)rand.NextDouble() * probabilitySum; i = 0; - foreach (XElement element in doc.Root.Elements()) + foreach (XElement element in matchingElements) { if (randomNumber <= eventProbability[i]) { diff --git a/Subsurface/Source/GameMain.cs b/Subsurface/Source/GameMain.cs index 45aacb904..ecc7054b7 100644 --- a/Subsurface/Source/GameMain.cs +++ b/Subsurface/Source/GameMain.cs @@ -204,6 +204,7 @@ namespace Barotrauma TitleScreen.LoadState = 2.0f; yield return CoroutineStatus.Running; + Mission.Init(); MapEntityPrefab.Init(); TitleScreen.LoadState = 10.0f; yield return CoroutineStatus.Running; diff --git a/Subsurface/Source/GameSession/GameModes/GameMode.cs b/Subsurface/Source/GameSession/GameModes/GameMode.cs index 7396a875a..d104d6865 100644 --- a/Subsurface/Source/GameSession/GameModes/GameMode.cs +++ b/Subsurface/Source/GameSession/GameModes/GameMode.cs @@ -50,7 +50,7 @@ namespace Barotrauma get { return preset; } } - public GameMode(GameModePreset preset) + public GameMode(GameModePreset preset, object param) { this.preset = preset; } diff --git a/Subsurface/Source/GameSession/GameModes/GameModePreset.cs b/Subsurface/Source/GameSession/GameModes/GameModePreset.cs index f5906c7c9..d08cb2d66 100644 --- a/Subsurface/Source/GameSession/GameModes/GameModePreset.cs +++ b/Subsurface/Source/GameSession/GameModes/GameModePreset.cs @@ -19,19 +19,17 @@ namespace Barotrauma public GameModePreset(string name, Type type, bool isSinglePlayer = false) { this.Name = name; - //Constructor = constructor; - - Constructor = type.GetConstructor(new Type[] { typeof(GameModePreset) }); + Constructor = type.GetConstructor(new Type[] { typeof(GameModePreset), typeof(object) }); IsSinglePlayer = isSinglePlayer; list.Add(this); } - public GameMode Instantiate() + public GameMode Instantiate(object param) { - object[] lobject = new object[] { this }; + object[] lobject = new object[] { this, param }; return (GameMode)Constructor.Invoke(lobject); } diff --git a/Subsurface/Source/GameSession/GameModes/MissionMode.cs b/Subsurface/Source/GameSession/GameModes/MissionMode.cs index ea550e0da..8e9111f5c 100644 --- a/Subsurface/Source/GameSession/GameModes/MissionMode.cs +++ b/Subsurface/Source/GameSession/GameModes/MissionMode.cs @@ -14,8 +14,8 @@ namespace Barotrauma } } - public MissionMode(GameModePreset preset) - : base(preset) + public MissionMode(GameModePreset preset, object param) + : base(preset, param) { Location[] locations = new Location[2]; @@ -25,13 +25,16 @@ namespace Barotrauma { locations[i] = Location.CreateRandom(new Vector2((float)rand.NextDouble() * 10000.0f, (float)rand.NextDouble() * 10000.0f)); } - mission = Mission.LoadRandom(locations, rand); + + mission = Mission.LoadRandom(locations, rand, param as string); } public override void Start() { base.Start(); + if (mission == null) return; + new GUIMessageBox(mission.Name, mission.Description, 400, 400); Networking.GameServer.Log("Mission: " + mission.Name, Color.Cyan); diff --git a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs index 3c57abf41..9e933d519 100644 --- a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs +++ b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs @@ -45,8 +45,8 @@ namespace Barotrauma get { return GameMain.GameSession.CrewManager; } } - public SinglePlayerMode(GameModePreset preset) - : base(preset) + public SinglePlayerMode(GameModePreset preset, object param) + : base(preset, param) { CargoManager = new CargoManager(); @@ -79,7 +79,7 @@ namespace Barotrauma } public SinglePlayerMode(XElement element) - : this(GameModePreset.list.Find(gm => gm.Name == "Single Player")) + : this(GameModePreset.list.Find(gm => gm.Name == "Single Player"), null) { string mapSeed = ToolBox.GetAttributeString(element, "mapseed", "a"); diff --git a/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialMode.cs b/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialMode.cs index 0188fd925..5a16434a4 100644 --- a/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialMode.cs +++ b/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialMode.cs @@ -15,8 +15,8 @@ namespace Barotrauma tutorialType.Initialize(); } - public TutorialMode(GameModePreset preset) - : base(preset) + public TutorialMode(GameModePreset preset, object param) + : base(preset, param) { } diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs index 8f0168bdb..ecffffafa 100644 --- a/Subsurface/Source/GameSession/GameSession.cs +++ b/Subsurface/Source/GameSession/GameSession.cs @@ -66,7 +66,7 @@ namespace Barotrauma get { return shiftSummary; } } - public GameSession(Submarine submarine, string saveFile, GameModePreset gameModePreset = null) + public GameSession(Submarine submarine, string saveFile, GameModePreset gameModePreset = null, string missionType="") { GameMain.GameSession = this; @@ -81,7 +81,7 @@ namespace Barotrauma infoButton = new GUIButton(new Rectangle(10, 10, 100, 20), "Info", GUI.Style, null); infoButton.OnClicked = ToggleInfoFrame; - if (gameModePreset!=null) gameMode = gameModePreset.Instantiate(); + if (gameModePreset!=null) gameMode = gameModePreset.Instantiate(missionType); this.submarine = submarine; } diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index fdb32c0d1..19ce65df5 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -610,6 +610,8 @@ namespace Barotrauma.Networking string levelSeed = inc.ReadString(); + int missionTypeIndex = inc.ReadByte(); + string mapName = inc.ReadString(); string mapHash = inc.ReadString(); @@ -633,7 +635,7 @@ namespace Barotrauma.Networking Rand.SetSyncedSeed(seed); //int gameModeIndex = inc.ReadInt32(); - GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode); + GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, Mission.MissionTypes[missionTypeIndex]); GameMain.GameSession.StartShift(levelSeed); yield return CoroutineStatus.Running; diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index e53f56549..777c1ad98 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -876,7 +876,7 @@ namespace Barotrauma.Networking roundStartSeed = DateTime.Now.Millisecond; Rand.SetSyncedSeed(roundStartSeed); - GameMain.GameSession = new GameSession(selectedSub, "", selectedMode); + GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, Mission.MissionTypes[GameMain.NetLobbyScreen.MissionTypeIndex]); GameMain.GameSession.StartShift(GameMain.NetLobbyScreen.LevelSeed); GameServer.Log("Starting a new round...", Color.Cyan); @@ -978,6 +978,8 @@ namespace Barotrauma.Networking msg.Write(GameMain.NetLobbyScreen.LevelSeed); + msg.Write((byte)GameMain.NetLobbyScreen.MissionTypeIndex); + msg.Write(selectedSub.Name); msg.Write(selectedSub.MD5Hash.Hash); diff --git a/Subsurface/Source/Screens/NetLobbyScreen.cs b/Subsurface/Source/Screens/NetLobbyScreen.cs index 187f6d2b2..62860778b 100644 --- a/Subsurface/Source/Screens/NetLobbyScreen.cs +++ b/Subsurface/Source/Screens/NetLobbyScreen.cs @@ -21,6 +21,9 @@ namespace Barotrauma private GUIButton[] traitorProbabilityButtons; private GUITextBlock traitorProbabilityText; + + private GUIButton[] missionTypeButtons; + private GUIComponent missionTypeBlock; private GUIListBox jobList; @@ -75,6 +78,12 @@ namespace Barotrauma get { return modeList.SelectedData as GameModePreset; } } + public int MissionTypeIndex + { + get { return (int)missionTypeBlock.UserData; } + set { missionTypeBlock.UserData = value; } + } + //for guitextblock delegate public string GetServerName() { @@ -220,6 +229,23 @@ namespace Barotrauma } + //mission type ------------------------------------------------------------------ + + missionTypeBlock = new GUITextBlock(new Rectangle(columnX, 0, 300, 20), "Mission type:", GUI.Style, Alignment.BottomLeft, Alignment.TopLeft, infoFrame); + missionTypeBlock.UserData = 0; + + missionTypeButtons = new GUIButton[2]; + + missionTypeButtons[0] = new GUIButton(new Rectangle(120, 0, 20, 20), "<", Alignment.BottomLeft, GUI.Style, missionTypeBlock); + missionTypeButtons[0].UserData = -1; + + new GUITextBlock(new Rectangle(120, 0, 120, 20), "Random", GUI.Style, Alignment.BottomLeft, Alignment.TopCenter, missionTypeBlock).UserData = 0; + + missionTypeButtons[1] = new GUIButton(new Rectangle(240, 0, 20, 20), ">", Alignment.BottomLeft, GUI.Style, missionTypeBlock); + missionTypeButtons[1].UserData = 1; + + missionTypeBlock.Visible = false; + columnX += columnWidth + 20; //gamemode description ------------------------------------------------------------------ @@ -257,6 +283,7 @@ namespace Barotrauma traitorProbabilityButtons[1] = new GUIButton(new Rectangle(columnX + 100, 205, 20, 20), ">", GUI.Style, infoFrame); traitorProbabilityButtons[1].UserData = 1; + //automatic restart ------------------------------------------------------------------ autoRestartBox = new GUITickBox(new Rectangle(columnX, 240, 20, 20), "Automatic restart", Alignment.TopLeft, infoFrame); @@ -308,6 +335,9 @@ namespace Barotrauma traitorProbabilityButtons[0].Enabled = GameMain.Server != null; traitorProbabilityButtons[1].Enabled = GameMain.Server != null; + missionTypeButtons[0].Enabled = GameMain.Server != null; + missionTypeButtons[1].Enabled = GameMain.Server != null; + ServerName = (GameMain.Server==null) ? "Server" : GameMain.Server.Name; infoFrame.RemoveChild(infoFrame.children.Find(c => c.UserData as string == "startButton")); @@ -326,6 +356,9 @@ namespace Barotrauma traitorProbabilityButtons[0].OnClicked = ToggleTraitorsEnabled; traitorProbabilityButtons[1].OnClicked = ToggleTraitorsEnabled; + missionTypeButtons[0].OnClicked = ToggleMissionType; + missionTypeButtons[1].OnClicked = ToggleMissionType; + GUIButton startButton = new GUIButton(new Rectangle(0, 0, 80, 30), "Start", Alignment.BottomRight, GUI.Style, infoFrame); startButton.OnClicked = GameMain.Server.StartGameClicked; startButton.UserData = "startButton"; @@ -478,6 +511,27 @@ namespace Barotrauma GameMain.Server.AutoRestart = tickBox.Selected; valueChanged = true; + + return true; + } + + private void SetMissionType(int missionTypeIndex) + { + if (missionTypeIndex < 0 || missionTypeIndex >= Mission.MissionTypes.Count) return; + + missionTypeBlock.GetChild().Text = Mission.MissionTypes[missionTypeIndex]; + missionTypeBlock.UserData = missionTypeIndex; + } + + public bool ToggleMissionType(GUIButton button, object userData) + { + int missionTypeIndex = (int)missionTypeBlock.UserData; + missionTypeIndex += (int)userData; + + if (missionTypeIndex<0) missionTypeIndex = Mission.MissionTypes.Count-1; + if (missionTypeIndex>=Mission.MissionTypes.Count) missionTypeIndex=0; + + SetMissionType(missionTypeIndex); return true; } @@ -830,6 +884,8 @@ namespace Barotrauma //} GameModePreset modePreset = obj as GameModePreset; + missionTypeBlock.Visible = modePreset.Name == "Mission"; + if (modePreset == null) return false; valueChanged = true; @@ -993,11 +1049,9 @@ namespace Barotrauma msg.WriteRangedInteger(0, 2, (int)GameMain.Server.TraitorsEnabled); - //msg.Write(AllowSubVoting); - //msg.Write(AllowModeVoting); + msg.WriteRangedInteger(0, Mission.MissionTypes.Count-1, MissionTypeIndex); msg.Write((byte)modeList.SelectedIndex); - //msg.Write(durationBar.BarScroll); msg.Write(LevelSeed); msg.Write(GameMain.Server != null && GameMain.Server.AutoRestart); @@ -1035,14 +1089,11 @@ namespace Barotrauma traitorsEnabled = (YesNoMaybe)msg.ReadRangedInteger(0, 2); - //AllowSubVoting = msg.ReadBoolean(); - //AllowModeVoting = msg.ReadBoolean(); + SetMissionType(msg.ReadRangedInteger(0, Mission.MissionTypes.Count - 1)); modeIndex = msg.ReadByte(); - //durationScroll = msg.ReadFloat(); - - newSeed = msg.ReadString(); + newSeed = msg.ReadString(); autoRestart = msg.ReadBoolean(); restartTimer = msg.ReadFloat(); @@ -1063,7 +1114,10 @@ namespace Barotrauma if (!string.IsNullOrWhiteSpace(mapName) && !GameMain.NetworkMember.Voting.AllowSubVoting) TrySelectSub(mapName, md5Hash); - if (!GameMain.NetworkMember.Voting.AllowModeVoting) modeList.Select(modeIndex, true); + if (!GameMain.NetworkMember.Voting.AllowModeVoting) + { + SelectMode(modeList.children[modeIndex], modeList.children[modeIndex].UserData); + } SetTraitorsEnabled(traitorsEnabled);