]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Voice mask effects are toggleable and hide your accent (#41965)
authoralexalexmax <149889301+alexalexmax@users.noreply.github.com>
Fri, 26 Dec 2025 02:47:05 +0000 (18:47 -0800)
committerGitHub <noreply@github.com>
Fri, 26 Dec 2025 02:47:05 +0000 (02:47 +0000)
* apply negate accents system

* add toggle to voice mask ui

* roll negateaccents into voice mask system, delete negate accents comp&system, update yml entries

* convert button to ToggleButton and some cleanup

* retry for heisenfail

* accent toggle

* update names and add mask active check for accent hiding

12 files changed:
Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs
Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml
Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs
Content.Server/Chat/Systems/ChatSystem.cs
Content.Server/Speech/AccentSystem.cs
Content.Server/VoiceMask/VoiceMaskComponent.cs
Content.Server/VoiceMask/VoiceMaskSystem.cs
Content.Shared/Chat/SharedChatEvents.cs
Content.Shared/Implants/SharedSubdermalImplantSystem.Relays.cs
Content.Shared/Inventory/InventorySystem.Relay.cs
Content.Shared/VoiceMask/SharedVoiceMaskSystem.cs
Resources/Locale/en-US/voice-mask.ftl

index e76ca1cf8f70356cb1d67f17c45d3b47a5a28db5..b2b374cac5b88575356a016bf4bd638e9f1da19a 100644 (file)
@@ -26,6 +26,8 @@ public sealed class VoiceMaskBoundUserInterface : BoundUserInterface
 
         _window.OnNameChange += OnNameSelected;
         _window.OnVerbChange += verb => SendMessage(new VoiceMaskChangeVerbMessage(verb));
+        _window.OnToggle += OnToggle;
+        _window.OnAccentToggle += OnAccentToggle;
     }
 
     private void OnNameSelected(string name)
@@ -33,6 +35,16 @@ public sealed class VoiceMaskBoundUserInterface : BoundUserInterface
         SendMessage(new VoiceMaskChangeNameMessage(name));
     }
 
+    private void OnToggle()
+    {
+        SendMessage(new VoiceMaskToggleMessage());
+    }
+
+    private void OnAccentToggle()
+    {
+        SendMessage(new VoiceMaskAccentToggleMessage());
+    }
+
     protected override void UpdateState(BoundUserInterfaceState state)
     {
         if (state is not VoiceMaskBuiState cast || _window == null)
@@ -40,7 +52,7 @@ public sealed class VoiceMaskBoundUserInterface : BoundUserInterface
             return;
         }
 
-        _window.UpdateState(cast.Name, cast.Verb);
+        _window.UpdateState(cast.Name, cast.Verb, cast.Active, cast.AccentHide);
     }
 
     protected override void Dispose(bool disposing)
index e23aca123919de60a0333c82b31c73fe1fd50507..18416757b9ece7b57086167b4faeb4ff5f9bb8ea 100644 (file)
@@ -12,5 +12,7 @@
             <Label Text="{Loc 'voice-mask-name-change-speech-style'}" />
             <OptionButton Name="SpeechVerbSelector" /> <!-- Populated in LoadVerbs -->
         </BoxContainer>
+        <Button Name="ToggleAccentButton" Text="{Loc 'voice-mask-name-change-accent-toggle'}" HorizontalExpand="True" ToggleMode="True" Margin="5"/>
+        <Button Name="ToggleButton" Text="{Loc 'voice-mask-name-change-toggle'}" HorizontalExpand="True" ToggleMode="True" Margin="5"/>
     </BoxContainer>
 </controls:FancyWindow>
index 7ca4dd4b95701e71ff8febcae24d95d32677bdff..a5e70362831116fc16266c3b4b27b86ee13c4341 100644 (file)
@@ -12,6 +12,8 @@ public sealed partial class VoiceMaskNameChangeWindow : FancyWindow
 {
     public Action<string>? OnNameChange;
     public Action<string?>? OnVerbChange;
+    public Action? OnToggle;
+    public Action? OnAccentToggle;
 
     private List<(string, string)> _verbs = new();
 
@@ -31,6 +33,9 @@ public sealed partial class VoiceMaskNameChangeWindow : FancyWindow
             OnVerbChange?.Invoke((string?) args.Button.GetItemMetadata(args.Id));
             SpeechVerbSelector.SelectId(args.Id);
         };
+
+        ToggleButton.OnPressed += args => OnToggle?.Invoke();
+        ToggleAccentButton.OnPressed += args => OnAccentToggle?.Invoke();
     }
 
     public void ReloadVerbs(IPrototypeManager proto)
@@ -64,10 +69,12 @@ public sealed partial class VoiceMaskNameChangeWindow : FancyWindow
             SpeechVerbSelector.SelectId(id);
     }
 
-    public void UpdateState(string name, string? verb)
+    public void UpdateState(string name, string? verb, bool active, bool accentHide)
     {
         NameSelector.Text = name;
         _verb = verb;
+        ToggleButton.Pressed = active;
+        ToggleAccentButton.Pressed = accentHide;
 
         for (int id = 0; id < SpeechVerbSelector.ItemCount; id++)
         {
index 581b678b843d9477452f4bb6d5ca7c397f5b5093..9ea04ca3bce4d18247038864a2ae949bb65ec780 100644 (file)
@@ -736,7 +736,7 @@ public sealed partial class ChatSystem : SharedChatSystem
     public string TransformSpeech(EntityUid sender, string message)
     {
         var ev = new TransformSpeechEvent(sender, message);
-        RaiseLocalEvent(ev);
+        RaiseLocalEvent(sender, ev, true);
 
         return ev.Message;
     }
index 275a4175c808c103442d7948ec203ca0c6369960..6f89a7d14d1df40f4415598018ec5b719695a667 100644 (file)
@@ -15,6 +15,9 @@ public sealed class AccentSystem : EntitySystem
 
     private void AccentHandler(TransformSpeechEvent args)
     {
+        if (args.Cancelled)
+            return;
+
         var accentEvent = new AccentGetEvent(args.Sender, args.Message);
 
         RaiseLocalEvent(args.Sender, accentEvent, true);
index f7e07f2bd1af5e0e869713acf82f1a3d37b2306b..042b78a85917e1b3325209b45b8ffcb72c682dc7 100644 (file)
@@ -43,5 +43,17 @@ public sealed partial class VoiceMaskComponent : Component
     /// </summary>
     [DataField]
     public EntityUid? ActionEntity;
+
+    /// <summary>
+    ///     If user's voice is getting changed when they speak.
+    /// </summary>
+    [DataField]
+    public bool Active = true;
+
+    /// <summary>
+    ///     If user's accent is getting hidden when they speak.
+    /// </summary>
+    [DataField]
+    public bool AccentHide = true;
 }
 
index 170bddf0828d158882fc70fd10cdf683e70430da..a67bfb8b669f886f29ed74734e8764e982df666d 100644 (file)
@@ -1,3 +1,4 @@
+using Content.Server.Speech;
 using Content.Shared.Actions;
 using Content.Shared.Administration.Logs;
 using Content.Shared.CCVar;
@@ -10,7 +11,6 @@ using Content.Shared.Implants;
 using Content.Shared.Inventory;
 using Content.Shared.Lock;
 using Content.Shared.Popups;
-using Content.Shared.Preferences;
 using Content.Shared.Speech;
 using Content.Shared.VoiceMask;
 using Robust.Shared.Configuration;
@@ -45,12 +45,41 @@ public sealed partial class VoiceMaskSystem : EntitySystem
         SubscribeLocalEvent<VoiceMaskComponent, LockToggledEvent>(OnLockToggled);
         SubscribeLocalEvent<VoiceMaskComponent, VoiceMaskChangeNameMessage>(OnChangeName);
         SubscribeLocalEvent<VoiceMaskComponent, VoiceMaskChangeVerbMessage>(OnChangeVerb);
+        SubscribeLocalEvent<VoiceMaskComponent, VoiceMaskToggleMessage>(OnToggle);
+        SubscribeLocalEvent<VoiceMaskComponent, VoiceMaskAccentToggleMessage>(OnAccentToggle);
         SubscribeLocalEvent<VoiceMaskComponent, ClothingGotEquippedEvent>(OnEquip);
         SubscribeLocalEvent<VoiceMaskSetNameEvent>(OpenUI);
+        SubscribeLocalEvent<VoiceMaskComponent, TransformSpeechEvent>(OnTransformSpeech, before: [typeof(AccentSystem)]);
+        SubscribeLocalEvent<VoiceMaskComponent, InventoryRelayedEvent<TransformSpeechEvent>>(OnTransformSpeechInventory, before: [typeof(AccentSystem)]);
+        SubscribeLocalEvent<VoiceMaskComponent, ImplantRelayEvent<TransformSpeechEvent>>(OnTransformSpeechImplant, before: [typeof(AccentSystem)]);
 
         Subs.CVar(_cfgManager, CCVars.MaxNameLength, value => _maxNameLength = value, true);
     }
 
+    /// <summary>
+    ///     Hides accent if the voice mask is on and the option to block accents is on
+    /// </summary>
+    private void TransformSpeech(Entity<VoiceMaskComponent> entity, TransformSpeechEvent args)
+    {
+        if (entity.Comp.AccentHide && entity.Comp.Active)
+            args.Cancel();
+    }
+
+    private void OnTransformSpeech(Entity<VoiceMaskComponent> entity, ref TransformSpeechEvent args)
+    {
+        TransformSpeech(entity, args);
+    }
+
+    private void OnTransformSpeechInventory(Entity<VoiceMaskComponent> entity, ref InventoryRelayedEvent<TransformSpeechEvent> args)
+    {
+        TransformSpeech(entity, args.Args);
+    }
+
+    private void OnTransformSpeechImplant(Entity<VoiceMaskComponent> entity, ref ImplantRelayEvent<TransformSpeechEvent> args)
+    {
+        TransformSpeech(entity, args.Event);
+    }
+
     private void OnTransformSpeakerNameInventory(Entity<VoiceMaskComponent> entity, ref InventoryRelayedEvent<TransformSpeakerNameEvent> args)
     {
         TransformVoice(entity, args.Args);
@@ -63,8 +92,10 @@ public sealed partial class VoiceMaskSystem : EntitySystem
 
     private void OnSeeIdentityAttemptEvent(Entity<VoiceMaskComponent> entity, ref ImplantRelayEvent<SeeIdentityAttemptEvent> args)
     {
-        if (entity.Comp.OverrideIdentity)
-            args.Event.NameOverride = GetCurrentVoiceName(entity);
+        if (!entity.Comp.OverrideIdentity || !entity.Comp.Active)
+            return;
+
+        args.Event.NameOverride = GetCurrentVoiceName(entity);
     }
 
     private void OnImplantImplantedEvent(Entity<VoiceMaskComponent> entity, ref ImplantImplantedEvent ev)
@@ -117,6 +148,21 @@ public sealed partial class VoiceMaskSystem : EntitySystem
 
         UpdateUI(entity);
     }
+
+    private void OnToggle(Entity<VoiceMaskComponent> entity, ref VoiceMaskToggleMessage args)
+    {
+        _popupSystem.PopupEntity(Loc.GetString("voice-mask-popup-toggle"), entity, args.Actor);
+        entity.Comp.Active = !entity.Comp.Active;
+
+        // Update identity because of possible name override
+        _identity.QueueIdentityUpdate(args.Actor);
+    }
+
+    private void OnAccentToggle(Entity<VoiceMaskComponent> entity, ref VoiceMaskAccentToggleMessage args)
+    {
+        _popupSystem.PopupEntity(Loc.GetString("voice-mask-popup-accent-toggle"), entity, args.Actor);
+        entity.Comp.AccentHide = !entity.Comp.AccentHide;
+    }
     #endregion
 
     #region UI
@@ -145,7 +191,7 @@ public sealed partial class VoiceMaskSystem : EntitySystem
     private void UpdateUI(Entity<VoiceMaskComponent> entity)
     {
         if (_uiSystem.HasUi(entity, VoiceMaskUIKey.Key))
-            _uiSystem.SetUiState(entity.Owner, VoiceMaskUIKey.Key, new VoiceMaskBuiState(GetCurrentVoiceName(entity), entity.Comp.VoiceMaskSpeechVerb));
+            _uiSystem.SetUiState(entity.Owner, VoiceMaskUIKey.Key, new VoiceMaskBuiState(GetCurrentVoiceName(entity), entity.Comp.VoiceMaskSpeechVerb, entity.Comp.Active, entity.Comp.AccentHide));
     }
     #endregion
 
@@ -157,6 +203,9 @@ public sealed partial class VoiceMaskSystem : EntitySystem
 
     private void TransformVoice(Entity<VoiceMaskComponent> entity, TransformSpeakerNameEvent args)
     {
+        if (!entity.Comp.Active)
+            return;
+
         args.VoiceName = GetCurrentVoiceName(entity);
         args.SpeechVerb = entity.Comp.VoiceMaskSpeechVerb ?? args.SpeechVerb;
     }
index f9b706e57d93472a7dff85fb697cb23a059cf41e..5701081b56f0ff466cc194708d09a4995cc15ed9 100644 (file)
@@ -27,8 +27,9 @@ public sealed class TransformSpeakerNameEvent : EntityEventArgs, IInventoryRelay
 /// <summary>
 /// Raised broadcast in order to transform speech.transmit
 /// </summary>
-public sealed class TransformSpeechEvent : EntityEventArgs
+public sealed class TransformSpeechEvent : CancellableEntityEventArgs, IInventoryRelayEvent
 {
+    public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
     public EntityUid Sender;
     public string Message;
 
index 774be5d9b27275cf53a37a2a66a9120e168c2142..24b76e15c56ac74a40156a88d502f112617d80c8 100644 (file)
@@ -15,6 +15,7 @@ public abstract partial class SharedSubdermalImplantSystem
         SubscribeLocalEvent<ImplantedComponent, AfterInteractUsingEvent>(RelayToImplantEvent);
         SubscribeLocalEvent<ImplantedComponent, SuicideEvent>(RelayToImplantEvent);
         SubscribeLocalEvent<ImplantedComponent, TransformSpeakerNameEvent>(RelayToImplantEvent);
+        SubscribeLocalEvent<ImplantedComponent, TransformSpeechEvent>(RelayToImplantEvent);
         SubscribeLocalEvent<ImplantedComponent, SeeIdentityAttemptEvent>(RelayToImplantEvent);
     }
 
index 242e8d0de9a8b90019c74a4c801b659f55dea3ab..280a99cd326fcf3671964312b1fc8d69032fd618 100644 (file)
@@ -47,6 +47,7 @@ public partial class InventorySystem
         SubscribeLocalEvent<InventoryComponent, GetDefaultRadioChannelEvent>(RelayInventoryEvent);
         SubscribeLocalEvent<InventoryComponent, RefreshNameModifiersEvent>(RelayInventoryEvent);
         SubscribeLocalEvent<InventoryComponent, TransformSpeakerNameEvent>(RelayInventoryEvent);
+        SubscribeLocalEvent<InventoryComponent, TransformSpeechEvent>(RelayInventoryEvent);
         SubscribeLocalEvent<InventoryComponent, SelfBeforeInjectEvent>(RelayInventoryEvent);
         SubscribeLocalEvent<InventoryComponent, BeforeInjectTargetEvent>(RelayInventoryEvent);
         SubscribeLocalEvent<InventoryComponent, SelfBeforeGunShotEvent>(RelayInventoryEvent);
index 28558919461773a15b3b59603204251b53ec5474..9d586a5af8ce35e84621eccc4f1ca075e2146560 100644 (file)
@@ -13,11 +13,15 @@ public sealed class VoiceMaskBuiState : BoundUserInterfaceState
 {
     public readonly string Name;
     public readonly string? Verb;
+    public readonly bool Active;
+    public readonly bool AccentHide;
 
-    public VoiceMaskBuiState(string name, string? verb)
+    public VoiceMaskBuiState(string name, string? verb, bool active, bool accentHide)
     {
         Name = name;
         Verb = verb;
+        Active = active;
+        AccentHide = accentHide;
     }
 }
 
@@ -45,3 +49,15 @@ public sealed class VoiceMaskChangeVerbMessage : BoundUserInterfaceMessage
         Verb = verb;
     }
 }
+
+/// <summary>
+///     Toggle the effects of the voice mask.
+/// </summary>
+[Serializable, NetSerializable]
+public sealed class VoiceMaskToggleMessage : BoundUserInterfaceMessage;
+
+/// <summary>
+///     Toggle the effects of accent negation.
+/// </summary>
+[Serializable, NetSerializable]
+public sealed class VoiceMaskAccentToggleMessage : BoundUserInterfaceMessage;
index f3740cdafb68d70d55eec89d8a20ceb15cbb41d8..cd06e61eb2eb465b7ad5a731afda0c28301bd336 100644 (file)
@@ -5,6 +5,11 @@ voice-mask-name-change-info = Type in the name you want to mimic.
 voice-mask-name-change-speech-style = Speech style
 voice-mask-name-change-set = Set name
 voice-mask-name-change-set-description = Change the name others hear to something else.
+voice-mask-name-change-toggle = Toggle voice mask
+voice-mask-name-change-accent-toggle = Block accent
+
+voice-mask-popup-toggle = Toggled voice mask.
+voice-mask-popup-accent-toggle = Toggled accent.
 
 voice-mask-popup-success = Name set successfully.
 voice-mask-popup-failure = Name could not be set.