diff --git a/Content.Shared/Movement/Components/MovementSoundComponent.cs b/Content.Shared/Movement/Components/MovementSoundComponent.cs new file mode 100644 index 0000000000..92a6974cc6 --- /dev/null +++ b/Content.Shared/Movement/Components/MovementSoundComponent.cs @@ -0,0 +1,20 @@ +using Robust.Shared.Audio; +using Robust.Shared.GameStates; + +namespace Content.Shared.Movement.Components; + +/// +/// Plays a sound whenever InputMover is running. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class MovementSoundComponent : Component +{ + /// + /// Sound to play when InputMover has inputs. + /// + [DataField(required: true), AutoNetworkedField] + public SoundSpecifier? Sound; + + [DataField, AutoNetworkedField] + public EntityUid? SoundEntity; +} diff --git a/Content.Shared/Movement/Systems/MovementSoundSystem.cs b/Content.Shared/Movement/Systems/MovementSoundSystem.cs new file mode 100644 index 0000000000..9a1146779f --- /dev/null +++ b/Content.Shared/Movement/Systems/MovementSoundSystem.cs @@ -0,0 +1,44 @@ +using Content.Shared.Movement.Components; +using Content.Shared.Movement.Events; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Timing; +using Robust.Shared.Utility; + +namespace Content.Shared.Movement.Systems; + +/// +/// Plays a sound on MoveInputEvent. +/// +public sealed class MovementSoundSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnMoveInput); + } + + private void OnMoveInput(Entity ent, ref MoveInputEvent args) + { + if (!_timing.IsFirstTimePredicted) + return; + + var oldMoving = (SharedMoverController.GetNormalizedMovement(args.OldMovement) & MoveButtons.AnyDirection) != MoveButtons.None; + var moving = (SharedMoverController.GetNormalizedMovement(args.Entity.Comp.HeldMoveButtons) & MoveButtons.AnyDirection) != MoveButtons.None; + + if (oldMoving == moving) + return; + + if (moving) + { + DebugTools.Assert(ent.Comp.SoundEntity == null); + ent.Comp.SoundEntity = _audio.PlayPredicted(ent.Comp.Sound, ent.Owner, ent.Owner)?.Entity; + } + else + { + ent.Comp.SoundEntity = _audio.Stop(ent.Comp.SoundEntity); + } + } +}