action refactor proper ecs edition (#27422)

This commit is contained in:
deltanedas
2025-05-28 19:52:11 +00:00
committed by GitHub
parent a9f7cfbcb6
commit b3825dce97
111 changed files with 1995 additions and 2901 deletions

View File

@@ -1,5 +1,6 @@
using System.Linq;
using Content.Shared.Actions;
using Content.Shared.Actions.Components;
using Content.Shared.Charges.Components;
using Content.Shared.Charges.Systems;
using Content.Shared.Interaction;
@@ -60,8 +61,10 @@ public sealed class ActionOnInteractSystem : EntitySystem
if (!TryUseCharge((uid, component)))
return;
var (actId, act) = _random.Pick(options);
_actions.PerformAction(args.User, null, actId, act, act.Event, _timing.CurTime, false);
// not predicted as this is in server due to random
// TODO: use predicted random and move to shared?
var (actId, action, comp) = _random.Pick(options);
_actions.PerformAction(args.User, (actId, action), predicted: false);
args.Handled = true;
}
@@ -79,13 +82,13 @@ public sealed class ActionOnInteractSystem : EntitySystem
}
// First, try entity target actions
if (args.Target != null)
if (args.Target is {} target)
{
var entOptions = GetValidActions<EntityTargetActionComponent>(actionEnts, args.CanReach);
for (var i = entOptions.Count - 1; i >= 0; i--)
{
var action = entOptions[i];
if (!_actions.ValidateEntityTarget(args.User, args.Target.Value, action))
if (!_actions.ValidateEntityTarget(args.User, target, (action, action.Comp2)))
entOptions.RemoveAt(i);
}
@@ -94,50 +97,19 @@ public sealed class ActionOnInteractSystem : EntitySystem
if (!TryUseCharge((uid, component)))
return;
var (entActId, entAct) = _random.Pick(entOptions);
if (entAct.Event != null)
{
entAct.Event.Target = args.Target.Value;
}
_actions.PerformAction(args.User, null, entActId, entAct, entAct.Event, _timing.CurTime, false);
var (actionId, action, _) = _random.Pick(entOptions);
_actions.SetEventTarget(actionId, target);
_actions.PerformAction(args.User, (actionId, action), predicted: false);
args.Handled = true;
return;
}
}
// Then EntityWorld target actions
var entWorldOptions = GetValidActions<EntityWorldTargetActionComponent>(actionEnts, args.CanReach);
for (var i = entWorldOptions.Count - 1; i >= 0; i--)
{
var action = entWorldOptions[i];
if (!_actions.ValidateEntityWorldTarget(args.User, args.Target, args.ClickLocation, action))
entWorldOptions.RemoveAt(i);
}
if (entWorldOptions.Count > 0)
{
if (!TryUseCharge((uid, component)))
return;
var (entActId, entAct) = _random.Pick(entWorldOptions);
if (entAct.Event != null)
{
entAct.Event.Entity = args.Target;
entAct.Event.Coords = args.ClickLocation;
}
_actions.PerformAction(args.User, null, entActId, entAct, entAct.Event, _timing.CurTime, false);
args.Handled = true;
return;
}
// else: try world target actions
var options = GetValidActions<WorldTargetActionComponent>(component.ActionEntities, args.CanReach);
for (var i = options.Count - 1; i >= 0; i--)
{
var action = options[i];
if (!_actions.ValidateWorldTarget(args.User, args.ClickLocation, action))
if (!_actions.ValidateWorldTarget(args.User, args.ClickLocation, (action, action.Comp2)))
options.RemoveAt(i);
}
@@ -147,33 +119,34 @@ public sealed class ActionOnInteractSystem : EntitySystem
if (!TryUseCharge((uid, component)))
return;
var (actId, act) = _random.Pick(options);
if (act.Event != null)
var (actId, comp, world) = _random.Pick(options);
if (world.Event is {} worldEv)
{
act.Event.Target = args.ClickLocation;
worldEv.Target = args.ClickLocation;
worldEv.Entity = HasComp<EntityTargetActionComponent>(actId) ? args.Target : null;
}
_actions.PerformAction(args.User, null, actId, act, act.Event, _timing.CurTime, false);
_actions.PerformAction(args.User, (actId, comp), world.Event, predicted: false);
args.Handled = true;
}
private List<(EntityUid Id, T Comp)> GetValidActions<T>(List<EntityUid>? actions, bool canReach = true) where T : BaseActionComponent
private List<Entity<ActionComponent, T>> GetValidActions<T>(List<EntityUid>? actions, bool canReach = true) where T: Component
{
var valid = new List<(EntityUid Id, T Comp)>();
var valid = new List<Entity<ActionComponent, T>>();
if (actions == null)
return valid;
foreach (var id in actions)
{
if (!_actions.TryGetActionData(id, out var baseAction) ||
baseAction as T is not { } action ||
if (_actions.GetAction(id) is not {} action ||
!TryComp<T>(id, out var comp) ||
!_actions.ValidAction(action, canReach))
{
continue;
}
valid.Add((id, action));
valid.Add((id, action, comp));
}
return valid;

View File

@@ -1,5 +1,6 @@
using Content.Server.Administration;
using Content.Server.Administration;
using Content.Shared.Actions;
using Content.Shared.Actions.Components;
using Content.Shared.Administration;
using Robust.Shared.Console;

View File

@@ -1,5 +1,5 @@
using Content.Server.NPC.Systems;
using Content.Shared.Actions;
using Content.Shared.Actions.Components;
using Robust.Shared.Prototypes;
namespace Content.Server.NPC.Components;
@@ -20,7 +20,7 @@ public sealed partial class NPCUseActionOnTargetComponent : Component
/// Action that's going to attempt to be used.
/// </summary>
[DataField(required: true)]
public EntProtoId<EntityWorldTargetActionComponent> ActionId;
public EntProtoId<TargetActionComponent> ActionId;
[DataField]
public EntityUid? ActionEnt;

View File

@@ -28,24 +28,16 @@ public sealed class NPCUseActionOnTargetSystem : EntitySystem
if (!Resolve(user, ref user.Comp, false))
return false;
if (!TryComp<EntityWorldTargetActionComponent>(user.Comp.ActionEnt, out var action))
if (_actions.GetAction(user.Comp.ActionEnt) is not {} action)
return false;
if (!_actions.ValidAction(action))
return false;
if (action.Event != null)
{
action.Event.Coords = Transform(target).Coordinates;
}
_actions.SetEventTarget(action, target);
_actions.PerformAction(user,
null,
user.Comp.ActionEnt.Value,
action,
action.BaseEvent,
_timing.CurTime,
false);
// NPC is serverside, no prediction :(
_actions.PerformAction(user.Owner, action, predicted: false);
return true;
}

View File

@@ -4,6 +4,7 @@ using Content.Server.Inventory;
using Content.Server.Mind.Commands;
using Content.Server.Polymorph.Components;
using Content.Shared.Actions;
using Content.Shared.Actions.Components;
using Content.Shared.Buckle;
using Content.Shared.Coordinates;
using Content.Shared.Damage;
@@ -111,8 +112,8 @@ public sealed partial class PolymorphSystem : EntitySystem
if (_actions.AddAction(uid, ref component.Action, out var action, RevertPolymorphId))
{
action.EntityIcon = component.Parent;
action.UseDelay = TimeSpan.FromSeconds(component.Configuration.Delay);
_actions.SetEntityIcon((component.Action.Value, action), component.Parent);
_actions.SetUseDelay(component.Action.Value, TimeSpan.FromSeconds(component.Configuration.Delay));
}
}
@@ -397,20 +398,19 @@ public sealed partial class PolymorphSystem : EntitySystem
_metaData.SetEntityName(actionId.Value, Loc.GetString("polymorph-self-action-name", ("target", entProto.Name)), metaDataCache);
_metaData.SetEntityDescription(actionId.Value, Loc.GetString("polymorph-self-action-description", ("target", entProto.Name)), metaDataCache);
if (!_actions.TryGetActionData(actionId, out var baseAction))
if (_actions.GetAction(actionId) is not {} action)
return;
baseAction.Icon = new SpriteSpecifier.EntityPrototype(polyProto.Configuration.Entity);
if (baseAction is InstantActionComponent action)
action.Event = new PolymorphActionEvent(id);
_actions.SetIcon((action, action.Comp), new SpriteSpecifier.EntityPrototype(polyProto.Configuration.Entity));
_actions.SetEvent(action, new PolymorphActionEvent(id));
}
public void RemovePolymorphAction(ProtoId<PolymorphPrototype> id, Entity<PolymorphableComponent> target)
{
if (target.Comp.PolymorphActions == null)
if (target.Comp.PolymorphActions is not {} actions)
return;
if (target.Comp.PolymorphActions.TryGetValue(id, out var val))
_actions.RemoveAction(target, val);
if (actions.TryGetValue(id, out var action))
_actions.RemoveAction(target.Owner, action);
}
}

View File

@@ -61,12 +61,10 @@ public sealed partial class BorgSystem
if (_actions.AddAction(chassis, ref component.ModuleSwapActionEntity, out var action, component.ModuleSwapActionId, uid))
{
if(TryComp<BorgModuleIconComponent>(uid, out var moduleIconComp))
{
action.Icon = moduleIconComp.Icon;
};
action.EntityIcon = uid;
Dirty(component.ModuleSwapActionEntity.Value, action);
var actEnt = (component.ModuleSwapActionEntity.Value, action);
_actions.SetEntityIcon(actEnt, uid);
if (TryComp<BorgModuleIconComponent>(uid, out var moduleIconComp))
_actions.SetIcon(actEnt, moduleIconComp.Icon);
}
if (!TryComp(chassis, out BorgChassisComponent? chassisComp))

View File

@@ -350,10 +350,7 @@ public sealed partial class StoreSystem
component.BoughtEntities.RemoveAt(i);
if (_actions.TryGetActionData(purchase, out var actionComponent, logError: false))
{
_actionContainer.RemoveAction(purchase, actionComponent);
}
_actionContainer.RemoveAction(purchase, logMissing: false);
EntityManager.DeleteEntity(purchase);
}