]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Change Thief Syndie & Chameleon kit contents, add Syndie codeword paper (#30446)
authorSlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com>
Mon, 5 Aug 2024 08:03:24 +0000 (10:03 +0200)
committerGitHub <noreply@github.com>
Mon, 5 Aug 2024 08:03:24 +0000 (11:03 +0300)
* Initial commit

* more like bYE

* Fix exception during test

Content.Server/GameTicking/Rules/TraitorRuleSystem.cs
Content.Server/Traitor/Components/TraitorCodePaperComponent.cs [new file with mode: 0644]
Content.Server/Traitor/Systems/TraitorCodePaperSystem.cs [new file with mode: 0644]
Resources/Locale/en-US/thief/backpack.ftl
Resources/Locale/en-US/traitor/traitor-codes-component.ftl [new file with mode: 0644]
Resources/Prototypes/Catalog/thief_toolbox_sets.yml
Resources/Prototypes/Entities/Objects/Misc/paper.yml

index acd2a3ffde96846f6a1548b12de1113cf1513ddb..9e8a878a2d1cf103242078a4dca32f7498845b45 100644 (file)
@@ -42,7 +42,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
     protected override void Added(EntityUid uid, TraitorRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
     {
         base.Added(uid, component, gameRule, args);
-        MakeCodewords(component);
+        SetCodewords(component);
     }
 
     private void AfterEntitySelected(Entity<TraitorRuleComponent> ent, ref AfterAntagEntitySelectedEvent args)
@@ -50,17 +50,23 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
         MakeTraitor(args.EntityUid, ent);
     }
 
-    private void MakeCodewords(TraitorRuleComponent component)
+    private void SetCodewords(TraitorRuleComponent component)
+    {
+        component.Codewords = GenerateTraitorCodewords(component);
+    }
+
+    public string[] GenerateTraitorCodewords(TraitorRuleComponent component)
     {
         var adjectives = _prototypeManager.Index(component.CodewordAdjectives).Values;
         var verbs = _prototypeManager.Index(component.CodewordVerbs).Values;
         var codewordPool = adjectives.Concat(verbs).ToList();
         var finalCodewordCount = Math.Min(component.CodewordCount, codewordPool.Count);
-        component.Codewords = new string[finalCodewordCount];
+        string[] codewords = new string[finalCodewordCount];
         for (var i = 0; i < finalCodewordCount; i++)
         {
-            component.Codewords[i] = _random.PickAndTake(codewordPool);
+            codewords[i] = _random.PickAndTake(codewordPool);
         }
+        return codewords;
     }
 
     public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component, bool giveUplink = true)
diff --git a/Content.Server/Traitor/Components/TraitorCodePaperComponent.cs b/Content.Server/Traitor/Components/TraitorCodePaperComponent.cs
new file mode 100644 (file)
index 0000000..7887248
--- /dev/null
@@ -0,0 +1,27 @@
+namespace Content.Server.Traitor.Components;
+
+/// <summary>
+///     Paper with written traitor codewords on it.
+/// </summary>
+[RegisterComponent]
+public sealed partial class TraitorCodePaperComponent : Component
+{
+    /// <summary>
+    /// The number of codewords that should be generated on this paper.
+    /// Will not extend past the max number of available codewords.
+    /// </summary>
+    [DataField]
+    public int CodewordAmount = 1;
+
+    /// <summary>
+    /// Whether the codewords should be faked if there is no traitor gamerule set.
+    /// </summary>
+    [DataField]
+    public bool FakeCodewords = true;
+
+    /// <summary>
+    /// Whether all codewords added to the round should be used. Overrides CodewordAmount if true.
+    /// </summary>
+    [DataField]
+    public bool CodewordShowAll = false;
+}
diff --git a/Content.Server/Traitor/Systems/TraitorCodePaperSystem.cs b/Content.Server/Traitor/Systems/TraitorCodePaperSystem.cs
new file mode 100644 (file)
index 0000000..72baa2c
--- /dev/null
@@ -0,0 +1,93 @@
+using System.Diagnostics.CodeAnalysis;
+using Content.Server.GameTicking;
+using Content.Server.GameTicking.Rules;
+using Content.Server.GameTicking.Rules.Components;
+using Content.Server.Paper;
+using Content.Server.Traitor.Components;
+using Robust.Shared.Random;
+using Robust.Shared.Utility;
+using System.Linq;
+
+namespace Content.Server.Traitor.Systems;
+
+public sealed class TraitorCodePaperSystem : EntitySystem
+{
+    [Dependency] private readonly GameTicker _gameTicker = default!;
+    [Dependency] private readonly TraitorRuleSystem _traitorRuleSystem = default!;
+    [Dependency] private readonly IRobustRandom _random = default!;
+    [Dependency] private readonly PaperSystem _paper = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+        SubscribeLocalEvent<TraitorCodePaperComponent, MapInitEvent>(OnMapInit);
+    }
+
+    private void OnMapInit(EntityUid uid, TraitorCodePaperComponent component, MapInitEvent args)
+    {
+        SetupPaper(uid, component);
+    }
+
+    private void SetupPaper(EntityUid uid, TraitorCodePaperComponent? component = null)
+    {
+        if (!Resolve(uid, ref component))
+            return;
+
+        if (HasComp<PaperComponent>(uid))
+        {
+            if (TryGetTraitorCode(out var paperContent, component))
+            {
+                _paper.SetContent(uid, paperContent);
+            }
+        }
+    }
+
+    private bool TryGetTraitorCode([NotNullWhen(true)] out string? traitorCode, TraitorCodePaperComponent component)
+    {
+        traitorCode = null;
+
+        var codesMessage = new FormattedMessage();
+        List<string> codeList = new();
+        // Find the first nuke that matches the passed location.
+        if (_gameTicker.IsGameRuleAdded<TraitorRuleComponent>())
+        {
+            var ruleEnts = _gameTicker.GetAddedGameRules();
+            foreach (var ruleEnt in ruleEnts)
+            {
+                if (TryComp(ruleEnt, out TraitorRuleComponent? traitorComp))
+                {
+                    codeList.AddRange(traitorComp.Codewords.ToList());
+                }
+            }
+        }
+        if (codeList.Count == 0)
+        {
+            if (component.FakeCodewords)
+                codeList = _traitorRuleSystem.GenerateTraitorCodewords(new TraitorRuleComponent()).ToList();
+            else
+                codeList = [Loc.GetString("traitor-codes-none")];
+        }
+
+        _random.Shuffle(codeList);
+
+        int i = 0;
+        foreach (var code in codeList)
+        {
+            i++;
+            if (i > component.CodewordAmount && !component.CodewordShowAll)
+                break;
+
+            codesMessage.PushNewline();
+            codesMessage.AddMarkup(code);
+        }
+
+        if (!codesMessage.IsEmpty)
+        {
+            if (i == 1) 
+                traitorCode = Loc.GetString("traitor-codes-message-singular") + codesMessage;
+            else
+                traitorCode = Loc.GetString("traitor-codes-message-plural") + codesMessage;
+        }
+        return !codesMessage.IsEmpty;
+    }
+}
index 0911bc042b6e32edb5ccc2b82326a1ebf373b4a4..6a69ab8bc6f35f7e7ac159712abefe4cdf06990f 100644 (file)
@@ -18,7 +18,8 @@ thief-backpack-button-deselect = Select [X]
 thief-backpack-category-chameleon-name = chameleon kit
 thief-backpack-category-chameleon-description =
     You are everyone and no one; you are a master of disguise.
-    Includes: Set of chameleon clothing, a chameleon projector.
+    Includes: A full set of chameleon clothing,
+    a chameleon projector, and an Agent ID.
     Disguise as anyone and anything.
 
 thief-backpack-category-tools-name = breacher kit
@@ -38,8 +39,8 @@ thief-backpack-category-syndie-name = syndie kit
 thief-backpack-category-syndie-description =
     Trinkets from a disavowed past, or stolen from a careless agent?
     You've made some connections. Whiskey, echo...
-    Includes: Agent ID card, Emag, syndicate pAI, Interdyne cigs,
-    and some strange red crystals.
+    Includes: An Emag, Interdyne cigs, a Syndicate codeword,
+    a Radio Jammer, a lighter and some strange red crystals.
 
 thief-backpack-category-sleeper-name = sleeper kit
 thief-backpack-category-sleeper-description =
diff --git a/Resources/Locale/en-US/traitor/traitor-codes-component.ftl b/Resources/Locale/en-US/traitor/traitor-codes-component.ftl
new file mode 100644 (file)
index 0000000..3524603
--- /dev/null
@@ -0,0 +1,3 @@
+traitor-codes-message-singular = syndicate codeword:
+traitor-codes-message-plural = syndicate codewords:
+traitor-codes-none = no known codewords
index 322fd9261b5a6a5f2f06072fe7a71acc8aa4d690..fe1a4fe75c92ffaca37708533cdded830f3c3ed8 100644 (file)
@@ -16,6 +16,7 @@
   - ClothingShoesChameleon
   - BarberScissors
   - ChameleonProjector
+  - AgentIDCard
 
 - type: thiefBackpackSet
   id: ToolsSet
     sprite: Objects/Specific/Syndicate/telecrystal.rsi
     state: telecrystal
   content:
-  - AgentIDCard
+  - RadioJammer
+  - TraitorCodePaper
   - Emag
-  - SyndicatePersonalAI
+  - Lighter
   - CigPackSyndicate
   - Telecrystal10 #The thief cannot use them, but it may induce communication with traitors
 
index edd4aee3ba67ed430d0b864dda7b1b52067f0721..617db53c4e1a1a8cef21e199a669bc31945a15b5 100644 (file)
   - type: StealTarget
     stealGroup: BoxFolderQmClipboard
 
+- type: entity
+  parent: Paper
+  id: TraitorCodePaper
+  name: syndicate codeword
+  description: A leaked codeword to possibly get in touch with the Syndicate.
+  suffix: DO NOT MAP
+  components:
+  - type: TraitorCodePaper
+
+- type: entity
+  parent: Paper
+  id: AllTraitorCodesPaper
+  name: syndicate codewords registry
+  description: A registry of all active Syndicate codewords.
+  suffix: Admeme
+  components:
+  - type: TraitorCodePaper
+    fakeCodewords: false
+    codewordShowAll: true
+
 - type: entity
   name: envelope
   parent: BaseItem