From 6bf24e748bf1aa6a4d8ecc07737e22078d64b5ad Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Fri, 11 Mar 2022 14:56:43 +1100 Subject: [PATCH] Revert "Predicted footstep sounds" (#7068) --- Content.Client/Entry/IgnoredComponents.cs | 1 + .../Physics/Controllers/MoverController.cs | 15 +- .../Components/FootstepModifierComponent.cs | 28 ++++ .../Physics/Controllers/MoverController.cs | 149 +++++++++++++++--- Content.Shared/CCVar/CCVars.cs | 4 + .../Components/FootstepModifierComponent.cs | 17 -- .../Movement/SharedMoverController.cs | 122 ++------------ Content.Shared/Tag/TagSystem.cs | 9 -- 8 files changed, 177 insertions(+), 168 deletions(-) create mode 100644 Content.Server/Movement/Components/FootstepModifierComponent.cs delete mode 100644 Content.Shared/Movement/Components/FootstepModifierComponent.cs diff --git a/Content.Client/Entry/IgnoredComponents.cs b/Content.Client/Entry/IgnoredComponents.cs index 5e0c0a5de8..3667507aa0 100644 --- a/Content.Client/Entry/IgnoredComponents.cs +++ b/Content.Client/Entry/IgnoredComponents.cs @@ -23,6 +23,7 @@ namespace Content.Client.Entry "EmitSoundOnLand", "NameIdentifier", "EmitSoundOnActivate", + "FootstepModifier", "HeatResistance", "EntityStorage", "MeleeWeapon", diff --git a/Content.Client/Physics/Controllers/MoverController.cs b/Content.Client/Physics/Controllers/MoverController.cs index db1bd3d1cf..91d1735d39 100644 --- a/Content.Client/Physics/Controllers/MoverController.cs +++ b/Content.Client/Physics/Controllers/MoverController.cs @@ -3,16 +3,15 @@ using Content.Shared.Movement; using Content.Shared.Movement.Components; using Content.Shared.Pulling.Components; using Robust.Client.Player; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Physics; -using Robust.Shared.Player; -using Robust.Shared.Timing; namespace Content.Client.Physics.Controllers { public sealed class MoverController : SharedMoverController { - [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; public override void UpdateBeforeSolve(bool prediction, float frameTime) @@ -77,15 +76,5 @@ namespace Content.Client.Physics.Controllers HandleKinematicMovement(mover, body); } - - protected override Filter GetSoundPlayers(EntityUid mover) - { - return Filter.Local(); - } - - protected override bool CanSound() - { - return _timing.IsFirstTimePredicted; - } } } diff --git a/Content.Server/Movement/Components/FootstepModifierComponent.cs b/Content.Server/Movement/Components/FootstepModifierComponent.cs new file mode 100644 index 0000000000..1e83eeb6b6 --- /dev/null +++ b/Content.Server/Movement/Components/FootstepModifierComponent.cs @@ -0,0 +1,28 @@ +using Content.Shared.Audio; +using Content.Shared.Sound; +using Robust.Shared.Audio; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Player; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Server.Movement.Components +{ + /// + /// Changes footstep sound + /// + [RegisterComponent] + public sealed class FootstepModifierComponent : Component + { + [DataField("footstepSoundCollection", required: true)] + public SoundSpecifier SoundCollection = default!; + + [DataField("variation")] + public float Variation = default; + + public void PlayFootstep() + { + SoundSystem.Play(Filter.Pvs(Owner), SoundCollection.GetSound(), IoCManager.Resolve().GetComponent(Owner).Coordinates, AudioHelpers.WithVariation(Variation).WithVolume(-2f)); + } + } +} diff --git a/Content.Server/Physics/Controllers/MoverController.cs b/Content.Server/Physics/Controllers/MoverController.cs index 48a2949ced..0e571480ad 100644 --- a/Content.Server/Physics/Controllers/MoverController.cs +++ b/Content.Server/Physics/Controllers/MoverController.cs @@ -1,9 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using Content.Server.Movement.Components; using Content.Server.Shuttles.Components; using Content.Server.Shuttles.EntitySystems; +using Content.Shared.CCVar; +using Content.Shared.Inventory; +using Content.Shared.Item; +using Content.Shared.Maps; using Content.Shared.Movement; using Content.Shared.Movement.Components; using Content.Shared.Shuttles.Components; +using Content.Shared.Tag; +using Robust.Shared.Audio; +using Robust.Shared.Configuration; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Log; using Robust.Shared.Map; +using Robust.Shared.Maths; using Robust.Shared.Player; using Robust.Shared.Utility; @@ -11,21 +26,24 @@ namespace Content.Server.Physics.Controllers { public sealed class MoverController : SharedMoverController { + [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly ShuttleSystem _shuttle = default!; - [Dependency] private readonly ThrusterSystem _thruster = default!; + [Dependency] private readonly TagSystem _tags = default!; + + private const float StepSoundMoveDistanceRunning = 2; + private const float StepSoundMoveDistanceWalking = 1.5f; + + private float _shuttleDockSpeedCap; private HashSet _excludedMobs = new(); private Dictionary> _shuttlePilots = new(); - protected override Filter GetSoundPlayers(EntityUid mover) + public override void Initialize() { - return Filter.Pvs(mover, entityManager: EntityManager).RemoveWhereAttachedEntity(o => o == mover); - } + base.Initialize(); - protected override bool CanSound() - { - return true; + var configManager = IoCManager.Resolve(); + configManager.OnValueChanged(CCVars.ShuttleDockSpeedCap, value => _shuttleDockSpeedCap = value, true); } public override void UpdateBeforeSolve(bool prediction, float frameTime) @@ -73,12 +91,15 @@ namespace Content.Server.Physics.Controllers pilots.Add((pilot, mover)); } + var shuttleSystem = EntitySystem.Get(); + var thrusterSystem = EntitySystem.Get(); + // Reset inputs for non-piloted shuttles. foreach (var (shuttle, _) in _shuttlePilots) { if (newPilots.ContainsKey(shuttle)) continue; - _thruster.DisableLinearThrusters(shuttle); + thrusterSystem.DisableLinearThrusters(shuttle); } _shuttlePilots = newPilots; @@ -149,8 +170,8 @@ namespace Content.Server.Physics.Controllers // Handle shuttle movement if (linearInput.Length.Equals(0f)) { - _thruster.DisableLinearThrusters(shuttle); - body.LinearDamping = _shuttle.ShuttleIdleLinearDamping * body.InvMass; + thrusterSystem.DisableLinearThrusters(shuttle); + body.LinearDamping = shuttleSystem.ShuttleIdleLinearDamping * body.InvMass; if (body.LinearVelocity.Length < 0.08) { body.LinearVelocity = Vector2.Zero; @@ -183,7 +204,7 @@ namespace Content.Server.Physics.Controllers if ((dir & dockFlag) == 0x0) { - _thruster.DisableLinearThrustDirection(shuttle, dir); + thrusterSystem.DisableLinearThrustDirection(shuttle, dir); continue; } @@ -212,7 +233,7 @@ namespace Content.Server.Physics.Controllers throw new ArgumentOutOfRangeException(); } - _thruster.EnableLinearThrustDirection(shuttle, dir); + thrusterSystem.EnableLinearThrustDirection(shuttle, dir); var index = (int) Math.Log2((int) dir); var force = thrustAngle.RotateVec(shuttleNorth) * shuttle.LinearThrust[index] * length; @@ -220,14 +241,14 @@ namespace Content.Server.Physics.Controllers totalForce += force; } - var dragForce = body.LinearVelocity * (totalForce.Length / _shuttle.ShuttleMaxLinearSpeed); + var dragForce = body.LinearVelocity * (totalForce.Length / shuttleSystem.ShuttleMaxLinearSpeed); body.ApplyLinearImpulse((totalForce - dragForce) * frameTime); } if (MathHelper.CloseTo(angularInput, 0f)) { - _thruster.SetAngularThrust(shuttle, false); - body.AngularDamping = _shuttle.ShuttleIdleAngularDamping * body.InvI; + thrusterSystem.SetAngularThrust(shuttle, false); + body.AngularDamping = shuttleSystem.ShuttleIdleAngularDamping * body.InvI; body.SleepingAllowed = true; if (Math.Abs(body.AngularVelocity) < 0.01f) @@ -240,17 +261,107 @@ namespace Content.Server.Physics.Controllers body.AngularDamping = 0; body.SleepingAllowed = false; - var maxSpeed = Math.Min(_shuttle.ShuttleMaxAngularMomentum * body.InvI, _shuttle.ShuttleMaxAngularSpeed); - var maxTorque = body.Inertia * _shuttle.ShuttleMaxAngularAcc; + var maxSpeed = Math.Min(shuttleSystem.ShuttleMaxAngularMomentum * body.InvI, shuttleSystem.ShuttleMaxAngularSpeed); + var maxTorque = body.Inertia * shuttleSystem.ShuttleMaxAngularAcc; var torque = Math.Min(shuttle.AngularThrust, maxTorque); var dragTorque = body.AngularVelocity * (torque / maxSpeed); body.ApplyAngularImpulse((-angularInput * torque - dragTorque) * frameTime); - _thruster.SetAngularThrust(shuttle, true); + thrusterSystem.SetAngularThrust(shuttle, true); } } } + + protected override void HandleFootsteps(IMoverComponent mover, IMobMoverComponent mobMover) + { + if (!_tags.HasTag(mover.Owner, "FootstepSound")) return; + + var transform = EntityManager.GetComponent(mover.Owner); + var coordinates = transform.Coordinates; + var gridId = coordinates.GetGridId(EntityManager); + var distanceNeeded = mover.Sprinting ? StepSoundMoveDistanceRunning : StepSoundMoveDistanceWalking; + + // Handle footsteps. + if (_mapManager.GridExists(gridId)) + { + // Can happen when teleporting between grids. + if (!coordinates.TryDistance(EntityManager, mobMover.LastPosition, out var distance) || + distance > distanceNeeded) + { + mobMover.StepSoundDistance = distanceNeeded; + } + else + { + mobMover.StepSoundDistance += distance; + } + } + else + { + // In space no one can hear you squeak + return; + } + + DebugTools.Assert(gridId != GridId.Invalid); + mobMover.LastPosition = coordinates; + + if (mobMover.StepSoundDistance < distanceNeeded) return; + + mobMover.StepSoundDistance -= distanceNeeded; + + var invSystem = EntitySystem.Get(); + + if (invSystem.TryGetSlotEntity(mover.Owner, "shoes", out var shoes) && + EntityManager.TryGetComponent(shoes, out var modifier)) + { + modifier.PlayFootstep(); + } + else + { + PlayFootstepSound(mover.Owner, gridId, coordinates, mover.Sprinting); + } + } + + private void PlayFootstepSound(EntityUid mover, GridId gridId, EntityCoordinates coordinates, bool sprinting) + { + var grid = _mapManager.GetGrid(gridId); + var tile = grid.GetTileRef(coordinates); + + if (tile.IsSpace(_tileDefinitionManager)) return; + + // If the coordinates have a FootstepModifier component + // i.e. component that emit sound on footsteps emit that sound + string? soundToPlay = null; + foreach (var maybeFootstep in grid.GetAnchoredEntities(tile.GridIndices)) + { + if (EntityManager.TryGetComponent(maybeFootstep, out FootstepModifierComponent? footstep)) + { + soundToPlay = footstep.SoundCollection.GetSound(); + break; + } + } + // if there is no FootstepModifierComponent, determine sound based on tiles + if (soundToPlay == null) + { + // Walking on a tile. + var def = (ContentTileDefinition) _tileDefinitionManager[tile.Tile.TypeId]; + soundToPlay = def.FootstepSounds?.GetSound(); + if (string.IsNullOrEmpty(soundToPlay)) + return; + } + + if (string.IsNullOrWhiteSpace(soundToPlay)) + { + Logger.ErrorS("sound", $"Unable to find sound in {nameof(PlayFootstepSound)}"); + return; + } + + SoundSystem.Play( + Filter.Pvs(coordinates), + soundToPlay, + EntityManager.GetComponent(mover).Coordinates, + sprinting ? AudioParams.Default.WithVolume(0.75f) : null); + } } } diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 5bd1dafe68..2e2e4bc5e5 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -609,6 +609,10 @@ namespace Content.Shared.CCVar /* * Shuttles */ + // Once cruising actually gets implemented I'd likely drop this speed to 3 maybe. + public static readonly CVarDef ShuttleDockSpeedCap = + CVarDef.Create("shuttle.dock_speed_cap", 5f, CVar.SERVERONLY); + public static readonly CVarDef ShuttleMaxLinearSpeed = CVarDef.Create("shuttle.max_linear_speed", 13f, CVar.SERVERONLY); diff --git a/Content.Shared/Movement/Components/FootstepModifierComponent.cs b/Content.Shared/Movement/Components/FootstepModifierComponent.cs deleted file mode 100644 index 54d20757fb..0000000000 --- a/Content.Shared/Movement/Components/FootstepModifierComponent.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Content.Shared.Sound; - -namespace Content.Shared.Movement.Components -{ - /// - /// Changes footstep sound - /// - [RegisterComponent] - public sealed class FootstepModifierComponent : Component - { - [DataField("footstepSoundCollection", required: true)] - public SoundSpecifier SoundCollection = default!; - - [DataField("variation")] - public float Variation = default; - } -} diff --git a/Content.Shared/Movement/SharedMoverController.cs b/Content.Shared/Movement/SharedMoverController.cs index b02637b21a..74f22cf7d7 100644 --- a/Content.Shared/Movement/SharedMoverController.cs +++ b/Content.Shared/Movement/SharedMoverController.cs @@ -1,20 +1,18 @@ -using System.Diagnostics.CodeAnalysis; +using System.Collections.Generic; using Content.Shared.ActionBlocker; -using Content.Shared.Audio; using Content.Shared.CCVar; using Content.Shared.Friction; -using Content.Shared.Inventory; -using Content.Shared.Maps; using Content.Shared.MobState.Components; using Content.Shared.Movement.Components; using Content.Shared.Pulling.Components; -using Content.Shared.Tag; -using Robust.Shared.Audio; +using JetBrains.Annotations; using Robust.Shared.Configuration; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; using Robust.Shared.Map; +using Robust.Shared.Maths; using Robust.Shared.Physics; using Robust.Shared.Physics.Controllers; -using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Shared.Movement @@ -26,17 +24,9 @@ namespace Content.Shared.Movement public abstract class SharedMoverController : VirtualController { [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; - [Dependency] private readonly ActionBlockerSystem _blocker = default!; - [Dependency] private readonly InventorySystem _inventory = default!; + + [Dependency] private ActionBlockerSystem _blocker = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; - [Dependency] private readonly TagSystem _tags = default!; - - private const float StepSoundMoveDistanceRunning = 2; - private const float StepSoundMoveDistanceWalking = 1.5f; - - private const float FootstepVariation = 0f; - private const float FootstepVolume = 1f; private bool _relativeMovement; @@ -165,15 +155,7 @@ namespace Content.Shared.Movement ? total.ToWorldAngle() : worldTotal.ToWorldAngle(); xform.DeferUpdates = false; - - if (TryGetSound(mover, mobMover, xform, out var variation, out var sound)) - { - SoundSystem.Play( - GetSoundPlayers(mover.Owner), - sound, - mover.Owner, - AudioHelpers.WithVariation(variation).WithVolume(FootstepVolume)); - } + HandleFootsteps(mover, mobMover); } _physics.SetLinearVelocity(physicsComponent, worldTotal); @@ -196,7 +178,7 @@ namespace Content.Shared.Movement /// /// Used for weightlessness to determine if we are near a wall. /// - private bool IsAroundCollider(SharedPhysicsSystem broadPhaseSystem, TransformComponent transform, IMobMoverComponent mover, IPhysBody collider) + public static bool IsAroundCollider(SharedPhysicsSystem broadPhaseSystem, TransformComponent transform, IMobMoverComponent mover, IPhysBody collider) { var enlargedAABB = collider.GetWorldAABB().Enlarged(mover.GrabRange); @@ -209,7 +191,7 @@ namespace Content.Shared.Movement !otherCollider.CanCollide || ((collider.CollisionMask & otherCollider.CollisionLayer) == 0 && (otherCollider.CollisionMask & collider.CollisionLayer) == 0) || - (TryComp(otherCollider.Owner, out SharedPullableComponent? pullable) && pullable.BeingPulled)) + (IoCManager.Resolve().TryGetComponent(otherCollider.Owner, out SharedPullableComponent? pullable) && pullable.BeingPulled)) { continue; } @@ -220,87 +202,7 @@ namespace Content.Shared.Movement return false; } - // TODO: Predicted audio moment. - protected abstract Filter GetSoundPlayers(EntityUid mover); - - protected abstract bool CanSound(); - - private bool TryGetSound(IMoverComponent mover, IMobMoverComponent mobMover, TransformComponent xform, out float variation, [NotNullWhen(true)] out string? sound) - { - sound = null; - variation = 0f; - - if (!CanSound() || !_tags.HasTag(mover.Owner, "FootstepSound")) return false; - - var coordinates = xform.Coordinates; - var gridId = coordinates.GetGridId(EntityManager); - var distanceNeeded = mover.Sprinting ? StepSoundMoveDistanceRunning : StepSoundMoveDistanceWalking; - - // Handle footsteps. - if (_mapManager.GridExists(gridId)) - { - // Can happen when teleporting between grids. - if (!coordinates.TryDistance(EntityManager, mobMover.LastPosition, out var distance) || - distance > distanceNeeded) - { - mobMover.StepSoundDistance = distanceNeeded; - } - else - { - mobMover.StepSoundDistance += distance; - } - } - else - { - // In space no one can hear you squeak - return false; - } - - DebugTools.Assert(gridId != GridId.Invalid); - mobMover.LastPosition = coordinates; - - if (mobMover.StepSoundDistance < distanceNeeded) return false; - - mobMover.StepSoundDistance -= distanceNeeded; - - if (_inventory.TryGetSlotEntity(mover.Owner, "shoes", out var shoes) && - EntityManager.TryGetComponent(shoes, out var modifier)) - { - sound = modifier.SoundCollection.GetSound(); - variation = modifier.Variation; - return true; - } - - return TryGetFootstepSound(gridId, coordinates, out variation, out sound); - } - - private bool TryGetFootstepSound(GridId gridId, EntityCoordinates coordinates, out float variation, [NotNullWhen(true)] out string? sound) - { - variation = 0f; - sound = null; - var grid = _mapManager.GetGrid(gridId); - var tile = grid.GetTileRef(coordinates); - - if (tile.IsSpace(_tileDefinitionManager)) return false; - - // If the coordinates have a FootstepModifier component - // i.e. component that emit sound on footsteps emit that sound - foreach (var maybeFootstep in grid.GetAnchoredEntities(tile.GridIndices)) - { - if (EntityManager.TryGetComponent(maybeFootstep, out FootstepModifierComponent? footstep)) - { - sound = footstep.SoundCollection.GetSound(); - variation = footstep.Variation; - return true; - } - } - - // Walking on a tile. - var def = (ContentTileDefinition) _tileDefinitionManager[tile.Tile.TypeId]; - sound = def.FootstepSounds?.GetSound(); - variation = FootstepVariation; - - return !string.IsNullOrEmpty(sound); - } + // TODO: Need a predicted client version that only plays for our own entity and then have server-side ignore our session (for that entity only) + protected virtual void HandleFootsteps(IMoverComponent mover, IMobMoverComponent mobMover) {} } } diff --git a/Content.Shared/Tag/TagSystem.cs b/Content.Shared/Tag/TagSystem.cs index d037abf95b..294bcba302 100644 --- a/Content.Shared/Tag/TagSystem.cs +++ b/Content.Shared/Tag/TagSystem.cs @@ -177,15 +177,6 @@ public sealed class TagSystem : EntitySystem HasTag(component, id); } - /// - /// Checks if a tag has been added to an entity. - /// - public bool HasTag(EntityUid entity, string id, EntityQuery tagQuery) - { - return tagQuery.TryGetComponent(entity, out var component) && - HasTag(component, id); - } - /// /// Checks if all of the given tags have been added to an entity. ///