From 0740ca84bc3afbe7ce6618be6cde1c98f4e90d79 Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Sat, 2 Dec 2017 16:15:50 +0300 Subject: [PATCH 1/9] Overhauled GetEndMessage() to also include detaining --- .../GameSession/GameModes/TraitorManager.cs | 68 ++++++++++++------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs index 26db8d153..935c91d93 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs @@ -72,35 +72,51 @@ namespace Barotrauma string endMessage = ""; - if (targetCharacter.IsDead && !traitorCharacter.IsDead) + endMessage = traitorCharacter.Name + " was a traitor! "; + endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "His" : "Her"; + endMessage += " task was to assassinate " + targetCharacter.Name; + + if (targetCharacter.IsDead) //Partial or complete mission success { - endMessage = traitorCharacter.Name + " was a traitor! "; - endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "His" : "Her"; - endMessage += " task was to assassinate " + targetCharacter.Name + ". The task was successful."; + endMessage += ". The task was successful"; + if (traitorCharacter.IsDead) + { + endMessage += ", but luckily the bastard didn't make it out alive either."; + } + else if (traitorCharacter.LockHands) + { + endMessage += ", but "; + endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "he" : "she"; + endMessage += " was successfuly detained."; + } + else + endMessage += "."; } - else if (targetCharacter.IsDead && traitorCharacter.IsDead) + else //Partial or complete failure { - endMessage = traitorCharacter.Name + " was a traitor! "; - endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "His" : "Her"; - endMessage += " task was to assassinate " + targetCharacter.Name + ". The task was successful, but luckily the bastard didn't make it out alive either."; - } - else if (traitorCharacter.IsDead) - { - endMessage = traitorCharacter.Name + " was a traitor! "; - endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "His" : "Her"; - endMessage += " task was to assassinate " + targetCharacter.Name + ", but "; - endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "he" : "she"; - endMessage += " got " + ((traitorCharacter.Info.Gender == Gender.Male) ? "himself" : "herself"); - endMessage += " killed before completing it."; - } - else - { - endMessage = traitorCharacter.Name + " was a traitor! "; - endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "His" : "Her"; - endMessage += " task was to assassinate " + targetCharacter.Name + ". "; - endMessage += (Submarine.MainSub.AtEndPosition) ? - "The task was unsuccessful - the submarine has reached its destination." : - "The task was unsuccessful."; + if (traitorCharacter.IsDead) + { + endMessage += ", but "; + endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "he" : "she"; + endMessage += " got " + ((traitorCharacter.Info.Gender == Gender.Male) ? "himself" : "herself"); + endMessage += " killed before completing it."; + } + else + { + endMessage += ". The task was unsuccessful"; + if (traitorCharacter.LockHands) + { + endMessage += " - "; + endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "he" : "she"; + endMessage += " was successfuly detained"; + } + if (Submarine.MainSub.AtEndPosition) + { + endMessage += (traitorCharacter.LockHands ? " and " : " - "); + endMessage += "the submarine has reached its destination"; + } + endMessage += "."; + } } return endMessage; From 56df7b69005603e352704344ceb9aded917ca212 Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Sun, 3 Dec 2017 00:43:14 +0300 Subject: [PATCH 2/9] Support for multi-traitors! It's possible for traitors to share targets and/or target each other. Todo: code phrases-responses, clientside settings for traitor amount --- .../GameSession/GameModes/TraitorManager.cs | 177 ++++++++++-------- .../Source/Networking/GameServer.cs | 29 ++- 2 files changed, 123 insertions(+), 83 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs index 935c91d93..6c8e2574b 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs @@ -3,120 +3,149 @@ using System.Collections.Generic; namespace Barotrauma { + partial class Traitor + { + public Character Character; + public Character TargetCharacter; + + public Traitor(Character character, Character targetCharacter) + { + Character = character; TargetCharacter = targetCharacter; + } + } + partial class TraitorManager { - public Character TraitorCharacter + public List TraitorList { - get { return traitorCharacter; } + get { return traitorList; } } - public Character TargetCharacter + private List traitorList; + + public TraitorManager(GameServer server, int TraitorCount) { - get { return targetCharacter; } + if(TraitorCount < 1) //what why how + { + TraitorCount = 1; + DebugConsole.ThrowError("Traitor Manager: TraitorCount somehow ended up less than 1, setting it to 1."); + } + Start(server, TraitorCount); } - private Character traitorCharacter, targetCharacter; - - public TraitorManager(GameServer server) - { - Start(server); - } - - private void Start(GameServer server) + private void Start(GameServer server, int TraitorCount) { if (server == null) return; - List characters = new List(); + List characters = new List(); //ANYONE can be a target. + List traitorCandidates = new List(); //Keep this to not re-pick traitors twice foreach (Client client in server.ConnectedClients) { if (client.Character != null) + { characters.Add(client.Character); + traitorCandidates.Add(client.Character); + } } - - if (server.Character!= null) characters.Add(server.Character); + + if (server.Character!= null) characters.Add(server.Character); //Add host character if (characters.Count < 2) { - traitorCharacter = null; - targetCharacter = null; return; } - int traitorIndex = Rand.Range(0, characters.Count); - - int targetIndex = Rand.Range(0, characters.Count); - while (targetIndex == traitorIndex) + traitorList = new List(); + while (TraitorCount-- >= 0) { - targetIndex = Rand.Range(0, characters.Count); - } + if (traitorCandidates.Count <= 0) + break; - traitorCharacter = characters[traitorIndex]; - targetCharacter = characters[targetIndex]; + int traitorIndex = Rand.Int(traitorCandidates.Count); + var traitorCharacter = traitorCandidates[traitorIndex]; + traitorCandidates.Remove(traitorCharacter); + + int targetIndex = Rand.Int(characters.Count); + while (characters[targetIndex] == traitorCharacter) //Cannot target self + { + targetIndex = Rand.Int(characters.Count); + } + var targetCharacter = characters[targetIndex]; + + //Add them to the list + traitorList.Add(new Traitor(traitorCharacter, targetCharacter)); #if CLIENT - if (server.Character == null) - { - new GUIMessageBox("New traitor", traitorCharacter.Name + " is the traitor and the target is " + targetCharacter.Name+"."); - } - else if (server.Character == traitorCharacter) - { - CreateStartPopUp(targetCharacter.Name); - return; - } + if (server.Character == null) + { + new GUIMessageBox("New traitor", traitorCharacter.Name + " is the traitor and the target is " + targetCharacter.Name+"."); + } + else if (server.Character == traitorCharacter) + { + CreateStartPopUp(targetCharacter.Name); + return; + } #endif + } } public string GetEndMessage() { - if (GameMain.Server == null || traitorCharacter == null || targetCharacter == null) return ""; + if (GameMain.Server == null || traitorList.Count <= 0) return ""; string endMessage = ""; - endMessage = traitorCharacter.Name + " was a traitor! "; - endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "His" : "Her"; - endMessage += " task was to assassinate " + targetCharacter.Name; + foreach (Traitor traitor in traitorList) + { + Character traitorCharacter = traitor.Character; + Character targetCharacter = traitor.TargetCharacter; + endMessage += traitorCharacter.Name + " was a traitor! "; + endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "His" : "Her"; + endMessage += " task was to assassinate " + targetCharacter.Name; - if (targetCharacter.IsDead) //Partial or complete mission success - { - endMessage += ". The task was successful"; - if (traitorCharacter.IsDead) + if (targetCharacter.IsDead) //Partial or complete mission success { - endMessage += ", but luckily the bastard didn't make it out alive either."; - } - else if (traitorCharacter.LockHands) - { - endMessage += ", but "; - endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "he" : "she"; - endMessage += " was successfuly detained."; - } - else - endMessage += "."; - } - else //Partial or complete failure - { - if (traitorCharacter.IsDead) - { - endMessage += ", but "; - endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "he" : "she"; - endMessage += " got " + ((traitorCharacter.Info.Gender == Gender.Male) ? "himself" : "herself"); - endMessage += " killed before completing it."; - } - else - { - endMessage += ". The task was unsuccessful"; - if (traitorCharacter.LockHands) + endMessage += ". The task was successful"; + if (traitorCharacter.IsDead) { - endMessage += " - "; + endMessage += ", but luckily the bastard didn't make it out alive either."; + } + else if (traitorCharacter.LockHands) + { + endMessage += ", but "; endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "he" : "she"; - endMessage += " was successfuly detained"; + endMessage += " was successfuly detained."; } - if (Submarine.MainSub.AtEndPosition) - { - endMessage += (traitorCharacter.LockHands ? " and " : " - "); - endMessage += "the submarine has reached its destination"; - } - endMessage += "."; + else + endMessage += "."; } + else //Partial or complete failure + { + if (traitorCharacter.IsDead) + { + endMessage += ", but "; + endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "he" : "she"; + endMessage += " got " + ((traitorCharacter.Info.Gender == Gender.Male) ? "himself" : "herself"); + endMessage += " killed before completing it."; + } + else + { + endMessage += ". The task was unsuccessful"; + if (traitorCharacter.LockHands) + { + endMessage += " - "; + endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "he" : "she"; + endMessage += " was successfuly detained"; + } + if (Submarine.MainSub.AtEndPosition) + { + endMessage += (traitorCharacter.LockHands ? " and " : " - "); + endMessage += "the submarine has reached its destination"; + } + endMessage += "."; + } + } + endMessage += "\n"; } return endMessage; diff --git a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs index 12c5ea68e..2c948368a 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs @@ -1323,11 +1323,22 @@ namespace Barotrauma.Networking if (TraitorsEnabled == YesNoMaybe.Yes || (TraitorsEnabled == YesNoMaybe.Maybe && Rand.Range(0.0f, 1.0f) < 0.5f)) { - TraitorManager = new TraitorManager(this); - - if (TraitorManager.TraitorCharacter!=null && TraitorManager.TargetCharacter != null) + List characters = new List(); + foreach (Client client in ConnectedClients) { - Log(TraitorManager.TraitorCharacter.Name + " is the traitor and the target is " + TraitorManager.TargetCharacter.Name, ServerLog.MessageType.ServerMessage); + if (client.Character != null) + characters.Add(client.Character); + } + var max = (int)Math.Round(characters.Count * 0.2f, 1); + var traitorCount = Math.Max(1, TraitorsEnabled == YesNoMaybe.Maybe ? Rand.Int(max) + 1 : max); + TraitorManager = new TraitorManager(this, traitorCount); + + if (TraitorManager.TraitorList.Count > 0) + { + for (int i = 0; i < TraitorManager.TraitorList.Count; i++) + { + Log(TraitorManager.TraitorList[i].Character.Name + " is the traitor and the target is " + TraitorManager.TraitorList[i].TargetCharacter.Name, ServerLog.MessageType.ServerMessage); + } } } @@ -1386,13 +1397,13 @@ namespace Barotrauma.Networking msg.Write(AllowRespawn && missionAllowRespawn); msg.Write(Submarine.MainSubs[1] != null); //loadSecondSub - if (TraitorManager != null && - TraitorManager.TraitorCharacter != null && - TraitorManager.TargetCharacter != null && - TraitorManager.TraitorCharacter == client.Character) + Traitor traitor = null; + if (TraitorManager != null && TraitorManager.TraitorList.Count > 0) + traitor = TraitorManager.TraitorList.Find(t => t.Character == client.Character); + if (traitor != null) { msg.Write(true); - msg.Write(TraitorManager.TargetCharacter.Name); + msg.Write(traitor.TargetCharacter.Name); } else { From 63f8760b86bcc7b14f9f6335e34a0a2f1e25bc04 Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Sun, 3 Dec 2017 19:39:31 +0300 Subject: [PATCH 3/9] Added traitor code words Fixed host never being traitor --- .../BarotraumaShared.projitems | 3 + .../BarotraumaShared/Content/CodeWords.txt | 75 +++++++++++++++++++ .../BarotraumaShared/Source/DebugConsole.cs | 10 +++ .../GameSession/GameModes/TraitorManager.cs | 46 +++++++++++- 4 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 Barotrauma/BarotraumaShared/Content/CodeWords.txt diff --git a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems index b2beaca84..0f3ac76c9 100644 --- a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems +++ b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems @@ -222,6 +222,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/Barotrauma/BarotraumaShared/Content/CodeWords.txt b/Barotrauma/BarotraumaShared/Content/CodeWords.txt new file mode 100644 index 000000000..e34ad11d5 --- /dev/null +++ b/Barotrauma/BarotraumaShared/Content/CodeWords.txt @@ -0,0 +1,75 @@ +carrier +charybdis +coelanth +crawler +endworm +guardian +husk +mantis +moloch +thresher +watcher +water +submarine +red +green +blue +yellow +toxic +explosive +combustible +crate +renegade +ally +teamwork +railgun +nonsense +abyss +artifact +party +signal +airlock +scooter +ruins +C4 +Compound-N +hyperzine +plasma +morbusine +oxygenite +revolver +harpoon +ocean +wrench +door +man +comrade +mask +diving +monitor +lights +battery +junction +button +locker +crate +honk +clown +horn +grenade +stun +baton +circuit +death +life +fish +shark +damage +ruins +shaft +aft +starboard +ice +cold +hot +fire \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs index 7c237cb9d..7ffd85c78 100644 --- a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs @@ -102,6 +102,16 @@ namespace Barotrauma NewMessage("***************", Color.Cyan); })); + commands.Add(new Command("traitorlist", "traitorlist: List all the traitors and their targets.", (string[] args) => + { + if (GameMain.Server == null) return; + TraitorManager traitorManager = GameMain.Server.TraitorManager; + if (traitorManager == null) return; + foreach (Traitor T in traitorManager.TraitorList) + { + NewMessage("- Traitor " + T.Character.Name + "'s target is " + T.TargetCharacter.Name + ".", Color.Cyan); + } + })); commands.Add(new Command("createfilelist", "", (string[] args) => { diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs index 6c8e2574b..0b18a72f1 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs @@ -1,5 +1,6 @@ using Barotrauma.Networking; using System.Collections.Generic; +using System.IO; namespace Barotrauma { @@ -16,6 +17,8 @@ namespace Barotrauma partial class TraitorManager { + private static string CodeWords = Path.Combine("Content", "CodeWords.txt"); + public List TraitorList { get { return traitorList; } @@ -47,14 +50,21 @@ namespace Barotrauma traitorCandidates.Add(client.Character); } } - - if (server.Character!= null) characters.Add(server.Character); //Add host character + + if (server.Character != null) + { + characters.Add(server.Character); //Add host character + traitorCandidates.Add(server.Character); + } if (characters.Count < 2) { return; } + string codeWords = ToolBox.GetRandomLine(CodeWords) + ", " + ToolBox.GetRandomLine(CodeWords); + string codeResponse = ToolBox.GetRandomLine(CodeWords) + ", " + ToolBox.GetRandomLine(CodeWords); + traitorList = new List(); while (TraitorCount-- >= 0) { @@ -75,6 +85,34 @@ namespace Barotrauma //Add them to the list traitorList.Add(new Traitor(traitorCharacter, targetCharacter)); + string greetingMessage = "You are the Traitor! Your secret task is to assassinate " + targetCharacter.Name + "! Discretion is an utmost concern; sinking the submarine and killing the entire crew " + + "will arouse suspicion amongst the Fleet. If possible, make the death look like an accident."; + string moreAgentsMessage = "It is possible that there are other agents on this submarine. You don't know their names, but you do have a method of communication. " + + "Use the code words to greet the agent and code response to respond. Disguise such words in a normal-looking phrase so the crew doesn't suspect anything."; + moreAgentsMessage += "\nThe code words are: " + codeWords + "."; + moreAgentsMessage += "\nThe code response is: " + codeResponse + "."; + + if (server.Character != traitorCharacter) + { + var chatMsg = ChatMessage.Create( + null, + greetingMessage + "\n" + moreAgentsMessage, + (ChatMessageType)ChatMessageType.Server, + null); + + var msgBox = ChatMessage.Create( + null, + "There might be other agents. Use these to communicate with them." + + "\nThe code words are: " + codeWords + "." + + "\nThe code response is: " + codeResponse + ".", + (ChatMessageType)ChatMessageType.MessageBox, + null); + + Client client = server.ConnectedClients.Find(c => c.Character == traitorCharacter); + GameMain.Server.SendChatMessage(chatMsg, client); + GameMain.Server.SendChatMessage(msgBox, client); + } + #if CLIENT if (server.Character == null) { @@ -83,6 +121,10 @@ namespace Barotrauma else if (server.Character == traitorCharacter) { CreateStartPopUp(targetCharacter.Name); + GameMain.NetworkMember.AddChatMessage(greetingMessage + "\n" + moreAgentsMessage, ChatMessageType.Server); + GameMain.NetworkMember.AddChatMessage("There might be other agents. Use these to communicate with them." + + "\nThe code words are: " + codeWords + "." + + "\nThe code response is: " + codeResponse + ".", ChatMessageType.MessageBox); return; } #endif From c74f2d66b2e3cd8ebd18a9b53fb5fccd349fb3e1 Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Sun, 3 Dec 2017 23:26:02 +0300 Subject: [PATCH 4/9] one more keyword --- Barotrauma/BarotraumaShared/Content/CodeWords.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Barotrauma/BarotraumaShared/Content/CodeWords.txt b/Barotrauma/BarotraumaShared/Content/CodeWords.txt index e34ad11d5..4ebcad52f 100644 --- a/Barotrauma/BarotraumaShared/Content/CodeWords.txt +++ b/Barotrauma/BarotraumaShared/Content/CodeWords.txt @@ -72,4 +72,5 @@ starboard ice cold hot -fire \ No newline at end of file +fire +extinguisher \ No newline at end of file From 94b2c4c9e78265b942b1e1f71152af6ed48b25cc Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Mon, 4 Dec 2017 20:03:29 +0300 Subject: [PATCH 5/9] Moved code around a bit, moved traitor greeting to Greet function in Traitor class --- .../GameSession/GameModes/TraitorManager.cs | 122 ++++++++++-------- 1 file changed, 68 insertions(+), 54 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs index 0b18a72f1..24f9d5a5d 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs @@ -7,17 +7,65 @@ namespace Barotrauma partial class Traitor { public Character Character; - public Character TargetCharacter; + public Character TargetCharacter; //TODO: make a modular objective system (similar to crew missions) that allows for things OTHER than assasinations. - public Traitor(Character character, Character targetCharacter) + public Traitor(Character character) { - Character = character; TargetCharacter = targetCharacter; + Character = character; + } + + public void Greet(GameServer server) + { + //Greeting messages TODO: Move this to a function in Traitor class + string greetingMessage = "You are the Traitor! Your secret task is to assassinate " + TargetCharacter.Name + "! Discretion is an utmost concern; sinking the submarine and killing the entire crew " + + "will arouse suspicion amongst the Fleet. If possible, make the death look like an accident."; + string moreAgentsMessage = "It is possible that there are other agents on this submarine. You don't know their names, but you do have a method of communication. " + + "Use the code words to greet the agent and code response to respond. Disguise such words in a normal-looking phrase so the crew doesn't suspect anything."; + moreAgentsMessage += "\nThe code words are: " + server.TraitorManager.codeWords + "."; + moreAgentsMessage += "\nThe code response is: " + server.TraitorManager.codeResponse + ".\n"; + + if (server.Character != Character) + { + var chatMsg = ChatMessage.Create( + null, + greetingMessage + "\n" + moreAgentsMessage, + (ChatMessageType)ChatMessageType.Server, + null); + + var msgBox = ChatMessage.Create( + null, + "There might be other agents. Use these to communicate with them." + + "\nThe code words are: " + server.TraitorManager.codeWords + "." + + "\nThe code response is: " + server.TraitorManager.codeResponse + ".", + (ChatMessageType)ChatMessageType.MessageBox, + null); + + Client client = server.ConnectedClients.Find(c => c.Character == Character); + GameMain.Server.SendChatMessage(chatMsg, client); + GameMain.Server.SendChatMessage(msgBox, client); + } + +#if CLIENT + if (server.Character == null) + { + new GUIMessageBox("New traitor", Character.Name + " is the traitor and the target is " + Character.Name+"."); + } + else if (server.Character == Character) + { + TraitorManager.CreateStartPopUp(TargetCharacter.Name); + GameMain.NetworkMember.AddChatMessage(greetingMessage + "\n" + moreAgentsMessage, ChatMessageType.Server); + GameMain.NetworkMember.AddChatMessage("There might be other agents. Use these to communicate with them." + + "\nThe code words are: " + server.TraitorManager.codeWords + "." + + "\nThe code response is: " + server.TraitorManager.codeResponse + ".", ChatMessageType.MessageBox); + return; + } +#endif } } partial class TraitorManager { - private static string CodeWords = Path.Combine("Content", "CodeWords.txt"); + private static string wordsTxt = Path.Combine("Content", "CodeWords.txt"); public List TraitorList { @@ -26,6 +74,8 @@ namespace Barotrauma private List traitorList; + public string codeWords, codeResponse; + public TraitorManager(GameServer server, int TraitorCount) { if(TraitorCount < 1) //what why how @@ -62,8 +112,8 @@ namespace Barotrauma return; } - string codeWords = ToolBox.GetRandomLine(CodeWords) + ", " + ToolBox.GetRandomLine(CodeWords); - string codeResponse = ToolBox.GetRandomLine(CodeWords) + ", " + ToolBox.GetRandomLine(CodeWords); + codeWords = ToolBox.GetRandomLine(wordsTxt) + ", " + ToolBox.GetRandomLine(wordsTxt); + codeResponse = ToolBox.GetRandomLine(wordsTxt) + ", " + ToolBox.GetRandomLine(wordsTxt); traitorList = new List(); while (TraitorCount-- >= 0) @@ -72,62 +122,26 @@ namespace Barotrauma break; int traitorIndex = Rand.Int(traitorCandidates.Count); - var traitorCharacter = traitorCandidates[traitorIndex]; + Character traitorCharacter = traitorCandidates[traitorIndex]; traitorCandidates.Remove(traitorCharacter); + //Add them to the list + traitorList.Add(new Traitor(traitorCharacter)); + } + + //Now that traitors have been decided, let's do objectives in post for deciding things like Document Exchange. + foreach (Traitor traitor in traitorList) + { + Character traitorCharacter = traitor.Character; int targetIndex = Rand.Int(characters.Count); while (characters[targetIndex] == traitorCharacter) //Cannot target self { targetIndex = Rand.Int(characters.Count); } - var targetCharacter = characters[targetIndex]; - //Add them to the list - traitorList.Add(new Traitor(traitorCharacter, targetCharacter)); - - string greetingMessage = "You are the Traitor! Your secret task is to assassinate " + targetCharacter.Name + "! Discretion is an utmost concern; sinking the submarine and killing the entire crew " - + "will arouse suspicion amongst the Fleet. If possible, make the death look like an accident."; - string moreAgentsMessage = "It is possible that there are other agents on this submarine. You don't know their names, but you do have a method of communication. " - + "Use the code words to greet the agent and code response to respond. Disguise such words in a normal-looking phrase so the crew doesn't suspect anything."; - moreAgentsMessage += "\nThe code words are: " + codeWords + "."; - moreAgentsMessage += "\nThe code response is: " + codeResponse + "."; - - if (server.Character != traitorCharacter) - { - var chatMsg = ChatMessage.Create( - null, - greetingMessage + "\n" + moreAgentsMessage, - (ChatMessageType)ChatMessageType.Server, - null); - - var msgBox = ChatMessage.Create( - null, - "There might be other agents. Use these to communicate with them." + - "\nThe code words are: " + codeWords + "." + - "\nThe code response is: " + codeResponse + ".", - (ChatMessageType)ChatMessageType.MessageBox, - null); - - Client client = server.ConnectedClients.Find(c => c.Character == traitorCharacter); - GameMain.Server.SendChatMessage(chatMsg, client); - GameMain.Server.SendChatMessage(msgBox, client); - } - -#if CLIENT - if (server.Character == null) - { - new GUIMessageBox("New traitor", traitorCharacter.Name + " is the traitor and the target is " + targetCharacter.Name+"."); - } - else if (server.Character == traitorCharacter) - { - CreateStartPopUp(targetCharacter.Name); - GameMain.NetworkMember.AddChatMessage(greetingMessage + "\n" + moreAgentsMessage, ChatMessageType.Server); - GameMain.NetworkMember.AddChatMessage("There might be other agents. Use these to communicate with them." + - "\nThe code words are: " + codeWords + "." + - "\nThe code response is: " + codeResponse + ".", ChatMessageType.MessageBox); - return; - } -#endif + Character targetCharacter = characters[targetIndex]; + traitor.TargetCharacter = targetCharacter; + traitor.Greet(server); } } From 3b02f0c86a37315ff581caf36ebde2481d483f17 Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Tue, 5 Dec 2017 00:20:36 +0300 Subject: [PATCH 6/9] Seems like sending a long-winded copy-paste of the traitor greeting message to host when he's still in lobby causes an error: https://cdn.discordapp.com/attachments/386620407035330561/387295192946049025/unknown.png This is mostly a bugfix --- .../GameSession/GameModes/TraitorManager.cs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs index 24f9d5a5d..8c201805d 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs @@ -14,15 +14,15 @@ namespace Barotrauma Character = character; } - public void Greet(GameServer server) + public void Greet(GameServer server, string codeWords, string codeResponse) { //Greeting messages TODO: Move this to a function in Traitor class string greetingMessage = "You are the Traitor! Your secret task is to assassinate " + TargetCharacter.Name + "! Discretion is an utmost concern; sinking the submarine and killing the entire crew " + "will arouse suspicion amongst the Fleet. If possible, make the death look like an accident."; string moreAgentsMessage = "It is possible that there are other agents on this submarine. You don't know their names, but you do have a method of communication. " + "Use the code words to greet the agent and code response to respond. Disguise such words in a normal-looking phrase so the crew doesn't suspect anything."; - moreAgentsMessage += "\nThe code words are: " + server.TraitorManager.codeWords + "."; - moreAgentsMessage += "\nThe code response is: " + server.TraitorManager.codeResponse + ".\n"; + moreAgentsMessage += "\nThe code words are: " + codeWords + "."; + moreAgentsMessage += "\nThe code response is: " + codeResponse + ".\n"; if (server.Character != Character) { @@ -35,8 +35,8 @@ namespace Barotrauma var msgBox = ChatMessage.Create( null, "There might be other agents. Use these to communicate with them." + - "\nThe code words are: " + server.TraitorManager.codeWords + "." + - "\nThe code response is: " + server.TraitorManager.codeResponse + ".", + "\nThe code words are: " + codeWords + "." + + "\nThe code response is: " + codeResponse + ".", (ChatMessageType)ChatMessageType.MessageBox, null); @@ -48,15 +48,12 @@ namespace Barotrauma #if CLIENT if (server.Character == null) { - new GUIMessageBox("New traitor", Character.Name + " is the traitor and the target is " + Character.Name+"."); + new GUIMessageBox("New traitor", Character.Name + " is the traitor and the target is " + TargetCharacter.Name+"."); } else if (server.Character == Character) { TraitorManager.CreateStartPopUp(TargetCharacter.Name); - GameMain.NetworkMember.AddChatMessage(greetingMessage + "\n" + moreAgentsMessage, ChatMessageType.Server); - GameMain.NetworkMember.AddChatMessage("There might be other agents. Use these to communicate with them." + - "\nThe code words are: " + server.TraitorManager.codeWords + "." + - "\nThe code response is: " + server.TraitorManager.codeResponse + ".", ChatMessageType.MessageBox); + GameMain.NetworkMember.AddChatMessage(moreAgentsMessage, ChatMessageType.Server); return; } #endif @@ -141,7 +138,7 @@ namespace Barotrauma Character targetCharacter = characters[targetIndex]; traitor.TargetCharacter = targetCharacter; - traitor.Greet(server); + traitor.Greet(server, codeWords, codeResponse); } } From 38815c3b69c506fc8f67ebc27cb0538a38ed2105 Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Tue, 5 Dec 2017 00:30:21 +0300 Subject: [PATCH 7/9] Added code words to traitorlist console command --- Barotrauma/BarotraumaShared/Source/DebugConsole.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs index c16f5fcd0..177d6ed94 100644 --- a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs @@ -111,6 +111,7 @@ namespace Barotrauma { NewMessage("- Traitor " + T.Character.Name + "'s target is " + T.TargetCharacter.Name + ".", Color.Cyan); } + NewMessage("The code words are: " + traitorManager.codeWords + ", response: " + traitorManager.codeResponse + ".", Color.Cyan); })); commands.Add(new Command("createfilelist", "", (string[] args) => From 1e8c1f7f04192c7172ba5849624acd6168e4fe5b Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Tue, 5 Dec 2017 16:17:51 +0300 Subject: [PATCH 8/9] Fixed a NullReferenceException caused when you try to play a round with traitors enabled while there are not enough player characters. --- .../Source/GameSession/GameModes/TraitorManager.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs index 8c201805d..e3d4790c5 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs @@ -69,7 +69,7 @@ namespace Barotrauma get { return traitorList; } } - private List traitorList; + private List traitorList = new List(); public string codeWords, codeResponse; @@ -112,7 +112,6 @@ namespace Barotrauma codeWords = ToolBox.GetRandomLine(wordsTxt) + ", " + ToolBox.GetRandomLine(wordsTxt); codeResponse = ToolBox.GetRandomLine(wordsTxt) + ", " + ToolBox.GetRandomLine(wordsTxt); - traitorList = new List(); while (TraitorCount-- >= 0) { if (traitorCandidates.Count <= 0) From 6e78e945a7562c6e439ee0e2babd34295ed52ab5 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Tue, 5 Dec 2017 19:05:21 +0200 Subject: [PATCH 9/9] Minor code style nitpicking :) --- Barotrauma/BarotraumaShared/Source/DebugConsole.cs | 4 ++-- .../Source/GameSession/GameModes/TraitorManager.cs | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs index 177d6ed94..df9a05ad7 100644 --- a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs @@ -107,9 +107,9 @@ namespace Barotrauma if (GameMain.Server == null) return; TraitorManager traitorManager = GameMain.Server.TraitorManager; if (traitorManager == null) return; - foreach (Traitor T in traitorManager.TraitorList) + foreach (Traitor t in traitorManager.TraitorList) { - NewMessage("- Traitor " + T.Character.Name + "'s target is " + T.TargetCharacter.Name + ".", Color.Cyan); + NewMessage("- Traitor " + t.Character.Name + "'s target is " + t.TargetCharacter.Name + ".", Color.Cyan); } NewMessage("The code words are: " + traitorManager.codeWords + ", response: " + traitorManager.codeResponse + ".", Color.Cyan); })); diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs index e3d4790c5..027561f23 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/TraitorManager.cs @@ -6,7 +6,7 @@ namespace Barotrauma { partial class Traitor { - public Character Character; + public readonly Character Character; public Character TargetCharacter; //TODO: make a modular objective system (similar to crew missions) that allows for things OTHER than assasinations. public Traitor(Character character) @@ -73,17 +73,17 @@ namespace Barotrauma public string codeWords, codeResponse; - public TraitorManager(GameServer server, int TraitorCount) + public TraitorManager(GameServer server, int traitorCount) { - if(TraitorCount < 1) //what why how + if (traitorCount < 1) //what why how { - TraitorCount = 1; + traitorCount = 1; DebugConsole.ThrowError("Traitor Manager: TraitorCount somehow ended up less than 1, setting it to 1."); } - Start(server, TraitorCount); + Start(server, traitorCount); } - private void Start(GameServer server, int TraitorCount) + private void Start(GameServer server, int traitorCount) { if (server == null) return; @@ -112,7 +112,7 @@ namespace Barotrauma codeWords = ToolBox.GetRandomLine(wordsTxt) + ", " + ToolBox.GetRandomLine(wordsTxt); codeResponse = ToolBox.GetRandomLine(wordsTxt) + ", " + ToolBox.GetRandomLine(wordsTxt); - while (TraitorCount-- >= 0) + while (traitorCount-- >= 0) { if (traitorCandidates.Count <= 0) break;