Action stuff (#31305)

* Action stuff

- Cleanup some event stuff
- Avoid dirtying entity unnecessarily
- Add ActionGrant as an easy way to apply / remove actions via compregistry.

* Fix merge
This commit is contained in:
metalgearsloth
2024-08-25 22:43:31 +10:00
committed by GitHub
parent f96dddd9fb
commit 2e029a7d5b
10 changed files with 168 additions and 40 deletions

View File

@@ -11,7 +11,6 @@ using Content.Shared.Mind;
using Content.Shared.Rejuvenate;
using Content.Shared.Whitelist;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Timing;
@@ -45,6 +44,8 @@ public abstract class SharedActionsSystem : EntitySystem
SubscribeLocalEvent<WorldTargetActionComponent, ComponentShutdown>(OnActionShutdown);
SubscribeLocalEvent<EntityWorldTargetActionComponent, ComponentShutdown>(OnActionShutdown);
SubscribeLocalEvent<ActionsComponent, ActionComponentChangeEvent>(OnActionCompChange);
SubscribeLocalEvent<ActionsComponent, RelayedActionComponentChangeEvent>(OnRelayActionCompChange);
SubscribeLocalEvent<ActionsComponent, DidEquipEvent>(OnDidEquip);
SubscribeLocalEvent<ActionsComponent, DidEquipHandEvent>(OnHandEquipped);
SubscribeLocalEvent<ActionsComponent, DidUnequipEvent>(OnDidUnequip);
@@ -490,12 +491,6 @@ public abstract class SharedActionsSystem : EntitySystem
break;
}
if (performEvent != null)
{
performEvent.Performer = user;
performEvent.Action = actionEnt;
}
// All checks passed. Perform the action!
PerformAction(user, component, actionEnt, action, performEvent, curTime);
}
@@ -641,6 +636,8 @@ public abstract class SharedActionsSystem : EntitySystem
// This here is required because of client-side prediction (RaisePredictiveEvent results in event re-use).
actionEvent.Handled = false;
var target = performer;
actionEvent.Performer = performer;
actionEvent.Action = (actionId, action);
if (!action.RaiseOnUser && action.Container != null && !HasComp<MindComponent>(action.Container))
target = action.Container.Value;
@@ -653,10 +650,14 @@ public abstract class SharedActionsSystem : EntitySystem
return; // no interaction occurred.
// play sound, reduce charges, start cooldown, and mark as dirty (if required).
if (actionEvent?.Toggle == true)
{
action.Toggled = !action.Toggled;
}
_audio.PlayPredicted(action.Sound, performer,predicted ? performer : null);
_audio.PlayPredicted(action.Sound, performer, predicted ? performer : null);
var dirty = toggledBefore == action.Toggled;
var dirty = toggledBefore != action.Toggled;
if (action.Charges != null)
{
@@ -673,10 +674,11 @@ public abstract class SharedActionsSystem : EntitySystem
action.Cooldown = (curTime, curTime + action.UseDelay.Value);
}
Dirty(actionId, action);
if (dirty && component != null)
Dirty(performer, component);
if (dirty)
{
Dirty(actionId, action);
UpdateAction(actionId, action);
}
var ev = new ActionPerformedEvent(performer);
RaiseLocalEvent(actionId, ref ev);
@@ -975,6 +977,47 @@ public abstract class SharedActionsSystem : EntitySystem
#endregion
private void OnRelayActionCompChange(Entity<ActionsComponent> ent, ref RelayedActionComponentChangeEvent args)
{
if (args.Handled)
return;
var ev = new AttemptRelayActionComponentChangeEvent();
RaiseLocalEvent(ent.Owner, ref ev);
var target = ev.Target ?? ent.Owner;
args.Handled = true;
args.Toggle = true;
if (!args.Action.Comp.Toggled)
{
EntityManager.AddComponents(target, args.Components);
}
else
{
EntityManager.RemoveComponents(target, args.Components);
}
}
private void OnActionCompChange(Entity<ActionsComponent> ent, ref ActionComponentChangeEvent args)
{
if (args.Handled)
return;
args.Handled = true;
args.Toggle = true;
var target = ent.Owner;
if (!args.Action.Comp.Toggled)
{
EntityManager.AddComponents(target, args.Components);
}
else
{
EntityManager.RemoveComponents(target, args.Components);
}
}
#region EquipHandlers
private void OnDidEquip(EntityUid uid, ActionsComponent component, DidEquipEvent args)
{