From 401ccfba0a11bbfa91be5c1cdee4d08fa5bdc94d Mon Sep 17 00:00:00 2001 From: Radrark <76271993+Radrark@users.noreply.github.com> Date: Mon, 7 Mar 2022 02:03:53 -0300 Subject: [PATCH] Tweak shuttle movement (#6468) Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> --- .../Physics/Controllers/MoverController.cs | 55 ++++++++++--------- .../Shuttles/Components/ShuttleComponent.cs | 4 +- .../Shuttles/Components/ThrusterComponent.cs | 9 ++- .../Shuttles/EntitySystems/ShuttleSystem.cs | 39 +++++++++++-- .../Shuttles/EntitySystems/ThrusterSystem.cs | 16 +++--- Content.Shared/CCVar/CCVars.cs | 19 +++++++ .../Structures/Shuttles/thrusters.yml | 28 +++++++++- 7 files changed, 126 insertions(+), 44 deletions(-) diff --git a/Content.Server/Physics/Controllers/MoverController.cs b/Content.Server/Physics/Controllers/MoverController.cs index 5bde14ece8..0e571480ad 100644 --- a/Content.Server/Physics/Controllers/MoverController.cs +++ b/Content.Server/Physics/Controllers/MoverController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using Content.Server.Movement.Components; using Content.Server.Shuttles.Components; using Content.Server.Shuttles.EntitySystems; @@ -170,17 +171,22 @@ namespace Content.Server.Physics.Controllers if (linearInput.Length.Equals(0f)) { thrusterSystem.DisableLinearThrusters(shuttle); - body.LinearDamping = shuttleSystem.ShuttleIdleLinearDamping; + body.LinearDamping = shuttleSystem.ShuttleIdleLinearDamping * body.InvMass; + if (body.LinearVelocity.Length < 0.08) + { + body.LinearVelocity = Vector2.Zero; + } } else { - body.LinearDamping = shuttleSystem.ShuttleMovingLinearDamping; - + body.LinearDamping = 0; var angle = linearInput.ToWorldAngle(); var linearDir = angle.GetDir(); var dockFlag = linearDir.AsFlag(); var shuttleNorth = EntityManager.GetComponent(body.Owner).WorldRotation.ToWorldVec(); + var totalForce = new Vector2(); + // Won't just do cardinal directions. foreach (DirectionFlag dir in Enum.GetValues(typeof(DirectionFlag))) { @@ -230,41 +236,38 @@ namespace Content.Server.Physics.Controllers thrusterSystem.EnableLinearThrustDirection(shuttle, dir); var index = (int) Math.Log2((int) dir); - var speed = shuttle.LinearThrusterImpulse[index] * length; + var force = thrustAngle.RotateVec(shuttleNorth) * shuttle.LinearThrust[index] * length; - if (body.LinearVelocity.LengthSquared < 0.5f) - { - speed *= 5f; - } - - body.ApplyLinearImpulse( - thrustAngle.RotateVec(shuttleNorth) * - speed * - frameTime); + totalForce += force; } + + var dragForce = body.LinearVelocity * (totalForce.Length / shuttleSystem.ShuttleMaxLinearSpeed); + body.ApplyLinearImpulse((totalForce - dragForce) * frameTime); } if (MathHelper.CloseTo(angularInput, 0f)) { thrusterSystem.SetAngularThrust(shuttle, false); - body.AngularDamping = shuttleSystem.ShuttleIdleAngularDamping; + body.AngularDamping = shuttleSystem.ShuttleIdleAngularDamping * body.InvI; + body.SleepingAllowed = true; + + if (Math.Abs(body.AngularVelocity) < 0.01f) + { + body.AngularVelocity = 0f; + } } else { - body.AngularDamping = shuttleSystem.ShuttleMovingAngularDamping; - var angularSpeed = shuttle.AngularThrust; + body.AngularDamping = 0; + body.SleepingAllowed = false; - if (body.AngularVelocity < 0.5f) - { - angularSpeed *= 5f; - } + var maxSpeed = Math.Min(shuttleSystem.ShuttleMaxAngularMomentum * body.InvI, shuttleSystem.ShuttleMaxAngularSpeed); + var maxTorque = body.Inertia * shuttleSystem.ShuttleMaxAngularAcc; - // Scale rotation by mass just to make rotating larger things a bit more bearable. - body.ApplyAngularImpulse( - -angularInput * - angularSpeed * - frameTime * - body.Mass / 100f); + var torque = Math.Min(shuttle.AngularThrust, maxTorque); + var dragTorque = body.AngularVelocity * (torque / maxSpeed); + + body.ApplyAngularImpulse((-angularInput * torque - dragTorque) * frameTime); thrusterSystem.SetAngularThrust(shuttle, true); } diff --git a/Content.Server/Shuttles/Components/ShuttleComponent.cs b/Content.Server/Shuttles/Components/ShuttleComponent.cs index 6f77caf198..859331489f 100644 --- a/Content.Server/Shuttles/Components/ShuttleComponent.cs +++ b/Content.Server/Shuttles/Components/ShuttleComponent.cs @@ -10,10 +10,10 @@ namespace Content.Server.Shuttles.Components public sealed class ShuttleComponent : SharedShuttleComponent { /// - /// The cached impulse available for each cardinal direction + /// The cached thrust available for each cardinal direction /// [ViewVariables] - public readonly float[] LinearThrusterImpulse = new float[4]; + public readonly float[] LinearThrust = new float[4]; /// /// The thrusters contributing to each direction for impulse. diff --git a/Content.Server/Shuttles/Components/ThrusterComponent.cs b/Content.Server/Shuttles/Components/ThrusterComponent.cs index 0020b7a18c..2ac8f90055 100644 --- a/Content.Server/Shuttles/Components/ThrusterComponent.cs +++ b/Content.Server/Shuttles/Components/ThrusterComponent.cs @@ -47,9 +47,9 @@ namespace Content.Server.Shuttles.Components /// public bool IsOn; - [ViewVariables] - [DataField("impulse")] - public float Impulse = 450f; + [ViewVariables(VVAccess.ReadWrite)] + [DataField("thrust")] + public float Thrust = 750f; [ViewVariables] [DataField("thrusterType")] @@ -68,6 +68,9 @@ namespace Content.Server.Shuttles.Components /// [ViewVariables] [DataField("damage")] public DamageSpecifier? Damage = new(); + [ViewVariables] [DataField("requireSpace")] + public bool RequireSpace = true; + // Used for burns public List Colliding = new(); diff --git a/Content.Server/Shuttles/EntitySystems/ShuttleSystem.cs b/Content.Server/Shuttles/EntitySystems/ShuttleSystem.cs index 172aa6339d..005dc4c4ca 100644 --- a/Content.Server/Shuttles/EntitySystems/ShuttleSystem.cs +++ b/Content.Server/Shuttles/EntitySystems/ShuttleSystem.cs @@ -1,6 +1,8 @@ using System.Collections.Generic; using Content.Server.Shuttles.Components; +using Content.Shared.CCVar; using JetBrains.Annotations; +using Robust.Shared.Configuration; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Physics; @@ -12,11 +14,14 @@ namespace Content.Server.Shuttles.EntitySystems { private const float TileMassMultiplier = 4f; - public float ShuttleIdleLinearDamping = 0.1f; - public float ShuttleIdleAngularDamping = 0.2f; + public float ShuttleMaxLinearSpeed; - public float ShuttleMovingLinearDamping = 0.05f; - public float ShuttleMovingAngularDamping = 0.05f; + public float ShuttleMaxAngularMomentum; + public float ShuttleMaxAngularAcc; + public float ShuttleMaxAngularSpeed; + + public float ShuttleIdleLinearDamping; + public float ShuttleIdleAngularDamping; public override void Initialize() { @@ -27,6 +32,32 @@ namespace Content.Server.Shuttles.EntitySystems SubscribeLocalEvent(OnGridInit); SubscribeLocalEvent(OnGridFixtureChange); + + var configManager = IoCManager.Resolve(); + configManager.OnValueChanged(CCVars.ShuttleMaxLinearSpeed, SetShuttleMaxLinearSpeed, true); + configManager.OnValueChanged(CCVars.ShuttleMaxAngularSpeed, SetShuttleMaxAngularSpeed, true); + configManager.OnValueChanged(CCVars.ShuttleIdleLinearDamping, SetShuttleIdleLinearDamping, true); + configManager.OnValueChanged(CCVars.ShuttleIdleAngularDamping, SetShuttleIdleAngularDamping, true); + configManager.OnValueChanged(CCVars.ShuttleMaxAngularAcc, SetShuttleMaxAngularAcc, true); + configManager.OnValueChanged(CCVars.ShuttleMaxAngularMomentum, SetShuttleMaxAngularMomentum, true); + } + + private void SetShuttleMaxLinearSpeed(float value) => ShuttleMaxLinearSpeed = value; + private void SetShuttleMaxAngularSpeed(float value) => ShuttleMaxAngularSpeed = value; + private void SetShuttleMaxAngularAcc(float value) => ShuttleMaxAngularAcc = value; + private void SetShuttleMaxAngularMomentum(float value) => ShuttleMaxAngularMomentum = value; + private void SetShuttleIdleLinearDamping(float value) => ShuttleIdleLinearDamping = value; + private void SetShuttleIdleAngularDamping(float value) => ShuttleIdleAngularDamping = value; + + public override void Shutdown() + { + base.Shutdown(); + var configManager = IoCManager.Resolve(); + configManager.UnsubValueChanged(CCVars.ShuttleMaxLinearSpeed, SetShuttleMaxLinearSpeed); + configManager.UnsubValueChanged(CCVars.ShuttleMaxAngularSpeed, SetShuttleMaxAngularSpeed); + configManager.UnsubValueChanged(CCVars.ShuttleIdleLinearDamping, SetShuttleIdleLinearDamping); + configManager.UnsubValueChanged(CCVars.ShuttleIdleAngularDamping, SetShuttleIdleAngularDamping); + configManager.UnsubValueChanged(CCVars.ShuttleMaxAngularMomentum, SetShuttleMaxAngularMomentum); } private void OnShuttleAdd(EntityUid uid, ShuttleComponent component, ComponentAdd args) diff --git a/Content.Server/Shuttles/EntitySystems/ThrusterSystem.cs b/Content.Server/Shuttles/EntitySystems/ThrusterSystem.cs index e9c44b1060..4f62cef87c 100644 --- a/Content.Server/Shuttles/EntitySystems/ThrusterSystem.cs +++ b/Content.Server/Shuttles/EntitySystems/ThrusterSystem.cs @@ -118,7 +118,7 @@ namespace Content.Server.Shuttles.EntitySystems foreach (var ent in _mapManager.GetGrid(e.NewTile.GridIndex).GetAnchoredEntities(checkPos)) { - if (!EntityManager.TryGetComponent(ent, out ThrusterComponent? thruster) || thruster.Type == ThrusterType.Angular) continue; + if (!EntityManager.TryGetComponent(ent, out ThrusterComponent? thruster) || !thruster.RequireSpace) continue; // Work out if the thruster is facing this direction var direction = EntityManager.GetComponent(ent).LocalRotation.ToWorldVec(); @@ -174,11 +174,11 @@ namespace Content.Server.Shuttles.EntitySystems var oldDirection = (int) args.OldRotation.GetCardinalDir() / 2; var direction = (int) args.NewRotation.GetCardinalDir() / 2; - shuttleComponent.LinearThrusterImpulse[oldDirection] -= component.Impulse; + shuttleComponent.LinearThrust[oldDirection] -= component.Thrust; DebugTools.Assert(shuttleComponent.LinearThrusters[oldDirection].Contains(component)); shuttleComponent.LinearThrusters[oldDirection].Remove(component); - shuttleComponent.LinearThrusterImpulse[direction] += component.Impulse; + shuttleComponent.LinearThrust[direction] += component.Thrust; DebugTools.Assert(!shuttleComponent.LinearThrusters[direction].Contains(component)); shuttleComponent.LinearThrusters[direction].Add(component); } @@ -247,7 +247,7 @@ namespace Content.Server.Shuttles.EntitySystems case ThrusterType.Linear: var direction = (int) xform.LocalRotation.GetCardinalDir() / 2; - shuttleComponent.LinearThrusterImpulse[direction] += component.Impulse; + shuttleComponent.LinearThrust[direction] += component.Thrust; DebugTools.Assert(!shuttleComponent.LinearThrusters[direction].Contains(component)); shuttleComponent.LinearThrusters[direction].Add(component); @@ -271,7 +271,7 @@ namespace Content.Server.Shuttles.EntitySystems break; case ThrusterType.Angular: - shuttleComponent.AngularThrust += component.Impulse; + shuttleComponent.AngularThrust += component.Thrust; DebugTools.Assert(!shuttleComponent.AngularThrusters.Contains(component)); shuttleComponent.AngularThrusters.Add(component); break; @@ -313,12 +313,12 @@ namespace Content.Server.Shuttles.EntitySystems angle ??= xform.LocalRotation; var direction = (int) angle.Value.GetCardinalDir() / 2; - shuttleComponent.LinearThrusterImpulse[direction] -= component.Impulse; + shuttleComponent.LinearThrust[direction] -= component.Thrust; DebugTools.Assert(shuttleComponent.LinearThrusters[direction].Contains(component)); shuttleComponent.LinearThrusters[direction].Remove(component); break; case ThrusterType.Angular: - shuttleComponent.AngularThrust -= component.Impulse; + shuttleComponent.AngularThrust -= component.Thrust; DebugTools.Assert(shuttleComponent.AngularThrusters.Contains(component)); shuttleComponent.AngularThrusters.Remove(component); break; @@ -359,7 +359,7 @@ namespace Content.Server.Shuttles.EntitySystems return false; } - if (component.Type == ThrusterType.Angular) + if (!component.RequireSpace) return true; return NozzleExposed(xform); diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index dc254b0468..2e2e4bc5e5 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -613,6 +613,25 @@ namespace Content.Shared.CCVar 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); + + public static readonly CVarDef ShuttleMaxAngularSpeed = + CVarDef.Create("shuttle.max_angular_speed", 1.4f, CVar.SERVERONLY); + + public static readonly CVarDef ShuttleMaxAngularAcc = + CVarDef.Create("shuttle.max_angular_acc", 2f, CVar.SERVERONLY); + + public static readonly CVarDef ShuttleMaxAngularMomentum = + CVarDef.Create("shuttle.max_angular_momentum", 60000f, CVar.SERVERONLY); + + public static readonly CVarDef ShuttleIdleLinearDamping = + CVarDef.Create("shuttle.idle_linear_damping", 50f, CVar.SERVERONLY); + + public static readonly CVarDef ShuttleIdleAngularDamping = + CVarDef.Create("shuttle.idle_angular_damping", 100f, CVar.SERVERONLY); + + /* * VIEWPORT */ diff --git a/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml b/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml index a8b365674e..707a10a8a4 100644 --- a/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml +++ b/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml @@ -60,6 +60,31 @@ map: ["enum.ThrusterVisualLayers.ThrustingUnshaded"] shader: unshaded offset: 0, 1 + +- type: entity + id: DebugThruster + parent: BaseThruster + name: thruster + suffix: DEBUG + description: It goes nyooooooom. It doesn't need power nor space. + components: + - type: Thruster + requireSpace: false + - type: ApcPowerReceiver + needsPower: false + powerLoad: 0 + - type: Sprite + sprite: Structures/Shuttles/thruster.rsi + layers: + - state: base + map: ["enum.ThrusterVisualLayers.Base"] + - state: thrust + map: ["enum.ThrusterVisualLayers.ThrustOn"] + shader: unshaded + - state: thrust_burn_unshaded + map: ["enum.ThrusterVisualLayers.ThrustingUnshaded"] + shader: unshaded + offset: 0, 1 - type: entity id: Gyroscope @@ -69,7 +94,8 @@ components: - type: Thruster thrusterType: Angular - impulse: 200 + requireSpace: false + thrust: 5000 - type: Sprite # Listen I'm not the biggest fan of the sprite but it was the most appropriate thing I could find. sprite: Structures/Shuttles/gyroscope.rsi