Change Thief Syndie & Chameleon kit contents, add Syndie codeword paper (#30446)
* Initial commit * more like bYE * Fix exception during test
This commit is contained in:
@@ -42,7 +42,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
|||||||
protected override void Added(EntityUid uid, TraitorRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
|
protected override void Added(EntityUid uid, TraitorRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
|
||||||
{
|
{
|
||||||
base.Added(uid, component, gameRule, args);
|
base.Added(uid, component, gameRule, args);
|
||||||
MakeCodewords(component);
|
SetCodewords(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AfterEntitySelected(Entity<TraitorRuleComponent> ent, ref AfterAntagEntitySelectedEvent args)
|
private void AfterEntitySelected(Entity<TraitorRuleComponent> ent, ref AfterAntagEntitySelectedEvent args)
|
||||||
@@ -50,17 +50,23 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
|||||||
MakeTraitor(args.EntityUid, ent);
|
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 adjectives = _prototypeManager.Index(component.CodewordAdjectives).Values;
|
||||||
var verbs = _prototypeManager.Index(component.CodewordVerbs).Values;
|
var verbs = _prototypeManager.Index(component.CodewordVerbs).Values;
|
||||||
var codewordPool = adjectives.Concat(verbs).ToList();
|
var codewordPool = adjectives.Concat(verbs).ToList();
|
||||||
var finalCodewordCount = Math.Min(component.CodewordCount, codewordPool.Count);
|
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++)
|
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)
|
public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component, bool giveUplink = true)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
93
Content.Server/Traitor/Systems/TraitorCodePaperSystem.cs
Normal file
93
Content.Server/Traitor/Systems/TraitorCodePaperSystem.cs
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,7 +18,8 @@ thief-backpack-button-deselect = Select [X]
|
|||||||
thief-backpack-category-chameleon-name = chameleon kit
|
thief-backpack-category-chameleon-name = chameleon kit
|
||||||
thief-backpack-category-chameleon-description =
|
thief-backpack-category-chameleon-description =
|
||||||
You are everyone and no one; you are a master of disguise.
|
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.
|
Disguise as anyone and anything.
|
||||||
|
|
||||||
thief-backpack-category-tools-name = breacher kit
|
thief-backpack-category-tools-name = breacher kit
|
||||||
@@ -38,8 +39,8 @@ thief-backpack-category-syndie-name = syndie kit
|
|||||||
thief-backpack-category-syndie-description =
|
thief-backpack-category-syndie-description =
|
||||||
Trinkets from a disavowed past, or stolen from a careless agent?
|
Trinkets from a disavowed past, or stolen from a careless agent?
|
||||||
You've made some connections. Whiskey, echo...
|
You've made some connections. Whiskey, echo...
|
||||||
Includes: Agent ID card, Emag, syndicate pAI, Interdyne cigs,
|
Includes: An Emag, Interdyne cigs, a Syndicate codeword,
|
||||||
and some strange red crystals.
|
a Radio Jammer, a lighter and some strange red crystals.
|
||||||
|
|
||||||
thief-backpack-category-sleeper-name = sleeper kit
|
thief-backpack-category-sleeper-name = sleeper kit
|
||||||
thief-backpack-category-sleeper-description =
|
thief-backpack-category-sleeper-description =
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
traitor-codes-message-singular = syndicate codeword:
|
||||||
|
traitor-codes-message-plural = syndicate codewords:
|
||||||
|
traitor-codes-none = no known codewords
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
- ClothingShoesChameleon
|
- ClothingShoesChameleon
|
||||||
- BarberScissors
|
- BarberScissors
|
||||||
- ChameleonProjector
|
- ChameleonProjector
|
||||||
|
- AgentIDCard
|
||||||
|
|
||||||
- type: thiefBackpackSet
|
- type: thiefBackpackSet
|
||||||
id: ToolsSet
|
id: ToolsSet
|
||||||
@@ -57,9 +58,10 @@
|
|||||||
sprite: Objects/Specific/Syndicate/telecrystal.rsi
|
sprite: Objects/Specific/Syndicate/telecrystal.rsi
|
||||||
state: telecrystal
|
state: telecrystal
|
||||||
content:
|
content:
|
||||||
- AgentIDCard
|
- RadioJammer
|
||||||
|
- TraitorCodePaper
|
||||||
- Emag
|
- Emag
|
||||||
- SyndicatePersonalAI
|
- Lighter
|
||||||
- CigPackSyndicate
|
- CigPackSyndicate
|
||||||
- Telecrystal10 #The thief cannot use them, but it may induce communication with traitors
|
- Telecrystal10 #The thief cannot use them, but it may induce communication with traitors
|
||||||
|
|
||||||
|
|||||||
@@ -565,6 +565,26 @@
|
|||||||
- type: StealTarget
|
- type: StealTarget
|
||||||
stealGroup: BoxFolderQmClipboard
|
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
|
- type: entity
|
||||||
name: envelope
|
name: envelope
|
||||||
parent: BaseItem
|
parent: BaseItem
|
||||||
|
|||||||
Reference in New Issue
Block a user