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.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<TransformComponent>(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);
|
||||
}
|
||||
|
||||
@@ -10,10 +10,10 @@ namespace Content.Server.Shuttles.Components
|
||||
public sealed class ShuttleComponent : SharedShuttleComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// The cached impulse available for each cardinal direction
|
||||
/// The cached thrust available for each cardinal direction
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public readonly float[] LinearThrusterImpulse = new float[4];
|
||||
public readonly float[] LinearThrust = new float[4];
|
||||
|
||||
/// <summary>
|
||||
/// The thrusters contributing to each direction for impulse.
|
||||
|
||||
@@ -47,9 +47,9 @@ namespace Content.Server.Shuttles.Components
|
||||
/// </summary>
|
||||
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
|
||||
/// </summary>
|
||||
[ViewVariables] [DataField("damage")] public DamageSpecifier? Damage = new();
|
||||
|
||||
[ViewVariables] [DataField("requireSpace")]
|
||||
public bool RequireSpace = true;
|
||||
|
||||
// Used for burns
|
||||
|
||||
public List<EntityUid> Colliding = new();
|
||||
|
||||
@@ -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<GridInitializeEvent>(OnGridInit);
|
||||
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)
|
||||
|
||||
@@ -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<TransformComponent>(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);
|
||||
|
||||
@@ -613,6 +613,25 @@ namespace Content.Shared.CCVar
|
||||
public static readonly CVarDef<float> ShuttleDockSpeedCap =
|
||||
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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user