diff --git a/Content.Client/Actions/ActionsSystem.cs b/Content.Client/Actions/ActionsSystem.cs index 5ff003452a..aff6c1ff7b 100644 --- a/Content.Client/Actions/ActionsSystem.cs +++ b/Content.Client/Actions/ActionsSystem.cs @@ -247,7 +247,10 @@ namespace Content.Client.Actions if (action.ClientExclusive) { if (instantAction.Event != null) + { instantAction.Event.Performer = user; + instantAction.Event.Action = actionId; + } PerformAction(user, actions, actionId, instantAction, instantAction.Event, GameTiming.CurTime); } diff --git a/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs b/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs index 5d9706452c..69ac3ab023 100644 --- a/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs +++ b/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs @@ -217,6 +217,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged(); _spriteSys ??= _entities.System(); - if ((_controller.SelectingTargetFor == ActionId || _action.Toggled) && _action.IconOn != null) - SetActionIcon(_spriteSys.Frame0(_action.IconOn)); + if ((_controller.SelectingTargetFor == ActionId || _action.Toggled)) + { + if (_action.IconOn != null) + SetActionIcon(_spriteSys.Frame0(_action.IconOn)); + + if (_action.BackgroundOn != null) + _buttonBackgroundTexture = _spriteSys.Frame0(_action.BackgroundOn); + } else + { SetActionIcon(_action.Icon != null ? _spriteSys.Frame0(_action.Icon) : null); + _buttonBackgroundTexture = Theme.ResolveTexture("SlotBackground"); + } } public void UpdateBackground() diff --git a/Content.Server/Actions/ActionOnInteractSystem.cs b/Content.Server/Actions/ActionOnInteractSystem.cs index eb35d41196..657ab46d60 100644 --- a/Content.Server/Actions/ActionOnInteractSystem.cs +++ b/Content.Server/Actions/ActionOnInteractSystem.cs @@ -47,7 +47,10 @@ public sealed class ActionOnInteractSystem : EntitySystem var (actId, act) = _random.Pick(options); if (act.Event != null) + { act.Event.Performer = args.User; + act.Event.Action = actId; + } _actions.PerformAction(args.User, null, actId, act, act.Event, _timing.CurTime, false); args.Handled = true; @@ -75,6 +78,7 @@ public sealed class ActionOnInteractSystem : EntitySystem if (entAct.Event != null) { entAct.Event.Performer = args.User; + entAct.Event.Action = entActId; entAct.Event.Target = args.Target.Value; } @@ -100,6 +104,7 @@ public sealed class ActionOnInteractSystem : EntitySystem if (act.Event != null) { act.Event.Performer = args.User; + act.Event.Action = actId; act.Event.Target = args.ClickLocation; } diff --git a/Content.Shared/Actions/ActionEvents.cs b/Content.Shared/Actions/ActionEvents.cs index cddb70f74d..c6002d0d4a 100644 --- a/Content.Shared/Actions/ActionEvents.cs +++ b/Content.Shared/Actions/ActionEvents.cs @@ -155,4 +155,9 @@ public abstract partial class BaseActionEvent : HandledEntityEventArgs /// The user performing the action. /// public EntityUid Performer; + + /// + /// The action that was performed. + /// + public EntityUid Action; } diff --git a/Content.Shared/Actions/BaseActionComponent.cs b/Content.Shared/Actions/BaseActionComponent.cs index 6d9242acc1..57c145a0ec 100644 --- a/Content.Shared/Actions/BaseActionComponent.cs +++ b/Content.Shared/Actions/BaseActionComponent.cs @@ -1,5 +1,4 @@ -using Content.Shared.Mobs; -using Robust.Shared.Audio; +using Robust.Shared.Audio; using Robust.Shared.Serialization; using Robust.Shared.Utility; @@ -25,6 +24,11 @@ public abstract partial class BaseActionComponent : Component /// [DataField("iconOn")] public SpriteSpecifier? IconOn; + /// + /// For toggle actions only, background to show when toggled on. + /// + [DataField] public SpriteSpecifier? BackgroundOn; + /// /// If not null, this color will modulate the action icon color. /// diff --git a/Content.Shared/Actions/Events/ActionPerformedEvent.cs b/Content.Shared/Actions/Events/ActionPerformedEvent.cs new file mode 100644 index 0000000000..530d7c9335 --- /dev/null +++ b/Content.Shared/Actions/Events/ActionPerformedEvent.cs @@ -0,0 +1,8 @@ +namespace Content.Shared.Actions.Events; + +/// +/// Raised on the action entity when it is used and . +/// +/// The entity that performed this action. +[ByRefEvent] +public readonly record struct ActionPerformedEvent(EntityUid Performer); diff --git a/Content.Shared/Actions/SharedActionsSystem.cs b/Content.Shared/Actions/SharedActionsSystem.cs index e1b76f517e..315d2725b2 100644 --- a/Content.Shared/Actions/SharedActionsSystem.cs +++ b/Content.Shared/Actions/SharedActionsSystem.cs @@ -144,9 +144,6 @@ public abstract class SharedActionsSystem : EntitySystem public void SetCooldown(EntityUid? actionId, TimeSpan start, TimeSpan end) { - if (actionId == null) - return; - if (!TryGetActionData(actionId, out var action)) return; @@ -162,9 +159,6 @@ public abstract class SharedActionsSystem : EntitySystem public void ClearCooldown(EntityUid? actionId) { - if (actionId == null) - return; - if (!TryGetActionData(actionId, out var action)) return; @@ -175,6 +169,27 @@ public abstract class SharedActionsSystem : EntitySystem Dirty(actionId.Value, action); } + /// + /// Sets the cooldown for this action only if it is bigger than the one it already has. + /// + public void SetIfBiggerCooldown(EntityUid? actionId, TimeSpan? cooldown) + { + if (cooldown == null || + cooldown.Value <= TimeSpan.Zero || + !TryGetActionData(actionId, out var action)) + { + return; + } + + var start = GameTiming.CurTime; + var end = start + cooldown; + if (action.Cooldown?.End > end) + return; + + action.Cooldown = (start, end.Value); + Dirty(actionId.Value, action); + } + public void StartUseDelay(EntityUid? actionId) { if (actionId == null) @@ -438,7 +453,10 @@ public abstract class SharedActionsSystem : EntitySystem } if (performEvent != null) + { performEvent.Performer = user; + performEvent.Action = actionEnt; + } // All checks passed. Perform the action! PerformAction(user, component, actionEnt, action, performEvent, curTime); @@ -580,6 +598,9 @@ public abstract class SharedActionsSystem : EntitySystem if (dirty && component != null) Dirty(performer, component); + + var ev = new ActionPerformedEvent(performer); + RaiseLocalEvent(actionId, ref ev); } #endregion