From e86770f5a03231e3189920c5d7ad93542d48e922 Mon Sep 17 00:00:00 2001 From: SpeltIncorrectyl <66873282+SpeltIncorrectyl@users.noreply.github.com> Date: Wed, 26 Feb 2025 09:11:59 +0000 Subject: [PATCH] Mime can no longer write on paper without breaking their vow (#35043) Co-authored-by: Simon <63975668+Simyon264@users.noreply.github.com> --- .../Abilities/Mime/MimePowersComponent.cs | 11 ++++++++ .../Abilities/Mime/MimePowersSystem.cs | 17 ++++++++++++ Content.Shared/Paper/BlockWritingComponent.cs | 17 ++++++++++++ Content.Shared/Paper/BlockWritingSystem.cs | 20 ++++++++++++++ Content.Shared/Paper/PaperSystem.cs | 27 +++++++++++++++++++ Resources/Locale/en-US/alerts/alerts.ftl | 4 +-- .../Locale/en-US/job/job-description.ftl | 2 +- .../Locale/en-US/paper/paper-component.ftl | 2 ++ Resources/Locale/en-US/tips.ftl | 2 +- .../Prototypes/Roles/Jobs/Civilian/mime.yml | 4 +-- 10 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 Content.Shared/Paper/BlockWritingComponent.cs create mode 100644 Content.Shared/Paper/BlockWritingSystem.cs diff --git a/Content.Server/Abilities/Mime/MimePowersComponent.cs b/Content.Server/Abilities/Mime/MimePowersComponent.cs index d56644ed19..24ffe5d023 100644 --- a/Content.Server/Abilities/Mime/MimePowersComponent.cs +++ b/Content.Server/Abilities/Mime/MimePowersComponent.cs @@ -55,5 +55,16 @@ namespace Content.Server.Abilities.Mime [DataField] public ProtoId VowBrokenAlert = "VowBroken"; + /// + /// Does this component prevent the mime from writing on paper while their vow is active? + /// + [DataField] + public bool PreventWriting = false; + + /// + /// What message is displayed when the mime fails to write? + /// + [DataField] + public LocId FailWriteMessage = "paper-component-illiterate-mime"; } } diff --git a/Content.Server/Abilities/Mime/MimePowersSystem.cs b/Content.Server/Abilities/Mime/MimePowersSystem.cs index bd8cf7c176..3de356f608 100644 --- a/Content.Server/Abilities/Mime/MimePowersSystem.cs +++ b/Content.Server/Abilities/Mime/MimePowersSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.Actions.Events; using Content.Shared.Alert; using Content.Shared.Coordinates.Helpers; using Content.Shared.Maps; +using Content.Shared.Paper; using Content.Shared.Physics; using Robust.Shared.Containers; using Robust.Shared.Map; @@ -55,6 +56,13 @@ namespace Content.Server.Abilities.Mime private void OnComponentInit(EntityUid uid, MimePowersComponent component, ComponentInit args) { EnsureComp(uid); + if (component.PreventWriting) + { + EnsureComp(uid, out var illiterateComponent); + illiterateComponent.FailWriteMessage = component.FailWriteMessage; + Dirty(uid, illiterateComponent); + } + _alertsSystem.ShowAlert(uid, component.VowAlert); _actionsSystem.AddAction(uid, ref component.InvisibleWallActionEntity, component.InvisibleWallAction, uid); } @@ -123,6 +131,8 @@ namespace Content.Server.Abilities.Mime mimePowers.VowBroken = true; mimePowers.VowRepentTime = _timing.CurTime + mimePowers.VowCooldown; RemComp(uid); + if (mimePowers.PreventWriting) + RemComp(uid); _alertsSystem.ClearAlert(uid, mimePowers.VowAlert); _alertsSystem.ShowAlert(uid, mimePowers.VowBrokenAlert); _actionsSystem.RemoveAction(uid, mimePowers.InvisibleWallActionEntity); @@ -146,6 +156,13 @@ namespace Content.Server.Abilities.Mime mimePowers.ReadyToRepent = false; mimePowers.VowBroken = false; AddComp(uid); + if (mimePowers.PreventWriting) + { + EnsureComp(uid, out var illiterateComponent); + illiterateComponent.FailWriteMessage = mimePowers.FailWriteMessage; + Dirty(uid, illiterateComponent); + } + _alertsSystem.ClearAlert(uid, mimePowers.VowBrokenAlert); _alertsSystem.ShowAlert(uid, mimePowers.VowAlert); _actionsSystem.AddAction(uid, ref mimePowers.InvisibleWallActionEntity, mimePowers.InvisibleWallAction, uid); diff --git a/Content.Shared/Paper/BlockWritingComponent.cs b/Content.Shared/Paper/BlockWritingComponent.cs new file mode 100644 index 0000000000..ae30e95458 --- /dev/null +++ b/Content.Shared/Paper/BlockWritingComponent.cs @@ -0,0 +1,17 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Paper; + +/// +/// An entity with this component cannot write on paper. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class BlockWritingComponent : Component +{ + /// + /// What message is displayed when the entity fails to write? + /// + [DataField] + [AutoNetworkedField] + public LocId FailWriteMessage = "paper-component-illiterate"; +} diff --git a/Content.Shared/Paper/BlockWritingSystem.cs b/Content.Shared/Paper/BlockWritingSystem.cs new file mode 100644 index 0000000000..476e3a2d94 --- /dev/null +++ b/Content.Shared/Paper/BlockWritingSystem.cs @@ -0,0 +1,20 @@ +namespace Content.Shared.Paper; + +/// +/// A system that prevents those with the IlliterateComponent from writing on paper. +/// Has no effect on reading ability. +/// +public sealed class BlockWritingSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnPaperWriteAttempt); + } + + private void OnPaperWriteAttempt(Entity entity, ref PaperWriteAttemptEvent args) + { + args.FailReason = entity.Comp.FailWriteMessage; + args.Cancelled = true; + } +} diff --git a/Content.Shared/Paper/PaperSystem.cs b/Content.Shared/Paper/PaperSystem.cs index 3c10ff2aaa..07fe8150e1 100644 --- a/Content.Shared/Paper/PaperSystem.cs +++ b/Content.Shared/Paper/PaperSystem.cs @@ -113,6 +113,21 @@ public sealed class PaperSystem : EntitySystem args.Handled = true; return; } + + var ev = new PaperWriteAttemptEvent(entity.Owner); + RaiseLocalEvent(args.User, ref ev); + if (ev.Cancelled) + { + if (ev.FailReason is not null) + { + var fileWriteMessage = Loc.GetString(ev.FailReason); + _popupSystem.PopupClient(fileWriteMessage, entity.Owner, args.User); + } + + args.Handled = true; + return; + } + var writeEvent = new PaperWriteEvent(entity, args.User); RaiseLocalEvent(args.Used, ref writeEvent); @@ -156,6 +171,11 @@ public sealed class PaperSystem : EntitySystem private void OnInputTextMessage(Entity entity, ref PaperInputTextMessage args) { + var ev = new PaperWriteAttemptEvent(entity.Owner); + RaiseLocalEvent(args.Actor, ref ev); + if (ev.Cancelled) + return; + if (args.Text.Length <= entity.Comp.ContentSize) { SetContent(entity, args.Text); @@ -229,3 +249,10 @@ public sealed class PaperSystem : EntitySystem /// [ByRefEvent] public record struct PaperWriteEvent(EntityUid User, EntityUid Paper); + +/// +/// Cancellable event for attempting to write on a piece of paper. +/// +/// The paper that the writing will take place on. +[ByRefEvent] +public record struct PaperWriteAttemptEvent(EntityUid Paper, string? FailReason = null, bool Cancelled = false); diff --git a/Resources/Locale/en-US/alerts/alerts.ftl b/Resources/Locale/en-US/alerts/alerts.ftl index 1748798bea..800e8950a5 100644 --- a/Resources/Locale/en-US/alerts/alerts.ftl +++ b/Resources/Locale/en-US/alerts/alerts.ftl @@ -82,10 +82,10 @@ alerts-muted-name = Muted alerts-muted-desc = You have lost the ability to speak. alerts-vow-silence-name = Vow of Silence -alerts-vow-silence-desc = You have taken a vow of silence as part of initiation into the Mystiko Tagma Mimon. Click to break your vow. +alerts-vow-silence-desc = You have taken a vow forbidding verbal or written communication as part of initiation into the Mystiko Tagma Mimon. Click to break your vow. alerts-vow-broken-name = Vow Broken -alerts-vow-broken-desc = You've broken your vows to Mimes everywhere. You can speak, but you've lost your powers for at least 5 entire minutes!!! Click to try and retake your vow. +alerts-vow-broken-desc = You've broken your vows to Mimes everywhere. You can speak and write, but you've lost your powers for at least 5 entire minutes!!! Click to try and retake your vow. alerts-pulled-name = Pulled alerts-pulled-desc = You're being pulled. Move to break free. diff --git a/Resources/Locale/en-US/job/job-description.ftl b/Resources/Locale/en-US/job/job-description.ftl index d91bb8bd21..fea5928ad2 100644 --- a/Resources/Locale/en-US/job/job-description.ftl +++ b/Resources/Locale/en-US/job/job-description.ftl @@ -31,7 +31,7 @@ job-description-intern = Learn the basics of administering medicine, basic chemi job-description-janitor = Keep the station clean of any trash or slipping hazards, and help deal with rat infestations. job-description-lawyer = Ensure that every prisoner or criminal receives a fair judgment and trial if necessary. job-description-librarian = Manage the library, give out knowledge to any who seek it, and report on activities aboard the station. -job-description-mime = Entertain the crew through non-vocal means, and engage with light rivalry with the clown. +job-description-mime = Entertain the crew without speaking or writing, and engage with light rivalry with the clown. job-description-musician = Entertain the crew with your unique musical talent, and acquire new instruments to mess around with. job-description-passenger = Enjoy your stay aboard the station with no obligations! job-description-psychologist = Provide emotional support to traumatized crew. Currently available on Box, Marathon and Oasis. diff --git a/Resources/Locale/en-US/paper/paper-component.ftl b/Resources/Locale/en-US/paper/paper-component.ftl index 7425ea2da1..b4bf222e03 100644 --- a/Resources/Locale/en-US/paper/paper-component.ftl +++ b/Resources/Locale/en-US/paper/paper-component.ftl @@ -7,6 +7,8 @@ paper-ui-blank-page-message = This page intentionally left blank paper-component-examine-detail-has-words = {CAPITALIZE(THE($paper))} has something written on it. # Shown when paper with stamps examined paper-component-examine-detail-stamped-by = {CAPITALIZE(THE($paper))} {CONJUGATE-HAVE($paper)} been stamped by: {$stamps}. +paper-component-illiterate = You are unable to write. +paper-component-illiterate-mime = Your vow forbids you from writing. paper-component-action-stamp-paper-other = {CAPITALIZE(THE($user))} stamps {THE($target)} with {THE($stamp)}. paper-component-action-stamp-paper-self = You stamp {THE($target)} with {THE($stamp)}. diff --git a/Resources/Locale/en-US/tips.ftl b/Resources/Locale/en-US/tips.ftl index dcadd15b1b..e0e71d66da 100644 --- a/Resources/Locale/en-US/tips.ftl +++ b/Resources/Locale/en-US/tips.ftl @@ -61,7 +61,7 @@ tips-dataset-60 = As the Clown, spice your gimmicks up! Nobody likes a one-trick tips-dataset-61 = As the Clown, if you lose your banana peels and soap, you can still slip people with your PDA! Honk! tips-dataset-62 = As the Chef, your knife can act as a weapon in an emergency. tips-dataset-63 = As the Chef, you can sneak liquids into your foods. As a traitor, putting a little bit of amatoxin or other poison can greatly annoy the crew! -tips-dataset-64 = As the Mime, your oath of silence is your source of power. Breaking it robs you of your powers and of your honor. +tips-dataset-64 = As the Mime, your vow to not speak or write is your source of power. Breaking it robs you of your powers and of your honor. tips-dataset-65 = As the Lawyer, try to negotiate with the Warden if sentences seem too high for the crime. tips-dataset-66 = As a Security Officer, communicate and coordinate with your fellow officers using the security radio channel to avoid confusion. tips-dataset-67 = As a Security Officer, remember that correlation does not equal causation. Someone may have just been at the wrong place at the wrong time! diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/mime.yml b/Resources/Prototypes/Roles/Jobs/Civilian/mime.yml index de8a900f8e..243dafabf2 100644 --- a/Resources/Prototypes/Roles/Jobs/Civilian/mime.yml +++ b/Resources/Prototypes/Roles/Jobs/Civilian/mime.yml @@ -16,6 +16,7 @@ - !type:AddComponentSpecial components: - type: MimePowers + preventWriting: true - type: FrenchAccent - type: startingGear @@ -23,9 +24,8 @@ equipment: gloves: ClothingHandsGlovesColorWhite shoes: ClothingShoesColorWhite - pocket1: CrayonMime - pocket2: Paper id: MimePDA + pocket1: CrayonMime ears: ClothingHeadsetService storage: back: -- 2.51.2