From d3beadbb38cbe076cec960b024e31a500fbebcbc Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Mon, 26 Jul 2021 01:48:22 +1000 Subject: [PATCH] Grid-relative movement (#4327) * Grid-relative movement Might add a test for it, but not today as it's obvious when it's on / off. * Comment --- Content.Shared/CCVar/CCVars.cs | 6 ++++ .../Movement/SharedMoverController.cs | 35 ++++++++++++++----- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 3656505a4e..966377ae77 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -175,6 +175,12 @@ namespace Content.Shared.CCVar * Physics */ + /// + /// When a mob is walking should its X / Y movement be relative to its parent (true) or the map (false). + /// + public static readonly CVarDef RelativeMovement = + CVarDef.Create("physics.relative_movement", true, CVar.ARCHIVE | CVar.REPLICATED); + public static readonly CVarDef TileFrictionModifier = CVarDef.Create("physics.tile_friction", 40.0f); diff --git a/Content.Shared/Movement/SharedMoverController.cs b/Content.Shared/Movement/SharedMoverController.cs index d48d7ff3b9..0c1bc416a9 100644 --- a/Content.Shared/Movement/SharedMoverController.cs +++ b/Content.Shared/Movement/SharedMoverController.cs @@ -1,7 +1,9 @@ using Content.Shared.ActionBlocker; +using Content.Shared.CCVar; using Content.Shared.MobState; using Content.Shared.Movement.Components; using Content.Shared.Pulling.Components; +using Robust.Shared.Configuration; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; @@ -9,6 +11,7 @@ using Robust.Shared.Maths; using Robust.Shared.Physics; using Robust.Shared.Physics.Broadphase; using Robust.Shared.Physics.Controllers; +using Robust.Shared.Utility; namespace Content.Shared.Movement { @@ -22,10 +25,14 @@ namespace Content.Shared.Movement private SharedBroadphaseSystem _broadPhaseSystem = default!; + private bool _relativeMovement; + public override void Initialize() { base.Initialize(); _broadPhaseSystem = EntitySystem.Get(); + var configManager = IoCManager.Resolve(); + configManager.OnValueChanged(CCVars.RelativeMovement, value => _relativeMovement = value, true); } /// @@ -39,12 +46,14 @@ namespace Content.Shared.Movement // Target velocity. var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed); - if (total != Vector2.Zero) + var worldTotal = _relativeMovement ? new Angle(mover.Owner.Transform.Parent!.WorldRotation.Theta).RotateVec(total) : total; + + if (worldTotal != Vector2.Zero) { - mover.Owner.Transform.LocalRotation = total.GetDir().ToAngle(); + mover.Owner.Transform.WorldRotation = worldTotal.GetDir().ToAngle(); } - physicsComponent.LinearVelocity = total; + physicsComponent.LinearVelocity = worldTotal; } /// @@ -53,7 +62,8 @@ namespace Content.Shared.Movement /// /// /// - protected void HandleMobMovement(IMoverComponent mover, PhysicsComponent physicsComponent, IMobMoverComponent mobMover) + protected void HandleMobMovement(IMoverComponent mover, PhysicsComponent physicsComponent, + IMobMoverComponent mobMover) { // TODO: Look at https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/CharacterControllers.html?highlight=controller as it has some adviceo n kinematic controllersx if (!UseMobMovement(_broadPhaseSystem, physicsComponent, _mapManager)) @@ -74,30 +84,37 @@ namespace Content.Shared.Movement if (!touching) { - transform.LocalRotation = physicsComponent.LinearVelocity.GetDir().ToAngle(); + transform.WorldRotation = physicsComponent.LinearVelocity.GetDir().ToAngle(); return; } } // Regular movement. // Target velocity. + // This is relative to the map / grid we're on. var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed); + var worldTotal = _relativeMovement ? + new Angle(transform.Parent!.WorldRotation.Theta).RotateVec(total) : + total; + + DebugTools.Assert(MathHelper.CloseTo(total.Length, worldTotal.Length)); + if (weightless) { - total *= mobMover.WeightlessStrength; + worldTotal *= mobMover.WeightlessStrength; } - if (total != Vector2.Zero) + if (worldTotal != Vector2.Zero) { // This should have its event run during island solver soooo transform.DeferUpdates = true; - transform.LocalRotation = total.GetDir().ToAngle(); + transform.WorldRotation = worldTotal.GetDir().ToAngle(); transform.DeferUpdates = false; HandleFootsteps(mover, mobMover); } - physicsComponent.LinearVelocity = total; + physicsComponent.LinearVelocity = worldTotal; } public static bool UseMobMovement(SharedBroadphaseSystem broadPhaseSystem, PhysicsComponent body, IMapManager mapManager)