From e94e2a8ded12ef205efa33cc4659f405f60aee25 Mon Sep 17 00:00:00 2001 From: whateverusername0 Date: Fri, 14 Jun 2024 21:44:32 +1000 Subject: [PATCH] traitor flavor --- .../Rules/Components/TraitorRuleComponent.cs | 3 +- .../GameTicking/Rules/TraitorRuleSystem.cs | 53 +++++++++++--- Content.Server/Objectives/ObjectivesSystem.cs | 69 ++++++++++--------- .../game-presets/preset-traitor.ftl | 20 ++++-- .../Locale/en-US/objectives/round-end.ftl | 4 +- .../Locale/en-US/prototypes/roles/antags.ftl | 8 +-- Resources/Locale/en-US/traitor/flavor.ftl | 65 +++++++++++++++++ .../Prototypes/Datasets/corporations.yml | 12 ---- .../Prototypes/Datasets/traitor_flavor.yml | 14 ++++ Resources/Prototypes/Roles/Antags/traitor.yml | 4 +- 10 files changed, 185 insertions(+), 67 deletions(-) create mode 100644 Resources/Locale/en-US/traitor/flavor.ftl delete mode 100644 Resources/Prototypes/Datasets/corporations.yml create mode 100644 Resources/Prototypes/Datasets/traitor_flavor.yml diff --git a/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs index 62f92963aa7..31775d67b3f 100644 --- a/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs +++ b/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs @@ -29,10 +29,11 @@ public sealed partial class TraitorRuleComponent : Component public ProtoId CodewordVerbs = "verbs"; [DataField] - public ProtoId ObjectiveIssuers = "TraitorCorporations"; + public ProtoId ObjectiveIssuers = "TraitorFlavor"; public int TotalTraitors => TraitorMinds.Count; public string[] Codewords = new string[3]; + public string ObjectiveIssuer = string.Empty; public enum SelectionState { diff --git a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs index 4e4191a51bf..ff349b8837c 100644 --- a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs @@ -41,6 +41,7 @@ public override void Initialize() SubscribeLocalEvent(AfterEntitySelected); + SubscribeLocalEvent(OnObjectivesTextGetInfo, after: new[] { typeof(AntagSelectionSystem) }); SubscribeLocalEvent(OnObjectivesTextPrepend); } @@ -82,6 +83,7 @@ public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component, bool var briefing = Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", component.Codewords))); var issuer = _random.Pick(_prototypeManager.Index(component.ObjectiveIssuers).Values); + component.ObjectiveIssuer = issuer; Note[]? code = null; if (giveUplink) @@ -99,13 +101,9 @@ public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component, bool // Give traitors their codewords and uplink code to keep in their character info menu code = EnsureComp(pda.Value).Code; - - // If giveUplink is false the uplink code part is omitted - briefing = string.Format("{0}\n{1}", briefing, - Loc.GetString("traitor-role-uplink-code-short", ("code", string.Join("-", code).Replace("sharp", "#")))); } - _antag.SendBriefing(traitor, GenerateBriefing(component.Codewords, code, issuer), null, component.GreetSoundNotification); + _antag.SendBriefing(traitor, GenerateBriefing(component.Codewords, code, issuer), Color.Crimson, component.GreetSoundNotification); component.TraitorMinds.Add(mindId); @@ -113,7 +111,7 @@ public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component, bool // Assign briefing _roleSystem.MindAddRole(mindId, new RoleBriefingComponent { - Briefing = briefing + Briefing = GenerateBriefingCharacter(component.Codewords, code, issuer) }, mind, true); // Send codewords to only the traitor client @@ -129,6 +127,12 @@ public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component, bool return true; } + private void OnObjectivesTextGetInfo(EntityUid uid, TraitorRuleComponent comp, ref ObjectivesTextGetInfoEvent args) + { + args.AgentName = Loc.GetString($"traitor-{comp.ObjectiveIssuer}-roundend"); + args.Faction = Loc.GetString($"traitor-round-end-agent-name"); + } + // TODO: AntagCodewordsComponent private void OnObjectivesTextPrepend(EntityUid uid, TraitorRuleComponent comp, ref ObjectivesTextPrependEvent args) { @@ -136,13 +140,42 @@ private void OnObjectivesTextPrepend(EntityUid uid, TraitorRuleComponent comp, r } // TODO: figure out how to handle this? add priority to briefing event? - private string GenerateBriefing(string[] codewords, Note[]? uplinkCode, string? objectiveIssuer = null) + private string GenerateBriefing(string[] codewords, Note[]? uplinkCode, string objectiveIssuer) + { + var sb = new StringBuilder(); + sb.AppendLine("\n" + Loc.GetString($"traitor-{objectiveIssuer}-intro")); + + if (uplinkCode != null) + { + sb.AppendLine("\n" + Loc.GetString($"traitor-{objectiveIssuer}-uplink")); + sb.AppendLine(Loc.GetString($"traitor-role-uplink-code", ("code", string.Join("-", uplinkCode).Replace("sharp", "#")))); + } + else sb.AppendLine("\n" + Loc.GetString($"traitor-role-nouplink")); + + sb.AppendLine("\n" + Loc.GetString($"traitor-role-codewords", ("codewords", string.Join(", ", codewords)))); + + sb.AppendLine("\n" + Loc.GetString($"traitor-role-moreinfo")); + + return sb.ToString(); + } + private string GenerateBriefingCharacter(string[] codewords, Note[]? uplinkCode, string objectiveIssuer) { var sb = new StringBuilder(); - sb.AppendLine(Loc.GetString("traitor-role-greeting", ("corporation", objectiveIssuer ?? Loc.GetString("objective-issuer-unknown")))); - sb.AppendLine(Loc.GetString("traitor-role-codewords", ("codewords", string.Join(", ", codewords)))); + sb.AppendLine("\n" + Loc.GetString($"traitor-{objectiveIssuer}-intro")); + if (uplinkCode != null) - sb.AppendLine(Loc.GetString("traitor-role-uplink-code", ("code", string.Join("-", uplinkCode).Replace("sharp", "#")))); + sb.AppendLine(Loc.GetString($"traitor-role-uplink-code-short", ("code", string.Join("-", uplinkCode).Replace("sharp", "#")))); + else sb.AppendLine("\n" + Loc.GetString($"traitor-role-nouplink")); + + sb.AppendLine(Loc.GetString($"traitor-role-codewords-short", ("codewords", string.Join(", ", codewords)))); + + sb.AppendLine("\n" + Loc.GetString($"traitor-role-allegiances")); + sb.AppendLine(Loc.GetString($"traitor-{objectiveIssuer}-allies")); + + sb.AppendLine("\n" + Loc.GetString($"traitor-role-notes")); + sb.AppendLine(Loc.GetString($"traitor-{objectiveIssuer}-goal")); + + sb.AppendLine("\n" + Loc.GetString($"traitor-role-clarity")); return sb.ToString(); } diff --git a/Content.Server/Objectives/ObjectivesSystem.cs b/Content.Server/Objectives/ObjectivesSystem.cs index 73bb74d5244..83886073e79 100644 --- a/Content.Server/Objectives/ObjectivesSystem.cs +++ b/Content.Server/Objectives/ObjectivesSystem.cs @@ -52,7 +52,7 @@ public override void Shutdown() private void OnRoundEndText(RoundEndTextAppendEvent ev) { // go through each gamerule getting data for the roundend summary. - var summaries = new Dictionary>>(); + var summaries = new Dictionary>>>(); var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var gameRule)) { @@ -64,17 +64,21 @@ private void OnRoundEndText(RoundEndTextAppendEvent ev) if (info.Minds.Count == 0) continue; - // first group the gamerules by their agents, for example 2 different dragons - var agent = info.AgentName; + // first group the gamerules by their factions, for example 2 different dragons + var agent = info.Faction ?? info.AgentName; if (!summaries.ContainsKey(agent)) - summaries[agent] = new Dictionary>(); + summaries[agent] = new Dictionary>>(); + + // next group them by agent names, for example different traitors, blood brother teams, etc. + if (!summaries[agent].ContainsKey(info.AgentName)) + summaries[agent][info.AgentName] = new Dictionary>(); var prepend = new ObjectivesTextPrependEvent(""); RaiseLocalEvent(uid, ref prepend); // next group them by their prepended texts // for example with traitor rule, group them by the codewords they share - var summary = summaries[agent]; + var summary = summaries[agent][info.AgentName]; if (summary.ContainsKey(prepend.Text)) { // same prepended text (usually empty) so combine them @@ -87,36 +91,39 @@ private void OnRoundEndText(RoundEndTextAppendEvent ev) } // convert the data into summary text - foreach (var (agent, summary) in summaries) + foreach (var (faction, summariesFaction) in summaries) { - // first get the total number of players that were in these game rules combined - var total = 0; - var totalInCustody = 0; - foreach (var (_, minds) in summary) + foreach (var (agent, summary) in summariesFaction) { - total += minds.Count; - totalInCustody += minds.Where(pair => IsInCustody(pair.Item1)).Count(); - } + // first get the total number of players that were in these game rules combined + var total = 0; + var totalInCustody = 0; + foreach (var (_, minds) in summary) + { + total += minds.Count; + totalInCustody += minds.Where(m => IsInCustody(m.Item1)).Count(); + } - var result = new StringBuilder(); - result.AppendLine(Loc.GetString("objectives-round-end-result", ("count", total), ("agent", agent))); - if (agent == Loc.GetString("traitor-round-end-agent-name")) - { - result.AppendLine(Loc.GetString("objectives-round-end-result-in-custody", ("count", total), ("custody", totalInCustody), ("agent", agent))); - } - // next add all the players with its own prepended text - foreach (var (prepend, minds) in summary) - { - if (prepend != string.Empty) - result.Append(prepend); + var result = new StringBuilder(); + result.AppendLine(Loc.GetString("objectives-round-end-result", ("count", total), ("agent", faction))); + if (agent == Loc.GetString("traitor-round-end-agent-name")) + { + result.AppendLine(Loc.GetString("objectives-round-end-result-in-custody", ("count", total), ("custody", totalInCustody), ("agent", faction))); + } + // next add all the players with its own prepended text + foreach (var (prepend, minds) in summary) + { + if (prepend != string.Empty) + result.Append(prepend); - // add space between the start text and player list - result.AppendLine(); + // add space between the start text and player list + result.AppendLine(); - AddSummary(result, agent, minds); - } + AddSummary(result, agent, minds); + } - ev.AddLine(result.AppendLine().ToString()); + ev.AddLine(result.AppendLine().ToString()); + } } } @@ -252,7 +259,7 @@ private bool IsInCustody(EntityUid mindId, MindComponent? mind = null) /// Get the title for a player's mind used in round end. /// Pass in the original entity name which is shown alongside username. /// - public string GetTitle(Entity mind, string name) + public string GetTitle(Entity mind, string name = "") { if (Resolve(mind, ref mind.Comp) && mind.Comp.OriginalOwnerUserId != null && @@ -306,7 +313,7 @@ private void CreateCompletions() /// The objectives system already checks if the game rule is added so you don't need to check that in this event's handler. /// [ByRefEvent] -public record struct ObjectivesTextGetInfoEvent(List<(EntityUid, string)> Minds, string AgentName); +public record struct ObjectivesTextGetInfoEvent(List<(EntityUid, string)> Minds, string AgentName, string? Faction = null); /// /// Raised on the game rule before text for each agent's objectives is added, letting you prepend something. diff --git a/Resources/Locale/en-US/game-ticking/game-presets/preset-traitor.ftl b/Resources/Locale/en-US/game-ticking/game-presets/preset-traitor.ftl index fd3e6b82aa7..435d1233cdb 100644 --- a/Resources/Locale/en-US/game-ticking/game-presets/preset-traitor.ftl +++ b/Resources/Locale/en-US/game-ticking/game-presets/preset-traitor.ftl @@ -23,11 +23,6 @@ traitor-death-match-end-round-description-entry = {$originalName}'s PDA, with {$ ## TraitorRole # TraitorRole -traitor-role-greeting = - You are an agent sent by {$corporation} on behalf of [color = darkred]The Syndicate.[/color] - Your objectives and codewords are listed in the character menu. - Use the uplink loaded into your PDA to buy the tools you'll need for this mission. - Death to Nanotrasen! traitor-role-codewords = The codewords are: [color = lightgray] {$codewords}.[/color] @@ -37,6 +32,21 @@ traitor-role-uplink-code = Set your ringtone to the notes [color = lightgray]{$code}[/color] to lock or unlock your uplink. Remember to lock it after, or the stations crew will easily open it too! +traitor-role-moreinfo = + Find more information about your role in the character menu. + +traitor-role-nouplink = + You do not have a syndicate uplink. Make it count. + +traitor-role-allegiances = + Your allegiances: + +traitor-role-notes = + Notes from your employer: + +traitor-role-clarity = + Allegiances and additional notes are recommendations. You do not have to strictly follow them. + # don't need all the flavour text for character menu traitor-role-codewords-short = The codewords are: diff --git a/Resources/Locale/en-US/objectives/round-end.ftl b/Resources/Locale/en-US/objectives/round-end.ftl index 3da81fc9640..ca6ed99d20f 100644 --- a/Resources/Locale/en-US/objectives/round-end.ftl +++ b/Resources/Locale/en-US/objectives/round-end.ftl @@ -8,8 +8,8 @@ objectives-round-end-result-in-custody = {$custody} out of {$count} {MAKEPLURAL( objectives-player-user-named = [color=White]{$name}[/color] ([color=gray]{$user}[/color]) objectives-player-named = [color=White]{$name}[/color] -objectives-no-objectives = {$custody}{$title} was a {$agent}. -objectives-with-objectives = {$custody}{$title} was a {$agent} who had the following objectives: +objectives-no-objectives = {$custody}{$title} was {$agent}. +objectives-with-objectives = {$custody}{$title} was {$agent} who had the following objectives: objectives-objective-success = {$objective} | [color={$markupColor}]Success![/color] objectives-objective-fail = {$objective} | [color={$markupColor}]Failure![/color] ({$progress}%) diff --git a/Resources/Locale/en-US/prototypes/roles/antags.ftl b/Resources/Locale/en-US/prototypes/roles/antags.ftl index ba43d4ff85b..efaaa4bad86 100644 --- a/Resources/Locale/en-US/prototypes/roles/antags.ftl +++ b/Resources/Locale/en-US/prototypes/roles/antags.ftl @@ -1,5 +1,5 @@ -roles-antag-syndicate-agent-name = Syndicate agent -roles-antag-syndicate-agent-objective = Complete your objectives without being caught. +roles-antag-traitor-name = Traitor +roles-antag-traitor-objective = Complete your objectives without being caught. roles-antag-syndicate-agent-sleeper-name = Syndicate sleeper agent roles-antag-syndicate-agent-sleeper-objective = A form of syndicate agent that can activate at any point in the middle of the shift. @@ -17,13 +17,13 @@ roles-antag-suspicion-suspect-name = Suspect roles-antag-suspicion-suspect-objective = Kill the innocents. roles-antag-nuclear-operative-commander-name = Nuclear operative commander -roles-antag-nuclear-operative-commander-objective = Lead your team to the destruction of the station. +roles-antag-nuclear-operative-commander-objective = Lead your team to the destruction of the station! roles-antag-nuclear-operative-agent-name = Nuclear operative agent roles-antag-nuclear-operative-agent-objective = Like default operative, the team's treatment will have priority. roles-antag-nuclear-operative-name = Nuclear operative -roles-antag-nuclear-operative-objective = Find the nuke disk and blow up the station. +roles-antag-nuclear-operative-objective = Find the nuke disk and blow up the station! roles-antag-subverted-silicon-name = Subverted silicon roles-antag-subverted-silicon-objective = Follow your new laws and do bad unto the station. diff --git a/Resources/Locale/en-US/traitor/flavor.ftl b/Resources/Locale/en-US/traitor/flavor.ftl new file mode 100644 index 00000000000..672582591ea --- /dev/null +++ b/Resources/Locale/en-US/traitor/flavor.ftl @@ -0,0 +1,65 @@ +traitor-arc-intro = You are the ARC terrorist. +traitor-arc-goal = The creatures of this world must be freed from the iron grasp of Nanotrasen, and you are their only hope! +traitor-arc-allies = You may cooperate with other syndicate agents if you support our cause. Maybe you can convince the Bee Liberation Front agents to cooperate for once? +traitor-arc-uplink = The Syndicate have graciously given one of their PDA-uplinks for your task. +traitor-arc-roundend = [color=green]an activist from the Animal Rights Consortium[/color] + +traitor-blf-intro = You are the Bee Liberation Front activist. +traitor-blf-goal = We must prove ourselves to the Syndicate or we will not be able to join. Animal Rights Consort will roll us! +traitor-blf-allies = You may cooperate with other syndicate agents if they support our cause. Maybe you can recruit an Animal Rights Consort to be useful for once? +traitor-blf-uplink = The Syndicate have graciously given one of their PDA-uplinks to see if we are worthy. +traitor-blf-roundend = [color=green]an activist from Bee Liberation Front[/color] + +traitor-cybersun-intro = You are a specialist from Cybersun Industries. +traitor-cybersun-goal = Do not establish substantial presence on the designated facility, as larger incidents are harder to cover up. +traitor-cybersun-allies = Fellow Cybersun operatives are to be trusted. Members of the MI13 organization can be trusted. All other syndicate agents are not to be trusted. +traitor-cybersun-uplink = You have been supplied the tools for the job in the form of a syndicate uplink located in your PDA. +traitor-cybersun-roundend = [color=yellow]a specialist from Cybersun Industries[/color] + +traitor-corporateclimber-intro = You are a Corporate Climber. +traitor-corporateclimber-goal = Killing needlessly would make you some kind of traitor, or at least definitely seen as one. This is all just a means to an end. +traitor-corporateclimber-allies = Death to the Syndicate. +traitor-corporateclimber-uplink = You have connections to the black market for the deeds. Your uplink is located in your PDA. Knock off a few loose weights, and your climb will be so much smoother. +traitor-corporateclimber-roundend = [color=yellow]a corporate climber.[/color] + +traitor-donkco-intro = You are a Donk Co. infiltrator. +traitor-donkco-goal = We do not approve of mindless killing of innocent workers; get in, get done, get out is our motto. +traitor-donkco-allies = Members of Waffle Co. are to be killed on sight; they are not allowed to be on the station while we're around. +traitor-donkco-uplink = You have been provided with a syndicate uplink located in your PDA to accomplish your task. +traitor-donkco-roundend = [color=orange]an employee from Donk Corporation[/color] + +traitor-gorlex-intro = You are a Gorlex Marauder. +traitor-gorlex-goal = Getting noticed is not an issue, and you may use any level of ordinance to get the job done. That being said, do not make this sloppy by dragging in random slaughter. +traitor-gorlex-allies = You may collaborate with any friends of the Syndicate coalition, but keep an eye on any of those Tiger punks if they do show up. +traitor-gorlex-uplink = You have been provided with a syndicate uplink located in your PDA to accomplish your task. +traitor-gorlex-roundend = [color=red]a Gorlex Marauder[/color] + +traitor-legaltrouble-intro = You are in legal trouble. +traitor-legaltrouble-goal = Try to finish your to-do list, and don't get caught. If they find out what you're actually doing, this scandal will go galactic. +traitor-legaltrouble-allies = Death to the Syndicate. +traitor-legaltrouble-uplink = You've connected to the black market to clean this mess up. Your uplink is located in your PDA. If there's no evidence, there's no crime. +traitor-legaltrouble-roundend = [color=white]in Legal Trouble[/color] + +traitor-mi13-intro = You are the MI13 agent. +traitor-mi13-goal = Avoid killing innocent personnel at all costs. You are not here to mindlessly kill people, as that would attract too much attention and is not our goal. Avoid detection at all costs. +traitor-mi13-allies = You are the only operative we are sending, any others are fake. All other syndicate agents are not to be trusted, with the exception of Cybersun specialists. +traitor-mi13-uplink = You have been provided with a syndicate uplink located in your PDA to accomplish your task. +traitor-mi13-roundend = [color=cyan]an MI13 agent[/color] + +traitor-tiger-intro = You are the Tiger Cooperative Fanatic. +traitor-tiger-goal = Remember the teachings of Hy-lurgixon; kill first, ask questions later! +traitor-tiger-allies = Only the enlightened Tiger brethren can be trusted; all others must be expelled from this mortal realm! +traitor-tiger-uplink = You have been provided with a syndicate uplink from your friends at Cybersun Industries to prove yourself to the changeling hive. If you accomplish your tasks, you will be assimilated. +traitor-tiger-roundend = [color=crimson]a Tiger Cooperative Fanatic[/color] + +traitor-waffleco-intro = You are a Waffle Co. infiltrator. +traitor-waffleco-goal = You are not here for a station-wide demonstration. Again, other Waffle Co. infiltrators may be, so watch out. Your job is to only accomplish your objectives. +traitor-waffleco-allies = Members of Donk Co. are to be killed on sight; they are not allowed to be on the station while we're around. +traitor-waffleco-uplink = You have been provided with a syndicate uplink located in your PDA to accomplish your task. +traitor-waffleco-roundend = [color=orange]an employee from Waffle Corporation[/color] + +traitor-waffleco-terrorist-intro = You are the Waffle Corporation terrorist. +traitor-waffleco-terrorist-goal = Our investors need a demonstration of our pledge to destroying Nanotrasen. Let's give them a loud one! +traitor-waffleco-terrorist-allies = Most other syndicate agents are not to be trusted, except for members of the Gorlex Marauders. +traitor-waffleco-terrorist-uplink = You have been provided with a syndicate uplink located in your PDA to accomplish your task. +traitor-waffleco-terrorist-roundend = [color=red]a terrorist from Waffle Corporation[/color] diff --git a/Resources/Prototypes/Datasets/corporations.yml b/Resources/Prototypes/Datasets/corporations.yml deleted file mode 100644 index 497d699ed02..00000000000 --- a/Resources/Prototypes/Datasets/corporations.yml +++ /dev/null @@ -1,12 +0,0 @@ -- type: dataset - id: TraitorCorporations - values: - - "CyberSun Industries" - - "Мародёры Горлекса" - - "MI13" - - "Tiger Cooperative" - - "S.E.L.F." - - "Animal Rights Consortium" - - "Donk Corporation" - - "Waffle Corporation" - - "Interdyne Pharmaceutics" diff --git a/Resources/Prototypes/Datasets/traitor_flavor.yml b/Resources/Prototypes/Datasets/traitor_flavor.yml new file mode 100644 index 00000000000..e9209c721dc --- /dev/null +++ b/Resources/Prototypes/Datasets/traitor_flavor.yml @@ -0,0 +1,14 @@ +- type: dataset + id: TraitorFlavor + values: + - "arc" # animal rights consortium + - "blf" # bee liberation front + - "cybersun" + - "corporateclimber" + - "donkco" + - "gorlex" + - "legaltrouble" + - "mi13" + - "tiger" # tiger cooperative + - "waffleco" + - "waffleco-terrorist" diff --git a/Resources/Prototypes/Roles/Antags/traitor.yml b/Resources/Prototypes/Roles/Antags/traitor.yml index 68f1bedb7ba..8779bce7011 100644 --- a/Resources/Prototypes/Roles/Antags/traitor.yml +++ b/Resources/Prototypes/Roles/Antags/traitor.yml @@ -1,9 +1,9 @@ - type: antag id: Traitor - name: roles-antag-syndicate-agent-name + name: roles-antag-traitor-name antagonist: true setPreference: true - objective: roles-antag-syndicate-agent-objective + objective: roles-antag-traitor-objective guides: [ Traitors ] requirements: - !type:OverallPlaytimeRequirement