Support multiple named Ghola commitments
Verify and publish checkpoint container / container (push) Canceled after 0s

This commit is contained in:
Quintine committed 2026-10-29 17:50:08 +11:00
1 parent 6c1530382d
commit bdd5aaf18c
8 files changed
+286 -26

No files matched your search

+22 -10
View File
@@ -14,25 +14,37 @@ export function GholaLeaderPromiseGuideButton(props: Props) {
if (!guide) return null;
const actor = game.me, turn = game.turn, phase = game.phase, action = guide.action;
const signature = JSON.stringify(action), quote = game.ghola, quoteSignature = JSON.stringify(quote);
const box = game.nullentropy, search = box?.search, boxSignature = JSON.stringify(box);
const card = game.players.find(player => player.id === actor)?.hand?.find(c => c.id === action.card);
const canAct = () => {
const current = props.game, me = current.players.find(player => player.id === actor);
const named = typeof action.leader === 'string' && liveGholaLeaderPromises(current.gholaLeaderPromises, actor, turn)
.some(promise => promise.answer && promise.leader === action.leader);
return !props.busy && current === game && current.status === 'playing' && current.me === actor &&
current.turn === turn && current.phase === phase && current.gholaLeaderPromiseGuide === guide &&
guide.action === action && JSON.stringify(action) === signature && action.type === 'card' &&
action.mode === undefined && typeof action.card === 'string' && !!named && !!me && !me.autopilot &&
!!card && card.kind === 'special' && card.effect === 'ghola' && me.hand?.includes(card) &&
const live = liveGholaLeaderPromises(current.gholaLeaderPromises, actor, turn).filter(promise => promise.answer);
const named = typeof action.leader === 'string' && live.some(promise => promise.leader === action.leader);
const ghola = action.type === 'card' && action.mode === undefined && typeof action.card === 'string' && !!named &&
!!card && card.kind === 'special' && card.effect === 'ghola' && !!me?.hand?.includes(card) &&
current.ghola === quote && JSON.stringify(quote) === quoteSignature && quote.available &&
quote.cards.includes(action.card) && (action.leader === 'kwisatz' ? quote.kwisatz
: quote.leaders.some(leader => leader.id === action.leader)) &&
!current.truthtrance && !current.response && !current.decision && !current.phaseOpening &&
: quote.leaders.some(leader => leader.id === action.leader)) && !current.decision;
const startBox = action.type === 'card' && action.mode === undefined && typeof action.card === 'string' &&
!!card && card.kind === 'special' && card.effect === 'nullentropyBox' && !!me?.hand?.includes(card) &&
current.nullentropy === box && JSON.stringify(box) === boxSignature && !!box &&
box.card.id === card.id && !box.blocked && !box.search && !current.decision;
const chooseBox = action.type === 'decision' && typeof action.card === 'string' &&
current.decision?.kind === 'nullentropy' && current.decision.player === actor &&
current.nullentropy === box && JSON.stringify(box) === boxSignature && !!search &&
box?.search === search && search.event === action.event && !box.blocked &&
search.cards.some(candidate => candidate.id === action.card && candidate.effect === 'ghola');
return !props.busy && current === game && current.status === 'playing' && current.me === actor &&
current.turn === turn && current.phase === phase && current.gholaLeaderPromiseGuide === guide &&
guide.action === action && JSON.stringify(action) === signature && live.length > 0 && !!me && !me.autopilot &&
(ghola || startBox || chooseBox) && !current.truthtrance && !current.response && !current.phaseOpening &&
!current.automaticContinuationPending && !current.roomControl?.paused && !current.roomControl?.closed;
};
return <Button className="game-action min-h-11 whitespace-normal" data-testid="ghola-leader-promise-guide"
disabled={!canAct()} onClick={() => { if (canAct()) props.send(action); }}>
Revive {leaderName(game, typeof action.leader === 'string' ? action.leader : '')} with Ghola while honoring your answer
{action.type === 'decision' ? 'Recover Ghola from your paid Nullentropy Box search'
: card?.effect === 'nullentropyBox' ? 'Pay 2 spice to search with Nullentropy Box for your Ghola answer'
: `Revive ${leaderName(game, typeof action.leader === 'string' ? action.leader : '')} with Ghola while honoring your answer`}
</Button>;
}