feat: restore final CHOAM Mentat after Semuta Gamont reactions

This commit is contained in:
Quintine committed 2026-10-12 03:37:23 +11:00
1 parent c468dc9e44
commit 12e4bcbf45
7 files changed
+145 -7

No files matched your search

+6 -1
View File
@@ -1399,6 +1399,7 @@ export type Game = {
location: string;
elite?: 1;
noFieldEvent?: string;
mentat?: true;
stateSignature: string;
}
| {
@@ -5259,6 +5260,7 @@ function choamGamontDiscardSignature(g: Game, c: ChoamGamontDiscardContinuation)
return JSON.stringify({
player: c.player, card: c.card, target: c.target, location: c.location,
elite: c.elite, noFieldEvent: c.noFieldEvent,
mentat: c.mentat, mentatPending: c.mentat ? g.choamMentatPending : undefined,
turn: g.turn, phase: g.phase, active: g.active, order: g.order,
ready: g.ready, storm: g.storm,
parent: nullentropyParentSignature(g,
@@ -5972,6 +5974,7 @@ function treacheryDiscardIntegrity(g: Game) {
(c.elite === undefined || c.elite === 1) &&
(c.noFieldEvent === undefined ||
(typeof c.noFieldEvent === 'string' && c.noFieldEvent.length > 0)) &&
(c.mentat === undefined || (c.mentat === true && g.choamMentatPending === true)) &&
gamontAvailable(g, c.target, c.location, c.elite ?? 0, c.noFieldEvent) &&
!g.pendingChoamWorthless && !g.response && !g.decision &&
!g.phaseOpening && !g.choamMarket &&
@@ -6966,6 +6969,7 @@ function finishTreacheryDiscard(g: Game, claim?: { player: string; card: string
} else if (next.kind === 'choamGamontDiscard') {
completeChoamGamont(g, getPlayer(g, next.player), next.target,
next.location, next.elite ?? 0, next.noFieldEvent);
if (next.mentat) g.decision = { kind: 'choamMentat', player: next.player };
} else if (next.kind === 'choamJubbaDiscard') {
completeChoamJubba(g, getPlayer(g, next.player), next.territory);
offerChoamStorm(g);
@@ -24059,7 +24063,7 @@ function finishResponse(g: Game, canceled: boolean,bureaucratDiversion?:number)
} else if (pending.effect === 'gamont') {
if (g.semutaPreview && used.name === 'Trip to Gamont' &&
!pending.storm && !pending.revival && !pending.movement &&
!pending.mentat && !pending.nexusEvent) {
!pending.nexusEvent) {
const continuation: ChoamGamontDiscardContinuation = {
kind: 'choamGamontDiscard', player: choam.id,
card: used.id, target: pending.target!,
@@ -24067,6 +24071,7 @@ function finishResponse(g: Game, canceled: boolean,bureaucratDiversion?:number)
};
if (pending.elite === 1) continuation.elite = 1;
if (pending.noFieldEvent) continuation.noFieldEvent = pending.noFieldEvent;
if (pending.mentat) continuation.mentat = true;
const entries = [{ card: used, discardedBy: choam.id, publicFace: true }];
if (semutaOfferSupported(g, continuation, entries)) {
continuation.stateSignature = choamGamontDiscardSignature(g, continuation);
+1
View File
@@ -1178,6 +1178,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'A clean Distrans transfer during battle also offers only the used Distrans. The private card has already reached its recipient; claim or Continue cannot repeat the gift or change a sealed plan. A recipient holding Semuta may claim the used Distrans and keep the already-transferred card.',
'Reactive Baliset and La La La also offer their used card after the accepted cost. The original uncommitted move or free-revival request is already stopped: claim or Continue installs the original restriction without moving forces, consuming movement, reviving or charging the denied request. Another legal move or paid revival remains available. Movement-card, Ambassador, Nexus and other competing parents remain separate.',
'A clean proactive Trip to Gamont also pauses for a selected elite or concealed No-Field. Claim or Continue returns the exact selected physical counter, or performs the native No-Field reveal and returns at most one actual force after reserve-capped materialization. A zero token reveals without inventing a force; taking the used card does not undo that effect or spend revival usage.',
'Trip to Gamont in CHOAM’s final Mentat opportunity also offers the used card. Claim or Continue completes the selected return and restores that same CHOAM-owned opportunity. It does not check victory or advance the turn: CHOAM must still choose Finish and check victory, using the changed board.',
'The same local semuta entry also admits Basic native Richese and Moritani with classic opponents, exactly CHOAM/Ecaz decks and no optional modules. A clean shipment/movement Sabotage or Robbery overflow offers its private fresh discard without showing the face before commitment. Claim or Continue preserves the original victim/draw, removed token, shipment payment and forces; Sabotage may then offer its original optional gift. Advanced Moritani, native Ecaz, Ix/E3 mixtures and worm/Ambassador/overlap arrivals remain outside this bounded entry. The table visibly labels the development preview.',
] : []),
],