]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix looking at verbs causing sounds or popups (#41609)
authorslarticodefast <161409025+slarticodefast@users.noreply.github.com>
Fri, 28 Nov 2025 21:41:44 +0000 (22:41 +0100)
committerGitHub <noreply@github.com>
Fri, 28 Nov 2025 21:41:44 +0000 (21:41 +0000)
* fix verb popups

* spelling

14 files changed:
Content.Client/Power/ActivatableUIRequiresPowerSystem.cs
Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs
Content.Server/Atmos/Portable/SpaceHeaterSystem.cs
Content.Server/DeviceNetwork/Systems/NetworkConfiguratorSystem.cs
Content.Server/NukeOps/WarDeclaratorSystem.cs
Content.Server/Store/Systems/StoreSystem.cs
Content.Shared/Access/Systems/ActivatableUIRequiresAccessSystem.cs
Content.Shared/Eye/Blinding/Systems/ActivatableUIRequiresVisionSystem.cs
Content.Shared/Lock/LockSystem.cs
Content.Shared/Shuttles/Systems/SharedEmergencyShuttleSystem.cs
Content.Shared/UserInterface/ActivatableUIEvents.cs
Content.Shared/UserInterface/ActivatableUIRequiresAnchorSystem.cs
Content.Shared/UserInterface/ActivatableUISystem.Power.cs
Content.Shared/UserInterface/ActivatableUISystem.cs

index a6a20958f536a85dfc77df19e9b11dfd6fca3278..1db0daef2dd92831e19c4a755754f456bb3229da 100644 (file)
@@ -18,7 +18,9 @@ public sealed class ActivatableUIRequiresPowerSystem : SharedActivatableUIRequir
             return;
         }
 
-        _popup.PopupClient(Loc.GetString("base-computer-ui-component-not-powered", ("machine", ent.Owner)), args.User, args.User);
+        if (!args.Silent)
+            _popup.PopupClient(Loc.GetString("base-computer-ui-component-not-powered", ("machine", ent.Owner)), args.User, args.User);
+
         args.Cancel();
     }
 }
index 1e8ed8cdf3af2e1f1abb28a697d4a8155701786c..f21dc2471f4a9e02e339f1ed7733da2a9db6b0ac 100644 (file)
@@ -52,12 +52,12 @@ public sealed class BlockGameArcadeSystem : EntitySystem
     private void OnAfterUIOpen(EntityUid uid, BlockGameArcadeComponent component, AfterActivatableUIOpenEvent args)
     {
         if (component.Player == null)
-            component.Player = args.Actor;
+            component.Player = args.User;
         else
-            component.Spectators.Add(args.Actor);
+            component.Spectators.Add(args.User);
 
-        UpdatePlayerStatus(uid, args.Actor, component);
-        component.Game?.UpdateNewPlayerUI(args.Actor);
+        UpdatePlayerStatus(uid, args.User, component);
+        component.Game?.UpdateNewPlayerUI(args.User);
     }
 
     private void OnAfterUiClose(EntityUid uid, BlockGameArcadeComponent component, BoundUIClosedEvent args)
index 0d55ed12bd04e5b3dfca9258d56a6e357b0599d7..7410810f8b447545a4b78f7daa2f8067656b0335 100644 (file)
@@ -54,11 +54,13 @@ public sealed class SpaceHeaterSystem : EntitySystem
 
     private void OnUIActivationAttempt(EntityUid uid, SpaceHeaterComponent spaceHeater, ActivatableUIOpenAttemptEvent args)
     {
-        if (!Comp<TransformComponent>(uid).Anchored)
-        {
+        if (Comp<TransformComponent>(uid).Anchored)
+            return;
+
+        if (!args.Silent)
             _popup.PopupEntity(Loc.GetString("comp-space-heater-unanchored", ("device", Loc.GetString("comp-space-heater-device-name"))), uid, args.User);
-            args.Cancel();
-        }
+
+        args.Cancel();
     }
 
     private void OnDeviceUpdated(EntityUid uid, SpaceHeaterComponent spaceHeater, ref AtmosDeviceUpdateEvent args)
index 97b27821fd4a007c028d567682ddfa0d225a625a..b31e6a6d3bf1a164636ac392998b0ccae0212281 100644 (file)
@@ -839,11 +839,5 @@ public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
 
         UpdateListUiState(conf, conf.Comp);
     }
-
-    private void OnUiOpenAttempt(EntityUid uid, NetworkConfiguratorComponent configurator, ActivatableUIOpenAttemptEvent args)
-    {
-        if (configurator.LinkModeActive)
-            args.Cancel();
-    }
     #endregion
 }
index a2d74e16b32848e6a53f448502f320084329255d..71e4431d7354082bacebb48847f78ad2ef9cdf5a 100644 (file)
@@ -44,8 +44,11 @@ public sealed class WarDeclaratorSystem : EntitySystem
     {
         if (!_accessReaderSystem.IsAllowed(args.User, ent))
         {
-            var msg = Loc.GetString("war-declarator-not-working");
-            _popupSystem.PopupEntity(msg, ent);
+            if (!args.Silent)
+            {
+                var msg = Loc.GetString("war-declarator-not-working");
+                _popupSystem.PopupEntity(msg, ent);
+            }
             args.Cancel();
             return;
         }
index 279026c8738bf4bd0a5d578a8fb33618206a2e1a..7c5c99b5b4fbeebc981db7651bf37f3edc5af002 100644 (file)
@@ -81,7 +81,9 @@ public sealed partial class StoreSystem : EntitySystem
         if (component.AccountOwner == mind)
             return;
 
-        _popup.PopupEntity(Loc.GetString("store-not-account-owner", ("store", uid)), uid, args.User);
+        if (!args.Silent)
+            _popup.PopupEntity(Loc.GetString("store-not-account-owner", ("store", uid)), uid, args.User);
+
         args.Cancel();
     }
 
index 9020518f216e835c46eb1dbfec1ab6107137e71c..eb94ed324d1f4fc2b5e369b507f3de2185eeb52a 100644 (file)
@@ -23,7 +23,7 @@ public sealed class ActivatableUIRequiresAccessSystem : EntitySystem
         if (!_access.IsAllowed(args.User, activatableUI))
         {
             args.Cancel();
-            if (activatableUI.Comp.PopupMessage != null)
+            if (activatableUI.Comp.PopupMessage != null && !args.Silent)
                 _popup.PopupClient(Loc.GetString(activatableUI.Comp.PopupMessage), activatableUI, args.User);
         }
     }
index 6ed0c4cd6db03d984f8b8a276fb6202b5321aaa4..01c83ded9516aae88ed180b2c033d9998b0caa7e 100644 (file)
@@ -24,7 +24,8 @@ public sealed class ActivatableUIRequiresVisionSystem : EntitySystem
 
         if (TryComp<BlindableComponent>(args.User, out var blindable) && blindable.IsBlind)
         {
-            _popupSystem.PopupClient(Loc.GetString("blindness-fail-attempt"), args.User, Shared.Popups.PopupType.MediumCaution);
+            if (!args.Silent)
+                _popupSystem.PopupClient(Loc.GetString("blindness-fail-attempt"), args.User, Shared.Popups.PopupType.MediumCaution);
             args.Cancel();
         }
     }
index 560bb296ac391beebb1c7b10caa98f13d3326252..4b44378cdfe2e1ea7906f7eb4e872dc1a8b1307c 100644 (file)
@@ -477,6 +477,10 @@ public sealed class LockSystem : EntitySystem
             return;
 
         args.Cancel();
+
+        if (args.Silent)
+            return;
+
         if (lockComp.Locked && component.Popup != null)
         {
             _sharedPopupSystem.PopupClient(Loc.GetString(component.Popup), uid, args.User);
index 7f818767ea6d794940daba6b724c5cf04628b4b1..5f1477acc223baf38b28b16ea714affa4d8a39a5 100644 (file)
@@ -29,6 +29,8 @@ public abstract class SharedEmergencyShuttleSystem : EntitySystem
             return;
 
         args.Cancel();
-        Popup.PopupClient(Loc.GetString("emergency-shuttle-console-no-early-launches"), ent, args.User);
+
+        if (!args.Silent)
+            Popup.PopupClient(Loc.GetString("emergency-shuttle-console-no-early-launches"), ent, args.User);
     }
 }
index ef2a7b1b9f75534527e0fb001bc649d381051d1a..81aac5433435250ac5eb361ccd191e51fb814de7 100644 (file)
@@ -1,53 +1,70 @@
 namespace Content.Shared.UserInterface;
 
 /// <summary>
+/// Raised on the entity with an activatable UI when attempting to open it.
 /// This is raised BEFORE opening a UI! Do not listen and then open / do something use
 /// <see cref="AfterActivatableUIOpenEvent"/> for that.
 /// </summary>
-public sealed class ActivatableUIOpenAttemptEvent : CancellableEntityEventArgs
+public sealed class ActivatableUIOpenAttemptEvent(EntityUid user, bool silent) : CancellableEntityEventArgs
 {
-    public EntityUid User { get; }
-    public ActivatableUIOpenAttemptEvent(EntityUid who)
-    {
-        User = who;
-    }
+    /// <summary>
+    /// The player trying to open the UI.
+    /// </summary>
+    public readonly EntityUid User = user;
+
+    /// <summary>
+    /// Whether subscriptions are allowed to play a sound or show popups.
+    /// This is used to prevent just looking at the verb without even clicking on it showing a popup or playing sounds.
+    /// </summary>
+    public bool Silent = silent;
 }
 
-public sealed class UserOpenActivatableUIAttemptEvent : CancellableEntityEventArgs //have to one-up the already stroke-inducing name
+/// <summary>
+/// Raised on the player when they are attempting to open an activatable UI.
+/// This is raised BEFORE opening a UI! Do not listen and then open / do something use
+/// <see cref="AfterActivatableUIOpenEvent"/> for that.
+/// </summary>
+public sealed class UserOpenActivatableUIAttemptEvent(EntityUid user, EntityUid target, bool silent) : CancellableEntityEventArgs //have to one-up the already stroke-inducing name
 {
-    public EntityUid User { get; }
-    public EntityUid Target { get; }
-    public UserOpenActivatableUIAttemptEvent(EntityUid who, EntityUid target)
-    {
-        User = who;
-        Target = target;
-    }
+    /// <summary>
+    /// The player trying to open the UI.
+    /// </summary>
+    public readonly EntityUid User = user;
+
+    /// <summary>
+    /// The target entity with the UI.
+    /// </summary>
+    public readonly EntityUid Target = target;
+
+    /// <summary>
+    /// Whether subscriptions are allowed to play a sound or show popups.
+    /// This is used to prevent just looking at the verb without even clicking on it to show a popup or play sounds if the attempt is cancelled.
+    /// </summary>
+    public bool Silent = silent;
 }
 
-public sealed class AfterActivatableUIOpenEvent : EntityEventArgs
+/// <summary>
+/// Raised on the entity with an activatable UI after the UI has been opened.
+/// </summary>
+public sealed class AfterActivatableUIOpenEvent(EntityUid user) : EntityEventArgs
 {
-    public EntityUid User { get; }
-    public readonly EntityUid Actor;
-
-    public AfterActivatableUIOpenEvent(EntityUid who, EntityUid actor)
-    {
-        User = who;
-        Actor = actor;
-    }
+    /// <summary>
+    /// The player that opened the UI.
+    /// </summary>
+    public readonly EntityUid User = user;
 }
 
 /// <summary>
-/// This is after it's decided the user can open the UI,
+/// Raised on the entity with an activatable UI after it's decided the user can open the UI,
 /// but before the UI actually opens.
-/// Use this if you need to prepare the UI itself
+/// Use this if you need to prepare the UI itself.
 /// </summary>
-public sealed class BeforeActivatableUIOpenEvent : EntityEventArgs
+public sealed class BeforeActivatableUIOpenEvent(EntityUid user) : EntityEventArgs
 {
-    public EntityUid User { get; }
-    public BeforeActivatableUIOpenEvent(EntityUid who)
-    {
-        User = who;
-    }
+    /// <summary>
+    /// The player that is opening the UI.
+    /// </summary>
+    public readonly EntityUid User = user;
 }
 
 public sealed class ActivatableUIPlayerChangedEvent : EntityEventArgs
index 6aa505963300c2ef32528964d1c4b713cac177c5..c9f4a0ce1330c4f0a076f07d3ee2143dab910e46 100644 (file)
@@ -32,14 +32,14 @@ public sealed class ActivatableUIRequiresAnchorSystem : EntitySystem
         if (args.Cancelled)
             return;
 
-        if (!Transform(ent.Owner).Anchored)
-        {
-            if (ent.Comp.Popup != null)
-            {
-                _popup.PopupClient(Loc.GetString(ent.Comp.Popup), args.User);
-            }
+        if (Transform(ent.Owner).Anchored)
+            return;
 
-            args.Cancel();
+        if (ent.Comp.Popup != null && !args.Silent)
+        {
+            _popup.PopupClient(Loc.GetString(ent.Comp.Popup), args.User);
         }
+
+        args.Cancel();
     }
 }
index 3e52e3ed36f030dcf9788044773c4ab1be78003f..f4b866044cc0661d6f4cd8b10ded69dd84ce90d5 100644 (file)
@@ -74,8 +74,9 @@ public sealed partial class ActivatableUISystem
             return;
 
         // Check if we have the appropriate drawrate / userate to even open it.
-        if (!_cell.HasActivatableCharge(uid, user: args.User, predicted: true) ||
-            !_cell.HasDrawCharge(uid, user: args.User, predicted: true))
+        // Don't pass in the user for the popup if silent.
+        if (!_cell.HasActivatableCharge(uid, user: args.Silent ? null : args.User, predicted: true) ||
+            !_cell.HasDrawCharge(uid, user: args.Silent ? null : args.User, predicted: true))
         {
             args.Cancel();
         }
index d1df375ccb54406e9c3ee164fd1b3a7d5c9f88ab..8b2299ccfc43a8498884d0a89a4531eeeaf21054 100644 (file)
@@ -108,7 +108,7 @@ public sealed partial class ActivatableUISystem : EntitySystem
 
             if (component.InHandsOnly)
             {
-                if (!_hands.IsHolding((args.User, args.Hands), uid, out var hand ))
+                if (!_hands.IsHolding((args.User, args.Hands), uid, out var hand))
                     return false;
 
                 if (component.RequireActiveHand && args.Hands.ActiveHandId != hand)
@@ -116,7 +116,10 @@ public sealed partial class ActivatableUISystem : EntitySystem
             }
         }
 
-        return (args.CanInteract || HasComp<GhostComponent>(args.User) && !component.BlockSpectators) && !RaiseCanOpenEventChecks(args.User, uid);
+        return ((args.CanInteract
+            || HasComp<GhostComponent>(args.User)
+            && !component.BlockSpectators))
+            && RaiseCanOpenEventChecks(args.User, uid, silent: true); // silent to prevent popups or sounds when only looking at the verb
     }
 
     private void OnUseInHand(EntityUid uid, ActivatableUIComponent component, UseInHandEvent args)
@@ -225,7 +228,7 @@ public sealed partial class ActivatableUISystem : EntitySystem
 
         // If we've gotten this far, fire a cancellable event that indicates someone is about to activate this.
         // This is so that stuff can require further conditions (like power).
-        if (RaiseCanOpenEventChecks(user, uiEntity))
+        if (!RaiseCanOpenEventChecks(user, uiEntity))
             return false;
 
         // Give the UI an opportunity to prepare itself if it needs to do anything
@@ -237,7 +240,7 @@ public sealed partial class ActivatableUISystem : EntitySystem
         _uiSystem.OpenUi(uiEntity, aui.Key, user);
 
         //Let the component know a user opened it so it can do whatever it needs to do
-        var aae = new AfterActivatableUIOpenEvent(user, user);
+        var aae = new AfterActivatableUIOpenEvent(user);
         RaiseLocalEvent(uiEntity, aae);
 
         return true;
@@ -283,14 +286,22 @@ public sealed partial class ActivatableUISystem : EntitySystem
             CloseAll(ent, ent);
     }
 
-    private bool RaiseCanOpenEventChecks(EntityUid user, EntityUid uiEntity)
+    private bool RaiseCanOpenEventChecks(EntityUid user, EntityUid uiEntity, bool silent = false)
     {
-        // If we've gotten this far, fire a cancellable event that indicates someone is about to activate this.
+        // If we've gotten this far, fire a cancellable event that indicates someone is attempting to activate this UI.
         // This is so that stuff can require further conditions (like power).
-        var oae = new ActivatableUIOpenAttemptEvent(user);
-        var uae = new UserOpenActivatableUIAttemptEvent(user, uiEntity);
+        var uae = new UserOpenActivatableUIAttemptEvent(user, uiEntity, silent);
         RaiseLocalEvent(user, uae);
+
+        if (uae.Cancelled)
+            return false;
+
+        var oae = new ActivatableUIOpenAttemptEvent(user, silent);
         RaiseLocalEvent(uiEntity, oae);
-        return oae.Cancelled || uae.Cancelled;
+
+        if (oae.Cancelled)
+            return false;
+
+        return true;
     }
 }