From 536d33454352ea05725c4659e2a0227e30e7b1e6 Mon Sep 17 00:00:00 2001
From: Quintine <15965533+Quintine@users.noreply.github.com>
Date: Tue, 27 Oct 2026 21:19:07 +1100
Subject: [PATCH] Support sector-specific Truthtrance shipments
---
components/shipment-claim-fields.tsx | 32 ++++++-
components/travel-claim-fields.tsx | 28 +++++-
components/turn-action-fields.tsx | 29 +++++-
components/turn-action-promises.tsx | 24 ++++-
docs/CURRENT_STATUS.md | 8 ++
docs/IMPLEMENTATION_STATUS.md | 9 ++
docs/RULE_DECISIONS.md | 8 ++
docs/TRUTHTRANCE_TURN_ACTIONS.md | 23 +++++
game/bots.ts | 3 +-
game/engine.ts | 84 +++++++++++------
game/reference.ts | 2 +-
game/shipment-expression-input.ts | 5 +-
game/shipment-promises.ts | 26 +++--
game/travel-expression-promises.ts | 55 +++++++----
game/turn-action-promises.ts | 37 ++++++--
tests/fixture-truth-shipment-sector-guards.ts | 48 ++++++++++
tests/fixture-truth-shipment-sector.ts | 43 +++++++++
tests/shipment-sector-promises.test.ts | 68 ++++++++++++++
...andalone-shipment-sector-controls.test.tsx | 56 +++++++++++
.../travel-shipment-sector-controls.test.tsx | 64 +++++++++++++
tests/travel-shipment-sector.test.ts | 91 ++++++++++++++++++
tests/truth-shipment-sector-guards.test.ts | 48 ++++++++++
tests/truth-shipment-sector-runtime.test.ts | 94 +++++++++++++++++++
...standalone-shipment-sector-runtime.test.ts | 71 ++++++++++++++
...uth-travel-shipment-sector-runtime.test.ts | 86 +++++++++++++++++
...n-action-shipment-sector-controls.test.tsx | 66 +++++++++++++
tests/turn-action-shipment-sector.test.ts | 84 +++++++++++++++++
27 files changed, 1121 insertions(+), 71 deletions(-)
create mode 100644 tests/fixture-truth-shipment-sector-guards.ts
create mode 100644 tests/fixture-truth-shipment-sector.ts
create mode 100644 tests/shipment-sector-promises.test.ts
create mode 100644 tests/standalone-shipment-sector-controls.test.tsx
create mode 100644 tests/travel-shipment-sector-controls.test.tsx
create mode 100644 tests/travel-shipment-sector.test.ts
create mode 100644 tests/truth-shipment-sector-guards.test.ts
create mode 100644 tests/truth-shipment-sector-runtime.test.ts
create mode 100644 tests/truth-standalone-shipment-sector-runtime.test.ts
create mode 100644 tests/truth-travel-shipment-sector-runtime.test.ts
create mode 100644 tests/turn-action-shipment-sector-controls.test.tsx
create mode 100644 tests/turn-action-shipment-sector.test.ts
diff --git a/components/shipment-claim-fields.tsx b/components/shipment-claim-fields.tsx
index e8bcbb9f..a72f9f63 100644
--- a/components/shipment-claim-fields.tsx
+++ b/components/shipment-claim-fields.tsx
@@ -2,9 +2,11 @@
import { TERRITORIES } from '@/game/board';
import { Input } from '@/components/ui/input';
-export type ShipmentClauseInput = { territory: string; minimum: number };
+export type ShipmentClauseInput = { territory: string; minimum: number; sector?: number };
export function invalidShipmentClause(claim: ShipmentClauseInput) {
- return !Number.isSafeInteger(claim.minimum) || claim.minimum < 1 || claim.minimum > 20;
+ return !Number.isSafeInteger(claim.minimum) || claim.minimum < 1 || claim.minimum > 20 ||
+ claim.sector !== undefined && (!Number.isSafeInteger(claim.sector) ||
+ !TERRITORIES.find(destination => destination.id === claim.territory)?.sectors.includes(claim.sector));
}
/** Destination and physical minimum shared by flat and nested question builders. */
@@ -13,12 +15,36 @@ export function ShipmentClauseFields({ id, value, onChange }: {
value: ShipmentClauseInput;
onChange: (claim: ShipmentClauseInput) => void;
}) {
+ const printed = TERRITORIES.find(destination => destination.id === value.territory);
+ // Mixed-shipment leaves have their own `kind` and remain on their existing
+ // territory-only parser until that separate question family is integrated.
+ const allowSector = !('kind' in value);
return <>
+ {allowSector && <>
+
+
+ >}
= {
actionLabel: 'shipment or ground-movement condition',
actionTiming: 'Future shipment or ground move · this turn',
actionHelp: <>Shipment conditions concern your single future original reserve shipment after the answer.
+ Choose any sector or one exact printed sector in that territory; only that sector satisfies an exact condition.
Ground-movement conditions concern one actual future ground move before your Movement turn ends this round.
Count physical forces in one action; smaller moves never add together. Earlier actions do not count.
OR keeps legal shipment and movement alternatives available. No makes the whole expression false.
@@ -28,7 +29,8 @@ const config: MixedActionConfig = {