action refactor proper ecs edition (#27422)
This commit is contained in:
@@ -3,7 +3,7 @@ using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Abilities.Goliath;
|
||||
|
||||
public sealed partial class GoliathSummonTentacleAction : EntityWorldTargetActionEvent
|
||||
public sealed partial class GoliathSummonTentacleAction : WorldTargetActionEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the entity that is spawned.
|
||||
|
||||
@@ -28,7 +28,7 @@ public sealed class GoliathTentacleSystem : EntitySystem
|
||||
|
||||
private void OnSummonAction(GoliathSummonTentacleAction args)
|
||||
{
|
||||
if (args.Handled || args.Coords is not { } coords)
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
// TODO: animation
|
||||
@@ -36,6 +36,7 @@ public sealed class GoliathTentacleSystem : EntitySystem
|
||||
_popup.PopupPredicted(Loc.GetString("tentacle-ability-use-popup", ("entity", args.Performer)), args.Performer, args.Performer, type: PopupType.SmallCaution);
|
||||
_stun.TryStun(args.Performer, TimeSpan.FromSeconds(0.8f), false);
|
||||
|
||||
var coords = args.Target;
|
||||
List<EntityCoordinates> spawnPos = new();
|
||||
spawnPos.Add(coords);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.Ghost;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Mind.Components;
|
||||
@@ -22,10 +23,14 @@ public sealed class ActionContainerSystem : EntitySystem
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||
|
||||
private EntityQuery<ActionComponent> _query;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
_query = GetEntityQuery<ActionComponent>();
|
||||
|
||||
SubscribeLocalEvent<ActionsContainerComponent, ComponentInit>(OnInit);
|
||||
SubscribeLocalEvent<ActionsContainerComponent, ComponentShutdown>(OnShutdown);
|
||||
SubscribeLocalEvent<ActionsContainerComponent, EntRemovedFromContainerMessage>(OnEntityRemoved);
|
||||
@@ -77,7 +82,7 @@ public sealed class ActionContainerSystem : EntitySystem
|
||||
/// <inheritdoc cref="EnsureAction(Robust.Shared.GameObjects.EntityUid,ref System.Nullable{Robust.Shared.GameObjects.EntityUid},string?,Content.Shared.Actions.ActionsContainerComponent?)"/>
|
||||
public bool EnsureAction(EntityUid uid,
|
||||
[NotNullWhen(true)] ref EntityUid? actionId,
|
||||
[NotNullWhen(true)] out BaseActionComponent? action,
|
||||
[NotNullWhen(true)] out ActionComponent? action,
|
||||
string? actionPrototypeId,
|
||||
ActionsContainerComponent? comp = null)
|
||||
{
|
||||
@@ -94,12 +99,14 @@ public sealed class ActionContainerSystem : EntitySystem
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_actions.TryGetActionData(actionId, out action))
|
||||
if (_actions.GetAction(actionId) is not {} ent)
|
||||
return false;
|
||||
|
||||
DebugTools.Assert(Transform(actionId.Value).ParentUid == uid);
|
||||
DebugTools.Assert(_container.IsEntityInContainer(actionId.Value));
|
||||
DebugTools.Assert(action.Container == uid);
|
||||
actionId = ent;
|
||||
action = ent.Comp;
|
||||
DebugTools.Assert(Transform(ent).ParentUid == uid);
|
||||
DebugTools.Assert(_container.IsEntityInContainer(ent));
|
||||
DebugTools.Assert(ent.Comp.Container == uid);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -112,7 +119,14 @@ public sealed class ActionContainerSystem : EntitySystem
|
||||
return false;
|
||||
|
||||
actionId = Spawn(actionPrototypeId);
|
||||
if (AddAction(uid, actionId.Value, action, comp) && _actions.TryGetActionData(actionId, out action))
|
||||
if (!_query.TryComp(actionId, out action))
|
||||
{
|
||||
Log.Error($"Tried to add invalid action {ToPrettyString(actionId)} to {ToPrettyString(uid)}!");
|
||||
Del(actionId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AddAction(uid, actionId.Value, action, comp))
|
||||
return true;
|
||||
|
||||
Del(actionId.Value);
|
||||
@@ -129,21 +143,21 @@ public sealed class ActionContainerSystem : EntitySystem
|
||||
public void TransferAction(
|
||||
EntityUid actionId,
|
||||
EntityUid newContainer,
|
||||
BaseActionComponent? action = null,
|
||||
ActionComponent? action = null,
|
||||
ActionsContainerComponent? container = null)
|
||||
{
|
||||
if (!_actions.ResolveActionData(actionId, ref action))
|
||||
if (_actions.GetAction((actionId, action)) is not {} ent)
|
||||
return;
|
||||
|
||||
if (action.Container == newContainer)
|
||||
if (ent.Comp.Container == newContainer)
|
||||
return;
|
||||
|
||||
var attached = action.AttachedEntity;
|
||||
if (!AddAction(newContainer, actionId, action, container))
|
||||
var attached = ent.Comp.AttachedEntity;
|
||||
if (!AddAction(newContainer, ent, ent.Comp, container))
|
||||
return;
|
||||
|
||||
DebugTools.AssertEqual(action.Container, newContainer);
|
||||
DebugTools.AssertEqual(action.AttachedEntity, attached);
|
||||
DebugTools.AssertEqual(ent.Comp.Container, newContainer);
|
||||
DebugTools.AssertEqual(ent.Comp.AttachedEntity, attached);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -180,23 +194,23 @@ public sealed class ActionContainerSystem : EntitySystem
|
||||
EntityUid actionId,
|
||||
EntityUid newContainer,
|
||||
EntityUid newAttached,
|
||||
BaseActionComponent? action = null,
|
||||
ActionComponent? action = null,
|
||||
ActionsContainerComponent? container = null)
|
||||
{
|
||||
if (!_actions.ResolveActionData(actionId, ref action))
|
||||
if (_actions.GetAction((actionId, action)) is not {} ent)
|
||||
return;
|
||||
|
||||
if (action.Container == newContainer)
|
||||
if (ent.Comp.Container == newContainer)
|
||||
return;
|
||||
|
||||
var attached = newAttached;
|
||||
if (!AddAction(newContainer, actionId, action, container))
|
||||
if (!AddAction(newContainer, ent, ent.Comp, container))
|
||||
return;
|
||||
|
||||
DebugTools.AssertEqual(action.Container, newContainer);
|
||||
_actions.AddActionDirect(newAttached, actionId, action: action);
|
||||
DebugTools.AssertEqual(ent.Comp.Container, newContainer);
|
||||
_actions.AddActionDirect(newAttached, (ent, ent.Comp));
|
||||
|
||||
DebugTools.AssertEqual(action.AttachedEntity, attached);
|
||||
DebugTools.AssertEqual(ent.Comp.AttachedEntity, attached);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -227,25 +241,25 @@ public sealed class ActionContainerSystem : EntitySystem
|
||||
/// <summary>
|
||||
/// Adds a pre-existing action to an action container. If the action is already in some container it will first remove it.
|
||||
/// </summary>
|
||||
public bool AddAction(EntityUid uid, EntityUid actionId, BaseActionComponent? action = null, ActionsContainerComponent? comp = null)
|
||||
public bool AddAction(EntityUid uid, EntityUid actionId, ActionComponent? action = null, ActionsContainerComponent? comp = null)
|
||||
{
|
||||
if (!_actions.ResolveActionData(actionId, ref action))
|
||||
if (_actions.GetAction((actionId, action)) is not {} ent)
|
||||
return false;
|
||||
|
||||
if (action.Container != null)
|
||||
RemoveAction(actionId, action);
|
||||
if (ent.Comp.Container != null)
|
||||
RemoveAction((ent, ent));
|
||||
|
||||
DebugTools.AssertOwner(uid, comp);
|
||||
comp ??= EnsureComp<ActionsContainerComponent>(uid);
|
||||
if (!_container.Insert(actionId, comp.Container))
|
||||
if (!_container.Insert(ent.Owner, comp.Container))
|
||||
{
|
||||
Log.Error($"Failed to insert action {ToPrettyString(actionId)} into {ToPrettyString(uid)}");
|
||||
Log.Error($"Failed to insert action {ToPrettyString(ent)} into {ToPrettyString(uid)}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Container insert events should have updated the component's fields:
|
||||
DebugTools.Assert(comp.Container.Contains(actionId));
|
||||
DebugTools.Assert(action.Container == uid);
|
||||
DebugTools.Assert(comp.Container.Contains(ent));
|
||||
DebugTools.Assert(ent.Comp.Container == uid);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -253,30 +267,31 @@ public sealed class ActionContainerSystem : EntitySystem
|
||||
/// <summary>
|
||||
/// Removes an action from its container and any action-performer and moves the action to null-space
|
||||
/// </summary>
|
||||
public void RemoveAction(EntityUid actionId, BaseActionComponent? action = null)
|
||||
public void RemoveAction(Entity<ActionComponent?>? action, bool logMissing = true)
|
||||
{
|
||||
if (!_actions.ResolveActionData(actionId, ref action))
|
||||
if (_actions.GetAction(action, logMissing) is not {} ent)
|
||||
return;
|
||||
|
||||
if (action.Container == null)
|
||||
if (ent.Comp.Container == null)
|
||||
return;
|
||||
|
||||
_transform.DetachEntity(actionId, Transform(actionId));
|
||||
_transform.DetachEntity(ent, Transform(ent));
|
||||
|
||||
// Container removal events should have removed the action from the action container.
|
||||
// However, just in case the container was already deleted we will still manually clear the container field
|
||||
if (action.Container != null)
|
||||
if (ent.Comp.Container is {} container)
|
||||
{
|
||||
if (Exists(action.Container))
|
||||
Log.Error($"Failed to remove action {ToPrettyString(actionId)} from its container {ToPrettyString(action.Container)}?");
|
||||
action.Container = null;
|
||||
if (Exists(container))
|
||||
Log.Error($"Failed to remove action {ToPrettyString(ent)} from its container {ToPrettyString(container)}?");
|
||||
ent.Comp.Container = null;
|
||||
DirtyField(ent, ent.Comp, nameof(ActionComponent.Container));
|
||||
}
|
||||
|
||||
// If the action was granted to some entity, then the removal from the container should have automatically removed it.
|
||||
// However, if the action was granted without ever being placed in an action container, it will not have been removed.
|
||||
// Therefore, to ensure that the behaviour of the method is consistent we will also explicitly remove the action.
|
||||
if (action.AttachedEntity != null)
|
||||
_actions.RemoveAction(action.AttachedEntity.Value, actionId, action: action);
|
||||
if (ent.Comp.AttachedEntity is {} actions)
|
||||
_actions.RemoveAction(actions, (ent, ent));
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, ActionsContainerComponent component, ComponentInit args)
|
||||
@@ -297,16 +312,16 @@ public sealed class ActionContainerSystem : EntitySystem
|
||||
if (args.Container.ID != ActionsContainerComponent.ContainerId)
|
||||
return;
|
||||
|
||||
if (!_actions.TryGetActionData(args.Entity, out var data))
|
||||
if (_actions.GetAction(args.Entity) is not {} action)
|
||||
return;
|
||||
|
||||
if (data.Container != uid)
|
||||
if (action.Comp.Container != uid)
|
||||
{
|
||||
data.Container = uid;
|
||||
Dirty(args.Entity, data);
|
||||
action.Comp.Container = uid;
|
||||
DirtyField(action, action.Comp, nameof(ActionComponent.Container));
|
||||
}
|
||||
|
||||
var ev = new ActionAddedEvent(args.Entity, data);
|
||||
var ev = new ActionAddedEvent(args.Entity, action);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
}
|
||||
|
||||
@@ -315,17 +330,17 @@ public sealed class ActionContainerSystem : EntitySystem
|
||||
if (args.Container.ID != ActionsContainerComponent.ContainerId)
|
||||
return;
|
||||
|
||||
if (!_actions.TryGetActionData(args.Entity, out var data, false))
|
||||
if (_actions.GetAction(args.Entity, false) is not {} action)
|
||||
return;
|
||||
|
||||
var ev = new ActionRemovedEvent(args.Entity, data);
|
||||
var ev = new ActionRemovedEvent(args.Entity, action);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
|
||||
if (data.Container == null)
|
||||
if (action.Comp.Container == null)
|
||||
return;
|
||||
|
||||
data.Container = null;
|
||||
Dirty(args.Entity, data);
|
||||
action.Comp.Container = null;
|
||||
DirtyField(action, action.Comp, nameof(ActionComponent.Container));
|
||||
}
|
||||
|
||||
private void OnActionAdded(EntityUid uid, ActionsContainerComponent component, ActionAddedEvent args)
|
||||
@@ -342,9 +357,9 @@ public sealed class ActionContainerSystem : EntitySystem
|
||||
public readonly struct ActionAddedEvent
|
||||
{
|
||||
public readonly EntityUid Action;
|
||||
public readonly BaseActionComponent Component;
|
||||
public readonly ActionComponent Component;
|
||||
|
||||
public ActionAddedEvent(EntityUid action, BaseActionComponent component)
|
||||
public ActionAddedEvent(EntityUid action, ActionComponent component)
|
||||
{
|
||||
Action = action;
|
||||
Component = component;
|
||||
@@ -358,9 +373,9 @@ public readonly struct ActionAddedEvent
|
||||
public readonly struct ActionRemovedEvent
|
||||
{
|
||||
public readonly EntityUid Action;
|
||||
public readonly BaseActionComponent Component;
|
||||
public readonly ActionComponent Component;
|
||||
|
||||
public ActionRemovedEvent(EntityUid action, BaseActionComponent component)
|
||||
public ActionRemovedEvent(EntityUid action, ActionComponent component)
|
||||
{
|
||||
Action = action;
|
||||
Component = component;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Inventory.Events;
|
||||
@@ -102,7 +103,7 @@ public sealed class RequestPerformActionEvent : EntityEventArgs
|
||||
EntityCoordinatesTarget = entityCoordinatesTarget;
|
||||
}
|
||||
|
||||
public RequestPerformActionEvent(NetEntity action, NetEntity entityTarget, NetCoordinates entityCoordinatesTarget)
|
||||
public RequestPerformActionEvent(NetEntity action, NetEntity? entityTarget, NetCoordinates entityCoordinatesTarget)
|
||||
{
|
||||
Action = action;
|
||||
EntityTarget = entityTarget;
|
||||
@@ -149,27 +150,12 @@ public abstract partial class WorldTargetActionEvent : BaseActionEvent
|
||||
/// The coordinates of the location that the user targeted.
|
||||
/// </summary>
|
||||
public EntityCoordinates Target;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the type of event that gets raised when an <see cref="EntityWorldTargetActionComponent"/> is performed.
|
||||
/// The <see cref="BaseActionEvent.Performer"/>, <see cref="Entity"/>, and <see cref="Coords"/>
|
||||
/// fields will automatically be filled out by the <see cref="SharedActionsSystem"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// To define a new action for some system, you need to create an event that inherits from this class.
|
||||
/// </remarks>
|
||||
public abstract partial class EntityWorldTargetActionEvent : BaseActionEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// The entity that the user targeted.
|
||||
/// When combined with <see cref="EntityTargetAction"/> (and <c>Event</c> is null), the entity the client was hovering when clicked.
|
||||
/// This can be null as the primary purpose of this event is for getting coordinates.
|
||||
/// </summary>
|
||||
public EntityUid? Entity;
|
||||
|
||||
/// <summary>
|
||||
/// The coordinates of the location that the user targeted.
|
||||
/// </summary>
|
||||
public EntityCoordinates? Coords;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -187,7 +173,7 @@ public abstract partial class BaseActionEvent : HandledEntityEventArgs
|
||||
/// <summary>
|
||||
/// The action the event belongs to.
|
||||
/// </summary>
|
||||
public Entity<BaseActionComponent> Action;
|
||||
public Entity<ActionComponent> Action;
|
||||
|
||||
/// <summary>
|
||||
/// Should we toggle the action entity?
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.Actions.Events;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -22,13 +23,13 @@ public sealed class ActionUpgradeSystem : EntitySystem
|
||||
private void OnActionUpgradeEvent(EntityUid uid, ActionUpgradeComponent component, ActionUpgradeEvent args)
|
||||
{
|
||||
if (!CanUpgrade(args.NewLevel, component.EffectedLevels, out var newActionProto)
|
||||
|| !_actions.TryGetActionData(uid, out var actionComp))
|
||||
|| _actions.GetAction(uid) is not {} action)
|
||||
return;
|
||||
|
||||
var originalContainer = actionComp.Container;
|
||||
var originalAttachedEntity = actionComp.AttachedEntity;
|
||||
var originalContainer = action.Comp.Container;
|
||||
var originalAttachedEntity = action.Comp.AttachedEntity;
|
||||
|
||||
_actionContainer.RemoveAction(uid, actionComp);
|
||||
_actionContainer.RemoveAction((action, action));
|
||||
|
||||
EntityUid? upgradedActionId = null;
|
||||
if (originalContainer != null
|
||||
@@ -150,16 +151,16 @@ public sealed class ActionUpgradeSystem : EntitySystem
|
||||
// RaiseActionUpgradeEvent(newLevel, actionId.Value);
|
||||
|
||||
if (!CanUpgrade(newLevel, actionUpgradeComponent.EffectedLevels, out var newActionPrototype)
|
||||
|| !_actions.TryGetActionData(actionId, out var actionComp))
|
||||
|| _actions.GetAction(actionId) is not {} action)
|
||||
return null;
|
||||
|
||||
newActionProto ??= newActionPrototype;
|
||||
DebugTools.AssertNotNull(newActionProto);
|
||||
|
||||
var originalContainer = actionComp.Container;
|
||||
var originalAttachedEntity = actionComp.AttachedEntity;
|
||||
var originalContainer = action.Comp.Container;
|
||||
var originalAttachedEntity = action.Comp.AttachedEntity;
|
||||
|
||||
_actionContainer.RemoveAction(actionId.Value, actionComp);
|
||||
_actionContainer.RemoveAction((action, action.Comp));
|
||||
|
||||
EntityUid? upgradedActionId = null;
|
||||
if (originalContainer != null
|
||||
|
||||
@@ -1,35 +1,39 @@
|
||||
using Robust.Shared.Audio;
|
||||
using Content.Shared.Actions;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Actions;
|
||||
namespace Content.Shared.Actions.Components;
|
||||
|
||||
// TODO ACTIONS make this a separate component and remove the inheritance stuff.
|
||||
// TODO ACTIONS convert to auto comp state?
|
||||
|
||||
// TODO add access attribute. Need to figure out what to do with decal & mapping actions.
|
||||
// [Access(typeof(SharedActionsSystem))]
|
||||
/// <summary>
|
||||
/// Component all actions are required to have.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedActionsSystem))]
|
||||
[AutoGenerateComponentState(true, true)]
|
||||
[EntityCategory("Actions")]
|
||||
public abstract partial class BaseActionComponent : Component
|
||||
public sealed partial class ActionComponent : Component
|
||||
{
|
||||
public abstract BaseActionEvent? BaseEvent { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Icon representing this action in the UI.
|
||||
/// </summary>
|
||||
[DataField("icon")] public SpriteSpecifier? Icon;
|
||||
[DataField, AutoNetworkedField]
|
||||
public SpriteSpecifier? Icon;
|
||||
|
||||
/// <summary>
|
||||
/// For toggle actions only, icon to show when toggled on. If omitted, the action will simply be highlighted
|
||||
/// when turned on.
|
||||
/// </summary>
|
||||
[DataField("iconOn")] public SpriteSpecifier? IconOn;
|
||||
[DataField, AutoNetworkedField]
|
||||
public SpriteSpecifier? IconOn;
|
||||
|
||||
/// <summary>
|
||||
/// For toggle actions only, background to show when toggled on.
|
||||
/// </summary>
|
||||
[DataField] public SpriteSpecifier? BackgroundOn;
|
||||
[DataField]
|
||||
public SpriteSpecifier? BackgroundOn;
|
||||
|
||||
/// <summary>
|
||||
/// If not null, this color will modulate the action icon color.
|
||||
@@ -38,12 +42,14 @@ public abstract partial class BaseActionComponent : Component
|
||||
/// This currently only exists for decal-placement actions, so that the action icons correspond to the color of
|
||||
/// the decal. But this is probably useful for other actions, including maybe changing color on toggle.
|
||||
/// </remarks>
|
||||
[DataField("iconColor")] public Color IconColor = Color.White;
|
||||
[DataField, AutoNetworkedField]
|
||||
public Color IconColor = Color.White;
|
||||
|
||||
/// <summary>
|
||||
/// The original <see cref="IconColor"/> this action was.
|
||||
/// </summary>
|
||||
[DataField] public Color OriginalIconColor;
|
||||
[DataField, AutoNetworkedField]
|
||||
public Color OriginalIconColor;
|
||||
|
||||
/// <summary>
|
||||
/// The color the action should turn to when disabled
|
||||
@@ -53,12 +59,14 @@ public abstract partial class BaseActionComponent : Component
|
||||
/// <summary>
|
||||
/// Keywords that can be used to search for this action in the action menu.
|
||||
/// </summary>
|
||||
[DataField("keywords")] public HashSet<string> Keywords = new();
|
||||
[DataField, AutoNetworkedField]
|
||||
public HashSet<string> Keywords = new();
|
||||
|
||||
/// <summary>
|
||||
/// Whether this action is currently enabled. If not enabled, this action cannot be performed.
|
||||
/// </summary>
|
||||
[DataField("enabled")] public bool Enabled = true;
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool Enabled = true;
|
||||
|
||||
/// <summary>
|
||||
/// The toggle state of this action. Toggling switches the currently displayed icon, see <see cref="Icon"/> and <see cref="IconOn"/>.
|
||||
@@ -67,14 +75,14 @@ public abstract partial class BaseActionComponent : Component
|
||||
/// The toggle can set directly via <see cref="SharedActionsSystem.SetToggled"/>, but it will also be
|
||||
/// automatically toggled for targeted-actions while selecting a target.
|
||||
/// </remarks>
|
||||
[DataField]
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool Toggled;
|
||||
|
||||
/// <summary>
|
||||
/// The current cooldown on the action.
|
||||
/// </summary>
|
||||
// TODO serialization
|
||||
public (TimeSpan Start, TimeSpan End)? Cooldown;
|
||||
[DataField, AutoNetworkedField]
|
||||
public ActionCooldown? Cooldown;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the action will have an initial cooldown applied upon addition.
|
||||
@@ -84,14 +92,15 @@ public abstract partial class BaseActionComponent : Component
|
||||
/// <summary>
|
||||
/// Time interval between action uses.
|
||||
/// </summary>
|
||||
[DataField("useDelay")] public TimeSpan? UseDelay;
|
||||
[DataField, AutoNetworkedField]
|
||||
public TimeSpan? UseDelay;
|
||||
|
||||
/// <summary>
|
||||
/// The entity that contains this action. If the action is innate, this may be the user themselves.
|
||||
/// This should almost always be non-null.
|
||||
/// </summary>
|
||||
[Access(typeof(ActionContainerSystem), typeof(SharedActionsSystem))]
|
||||
[DataField]
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityUid? Container;
|
||||
|
||||
/// <summary>
|
||||
@@ -113,40 +122,45 @@ public abstract partial class BaseActionComponent : Component
|
||||
set => EntIcon = value;
|
||||
}
|
||||
|
||||
[DataField]
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityUid? EntIcon;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the action system should block this action if the user cannot currently interact. Some spells or
|
||||
/// abilities may want to disable this and implement their own checks.
|
||||
/// </summary>
|
||||
[DataField("checkCanInteract")] public bool CheckCanInteract = true;
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool CheckCanInteract = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to check if the user is conscious or not. Can be used instead of <see cref="CheckCanInteract"/>
|
||||
/// for a more permissive check.
|
||||
/// </summary>
|
||||
[DataField] public bool CheckConsciousness = true;
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool CheckConsciousness = true;
|
||||
|
||||
/// <summary>
|
||||
/// If true, this will cause the action to only execute locally without ever notifying the server.
|
||||
/// </summary>
|
||||
[DataField("clientExclusive")] public bool ClientExclusive = false;
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool ClientExclusive;
|
||||
|
||||
/// <summary>
|
||||
/// Determines the order in which actions are automatically added the action bar.
|
||||
/// </summary>
|
||||
[DataField("priority")] public int Priority = 0;
|
||||
[DataField, AutoNetworkedField]
|
||||
public int Priority = 0;
|
||||
|
||||
/// <summary>
|
||||
/// What entity, if any, currently has this action in the actions component?
|
||||
/// </summary>
|
||||
[DataField] public EntityUid? AttachedEntity;
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityUid? AttachedEntity;
|
||||
|
||||
/// <summary>
|
||||
/// If true, this will cause the the action event to always be raised directed at the action performer/user instead of the action's container/provider.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool RaiseOnUser;
|
||||
|
||||
/// <summary>
|
||||
@@ -160,75 +174,34 @@ public abstract partial class BaseActionComponent : Component
|
||||
/// <summary>
|
||||
/// Whether or not to automatically add this action to the action bar when it becomes available.
|
||||
/// </summary>
|
||||
[DataField("autoPopulate")] public bool AutoPopulate = true;
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool AutoPopulate = true;
|
||||
|
||||
/// <summary>
|
||||
/// Temporary actions are deleted when they get removed a <see cref="ActionsComponent"/>.
|
||||
/// </summary>
|
||||
[DataField("temporary")] public bool Temporary;
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool Temporary;
|
||||
|
||||
/// <summary>
|
||||
/// Determines the appearance of the entity-icon for actions that are enabled via some entity.
|
||||
/// </summary>
|
||||
[DataField("itemIconStyle")] public ItemActionIconStyle ItemIconStyle;
|
||||
[DataField, AutoNetworkedField]
|
||||
public ItemActionIconStyle ItemIconStyle;
|
||||
|
||||
/// <summary>
|
||||
/// If not null, this sound will be played when performing this action.
|
||||
/// </summary>
|
||||
[DataField("sound")] public SoundSpecifier? Sound;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public abstract class BaseActionComponentState : ComponentState
|
||||
{
|
||||
public SpriteSpecifier? Icon;
|
||||
public SpriteSpecifier? IconOn;
|
||||
public Color IconColor;
|
||||
public Color OriginalIconColor;
|
||||
public Color DisabledIconColor;
|
||||
public HashSet<string> Keywords;
|
||||
public bool Enabled;
|
||||
public bool Toggled;
|
||||
public (TimeSpan Start, TimeSpan End)? Cooldown;
|
||||
public TimeSpan? UseDelay;
|
||||
public NetEntity? Container;
|
||||
public NetEntity? EntityIcon;
|
||||
public bool CheckCanInteract;
|
||||
public bool CheckConsciousness;
|
||||
public bool ClientExclusive;
|
||||
public int Priority;
|
||||
public NetEntity? AttachedEntity;
|
||||
public bool RaiseOnUser;
|
||||
public bool RaiseOnAction;
|
||||
public bool AutoPopulate;
|
||||
public bool Temporary;
|
||||
public ItemActionIconStyle ItemIconStyle;
|
||||
[DataField, AutoNetworkedField]
|
||||
public SoundSpecifier? Sound;
|
||||
|
||||
protected BaseActionComponentState(BaseActionComponent component, IEntityManager entManager)
|
||||
{
|
||||
Container = entManager.GetNetEntity(component.Container);
|
||||
EntityIcon = entManager.GetNetEntity(component.EntIcon);
|
||||
AttachedEntity = entManager.GetNetEntity(component.AttachedEntity);
|
||||
RaiseOnUser = component.RaiseOnUser;
|
||||
RaiseOnAction = component.RaiseOnAction;
|
||||
Icon = component.Icon;
|
||||
IconOn = component.IconOn;
|
||||
IconColor = component.IconColor;
|
||||
OriginalIconColor = component.OriginalIconColor;
|
||||
DisabledIconColor = component.DisabledIconColor;
|
||||
Keywords = component.Keywords;
|
||||
Enabled = component.Enabled;
|
||||
Toggled = component.Toggled;
|
||||
Cooldown = component.Cooldown;
|
||||
UseDelay = component.UseDelay;
|
||||
CheckCanInteract = component.CheckCanInteract;
|
||||
CheckConsciousness = component.CheckConsciousness;
|
||||
ClientExclusive = component.ClientExclusive;
|
||||
Priority = component.Priority;
|
||||
AutoPopulate = component.AutoPopulate;
|
||||
Temporary = component.Temporary;
|
||||
ItemIconStyle = component.ItemIconStyle;
|
||||
Sound = component.Sound;
|
||||
}
|
||||
}
|
||||
|
||||
[DataRecord, Serializable, NetSerializable]
|
||||
public record struct ActionCooldown
|
||||
{
|
||||
[DataField(required: true, customTypeSerializer: typeof(TimeOffsetSerializer))]
|
||||
public TimeSpan Start;
|
||||
|
||||
[DataField(required: true, customTypeSerializer: typeof(TimeOffsetSerializer))]
|
||||
public TimeSpan End;
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
using Content.Shared.Actions;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Actions;
|
||||
namespace Content.Shared.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// This component indicates that this entity contains actions inside of some container.
|
||||
/// </summary>
|
||||
[NetworkedComponent, RegisterComponent]
|
||||
[Access(typeof(ActionContainerSystem), typeof(SharedActionsSystem))]
|
||||
[NetworkedComponent, RegisterComponent, Access(typeof(ActionContainerSystem), typeof(SharedActionsSystem))]
|
||||
public sealed partial class ActionsContainerComponent : Component
|
||||
{
|
||||
public const string ContainerId = "actions";
|
||||
@@ -1,24 +1,29 @@
|
||||
using Content.Shared.Actions;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Actions;
|
||||
namespace Content.Shared.Actions.Components;
|
||||
|
||||
// For actions that can use basic upgrades
|
||||
// Not all actions should be upgradable
|
||||
/// <summary>
|
||||
/// For actions that can use basic upgrades
|
||||
/// Not all actions should be upgradable
|
||||
/// Requires <see cref="ActionComponent"/>.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(ActionUpgradeSystem))]
|
||||
[EntityCategory("Actions")]
|
||||
public sealed partial class ActionUpgradeComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Current Level of the action.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
[DataField]
|
||||
public int Level = 1;
|
||||
|
||||
/// <summary>
|
||||
/// What level(s) effect this action?
|
||||
/// You can skip levels, so you can have this entity change at level 2 but then won't change again until level 5.
|
||||
/// </summary>
|
||||
[DataField("effectedLevels"), ViewVariables]
|
||||
[DataField]
|
||||
public Dictionary<int, EntProtoId> EffectedLevels = new();
|
||||
|
||||
// TODO: Branching level upgrades
|
||||
@@ -1,18 +1,21 @@
|
||||
using Content.Shared.Actions;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Actions;
|
||||
namespace Content.Shared.Actions.Components;
|
||||
|
||||
[NetworkedComponent]
|
||||
[RegisterComponent]
|
||||
[Access(typeof(SharedActionsSystem))]
|
||||
/// <summary>
|
||||
/// Lets the player controlling this entity use actions.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedActionsSystem))]
|
||||
public sealed partial class ActionsComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// List of actions currently granted to this entity.
|
||||
/// On the client, this may contain a mixture of client-side and networked entities.
|
||||
/// </summary>
|
||||
[DataField] public HashSet<EntityUid> Actions = new();
|
||||
[DataField]
|
||||
public HashSet<EntityUid> Actions = new();
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
@@ -1,15 +1,19 @@
|
||||
using Content.Shared.Actions;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Shared.Actions;
|
||||
namespace Content.Shared.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// An action that must be confirmed before using it.
|
||||
/// Using it for the first time primes it, after a delay you can then confirm it.
|
||||
/// Used for dangerous actions that cannot be undone (unlike screaming).
|
||||
/// Requires <see cref="ActionComponent"/>.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(ConfirmableActionSystem))]
|
||||
[AutoGenerateComponentState, AutoGenerateComponentPause]
|
||||
[EntityCategory("Actions")]
|
||||
public sealed partial class ConfirmableActionComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
@@ -0,0 +1,48 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Used on action entities to define an action that triggers when targeting an entity.
|
||||
/// If used with <see cref="WorldTargetActionComponent"/>, the event here can be set to null and <c>Optional</c> should be set.
|
||||
/// Then <see cref="WorldActionEvent"> can have <c>TargetEntity</c> optionally set to the client's hovered entity, if it is valid.
|
||||
/// Using entity-world targeting like this will always give coords, but doesn't need to have an entity.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Requires <see cref="TargetActionComponent"/>.
|
||||
/// </remarks>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedActionsSystem))]
|
||||
[EntityCategory("Actions")]
|
||||
[AutoGenerateComponentState]
|
||||
public sealed partial class EntityTargetActionComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The local-event to raise when this action is performed.
|
||||
/// If this is null entity-world targeting is done as specified on the component doc.
|
||||
/// </summary>
|
||||
[DataField, NonSerialized]
|
||||
public EntityTargetActionEvent? Event;
|
||||
|
||||
/// <summary>
|
||||
/// Determines which entities are valid targets for this action.
|
||||
/// </summary>
|
||||
/// <remarks>No whitelist check when null.</remarks>
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityWhitelist? Whitelist;
|
||||
|
||||
/// <summary>
|
||||
/// Determines which entities cannot be valid targets for this action, even if matching the whitelist.
|
||||
/// </summary>
|
||||
/// <remarks>No blacklist check when null.</remarks>
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityWhitelist? Blacklist;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this action considers the user as a valid target entity when using this action.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool CanTargetSelf = true;
|
||||
}
|
||||
20
Content.Shared/Actions/Components/InstantActionComponent.cs
Normal file
20
Content.Shared/Actions/Components/InstantActionComponent.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Content.Shared.Actions;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// An action that raises an event as soon as it gets used.
|
||||
/// Requires <see cref="ActionComponent"/>.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedActionsSystem))]
|
||||
[EntityCategory("Actions")]
|
||||
public sealed partial class InstantActionComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The local-event to raise when this action is performed.
|
||||
/// </summary>
|
||||
[DataField(required: true), NonSerialized]
|
||||
public InstantActionEvent? Event;
|
||||
}
|
||||
@@ -1,19 +1,30 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Interaction;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Actions;
|
||||
namespace Content.Shared.Actions.Components;
|
||||
|
||||
public abstract partial class BaseTargetActionComponent : BaseActionComponent
|
||||
/// <summary>
|
||||
/// An action that targets an entity or map.
|
||||
/// Requires <see cref="ActionComponent"/>.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedActionsSystem))]
|
||||
[EntityCategory("Actions")]
|
||||
public sealed partial class TargetActionComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// For entity- or map-targeting actions, if this is true the action will remain selected after it is used, so
|
||||
/// it can be continuously re-used. If this is false, the action will be deselected after one use.
|
||||
/// </summary>
|
||||
[DataField("repeat")] public bool Repeat;
|
||||
[DataField]
|
||||
public bool Repeat;
|
||||
|
||||
/// <summary>
|
||||
/// For entity- or map-targeting action, determines whether the action is deselected if the user doesn't click a valid target.
|
||||
/// </summary>
|
||||
[DataField("deselectOnMiss")] public bool DeselectOnMiss;
|
||||
[DataField]
|
||||
public bool DeselectOnMiss;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the action system should block this action if the user cannot actually access the target
|
||||
@@ -23,9 +34,11 @@ public abstract partial class BaseTargetActionComponent : BaseActionComponent
|
||||
/// <remarks>
|
||||
/// Even if this is false, the <see cref="Range"/> will still be checked.
|
||||
/// </remarks>
|
||||
[DataField("checkCanAccess")] public bool CheckCanAccess = true;
|
||||
[DataField]
|
||||
public bool CheckCanAccess = true;
|
||||
|
||||
[DataField("range")] public float Range = SharedInteractionSystem.InteractionRange;
|
||||
[DataField]
|
||||
public float Range = SharedInteractionSystem.InteractionRange;
|
||||
|
||||
/// <summary>
|
||||
/// If the target is invalid, this bool determines whether the left-click will default to performing a standard-interaction
|
||||
@@ -33,11 +46,13 @@ public abstract partial class BaseTargetActionComponent : BaseActionComponent
|
||||
/// <remarks>
|
||||
/// Interactions will still be blocked if the target-validation generates a pop-up
|
||||
/// </remarks>
|
||||
[DataField("interactOnMiss")] public bool InteractOnMiss = false;
|
||||
[DataField]
|
||||
public bool InteractOnMiss;
|
||||
|
||||
/// <summary>
|
||||
/// If true, and if <see cref="ShowHandItemOverlay"/> is enabled, then this action's icon will be drawn by that
|
||||
/// over lay in place of the currently held item "held item".
|
||||
/// </summary>
|
||||
[DataField("targetingIndicator")] public bool TargetingIndicator = true;
|
||||
[DataField]
|
||||
public bool TargetingIndicator = true;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Content.Shared.Actions;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Actions.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Used on action entities to define an action that triggers when targeting an entity coordinate.
|
||||
/// Can be combined with <see cref="EntityTargetActionComponent"/>, see its docs for more information.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Requires <see cref="TargetActionComponent"/>.
|
||||
/// </remarks>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedActionsSystem))]
|
||||
[EntityCategory("Actions")]
|
||||
public sealed partial class WorldTargetActionComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The local-event to raise when this action is performed.
|
||||
/// </summary>
|
||||
[DataField(required: true), NonSerialized]
|
||||
public WorldTargetActionEvent? Event;
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.Actions.Events;
|
||||
using Content.Shared.Popups;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Actions;
|
||||
|
||||
/// <summary>
|
||||
/// Used on action entities to define an action that triggers when targeting an entity.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class EntityTargetActionComponent : BaseTargetActionComponent
|
||||
{
|
||||
public override BaseActionEvent? BaseEvent => Event;
|
||||
|
||||
/// <summary>
|
||||
/// The local-event to raise when this action is performed.
|
||||
/// </summary>
|
||||
[DataField("event")]
|
||||
[NonSerialized]
|
||||
public EntityTargetActionEvent? Event;
|
||||
|
||||
/// <summary>
|
||||
/// Determines which entities are valid targets for this action.
|
||||
/// </summary>
|
||||
/// <remarks>No whitelist check when null.</remarks>
|
||||
[DataField("whitelist")] public EntityWhitelist? Whitelist;
|
||||
|
||||
/// <summary>
|
||||
/// Determines which entities are NOT valid targets for this action.
|
||||
/// </summary>
|
||||
/// <remarks>No blacklist check when null.</remarks>
|
||||
[DataField] public EntityWhitelist? Blacklist;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this action considers the user as a valid target entity when using this action.
|
||||
/// </summary>
|
||||
[DataField("canTargetSelf")] public bool CanTargetSelf = true;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class EntityTargetActionComponentState : BaseActionComponentState
|
||||
{
|
||||
public EntityWhitelist? Whitelist;
|
||||
public EntityWhitelist? Blacklist;
|
||||
public bool CanTargetSelf;
|
||||
|
||||
public EntityTargetActionComponentState(EntityTargetActionComponent component, IEntityManager entManager) : base(component, entManager)
|
||||
{
|
||||
Whitelist = component.Whitelist;
|
||||
Blacklist = component.Blacklist;
|
||||
CanTargetSelf = component.CanTargetSelf;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Actions;
|
||||
|
||||
/// <summary>
|
||||
/// Used on action entities to define an action that triggers when targeting an entity or entity coordinates.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class EntityWorldTargetActionComponent : BaseTargetActionComponent
|
||||
{
|
||||
public override BaseActionEvent? BaseEvent => Event;
|
||||
|
||||
/// <summary>
|
||||
/// The local-event to raise when this action is performed.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
[NonSerialized]
|
||||
public EntityWorldTargetActionEvent? Event;
|
||||
|
||||
/// <summary>
|
||||
/// Determines which entities are valid targets for this action.
|
||||
/// </summary>
|
||||
/// <remarks>No whitelist check when null.</remarks>
|
||||
[DataField] public EntityWhitelist? Whitelist;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this action considers the user as a valid target entity when using this action.
|
||||
/// </summary>
|
||||
[DataField] public bool CanTargetSelf = true;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class EntityWorldTargetActionComponentState(
|
||||
EntityWorldTargetActionComponent component,
|
||||
IEntityManager entManager)
|
||||
: BaseActionComponentState(component, entManager)
|
||||
{
|
||||
public EntityWhitelist? Whitelist = component.Whitelist;
|
||||
public bool CanTargetSelf = component.CanTargetSelf;
|
||||
}
|
||||
@@ -2,7 +2,7 @@ namespace Content.Shared.Actions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Raised before an action is used and can be cancelled to prevent it.
|
||||
/// Allowed to have side effects like modifying the action component.
|
||||
/// Allowed to have side effects like modifying the action components.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct ActionAttemptEvent(EntityUid User, bool Cancelled = false);
|
||||
|
||||
7
Content.Shared/Actions/Events/ActionGetEventEvent.cs
Normal file
7
Content.Shared/Actions/Events/ActionGetEventEvent.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Content.Shared.Actions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Raised on an action entity to get its event.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct ActionGetEventEvent(BaseActionEvent? Event = null);
|
||||
8
Content.Shared/Actions/Events/ActionSetEventEvent.cs
Normal file
8
Content.Shared/Actions/Events/ActionSetEventEvent.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Content.Shared.Actions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Raised on an action entity to have the event-holding component cast and set its event.
|
||||
/// If it was set successfully then <c>Handled</c> must be set to true.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct ActionSetEventEvent(BaseActionEvent Event, bool Handled = false);
|
||||
8
Content.Shared/Actions/Events/ActionSetTargetEvent.cs
Normal file
8
Content.Shared/Actions/Events/ActionSetTargetEvent.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Content.Shared.Actions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Raised on an action entity to set its event's target to an entity, if it makes sense.
|
||||
/// Does nothing for an instant action as it has no target.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct ActionSetTargetEvent(EntityUid Target, bool Handled = false);
|
||||
32
Content.Shared/Actions/Events/ActionValidateEvent.cs
Normal file
32
Content.Shared/Actions/Events/ActionValidateEvent.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
namespace Content.Shared.Actions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Raised on an action entity before being used to:
|
||||
/// 1. Make sure client is sending the correct kind of target (if any)
|
||||
/// 2. Do any validation on the target, if needed
|
||||
/// 3. Give the action system an event to raise on the performer, to actually do the action.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public struct ActionValidateEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// Request event the client sent.
|
||||
/// </summary>
|
||||
public RequestPerformActionEvent Input;
|
||||
|
||||
/// <summary>
|
||||
/// User trying to use the action.
|
||||
/// </summary>
|
||||
public EntityUid User;
|
||||
|
||||
/// <summary>
|
||||
/// Entity providing this action to the user, used for logging.
|
||||
/// </summary>
|
||||
public EntityUid Provider;
|
||||
|
||||
/// <summary>
|
||||
/// If set to true, the client sent invalid event data and this should be logged as an error.
|
||||
/// For functioning input that happens to not be allowed this should not be set, for example a range check.
|
||||
/// </summary>
|
||||
public bool Invalid;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
namespace Content.Shared.Actions.Events;
|
||||
|
||||
[ByRefEvent]
|
||||
public record struct GetActionDataEvent(BaseActionComponent? Action);
|
||||
@@ -1,4 +0,0 @@
|
||||
namespace Content.Shared.Actions.Events;
|
||||
|
||||
[ByRefEvent]
|
||||
public record struct ValidateActionEntityTargetEvent(EntityUid User, EntityUid Target, bool Cancelled = false);
|
||||
@@ -1,10 +0,0 @@
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Shared.Actions.Events;
|
||||
|
||||
[ByRefEvent]
|
||||
public record struct ValidateActionEntityWorldTargetEvent(
|
||||
EntityUid User,
|
||||
EntityUid? Target,
|
||||
EntityCoordinates? Coords,
|
||||
bool Cancelled = false);
|
||||
@@ -1,6 +0,0 @@
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Shared.Actions.Events;
|
||||
|
||||
[ByRefEvent]
|
||||
public record struct ValidateActionWorldTargetEvent(EntityUid User, EntityCoordinates Target, bool Cancelled = false);
|
||||
@@ -1,25 +0,0 @@
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Actions;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class InstantActionComponent : BaseActionComponent
|
||||
{
|
||||
public override BaseActionEvent? BaseEvent => Event;
|
||||
|
||||
/// <summary>
|
||||
/// The local-event to raise when this action is performed.
|
||||
/// </summary>
|
||||
[DataField("event")]
|
||||
[NonSerialized]
|
||||
public InstantActionEvent? Event;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class InstantActionComponentState : BaseActionComponentState
|
||||
{
|
||||
public InstantActionComponentState(InstantActionComponent component, IEntityManager entManager) : base(component, entManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,28 +0,0 @@
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Actions;
|
||||
|
||||
/// <summary>
|
||||
/// Used on action entities to define an action that triggers when targeting an entity coordinate.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class WorldTargetActionComponent : BaseTargetActionComponent
|
||||
{
|
||||
public override BaseActionEvent? BaseEvent => Event;
|
||||
|
||||
/// <summary>
|
||||
/// The local-event to raise when this action is performed.
|
||||
/// </summary>
|
||||
[DataField("event")]
|
||||
[NonSerialized]
|
||||
public WorldTargetActionEvent? Event;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class WorldTargetActionComponentState : BaseActionComponentState
|
||||
{
|
||||
public WorldTargetActionComponentState(WorldTargetActionComponent component, IEntityManager entManager) : base(component, entManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ public abstract class SharedBedSystem : EntitySystem
|
||||
|
||||
private void OnUnstrapped(Entity<HealOnBuckleComponent> bed, ref UnstrappedEvent args)
|
||||
{
|
||||
_actionsSystem.RemoveAction(args.Buckle, bed.Comp.SleepAction);
|
||||
_actionsSystem.RemoveAction(args.Buckle.Owner, bed.Comp.SleepAction);
|
||||
_sleepingSystem.TryWaking(args.Buckle.Owner);
|
||||
RemComp<HealOnBuckleHealingComponent>(bed);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.Buckle.Components;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Damage.Events;
|
||||
@@ -255,7 +256,7 @@ public sealed partial class SleepingSystem : EntitySystem
|
||||
private void Wake(Entity<SleepingComponent> ent)
|
||||
{
|
||||
RemComp<SleepingComponent>(ent);
|
||||
_actionsSystem.RemoveAction(ent, ent.Comp.WakeAction);
|
||||
_actionsSystem.RemoveAction(ent.Owner, ent.Comp.WakeAction);
|
||||
|
||||
var ev = new SleepStateChangedEvent(false);
|
||||
RaiseLocalEvent(ent, ref ev);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.Clothing.EntitySystems;
|
||||
using Content.Shared.Item.ItemToggle.Components;
|
||||
using Content.Shared.Toggleable;
|
||||
@@ -23,7 +23,7 @@ public sealed partial class ToggleClothingComponent : Component
|
||||
/// This must raise <see cref="ToggleActionEvent"/> to then get handled.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public EntProtoId<InstantActionComponent> Action = string.Empty;
|
||||
public EntProtoId<InstantActionComponent> Action;
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityUid? ActionEntity;
|
||||
|
||||
@@ -296,7 +296,7 @@ public sealed class ToggleableClothingSystem : EntitySystem
|
||||
}
|
||||
|
||||
if (_actionContainer.EnsureAction(uid, ref component.ActionEntity, out var action, component.Action))
|
||||
_actionsSystem.SetEntityIcon(component.ActionEntity.Value, component.ClothingUid, action);
|
||||
_actionsSystem.SetEntityIcon((component.ActionEntity.Value, action), component.ClothingUid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public sealed class EyeClosingSystem : EntitySystem
|
||||
|
||||
private void OnShutdown(Entity<EyeClosingComponent> eyelids, ref ComponentShutdown args)
|
||||
{
|
||||
_actionsSystem.RemoveAction(eyelids, eyelids.Comp.EyeToggleActionEntity);
|
||||
_actionsSystem.RemoveAction(eyelids.Owner, eyelids.Comp.EyeToggleActionEntity);
|
||||
|
||||
SetEyelids((eyelids.Owner, eyelids.Comp), false);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.IdentityManagement;
|
||||
@@ -73,23 +74,21 @@ public abstract partial class SharedItemRecallSystem : EntitySystem
|
||||
if (!Resolve(ent.Owner, ref ent.Comp, false))
|
||||
return;
|
||||
|
||||
if (!TryComp<InstantActionComponent>(ent.Comp.MarkedByAction, out var instantAction))
|
||||
if (_actions.GetAction(ent.Comp.MarkedByAction) is not {} action)
|
||||
return;
|
||||
|
||||
var actionOwner = instantAction.AttachedEntity;
|
||||
|
||||
if (actionOwner == null)
|
||||
if (action.Comp.AttachedEntity is not {} user)
|
||||
return;
|
||||
|
||||
if (TryComp<EmbeddableProjectileComponent>(ent, out var projectile))
|
||||
_proj.EmbedDetach(ent, projectile, actionOwner.Value);
|
||||
_proj.EmbedDetach(ent, projectile, user);
|
||||
|
||||
_popups.PopupPredicted(Loc.GetString("item-recall-item-summon-self", ("item", ent)),
|
||||
Loc.GetString("item-recall-item-summon-others", ("item", ent), ("name", Identity.Entity(actionOwner.Value, EntityManager))),
|
||||
actionOwner.Value, actionOwner.Value);
|
||||
_popups.PopupPredictedCoordinates(Loc.GetString("item-recall-item-disappear", ("item", ent)), Transform(ent).Coordinates, actionOwner.Value);
|
||||
Loc.GetString("item-recall-item-summon-others", ("item", ent), ("name", Identity.Entity(user, EntityManager))),
|
||||
user, user);
|
||||
_popups.PopupPredictedCoordinates(Loc.GetString("item-recall-item-disappear", ("item", ent)), Transform(ent).Coordinates, user);
|
||||
|
||||
_hands.TryForcePickupAnyHand(actionOwner.Value, ent);
|
||||
_hands.TryForcePickupAnyHand(user, ent);
|
||||
}
|
||||
|
||||
private void OnRecallMarkerShutdown(Entity<RecallMarkerComponent> ent, ref ComponentShutdown args)
|
||||
@@ -99,24 +98,22 @@ public abstract partial class SharedItemRecallSystem : EntitySystem
|
||||
|
||||
private void TryMarkItem(Entity<ItemRecallComponent> ent, EntityUid item)
|
||||
{
|
||||
if (!TryComp<InstantActionComponent>(ent, out var instantAction))
|
||||
if (_actions.GetAction(ent.Owner) is not {} action)
|
||||
return;
|
||||
|
||||
var actionOwner = instantAction.AttachedEntity;
|
||||
|
||||
if (actionOwner == null)
|
||||
if (action.Comp.AttachedEntity is not {} user)
|
||||
return;
|
||||
|
||||
AddToPvsOverride(item, actionOwner.Value);
|
||||
AddToPvsOverride(item, user);
|
||||
|
||||
var marker = AddComp<RecallMarkerComponent>(item);
|
||||
ent.Comp.MarkedEntity = item;
|
||||
Dirty(ent);
|
||||
|
||||
marker.MarkedByAction = ent.Owner;
|
||||
|
||||
UpdateActionAppearance(ent);
|
||||
var marker = AddComp<RecallMarkerComponent>(item);
|
||||
marker.MarkedByAction = ent;
|
||||
Dirty(item, marker);
|
||||
|
||||
UpdateActionAppearance((action, action, ent));
|
||||
}
|
||||
|
||||
private void TryUnmarkItem(EntityUid item)
|
||||
@@ -124,52 +121,47 @@ public abstract partial class SharedItemRecallSystem : EntitySystem
|
||||
if (!TryComp<RecallMarkerComponent>(item, out var marker))
|
||||
return;
|
||||
|
||||
if (!TryComp<InstantActionComponent>(marker.MarkedByAction, out var instantAction))
|
||||
if (_actions.GetAction(marker.MarkedByAction) is not {} action)
|
||||
return;
|
||||
|
||||
if (TryComp<ItemRecallComponent>(marker.MarkedByAction, out var action))
|
||||
if (TryComp<ItemRecallComponent>(action, out var itemRecall))
|
||||
{
|
||||
// For some reason client thinks the station grid owns the action on client and this doesn't work. It doesn't work in PopupEntity(mispredicts) and PopupPredicted either(doesnt show).
|
||||
// I don't have the heart to move this code to server because of this small thing.
|
||||
// This line will only do something once that is fixed.
|
||||
if (instantAction.AttachedEntity != null)
|
||||
if (action.Comp.AttachedEntity is {} user)
|
||||
{
|
||||
_popups.PopupClient(Loc.GetString("item-recall-item-unmark", ("item", item)), instantAction.AttachedEntity.Value, instantAction.AttachedEntity.Value, PopupType.MediumCaution);
|
||||
RemoveFromPvsOverride(item, instantAction.AttachedEntity.Value);
|
||||
_popups.PopupClient(Loc.GetString("item-recall-item-unmark", ("item", item)), user, user, PopupType.MediumCaution);
|
||||
RemoveFromPvsOverride(item, user);
|
||||
}
|
||||
|
||||
action.MarkedEntity = null;
|
||||
UpdateActionAppearance((marker.MarkedByAction.Value, action));
|
||||
Dirty(marker.MarkedByAction.Value, action);
|
||||
itemRecall.MarkedEntity = null;
|
||||
UpdateActionAppearance((action, action, itemRecall));
|
||||
Dirty(action, itemRecall);
|
||||
}
|
||||
|
||||
RemCompDeferred<RecallMarkerComponent>(item);
|
||||
}
|
||||
|
||||
private void UpdateActionAppearance(Entity<ItemRecallComponent> action)
|
||||
private void UpdateActionAppearance(Entity<ActionComponent, ItemRecallComponent> action)
|
||||
{
|
||||
if (!TryComp<InstantActionComponent>(action, out var instantAction))
|
||||
return;
|
||||
|
||||
if (action.Comp.MarkedEntity == null)
|
||||
if (action.Comp2.MarkedEntity is {} marked)
|
||||
{
|
||||
if (action.Comp.InitialName != null)
|
||||
_metaData.SetEntityName(action, action.Comp.InitialName);
|
||||
if (action.Comp.InitialDescription != null)
|
||||
_metaData.SetEntityDescription(action, action.Comp.InitialDescription);
|
||||
_actions.SetEntityIcon(action, null, instantAction);
|
||||
if (action.Comp2.WhileMarkedName is {} name)
|
||||
_metaData.SetEntityName(action, Loc.GetString(name, ("item", marked)));
|
||||
|
||||
if (action.Comp2.WhileMarkedDescription is {} desc)
|
||||
_metaData.SetEntityDescription(action, Loc.GetString(desc, ("item", marked)));
|
||||
|
||||
_actions.SetEntityIcon((action, action), marked);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (action.Comp.WhileMarkedName != null)
|
||||
_metaData.SetEntityName(action, Loc.GetString(action.Comp.WhileMarkedName,
|
||||
("item", action.Comp.MarkedEntity.Value)));
|
||||
|
||||
if (action.Comp.WhileMarkedDescription != null)
|
||||
_metaData.SetEntityDescription(action, Loc.GetString(action.Comp.WhileMarkedDescription,
|
||||
("item", action.Comp.MarkedEntity.Value)));
|
||||
|
||||
_actions.SetEntityIcon(action, action.Comp.MarkedEntity, instantAction);
|
||||
if (action.Comp2.InitialName is {} name)
|
||||
_metaData.SetEntityName(action, name);
|
||||
if (action.Comp2.InitialDescription is {} desc)
|
||||
_metaData.SetEntityDescription(action, desc);
|
||||
_actions.SetEntityIcon((action, action), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.Charges.Systems;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Interaction.Events;
|
||||
@@ -56,7 +57,7 @@ public sealed class SpellbookSystem : EntitySystem
|
||||
|
||||
if (!ent.Comp.LearnPermanently)
|
||||
{
|
||||
_actions.GrantActions(args.Args.User, ent.Comp.Spells, ent);
|
||||
_actions.GrantActions(args.Args.User, ent.Comp.Spells, ent.Owner);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Maps;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Mapping;
|
||||
|
||||
public sealed partial class StartPlacementActionEvent : InstantActionEvent
|
||||
{
|
||||
[DataField("entityType")]
|
||||
public string? EntityType;
|
||||
[DataField]
|
||||
public EntProtoId? EntityType;
|
||||
|
||||
[DataField("tileId")]
|
||||
public string? TileId;
|
||||
[DataField]
|
||||
public ProtoId<ContentTileDefinition>? TileId;
|
||||
|
||||
[DataField("placementOption")]
|
||||
[DataField]
|
||||
public string? PlacementOption;
|
||||
|
||||
[DataField("eraser")]
|
||||
[DataField]
|
||||
public bool Eraser;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Implants;
|
||||
using Content.Shared.Implants.Components;
|
||||
using Content.Shared.Mindshield.Components;
|
||||
@@ -28,7 +28,8 @@ public sealed class SharedFakeMindShieldImplantSystem : EntitySystem
|
||||
|
||||
if (!TryComp<FakeMindShieldComponent>(ent, out var comp))
|
||||
return;
|
||||
_actionsSystem.SetToggled(ev.Action, !comp.IsEnabled); // Set it to what the Mindshield component WILL be after this
|
||||
// TODO: is there a reason this cant set ev.Toggle = true;
|
||||
_actionsSystem.SetToggled((ev.Action, ev.Action), !comp.IsEnabled); // Set it to what the Mindshield component WILL be after this
|
||||
RaiseLocalEvent(ent, ev); //this reraises the action event to support an eventual future Changeling Antag which will also be using this component for it's "mindshield" ability
|
||||
}
|
||||
private void ImplantCheck(EntityUid uid, FakeMindShieldImplantComponent component ,ref ImplantImplantedEvent ev)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.Mobs.Components;
|
||||
|
||||
namespace Content.Shared.Mobs.Systems;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.Ninja.Systems;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.Ninja.Systems;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -22,7 +23,7 @@ public sealed partial class ItemCreatorComponent : Component
|
||||
/// The action id for creating an item.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public EntProtoId<InstantActionComponent> Action = string.Empty;
|
||||
public EntProtoId<InstantActionComponent> Action;
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityUid? ActionEntity;
|
||||
|
||||
@@ -30,7 +30,7 @@ public abstract class SharedPAISystem : EntitySystem
|
||||
|
||||
private void OnShutdown(Entity<PAIComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
_actions.RemoveAction(ent, ent.Comp.ShopAction);
|
||||
_actions.RemoveAction(ent.Owner, ent.Comp.ShopAction);
|
||||
}
|
||||
}
|
||||
public sealed partial class PAIShopActionEvent : InstantActionEvent
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Random;
|
||||
using Content.Shared.Random.Helpers;
|
||||
@@ -60,12 +61,13 @@ public abstract class SharedRatKingSystem : EntitySystem
|
||||
if (!TryComp(uid, out ActionsComponent? comp))
|
||||
return;
|
||||
|
||||
_action.RemoveAction(uid, component.ActionRaiseArmyEntity, comp);
|
||||
_action.RemoveAction(uid, component.ActionDomainEntity, comp);
|
||||
_action.RemoveAction(uid, component.ActionOrderStayEntity, comp);
|
||||
_action.RemoveAction(uid, component.ActionOrderFollowEntity, comp);
|
||||
_action.RemoveAction(uid, component.ActionOrderCheeseEmEntity, comp);
|
||||
_action.RemoveAction(uid, component.ActionOrderLooseEntity, comp);
|
||||
var actions = new Entity<ActionsComponent?>(uid, comp);
|
||||
_action.RemoveAction(actions, component.ActionRaiseArmyEntity);
|
||||
_action.RemoveAction(actions, component.ActionDomainEntity);
|
||||
_action.RemoveAction(actions, component.ActionOrderStayEntity);
|
||||
_action.RemoveAction(actions, component.ActionOrderFollowEntity);
|
||||
_action.RemoveAction(actions, component.ActionOrderCheeseEmEntity);
|
||||
_action.RemoveAction(actions, component.ActionOrderLooseEntity);
|
||||
}
|
||||
|
||||
private void OnOrderAction(EntityUid uid, RatKingComponent component, RatKingOrderActionEvent args)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Content.Shared.Movement.Components;
|
||||
@@ -56,7 +56,7 @@ public abstract class SharedBorgSwitchableTypeSystem : EntitySystem
|
||||
|
||||
private void OnShutdown(Entity<BorgSwitchableTypeComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
_actionsSystem.RemoveAction(ent, ent.Comp.SelectTypeAction);
|
||||
_actionsSystem.RemoveAction(ent.Owner, ent.Comp.SelectTypeAction);
|
||||
}
|
||||
|
||||
private void OnSelectBorgTypeAction(Entity<BorgSwitchableTypeComponent> ent, ref BorgToggleSelectTypeEvent args)
|
||||
@@ -90,7 +90,7 @@ public abstract class SharedBorgSwitchableTypeSystem : EntitySystem
|
||||
{
|
||||
ent.Comp.SelectedBorgType = borgType;
|
||||
|
||||
_actionsSystem.RemoveAction(ent, ent.Comp.SelectTypeAction);
|
||||
_actionsSystem.RemoveAction(ent.Owner, ent.Comp.SelectTypeAction);
|
||||
ent.Comp.SelectTypeAction = null;
|
||||
Dirty(ent);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.Destructible.Thresholds;
|
||||
using Content.Shared.EntityTable.EntitySelectors;
|
||||
using Content.Shared.Xenoarchaeology.Artifact.Prototypes;
|
||||
|
||||
Reference in New Issue
Block a user