Refactor actions to be entities with components (#19900)
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.ActionTypes;
|
||||
using Content.Shared.Interaction;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
@@ -25,51 +24,41 @@ public sealed class ActionOnInteractSystem : EntitySystem
|
||||
|
||||
private void OnActivate(EntityUid uid, ActionOnInteractComponent component, ActivateInWorldEvent args)
|
||||
{
|
||||
if (args.Handled || component.ActivateActions == null)
|
||||
if (args.Handled || component.ActionEntities == null)
|
||||
return;
|
||||
|
||||
var options = new List<InstantAction>();
|
||||
foreach (var action in component.ActivateActions)
|
||||
{
|
||||
if (ValidAction(action))
|
||||
options.Add(action);
|
||||
}
|
||||
|
||||
var options = GetValidActions<InstantActionComponent>(component.ActionEntities);
|
||||
if (options.Count == 0)
|
||||
return;
|
||||
|
||||
var act = _random.Pick(options);
|
||||
var (actId, act) = _random.Pick(options);
|
||||
if (act.Event != null)
|
||||
act.Event.Performer = args.User;
|
||||
|
||||
act.Provider = uid;
|
||||
_actions.PerformAction(args.User, null, act, act.Event, _timing.CurTime, false);
|
||||
_actions.PerformAction(args.User, null, actId, act, act.Event, _timing.CurTime, false);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnAfterInteract(EntityUid uid, ActionOnInteractComponent component, AfterInteractEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
if (args.Handled || component.ActionEntities == null)
|
||||
return;
|
||||
|
||||
// First, try entity target actions
|
||||
if (args.Target != null && component.EntityActions != null)
|
||||
if (args.Target != null)
|
||||
{
|
||||
var entOptions = new List<EntityTargetAction>();
|
||||
foreach (var action in component.EntityActions)
|
||||
var entOptions = GetValidActions<EntityTargetActionComponent>(component.ActionEntities, args.CanReach);
|
||||
for (var i = entOptions.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (!ValidAction(action, args.CanReach))
|
||||
continue;
|
||||
|
||||
var action = entOptions[i].Comp;
|
||||
if (!_actions.ValidateEntityTarget(args.User, args.Target.Value, action))
|
||||
continue;
|
||||
|
||||
entOptions.Add(action);
|
||||
entOptions.RemoveAt(i);
|
||||
}
|
||||
|
||||
if (entOptions.Count > 0)
|
||||
{
|
||||
var entAct = _random.Pick(entOptions);
|
||||
var (entActId, entAct) = _random.Pick(entOptions);
|
||||
if (entAct.Event != null)
|
||||
{
|
||||
entAct.Event.Performer = args.User;
|
||||
@@ -77,32 +66,25 @@ public sealed class ActionOnInteractSystem : EntitySystem
|
||||
}
|
||||
|
||||
entAct.Provider = uid;
|
||||
_actions.PerformAction(args.User, null, entAct, entAct.Event, _timing.CurTime, false);
|
||||
_actions.PerformAction(args.User, null, entActId, entAct, entAct.Event, _timing.CurTime, false);
|
||||
args.Handled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// else: try world target actions
|
||||
if (component.WorldActions == null)
|
||||
return;
|
||||
|
||||
var options = new List<WorldTargetAction>();
|
||||
foreach (var action in component.WorldActions)
|
||||
var options = GetValidActions<WorldTargetActionComponent>(component.ActionEntities, args.CanReach);
|
||||
for (var i = options.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (!ValidAction(action, args.CanReach))
|
||||
continue;
|
||||
|
||||
var action = options[i].Comp;
|
||||
if (!_actions.ValidateWorldTarget(args.User, args.ClickLocation, action))
|
||||
continue;
|
||||
|
||||
options.Add(action);
|
||||
options.RemoveAt(i);
|
||||
}
|
||||
|
||||
if (options.Count == 0)
|
||||
return;
|
||||
|
||||
var act = _random.Pick(options);
|
||||
var (actId, act) = _random.Pick(options);
|
||||
if (act.Event != null)
|
||||
{
|
||||
act.Event.Performer = args.User;
|
||||
@@ -110,22 +92,44 @@ public sealed class ActionOnInteractSystem : EntitySystem
|
||||
}
|
||||
|
||||
act.Provider = uid;
|
||||
_actions.PerformAction(args.User, null, act, act.Event, _timing.CurTime, false);
|
||||
_actions.PerformAction(args.User, null, actId, act, act.Event, _timing.CurTime, false);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private bool ValidAction(ActionType act, bool canReach = true)
|
||||
private bool ValidAction(BaseActionComponent action, bool canReach = true)
|
||||
{
|
||||
if (!act.Enabled)
|
||||
if (!action.Enabled)
|
||||
return false;
|
||||
|
||||
if (act.Charges.HasValue && act.Charges <= 0)
|
||||
if (action.Charges.HasValue && action.Charges <= 0)
|
||||
return false;
|
||||
|
||||
var curTime = _timing.CurTime;
|
||||
if (act.Cooldown.HasValue && act.Cooldown.Value.End > curTime)
|
||||
if (action.Cooldown.HasValue && action.Cooldown.Value.End > curTime)
|
||||
return false;
|
||||
|
||||
return canReach || act is TargetedAction { CheckCanAccess: false };
|
||||
return canReach || action is BaseTargetActionComponent { CheckCanAccess: false };
|
||||
}
|
||||
|
||||
private List<(EntityUid Id, T Comp)> GetValidActions<T>(List<EntityUid>? actions, bool canReach = true) where T : BaseActionComponent
|
||||
{
|
||||
var valid = new List<(EntityUid Id, T Comp)>();
|
||||
|
||||
if (actions == null)
|
||||
return valid;
|
||||
|
||||
foreach (var id in actions)
|
||||
{
|
||||
if (!_actions.TryGetActionData(id, out var baseAction) ||
|
||||
baseAction as T is not { } action ||
|
||||
!ValidAction(action, canReach))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
valid.Add((id, action));
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user