Extend the existing reserve-shipment promise pipeline to base Advanced games without Guild or optional modules. Share scope between parser, save validation and UI. Reuse canonical Ghola normal/elite revival eligibility and retain live BG conversion responses while proving conditional private feasibility. Hide future-price guidance until pending responses finish. Show exact Sardaukar/Fedaykin allocation in private executable steps. Validation: types, lint and all 4,192 offline tests pass; production build and all 40 HTTP tests pass. 41 focused shipment tests include 15 new cases covering genuine Advanced setup, all five non-Guild factions and four bot profiles, typed Ghola quota, BG allowance/cancellation/alternatives, private views, saved continuations and production SQLite duplicate races. Independent review found and resolved optional-module scope and pending price-guidance issues. Browser rooms EUZZ8D4M and GWNCVCAP verified an AI No route and human Yes with four-force/one-Sardaukar Ghola then six-force shipment. Phone settlement controls and refresh passed. Both existing browser room hashes/versions preserved through HTTP tests; 30 rooms added. Full source-bound report: 20260913-advanced-shipment-final; fingerprint 6c2f29d9b3e61bf6b9544ee3a95c47538abfb05e1c3b2ae9d0a603ef0cef38dd Broad checks ran once after focused fixes/review. No full-game AI study or complete Advanced mode acceptance is claimed; all existing release gates and pending Guild settlement questions remain intact.
51 lines
1.4 KiB
TypeScript
51 lines
1.4 KiB
TypeScript
/** A current-turn promise about the player's ordinary physical shipment from reserves. */
|
|
export type ShipmentClaim = { territory: string; minimum: number };
|
|
/** Software readiness boundary; this is not a printed restriction on Truthtrance. */
|
|
export function shipmentPromiseModeSupported(game: {
|
|
advanced: boolean;
|
|
expansions: readonly unknown[];
|
|
players: readonly { faction: string }[];
|
|
techTokens?: unknown;
|
|
strongholdCards?: unknown;
|
|
nexusCards?: unknown;
|
|
homeworlds?: unknown;
|
|
}): boolean {
|
|
return (
|
|
!game.expansions.length &&
|
|
(!game.advanced ||
|
|
(!game.players.some((player) => player.faction === 'guild') &&
|
|
!game.techTokens &&
|
|
!game.strongholdCards &&
|
|
!game.nexusCards &&
|
|
!game.homeworlds))
|
|
);
|
|
}
|
|
export type ShipmentPromise = ShipmentClaim & {
|
|
turn: number;
|
|
player: string;
|
|
asker: string;
|
|
answer: boolean;
|
|
released?: boolean;
|
|
fulfilled?: boolean;
|
|
};
|
|
export function matchesShipment(
|
|
claim: ShipmentClaim,
|
|
shipment: { territory: string; amount: number } | null,
|
|
): boolean {
|
|
return (
|
|
!!shipment &&
|
|
shipment.territory === claim.territory &&
|
|
shipment.amount >= claim.minimum
|
|
);
|
|
}
|
|
export function liveShipmentPromises(
|
|
promises: readonly ShipmentPromise[],
|
|
player: string,
|
|
turn: number,
|
|
): ShipmentPromise[] {
|
|
return promises.filter(
|
|
(p) =>
|
|
p.player === player && p.turn === turn && !p.released && !p.fulfilled,
|
|
);
|
|
}
|