Evasion r6: drop the aether drive from the envelope; the gemini fixtures fly thruster hulls

Ruling retire-longinusx. AetherDrive.Manoeuvre and the drive line in Ship.RecalculateEnvelope go: the envelope
sums thrusters only. TheDrivesReportReadsItsStateAndTheShipsSpeed, the EvGemini fixture and the drive-only asserts
are deleted. Sideways jinks and the shooters' target move to the generated Djinni; the gun platforms (FastBlast+-,
ColdFire) are EvLonginus, the Duel's guns on a Longinus. TheThreeShipsOrder becomes TheShipsOrder.

Not built or run on its own: verified together with the mount term at the head.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-07 16:39:45 +02:00
commit e360ceeb27
3 changed files with 77 additions and 173 deletions

View file

@ -126,31 +126,6 @@ public class AetherDrive : Behavior, IPowerConsumer
// Cut 5 (docs/stats-and-power-cut.md §1.3, PowerTiers.cs): Medium -- mobility, same as Thruster.
public int DefaultPowerTier => PowerTiers.Medium;
// What this drive adds to the ship's manoeuvre envelope: Execute's own arithmetic at full input on every axis,
// as a rate per second at the rotors' current state (the rotors spend what they hold, so a drive that has been
// thrusting reports less). Each axis delivers Rpm * lambda * RotorMass * efficiency / Mass, the efficiency
// falling as the ship's speed along that axis approaches the rotor speed, so the push along the current
// velocity is smaller than against it; the turn is the z axis through AetherTorqueMultiplier, the same both
// ways. Zero when the item is offline or unpowered, the gates Execute applies.
public ManoeuvreEnvelope Manoeuvre()
{
if (Item == null || !Item.Active.Value || Item.PowerSupply <= 1e-4f) return default;
var forward = normalize(Entity.Direction);
var right = forward.Rotate(ItemRotation.Clockwise);
var speed = float2(dot(Entity.Velocity, forward), dot(Entity.Velocity, right));
var rotorSpeed = max(Rpm * _data.RotorDiameter / 100, 1);
var couplingEfficiency = Evaluate(_data.CouplingEfficiency);
var perSecond = Rpm * _data.CouplingLambda * Item.Evaluate(_data.LambdaMultiplier) * _data.RotorMass / Entity.Mass;
float Push(float axisRate, float axisSpeed, float axisRotorSpeed, float direction) =>
axisRate * saturate(1 - axisSpeed / axisRotorSpeed * direction) * couplingEfficiency;
return new ManoeuvreEnvelope(
Push(perSecond.x, speed.x, rotorSpeed.x, 1), Push(perSecond.x, speed.x, rotorSpeed.x, -1),
Push(perSecond.y, speed.y, rotorSpeed.y, -1), Push(perSecond.y, speed.y, rotorSpeed.y, 1),
perSecond.z * ItemManager.GameplaySettings.AetherTorqueMultiplier,
perSecond.z * ItemManager.GameplaySettings.AetherTorqueMultiplier);
}
public override bool Execute(float dt)
{
var rotorSpeed = Rpm * _data.RotorDiameter / 100;

View file

@ -145,7 +145,7 @@ public class Ship : Entity
#region ThrustCalculation
// What this ship can do at this instant (see ManoeuvreEnvelope): the sum of what each live propulsor reports with
// its own Execute arithmetic. Derived each update, never saved. The aggregates above are not an envelope (they
// its own Execute arithmetic; thrusters are its only propulsors. Derived each update, never saved. The aggregates above are not an envelope (they
// mix units and cancel a lone off-axis strafer), so nothing in it reads them.
public ManoeuvreEnvelope Envelope { get; private set; }
@ -153,7 +153,6 @@ public class Ship : Entity
{
var envelope = default(ManoeuvreEnvelope);
foreach (var thruster in _allThrusters) envelope += thruster.Manoeuvre();
foreach (var drive in _aetherDrives) envelope += drive.Manoeuvre();
Envelope = envelope;
}