diff --git a/Content.Client/Paper/PaperComponent.cs b/Content.Client/Paper/PaperComponent.cs deleted file mode 100644 index 1dc827bf7e..0000000000 --- a/Content.Client/Paper/PaperComponent.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Content.Shared.Paper; - -namespace Content.Client.Paper; - -[RegisterComponent] -public sealed partial class PaperComponent : SharedPaperComponent; diff --git a/Content.Client/Paper/UI/PaperBoundUserInterface.cs b/Content.Client/Paper/UI/PaperBoundUserInterface.cs index f3ad1e347e..63645bc01e 100644 --- a/Content.Client/Paper/UI/PaperBoundUserInterface.cs +++ b/Content.Client/Paper/UI/PaperBoundUserInterface.cs @@ -2,7 +2,7 @@ using JetBrains.Annotations; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Utility; -using static Content.Shared.Paper.SharedPaperComponent; +using static Content.Shared.Paper.PaperComponent; namespace Content.Client.Paper.UI; diff --git a/Content.Client/Paper/UI/PaperSystem.cs b/Content.Client/Paper/UI/PaperVisualizerSystem.cs similarity index 82% rename from Content.Client/Paper/UI/PaperSystem.cs rename to Content.Client/Paper/UI/PaperVisualizerSystem.cs index f75d04a26b..a0d05736ad 100644 --- a/Content.Client/Paper/UI/PaperSystem.cs +++ b/Content.Client/Paper/UI/PaperVisualizerSystem.cs @@ -1,10 +1,10 @@ using Robust.Client.GameObjects; -using static Content.Shared.Paper.SharedPaperComponent; +using static Content.Shared.Paper.PaperComponent; -namespace Content.Client.Paper; +namespace Content.Client.Paper.UI; -public sealed class PaperSystem : VisualizerSystem +public sealed class PaperVisualizerSystem : VisualizerSystem { protected override void OnAppearanceChange(EntityUid uid, PaperVisualsComponent component, ref AppearanceChangeEvent args) { diff --git a/Content.Client/Paper/UI/PaperVisualsComponent.cs b/Content.Client/Paper/UI/PaperVisualsComponent.cs index 95040e77e6..f0dee3cf90 100644 --- a/Content.Client/Paper/UI/PaperVisualsComponent.cs +++ b/Content.Client/Paper/UI/PaperVisualsComponent.cs @@ -1,6 +1,6 @@ using System.Numerics; -namespace Content.Client.Paper; +namespace Content.Client.Paper.UI; [RegisterComponent] public sealed partial class PaperVisualsComponent : Component diff --git a/Content.Client/Paper/UI/PaperWindow.xaml.cs b/Content.Client/Paper/UI/PaperWindow.xaml.cs index f7cace642c..81b831068c 100644 --- a/Content.Client/Paper/UI/PaperWindow.xaml.cs +++ b/Content.Client/Paper/UI/PaperWindow.xaml.cs @@ -215,9 +215,9 @@ namespace Content.Client.Paper.UI /// Initialize the paper contents, i.e. the text typed by the /// user and any stamps that have peen put on the page. /// - public void Populate(SharedPaperComponent.PaperBoundUserInterfaceState state) + public void Populate(PaperComponent.PaperBoundUserInterfaceState state) { - bool isEditing = state.Mode == SharedPaperComponent.PaperAction.Write; + bool isEditing = state.Mode == PaperComponent.PaperAction.Write; bool wasEditing = InputContainer.Visible; InputContainer.Visible = isEditing; EditButtons.Visible = isEditing; diff --git a/Content.Client/Tips/TippyUI.xaml.cs b/Content.Client/Tips/TippyUI.xaml.cs index de3eaf4f51..4a2c4bfe2f 100644 --- a/Content.Client/Tips/TippyUI.xaml.cs +++ b/Content.Client/Tips/TippyUI.xaml.cs @@ -1,4 +1,4 @@ -using Content.Client.Paper; +using Content.Client.Paper.UI; using Robust.Client.AutoGenerated; using Robust.Client.Graphics; using Robust.Client.ResourceManagement; diff --git a/Content.Client/Tips/TippyUIController.cs b/Content.Client/Tips/TippyUIController.cs index 2cc694d97d..7737a3d698 100644 --- a/Content.Client/Tips/TippyUIController.cs +++ b/Content.Client/Tips/TippyUIController.cs @@ -1,21 +1,17 @@ -using Content.Client.Gameplay; using System.Numerics; using Content.Client.Message; -using Content.Client.Paper; +using Content.Client.Paper.UI; using Content.Shared.CCVar; using Content.Shared.Movement.Components; using Content.Shared.Tips; using Robust.Client.GameObjects; using Robust.Client.ResourceManagement; -using Robust.Client.State; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controllers; using Robust.Client.UserInterface.Controls; using Robust.Client.Audio; using Robust.Shared.Configuration; -using Robust.Shared.Console; using Robust.Shared.Map; -using Robust.Shared.Prototypes; using Robust.Shared.Timing; using static Content.Client.Tips.TippyUI; diff --git a/Content.Server/Cargo/Systems/CargoSystem.Bounty.cs b/Content.Server/Cargo/Systems/CargoSystem.Bounty.cs index 89c4635b0c..e118f49363 100644 --- a/Content.Server/Cargo/Systems/CargoSystem.Bounty.cs +++ b/Content.Server/Cargo/Systems/CargoSystem.Bounty.cs @@ -3,13 +3,13 @@ using System.Linq; using Content.Server.Cargo.Components; using Content.Server.Labels; using Content.Server.NameIdentifier; -using Content.Server.Paper; using Content.Shared.Access.Components; using Content.Shared.Cargo; using Content.Shared.Cargo.Components; using Content.Shared.Cargo.Prototypes; using Content.Shared.Database; using Content.Shared.NameIdentifier; +using Content.Shared.Paper; using Content.Shared.Stacks; using Content.Shared.Whitelist; using JetBrains.Annotations; @@ -125,7 +125,7 @@ public sealed partial class CargoSystem msg.PushNewline(); } msg.AddMarkup(Loc.GetString("bounty-console-manifest-reward", ("reward", prototype.Reward))); - _paperSystem.SetContent(uid, msg.ToMarkup(), paper); + _paperSystem.SetContent((uid, paper), msg.ToMarkup()); } /// diff --git a/Content.Server/Cargo/Systems/CargoSystem.Orders.cs b/Content.Server/Cargo/Systems/CargoSystem.Orders.cs index 7a2a3d474a..f68fe0fa63 100644 --- a/Content.Server/Cargo/Systems/CargoSystem.Orders.cs +++ b/Content.Server/Cargo/Systems/CargoSystem.Orders.cs @@ -1,7 +1,6 @@ using System.Diagnostics.CodeAnalysis; using Content.Server.Cargo.Components; using Content.Server.Labels.Components; -using Content.Server.Paper; using Content.Server.Station.Components; using Content.Shared.Cargo; using Content.Shared.Cargo.BUI; @@ -10,10 +9,9 @@ using Content.Shared.Cargo.Events; using Content.Shared.Cargo.Prototypes; using Content.Shared.Database; using Content.Shared.Interaction; +using Content.Shared.Paper; using Robust.Shared.Map; -using Robust.Shared.Player; using Robust.Shared.Prototypes; -using Robust.Shared.Random; using Robust.Shared.Utility; namespace Content.Server.Cargo.Systems @@ -512,15 +510,14 @@ namespace Content.Server.Cargo.Systems var val = Loc.GetString("cargo-console-paper-print-name", ("orderNumber", order.OrderId)); _metaSystem.SetEntityName(printed, val); - _paperSystem.SetContent(printed, Loc.GetString( + _paperSystem.SetContent((printed, paper), Loc.GetString( "cargo-console-paper-print-text", ("orderNumber", order.OrderId), ("itemName", MetaData(item).EntityName), ("orderQuantity", order.OrderQuantity), ("requester", order.Requester), ("reason", order.Reason), - ("approver", order.Approver ?? string.Empty)), - paper); + ("approver", order.Approver ?? string.Empty))); // attempt to attach the label to the item if (TryComp(item, out var label)) diff --git a/Content.Server/Cargo/Systems/CargoSystem.cs b/Content.Server/Cargo/Systems/CargoSystem.cs index 1b33404e35..0d205d762b 100644 --- a/Content.Server/Cargo/Systems/CargoSystem.cs +++ b/Content.Server/Cargo/Systems/CargoSystem.cs @@ -1,7 +1,6 @@ using Content.Server.Access.Systems; using Content.Server.Cargo.Components; using Content.Server.DeviceLinking.Systems; -using Content.Server.Paper; using Content.Server.Popups; using Content.Server.Shuttles.Systems; using Content.Server.Stack; @@ -13,6 +12,7 @@ using Content.Shared.Cargo; using Content.Shared.Cargo.Components; using Content.Shared.Containers.ItemSlots; using Content.Shared.Mobs.Components; +using Content.Shared.Paper; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Audio.Systems; diff --git a/Content.Server/Fax/FaxSystem.cs b/Content.Server/Fax/FaxSystem.cs index 2b059b4b80..3f10e180fe 100644 --- a/Content.Server/Fax/FaxSystem.cs +++ b/Content.Server/Fax/FaxSystem.cs @@ -5,7 +5,6 @@ using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork.Components; using Content.Server.DeviceNetwork.Systems; using Content.Server.Labels; -using Content.Server.Paper; using Content.Server.Popups; using Content.Server.Power.Components; using Content.Server.Tools; @@ -591,14 +590,14 @@ public sealed class FaxSystem : EntitySystem if (TryComp(printed, out var paper)) { - _paperSystem.SetContent(printed, printout.Content); + _paperSystem.SetContent((printed, paper), printout.Content); // Apply stamps if (printout.StampState != null) { foreach (var stamp in printout.StampedBy) { - _paperSystem.TryStamp(printed, stamp, printout.StampState); + _paperSystem.TryStamp((printed, paper), stamp, printout.StampState); } } diff --git a/Content.Server/Forensics/Systems/ForensicScannerSystem.cs b/Content.Server/Forensics/Systems/ForensicScannerSystem.cs index 5e2a562577..80062569b8 100644 --- a/Content.Server/Forensics/Systems/ForensicScannerSystem.cs +++ b/Content.Server/Forensics/Systems/ForensicScannerSystem.cs @@ -1,12 +1,12 @@ using System.Linq; using System.Text; -using Content.Server.Paper; using Content.Server.Popups; using Content.Shared.UserInterface; using Content.Shared.DoAfter; using Content.Shared.Forensics; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; +using Content.Shared.Paper; using Content.Shared.Verbs; using Robust.Shared.Audio.Systems; using Robust.Server.GameObjects; @@ -183,7 +183,7 @@ namespace Content.Server.Forensics var printed = EntityManager.SpawnEntity(component.MachineOutput, Transform(uid).Coordinates); _handsSystem.PickupOrDrop(args.Actor, printed, checkActionBlocker: false); - if (!HasComp(printed)) + if (!TryComp(printed, out var paperComp)) { Log.Error("Printed paper did not have PaperComponent."); return; @@ -217,7 +217,7 @@ namespace Content.Server.Forensics text.AppendLine(residue); } - _paperSystem.SetContent(printed, text.ToString()); + _paperSystem.SetContent((printed, paperComp), text.ToString()); _audioSystem.PlayPvs(component.SoundPrint, uid, AudioParams.Default .WithVariation(0.25f) diff --git a/Content.Server/Labels/Label/LabelSystem.cs b/Content.Server/Labels/Label/LabelSystem.cs index cbf29e16a2..b70c004123 100644 --- a/Content.Server/Labels/Label/LabelSystem.cs +++ b/Content.Server/Labels/Label/LabelSystem.cs @@ -1,10 +1,10 @@ using Content.Server.Labels.Components; -using Content.Server.Paper; using Content.Shared.Containers.ItemSlots; using Content.Shared.Examine; using Content.Shared.Labels; using Content.Shared.Labels.Components; using Content.Shared.Labels.EntitySystems; +using Content.Shared.Paper; using JetBrains.Annotations; using Robust.Shared.Containers; diff --git a/Content.Server/Nuke/NukeCodePaperSystem.cs b/Content.Server/Nuke/NukeCodePaperSystem.cs index 8025e2bbd5..e890aa0845 100644 --- a/Content.Server/Nuke/NukeCodePaperSystem.cs +++ b/Content.Server/Nuke/NukeCodePaperSystem.cs @@ -2,7 +2,6 @@ using System.Diagnostics.CodeAnalysis; using Content.Server.Chat.Systems; using Content.Server.Fax; using Content.Shared.Fax.Components; -using Content.Server.Paper; using Content.Server.Station.Components; using Content.Server.Station.Systems; using Content.Shared.Paper; @@ -38,7 +37,8 @@ namespace Content.Server.Nuke if (TryGetRelativeNukeCode(uid, out var paperContent, station, onlyCurrentStation: component.AllNukesAvailable)) { - _paper.SetContent(uid, paperContent); + if (TryComp(uid, out var paperComp)) + _paper.SetContent((uid, paperComp), paperContent); } } diff --git a/Content.Server/Paper/PaperComponent.cs b/Content.Server/Paper/PaperComponent.cs deleted file mode 100644 index 7b04a77d57..0000000000 --- a/Content.Server/Paper/PaperComponent.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Content.Shared.Paper; - -namespace Content.Server.Paper; - -[RegisterComponent] -public sealed partial class PaperComponent : SharedPaperComponent -{ - public PaperAction Mode; - [DataField("content")] - public string Content { get; set; } = ""; - - [DataField("contentSize")] - public int ContentSize { get; set; } = 6000; - - [DataField("stampedBy")] - public List StampedBy { get; set; } = new(); - - /// - /// Stamp to be displayed on the paper, state from beauracracy.rsi - /// - [DataField("stampState")] - public string? StampState { get; set; } - - [DataField] - public bool EditingDisabled = false; -} diff --git a/Content.Server/Paper/PaperRandomStorySystem.cs b/Content.Server/Paper/PaperRandomStorySystem.cs index 156718f545..2e43058197 100644 --- a/Content.Server/Paper/PaperRandomStorySystem.cs +++ b/Content.Server/Paper/PaperRandomStorySystem.cs @@ -1,3 +1,4 @@ +using Content.Shared.Paper; using Content.Shared.StoryGen; namespace Content.Server.Paper; @@ -11,10 +12,10 @@ public sealed class PaperRandomStorySystem : EntitySystem { base.Initialize(); - SubscribeLocalEvent(OnMapinit); + SubscribeLocalEvent(OnMapInit); } - private void OnMapinit(Entity paperStory, ref MapInitEvent ev) + private void OnMapInit(Entity paperStory, ref MapInitEvent ev) { if (!TryComp(paperStory, out var paper)) return; @@ -22,6 +23,6 @@ public sealed class PaperRandomStorySystem : EntitySystem if (!_storyGen.TryGenerateStoryFromTemplate(paperStory.Comp.Template, out var story)) return; - _paper.SetContent(paperStory.Owner, story, paper); + _paper.SetContent((paperStory.Owner, paper), story); } } diff --git a/Content.Server/Paper/PaperSystem.cs b/Content.Server/Paper/PaperSystem.cs deleted file mode 100644 index 3935df8370..0000000000 --- a/Content.Server/Paper/PaperSystem.cs +++ /dev/null @@ -1,231 +0,0 @@ -using System.Linq; -using Content.Server.Administration.Logs; -using Content.Server.Popups; -using Content.Shared.UserInterface; -using Content.Shared.Database; -using Content.Shared.Examine; -using Content.Shared.Interaction; -using Content.Shared.Paper; -using Content.Shared.Tag; -using Robust.Server.GameObjects; -using Robust.Shared.Player; -using Robust.Shared.Audio.Systems; -using static Content.Shared.Paper.SharedPaperComponent; - -namespace Content.Server.Paper -{ - public sealed class PaperSystem : EntitySystem - { - [Dependency] private readonly IAdminLogManager _adminLogger = default!; - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly SharedInteractionSystem _interaction = default!; - [Dependency] private readonly PopupSystem _popupSystem = default!; - [Dependency] private readonly TagSystem _tagSystem = default!; - [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; - [Dependency] private readonly MetaDataSystem _metaSystem = default!; - [Dependency] private readonly SharedAudioSystem _audio = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnInit); - SubscribeLocalEvent(BeforeUIOpen); - SubscribeLocalEvent(OnExamined); - SubscribeLocalEvent(OnInteractUsing); - SubscribeLocalEvent(OnInputTextMessage); - - SubscribeLocalEvent(OnPaperWrite); - - SubscribeLocalEvent(OnMapInit); - } - - private void OnMapInit(EntityUid uid, PaperComponent paperComp, MapInitEvent args) - { - if (!string.IsNullOrEmpty(paperComp.Content)) - { - paperComp.Content = Loc.GetString(paperComp.Content); - } - } - - private void OnInit(EntityUid uid, PaperComponent paperComp, ComponentInit args) - { - paperComp.Mode = PaperAction.Read; - UpdateUserInterface(uid, paperComp); - - if (TryComp(uid, out var appearance)) - { - if (paperComp.Content != "") - _appearance.SetData(uid, PaperVisuals.Status, PaperStatus.Written, appearance); - - if (paperComp.StampState != null) - _appearance.SetData(uid, PaperVisuals.Stamp, paperComp.StampState, appearance); - } - - } - - private void BeforeUIOpen(EntityUid uid, PaperComponent paperComp, BeforeActivatableUIOpenEvent args) - { - paperComp.Mode = PaperAction.Read; - UpdateUserInterface(uid, paperComp); - } - - private void OnExamined(EntityUid uid, PaperComponent paperComp, ExaminedEvent args) - { - if (!args.IsInDetailsRange) - return; - - using (args.PushGroup(nameof(PaperComponent))) - { - if (paperComp.Content != "") - args.PushMarkup( - Loc.GetString( - "paper-component-examine-detail-has-words", ("paper", uid) - ) - ); - - if (paperComp.StampedBy.Count > 0) - { - var commaSeparated = - string.Join(", ", paperComp.StampedBy.Select(s => Loc.GetString(s.StampedName))); - args.PushMarkup( - Loc.GetString( - "paper-component-examine-detail-stamped-by", ("paper", uid), ("stamps", commaSeparated)) - ); - } - } - } - - private void OnInteractUsing(EntityUid uid, PaperComponent paperComp, InteractUsingEvent args) - { - // only allow editing if there are no stamps or when using a cyberpen - var editable = paperComp.StampedBy.Count == 0 || _tagSystem.HasTag(args.Used, "WriteIgnoreStamps"); - if (_tagSystem.HasTag(args.Used, "Write") && editable) - { - if (paperComp.EditingDisabled) - { - var paperEditingDisabledMessage = Loc.GetString("paper-tamper-proof-modified-message"); - _popupSystem.PopupEntity(paperEditingDisabledMessage, uid, args.User); - - args.Handled = true; - return; - } - var writeEvent = new PaperWriteEvent(uid, args.User); - RaiseLocalEvent(args.Used, ref writeEvent); - - paperComp.Mode = PaperAction.Write; - _uiSystem.OpenUi(uid, PaperUiKey.Key, args.User); - UpdateUserInterface(uid, paperComp); - args.Handled = true; - return; - } - - // If a stamp, attempt to stamp paper - if (TryComp(args.Used, out var stampComp) && TryStamp(uid, GetStampInfo(stampComp), stampComp.StampState, paperComp)) - { - // successfully stamped, play popup - var stampPaperOtherMessage = Loc.GetString("paper-component-action-stamp-paper-other", - ("user", args.User), ("target", args.Target), ("stamp", args.Used)); - - _popupSystem.PopupEntity(stampPaperOtherMessage, args.User, Filter.PvsExcept(args.User, entityManager: EntityManager), true); - var stampPaperSelfMessage = Loc.GetString("paper-component-action-stamp-paper-self", - ("target", args.Target), ("stamp", args.Used)); - _popupSystem.PopupEntity(stampPaperSelfMessage, args.User, args.User); - - _audio.PlayPvs(stampComp.Sound, uid); - - UpdateUserInterface(uid, paperComp); - } - } - - private static StampDisplayInfo GetStampInfo(StampComponent stamp) - { - return new StampDisplayInfo - { - StampedName = stamp.StampedName, - StampedColor = stamp.StampedColor - }; - } - - private void OnInputTextMessage(EntityUid uid, PaperComponent paperComp, PaperInputTextMessage args) - { - if (args.Text.Length <= paperComp.ContentSize) - { - paperComp.Content = args.Text; - - if (TryComp(uid, out var appearance)) - _appearance.SetData(uid, PaperVisuals.Status, PaperStatus.Written, appearance); - - if (TryComp(uid, out MetaDataComponent? meta)) - _metaSystem.SetEntityDescription(uid, "", meta); - - _adminLogger.Add(LogType.Chat, LogImpact.Low, - $"{ToPrettyString(args.Actor):player} has written on {ToPrettyString(uid):entity} the following text: {args.Text}"); - - _audio.PlayPvs(paperComp.Sound, uid); - } - - paperComp.Mode = PaperAction.Read; - UpdateUserInterface(uid, paperComp); - } - - private void OnPaperWrite(EntityUid uid, ActivateOnPaperOpenedComponent comp, ref PaperWriteEvent args) - { - _interaction.UseInHandInteraction(args.User, uid); - } - - /// - /// Accepts the name and state to be stamped onto the paper, returns true if successful. - /// - public bool TryStamp(EntityUid uid, StampDisplayInfo stampInfo, string spriteStampState, PaperComponent? paperComp = null) - { - if (!Resolve(uid, ref paperComp)) - return false; - - if (!paperComp.StampedBy.Contains(stampInfo)) - { - paperComp.StampedBy.Add(stampInfo); - if (paperComp.StampState == null && TryComp(uid, out var appearance)) - { - paperComp.StampState = spriteStampState; - // Would be nice to be able to display multiple sprites on the paper - // but most of the existing images overlap - _appearance.SetData(uid, PaperVisuals.Stamp, paperComp.StampState, appearance); - } - } - return true; - } - - public void SetContent(EntityUid uid, string content, PaperComponent? paperComp = null) - { - if (!Resolve(uid, ref paperComp)) - return; - - paperComp.Content = content + '\n'; - UpdateUserInterface(uid, paperComp); - - if (!TryComp(uid, out var appearance)) - return; - - var status = string.IsNullOrWhiteSpace(content) - ? PaperStatus.Blank - : PaperStatus.Written; - - _appearance.SetData(uid, PaperVisuals.Status, status, appearance); - } - - public void UpdateUserInterface(EntityUid uid, PaperComponent? paperComp = null) - { - if (!Resolve(uid, ref paperComp)) - return; - - _uiSystem.SetUiState(uid, PaperUiKey.Key, new PaperBoundUserInterfaceState(paperComp.Content, paperComp.StampedBy, paperComp.Mode)); - } - } - - /// - /// Event fired when using a pen on paper, opening the UI. - /// - [ByRefEvent] - public record struct PaperWriteEvent(EntityUid User, EntityUid Paper); -} diff --git a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs index 59ca913a39..8fc2f26fa6 100644 --- a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs +++ b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs @@ -1,5 +1,4 @@ using System.Linq; -using Content.Server.Paper; using Content.Server.Power.Components; using Content.Server.Research.Systems; using Content.Shared.UserInterface; @@ -9,6 +8,7 @@ using Content.Server.Xenoarchaeology.XenoArtifacts.Events; using Content.Shared.Audio; using Content.Shared.DeviceLinking; using Content.Shared.DeviceLinking.Events; +using Content.Shared.Paper; using Content.Shared.Placeable; using Content.Shared.Popups; using Content.Shared.Research.Components; @@ -290,7 +290,8 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem return; _popup.PopupEntity(Loc.GetString("analysis-console-print-popup"), uid); - _paper.SetContent(report, msg.ToMarkup()); + if (TryComp(report, out var paperComp)) + _paper.SetContent((report, paperComp), msg.ToMarkup()); UpdateUserInterface(uid, component); } diff --git a/Content.Server/Paper/ActivateOnPaperOpenedComponent.cs b/Content.Shared/Paper/ActivateOnPaperOpenedComponent.cs similarity index 78% rename from Content.Server/Paper/ActivateOnPaperOpenedComponent.cs rename to Content.Shared/Paper/ActivateOnPaperOpenedComponent.cs index 0d0f72b612..82b366decd 100644 --- a/Content.Server/Paper/ActivateOnPaperOpenedComponent.cs +++ b/Content.Shared/Paper/ActivateOnPaperOpenedComponent.cs @@ -1,4 +1,6 @@ -namespace Content.Server.Paper; +using Content.Shared.Paper; + +namespace Content.Shared.Paper; /// /// Activates the item when used to write on paper, as if Z was pressed. diff --git a/Content.Shared/Paper/SharedPaperComponent.cs b/Content.Shared/Paper/PaperComponent.cs similarity index 68% rename from Content.Shared/Paper/SharedPaperComponent.cs rename to Content.Shared/Paper/PaperComponent.cs index f65a599e53..cd0758589d 100644 --- a/Content.Shared/Paper/SharedPaperComponent.cs +++ b/Content.Shared/Paper/PaperComponent.cs @@ -4,9 +4,28 @@ using Robust.Shared.Serialization; namespace Content.Shared.Paper; -[NetworkedComponent] -public abstract partial class SharedPaperComponent : Component +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class PaperComponent : Component { + public PaperAction Mode; + [DataField("content"), AutoNetworkedField] + public string Content { get; set; } = ""; + + [DataField("contentSize")] + public int ContentSize { get; set; } = 6000; + + [DataField("stampedBy"), AutoNetworkedField] + public List StampedBy { get; set; } = new(); + + /// + /// Stamp to be displayed on the paper, state from bureaucracy.rsi + /// + [DataField("stampState"), AutoNetworkedField] + public string? StampState { get; set; } + + [DataField, AutoNetworkedField] + public bool EditingDisabled; + /// /// Sound played after writing to the paper. /// diff --git a/Content.Shared/Paper/PaperSystem.cs b/Content.Shared/Paper/PaperSystem.cs new file mode 100644 index 0000000000..0f4bfef983 --- /dev/null +++ b/Content.Shared/Paper/PaperSystem.cs @@ -0,0 +1,228 @@ +using System.Linq; +using Content.Shared.Administration.Logs; +using Content.Shared.UserInterface; +using Content.Shared.Database; +using Content.Shared.Examine; +using Content.Shared.Interaction; +using Content.Shared.Popups; +using Content.Shared.Tag; +using Robust.Shared.Player; +using Robust.Shared.Audio.Systems; +using static Content.Shared.Paper.PaperComponent; + +namespace Content.Shared.Paper; + +public sealed class PaperSystem : EntitySystem +{ + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedInteractionSystem _interaction = default!; + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; + [Dependency] private readonly TagSystem _tagSystem = default!; + [Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!; + [Dependency] private readonly MetaDataSystem _metaSystem = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(BeforeUIOpen); + SubscribeLocalEvent(OnExamined); + SubscribeLocalEvent(OnInteractUsing); + SubscribeLocalEvent(OnInputTextMessage); + + SubscribeLocalEvent(OnPaperWrite); + } + + private void OnMapInit(Entity entity, ref MapInitEvent args) + { + if (!string.IsNullOrEmpty(entity.Comp.Content)) + { + SetContent(entity, Loc.GetString(entity.Comp.Content)); + } + } + + private void OnInit(Entity entity, ref ComponentInit args) + { + entity.Comp.Mode = PaperAction.Read; + UpdateUserInterface(entity); + + if (TryComp(entity, out var appearance)) + { + if (entity.Comp.Content != "") + _appearance.SetData(entity, PaperVisuals.Status, PaperStatus.Written, appearance); + + if (entity.Comp.StampState != null) + _appearance.SetData(entity, PaperVisuals.Stamp, entity.Comp.StampState, appearance); + } + } + + private void BeforeUIOpen(Entity entity, ref BeforeActivatableUIOpenEvent args) + { + entity.Comp.Mode = PaperAction.Read; + UpdateUserInterface(entity); + } + + private void OnExamined(Entity entity, ref ExaminedEvent args) + { + if (!args.IsInDetailsRange) + return; + + using (args.PushGroup(nameof(PaperComponent))) + { + if (entity.Comp.Content != "") + { + args.PushMarkup( + Loc.GetString( + "paper-component-examine-detail-has-words", + ("paper", entity) + ) + ); + } + + if (entity.Comp.StampedBy.Count > 0) + { + var commaSeparated = + string.Join(", ", entity.Comp.StampedBy.Select(s => Loc.GetString(s.StampedName))); + args.PushMarkup( + Loc.GetString( + "paper-component-examine-detail-stamped-by", + ("paper", entity), + ("stamps", commaSeparated)) + ); + } + } + } + + private void OnInteractUsing(Entity entity, ref InteractUsingEvent args) + { + // only allow editing if there are no stamps or when using a cyberpen + var editable = entity.Comp.StampedBy.Count == 0 || _tagSystem.HasTag(args.Used, "WriteIgnoreStamps"); + if (_tagSystem.HasTag(args.Used, "Write") && editable) + { + if (entity.Comp.EditingDisabled) + { + var paperEditingDisabledMessage = Loc.GetString("paper-tamper-proof-modified-message"); + _popupSystem.PopupEntity(paperEditingDisabledMessage, entity, args.User); + + args.Handled = true; + return; + } + var writeEvent = new PaperWriteEvent(entity, args.User); + RaiseLocalEvent(args.Used, ref writeEvent); + + entity.Comp.Mode = PaperAction.Write; + _uiSystem.OpenUi(entity.Owner, PaperUiKey.Key, args.User); + UpdateUserInterface(entity); + args.Handled = true; + return; + } + + // If a stamp, attempt to stamp paper + if (TryComp(args.Used, out var stampComp) && TryStamp(entity, GetStampInfo(stampComp), stampComp.StampState)) + { + // successfully stamped, play popup + var stampPaperOtherMessage = Loc.GetString("paper-component-action-stamp-paper-other", + ("user", args.User), + ("target", args.Target), + ("stamp", args.Used)); + + _popupSystem.PopupEntity(stampPaperOtherMessage, args.User, Filter.PvsExcept(args.User, entityManager: EntityManager), true); + var stampPaperSelfMessage = Loc.GetString("paper-component-action-stamp-paper-self", + ("target", args.Target), + ("stamp", args.Used)); + _popupSystem.PopupClient(stampPaperSelfMessage, args.User, args.User); + + _audio.PlayPredicted(stampComp.Sound, entity, args.User); + + UpdateUserInterface(entity); + } + } + + private static StampDisplayInfo GetStampInfo(StampComponent stamp) + { + return new StampDisplayInfo + { + StampedName = stamp.StampedName, + StampedColor = stamp.StampedColor + }; + } + + private void OnInputTextMessage(Entity entity, ref PaperInputTextMessage args) + { + if (args.Text.Length <= entity.Comp.ContentSize) + { + SetContent(entity, args.Text); + + if (TryComp(entity, out var appearance)) + _appearance.SetData(entity, PaperVisuals.Status, PaperStatus.Written, appearance); + + if (TryComp(entity, out MetaDataComponent? meta)) + _metaSystem.SetEntityDescription(entity, "", meta); + + _adminLogger.Add(LogType.Chat, + LogImpact.Low, + $"{ToPrettyString(args.Actor):player} has written on {ToPrettyString(entity):entity} the following text: {args.Text}"); + + _audio.PlayPvs(entity.Comp.Sound, entity); + } + + entity.Comp.Mode = PaperAction.Read; + UpdateUserInterface(entity); + } + + private void OnPaperWrite(Entity entity, ref PaperWriteEvent args) + { + _interaction.UseInHandInteraction(args.User, entity); + } + + /// + /// Accepts the name and state to be stamped onto the paper, returns true if successful. + /// + public bool TryStamp(Entity entity, StampDisplayInfo stampInfo, string spriteStampState) + { + if (!entity.Comp.StampedBy.Contains(stampInfo)) + { + entity.Comp.StampedBy.Add(stampInfo); + Dirty(entity); + if (entity.Comp.StampState == null && TryComp(entity, out var appearance)) + { + entity.Comp.StampState = spriteStampState; + // Would be nice to be able to display multiple sprites on the paper + // but most of the existing images overlap + _appearance.SetData(entity, PaperVisuals.Stamp, entity.Comp.StampState, appearance); + } + } + return true; + } + + public void SetContent(Entity entity, string content) + { + entity.Comp.Content = content + '\n'; + Dirty(entity); + UpdateUserInterface(entity); + + if (!TryComp(entity, out var appearance)) + return; + + var status = string.IsNullOrWhiteSpace(content) + ? PaperStatus.Blank + : PaperStatus.Written; + + _appearance.SetData(entity, PaperVisuals.Status, status, appearance); + } + + private void UpdateUserInterface(Entity entity) + { + _uiSystem.SetUiState(entity.Owner, PaperUiKey.Key, new PaperBoundUserInterfaceState(entity.Comp.Content, entity.Comp.StampedBy, entity.Comp.Mode)); + } +} + +/// +/// Event fired when using a pen on paper, opening the UI. +/// +[ByRefEvent] +public record struct PaperWriteEvent(EntityUid User, EntityUid Paper); diff --git a/Resources/Prototypes/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Entities/Objects/Misc/paper.yml index 37776f5ba2..edd4aee3ba 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/paper.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/paper.yml @@ -229,7 +229,6 @@ components: - type: Paper contentSize: 10000 - escapeFormatting: false content: book-cnc-sheet - type: Sprite layers: @@ -587,7 +586,6 @@ map: ["enum.PaperVisualLayers.Stamp"] visible: false - type: Paper - escapeFormatting: false content: envelope-default-message - type: PaperVisuals headerImagePath: "/Textures/Interface/Paper/paper_heading_postage_stamp.svg.96dpi.png" @@ -642,4 +640,4 @@ behaviors: - !type:EmptyAllContainersBehaviour - !type:DoActsBehavior - acts: [ "Destruction" ] \ No newline at end of file + acts: [ "Destruction" ]