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
This commit is contained in:
metalgearsloth
2021-07-26 01:48:22 +10:00
committed by GitHub
parent a91f919018
commit d3beadbb38
2 changed files with 32 additions and 9 deletions

View File

@@ -175,6 +175,12 @@ namespace Content.Shared.CCVar
* Physics * Physics
*/ */
/// <summary>
/// When a mob is walking should its X / Y movement be relative to its parent (true) or the map (false).
/// </summary>
public static readonly CVarDef<bool> RelativeMovement =
CVarDef.Create("physics.relative_movement", true, CVar.ARCHIVE | CVar.REPLICATED);
public static readonly CVarDef<float> TileFrictionModifier = public static readonly CVarDef<float> TileFrictionModifier =
CVarDef.Create("physics.tile_friction", 40.0f); CVarDef.Create("physics.tile_friction", 40.0f);

View File

@@ -1,7 +1,9 @@
using Content.Shared.ActionBlocker; using Content.Shared.ActionBlocker;
using Content.Shared.CCVar;
using Content.Shared.MobState; using Content.Shared.MobState;
using Content.Shared.Movement.Components; using Content.Shared.Movement.Components;
using Content.Shared.Pulling.Components; using Content.Shared.Pulling.Components;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Map; using Robust.Shared.Map;
@@ -9,6 +11,7 @@ using Robust.Shared.Maths;
using Robust.Shared.Physics; using Robust.Shared.Physics;
using Robust.Shared.Physics.Broadphase; using Robust.Shared.Physics.Broadphase;
using Robust.Shared.Physics.Controllers; using Robust.Shared.Physics.Controllers;
using Robust.Shared.Utility;
namespace Content.Shared.Movement namespace Content.Shared.Movement
{ {
@@ -22,10 +25,14 @@ namespace Content.Shared.Movement
private SharedBroadphaseSystem _broadPhaseSystem = default!; private SharedBroadphaseSystem _broadPhaseSystem = default!;
private bool _relativeMovement;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
_broadPhaseSystem = EntitySystem.Get<SharedBroadphaseSystem>(); _broadPhaseSystem = EntitySystem.Get<SharedBroadphaseSystem>();
var configManager = IoCManager.Resolve<IConfigurationManager>();
configManager.OnValueChanged(CCVars.RelativeMovement, value => _relativeMovement = value, true);
} }
/// <summary> /// <summary>
@@ -39,12 +46,14 @@ namespace Content.Shared.Movement
// Target velocity. // Target velocity.
var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed); 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;
} }
/// <summary> /// <summary>
@@ -53,7 +62,8 @@ namespace Content.Shared.Movement
/// <param name="mover"></param> /// <param name="mover"></param>
/// <param name="physicsComponent"></param> /// <param name="physicsComponent"></param>
/// <param name="mobMover"></param> /// <param name="mobMover"></param>
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 // 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)) if (!UseMobMovement(_broadPhaseSystem, physicsComponent, _mapManager))
@@ -74,30 +84,37 @@ namespace Content.Shared.Movement
if (!touching) if (!touching)
{ {
transform.LocalRotation = physicsComponent.LinearVelocity.GetDir().ToAngle(); transform.WorldRotation = physicsComponent.LinearVelocity.GetDir().ToAngle();
return; return;
} }
} }
// Regular movement. // Regular movement.
// Target velocity. // Target velocity.
// This is relative to the map / grid we're on.
var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed); 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) 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 // This should have its event run during island solver soooo
transform.DeferUpdates = true; transform.DeferUpdates = true;
transform.LocalRotation = total.GetDir().ToAngle(); transform.WorldRotation = worldTotal.GetDir().ToAngle();
transform.DeferUpdates = false; transform.DeferUpdates = false;
HandleFootsteps(mover, mobMover); HandleFootsteps(mover, mobMover);
} }
physicsComponent.LinearVelocity = total; physicsComponent.LinearVelocity = worldTotal;
} }
public static bool UseMobMovement(SharedBroadphaseSystem broadPhaseSystem, PhysicsComponent body, IMapManager mapManager) public static bool UseMobMovement(SharedBroadphaseSystem broadPhaseSystem, PhysicsComponent body, IMapManager mapManager)