From 718dba79865804a1a3fd508f3af5fcd5a5ba86eb Mon Sep 17 00:00:00 2001 From: Spatison <137375981+Spatison@users.noreply.github.com> Date: Mon, 28 Oct 2024 14:34:25 +0300 Subject: [PATCH 1/2] fix: waddle --- .../Movement/Systems/WaddleAnimationSystem.cs | 173 ------------------ .../Animations/WaddleAnimationSystem.cs | 100 ++++++++++ .../Animations/WaddleAnimationSystem.cs | 17 ++ .../Components/WaddleAnimationComponent.cs | 19 +- .../SharedWaddledAnimationSystem.cs | 51 ++++++ .../EntitySystems}/WaddleClothingSystem.cs | 2 +- 6 files changed, 180 insertions(+), 182 deletions(-) delete mode 100644 Content.Client/Movement/Systems/WaddleAnimationSystem.cs create mode 100644 Content.Client/_White/Animations/WaddleAnimationSystem.cs create mode 100644 Content.Server/_White/Animations/WaddleAnimationSystem.cs create mode 100644 Content.Shared/_White/Animations/SharedWaddledAnimationSystem.cs rename {Content.Client/Clothing/Systems => Content.Shared/_White/Clothing/EntitySystems}/WaddleClothingSystem.cs (95%) diff --git a/Content.Client/Movement/Systems/WaddleAnimationSystem.cs b/Content.Client/Movement/Systems/WaddleAnimationSystem.cs deleted file mode 100644 index 9555c1f6b9..0000000000 --- a/Content.Client/Movement/Systems/WaddleAnimationSystem.cs +++ /dev/null @@ -1,173 +0,0 @@ -using System.Numerics; -using Content.Client.Buckle; -using Content.Client.Gravity; -using Content.Shared.ActionBlocker; -using Content.Shared.Buckle.Components; -using Content.Shared.Mobs.Systems; -using Content.Shared.Movement.Components; -using Content.Shared.Movement.Events; -using Content.Shared.StatusEffect; -using Content.Shared.Stunnable; -using Robust.Client.Animations; -using Robust.Client.GameObjects; -using Robust.Shared.Animations; -using Robust.Shared.Timing; - -namespace Content.Client.Movement.Systems; - -public sealed class WaddleAnimationSystem : EntitySystem -{ - [Dependency] private readonly AnimationPlayerSystem _animation = default!; - [Dependency] private readonly GravitySystem _gravity = default!; - [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!; - [Dependency] private readonly BuckleSystem _buckle = default!; - [Dependency] private readonly MobStateSystem _mobState = default!; - - public override void Initialize() - { - SubscribeLocalEvent(OnMovementInput); - SubscribeLocalEvent(OnStartedWalking); - SubscribeLocalEvent(OnStoppedWalking); - SubscribeLocalEvent(OnAnimationCompleted); - SubscribeLocalEvent(OnStunned); - SubscribeLocalEvent(OnKnockedDown); - SubscribeLocalEvent(OnBuckleChange); - } - - private void OnMovementInput(EntityUid entity, WaddleAnimationComponent component, MoveInputEvent args) - { - // Prediction mitigation. Prediction means that MoveInputEvents are spammed repeatedly, even though you'd assume - // they're once-only for the user actually doing something. As such do nothing if we're just repeating this FoR. - if (!_timing.IsFirstTimePredicted) - { - return; - } - - if (!args.HasDirectionalMovement && component.IsCurrentlyWaddling) - { - var stopped = new StoppedWaddlingEvent(entity); - - RaiseLocalEvent(entity, ref stopped); - - return; - } - - // Only start waddling if we're not currently AND we're actually moving. - if (component.IsCurrentlyWaddling || !args.HasDirectionalMovement) - return; - - var started = new StartedWaddlingEvent(entity); - - RaiseLocalEvent(entity, ref started); - } - - private void OnStartedWalking(EntityUid uid, WaddleAnimationComponent component, StartedWaddlingEvent args) - { - if (_animation.HasRunningAnimation(uid, component.KeyName)) - return; - - if (!TryComp(uid, out var mover)) - return; - - if (_gravity.IsWeightless(uid)) - return; - - - if (!_actionBlocker.CanMove(uid, mover)) - return; - - // Do nothing if buckled in - if (_buckle.IsBuckled(uid)) - return; - - // Do nothing if crit or dead (for obvious reasons) - if (_mobState.IsIncapacitated(uid)) - return; - - var tumbleIntensity = component.LastStep ? 360 - component.TumbleIntensity : component.TumbleIntensity; - var len = mover.Sprinting ? component.AnimationLength * component.RunAnimationLengthMultiplier : component.AnimationLength; - - component.LastStep = !component.LastStep; - component.IsCurrentlyWaddling = true; - - var anim = new Animation() - { - Length = TimeSpan.FromSeconds(len), - AnimationTracks = - { - new AnimationTrackComponentProperty() - { - ComponentType = typeof(SpriteComponent), - Property = nameof(SpriteComponent.Rotation), - InterpolationMode = AnimationInterpolationMode.Linear, - KeyFrames = - { - new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(0), 0), - new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(tumbleIntensity), len/2), - new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(0), len/2), - } - }, - new AnimationTrackComponentProperty() - { - ComponentType = typeof(SpriteComponent), - Property = nameof(SpriteComponent.Offset), - InterpolationMode = AnimationInterpolationMode.Linear, - KeyFrames = - { - new AnimationTrackProperty.KeyFrame(new Vector2(), 0), - new AnimationTrackProperty.KeyFrame(component.HopIntensity, len/2), - new AnimationTrackProperty.KeyFrame(new Vector2(), len/2), - } - } - } - }; - - _animation.Play(uid, anim, component.KeyName); - } - - private void OnStoppedWalking(EntityUid uid, WaddleAnimationComponent component, StoppedWaddlingEvent args) - { - StopWaddling(uid, component); - } - - private void OnAnimationCompleted(EntityUid uid, WaddleAnimationComponent component, AnimationCompletedEvent args) - { - var started = new StartedWaddlingEvent(uid); - - RaiseLocalEvent(uid, ref started); - } - - private void OnStunned(EntityUid uid, WaddleAnimationComponent component, StunnedEvent args) - { - StopWaddling(uid, component); - } - - private void OnKnockedDown(EntityUid uid, WaddleAnimationComponent component, KnockedDownEvent args) - { - StopWaddling(uid, component); - } - - private void OnBuckleChange(EntityUid uid, WaddleAnimationComponent component, BuckleChangeEvent args) - { - StopWaddling(uid, component); - } - - private void StopWaddling(EntityUid uid, WaddleAnimationComponent component) - { - if (!component.IsCurrentlyWaddling) - return; - - _animation.Stop(uid, component.KeyName); - - if (!TryComp(uid, out var sprite)) - { - return; - } - - sprite.Offset = new Vector2(); - sprite.Rotation = Angle.FromDegrees(0); - - component.IsCurrentlyWaddling = false; - } -} diff --git a/Content.Client/_White/Animations/WaddleAnimationSystem.cs b/Content.Client/_White/Animations/WaddleAnimationSystem.cs new file mode 100644 index 0000000000..10c1dd59fc --- /dev/null +++ b/Content.Client/_White/Animations/WaddleAnimationSystem.cs @@ -0,0 +1,100 @@ +using System.Numerics; +using Content.Client.Buckle; +using Content.Client.Gravity; +using Content.Shared._White.Animations; +using Content.Shared.Movement.Components; +using Content.Shared.Standing; +using Robust.Client.Animations; +using Robust.Client.GameObjects; +using Robust.Shared.Animations; + +namespace Content.Client._White.Animations; + +public sealed class WaddleAnimationSystem : SharedWaddledAnimationSystem +{ + [Dependency] private readonly AnimationPlayerSystem _animation = default!; + [Dependency] private readonly StandingStateSystem _standingState = default!; + [Dependency] private readonly GravitySystem _gravity = default!; + [Dependency] private readonly BuckleSystem _buckle = default!; + + public override void Initialize() + { + SubscribeLocalEvent(OnAnimationCompleted); + + SubscribeAllEvent(ev => PlayAnimation(GetEntity(ev.User))); + SubscribeAllEvent(ev => StopAnimation(GetEntity(ev.User))); + } + + protected override void PlayAnimation(EntityUid uid) + { + if (!Timing.IsFirstTimePredicted + || !TryComp(uid, out var component) + || !TryComp(uid, out var mover) + || _animation.HasRunningAnimation(uid, component.KeyName) + || _standingState.IsDown(uid) + || _gravity.IsWeightless(uid) + || _buckle.IsBuckled(uid)) + return; + + var tumbleIntensity = component.LastStep ? 360 - component.TumbleIntensity : component.TumbleIntensity; + var len = mover.Sprinting ? component.AnimationLength * component.RunAnimationLengthMultiplier : component.AnimationLength; + + component.LastStep = !component.LastStep; + component.IsCurrentlyWaddling = true; + + var animation = new Animation() + { + Length = TimeSpan.FromSeconds(len), + AnimationTracks = + { + new AnimationTrackComponentProperty() + { + ComponentType = typeof(SpriteComponent), + Property = nameof(SpriteComponent.Rotation), + InterpolationMode = AnimationInterpolationMode.Linear, + KeyFrames = + { + new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(0), 0), + new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(tumbleIntensity), len/3), + new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(0), len/3), + } + }, + new AnimationTrackComponentProperty() + { + ComponentType = typeof(SpriteComponent), + Property = nameof(SpriteComponent.Offset), + InterpolationMode = AnimationInterpolationMode.Linear, + KeyFrames = + { + new AnimationTrackProperty.KeyFrame(new Vector2(), 0), + new AnimationTrackProperty.KeyFrame(component.HopIntensity, len/3), + new AnimationTrackProperty.KeyFrame(new Vector2(), len/3), + } + } + } + }; + + _animation.Play(uid, animation, component.KeyName); + } + + protected override void StopAnimation(EntityUid uid) + { + if (!TryComp(uid, out var component) + || !TryComp(uid, out var sprite)) + return; + + _animation.Stop(uid, component.KeyName); + + sprite.Offset = new Vector2(); + sprite.Rotation = Angle.FromDegrees(0); + component.IsCurrentlyWaddling = false; + } + + private void OnAnimationCompleted(EntityUid uid, WaddleAnimationComponent component, AnimationCompletedEvent args) + { + if (args.Key != component.KeyName) + return; + + PlayAnimation(uid); + } +} diff --git a/Content.Server/_White/Animations/WaddleAnimationSystem.cs b/Content.Server/_White/Animations/WaddleAnimationSystem.cs new file mode 100644 index 0000000000..d5b2ad06e1 --- /dev/null +++ b/Content.Server/_White/Animations/WaddleAnimationSystem.cs @@ -0,0 +1,17 @@ +using Content.Shared._White.Animations; +using Content.Shared.Movement.Components; + +namespace Content.Server._White.Animations; + +public sealed class WaddleAnimationSystem : SharedWaddledAnimationSystem +{ + protected override void PlayAnimation(EntityUid user) + { + RaiseNetworkEvent(new StartedWaddlingEvent(GetNetEntity(user))); + } + + protected override void StopAnimation(EntityUid user) + { + RaiseNetworkEvent(new StoppedWaddlingEvent(GetNetEntity(user))); + } +} diff --git a/Content.Shared/Movement/Components/WaddleAnimationComponent.cs b/Content.Shared/Movement/Components/WaddleAnimationComponent.cs index c43ef3042e..ef88f68b26 100644 --- a/Content.Shared/Movement/Components/WaddleAnimationComponent.cs +++ b/Content.Shared/Movement/Components/WaddleAnimationComponent.cs @@ -1,26 +1,29 @@ using System.Numerics; +using Robust.Shared.Serialization; namespace Content.Shared.Movement.Components; +// WD EDIT START /// /// Declares that an entity has started to waddle like a duck/clown. /// -/// The newly be-waddled. -[ByRefEvent] -public record struct StartedWaddlingEvent(EntityUid Entity) +/// The newly be-waddled. +[Serializable, NetSerializable] +public sealed class StartedWaddlingEvent(NetEntity user) : EntityEventArgs { - public EntityUid Entity = Entity; + public NetEntity User = user; } /// /// Declares that an entity has stopped waddling like a duck/clown. /// -/// The former waddle-er. -[ByRefEvent] -public record struct StoppedWaddlingEvent(EntityUid Entity) +/// The former waddle-er. +[Serializable, NetSerializable] +public sealed class StoppedWaddlingEvent(NetEntity user) : EntityEventArgs { - public EntityUid Entity = Entity; + public NetEntity User = user; } +// WD EDIT END /// /// Defines something as having a waddle animation when it moves. diff --git a/Content.Shared/_White/Animations/SharedWaddledAnimationSystem.cs b/Content.Shared/_White/Animations/SharedWaddledAnimationSystem.cs new file mode 100644 index 0000000000..039eadf1bd --- /dev/null +++ b/Content.Shared/_White/Animations/SharedWaddledAnimationSystem.cs @@ -0,0 +1,51 @@ +using Content.Shared.Buckle; +using Content.Shared.Gravity; +using Content.Shared.Movement.Components; +using Content.Shared.Movement.Events; +using Content.Shared.Standing; +using Robust.Shared.Timing; + +namespace Content.Shared._White.Animations; + +public abstract class SharedWaddledAnimationSystem : EntitySystem +{ + [Dependency] protected readonly IGameTiming Timing = default!; + [Dependency] private readonly StandingStateSystem _standingState = default!; + [Dependency] private readonly SharedGravitySystem _gravity = default!; + [Dependency] private readonly SharedBuckleSystem _buckle = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMovementInput); + } + + private void OnMovementInput(EntityUid uid, WaddleAnimationComponent component, MoveInputEvent args) + { + if (!Timing.IsFirstTimePredicted + || _standingState.IsDown(uid) + || _gravity.IsWeightless(uid) + || _buckle.IsBuckled(uid)) + return; + + if (!args.HasDirectionalMovement && component.IsCurrentlyWaddling) + { + component.IsCurrentlyWaddling = false; + StopAnimation(uid); + + return; + } + + if (component.IsCurrentlyWaddling || !args.HasDirectionalMovement) + return; + + component.IsCurrentlyWaddling = true; + + PlayAnimation(uid); + } + + protected abstract void PlayAnimation(EntityUid user); + + protected abstract void StopAnimation(EntityUid user); +} diff --git a/Content.Client/Clothing/Systems/WaddleClothingSystem.cs b/Content.Shared/_White/Clothing/EntitySystems/WaddleClothingSystem.cs similarity index 95% rename from Content.Client/Clothing/Systems/WaddleClothingSystem.cs rename to Content.Shared/_White/Clothing/EntitySystems/WaddleClothingSystem.cs index b8ac3c207b..175525611e 100644 --- a/Content.Client/Clothing/Systems/WaddleClothingSystem.cs +++ b/Content.Shared/_White/Clothing/EntitySystems/WaddleClothingSystem.cs @@ -2,7 +2,7 @@ using Content.Shared.Movement.Components; using Content.Shared.Inventory.Events; -namespace Content.Client.Clothing.Systems; +namespace Content.Shared._White.Clothing.EntitySystems; public sealed class WaddleClothingSystem : EntitySystem { From 67918ac8439237c94c5924d749db4703fd604d77 Mon Sep 17 00:00:00 2001 From: Spatison <137375981+Spatison@users.noreply.github.com> Date: Mon, 28 Oct 2024 15:41:55 +0300 Subject: [PATCH 2/2] tweak --- Content.Client/_White/Animations/WaddleAnimationSystem.cs | 2 +- Content.Server/_White/Animations/WaddleAnimationSystem.cs | 2 +- ...WaddledAnimationSystem.cs => SharedWaddleAnimationSystem.cs} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename Content.Shared/_White/Animations/{SharedWaddledAnimationSystem.cs => SharedWaddleAnimationSystem.cs} (95%) diff --git a/Content.Client/_White/Animations/WaddleAnimationSystem.cs b/Content.Client/_White/Animations/WaddleAnimationSystem.cs index 10c1dd59fc..eefe4668cc 100644 --- a/Content.Client/_White/Animations/WaddleAnimationSystem.cs +++ b/Content.Client/_White/Animations/WaddleAnimationSystem.cs @@ -10,7 +10,7 @@ namespace Content.Client._White.Animations; -public sealed class WaddleAnimationSystem : SharedWaddledAnimationSystem +public sealed class WaddleAnimationSystem : SharedWaddleAnimationSystem { [Dependency] private readonly AnimationPlayerSystem _animation = default!; [Dependency] private readonly StandingStateSystem _standingState = default!; diff --git a/Content.Server/_White/Animations/WaddleAnimationSystem.cs b/Content.Server/_White/Animations/WaddleAnimationSystem.cs index d5b2ad06e1..01e9f5c4b3 100644 --- a/Content.Server/_White/Animations/WaddleAnimationSystem.cs +++ b/Content.Server/_White/Animations/WaddleAnimationSystem.cs @@ -3,7 +3,7 @@ namespace Content.Server._White.Animations; -public sealed class WaddleAnimationSystem : SharedWaddledAnimationSystem +public sealed class WaddleAnimationSystem : SharedWaddleAnimationSystem { protected override void PlayAnimation(EntityUid user) { diff --git a/Content.Shared/_White/Animations/SharedWaddledAnimationSystem.cs b/Content.Shared/_White/Animations/SharedWaddleAnimationSystem.cs similarity index 95% rename from Content.Shared/_White/Animations/SharedWaddledAnimationSystem.cs rename to Content.Shared/_White/Animations/SharedWaddleAnimationSystem.cs index 039eadf1bd..72f111d60d 100644 --- a/Content.Shared/_White/Animations/SharedWaddledAnimationSystem.cs +++ b/Content.Shared/_White/Animations/SharedWaddleAnimationSystem.cs @@ -7,7 +7,7 @@ namespace Content.Shared._White.Animations; -public abstract class SharedWaddledAnimationSystem : EntitySystem +public abstract class SharedWaddleAnimationSystem : EntitySystem { [Dependency] protected readonly IGameTiming Timing = default!; [Dependency] private readonly StandingStateSystem _standingState = default!;