]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Add checks for various complex interactions (#37246)
authorKrunklehorn <42424291+Krunklehorn@users.noreply.github.com>
Mon, 2 Jun 2025 17:06:45 +0000 (13:06 -0400)
committerGitHub <noreply@github.com>
Mon, 2 Jun 2025 17:06:45 +0000 (10:06 -0700)
* Prevent toggling radiation collectors

* Prevent resisting locks

* Prevent unbuckling others, early exit before doafter

* Prevent camera and camera router setup

* Prevent rotating and flipping

* Also prevent adding the unbuckle verb.

* Revert ResistLocker changes

* Prevent emitter tampering

* Also prevent lock verb

* Prevent toggling welders

* Prevent gun open/close bolt, rack and switch mode

* Prevent toggling stun batons

13 files changed:
Content.Server/Rotatable/RotatableSystem.cs
Content.Server/Singularity/EntitySystems/EmitterSystem.cs
Content.Server/Singularity/EntitySystems/RadiationCollectorSystem.cs
Content.Server/Stunnable/Systems/StunbatonSystem.cs
Content.Server/SurveillanceCamera/Systems/SurveillanceCameraRouterSystem.cs
Content.Server/SurveillanceCamera/Systems/SurveillanceCameraSystem.cs
Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs
Content.Shared/Buckle/SharedBuckleSystem.Interaction.cs
Content.Shared/Lock/LockSystem.cs
Content.Shared/Stunnable/SharedStunbatonSystem.cs
Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs
Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.ChamberMagazine.cs
Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Interactions.cs

index 85681535ca7a47046da4d12150b601e7503f684c..32f8c91403341379d120c9607c779e3e4f10a02f 100644 (file)
@@ -37,7 +37,9 @@ namespace Content.Server.Rotatable
 
         private void AddFlipVerb(EntityUid uid, FlippableComponent component, GetVerbsEvent<Verb> args)
         {
-            if (!args.CanAccess || !args.CanInteract)
+            if (!args.CanAccess
+                || !args.CanInteract
+                || !args.CanComplexInteract)
                 return;
 
             // Check if the object is anchored.
@@ -60,6 +62,7 @@ namespace Content.Server.Rotatable
         {
             if (!args.CanAccess
                 || !args.CanInteract
+                || !args.CanComplexInteract
                 || Transform(uid).NoLocalRotation) // Good ol prototype inheritance, eh?
                 return;
 
@@ -125,7 +128,9 @@ namespace Content.Server.Rotatable
             if (!TryComp<RotatableComponent>(entity, out var rotatableComp))
                 return false;
 
-            if (!_actionBlocker.CanInteract(player, entity) || !_interaction.InRangeAndAccessible(player, entity))
+            if (!_actionBlocker.CanInteract(player, entity)
+                || !_actionBlocker.CanComplexInteract(player)
+                || !_interaction.InRangeAndAccessible(player, entity))
                 return false;
 
             // Check if the object is anchored, and whether we are still allowed to rotate it.
@@ -148,7 +153,9 @@ namespace Content.Server.Rotatable
             if (!TryComp<RotatableComponent>(entity, out var rotatableComp))
                 return false;
 
-            if (!_actionBlocker.CanInteract(player, entity) || !_interaction.InRangeAndAccessible(player, entity))
+            if (!_actionBlocker.CanInteract(player, entity)
+                || !_actionBlocker.CanComplexInteract(player)
+                || !_interaction.InRangeAndAccessible(player, entity))
                 return false;
 
             // Check if the object is anchored, and whether we are still allowed to rotate it.
@@ -171,7 +178,9 @@ namespace Content.Server.Rotatable
             if (!TryComp<FlippableComponent>(entity, out var flippableComp))
                 return false;
 
-            if (!_actionBlocker.CanInteract(player, entity) || !_interaction.InRangeAndAccessible(player, entity))
+            if (!_actionBlocker.CanInteract(player, entity)
+                || !_actionBlocker.CanComplexInteract(player)
+                || !_interaction.InRangeAndAccessible(player, entity))
                 return false;
 
             // Check if the object is anchored.
index b1efd8624cb22e5f0e9c5945ed54e24e5afc7538..662df43e1229eface8ecc3ce521ce81f4ffa2930 100644 (file)
@@ -62,7 +62,7 @@ namespace Content.Server.Singularity.EntitySystems
 
         private void OnActivate(EntityUid uid, EmitterComponent component, ActivateInWorldEvent args)
         {
-            if (args.Handled)
+            if (args.Handled || !args.Complex)
                 return;
 
             if (TryComp(uid, out LockComponent? lockComp) && lockComp.Locked)
@@ -101,7 +101,7 @@ namespace Content.Server.Singularity.EntitySystems
 
         private void OnGetVerb(EntityUid uid, EmitterComponent component, GetVerbsEvent<Verb> args)
         {
-            if (!args.CanAccess || !args.CanInteract || args.Hands == null)
+            if (!args.CanAccess || !args.CanInteract || !args.CanComplexInteract || args.Hands == null)
                 return;
 
             if (TryComp<LockComponent>(uid, out var lockComp) && lockComp.Locked)
index f8027b2f14155c51622b767734711237113ff0f1..63ff5f83007b8a78bac7d670c93fc6d0c1a2fa3c 100644 (file)
@@ -68,6 +68,9 @@ public sealed class RadiationCollectorSystem : EntitySystem
 
     private void OnActivate(EntityUid uid, RadiationCollectorComponent component, ActivateInWorldEvent args)
     {
+        if (!args.Complex)
+            return;
+
         if (TryComp(uid, out UseDelayComponent? useDelay) && !_useDelay.TryResetDelay((uid, useDelay), true))
             return;
 
index efe8cc442eb9eb1eac90446676bdcaabf5399891..f043c452ca4417bc9f1d27981a8f4e13f8b3fbae 100644 (file)
@@ -25,7 +25,6 @@ namespace Content.Server.Stunnable.Systems
             SubscribeLocalEvent<StunbatonComponent, ExaminedEvent>(OnExamined);
             SubscribeLocalEvent<StunbatonComponent, SolutionContainerChangedEvent>(OnSolutionChange);
             SubscribeLocalEvent<StunbatonComponent, StaminaDamageOnHitAttemptEvent>(OnStaminaHitAttempt);
-            SubscribeLocalEvent<StunbatonComponent, ItemToggleActivateAttemptEvent>(TryTurnOn);
             SubscribeLocalEvent<StunbatonComponent, ChargeChangedEvent>(OnChargeChanged);
         }
 
@@ -52,8 +51,10 @@ namespace Content.Server.Stunnable.Systems
             }
         }
 
-        private void TryTurnOn(Entity<StunbatonComponent> entity, ref ItemToggleActivateAttemptEvent args)
+        protected override void TryTurnOn(Entity<StunbatonComponent> entity, ref ItemToggleActivateAttemptEvent args)
         {
+            base.TryTurnOn(entity, ref args);
+
             if (!TryComp<BatteryComponent>(entity, out var battery) || battery.CurrentCharge < entity.Comp.EnergyPerUse)
             {
                 args.Cancelled = true;
index c6886dee338d7231be26930d1f7f120a3dc3a352..32e42a52dd44af21f2e0da8c03a21fb12ce7198b 100644 (file)
@@ -92,7 +92,7 @@ public sealed class SurveillanceCameraRouterSystem : EntitySystem
 
     private void AddVerbs(EntityUid uid, SurveillanceCameraRouterComponent component, GetVerbsEvent<AlternativeVerb> verbs)
     {
-        if (!_actionBlocker.CanInteract(verbs.User, uid))
+        if (!_actionBlocker.CanInteract(verbs.User, uid) || !_actionBlocker.CanComplexInteract(verbs.User))
         {
             return;
         }
index 709e383c06c1eaff42bd8f84e386f0801bccf0a4..624f414d78267b96fe84fda09da331ae832acc10 100644 (file)
@@ -129,7 +129,7 @@ public sealed class SurveillanceCameraSystem : EntitySystem
 
     private void AddVerbs(EntityUid uid, SurveillanceCameraComponent component, GetVerbsEvent<AlternativeVerb> verbs)
     {
-        if (!_actionBlocker.CanInteract(verbs.User, uid))
+        if (!_actionBlocker.CanInteract(verbs.User, uid) || !_actionBlocker.CanComplexInteract(verbs.User))
         {
             return;
         }
index 85d7698ff0c12cf139c46b701ce73704590b4de8..fa515f48bb5c4b5d5b32d345b8d83bee9f59fc81 100644 (file)
@@ -1,6 +1,7 @@
 using System.Diagnostics.CodeAnalysis;
 using System.Numerics;
 using Content.Shared.Alert;
+using Content.Shared.ActionBlocker;
 using Content.Shared.Buckle.Components;
 using Content.Shared.Cuffs.Components;
 using Content.Shared.Database;
@@ -32,6 +33,7 @@ public abstract partial class SharedBuckleSystem
     public static ProtoId<AlertCategoryPrototype> BuckledAlertCategory = "Buckled";
 
     [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
+    [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
 
     private void InitializeBuckle()
     {
@@ -516,8 +518,14 @@ public abstract partial class SharedBuckleSystem
         if (_gameTiming.CurTime < buckle.Comp.BuckleTime + buckle.Comp.Delay)
             return false;
 
-        if (user != null && !_interaction.InRangeUnobstructed(user.Value, strap.Owner, buckle.Comp.Range, popup: popup))
-            return false;
+        if (user != null)
+        {
+            if (!_interaction.InRangeUnobstructed(user.Value, strap.Owner, buckle.Comp.Range, popup: popup))
+                return false;
+
+            if (user.Value != buckle.Owner && !_actionBlocker.CanComplexInteract(user.Value))
+                return false;
+        }
 
         var unbuckleAttempt = new UnbuckleAttemptEvent(strap, buckle!, user, popup);
         RaiseLocalEvent(buckle, ref unbuckleAttempt);
index 2dba18c96e5a7aa0b423aa9c48d1afbaa954fcc1..73a78f101f4810774759b42d008e0d5030f630f9 100644 (file)
@@ -43,6 +43,10 @@ public abstract partial class SharedBuckleSystem
         }
         else
         {
+            if (!TryComp(args.Dragged, out BuckleComponent? buckle) ||
+                !CanBuckle(args.Dragged, args.User, uid, true, out var _, buckle))
+                return;
+
             var doAfterArgs = new DoAfterArgs(EntityManager, args.User, component.BuckleDoafterTime, new BuckleDoAfterEvent(), args.Dragged, args.Dragged, uid)
             {
                 BreakOnMove = true,
@@ -200,6 +204,9 @@ public abstract partial class SharedBuckleSystem
         if (!args.CanAccess || !args.CanInteract || !component.Buckled)
             return;
 
+        if (!CanUnbuckle((uid, component), args.User, false))
+            return;
+
         InteractionVerb verb = new()
         {
             Act = () => TryUnbuckle(uid, args.User, buckleComp: component),
index 444b3e28e615865bf23902e60f646bb333728034..16d676954ef3468b3a6e86238a1a2c4681fd3edc 100644 (file)
@@ -282,7 +282,7 @@ public sealed class LockSystem : EntitySystem
 
     private void AddToggleLockVerb(EntityUid uid, LockComponent component, GetVerbsEvent<AlternativeVerb> args)
     {
-        if (!args.CanAccess || !args.CanInteract)
+        if (!args.CanAccess || !args.CanInteract || !args.CanComplexInteract)
             return;
 
         AlternativeVerb verb = new()
index 28b68553b313c72a2643589b7e1c30cb90ae6a1a..aaee093a0ac0a23eb9fd17a848feb597eddef993 100644 (file)
@@ -1,9 +1,33 @@
+using Content.Shared.ActionBlocker;
+using Content.Shared.Item.ItemToggle.Components;
+
 namespace Content.Shared.Stunnable;
 
 public abstract class SharedStunbatonSystem : EntitySystem
 {
+    [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
+
     public override void Initialize()
     {
         base.Initialize();
+
+        SubscribeLocalEvent<StunbatonComponent, ItemToggleActivateAttemptEvent>(TryTurnOn);
+        SubscribeLocalEvent<StunbatonComponent, ItemToggleDeactivateAttemptEvent>(TryTurnOff);
+    }
+
+    protected virtual void TryTurnOn(Entity<StunbatonComponent> entity, ref ItemToggleActivateAttemptEvent args)
+    {
+        if (args.User != null && !_actionBlocker.CanComplexInteract(args.User.Value)) {
+            args.Cancelled = true;
+            return;
+        }
+    }
+
+    protected virtual void TryTurnOff(Entity<StunbatonComponent> entity, ref ItemToggleDeactivateAttemptEvent args)
+    {
+        if (args.User != null && !_actionBlocker.CanComplexInteract(args.User.Value)) {
+            args.Cancelled = true;
+            return;
+        }
     }
 }
index f8f0ae5d925f7843a3f0fba2b71a5e5283778d6e..af1dc85137edb165fdccf849323a7fe95170ab71 100644 (file)
@@ -1,3 +1,4 @@
+using Content.Shared.ActionBlocker;
 using Content.Shared.Chemistry.Components;
 using Content.Shared.Chemistry.Components.SolutionManager;
 using Content.Shared.Database;
@@ -12,6 +13,8 @@ namespace Content.Shared.Tools.Systems;
 
 public abstract partial class SharedToolSystem
 {
+    [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
+
     public void InitializeWelder()
     {
         SubscribeLocalEvent<WelderComponent, ExaminedEvent>(OnWelderExamine);
@@ -27,6 +30,7 @@ public abstract partial class SharedToolSystem
 
         SubscribeLocalEvent<WelderComponent, ItemToggledEvent>(OnToggle);
         SubscribeLocalEvent<WelderComponent, ItemToggleActivateAttemptEvent>(OnActivateAttempt);
+        SubscribeLocalEvent<WelderComponent, ItemToggleDeactivateAttemptEvent>(OnDeactivateAttempt);
     }
 
     public void TurnOn(Entity<WelderComponent> entity, EntityUid? user)
@@ -165,6 +169,11 @@ public abstract partial class SharedToolSystem
 
     private void OnActivateAttempt(Entity<WelderComponent> entity, ref ItemToggleActivateAttemptEvent args)
     {
+        if (args.User != null && !_actionBlocker.CanComplexInteract(args.User.Value)) {
+            args.Cancelled = true;
+            return;
+        }
+
         if (!SolutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.FuelSolutionName, out _, out var solution))
         {
             args.Cancelled = true;
@@ -179,4 +188,12 @@ public abstract partial class SharedToolSystem
             args.Cancelled = true;
         }
     }
+
+    private void OnDeactivateAttempt(Entity<WelderComponent> entity, ref ItemToggleDeactivateAttemptEvent args)
+    {
+        if (args.User != null && !_actionBlocker.CanComplexInteract(args.User.Value)) {
+            args.Cancelled = true;
+            return;
+        }
+    }
 }
index 39014d8248fe52ea2bdcd8c50024afc7e560eb5b..4de9196761e131083df4907277586774796b9d2b 100644 (file)
@@ -78,7 +78,7 @@ public abstract partial class SharedGunSystem
     /// </summary>
     private void OnChamberActivationVerb(EntityUid uid, ChamberMagazineAmmoProviderComponent component, GetVerbsEvent<ActivationVerb> args)
     {
-        if (!args.CanAccess || !args.CanInteract || component.BoltClosed == null || !component.CanRack)
+        if (!args.CanAccess || !args.CanInteract || !args.CanComplexInteract || args.Hands == null || component.BoltClosed == null || !component.CanRack)
             return;
 
         args.Verbs.Add(new ActivationVerb()
@@ -131,7 +131,7 @@ public abstract partial class SharedGunSystem
     /// </summary>
     private void OnChamberInteractionVerb(EntityUid uid, ChamberMagazineAmmoProviderComponent component, GetVerbsEvent<InteractionVerb> args)
     {
-        if (!args.CanAccess || !args.CanInteract || component.BoltClosed == null)
+        if (!args.CanAccess || !args.CanInteract || !args.CanComplexInteract || args.Hands == null || component.BoltClosed == null)
             return;
 
         args.Verbs.Add(new InteractionVerb()
index f3ff89a660e585081c0afc92a8d6c4ae101b18fc..2fece720f9c54bf02220bcff19ef1097246be4ec 100644 (file)
@@ -30,7 +30,7 @@ public abstract partial class SharedGunSystem
 
     private void OnAltVerb(EntityUid uid, GunComponent component, GetVerbsEvent<AlternativeVerb> args)
     {
-        if (!args.CanAccess || !args.CanInteract || component.SelectedMode == component.AvailableModes)
+        if (!args.CanAccess || !args.CanInteract || !args.CanComplexInteract || args.Hands == null || component.SelectedMode == component.AvailableModes)
             return;
 
         var nextMode = GetNextMode(component);