Implement Grumman collection and private stacked Terror choices
Add conserved token collection with four bank spice, owner-only stack selection, recovery proofs, controls and AI. Preserve unresolved removal and expansion release gates. Verified 3712 offline cases, types, lint, production build, 40 HTTP cases, three-seat desktop/mobile play, and unchanged 3081 preexisting saved games.
This commit is contained in:
1 parent
28ba1618ba
commit
1db11a0187
27 files changed
+2451
-43
No files matched your search
@@ -0,0 +1,57 @@
|
||||
import type { Action, GameView } from './engine';
|
||||
|
||||
/** Use the current private projection; do not reconstruct hidden Terror supply. */
|
||||
export function grummanCollectionCanAct(g: GameView): boolean {
|
||||
return !!(
|
||||
g.status === 'playing' &&
|
||||
g.grummanCollection?.player === g.me &&
|
||||
g.decision?.kind === 'grummanCollection' &&
|
||||
g.decision.player === g.me &&
|
||||
g.decision.event === g.grummanCollection.event &&
|
||||
!g.response &&
|
||||
!g.truthtrance &&
|
||||
!g.phaseOpening &&
|
||||
!g.automaticContinuationPending
|
||||
);
|
||||
}
|
||||
|
||||
export function grummanCollectionChoice(
|
||||
g: GameView,
|
||||
token: string,
|
||||
territory: string,
|
||||
): { blocked: string | null; action: Action | null } {
|
||||
const offer = g.grummanCollection;
|
||||
let blocked: string | null = null;
|
||||
if (!grummanCollectionCanAct(g))
|
||||
blocked = 'Wait for the current choice to finish.';
|
||||
else if (offer!.blocked) blocked = offer!.blocked;
|
||||
else if (!offer!.tokens.some((candidate) => candidate.id === token))
|
||||
blocked = 'Choose a currently available Terror token.';
|
||||
else if (!offer!.destinations.some((candidate) => candidate.id === territory))
|
||||
blocked = 'Choose a current destination stronghold.';
|
||||
return {
|
||||
blocked,
|
||||
action: blocked
|
||||
? null
|
||||
: {
|
||||
type: 'decision',
|
||||
event: offer!.event,
|
||||
mode: 'add',
|
||||
token,
|
||||
territory,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function grummanCollectionActions(g: GameView): Action[] {
|
||||
if (!grummanCollectionCanAct(g)) return [];
|
||||
const offer = g.grummanCollection!;
|
||||
const choice = grummanCollectionChoice(
|
||||
g,
|
||||
offer.tokens[0]?.id ?? '',
|
||||
offer.destinations[0]?.id ?? '',
|
||||
);
|
||||
return [
|
||||
choice.action ?? { type: 'decision', event: offer.event, decline: true },
|
||||
];
|
||||
}
|
||||
Reference in new issue
Block a user