Cache CanMove (#7480)

This commit is contained in:
Leon Friedrich
2022-04-10 16:48:11 +12:00
committed by GitHub
parent 4135d9813b
commit 87eede8785
26 changed files with 218 additions and 109 deletions

View File

@@ -1,3 +1,4 @@
using Content.Shared.ActionBlocker;
using Content.Shared.Buckle.Components; using Content.Shared.Buckle.Components;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -9,6 +10,9 @@ namespace Content.Client.Buckle
[ComponentReference(typeof(SharedBuckleComponent))] [ComponentReference(typeof(SharedBuckleComponent))]
public sealed class BuckleComponent : SharedBuckleComponent public sealed class BuckleComponent : SharedBuckleComponent
{ {
[Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
private bool _buckled; private bool _buckled;
private int? _originalDrawDepth; private int? _originalDrawDepth;
@@ -30,7 +34,10 @@ namespace Content.Client.Buckle
_buckled = buckle.Buckled; _buckled = buckle.Buckled;
LastEntityBuckledTo = buckle.LastEntityBuckledTo; LastEntityBuckledTo = buckle.LastEntityBuckledTo;
DontCollide = buckle.DontCollide; DontCollide = buckle.DontCollide;
if (!IoCManager.Resolve<IEntityManager>().TryGetComponent(Owner, out SpriteComponent? ownerSprite))
_sysMan.GetEntitySystem<ActionBlockerSystem>().UpdateCanMove(Owner);
if (!_entMan.TryGetComponent(Owner, out SpriteComponent? ownerSprite))
{ {
return; return;
} }

View File

@@ -1,4 +1,5 @@
using Content.Shared.CharacterAppearance; using Content.Shared.ActionBlocker;
using Content.Shared.CharacterAppearance;
using Content.Shared.Cuffs.Components; using Content.Shared.Cuffs.Components;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Client.Graphics; using Robust.Client.Graphics;
@@ -17,6 +18,7 @@ namespace Content.Client.Cuffs.Components
private string? _currentRSI; private string? _currentRSI;
[Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState) public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
{ {
@@ -26,6 +28,7 @@ namespace Content.Client.Cuffs.Components
} }
CanStillInteract = cuffState.CanStillInteract; CanStillInteract = cuffState.CanStillInteract;
_sysMan.GetEntitySystem<ActionBlockerSystem>().UpdateCanMove(Owner);
if (_entityManager.TryGetComponent<SpriteComponent>(Owner, out var spriteComponent)) if (_entityManager.TryGetComponent<SpriteComponent>(Owner, out var spriteComponent))
{ {

View File

@@ -1,14 +1,10 @@
using Content.Server.AI.EntitySystems; using Content.Server.AI.EntitySystems;
using Content.Server.GameTicking; using Content.Server.GameTicking;
using Content.Shared.ActionBlocker;
using Content.Shared.Movement.Components; using Content.Shared.Movement.Components;
using Content.Shared.Roles; using Content.Shared.Roles;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.ViewVariables;
namespace Content.Server.AI.Components namespace Content.Server.AI.Components
{ {
@@ -19,6 +15,8 @@ namespace Content.Server.AI.Components
{ {
[DataField("logic")] private float _visionRadius = 8.0f; [DataField("logic")] private float _visionRadius = 8.0f;
public bool CanMove { get; set; } = true;
// TODO: Need to ECS a lot more of the AI first before we can ECS this // TODO: Need to ECS a lot more of the AI first before we can ECS this
/// <summary> /// <summary>
/// Whether the AI is actively iterated. /// Whether the AI is actively iterated.

View File

@@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using System.Runtime.ExceptionServices; using System.Runtime.ExceptionServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -8,17 +6,10 @@ using Content.Server.AI.Pathfinding;
using Content.Server.AI.Pathfinding.Pathfinders; using Content.Server.AI.Pathfinding.Pathfinders;
using Content.Server.CPUJob.JobQueues; using Content.Server.CPUJob.JobQueues;
using Content.Shared.Access.Systems; using Content.Shared.Access.Systems;
using Content.Shared.ActionBlocker;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Interaction.Helpers;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics; using Robust.Shared.Physics;
using Robust.Shared.Timing;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
namespace Content.Server.AI.Steering namespace Content.Server.AI.Steering
{ {
@@ -249,7 +240,7 @@ namespace Content.Server.AI.Steering
// Main optimisation to be done below is the redundant calls and adding more variables // Main optimisation to be done below is the redundant calls and adding more variables
if (Deleted(entity) || if (Deleted(entity) ||
!EntityManager.TryGetComponent(entity, out AiControllerComponent? controller) || !EntityManager.TryGetComponent(entity, out AiControllerComponent? controller) ||
!EntitySystem.Get<ActionBlockerSystem>().CanMove(entity) || !controller.CanMove ||
!EntityManager.GetComponent<TransformComponent>(entity).GridID.IsValid()) !EntityManager.GetComponent<TransformComponent>(entity).GridID.IsValid())
{ {
return SteeringStatus.NoPath; return SteeringStatus.NoPath;

View File

@@ -26,6 +26,7 @@ namespace Content.Server.Buckle.Components
public sealed class BuckleComponent : SharedBuckleComponent public sealed class BuckleComponent : SharedBuckleComponent
{ {
[Dependency] private readonly IEntityManager _entMan = default!; [Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IGameTiming _gameTiming = default!;
[DataField("size")] [DataField("size")]
@@ -63,7 +64,8 @@ namespace Content.Server.Buckle.Components
{ {
_buckledTo = value; _buckledTo = value;
_buckleTime = _gameTiming.CurTime; _buckleTime = _gameTiming.CurTime;
Dirty(); _sysMan.GetEntitySystem<ActionBlockerSystem>().UpdateCanMove(Owner);
Dirty(_entMan);
} }
} }

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Content.Server.DoAfter; using Content.Server.DoAfter;
using Content.Server.Hands.Components; using Content.Server.Hands.Components;
using Content.Shared.ActionBlocker;
using Content.Shared.Alert; using Content.Shared.Alert;
using Content.Shared.Cuffs.Components; using Content.Shared.Cuffs.Components;
using Content.Shared.Hands.EntitySystems; using Content.Shared.Hands.EntitySystems;
@@ -112,6 +113,7 @@ namespace Content.Server.Cuffs.Components
Container.Insert(handcuff); Container.Insert(handcuff);
CanStillInteract = _entMan.TryGetComponent(Owner, out HandsComponent? ownerHands) && ownerHands.Hands.Count() > CuffedHandCount; CanStillInteract = _entMan.TryGetComponent(Owner, out HandsComponent? ownerHands) && ownerHands.Hands.Count() > CuffedHandCount;
_sysMan.GetEntitySystem<ActionBlockerSystem>().UpdateCanMove(Owner);
OnCuffedStateChanged?.Invoke(); OnCuffedStateChanged?.Invoke();
UpdateAlert(); UpdateAlert();
@@ -267,6 +269,7 @@ namespace Content.Server.Cuffs.Components
} }
CanStillInteract = _entMan.TryGetComponent(Owner, out HandsComponent? handsComponent) && handsComponent.SortedHands.Count() > CuffedHandCount; CanStillInteract = _entMan.TryGetComponent(Owner, out HandsComponent? handsComponent) && handsComponent.SortedHands.Count() > CuffedHandCount;
_sysMan.GetEntitySystem<ActionBlockerSystem>().UpdateCanMove(Owner);
OnCuffedStateChanged?.Invoke(); OnCuffedStateChanged?.Invoke();
UpdateAlert(); UpdateAlert();
Dirty(); Dirty();

View File

@@ -7,9 +7,6 @@ using Content.Shared.MobState.Components;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Player; using Robust.Shared.Player;
namespace Content.Server.Cuffs namespace Content.Server.Cuffs
@@ -121,6 +118,7 @@ namespace Content.Server.Cuffs
if (dirty) if (dirty)
{ {
cuffable.CanStillInteract = handCount > cuffable.CuffedHandCount; cuffable.CanStillInteract = handCount > cuffable.CuffedHandCount;
_actionBlockerSystem.UpdateCanMove(cuffable.Owner);
cuffable.CuffedStateChanged(); cuffable.CuffedStateChanged();
Dirty(cuffable); Dirty(cuffable);
} }

View File

@@ -1,16 +1,11 @@
using Content.Shared.Examine; using Content.Shared.Examine;
using Content.Shared.PAI; using Content.Shared.PAI;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Content.Shared.Instruments;
using Content.Server.Popups; using Content.Server.Popups;
using Content.Server.Instruments; using Content.Server.Instruments;
using Content.Server.Ghost.Roles.Components; using Content.Server.Ghost.Roles.Components;
using Content.Server.Mind.Components; using Content.Server.Mind.Components;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.GameObjects;
using Robust.Shared.Localization;
using Robust.Shared.Player; using Robust.Shared.Player;
using Content.Shared.Actions; using Content.Shared.Actions;
using Content.Shared.Interaction.Events; using Content.Shared.Interaction.Events;
@@ -21,7 +16,6 @@ namespace Content.Server.PAI
{ {
[Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly InstrumentSystem _instrumentSystem = default!; [Dependency] private readonly InstrumentSystem _instrumentSystem = default!;
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -32,21 +26,6 @@ namespace Content.Server.PAI
SubscribeLocalEvent<PAIComponent, MindAddedMessage>(OnMindAdded); SubscribeLocalEvent<PAIComponent, MindAddedMessage>(OnMindAdded);
SubscribeLocalEvent<PAIComponent, MindRemovedMessage>(OnMindRemoved); SubscribeLocalEvent<PAIComponent, MindRemovedMessage>(OnMindRemoved);
SubscribeLocalEvent<PAIComponent, GetVerbsEvent<ActivationVerb>>(AddWipeVerb); SubscribeLocalEvent<PAIComponent, GetVerbsEvent<ActivationVerb>>(AddWipeVerb);
SubscribeLocalEvent<PAIComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<PAIComponent, ComponentShutdown>(OnShutdown);
}
private void OnStartup(EntityUid uid, PAIComponent component, ComponentStartup args)
{
if (component.MidiAction != null)
_actionsSystem.AddAction(uid, component.MidiAction, null);
}
private void OnShutdown(EntityUid uid, PAIComponent component, ComponentShutdown args)
{
if (component.MidiAction != null)
_actionsSystem.RemoveAction(uid, component.MidiAction);
} }
private void OnExamined(EntityUid uid, PAIComponent component, ExaminedEvent args) private void OnExamined(EntityUid uid, PAIComponent component, ExaminedEvent args)

View File

@@ -10,9 +10,6 @@ using Content.Shared.Shuttles;
using Content.Shared.Shuttles.Components; using Content.Shared.Shuttles.Components;
using Content.Shared.Tag; using Content.Shared.Tag;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -36,7 +33,6 @@ namespace Content.Server.Shuttles.EntitySystems
SubscribeLocalEvent<ShuttleConsoleComponent, PowerChangedEvent>(HandlePowerChange); SubscribeLocalEvent<ShuttleConsoleComponent, PowerChangedEvent>(HandlePowerChange);
SubscribeLocalEvent<ShuttleConsoleComponent, GetVerbsEvent<InteractionVerb>>(OnConsoleInteract); SubscribeLocalEvent<ShuttleConsoleComponent, GetVerbsEvent<InteractionVerb>>(OnConsoleInteract);
SubscribeLocalEvent<PilotComponent, ComponentShutdown>(HandlePilotShutdown);
SubscribeLocalEvent<PilotComponent, MoveEvent>(HandlePilotMove); SubscribeLocalEvent<PilotComponent, MoveEvent>(HandlePilotMove);
} }
@@ -177,8 +173,9 @@ namespace Content.Server.Shuttles.EntitySystems
AddPilot(args.User, component); AddPilot(args.User, component);
} }
private void HandlePilotShutdown(EntityUid uid, PilotComponent component, ComponentShutdown args) protected override void HandlePilotShutdown(EntityUid uid, PilotComponent component, ComponentShutdown args)
{ {
base.HandlePilotShutdown(uid, component, args);
RemovePilot(component); RemovePilot(component);
} }
@@ -206,6 +203,7 @@ namespace Content.Server.Shuttles.EntitySystems
entity.PopupMessage(Loc.GetString("shuttle-pilot-start")); entity.PopupMessage(Loc.GetString("shuttle-pilot-start"));
pilotComponent.Console = component; pilotComponent.Console = component;
ActionBlockerSystem.UpdateCanMove(entity);
pilotComponent.Position = EntityManager.GetComponent<TransformComponent>(entity).Coordinates; pilotComponent.Position = EntityManager.GetComponent<TransformComponent>(entity).Coordinates;
pilotComponent.Dirty(); pilotComponent.Dirty();
} }

View File

@@ -1,15 +1,14 @@
using Content.Shared.Body.Events; using Content.Shared.Body.Events;
using Content.Shared.DragDrop; using Content.Shared.DragDrop;
using Content.Shared.Emoting; using Content.Shared.Emoting;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Interaction.Events; using Content.Shared.Interaction.Events;
using Content.Shared.Inventory.Events;
using Content.Shared.Item; using Content.Shared.Item;
using Content.Shared.Movement; using Content.Shared.Movement;
using Content.Shared.Movement.Components;
using Content.Shared.Speech; using Content.Shared.Speech;
using Content.Shared.Throwing; using Content.Shared.Throwing;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.GameObjects;
namespace Content.Shared.ActionBlocker namespace Content.Shared.ActionBlocker
{ {
@@ -19,11 +18,34 @@ namespace Content.Shared.ActionBlocker
[UsedImplicitly] [UsedImplicitly]
public sealed class ActionBlockerSystem : EntitySystem public sealed class ActionBlockerSystem : EntitySystem
{ {
public bool CanMove(EntityUid uid) public override void Initialize()
{ {
var ev = new MovementAttemptEvent(uid); base.Initialize();
SubscribeLocalEvent<IMoverComponent, ComponentStartup>(OnMoverStartup);
}
private void OnMoverStartup(EntityUid uid, IMoverComponent component, ComponentStartup args)
{
UpdateCanMove(uid, component);
}
public bool CanMove(EntityUid uid, IMoverComponent? component = null)
{
return Resolve(uid, ref component, false) && component.CanMove;
}
public bool UpdateCanMove(EntityUid uid, IMoverComponent? component = null)
{
if (!Resolve(uid, ref component, false))
return false;
var ev = new UpdateCanMoveEvent(uid);
RaiseLocalEvent(uid, ev); RaiseLocalEvent(uid, ev);
if (component.CanMove == ev.Cancelled && component is Component comp)
Dirty(comp);
component.CanMove = !ev.Cancelled;
return !ev.Cancelled; return !ev.Cancelled;
} }

View File

@@ -1,3 +1,4 @@
using Content.Shared.ActionBlocker;
using Content.Shared.Interaction.Events; using Content.Shared.Interaction.Events;
using Content.Shared.Item; using Content.Shared.Item;
using Content.Shared.Movement; using Content.Shared.Movement;
@@ -7,6 +8,8 @@ namespace Content.Shared.Administration;
public sealed class AdminFrozenSystem : EntitySystem public sealed class AdminFrozenSystem : EntitySystem
{ {
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
@@ -14,7 +17,22 @@ public sealed class AdminFrozenSystem : EntitySystem
SubscribeLocalEvent<AdminFrozenComponent, UseAttemptEvent>((_, _, args) => args.Cancel()); SubscribeLocalEvent<AdminFrozenComponent, UseAttemptEvent>((_, _, args) => args.Cancel());
SubscribeLocalEvent<AdminFrozenComponent, PickupAttemptEvent>((_, _, args) => args.Cancel()); SubscribeLocalEvent<AdminFrozenComponent, PickupAttemptEvent>((_, _, args) => args.Cancel());
SubscribeLocalEvent<AdminFrozenComponent, ThrowAttemptEvent>((_, _, args) => args.Cancel()); SubscribeLocalEvent<AdminFrozenComponent, ThrowAttemptEvent>((_, _, args) => args.Cancel());
SubscribeLocalEvent<AdminFrozenComponent, MovementAttemptEvent>((_, _, args) => args.Cancel());
SubscribeLocalEvent<AdminFrozenComponent, InteractionAttemptEvent>((_, _, args) => args.Cancel()); SubscribeLocalEvent<AdminFrozenComponent, InteractionAttemptEvent>((_, _, args) => args.Cancel());
SubscribeLocalEvent<AdminFrozenComponent, ComponentStartup>(UpdateCanMove);
SubscribeLocalEvent<AdminFrozenComponent, ComponentShutdown>(UpdateCanMove);
SubscribeLocalEvent<AdminFrozenComponent, UpdateCanMoveEvent>(OnUpdateCanMove);
}
private void OnUpdateCanMove(EntityUid uid, AdminFrozenComponent component, UpdateCanMoveEvent args)
{
if (component.LifeStage > ComponentLifeStage.Running)
return;
args.Cancel();
}
private void UpdateCanMove(EntityUid uid, AdminFrozenComponent component, EntityEventArgs args)
{
_blocker.UpdateCanMove(uid);
} }
} }

View File

@@ -17,7 +17,7 @@ namespace Content.Shared.Buckle
SubscribeLocalEvent<SharedBuckleComponent, DownAttemptEvent>(HandleDown); SubscribeLocalEvent<SharedBuckleComponent, DownAttemptEvent>(HandleDown);
SubscribeLocalEvent<SharedBuckleComponent, StandAttemptEvent>(HandleStand); SubscribeLocalEvent<SharedBuckleComponent, StandAttemptEvent>(HandleStand);
SubscribeLocalEvent<SharedBuckleComponent, ThrowPushbackAttemptEvent>(HandleThrowPushback); SubscribeLocalEvent<SharedBuckleComponent, ThrowPushbackAttemptEvent>(HandleThrowPushback);
SubscribeLocalEvent<SharedBuckleComponent, MovementAttemptEvent>(HandleMove); SubscribeLocalEvent<SharedBuckleComponent, UpdateCanMoveEvent>(HandleMove);
SubscribeLocalEvent<SharedBuckleComponent, ChangeDirectionAttemptEvent>(OnBuckleChangeDirectionAttempt); SubscribeLocalEvent<SharedBuckleComponent, ChangeDirectionAttemptEvent>(OnBuckleChangeDirectionAttempt);
} }
@@ -27,8 +27,11 @@ namespace Content.Shared.Buckle
args.Cancel(); args.Cancel();
} }
private void HandleMove(EntityUid uid, SharedBuckleComponent component, MovementAttemptEvent args) private void HandleMove(EntityUid uid, SharedBuckleComponent component, UpdateCanMoveEvent args)
{ {
if (component.LifeStage > ComponentLifeStage.Running)
return;
if (component.Buckled) if (component.Buckled)
args.Cancel(); args.Cancel();
} }

View File

@@ -8,11 +8,14 @@ namespace Content.Shared.Climbing
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<SharedClimbingComponent, MovementAttemptEvent>(HandleMoveAttempt); SubscribeLocalEvent<SharedClimbingComponent, UpdateCanMoveEvent>(HandleMoveAttempt);
} }
private void HandleMoveAttempt(EntityUid uid, SharedClimbingComponent component, MovementAttemptEvent args) private void HandleMoveAttempt(EntityUid uid, SharedClimbingComponent component, UpdateCanMoveEvent args)
{ {
if (component.LifeStage > ComponentLifeStage.Running)
return;
if (component.OwnerIsTransitioning) if (component.OwnerIsTransitioning)
args.Cancel(); args.Cancel();
} }

View File

@@ -1,12 +1,8 @@
using System;
using Content.Shared.ActionBlocker; using Content.Shared.ActionBlocker;
using Content.Shared.Physics; using Content.Shared.Physics;
using Robust.Shared.GameObjects;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.IoC;
using Robust.Shared.Physics; using Robust.Shared.Physics;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
namespace Content.Shared.Climbing namespace Content.Shared.Climbing
{ {
@@ -14,6 +10,7 @@ namespace Content.Shared.Climbing
public abstract class SharedClimbingComponent : Component public abstract class SharedClimbingComponent : Component
{ {
[Dependency] private readonly IEntityManager _entMan = default!; [Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
protected bool IsOnClimbableThisFrame protected bool IsOnClimbableThisFrame
{ {
@@ -47,6 +44,8 @@ namespace Content.Shared.Climbing
{ {
physicsComponent.BodyType = BodyType.KinematicController; physicsComponent.BodyType = BodyType.KinematicController;
} }
_sysMan.GetEntitySystem<ActionBlockerSystem>().UpdateCanMove(Owner);
} }
} }

View File

@@ -1,9 +1,11 @@
using Content.Shared.ActionBlocker;
using Content.Shared.Cuffs.Components; using Content.Shared.Cuffs.Components;
using Content.Shared.DragDrop; using Content.Shared.DragDrop;
using Content.Shared.Interaction.Events; using Content.Shared.Interaction.Events;
using Content.Shared.Inventory.Events; using Content.Shared.Inventory.Events;
using Content.Shared.Item; using Content.Shared.Item;
using Content.Shared.Movement; using Content.Shared.Movement;
using Content.Shared.Physics.Pull;
using Content.Shared.Pulling.Components; using Content.Shared.Pulling.Components;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -11,20 +13,29 @@ namespace Content.Shared.Cuffs
{ {
public abstract class SharedCuffableSystem : EntitySystem public abstract class SharedCuffableSystem : EntitySystem
{ {
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<SharedCuffableComponent, StopPullingEvent>(HandleStopPull); SubscribeLocalEvent<SharedCuffableComponent, StopPullingEvent>(HandleStopPull);
SubscribeLocalEvent<SharedCuffableComponent, MovementAttemptEvent>(HandleMoveAttempt); SubscribeLocalEvent<SharedCuffableComponent, UpdateCanMoveEvent>(HandleMoveAttempt);
SubscribeLocalEvent<SharedCuffableComponent, UseAttemptEvent>(OnUseAttempt); SubscribeLocalEvent<SharedCuffableComponent, UseAttemptEvent>(OnUseAttempt);
SubscribeLocalEvent<SharedCuffableComponent, InteractionAttemptEvent>(OnInteractAttempt); SubscribeLocalEvent<SharedCuffableComponent, InteractionAttemptEvent>(OnInteractAttempt);
SubscribeLocalEvent<SharedCuffableComponent, IsEquippingAttemptEvent>(OnEquipAttempt); SubscribeLocalEvent<SharedCuffableComponent, IsEquippingAttemptEvent>(OnEquipAttempt);
SubscribeLocalEvent<SharedCuffableComponent, IsUnequippingAttemptEvent>(OnUnequipAttempt); SubscribeLocalEvent<SharedCuffableComponent, IsUnequippingAttemptEvent>(OnUnequipAttempt);
SubscribeLocalEvent<SharedCuffableComponent, DropAttemptEvent>(OnDropAttempt); SubscribeLocalEvent<SharedCuffableComponent, DropAttemptEvent>(OnDropAttempt);
SubscribeLocalEvent<SharedCuffableComponent, PickupAttemptEvent>(OnPickupAttempt); SubscribeLocalEvent<SharedCuffableComponent, PickupAttemptEvent>(OnPickupAttempt);
SubscribeLocalEvent<SharedCuffableComponent, PullMessage>(OnPull);
} }
private void HandleMoveAttempt(EntityUid uid, SharedCuffableComponent component, MovementAttemptEvent args) private void OnPull(EntityUid uid, SharedCuffableComponent component, PullMessage args)
{
if (!component.CanStillInteract)
_blocker.UpdateCanMove(uid);
}
private void HandleMoveAttempt(EntityUid uid, SharedCuffableComponent component, UpdateCanMoveEvent args)
{ {
if (component.CanStillInteract || !EntityManager.TryGetComponent(uid, out SharedPullableComponent? pullable) || !pullable.BeingPulled) if (component.CanStillInteract || !EntityManager.TryGetComponent(uid, out SharedPullableComponent? pullable) || !pullable.BeingPulled)
return; return;

View File

@@ -1,3 +1,4 @@
using Content.Shared.ActionBlocker;
using Content.Shared.Damage; using Content.Shared.Damage;
using Content.Shared.DragDrop; using Content.Shared.DragDrop;
using Content.Shared.Emoting; using Content.Shared.Emoting;
@@ -17,6 +18,8 @@ namespace Content.Shared.MobState.EntitySystems
{ {
public sealed class MobStateSystem : EntitySystem public sealed class MobStateSystem : EntitySystem
{ {
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
@@ -33,12 +36,17 @@ namespace Content.Shared.MobState.EntitySystems
SubscribeLocalEvent<MobStateComponent, PickupAttemptEvent>(OnPickupAttempt); SubscribeLocalEvent<MobStateComponent, PickupAttemptEvent>(OnPickupAttempt);
SubscribeLocalEvent<MobStateComponent, StartPullAttemptEvent>(OnStartPullAttempt); SubscribeLocalEvent<MobStateComponent, StartPullAttemptEvent>(OnStartPullAttempt);
SubscribeLocalEvent<MobStateComponent, DamageChangedEvent>(UpdateState); SubscribeLocalEvent<MobStateComponent, DamageChangedEvent>(UpdateState);
SubscribeLocalEvent<MobStateComponent, MovementAttemptEvent>(OnMoveAttempt); SubscribeLocalEvent<MobStateComponent, UpdateCanMoveEvent>(OnMoveAttempt);
SubscribeLocalEvent<MobStateComponent, StandAttemptEvent>(OnStandAttempt); SubscribeLocalEvent<MobStateComponent, StandAttemptEvent>(OnStandAttempt);
SubscribeLocalEvent<MobStateChangedEvent>(OnStateChanged);
// Note that there's no check for Down attempts because if a mob's in crit or dead, they can be downed... // Note that there's no check for Down attempts because if a mob's in crit or dead, they can be downed...
} }
#region ActionBlocker #region ActionBlocker
private void OnStateChanged(MobStateChangedEvent ev)
{
_blocker.UpdateCanMove(ev.Entity);
}
private void CheckAct(EntityUid uid, MobStateComponent component, CancellableEntityEventArgs args) private void CheckAct(EntityUid uid, MobStateComponent component, CancellableEntityEventArgs args)
{ {
@@ -118,7 +126,7 @@ namespace Content.Shared.MobState.EntitySystems
component.UpdateState(args.Damageable.TotalDamage); component.UpdateState(args.Damageable.TotalDamage);
} }
private void OnMoveAttempt(EntityUid uid, MobStateComponent component, MovementAttemptEvent args) private void OnMoveAttempt(EntityUid uid, MobStateComponent component, UpdateCanMoveEvent args)
{ {
switch (component.CurrentState) switch (component.CurrentState)
{ {

View File

@@ -1,4 +1,4 @@
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Maths; using Robust.Shared.Maths;
namespace Content.Shared.Movement.Components namespace Content.Shared.Movement.Components
@@ -22,6 +22,12 @@ namespace Content.Shared.Movement.Components
/// </summary> /// </summary>
bool Sprinting { get; } bool Sprinting { get; }
/// <summary>
/// Can the entity currently move. Avoids having to raise move-attempt events every time a player moves.
/// Note that this value will be overridden by the action blocker system, and shouldn't just be set directly.
/// </summary>
bool CanMove { get; set; }
Angle LastGridAngle { get; set; } Angle LastGridAngle { get; set; }
/// <summary> /// <summary>

View File

@@ -10,6 +10,7 @@ namespace Content.Shared.Movement.Components
public bool IgnorePaused => false; public bool IgnorePaused => false;
public float CurrentWalkSpeed => 0f; public float CurrentWalkSpeed => 0f;
public float CurrentSprintSpeed => 0f; public float CurrentSprintSpeed => 0f;
public bool CanMove { get; set; } = true;
public Angle LastGridAngle { get => Angle.Zero; set {} } public Angle LastGridAngle { get => Angle.Zero; set {} }

View File

@@ -1,14 +1,10 @@
using System; using System;
using Content.Shared.ActionBlocker;
using Content.Shared.CCVar; using Content.Shared.CCVar;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Players;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Robust.Shared.ViewVariables;
namespace Content.Shared.Movement.Components namespace Content.Shared.Movement.Components
{ {
@@ -63,6 +59,9 @@ namespace Content.Shared.Movement.Components
public bool Sprinting => !HasFlag(_heldMoveButtons, MoveButtons.Walk); public bool Sprinting => !HasFlag(_heldMoveButtons, MoveButtons.Walk);
[ViewVariables(VVAccess.ReadWrite)]
public bool CanMove { get; set; } = true;
/// <summary> /// <summary>
/// Calculated linear velocity direction of the entity. /// Calculated linear velocity direction of the entity.
/// </summary> /// </summary>
@@ -124,7 +123,7 @@ namespace Content.Shared.Movement.Components
{ {
base.Initialize(); base.Initialize();
Owner.EnsureComponentWarn<PhysicsComponent>(); Owner.EnsureComponentWarn<PhysicsComponent>();
LastGridAngle = IoCManager.Resolve<IEntityManager>().GetComponent<TransformComponent>(Owner).Parent?.WorldRotation ?? new Angle(0); LastGridAngle = _entityManager.GetComponent<TransformComponent>(Owner).Parent?.WorldRotation ?? new Angle(0);
} }
/// <summary> /// <summary>
@@ -200,12 +199,13 @@ namespace Content.Shared.Movement.Components
_heldMoveButtons = state.Buttons; _heldMoveButtons = state.Buttons;
_lastInputTick = GameTick.Zero; _lastInputTick = GameTick.Zero;
_lastInputSubTick = 0; _lastInputSubTick = 0;
CanMove = state.CanMove;
} }
} }
public override ComponentState GetComponentState() public override ComponentState GetComponentState()
{ {
return new MoverComponentState(_heldMoveButtons); return new MoverComponentState(_heldMoveButtons, CanMove);
} }
/// <summary> /// <summary>
@@ -244,10 +244,12 @@ namespace Content.Shared.Movement.Components
private sealed class MoverComponentState : ComponentState private sealed class MoverComponentState : ComponentState
{ {
public MoveButtons Buttons { get; } public MoveButtons Buttons { get; }
public readonly bool CanMove;
public MoverComponentState(MoveButtons buttons) public MoverComponentState(MoveButtons buttons, bool canMove)
{ {
Buttons = buttons; Buttons = buttons;
CanMove = canMove;
} }
} }

View File

@@ -1,14 +0,0 @@
using Robust.Shared.GameObjects;
namespace Content.Shared.Movement
{
public sealed class MovementAttemptEvent : CancellableEntityEventArgs
{
public MovementAttemptEvent(EntityUid uid)
{
Uid = uid;
}
public EntityUid Uid { get; }
}
}

View File

@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Content.Shared.ActionBlocker;
using Content.Shared.Audio; using Content.Shared.Audio;
using Content.Shared.CCVar; using Content.Shared.CCVar;
using Content.Shared.Friction; using Content.Shared.Friction;
@@ -27,7 +26,6 @@ namespace Content.Shared.Movement
{ {
[Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!;
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
[Dependency] private readonly InventorySystem _inventory = default!; [Dependency] private readonly InventorySystem _inventory = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly TagSystem _tags = default!; [Dependency] private readonly TagSystem _tags = default!;
@@ -114,7 +112,7 @@ namespace Content.Shared.Movement
{ {
DebugTools.Assert(!UsedMobMovement.ContainsKey(mover.Owner)); DebugTools.Assert(!UsedMobMovement.ContainsKey(mover.Owner));
if (!UseMobMovement(physicsComponent)) if (!UseMobMovement(mover, physicsComponent))
{ {
UsedMobMovement[mover.Owner] = false; UsedMobMovement[mover.Owner] = false;
return; return;
@@ -184,13 +182,13 @@ namespace Content.Shared.Movement
return UsedMobMovement.TryGetValue(uid, out var used) && used; return UsedMobMovement.TryGetValue(uid, out var used) && used;
} }
protected bool UseMobMovement(PhysicsComponent body) protected bool UseMobMovement(IMoverComponent mover, PhysicsComponent body)
{ {
return body.BodyStatus == BodyStatus.OnGround && return mover.CanMove &&
EntityManager.HasComponent<MobStateComponent>(body.Owner) && body.BodyStatus == BodyStatus.OnGround &&
HasComp<MobStateComponent>(body.Owner) &&
// If we're being pulled then don't mess with our velocity. // If we're being pulled then don't mess with our velocity.
(!EntityManager.TryGetComponent(body.Owner, out SharedPullableComponent? pullable) || !pullable.BeingPulled) && (!TryComp(body.Owner, out SharedPullableComponent? pullable) || !pullable.BeingPulled);
_blocker.CanMove((body).Owner);
} }
/// <summary> /// <summary>

View File

@@ -0,0 +1,17 @@
using Content.Shared.Movement.Components;
namespace Content.Shared.Movement;
/// <summary>
/// Raised whenever <see cref="IMoverComponent.CanMove"/> needs to be updated. Cancel this event to prevent a
/// mover from moving.
/// </summary>
public sealed class UpdateCanMoveEvent : CancellableEntityEventArgs
{
public UpdateCanMoveEvent(EntityUid uid)
{
Uid = uid;
}
public EntityUid Uid { get; }
}

View File

@@ -1,9 +1,9 @@
using System; using Content.Shared.ActionBlocker;
using Content.Shared.Actions;
using Content.Shared.DragDrop; using Content.Shared.DragDrop;
using Content.Shared.Interaction.Events; using Content.Shared.Interaction.Events;
using Content.Shared.Item; using Content.Shared.Item;
using Content.Shared.Movement; using Content.Shared.Movement;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
namespace Content.Shared.PAI namespace Content.Shared.PAI
@@ -19,6 +19,9 @@ namespace Content.Shared.PAI
/// </summary> /// </summary>
public abstract class SharedPAISystem : EntitySystem public abstract class SharedPAISystem : EntitySystem
{ {
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
@@ -26,12 +29,32 @@ namespace Content.Shared.PAI
SubscribeLocalEvent<PAIComponent, InteractionAttemptEvent>(OnInteractAttempt); SubscribeLocalEvent<PAIComponent, InteractionAttemptEvent>(OnInteractAttempt);
SubscribeLocalEvent<PAIComponent, DropAttemptEvent>(OnDropAttempt); SubscribeLocalEvent<PAIComponent, DropAttemptEvent>(OnDropAttempt);
SubscribeLocalEvent<PAIComponent, PickupAttemptEvent>(OnPickupAttempt); SubscribeLocalEvent<PAIComponent, PickupAttemptEvent>(OnPickupAttempt);
SubscribeLocalEvent<PAIComponent, MovementAttemptEvent>(OnMoveAttempt); SubscribeLocalEvent<PAIComponent, UpdateCanMoveEvent>(OnMoveAttempt);
SubscribeLocalEvent<PAIComponent, ChangeDirectionAttemptEvent>(OnChangeDirectionAttempt); SubscribeLocalEvent<PAIComponent, ChangeDirectionAttemptEvent>(OnChangeDirectionAttempt);
SubscribeLocalEvent<PAIComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<PAIComponent, ComponentShutdown>(OnShutdown);
} }
private void OnMoveAttempt(EntityUid uid, PAIComponent component, MovementAttemptEvent args) private void OnStartup(EntityUid uid, PAIComponent component, ComponentStartup args)
{ {
_blocker.UpdateCanMove(uid);
if (component.MidiAction != null)
_actionsSystem.AddAction(uid, component.MidiAction, null);
}
private void OnShutdown(EntityUid uid, PAIComponent component, ComponentShutdown args)
{
_blocker.UpdateCanMove(uid);
if (component.MidiAction != null)
_actionsSystem.RemoveAction(uid, component.MidiAction);
}
private void OnMoveAttempt(EntityUid uid, PAIComponent component, UpdateCanMoveEvent args)
{
if (component.LifeStage > ComponentLifeStage.Running)
return;
args.Cancel(); // no more scurrying around on lil robot legs. args.Cancel(); // no more scurrying around on lil robot legs.
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using Content.Shared.ActionBlocker;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.IoC; using Robust.Shared.IoC;
@@ -16,6 +17,9 @@ namespace Content.Shared.Shuttles.Components
[NetworkedComponent] [NetworkedComponent]
public sealed class PilotComponent : Component public sealed class PilotComponent : Component
{ {
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
[Dependency] private readonly IEntityManager _entMan = default!;
[ViewVariables] public SharedShuttleConsoleComponent? Console { get; set; } [ViewVariables] public SharedShuttleConsoleComponent? Console { get; set; }
/// <summary> /// <summary>
@@ -37,15 +41,14 @@ namespace Content.Shared.Shuttles.Components
return; return;
} }
var entityManager = IoCManager.Resolve<IEntityManager>(); if (!_entMan.TryGetComponent(console, out SharedShuttleConsoleComponent? shuttleConsoleComponent))
if (!entityManager.TryGetComponent(console, out SharedShuttleConsoleComponent? shuttleConsoleComponent))
{ {
Logger.Warning($"Unable to set Helmsman console to {console}"); Logger.Warning($"Unable to set Helmsman console to {console}");
return; return;
} }
Console = shuttleConsoleComponent; Console = shuttleConsoleComponent;
_sysMan.GetEntitySystem<ActionBlockerSystem>().UpdateCanMove(Owner);
} }
public override ComponentState GetComponentState() public override ComponentState GetComponentState()

View File

@@ -1,19 +1,36 @@
using Content.Shared.ActionBlocker;
using Content.Shared.Movement; using Content.Shared.Movement;
using Content.Shared.Shuttles.Components; using Content.Shared.Shuttles.Components;
using Robust.Shared.GameObjects;
namespace Content.Shared.Shuttles namespace Content.Shared.Shuttles
{ {
public abstract class SharedShuttleConsoleSystem : EntitySystem public abstract class SharedShuttleConsoleSystem : EntitySystem
{ {
[Dependency] protected readonly ActionBlockerSystem ActionBlockerSystem = default!;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<PilotComponent, MovementAttemptEvent>(HandleMovementBlock); SubscribeLocalEvent<PilotComponent, UpdateCanMoveEvent>(HandleMovementBlock);
SubscribeLocalEvent<PilotComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<PilotComponent, ComponentShutdown>(HandlePilotShutdown);
} }
private void HandleMovementBlock(EntityUid uid, PilotComponent component, MovementAttemptEvent args) protected virtual void HandlePilotShutdown(EntityUid uid, PilotComponent component, ComponentShutdown args)
{ {
ActionBlockerSystem.UpdateCanMove(uid);
}
private void OnStartup(EntityUid uid, PilotComponent component, ComponentStartup args)
{
ActionBlockerSystem.UpdateCanMove(uid);
}
private void HandleMovementBlock(EntityUid uid, PilotComponent component, UpdateCanMoveEvent args)
{
if (component.LifeStage > ComponentLifeStage.Running)
return;
if (component.Console == null) return; if (component.Console == null) return;
args.Cancel(); args.Cancel();
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using Content.Shared.ActionBlocker;
using Content.Shared.Audio; using Content.Shared.Audio;
using Content.Shared.DragDrop; using Content.Shared.DragDrop;
using Content.Shared.Interaction; using Content.Shared.Interaction;
@@ -25,6 +26,7 @@ namespace Content.Shared.Stunnable
[UsedImplicitly] [UsedImplicitly]
public abstract class SharedStunSystem : EntitySystem public abstract class SharedStunSystem : EntitySystem
{ {
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
[Dependency] private readonly StandingStateSystem _standingStateSystem = default!; [Dependency] private readonly StandingStateSystem _standingStateSystem = default!;
[Dependency] private readonly StatusEffectsSystem _statusEffectSystem = default!; [Dependency] private readonly StatusEffectsSystem _statusEffectSystem = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!; [Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!;
@@ -37,6 +39,9 @@ namespace Content.Shared.Stunnable
SubscribeLocalEvent<SlowedDownComponent, ComponentInit>(OnSlowInit); SubscribeLocalEvent<SlowedDownComponent, ComponentInit>(OnSlowInit);
SubscribeLocalEvent<SlowedDownComponent, ComponentRemove>(OnSlowRemove); SubscribeLocalEvent<SlowedDownComponent, ComponentRemove>(OnSlowRemove);
SubscribeLocalEvent<StunnedComponent, ComponentStartup>(UpdateCanMove);
SubscribeLocalEvent<StunnedComponent, ComponentShutdown>(UpdateCanMove);
SubscribeLocalEvent<SlowedDownComponent, ComponentGetState>(OnSlowGetState); SubscribeLocalEvent<SlowedDownComponent, ComponentGetState>(OnSlowGetState);
SubscribeLocalEvent<SlowedDownComponent, ComponentHandleState>(OnSlowHandleState); SubscribeLocalEvent<SlowedDownComponent, ComponentHandleState>(OnSlowHandleState);
@@ -48,7 +53,7 @@ namespace Content.Shared.Stunnable
SubscribeLocalEvent<SlowedDownComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovespeed); SubscribeLocalEvent<SlowedDownComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovespeed);
// Attempt event subscriptions. // Attempt event subscriptions.
SubscribeLocalEvent<StunnedComponent, MovementAttemptEvent>(OnMoveAttempt); SubscribeLocalEvent<StunnedComponent, UpdateCanMoveEvent>(OnMoveAttempt);
SubscribeLocalEvent<StunnedComponent, InteractionAttemptEvent>(OnInteractAttempt); SubscribeLocalEvent<StunnedComponent, InteractionAttemptEvent>(OnInteractAttempt);
SubscribeLocalEvent<StunnedComponent, UseAttemptEvent>(OnUseAttempt); SubscribeLocalEvent<StunnedComponent, UseAttemptEvent>(OnUseAttempt);
SubscribeLocalEvent<StunnedComponent, ThrowAttemptEvent>(OnThrowAttempt); SubscribeLocalEvent<StunnedComponent, ThrowAttemptEvent>(OnThrowAttempt);
@@ -58,6 +63,11 @@ namespace Content.Shared.Stunnable
SubscribeLocalEvent<StunnedComponent, IsUnequippingAttemptEvent>(OnUnequipAttempt); SubscribeLocalEvent<StunnedComponent, IsUnequippingAttemptEvent>(OnUnequipAttempt);
} }
private void UpdateCanMove(EntityUid uid, StunnedComponent component, EntityEventArgs args)
{
_blocker.UpdateCanMove(uid);
}
private void OnSlowGetState(EntityUid uid, SlowedDownComponent component, ref ComponentGetState args) private void OnSlowGetState(EntityUid uid, SlowedDownComponent component, ref ComponentGetState args)
{ {
args.State = new SlowedDownComponentState(component.SprintSpeedModifier, component.WalkSpeedModifier); args.State = new SlowedDownComponentState(component.SprintSpeedModifier, component.WalkSpeedModifier);
@@ -205,8 +215,11 @@ namespace Content.Shared.Stunnable
#region Attempt Event Handling #region Attempt Event Handling
private void OnMoveAttempt(EntityUid uid, StunnedComponent stunned, MovementAttemptEvent args) private void OnMoveAttempt(EntityUid uid, StunnedComponent stunned, UpdateCanMoveEvent args)
{ {
if (stunned.LifeStage > ComponentLifeStage.Running)
return;
args.Cancel(); args.Cancel();
} }