Allow Richese No-Field reveal during Basic openings and markets
Verify and publish checkpoint container / container (push) Canceled after 0s

This commit is contained in:
Quintine committed 2026-10-29 07:27:08 +11:00
1 parent ac7db3cb35
commit 0d55333d5d
9 files changed
+617 -3

No files matched your search

+14 -1
View File
@@ -664,6 +664,7 @@ import { resolveBattleWeapons } from './effective-weapons';
import { choamGholaEvent, choamGholaSkillOfferEvent, choamGholaSkillSignature, choamMarketGholaError, choamSaleGholaTiming, type ChoamMarketGhola } from './choam-market-ghola';
import { quoteAdvisorPreparationWindow, quoteAdvisorPreparation, validateAdvisorPreparation, projectAdvisorPreparationWindow, AdvisorPreparationError, type AdvisorPreparationWindow, type AdvisorPreparationSource } from './advisor-preparation-window';
import { quoteFremenRevivalGrant, validateFremenRevivalGrant, projectFremenRevivalGrant, projectFremenGroupRevivalGrant, FremenRevivalGrantError, type FremenRevivalGrantSource } from './fremen-revival-grant';
import { richeseRevealInterruptSupported } from './richese-reveal-interruption';
import { splitOrdinaryPayments, type OrdinaryPayment } from './ordinary-payment-plan';
import {
charityAmount,
@@ -4905,7 +4906,8 @@ function noFieldRevealBlock(g: Game, p: Player): string | null {
if (g.status !== 'playing' || g.phase >= 6)
return 'Voluntary No-Field reveal is available before the Battle phase.';
if (!p.noField?.deployed) return 'No concealed No-Field is deployed.';
if (g.truthtrance || g.phaseOpening || g.response || g.decision)
if ((g.truthtrance || g.phaseOpening || g.response || g.decision) &&
!richeseRevealInterruptSupported(g))
return 'Resolve the pending interaction before revealing the No-Field.';
return null;
}
@@ -5813,6 +5815,7 @@ export function createGame(
spiceDiscard: [[], []],
spice: {},
log: [{ seq: 1, text: `${host.name} opened the table.` }],
truthHistory: [],
stormDials: {},
stormPending: null,
stormCard: null,
@@ -43285,6 +43288,16 @@ function applyActionInner(
);
requireRule(g.status !== 'finished', 'This game has ended.');
const t = action.type;
if (t === 'revealNoField' && richeseRevealInterruptSupported(g)) {
requireRule(p.faction === 'richese', 'Only Richese controls the concealed token.');
const blocked = noFieldRevealBlock(g, p);
requireRule(!blocked, blocked ?? 'Voluntary reveal is unavailable.');
requireRule(Object.keys(action).sort().join(',') === 'event,token,type' &&
action.event === p.noFieldEvent && action.token === p.noField?.deployed?.tokenId,
'This No-Field reveal selection is stale.');
revealPlayerNoField(g, p, 'voluntary');
return g;
}
if (g.pendingEmperorAuctionGift && !g.response && !g.pendingKarama) {
const pending = g.pendingEmperorAuctionGift;
if (t === 'advanceBots') return g;