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(OnComponentStartup); // Start moving possibilities SubscribeLocalEvent(OnMovementInput); SubscribeLocalEvent(OnStood); // Stop moving possibilities SubscribeLocalEvent((Entity ent, ref StunnedEvent _) => StopWaddling(ent)); SubscribeLocalEvent((Entity ent, ref DownedEvent _) => StopWaddling(ent)); SubscribeLocalEvent((Entity ent, ref BuckledEvent _) => StopWaddling(ent)); SubscribeLocalEvent((Entity ent, ref MobStateChangedEvent _) => StopWaddling(ent)); SubscribeLocalEvent(OnGravityChanged); } private void OnGravityChanged(Entity ent, ref GravityChangedEvent args) { if (!args.HasGravity) StopWaddling(ent); } private void OnComponentStartup(Entity ent, ref ComponentStartup args) { if (!TryComp(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 ent, ref MoveInputEvent args) { // Only start waddling if we're actually moving. SetWaddling(ent, args.HasDirectionalMovement); } private void OnStood(Entity ent, ref StoodEvent args) { if (!TryComp(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 ent) { SetWaddling(ent, false); } /// /// Enables or disables waddling for a entity, including the animation. /// Unless force is true, prevents dead people etc from waddling using . /// private void SetWaddling(Entity 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); } /// /// Returns true if an entity is allowed to waddle at all. /// 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; } /// /// Updates the waddling animation on the client. /// Does nothing on server. /// protected virtual void UpdateAnimation(Entity ent) { } }