Connect ordinary Semuta in Advanced Richese preview
Verify and publish checkpoint container / container (push) Canceled after 0s

This commit is contained in:
Quintine committed 2026-10-29 04:15:28 +11:00
1 parent 3c1cbd071e
commit b93c5c4cf5
7 files changed
+287 -2

No files matched your search

+27 -2
View File
@@ -2651,6 +2651,8 @@ export type Game = {
moritaniAssassinatePreview?: true;
/** Explicit development-only neutral Semuta reaction profile. */
semutaPreview?: true;
/** Fresh Advanced classic/Richese preview, limited to ordinary discards. */
semutaAdvancedOrdinaryPreview?: true;
/** Fresh Basic independent-card Semuta preview; scoped per discard source. */
semutaRecruitsPreview?: true;
moritaniAssassinate?: MoritaniAssassinateState;
@@ -7915,6 +7917,10 @@ function tupileDiscardSignature(g: Game, c: TupileDiscardContinuation) {
}
function treacheryDiscardIntegrity(g: Game) {
const discovery = g.discoveryEnabled === true && !!g.discoveries && discoveryModeSupported(g);
requireRule(g.semutaAdvancedOrdinaryPreview === undefined ||
g.semutaAdvancedOrdinaryPreview === true && !g.semutaPreview && !g.semutaRecruitsPreview &&
bareAdvancedClassicSemutaProfile(g),
'This Advanced ordinary Semuta preview no longer matches its original Richese profile.');
requireRule(g.semutaRecruitsPreview === undefined || g.semutaRecruitsPreview === true &&
basicIndependentRecruitsSemutaProfile(g) && !g.semutaPreview,
'This Recruits Semuta preview no longer matches its original Basic profile.');
@@ -9718,7 +9724,12 @@ function semutaOfferSupported(
continuation.kind === 'choamLaLaLaDiscard' || continuation.kind === 'choamBalisetDiscard' ||
continuation.kind === 'choamGamontDiscard' || continuation.kind === 'choamJubbaDiscard' ||
continuation.kind === 'karamaShipmentPriceDiscard';
return (g.semutaPreview === true || g.semutaRecruitsPreview === true &&
return (g.semutaPreview === true ||
g.semutaAdvancedOrdinaryPreview === true && bareAdvancedClassicSemutaProfile(g) &&
(!g.pendingTreacheryDiscard || !!g.pendingTreacheryDiscard.reaction) &&
continuation.kind === 'ordinaryCardDiscard' &&
['hajr', 'ghola', 'harvester', 'weather'].includes(continuation.effect) ||
g.semutaRecruitsPreview === true &&
(!g.pendingTreacheryDiscard || !!g.pendingTreacheryDiscard.reaction) &&
(independentNativeDiscard || continuation.kind === 'ordinaryCardDiscard' &&
['hajr', 'ghola', 'harvester', 'weather', 'atomics'].includes(continuation.effect) ||
@@ -10881,7 +10892,10 @@ function startModules(state: Game): Game {
if (g.homeworlds)
return g.expansions.length ? initializeHomeworldOccupationGameForAudit(g) : initializeHomeworldGameForAudit(g);
if (g.strongholdCards) return initializeStrongholdFactionsGameForAudit(g);
return initializeFactionExpansionsGame(g, bareBasicSemutaProfile(g));
const advancedOrdinarySemuta = bareAdvancedClassicSemutaProfile(g);
const initialized = initializeFactionExpansionsGame(g, bareBasicSemutaProfile(g));
if (advancedOrdinarySemuta) initialized.semutaAdvancedOrdinaryPreview = true;
return initialized;
}
/** Public consistency only; each module's genuine initializer validates its own envelope. */
function baseStartProfileBlock(g: Game): string | null {
@@ -13253,6 +13267,16 @@ function bareBasicSemutaProfile(g: Game): boolean {
!g.strongholdCards && !g.ecazTreachery && !g.discoveryEnabled &&
!g.discoveries && !g.discoveryStash && !g.greatMaker;
}
/** Fresh Advanced Richese starts with only the CHOAM deck and classic peers.
* The existing discard continuation decides which offers are supported. */
function bareAdvancedClassicSemutaProfile(g: Game): boolean {
return g.advanced === true && g.players.length >= 2 && g.players.length <= 6 &&
g.expansions.length === 1 && g.expansions[0] === 'choam' && !!byFaction(g, 'richese') &&
g.players.every(p => p.faction === 'richese' || p.faction === 'choam' || faction(p.faction).expansion === 'base') &&
!g.homeworlds && !g.nexusCards && !g.leaderSkills && !g.techTokens &&
!g.strongholdCards && !g.ecazTreachery && !g.discoveryEnabled &&
!g.discoveries && !g.discoveryStash && !g.greatMaker && !g.kullPreview && !g.nexusKullPreview;
}
/** Collection's printed bonus is Advanced-only. This fresh development entry
* retains original Ecaz/Richese setup without admitting unrelated E3 overlays. */
function bareAdvancedEcazSemutaProfile(g: Game): boolean {
@@ -47066,6 +47090,7 @@ export function viewGame(state: Game, id: string, now?: number) {
botsPending: g.botsPending ?? false,
semutaReaction: projectedSemutaReaction(g, me),
semutaPreview: g.semutaPreview === true,
semutaAdvancedOrdinaryPreview: g.semutaAdvancedOrdinaryPreview === true,
semutaRecruitsPreview: g.semutaRecruitsPreview === true,
automaticContinuationPending: (!!g.pendingTreacheryDiscard && !g.pendingTreacheryDiscard.reaction) || homeworldRevealPending(g) || homeworldShipmentAutomatic(g) || homeworldOccupiedIncomeAutomatic(g) || grummanCollectionAutomatic(g) || tupileAutomatic(g),
botNextActionAt: g.botNextActionAt ?? null,