From 9544099c993c5200cc1deff530a02a2e83d2bb7f Mon Sep 17 00:00:00 2001 From: adrian Date: Tue, 11 Feb 2020 20:01:05 -0300 Subject: [PATCH] Paper and pen (#582) * A very basic paper and pen implementation * Removes SharedWriteComponent * Update ContentNetIDs.cs --- Content.Client/EntryPoint.cs | 4 +- .../Paper/PaperBoundUserInterface.cs | 44 ++++++++++ .../Components/Paper/PaperWindow.cs | 36 ++++++++ .../Components/Paper/PaperComponent.cs | 78 ++++++++++++++++++ .../Components/Paper/WriteComponent.cs | 11 +++ .../Components/SharedPaperComponent.cs | 63 ++++++++++++++ Content.Shared/GameObjects/ContentNetIDs.cs | 1 + Resources/Prototypes/Entities/items/paper.yml | 37 +++++++++ .../Textures/Objects/Misc/bureaucracy.dmi | Bin 0 -> 15020 bytes 9 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 Content.Client/GameObjects/Components/Paper/PaperBoundUserInterface.cs create mode 100644 Content.Client/GameObjects/Components/Paper/PaperWindow.cs create mode 100644 Content.Server/GameObjects/Components/Paper/PaperComponent.cs create mode 100644 Content.Server/GameObjects/Components/Paper/WriteComponent.cs create mode 100644 Content.Shared/GameObjects/Components/SharedPaperComponent.cs create mode 100644 Resources/Prototypes/Entities/items/paper.yml create mode 100644 Resources/Textures/Objects/Misc/bureaucracy.dmi diff --git a/Content.Client/EntryPoint.cs b/Content.Client/EntryPoint.cs index 85ba2ba59c..7ed60563b9 100644 --- a/Content.Client/EntryPoint.cs +++ b/Content.Client/EntryPoint.cs @@ -129,7 +129,9 @@ namespace Content.Client "ShuttleController", "HumanInventoryController", "UseDelay", - "Pourable" + "Pourable", + "Paper", + "Write" }; foreach (var ignoreName in registerIgnore) diff --git a/Content.Client/GameObjects/Components/Paper/PaperBoundUserInterface.cs b/Content.Client/GameObjects/Components/Paper/PaperBoundUserInterface.cs new file mode 100644 index 0000000000..b064d7519c --- /dev/null +++ b/Content.Client/GameObjects/Components/Paper/PaperBoundUserInterface.cs @@ -0,0 +1,44 @@ +using Content.Shared.GameObjects.Components; +using Robust.Client.GameObjects.Components.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Shared.GameObjects.Components.UserInterface; + +namespace Content.Client.GameObjects.Components +{ + public class PaperBoundUserInterface : BoundUserInterface + { + private PaperWindow _window; + + public PaperBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey) + { + } + + protected override void Open() + { + base.Open(); + _window = new PaperWindow + { + Title = Owner.Owner.Name, + }; + _window.OnClose += Close; + _window.Input.OnTextEntered += Input_OnTextEntered; + _window.OpenCentered(); + + } + + protected override void UpdateState(BoundUserInterfaceState state) + { + base.UpdateState(state); + _window.Populate((SharedPaperComponent.PaperBoundUserInterfaceState)state); + } + + private void Input_OnTextEntered(LineEdit.LineEditEventArgs obj) + { + if(!string.IsNullOrEmpty(obj.Text)) + { + SendMessage(new SharedPaperComponent.PaperInputText(obj.Text)); + _window.Input.Text = string.Empty; + } + } + } +} diff --git a/Content.Client/GameObjects/Components/Paper/PaperWindow.cs b/Content.Client/GameObjects/Components/Paper/PaperWindow.cs new file mode 100644 index 0000000000..2762625832 --- /dev/null +++ b/Content.Client/GameObjects/Components/Paper/PaperWindow.cs @@ -0,0 +1,36 @@ +using Content.Shared.GameObjects.Components; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.CustomControls; +using Robust.Shared.Maths; +using Robust.Shared.Utility; + +namespace Content.Client.GameObjects.Components +{ + public class PaperWindow : SS14Window + { + private readonly RichTextLabel _label; + public readonly LineEdit Input; + protected override Vector2? CustomSize => (300, 300); + + public PaperWindow() + { + var container = new VBoxContainer(); + _label = new RichTextLabel(); + Input = new LineEdit {Visible = false}; + container.AddChild(_label); + container.AddChild(Input); + Contents.AddChild(container); + } + + public void Populate(SharedPaperComponent.PaperBoundUserInterfaceState state) + { + if (state.Mode == SharedPaperComponent.PaperAction.Write) + { + Input.Visible = true; + } + var msg = new FormattedMessage(); + msg.AddMarkup(state.Text); + _label.SetMessage(msg); + } + } +} diff --git a/Content.Server/GameObjects/Components/Paper/PaperComponent.cs b/Content.Server/GameObjects/Components/Paper/PaperComponent.cs new file mode 100644 index 0000000000..9c29df3cde --- /dev/null +++ b/Content.Server/GameObjects/Components/Paper/PaperComponent.cs @@ -0,0 +1,78 @@ +using Content.Server.GameObjects.EntitySystems; +using Content.Shared.GameObjects.Components; +using Robust.Server.GameObjects; +using Robust.Server.GameObjects.Components.UserInterface; +using Robust.Server.Interfaces.GameObjects; +using Robust.Shared.GameObjects; +using Robust.Shared.Utility; + +namespace Content.Server.GameObjects.Components.Interactable +{ + [RegisterComponent] + public class PaperComponent : SharedPaperComponent, IExamine, IAttackBy, IUse + { + + private BoundUserInterface _userInterface; + private string _content; + private PaperAction _mode; + + public override void Initialize() + { + base.Initialize(); + _userInterface = Owner.GetComponent() + .GetBoundUserInterface(PaperUiKey.Key); + _userInterface.OnReceiveMessage += OnUiReceiveMessage; + _content = ""; + _mode = PaperAction.Read; + UpdateUserInterface(); + } + private void UpdateUserInterface() + { + _userInterface.SetState(new PaperBoundUserInterfaceState(_content, _mode)); + } + + public void Examine(FormattedMessage message) + { + message.AddMarkup(_content); + } + + public bool UseEntity(UseEntityEventArgs eventArgs) + { + if (!eventArgs.User.TryGetComponent(out IActorComponent actor)) + return false; + _mode = PaperAction.Read; + UpdateUserInterface(); + _userInterface.Open(actor.playerSession); + return true; + } + + private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj) + { + var msg = (PaperInputText) obj.Message; + if (string.IsNullOrEmpty(msg.Text)) + return; + + _content += msg.Text + '\n'; + + if (Owner.TryGetComponent(out SpriteComponent sprite)) + { + sprite.LayerSetState(0, "paper_words"); + } + + UpdateUserInterface(); + } + + public bool AttackBy(AttackByEventArgs eventArgs) + { + if (!eventArgs.AttackWith.HasComponent()) + return false; + if (!eventArgs.User.TryGetComponent(out IActorComponent actor)) + return false; + + _mode = PaperAction.Write; + UpdateUserInterface(); + _userInterface.Open(actor.playerSession); + return true; + } + } +} diff --git a/Content.Server/GameObjects/Components/Paper/WriteComponent.cs b/Content.Server/GameObjects/Components/Paper/WriteComponent.cs new file mode 100644 index 0000000000..d154a388fc --- /dev/null +++ b/Content.Server/GameObjects/Components/Paper/WriteComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.GameObjects.Components; +using Robust.Shared.GameObjects; + +namespace Content.Server.GameObjects.Components.Interactable +{ + [RegisterComponent] + public class WriteComponent : Component + { + public override string Name => "Write"; + } +} diff --git a/Content.Shared/GameObjects/Components/SharedPaperComponent.cs b/Content.Shared/GameObjects/Components/SharedPaperComponent.cs new file mode 100644 index 0000000000..71b4317d9c --- /dev/null +++ b/Content.Shared/GameObjects/Components/SharedPaperComponent.cs @@ -0,0 +1,63 @@ +using System; +using System.Net.Mime; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Components.UserInterface; +using Robust.Shared.Serialization; + +namespace Content.Shared.GameObjects.Components +{ + public class SharedPaperComponent : Component + { + public override string Name => "Paper"; + + [Serializable, NetSerializable] + public class PaperBoundUserInterfaceState : BoundUserInterfaceState + { + public readonly string Text; + public readonly PaperAction Mode; + + public PaperBoundUserInterfaceState(string text, PaperAction mode = PaperAction.Read) + { + Text = text; + Mode = mode; + } + } + + [Serializable, NetSerializable] + public class PaperActionMessage : BoundUserInterfaceMessage + { + public readonly PaperAction Action; + public PaperActionMessage(PaperAction action) + { + Action = action; + } + } + + [Serializable, NetSerializable] + public class PaperInputText : BoundUserInterfaceMessage + { + public readonly string Text; + + public PaperInputText(string text) + { + Text = text; + } + } + + [Serializable, NetSerializable] + public enum PaperUiKey + { + Key + } + + [Serializable, NetSerializable] + public enum PaperAction + { + Read, + Write, + CrossOut, + Stamp + } + + } +} diff --git a/Content.Shared/GameObjects/ContentNetIDs.cs b/Content.Shared/GameObjects/ContentNetIDs.cs index f47007a8b1..bb3f1c6400 100644 --- a/Content.Shared/GameObjects/ContentNetIDs.cs +++ b/Content.Shared/GameObjects/ContentNetIDs.cs @@ -39,5 +39,6 @@ public const uint WELDER = 1034; public const uint STACK = 1035; public const uint HANDHELD_LIGHT = 1036; + public const uint PAPER = 1037; } } diff --git a/Resources/Prototypes/Entities/items/paper.yml b/Resources/Prototypes/Entities/items/paper.yml new file mode 100644 index 0000000000..48cef161f0 --- /dev/null +++ b/Resources/Prototypes/Entities/items/paper.yml @@ -0,0 +1,37 @@ +- type: entity + name: Paper + parent: BaseItem + id: Paper + description: '' + components: + - type: Sprite + sprite: Objects/Misc/bureaucracy.rsi + state: paper + - type: Icon + sprite: Objects/Misc/bureaucracy.rsi + state: paper + - type: Item + sprite: Objects/Misc/bureaucracy.rsi + state: paper + - type: Paper + - type: UserInterface + interfaces: + - key: enum.PaperUiKey.Key + type: PaperBoundUserInterface + +- type: entity + name: Pen + parent: BaseItem + id: Pen + description: 'A dark ink pen' + components: + - type: Sprite + sprite: Objects/Misc/bureaucracy.rsi + state: pen + - type: Icon + sprite: Objects/Misc/bureaucracy.rsi + state: pen + - type: Item + sprite: Objects/Misc/bureaucracy.rsi + state: pen + - type: Write diff --git a/Resources/Textures/Objects/Misc/bureaucracy.dmi b/Resources/Textures/Objects/Misc/bureaucracy.dmi new file mode 100644 index 0000000000000000000000000000000000000000..41e890e983f0367a6a323869d50710d1d3bf5052 GIT binary patch literal 15020 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 C!@n>9 literal 0 HcmV?d00001