From 3da0b0299f30db96477525926e2d3bc396765e21 Mon Sep 17 00:00:00 2001 From: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com> Date: Wed, 10 Sep 2025 15:30:53 +0200 Subject: [PATCH] Add support for contraband text to the reagent guidebook (#37113) * Add contraband text to reagent guidebook * Add reagent for examining * Update Content.Client/Guidebook/Controls/GuideReagentEmbed.xaml.cs --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- .../Controls/GuideReagentEmbed.xaml.cs | 25 +++++++++ .../Chemistry/Reagent/ReagentPrototype.cs | 21 +++++++ Content.Shared/Contraband/ContrabandSystem.cs | 31 +++++++++-- .../en-US/contraband/contraband-severity.ftl | 55 ++++++++++++++++--- 4 files changed, 118 insertions(+), 14 deletions(-) diff --git a/Content.Client/Guidebook/Controls/GuideReagentEmbed.xaml.cs b/Content.Client/Guidebook/Controls/GuideReagentEmbed.xaml.cs index 29569e40e6..dbfd36daea 100644 --- a/Content.Client/Guidebook/Controls/GuideReagentEmbed.xaml.cs +++ b/Content.Client/Guidebook/Controls/GuideReagentEmbed.xaml.cs @@ -5,14 +5,17 @@ using Content.Client.Guidebook.Richtext; using Content.Client.Message; using Content.Client.UserInterface.ControlExtensions; using Content.Shared.Body.Prototypes; +using Content.Shared.CCVar; using Content.Shared.Chemistry.Reaction; using Content.Shared.Chemistry.Reagent; +using Content.Shared.Contraband; using JetBrains.Annotations; using Robust.Client.AutoGenerated; using Robust.Client.Graphics; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.XAML; +using Robust.Shared.Configuration; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -27,8 +30,10 @@ public sealed partial class GuideReagentEmbed : BoxContainer, IDocumentTag, ISea [Dependency] private readonly IEntitySystemManager _systemManager = default!; [Dependency] private readonly ILogManager _logManager = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly IConfigurationManager _config = default!; private readonly ChemistryGuideDataSystem _chemistryGuideData; + private readonly ContrabandSystem _contraband; private readonly ISawmill _sawmill; public IPrototype? RepresentedPrototype { get; private set; } @@ -39,6 +44,7 @@ public sealed partial class GuideReagentEmbed : BoxContainer, IDocumentTag, ISea IoCManager.InjectDependencies(this); _sawmill = _logManager.GetSawmill("guidebook.reagent"); _chemistryGuideData = _systemManager.GetEntitySystem(); + _contraband = _systemManager.GetEntitySystem(); MouseFilter = MouseFilterMode.Stop; } @@ -204,6 +210,25 @@ public sealed partial class GuideReagentEmbed : BoxContainer, IDocumentTag, ISea description.PushNewline(); description.AddMarkupOrThrow(Loc.GetString("guidebook-reagent-physical-description", ("description", reagent.LocalizedPhysicalDescription))); + + if (_config.GetCVar(CCVars.ContrabandExamine)) + { + // Department-restricted text + if (reagent.AllowedJobs.Count > 0 || reagent.AllowedDepartments.Count > 0) + { + description.PushNewline(); + description.AddMarkupPermissive( + _contraband.GenerateDepartmentExamineMessage(reagent.AllowedDepartments, reagent.AllowedJobs, ContrabandItemType.Reagent)); + } + // Other contraband text + else if (reagent.ContrabandSeverity != null && + _prototype.Resolve(reagent.ContrabandSeverity.Value, out var severity)) + { + description.PushNewline(); + description.AddMarkupPermissive(Loc.GetString(severity.ExamineText, ("type", ContrabandItemType.Reagent))); + } + } + ReagentDescription.SetMessage(description); } diff --git a/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs b/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs index 4224fa4bc7..b999d8df61 100644 --- a/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs +++ b/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs @@ -6,10 +6,12 @@ using Content.Shared.Administration.Logs; using Content.Shared.Body.Prototypes; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Reaction; +using Content.Shared.Contraband; using Content.Shared.EntityEffects; using Content.Shared.Database; using Content.Shared.Nutrition; using Content.Shared.Prototypes; +using Content.Shared.Roles; using Content.Shared.Slippery; using Robust.Shared.Audio; using Robust.Shared.Map; @@ -57,6 +59,25 @@ namespace Content.Shared.Chemistry.Reagent [ViewVariables(VVAccess.ReadOnly)] public string LocalizedPhysicalDescription => Loc.GetString(PhysicalDescription); + /// + /// The degree of contraband severity this reagent is considered to have. + /// If AllowedDepartments or AllowedJobs are set, they take precedent and override this value. + /// + [DataField] + public ProtoId? ContrabandSeverity = null; + + /// + /// Which departments is this reagent restricted to, if any? + /// + [DataField] + public HashSet> AllowedDepartments = new(); + + /// + /// Which jobs is this reagent restricted to, if any? + /// + [DataField] + public HashSet> AllowedJobs = new(); + /// /// Is this reagent recognizable to the average spaceman (water, welding fuel, ketchup, etc)? /// diff --git a/Content.Shared/Contraband/ContrabandSystem.cs b/Content.Shared/Contraband/ContrabandSystem.cs index 2c2495ba9a..2f654e80d0 100644 --- a/Content.Shared/Contraband/ContrabandSystem.cs +++ b/Content.Shared/Contraband/ContrabandSystem.cs @@ -66,17 +66,13 @@ public sealed class ContrabandSystem : EntitySystem // two strings: // one, the actual informative 'this is restricted' // then, the 'you can/shouldn't carry this around' based on the ID the user is wearing - var localizedDepartments = component.AllowedDepartments.Select(p => Loc.GetString("contraband-department-plural", ("department", Loc.GetString(_proto.Index(p).Name)))); - var jobs = component.AllowedJobs.Select(p => _proto.Index(p).LocalizedName).ToArray(); - var localizedJobs = jobs.Select(p => Loc.GetString("contraband-job-plural", ("job", p))); var severity = _proto.Index(component.Severity); String departmentExamineMessage; if (severity.ShowDepartmentsAndJobs) { - //creating a combined list of jobs and departments for the restricted text - var list = ContentLocalizationManager.FormatList(localizedDepartments.Concat(localizedJobs).ToList()); // department restricted text - departmentExamineMessage = Loc.GetString("contraband-examine-text-Restricted-department", ("departments", list)); + departmentExamineMessage = + GenerateDepartmentExamineMessage(component.AllowedDepartments, component.AllowedJobs); } else { @@ -95,6 +91,7 @@ public sealed class ContrabandSystem : EntitySystem } } + var jobs = component.AllowedJobs.Select(p => _proto.Index(p).LocalizedName).ToArray(); // if it is fully restricted, you're department-less, or your department isn't in the allowed list, you cannot carry it. Otherwise, you can. var carryingMessage = Loc.GetString("contraband-examine-text-avoid-carrying-around"); var iconTexture = "/Textures/Interface/VerbIcons/lock-red.svg.192dpi.png"; @@ -112,6 +109,19 @@ public sealed class ContrabandSystem : EntitySystem iconTexture); } + public string GenerateDepartmentExamineMessage(HashSet> allowedDepartments, HashSet> allowedJobs, ContrabandItemType itemType = ContrabandItemType.Item) + { + var localizedDepartments = allowedDepartments.Select(p => Loc.GetString("contraband-department-plural", ("department", Loc.GetString(_proto.Index(p).Name)))); + var jobs = allowedJobs.Select(p => _proto.Index(p).LocalizedName).ToArray(); + var localizedJobs = jobs.Select(p => Loc.GetString("contraband-job-plural", ("job", p))); + + //creating a combined list of jobs and departments for the restricted text + var list = ContentLocalizationManager.FormatList(localizedDepartments.Concat(localizedJobs).ToList()); + + // department restricted text + return Loc.GetString("contraband-examine-text-Restricted-department", ("departments", list), ("type", itemType)); + } + private FormattedMessage GetContrabandExamine(String deptMessage, String carryMessage) { var msg = new FormattedMessage(); @@ -131,3 +141,12 @@ public sealed class ContrabandSystem : EntitySystem _contrabandExamineOnlyInHudEnabled = val; } } + +/// +/// The item type that the contraband text should follow in the description text. +/// +public enum ContrabandItemType +{ + Item, + Reagent +} diff --git a/Resources/Locale/en-US/contraband/contraband-severity.ftl b/Resources/Locale/en-US/contraband/contraband-severity.ftl index 7f0a1854eb..f5a77d08fa 100644 --- a/Resources/Locale/en-US/contraband/contraband-severity.ftl +++ b/Resources/Locale/en-US/contraband/contraband-severity.ftl @@ -1,11 +1,50 @@ -contraband-examine-text-Minor = [color=yellow]This item is considered minor contraband.[/color] -contraband-examine-text-Restricted = [color=yellow]This item is departmentally restricted.[/color] -contraband-examine-text-Restricted-department = [color=yellow]This item is restricted to {$departments}, and may be considered contraband.[/color] -contraband-examine-text-Major = [color=red]This item is considered major contraband.[/color] -contraband-examine-text-GrandTheft = [color=red]This item is a highly valuable target for Syndicate agents![/color] -contraband-examine-text-Highly-Illegal = [color=red]This item is highly illegal contraband![/color] -contraband-examine-text-Syndicate = [color=crimson]This item is highly illegal Syndicate contraband![/color] -contraband-examine-text-Magical = [color=#b337b3]This item is highly illegal magical contraband![/color] +contraband-examine-text-Minor = + { $type -> + *[item] [color=yellow]This item is considered minor contraband.[/color] + [reagent] [color=yellow]This reagent is considered minor contraband.[/color] + } + +contraband-examine-text-Restricted = + { $type -> + *[item] [color=yellow]This item is departmentally restricted.[/color] + [reagent] [color=yellow]This reagent is departmentally restricted.[/color] + } + +contraband-examine-text-Restricted-department = + { $type -> + *[item] [color=yellow]This item is restricted to {$departments}, and may be considered contraband.[/color] + [reagent] [color=yellow]This reagent is restricted to {$departments}, and may be considered contraband.[/color] + } + +contraband-examine-text-Major = + { $type -> + *[item] [color=red]This item is considered major contraband.[/color] + [reagent] [color=red]This reagent is considered major contraband.[/color] + } + +contraband-examine-text-GrandTheft = + { $type -> + *[item] [color=red]This item is a highly valuable target for Syndicate agents![/color] + [reagent] [color=red]This reagent is a highly valuable target for Syndicate agents![/color] + } + +contraband-examine-text-Highly-Illegal = + { $type -> + *[item] [color=crimson]This item is highly illegal contraband![/color] + [reagent] [color=crimson]This reagent is highly illegal contraband![/color] + } + +contraband-examine-text-Syndicate = + { $type -> + *[item] [color=crimson]This item is highly illegal Syndicate contraband![/color] + [reagent] [color=crimson]This reagent is highly illegal Syndicate contraband![/color] + } + +contraband-examine-text-Magical = + { $type -> + *[item] [color=#b337b3]This item is highly illegal magical contraband![/color] + [reagent] [color=#b337b3]This reagent is highly illegal magical contraband![/color] + } contraband-examine-text-avoid-carrying-around = [color=red][italic]You probably want to avoid visibly carrying this around without a good reason.[/italic][/color] contraband-examine-text-in-the-clear = [color=green][italic]You should be in the clear to visibly carry this around.[/italic][/color]