6
StarHorizon_Public/Content.Shared/_DV/Waddle/SharedWaddleAnimationSystem.cs
2025-11-03 10:15:18 +03:00

129 lines
4.9 KiB
C#

using Content.Shared.ActionBlocker;
using Content.Shared.Buckle;
using Content.Shared.Buckle.Components;
using Content.Shared.Gravity;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Systems;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Events;
using Content.Shared.Movement.Systems;
using Content.Shared.Standing;
using Content.Shared.Stunnable;
using Robust.Shared.Timing;
namespace Content.Shared._DV.Waddle;
public abstract class SharedWaddleAnimationSystem : EntitySystem
{
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly MobStateSystem _mob = default!;
[Dependency] private readonly SharedBuckleSystem _buckle = default!;
[Dependency] private readonly SharedGravitySystem _gravity = default!;
[Dependency] private readonly StandingStateSystem _standing = default!;
public override void Initialize()
{
// Startup
SubscribeLocalEvent<WaddleAnimationComponent, ComponentStartup>(OnComponentStartup);
// Start moving possibilities
SubscribeLocalEvent<WaddleAnimationComponent, MoveInputEvent>(OnMovementInput);
SubscribeLocalEvent<WaddleAnimationComponent, StoodEvent>(OnStood);
// Stop moving possibilities
SubscribeLocalEvent((Entity<WaddleAnimationComponent> ent, ref StunnedEvent _) => StopWaddling(ent));
SubscribeLocalEvent((Entity<WaddleAnimationComponent> ent, ref DownedEvent _) => StopWaddling(ent));
SubscribeLocalEvent((Entity<WaddleAnimationComponent> ent, ref BuckledEvent _) => StopWaddling(ent));
SubscribeLocalEvent((Entity<WaddleAnimationComponent> ent, ref MobStateChangedEvent _) => StopWaddling(ent));
SubscribeLocalEvent<WaddleAnimationComponent, GravityChangedEvent>(OnGravityChanged);
}
private void OnGravityChanged(Entity<WaddleAnimationComponent> ent, ref GravityChangedEvent args)
{
if (!args.HasGravity)
StopWaddling(ent);
}
private void OnComponentStartup(Entity<WaddleAnimationComponent> ent, ref ComponentStartup args)
{
if (!TryComp<InputMoverComponent>(ent, out var mover))
return;
// If the waddler is currently moving, make them start waddling
if ((mover.HeldMoveButtons & MoveButtons.AnyDirection) != MoveButtons.None)
SetWaddling(ent, true);
}
private void OnMovementInput(Entity<WaddleAnimationComponent> ent, ref MoveInputEvent args)
{
// Only start waddling if we're actually moving.
SetWaddling(ent, args.HasDirectionalMovement);
}
private void OnStood(Entity<WaddleAnimationComponent> ent, ref StoodEvent args)
{
if (!TryComp<InputMoverComponent>(ent, out var mover))
return;
// only resume waddling if they are trying to move
if ((mover.HeldMoveButtons & MoveButtons.AnyDirection) == MoveButtons.None)
return;
SetWaddling(ent, true);
}
private void StopWaddling(Entity<WaddleAnimationComponent> ent)
{
SetWaddling(ent, false);
}
/// <summary>
/// Enables or disables waddling for a entity, including the animation.
/// Unless force is true, prevents dead people etc from waddling using <see cref="CanWaddle"/>.
/// </summary>
private void SetWaddling(Entity<WaddleAnimationComponent> ent, bool waddling, bool force = false) // imp edit, made private
{
// it makes your sprite rotation stutter when moving, bad
if (!_timing.IsFirstTimePredicted)
return;
if (waddling && !force && !CanWaddle(ent))
waddling = false;
if (ent.Comp.IsWaddling == waddling)
return;
ent.Comp.IsWaddling = waddling;
DirtyField(ent, ent.Comp, nameof(WaddleAnimationComponent.IsWaddling));
UpdateAnimation(ent);
}
/// <summary>
/// Returns true if an entity is allowed to waddle at all.
/// </summary>
private bool CanWaddle(EntityUid uid) // imp edit, made private
{
// can't waddle when dead
return _mob.IsAlive(uid) &&
// bouncy shoes should make you spin in 0G really but definitely not bounce up and down
!_gravity.IsWeightless(uid) &&
// can't waddle if your legs are broken etc
_actionBlocker.CanMove(uid) &&
// can't waddle when buckled, if you are really strong/on meth the chair/bed should waddle instead
!_buckle.IsBuckled(uid) &&
// animation doesn't take being downed into account :(
!_standing.IsDown(uid) &&
// can't waddle in space... 1984
Transform(uid).GridUid != null;
}
/// <summary>
/// Updates the waddling animation on the client.
/// Does nothing on server.
/// </summary>
protected virtual void UpdateAnimation(Entity<WaddleAnimationComponent> ent)
{
}
}