Wind-adjusted fuel burn ±20% + refuel-for-flight buys 150% margin (ISS-070, ISS-071, v0.36.0)
CI / build + unit + e2e (pull_request) Successful in 10m34s
CI / build + unit + e2e (pull_request) Successful in 10m34s
This commit is contained in:
+14
-2
@@ -1,5 +1,10 @@
|
||||
import type { Page } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
// Real helpers (v0.36.0) — the wind-adjusted fuel math must match lib/ exactly; Playwright resolves
|
||||
// the repo's tsconfig paths, so importing beats mirroring a third copy of the formulas.
|
||||
import { initialBearingDeg } from '../lib/geo';
|
||||
import { weatherFor } from '../lib/weather';
|
||||
import { windBurnFactor } from '../lib/sim/movement';
|
||||
|
||||
// v0.31.0 — ISS-055: gameplay with TWO planes in the fleet. The reported bug ("can't load cargo
|
||||
// if both planes are on the same airport") was UX-only: LoadControls' multi-plane path rendered a
|
||||
@@ -114,18 +119,25 @@ async function twoNearestToHub(page: Page): Promise<Array<{ icao: string; lat: n
|
||||
}
|
||||
|
||||
// Farthest airport from EDDF whose leg still fits a FULL ATR tank — the longest flyable leg. The
|
||||
// dataset's absolute farthest can exceed range (a full-tank fly there would rightly 409).
|
||||
// dataset's absolute farthest can exceed range (a full-tank fly there would rightly 409). Wind-
|
||||
// adjusted (v0.36.0): BOTH directions must fit — the outbound is flown from a full tank and the
|
||||
// return leg is flown after a top-up, which also 409s if it doesn't fit.
|
||||
async function farthestFlyableToHub(page: Page): Promise<{ icao: string; lat: number; lon: number }> {
|
||||
const entry = (await getState(page)).catalog.find((e) => e.model === BUY_MODEL)!;
|
||||
const fc = (await (await page.request.get('/api/airports')).json()) as {
|
||||
features: Array<{ properties: { icao: string; lat: number; lon: number } }>;
|
||||
};
|
||||
const hub = fc.features.find((f) => f.properties.icao === HUB)!.properties;
|
||||
const wHub = weatherFor(HUB);
|
||||
let farthest: { icao: string; lat: number; lon: number; d: number } | null = null;
|
||||
for (const f of fc.features) {
|
||||
if (f.properties.icao === HUB) continue;
|
||||
const d = haversineKm(hub.lat, hub.lon, f.properties.lat, f.properties.lon);
|
||||
if (requiredFuelFor(entry.burnPerKm, entry.emptyWeightKg, entry.maxFuel, d) > entry.maxFuel) continue; // beyond range
|
||||
const wDest = weatherFor(f.properties.icao);
|
||||
const outBurn = entry.burnPerKm * windBurnFactor(wHub.windKt, wHub.windDirDeg, initialBearingDeg(hub.lat, hub.lon, f.properties.lat, f.properties.lon));
|
||||
if (requiredFuelFor(outBurn, entry.emptyWeightKg, entry.maxFuel, d) > entry.maxFuel) continue; // beyond range
|
||||
const backBurn = entry.burnPerKm * windBurnFactor(wDest.windKt, wDest.windDirDeg, initialBearingDeg(f.properties.lat, f.properties.lon, hub.lat, hub.lon));
|
||||
if (requiredFuelFor(backBurn, entry.emptyWeightKg, entry.maxFuel, d) > entry.maxFuel) continue; // return leg wouldn't fit a full tank either
|
||||
if (!farthest || d > farthest.d) {
|
||||
farthest = { icao: f.properties.icao, lat: f.properties.lat, lon: f.properties.lon, d };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user