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
This commit is contained in:
Alex Noir
2017-12-03 00:43:14 +03:00
parent 0740ca84bc
commit 56df7b6900
2 changed files with 123 additions and 83 deletions
@@ -3,55 +3,77 @@ using System.Collections.Generic;
namespace Barotrauma namespace Barotrauma
{ {
partial class Traitor
{
public Character Character;
public Character TargetCharacter;
public Traitor(Character character, Character targetCharacter)
{
Character = character; TargetCharacter = targetCharacter;
}
}
partial class TraitorManager partial class TraitorManager
{ {
public Character TraitorCharacter public List<Traitor> TraitorList
{ {
get { return traitorCharacter; } get { return traitorList; }
} }
public Character TargetCharacter private List<Traitor> 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; private void Start(GameServer server, int TraitorCount)
public TraitorManager(GameServer server)
{
Start(server);
}
private void Start(GameServer server)
{ {
if (server == null) return; if (server == null) return;
List<Character> characters = new List<Character>(); List<Character> characters = new List<Character>(); //ANYONE can be a target.
List<Character> traitorCandidates = new List<Character>(); //Keep this to not re-pick traitors twice
foreach (Client client in server.ConnectedClients) foreach (Client client in server.ConnectedClients)
{ {
if (client.Character != null) if (client.Character != null)
{
characters.Add(client.Character); 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) if (characters.Count < 2)
{ {
traitorCharacter = null;
targetCharacter = null;
return; return;
} }
int traitorIndex = Rand.Range(0, characters.Count); traitorList = new List<Traitor>();
while (TraitorCount-- >= 0)
int targetIndex = Rand.Range(0, characters.Count);
while (targetIndex == traitorIndex)
{ {
targetIndex = Rand.Range(0, characters.Count); if (traitorCandidates.Count <= 0)
} break;
traitorCharacter = characters[traitorIndex]; int traitorIndex = Rand.Int(traitorCandidates.Count);
targetCharacter = characters[targetIndex]; 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 CLIENT
if (server.Character == null) if (server.Character == null)
@@ -65,14 +87,19 @@ namespace Barotrauma
} }
#endif #endif
} }
}
public string GetEndMessage() public string GetEndMessage()
{ {
if (GameMain.Server == null || traitorCharacter == null || targetCharacter == null) return ""; if (GameMain.Server == null || traitorList.Count <= 0) return "";
string endMessage = ""; string endMessage = "";
endMessage = traitorCharacter.Name + " was a traitor! "; 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 += (traitorCharacter.Info.Gender == Gender.Male) ? "His" : "Her";
endMessage += " task was to assassinate " + targetCharacter.Name; endMessage += " task was to assassinate " + targetCharacter.Name;
@@ -118,6 +145,8 @@ namespace Barotrauma
endMessage += "."; endMessage += ".";
} }
} }
endMessage += "\n";
}
return endMessage; return endMessage;
} }
@@ -1323,11 +1323,22 @@ namespace Barotrauma.Networking
if (TraitorsEnabled == YesNoMaybe.Yes || if (TraitorsEnabled == YesNoMaybe.Yes ||
(TraitorsEnabled == YesNoMaybe.Maybe && Rand.Range(0.0f, 1.0f) < 0.5f)) (TraitorsEnabled == YesNoMaybe.Maybe && Rand.Range(0.0f, 1.0f) < 0.5f))
{ {
TraitorManager = new TraitorManager(this); List<Character> characters = new List<Character>();
foreach (Client client in ConnectedClients)
if (TraitorManager.TraitorCharacter!=null && TraitorManager.TargetCharacter != null)
{ {
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(AllowRespawn && missionAllowRespawn);
msg.Write(Submarine.MainSubs[1] != null); //loadSecondSub msg.Write(Submarine.MainSubs[1] != null); //loadSecondSub
if (TraitorManager != null && Traitor traitor = null;
TraitorManager.TraitorCharacter != null && if (TraitorManager != null && TraitorManager.TraitorList.Count > 0)
TraitorManager.TargetCharacter != null && traitor = TraitorManager.TraitorList.Find(t => t.Character == client.Character);
TraitorManager.TraitorCharacter == client.Character) if (traitor != null)
{ {
msg.Write(true); msg.Write(true);
msg.Write(TraitorManager.TargetCharacter.Name); msg.Write(traitor.TargetCharacter.Name);
} }
else else
{ {