diff --git a/Content.Server/Rotatable/RotatableSystem.cs b/Content.Server/Rotatable/RotatableSystem.cs index 85681535ca..32f8c91403 100644 --- a/Content.Server/Rotatable/RotatableSystem.cs +++ b/Content.Server/Rotatable/RotatableSystem.cs @@ -37,7 +37,9 @@ namespace Content.Server.Rotatable private void AddFlipVerb(EntityUid uid, FlippableComponent component, GetVerbsEvent 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(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(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(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. diff --git a/Content.Server/Singularity/EntitySystems/EmitterSystem.cs b/Content.Server/Singularity/EntitySystems/EmitterSystem.cs index b1efd8624c..662df43e12 100644 --- a/Content.Server/Singularity/EntitySystems/EmitterSystem.cs +++ b/Content.Server/Singularity/EntitySystems/EmitterSystem.cs @@ -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 args) { - if (!args.CanAccess || !args.CanInteract || args.Hands == null) + if (!args.CanAccess || !args.CanInteract || !args.CanComplexInteract || args.Hands == null) return; if (TryComp(uid, out var lockComp) && lockComp.Locked) diff --git a/Content.Server/Singularity/EntitySystems/RadiationCollectorSystem.cs b/Content.Server/Singularity/EntitySystems/RadiationCollectorSystem.cs index f8027b2f14..63ff5f8300 100644 --- a/Content.Server/Singularity/EntitySystems/RadiationCollectorSystem.cs +++ b/Content.Server/Singularity/EntitySystems/RadiationCollectorSystem.cs @@ -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; diff --git a/Content.Server/Stunnable/Systems/StunbatonSystem.cs b/Content.Server/Stunnable/Systems/StunbatonSystem.cs index efe8cc442e..f043c452ca 100644 --- a/Content.Server/Stunnable/Systems/StunbatonSystem.cs +++ b/Content.Server/Stunnable/Systems/StunbatonSystem.cs @@ -25,7 +25,6 @@ namespace Content.Server.Stunnable.Systems SubscribeLocalEvent(OnExamined); SubscribeLocalEvent(OnSolutionChange); SubscribeLocalEvent(OnStaminaHitAttempt); - SubscribeLocalEvent(TryTurnOn); SubscribeLocalEvent(OnChargeChanged); } @@ -52,8 +51,10 @@ namespace Content.Server.Stunnable.Systems } } - private void TryTurnOn(Entity entity, ref ItemToggleActivateAttemptEvent args) + protected override void TryTurnOn(Entity entity, ref ItemToggleActivateAttemptEvent args) { + base.TryTurnOn(entity, ref args); + if (!TryComp(entity, out var battery) || battery.CurrentCharge < entity.Comp.EnergyPerUse) { args.Cancelled = true; diff --git a/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraRouterSystem.cs b/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraRouterSystem.cs index c6886dee33..32e42a52dd 100644 --- a/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraRouterSystem.cs +++ b/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraRouterSystem.cs @@ -92,7 +92,7 @@ public sealed class SurveillanceCameraRouterSystem : EntitySystem private void AddVerbs(EntityUid uid, SurveillanceCameraRouterComponent component, GetVerbsEvent verbs) { - if (!_actionBlocker.CanInteract(verbs.User, uid)) + if (!_actionBlocker.CanInteract(verbs.User, uid) || !_actionBlocker.CanComplexInteract(verbs.User)) { return; } diff --git a/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraSystem.cs b/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraSystem.cs index 709e383c06..624f414d78 100644 --- a/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraSystem.cs +++ b/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraSystem.cs @@ -129,7 +129,7 @@ public sealed class SurveillanceCameraSystem : EntitySystem private void AddVerbs(EntityUid uid, SurveillanceCameraComponent component, GetVerbsEvent verbs) { - if (!_actionBlocker.CanInteract(verbs.User, uid)) + if (!_actionBlocker.CanInteract(verbs.User, uid) || !_actionBlocker.CanComplexInteract(verbs.User)) { return; } diff --git a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs index 85d7698ff0..fa515f48bb 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs @@ -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 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); diff --git a/Content.Shared/Buckle/SharedBuckleSystem.Interaction.cs b/Content.Shared/Buckle/SharedBuckleSystem.Interaction.cs index 2dba18c96e..73a78f101f 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.Interaction.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.Interaction.cs @@ -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), diff --git a/Content.Shared/Lock/LockSystem.cs b/Content.Shared/Lock/LockSystem.cs index 444b3e28e6..16d676954e 100644 --- a/Content.Shared/Lock/LockSystem.cs +++ b/Content.Shared/Lock/LockSystem.cs @@ -282,7 +282,7 @@ public sealed class LockSystem : EntitySystem private void AddToggleLockVerb(EntityUid uid, LockComponent component, GetVerbsEvent args) { - if (!args.CanAccess || !args.CanInteract) + if (!args.CanAccess || !args.CanInteract || !args.CanComplexInteract) return; AlternativeVerb verb = new() diff --git a/Content.Shared/Stunnable/SharedStunbatonSystem.cs b/Content.Shared/Stunnable/SharedStunbatonSystem.cs index 28b68553b3..aaee093a0a 100644 --- a/Content.Shared/Stunnable/SharedStunbatonSystem.cs +++ b/Content.Shared/Stunnable/SharedStunbatonSystem.cs @@ -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(TryTurnOn); + SubscribeLocalEvent(TryTurnOff); + } + + protected virtual void TryTurnOn(Entity entity, ref ItemToggleActivateAttemptEvent args) + { + if (args.User != null && !_actionBlocker.CanComplexInteract(args.User.Value)) { + args.Cancelled = true; + return; + } + } + + protected virtual void TryTurnOff(Entity entity, ref ItemToggleDeactivateAttemptEvent args) + { + if (args.User != null && !_actionBlocker.CanComplexInteract(args.User.Value)) { + args.Cancelled = true; + return; + } } } diff --git a/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs b/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs index f8f0ae5d92..af1dc85137 100644 --- a/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs +++ b/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs @@ -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(OnWelderExamine); @@ -27,6 +30,7 @@ public abstract partial class SharedToolSystem SubscribeLocalEvent(OnToggle); SubscribeLocalEvent(OnActivateAttempt); + SubscribeLocalEvent(OnDeactivateAttempt); } public void TurnOn(Entity entity, EntityUid? user) @@ -165,6 +169,11 @@ public abstract partial class SharedToolSystem private void OnActivateAttempt(Entity 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 entity, ref ItemToggleDeactivateAttemptEvent args) + { + if (args.User != null && !_actionBlocker.CanComplexInteract(args.User.Value)) { + args.Cancelled = true; + return; + } + } } diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.ChamberMagazine.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.ChamberMagazine.cs index 39014d8248..4de9196761 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.ChamberMagazine.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.ChamberMagazine.cs @@ -78,7 +78,7 @@ public abstract partial class SharedGunSystem /// private void OnChamberActivationVerb(EntityUid uid, ChamberMagazineAmmoProviderComponent component, GetVerbsEvent 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 /// private void OnChamberInteractionVerb(EntityUid uid, ChamberMagazineAmmoProviderComponent component, GetVerbsEvent 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() diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Interactions.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Interactions.cs index f3ff89a660..2fece720f9 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Interactions.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Interactions.cs @@ -30,7 +30,7 @@ public abstract partial class SharedGunSystem private void OnAltVerb(EntityUid uid, GunComponent component, GetVerbsEvent 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);