Extend Advanced Semuta to CHOAM and Residual Poison
Verify and publish checkpoint container / container (push) Canceled after 0s

This commit is contained in:
Quintine committed 2026-10-29 04:22:56 +11:00
1 parent b2bc3f2f01
commit 3a27c29a03
8 files changed
+302 -10

No files matched your search

+16 -7
View File
@@ -9732,6 +9732,10 @@ function semutaOfferSupported(
continuation.kind === 'battleResolved' || continuation.kind === 'winnerMandatoryDiscard' ||
continuation.kind === 'battleCleanup' && continuation.source === 'winner' ||
continuation.kind === 'nullentropyDiscard' || continuation.kind === 'distransDiscard' ||
continuation.kind === 'residualPoisonDiscard' || continuation.kind === 'choamSaleDiscard' ||
((continuation.kind === 'choamKulonDiscard' || continuation.kind === 'choamLaLaLaDiscard' ||
continuation.kind === 'choamBalisetDiscard' || continuation.kind === 'choamGamontDiscard' ||
continuation.kind === 'choamJubbaDiscard') && continuation.nexusEvent === undefined) ||
continuation.kind === 'truthtranceDiscard' && continuation.promise === null &&
(continuation.record.question.kind === 'fact' || continuation.record.question.kind === 'freeform')) ||
g.semutaRecruitsPreview === true &&
@@ -13259,6 +13263,11 @@ function basicIndependentRecruitsSemutaProfile(g: Game): boolean {
function semutaCardProducerEnabled(g: Game): boolean {
return g.semutaPreview === true || g.semutaRecruitsPreview === true && basicIndependentRecruitsSemutaProfile(g);
}
/** The public Advanced profile supports only the explicitly admitted native costs. */
function semutaAdvancedNativeProducerEnabled(g: Game): boolean {
return semutaCardProducerEnabled(g) ||
g.semutaAdvancedOrdinaryPreview === true && bareAdvancedClassicSemutaProfile(g);
}
/** Bare native Basic starts share the original deck/roster validation. Optional
* modules retain their own explicit Semuta envelopes; saved games are not upgraded. */
function bareBasicSemutaProfile(g: Game): boolean {
@@ -30873,7 +30882,7 @@ function playResidualPoison(
`${p.name} played Residual Poison against ${target.name}. ${victim.name} was randomly selected from the available leaders and sent to the Tanks. No spice is awarded, no forces are lost, and battle preparation continues.`,
{ faction: p.faction, name: 'Residual Poison' },
);
if (g.semutaPreview || g.semutaRecruitsPreview && basicIndependentRecruitsSemutaProfile(g)) {
if (semutaAdvancedNativeProducerEnabled(g)) {
const continuation: ResidualPoisonDiscardContinuation = {
kind: 'residualPoisonDiscard', player: p.id, target: target.id,
victim: victim.id, battleEvent: b.event!, card: used.id,
@@ -37189,7 +37198,7 @@ function finishResponse(g: Game, canceled: boolean, settlement?: BureaucratSettl
}
if (pending.effect === 'kulon') {
rememberMovementDiscards(g, [{ card: used, discardedBy: choam.id, publicFace: pending.nexusEvent === undefined }]);
if (semutaCardProducerEnabled(g) && (used.name === 'Kulon' || pending.nexusEvent) &&
if (semutaAdvancedNativeProducerEnabled(g) && (used.name === 'Kulon' || pending.nexusEvent) &&
!pending.storm && !pending.revival && !pending.movement &&
!pending.mentat) {
const continuation: ChoamKulonDiscardContinuation = {
@@ -37207,7 +37216,7 @@ function finishResponse(g: Game, canceled: boolean, settlement?: BureaucratSettl
}
completeChoamKulon(g, choam);
} else if (pending.effect === 'jubba') {
if (semutaCardProducerEnabled(g) && (used.name === 'Jubba Cloak' || pending.nexusEvent) &&
if (semutaAdvancedNativeProducerEnabled(g) && (used.name === 'Jubba Cloak' || pending.nexusEvent) &&
pending.storm && !pending.revival && !pending.movement &&
!pending.mentat) {
const continuation: ChoamJubbaDiscardContinuation = {
@@ -37224,7 +37233,7 @@ function finishResponse(g: Game, canceled: boolean, settlement?: BureaucratSettl
}
completeChoamJubba(g, choam, pending.location!);
} else if (pending.effect === 'baliset') {
if (semutaCardProducerEnabled(g) && (used.name === 'Baliset' || pending.nexusEvent) &&
if (semutaAdvancedNativeProducerEnabled(g) && (used.name === 'Baliset' || pending.nexusEvent) &&
!pending.storm && !pending.revival && !pending.mentat &&
(!pending.movement || (g.pendingChoamMove && !g.pendingChoamMove.source &&
!g.pendingChoamMove.ornithopterEvent && !g.pendingChoamMove.ornithopterRange &&
@@ -37259,7 +37268,7 @@ function finishResponse(g: Game, canceled: boolean, settlement?: BureaucratSettl
if (ambassador) offerAmbassadorRelocation(g);
}
} else if (pending.effect === 'gamont') {
if (semutaCardProducerEnabled(g) && (used.name === 'Trip to Gamont' || pending.nexusEvent) &&
if (semutaAdvancedNativeProducerEnabled(g) && (used.name === 'Trip to Gamont' || pending.nexusEvent) &&
!pending.storm && !pending.revival && !pending.movement) {
const continuation: ChoamGamontDiscardContinuation = {
kind: 'choamGamontDiscard', player: choam.id,
@@ -37281,7 +37290,7 @@ function finishResponse(g: Game, canceled: boolean, settlement?: BureaucratSettl
pending.elite!, pending.noFieldEvent,
{ card: used.id, mentat: pending.mentat, nexusEvent: pending.nexusEvent });
} else {
if (semutaCardProducerEnabled(g) && (used.name === 'La La La' || pending.nexusEvent) &&
if (semutaAdvancedNativeProducerEnabled(g) && (used.name === 'La La La' || pending.nexusEvent) &&
!pending.storm && !pending.movement && !pending.mentat &&
(!pending.revival || (g.pendingRevival?.kind === 'forces' &&
g.pendingRevival.player === pending.target))) {
@@ -37563,7 +37572,7 @@ function finishResponse(g: Game, canceled: boolean, settlement?: BureaucratSettl
owner.spice += sale.price;
log(g, `${owner.name} received ${sale.price} spice from the card sale.`);
delete market.sale;
if (semutaCardProducerEnabled(g)) {
if (semutaAdvancedNativeProducerEnabled(g)) {
const continuation: ChoamSaleDiscardContinuation = {
kind: 'choamSaleDiscard', owner: owner.id, card: used.id,
witness: sale.witness ?? null, price: sale.price,