Package weight, payload capacity and per-kg payout (ISS-045)
CI / build + unit + e2e (pull_request) Successful in 8m2s
CI / build + unit + e2e (pull_request) Successful in 8m2s
Packages carry a real weightKg (unit weight x count with +/-30% jitter), plane capacity becomes maxPayloadKg instead of 6 slots, load validation sums cargo weight against the payload, and the payout gains a per-kg part. Loadout display shows tonnage; OpenAPI swaps CatalogEntry.capacity for maxPayloadKg and adds PackageState.weightKg.
This commit is contained in:
@@ -9,7 +9,7 @@ import { formatCash, formatDeadlineRelative, formatFuel, formatSimClock } from '
|
||||
import { TIME_SCALES, scaleToSlider, sliderToScale } from '@/lib/timeScale';
|
||||
import { useGameAction } from '@/lib/useGameAction';
|
||||
import { useSimClock } from '@/lib/useSimClock';
|
||||
import { slotsUsedFor } from './RightPane';
|
||||
import { cargoWeightFor } from './RightPane';
|
||||
import type { HoverTarget } from './hoverTypes';
|
||||
|
||||
interface LeftPaneProps {
|
||||
@@ -39,13 +39,12 @@ function planeLocation(p: PlaneState): string {
|
||||
return p.locationName;
|
||||
}
|
||||
|
||||
// Cargo loadout "n/capacity pkgs" — expired packages still occupy their slot.
|
||||
// Cargo loadout "X.Xt / Y.Yt" (v0.27.0) — used/max payload in tonnes, one decimal;
|
||||
// expired packages still occupy their payload.
|
||||
function loadoutFor(state: StateSnapshot, p: PlaneState): string {
|
||||
const used = state.packages.filter(
|
||||
(pkg) => pkg.planeId === p.id && (pkg.status === 'loaded' || pkg.status === 'expired'),
|
||||
).length;
|
||||
const capacity = state.catalog.find((e) => e.model === p.model)?.capacity ?? PLANE_TYPES[p.model]?.capacity ?? 0;
|
||||
return `${used}/${capacity} pkgs`;
|
||||
const used = cargoWeightFor(state, p.id);
|
||||
const maxPayloadKg = state.catalog.find((e) => e.model === p.model)?.maxPayloadKg ?? PLANE_TYPES[p.model]?.maxPayloadKg ?? 0;
|
||||
return `${(used / 1000).toFixed(1)}t / ${(maxPayloadKg / 1000).toFixed(1)}t`;
|
||||
}
|
||||
|
||||
// ISS-001 — an optimistic slider value is cleared exactly when a rendered snapshot CONFIRMS it
|
||||
@@ -207,7 +206,7 @@ export default function LeftPane({ state, loading, error, onRefresh, applySnapsh
|
||||
// ISS-043 (v0.26.0): a plane with queued legs always shows its block too — the queue is the
|
||||
// reason it's here even when grounded with nothing on board.
|
||||
const onboard = state
|
||||
? state.planes.filter((p) => p.status === 'flying' || slotsUsedFor(state, p.id) > 0 || (p.queue?.length ?? 0) > 0)
|
||||
? state.planes.filter((p) => p.status === 'flying' || cargoWeightFor(state, p.id) > 0 || (p.queue?.length ?? 0) > 0)
|
||||
: [];
|
||||
|
||||
// ISS-023 (v0.21.0): Relocate — any GROUNDED plane can be repositioned to any airport via the
|
||||
|
||||
Reference in New Issue
Block a user