Combine current-turn payments with shipment and movement promises

This commit is contained in:
Quintine committed 2026-10-26 21:09:49 +11:00
1 parent 8dbec05844
commit 0d72a33ee5
18 files changed
+2591 -7

No files matched your search

+24 -2
View File
@@ -3,6 +3,9 @@
import { TravelClaimFields, travelClaimInputError } from './travel-claim-fields';
import { TravelAnswers } from './travel-promises';
import type { TravelActionClaim } from '@/game/travel-expression-promises';
import { TurnActionFields, turnActionInputError } from './turn-action-fields';
import { TurnActionAnswers } from './turn-action-promises';
import type { TurnActionLeaf } from '@/game/turn-action-promises';
import { MixedTraitorFields, mixedTraitorInputError } from './mixed-traitor-fields';
import type { TraitorActionClaim } from '@/game/mixed-traitor-question';
@@ -93,7 +96,7 @@ export function Truthtrance({
g.players.find((p) => p.id !== me.id)!.id,
);
const [kind, setKind] = useState<
'fact' | 'freeform' | 'battlePlan' | 'shipment' | 'mixedShipment' | 'movement' | 'traitorCall' | 'bid' | 'revival' | 'bribe' | 'alliance' | 'leaderRevival' | 'revivalExpression' | 'bribeExpression' | 'movementExpression' | 'mixedMovement' | 'mixedBribe' | 'mixedRevival' | 'mixedBid' | 'allianceExpression' | 'mixedAlliance' | 'mixedBattlePlan' | 'mixedTraitorCall' | 'travel'
'fact' | 'freeform' | 'battlePlan' | 'shipment' | 'mixedShipment' | 'movement' | 'traitorCall' | 'bid' | 'revival' | 'bribe' | 'alliance' | 'leaderRevival' | 'revivalExpression' | 'bribeExpression' | 'movementExpression' | 'mixedMovement' | 'mixedBribe' | 'mixedRevival' | 'mixedBid' | 'allianceExpression' | 'mixedAlliance' | 'mixedBattlePlan' | 'mixedTraitorCall' | 'travel' | 'turnActions'
>('fact');
const [revivalLeader, setRevivalLeader] = useState(g.allLeaders.find(leader =>
leader.faction === g.players.find(player => player.id === target)?.faction)?.id ?? '');
@@ -175,6 +178,12 @@ export function Truthtrance({
{ kind: 'action', action: { kind: 'move', territory: 'arrakeen', minimum: 1 } },
] });
const travelError = travelClaimInputError(travel, g, target);
const [turnActions, setTurnActions] = useState<MixedActionExpression<TurnActionLeaf>>({ kind: 'and', terms: [
{ kind: 'action', action: { kind: 'payment', recipient: g.me, minimum: 1 } },
{ kind: 'action', action: { kind: 'ship', territory: 'carthag', minimum: 1 } },
{ kind: 'action', action: { kind: 'move', territory: 'arrakeen', minimum: 1 } },
] });
const turnActionsError = turnActionInputError(turnActions, g, target);
const [shipment, setShipment] = useState<ShipmentExpression>({ territory: 'carthag', minimum: 6 });
const [mixed, setMixed] = useState<MixedShipmentExpression>({
kind: 'and',
@@ -211,6 +220,7 @@ export function Truthtrance({
claim: planClaim,
}
: kind === 'mixedBattlePlan' ? { kind, target, battle: g.battle?.event ?? null, territory: g.battle?.territory ?? '', mixed: mixedBattle }
: kind === 'turnActions' ? { kind, target, turn: g.turn, mixed: turnActions }
: kind === 'travel' ? { kind, target, turn: g.turn, mixed: travel }
: kind === 'mixedTraitorCall' ? { kind, target, battle: g.battle?.event ?? '', territory: g.battle?.territory ?? '', mixed: mixedTraitor }
: kind === 'traitorCall' ? { kind, target, battle: g.battle?.event ?? '', territory: g.battle?.territory ?? '' }
@@ -441,6 +451,8 @@ export function Truthtrance({
<div key={answer}>{button(answer === 'unknown' ? 'I don’t know yet' : `Answer ${answer === 'yes' ? 'Yes' : 'No'}`, { type: 'truthAnswer', answer })}</div>
))}
</>
) : w.question!.kind === 'turnActions' ? (
<TurnActionAnswers game={g} act={act} busy={busy} />
) : w.question!.kind === 'travel' ? (
<TravelAnswers game={g} act={act} busy={busy} />
) : w.question!.kind === 'traitorCall' || w.question!.kind === 'mixedTraitorCall' ? (
@@ -569,6 +581,7 @@ export function Truthtrance({
<option value="mixedBid">Combine current facts and ordinary bids</option>
<option value="traitorCall">Bind this battle’s Traitor declaration</option>
<option value="mixedTraitorCall">Combine current facts and this Traitor declaration</option>
<option value="turnActions">Combine this turn’s payments, shipment and ground movements</option>
<option value="travel">Combine this turn’s shipment and ground movements</option>
<option value="shipment">
Bind a shipment from reserves
@@ -585,7 +598,15 @@ export function Truthtrance({
)}
</select>
</label>
{kind === 'travel' ? (
{kind === 'turnActions' ? (
<>
<TurnActionFields value={turnActions} game={g} target={target}
disabled={busy || !g.truthTurnActionTargets.includes(target)} onChange={setTurnActions} />
{!g.truthTurnActionTargets.includes(target) && <p className="notice">Choose a player with a supported payment, shipment or ground-movement opportunity this turn.
Ordinary payments may remain available after their Shipment and Movement opportunity ends.</p>}
<p className="notice" aria-label="Public turn-action question preview">{turnActionsError ?? truthQuestionText(question, leaderName, locationName, name)}</p>
</>
) : kind === 'travel' ? (
<>
<TravelClaimFields value={travel} game={g} target={target}
disabled={busy || !g.truthTravelTargets.includes(target)} onChange={setTravel} />
@@ -833,6 +854,7 @@ export function Truthtrance({
(kind === 'revival' && (!!revivalClaimInputError(revivalClaim) || !g.truthRevivalTargets.includes(target))) ||
(kind === 'mixedBid' && (!!mixedBidError || !g.truthMixedBidTargets.includes(target))) ||
(kind === 'bid' && (!!bidClaimInputError(bidClaim) || !g.truthBidTargets.includes(target))) ||
(kind === 'turnActions' && (!!turnActionsError || !g.truthTurnActionTargets.includes(target))) ||
(kind === 'travel' && (!!travelError || !g.truthTravelTargets.includes(target))) ||
(kind === 'mixedTraitorCall' && (!!mixedTraitorError || !g.truthMixedTraitorTargets.includes(target))) ||
(kind === 'traitorCall' && !g.truthTraitorTargets.includes(target)) ||