Tweak shuttle movement (#6468)
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using Content.Server.Movement.Components;
|
using Content.Server.Movement.Components;
|
||||||
using Content.Server.Shuttles.Components;
|
using Content.Server.Shuttles.Components;
|
||||||
using Content.Server.Shuttles.EntitySystems;
|
using Content.Server.Shuttles.EntitySystems;
|
||||||
@@ -170,17 +171,22 @@ namespace Content.Server.Physics.Controllers
|
|||||||
if (linearInput.Length.Equals(0f))
|
if (linearInput.Length.Equals(0f))
|
||||||
{
|
{
|
||||||
thrusterSystem.DisableLinearThrusters(shuttle);
|
thrusterSystem.DisableLinearThrusters(shuttle);
|
||||||
body.LinearDamping = shuttleSystem.ShuttleIdleLinearDamping;
|
body.LinearDamping = shuttleSystem.ShuttleIdleLinearDamping * body.InvMass;
|
||||||
|
if (body.LinearVelocity.Length < 0.08)
|
||||||
|
{
|
||||||
|
body.LinearVelocity = Vector2.Zero;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
body.LinearDamping = shuttleSystem.ShuttleMovingLinearDamping;
|
body.LinearDamping = 0;
|
||||||
|
|
||||||
var angle = linearInput.ToWorldAngle();
|
var angle = linearInput.ToWorldAngle();
|
||||||
var linearDir = angle.GetDir();
|
var linearDir = angle.GetDir();
|
||||||
var dockFlag = linearDir.AsFlag();
|
var dockFlag = linearDir.AsFlag();
|
||||||
var shuttleNorth = EntityManager.GetComponent<TransformComponent>(body.Owner).WorldRotation.ToWorldVec();
|
var shuttleNorth = EntityManager.GetComponent<TransformComponent>(body.Owner).WorldRotation.ToWorldVec();
|
||||||
|
|
||||||
|
var totalForce = new Vector2();
|
||||||
|
|
||||||
// Won't just do cardinal directions.
|
// Won't just do cardinal directions.
|
||||||
foreach (DirectionFlag dir in Enum.GetValues(typeof(DirectionFlag)))
|
foreach (DirectionFlag dir in Enum.GetValues(typeof(DirectionFlag)))
|
||||||
{
|
{
|
||||||
@@ -230,41 +236,38 @@ namespace Content.Server.Physics.Controllers
|
|||||||
thrusterSystem.EnableLinearThrustDirection(shuttle, dir);
|
thrusterSystem.EnableLinearThrustDirection(shuttle, dir);
|
||||||
|
|
||||||
var index = (int) Math.Log2((int) 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)
|
totalForce += force;
|
||||||
{
|
|
||||||
speed *= 5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.ApplyLinearImpulse(
|
|
||||||
thrustAngle.RotateVec(shuttleNorth) *
|
|
||||||
speed *
|
|
||||||
frameTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var dragForce = body.LinearVelocity * (totalForce.Length / shuttleSystem.ShuttleMaxLinearSpeed);
|
||||||
|
body.ApplyLinearImpulse((totalForce - dragForce) * frameTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MathHelper.CloseTo(angularInput, 0f))
|
if (MathHelper.CloseTo(angularInput, 0f))
|
||||||
{
|
{
|
||||||
thrusterSystem.SetAngularThrust(shuttle, false);
|
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
|
else
|
||||||
{
|
{
|
||||||
body.AngularDamping = shuttleSystem.ShuttleMovingAngularDamping;
|
body.AngularDamping = 0;
|
||||||
var angularSpeed = shuttle.AngularThrust;
|
body.SleepingAllowed = false;
|
||||||
|
|
||||||
if (body.AngularVelocity < 0.5f)
|
var maxSpeed = Math.Min(shuttleSystem.ShuttleMaxAngularMomentum * body.InvI, shuttleSystem.ShuttleMaxAngularSpeed);
|
||||||
{
|
var maxTorque = body.Inertia * shuttleSystem.ShuttleMaxAngularAcc;
|
||||||
angularSpeed *= 5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scale rotation by mass just to make rotating larger things a bit more bearable.
|
var torque = Math.Min(shuttle.AngularThrust, maxTorque);
|
||||||
body.ApplyAngularImpulse(
|
var dragTorque = body.AngularVelocity * (torque / maxSpeed);
|
||||||
-angularInput *
|
|
||||||
angularSpeed *
|
body.ApplyAngularImpulse((-angularInput * torque - dragTorque) * frameTime);
|
||||||
frameTime *
|
|
||||||
body.Mass / 100f);
|
|
||||||
|
|
||||||
thrusterSystem.SetAngularThrust(shuttle, true);
|
thrusterSystem.SetAngularThrust(shuttle, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ namespace Content.Server.Shuttles.Components
|
|||||||
public sealed class ShuttleComponent : SharedShuttleComponent
|
public sealed class ShuttleComponent : SharedShuttleComponent
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The cached impulse available for each cardinal direction
|
/// The cached thrust available for each cardinal direction
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public readonly float[] LinearThrusterImpulse = new float[4];
|
public readonly float[] LinearThrust = new float[4];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The thrusters contributing to each direction for impulse.
|
/// The thrusters contributing to each direction for impulse.
|
||||||
|
|||||||
@@ -47,9 +47,9 @@ namespace Content.Server.Shuttles.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsOn;
|
public bool IsOn;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField("impulse")]
|
[DataField("thrust")]
|
||||||
public float Impulse = 450f;
|
public float Thrust = 750f;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
[DataField("thrusterType")]
|
[DataField("thrusterType")]
|
||||||
@@ -68,6 +68,9 @@ namespace Content.Server.Shuttles.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables] [DataField("damage")] public DamageSpecifier? Damage = new();
|
[ViewVariables] [DataField("damage")] public DamageSpecifier? Damage = new();
|
||||||
|
|
||||||
|
[ViewVariables] [DataField("requireSpace")]
|
||||||
|
public bool RequireSpace = true;
|
||||||
|
|
||||||
// Used for burns
|
// Used for burns
|
||||||
|
|
||||||
public List<EntityUid> Colliding = new();
|
public List<EntityUid> Colliding = new();
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.Shuttles.Components;
|
using Content.Server.Shuttles.Components;
|
||||||
|
using Content.Shared.CCVar;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Physics;
|
using Robust.Shared.Physics;
|
||||||
@@ -12,11 +14,14 @@ namespace Content.Server.Shuttles.EntitySystems
|
|||||||
{
|
{
|
||||||
private const float TileMassMultiplier = 4f;
|
private const float TileMassMultiplier = 4f;
|
||||||
|
|
||||||
public float ShuttleIdleLinearDamping = 0.1f;
|
public float ShuttleMaxLinearSpeed;
|
||||||
public float ShuttleIdleAngularDamping = 0.2f;
|
|
||||||
|
|
||||||
public float ShuttleMovingLinearDamping = 0.05f;
|
public float ShuttleMaxAngularMomentum;
|
||||||
public float ShuttleMovingAngularDamping = 0.05f;
|
public float ShuttleMaxAngularAcc;
|
||||||
|
public float ShuttleMaxAngularSpeed;
|
||||||
|
|
||||||
|
public float ShuttleIdleLinearDamping;
|
||||||
|
public float ShuttleIdleAngularDamping;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -27,6 +32,32 @@ namespace Content.Server.Shuttles.EntitySystems
|
|||||||
|
|
||||||
SubscribeLocalEvent<GridInitializeEvent>(OnGridInit);
|
SubscribeLocalEvent<GridInitializeEvent>(OnGridInit);
|
||||||
SubscribeLocalEvent<GridFixtureChangeEvent>(OnGridFixtureChange);
|
SubscribeLocalEvent<GridFixtureChangeEvent>(OnGridFixtureChange);
|
||||||
|
|
||||||
|
var configManager = IoCManager.Resolve<IConfigurationManager>();
|
||||||
|
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<IConfigurationManager>();
|
||||||
|
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)
|
private void OnShuttleAdd(EntityUid uid, ShuttleComponent component, ComponentAdd args)
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ namespace Content.Server.Shuttles.EntitySystems
|
|||||||
|
|
||||||
foreach (var ent in _mapManager.GetGrid(e.NewTile.GridIndex).GetAnchoredEntities(checkPos))
|
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
|
// Work out if the thruster is facing this direction
|
||||||
var direction = EntityManager.GetComponent<TransformComponent>(ent).LocalRotation.ToWorldVec();
|
var direction = EntityManager.GetComponent<TransformComponent>(ent).LocalRotation.ToWorldVec();
|
||||||
@@ -174,11 +174,11 @@ namespace Content.Server.Shuttles.EntitySystems
|
|||||||
var oldDirection = (int) args.OldRotation.GetCardinalDir() / 2;
|
var oldDirection = (int) args.OldRotation.GetCardinalDir() / 2;
|
||||||
var direction = (int) args.NewRotation.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));
|
DebugTools.Assert(shuttleComponent.LinearThrusters[oldDirection].Contains(component));
|
||||||
shuttleComponent.LinearThrusters[oldDirection].Remove(component);
|
shuttleComponent.LinearThrusters[oldDirection].Remove(component);
|
||||||
|
|
||||||
shuttleComponent.LinearThrusterImpulse[direction] += component.Impulse;
|
shuttleComponent.LinearThrust[direction] += component.Thrust;
|
||||||
DebugTools.Assert(!shuttleComponent.LinearThrusters[direction].Contains(component));
|
DebugTools.Assert(!shuttleComponent.LinearThrusters[direction].Contains(component));
|
||||||
shuttleComponent.LinearThrusters[direction].Add(component);
|
shuttleComponent.LinearThrusters[direction].Add(component);
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ namespace Content.Server.Shuttles.EntitySystems
|
|||||||
case ThrusterType.Linear:
|
case ThrusterType.Linear:
|
||||||
var direction = (int) xform.LocalRotation.GetCardinalDir() / 2;
|
var direction = (int) xform.LocalRotation.GetCardinalDir() / 2;
|
||||||
|
|
||||||
shuttleComponent.LinearThrusterImpulse[direction] += component.Impulse;
|
shuttleComponent.LinearThrust[direction] += component.Thrust;
|
||||||
DebugTools.Assert(!shuttleComponent.LinearThrusters[direction].Contains(component));
|
DebugTools.Assert(!shuttleComponent.LinearThrusters[direction].Contains(component));
|
||||||
shuttleComponent.LinearThrusters[direction].Add(component);
|
shuttleComponent.LinearThrusters[direction].Add(component);
|
||||||
|
|
||||||
@@ -271,7 +271,7 @@ namespace Content.Server.Shuttles.EntitySystems
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case ThrusterType.Angular:
|
case ThrusterType.Angular:
|
||||||
shuttleComponent.AngularThrust += component.Impulse;
|
shuttleComponent.AngularThrust += component.Thrust;
|
||||||
DebugTools.Assert(!shuttleComponent.AngularThrusters.Contains(component));
|
DebugTools.Assert(!shuttleComponent.AngularThrusters.Contains(component));
|
||||||
shuttleComponent.AngularThrusters.Add(component);
|
shuttleComponent.AngularThrusters.Add(component);
|
||||||
break;
|
break;
|
||||||
@@ -313,12 +313,12 @@ namespace Content.Server.Shuttles.EntitySystems
|
|||||||
angle ??= xform.LocalRotation;
|
angle ??= xform.LocalRotation;
|
||||||
var direction = (int) angle.Value.GetCardinalDir() / 2;
|
var direction = (int) angle.Value.GetCardinalDir() / 2;
|
||||||
|
|
||||||
shuttleComponent.LinearThrusterImpulse[direction] -= component.Impulse;
|
shuttleComponent.LinearThrust[direction] -= component.Thrust;
|
||||||
DebugTools.Assert(shuttleComponent.LinearThrusters[direction].Contains(component));
|
DebugTools.Assert(shuttleComponent.LinearThrusters[direction].Contains(component));
|
||||||
shuttleComponent.LinearThrusters[direction].Remove(component);
|
shuttleComponent.LinearThrusters[direction].Remove(component);
|
||||||
break;
|
break;
|
||||||
case ThrusterType.Angular:
|
case ThrusterType.Angular:
|
||||||
shuttleComponent.AngularThrust -= component.Impulse;
|
shuttleComponent.AngularThrust -= component.Thrust;
|
||||||
DebugTools.Assert(shuttleComponent.AngularThrusters.Contains(component));
|
DebugTools.Assert(shuttleComponent.AngularThrusters.Contains(component));
|
||||||
shuttleComponent.AngularThrusters.Remove(component);
|
shuttleComponent.AngularThrusters.Remove(component);
|
||||||
break;
|
break;
|
||||||
@@ -359,7 +359,7 @@ namespace Content.Server.Shuttles.EntitySystems
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (component.Type == ThrusterType.Angular)
|
if (!component.RequireSpace)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return NozzleExposed(xform);
|
return NozzleExposed(xform);
|
||||||
|
|||||||
@@ -613,6 +613,25 @@ namespace Content.Shared.CCVar
|
|||||||
public static readonly CVarDef<float> ShuttleDockSpeedCap =
|
public static readonly CVarDef<float> ShuttleDockSpeedCap =
|
||||||
CVarDef.Create("shuttle.dock_speed_cap", 5f, CVar.SERVERONLY);
|
CVarDef.Create("shuttle.dock_speed_cap", 5f, CVar.SERVERONLY);
|
||||||
|
|
||||||
|
public static readonly CVarDef<float> ShuttleMaxLinearSpeed =
|
||||||
|
CVarDef.Create("shuttle.max_linear_speed", 13f, CVar.SERVERONLY);
|
||||||
|
|
||||||
|
public static readonly CVarDef<float> ShuttleMaxAngularSpeed =
|
||||||
|
CVarDef.Create("shuttle.max_angular_speed", 1.4f, CVar.SERVERONLY);
|
||||||
|
|
||||||
|
public static readonly CVarDef<float> ShuttleMaxAngularAcc =
|
||||||
|
CVarDef.Create("shuttle.max_angular_acc", 2f, CVar.SERVERONLY);
|
||||||
|
|
||||||
|
public static readonly CVarDef<float> ShuttleMaxAngularMomentum =
|
||||||
|
CVarDef.Create("shuttle.max_angular_momentum", 60000f, CVar.SERVERONLY);
|
||||||
|
|
||||||
|
public static readonly CVarDef<float> ShuttleIdleLinearDamping =
|
||||||
|
CVarDef.Create("shuttle.idle_linear_damping", 50f, CVar.SERVERONLY);
|
||||||
|
|
||||||
|
public static readonly CVarDef<float> ShuttleIdleAngularDamping =
|
||||||
|
CVarDef.Create("shuttle.idle_angular_damping", 100f, CVar.SERVERONLY);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VIEWPORT
|
* VIEWPORT
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -60,6 +60,31 @@
|
|||||||
map: ["enum.ThrusterVisualLayers.ThrustingUnshaded"]
|
map: ["enum.ThrusterVisualLayers.ThrustingUnshaded"]
|
||||||
shader: unshaded
|
shader: unshaded
|
||||||
offset: 0, 1
|
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
|
- type: entity
|
||||||
id: Gyroscope
|
id: Gyroscope
|
||||||
@@ -69,7 +94,8 @@
|
|||||||
components:
|
components:
|
||||||
- type: Thruster
|
- type: Thruster
|
||||||
thrusterType: Angular
|
thrusterType: Angular
|
||||||
impulse: 200
|
requireSpace: false
|
||||||
|
thrust: 5000
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
# Listen I'm not the biggest fan of the sprite but it was the most appropriate thing I could find.
|
# 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
|
sprite: Structures/Shuttles/gyroscope.rsi
|
||||||
|
|||||||
Reference in New Issue
Block a user