using Content.Shared.ActionBlocker;
using Content.Shared.Emoting;
using Content.Shared.Interaction.Events;
using Content.Shared.Item;
using Content.Shared.Movement.Events;
using Content.Shared.Movement.Pulling.Components;
using Content.Shared.Movement.Pulling.Events;
using Content.Shared.Movement.Pulling.Systems;
using Content.Shared.Speech;
using Content.Shared.Throwing;
namespace Content.Shared._Starlight.Actions.Stasis;
///
/// System that handles the freezing behavior of entities in stasis.
/// This system prevents entities with StasisFrozenComponent from performing most actions,
/// while still allowing them to use the exit stasis action.
///
public abstract class SharedStasisFrozenSystem : EntitySystem
{
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
[Dependency] private readonly PullingSystem _pulling = default!;
public override void Initialize()
{
base.Initialize();
// Block various actions and interactions
SubscribeLocalEvent(OnUseAttempt);
SubscribeLocalEvent(OnCancellableAttempt);
SubscribeLocalEvent(OnCancellableAttempt);
SubscribeLocalEvent(OnInteractAttempt);
SubscribeLocalEvent(OnStartup);
SubscribeLocalEvent(UpdateCanMove);
SubscribeLocalEvent(OnUpdateCanMove);
SubscribeLocalEvent(OnPullAttempt);
SubscribeLocalEvent(OnCancellableAttempt);
SubscribeLocalEvent(OnCancellableAttempt);
SubscribeLocalEvent(OnEmoteAttempt);
SubscribeLocalEvent(OnSpeakAttempt);
}
///
/// Handles use attempts, allowing only the exit stasis action to proceed.
///
private void OnUseAttempt(EntityUid uid, StasisFrozenComponent component, UseAttemptEvent args)
{
// If we get here, the entity with StasisFrozenComponent is trying to use an action
if (!TryComp(uid, out var stasisComponent))
{
args.Cancel();
return;
}
// Check if this is the exit stasis action
if (stasisComponent.ExitStasisActionEntity != null && args.Used == stasisComponent.ExitStasisActionEntity)
{
// Allow the exit stasis action to proceed
return;
}
args.Cancel();
}
///
/// Handles speech attempts, blocking them if the entity is muted.
///
private void OnSpeakAttempt(EntityUid uid, StasisFrozenComponent component, SpeakAttemptEvent args)
{
if (!component.Muted)
{
return;
}
args.Cancel();
}
///
/// Handles various cancellable attempts, blocking them all.
///
private void OnCancellableAttempt(EntityUid uid, StasisFrozenComponent component,
CancellableEntityEventArgs args)
{
args.Cancel();
}
///
/// Handles pull attempts, preventing the entity from being pulled.
///
private void OnPullAttempt(EntityUid uid, StasisFrozenComponent component, PullAttemptEvent args)
{
args.Cancelled = true;
}
///
/// Handles component startup, stopping any active pulls and updating movement state.
///
private void OnStartup(EntityUid uid, StasisFrozenComponent component, ComponentStartup args)
{
if (TryComp(uid, out var pullable))
{
_pulling.TryStopPull(uid, pullable);
}
UpdateCanMove(uid, component, args);
}
///
/// Handles movement update events, preventing movement while in stasis.
///
private void OnUpdateCanMove(EntityUid uid, StasisFrozenComponent component, UpdateCanMoveEvent args)
{
if (component.LifeStage > ComponentLifeStage.Running)
return;
args.Cancel();
}
///
/// Updates the entity's movement state.
///
private void UpdateCanMove(EntityUid uid, StasisFrozenComponent component, EntityEventArgs args)
{
_blocker.UpdateCanMove(uid);
}
///
/// Handles emote attempts, blocking them if the entity is muted.
///
private void OnEmoteAttempt(EntityUid uid, StasisFrozenComponent component, EmoteAttemptEvent args)
{
if (component.Muted)
{
args.Cancel();
}
}
///
/// Handles general interaction attempts, blocking them all except for skills.
///
private void OnInteractAttempt(Entity ent, ref InteractionAttemptEvent args)
{
// Check if this is a skill interaction
if (args.Target == null)
{
return;
}
// Block all other interactions
args.Cancelled = true;
}
}