Prototype Tleilaxu special Karama Truthtrance
Verify and publish checkpoint container / container (push) Successful in 11m6s

This commit is contained in:
Quintine committed 2026-10-29 18:35:24 +11:00
1 parent 5b8d510470
commit cfccfe5acb
15 files changed
+391 -20

No files matched your search

+23 -3
View File
@@ -19003,7 +19003,8 @@ function karamaSpendingBlock(g: Game, p: Player, card: Card, purpose?: KullPurpo
required.effect === 'karamaHarkonnenSpecial' && purpose === 'special:harkonnen' ||
required.effect === 'karamaEmperorSpecial' && purpose === 'special:emperor' ||
required.effect === 'karamaAtreidesSpecial' && purpose === 'special:atreides' ||
required.effect === 'karamaFremenSpecial' && purpose === 'special:fremen') &&
required.effect === 'karamaFremenSpecial' && purpose === 'special:fremen' ||
required.effect === 'karamaTleilaxuSpecial' && purpose === 'special:tleilaxu') &&
windowCardOpportunity(g, required.effect)?.source === required.source))
return 'Retain this opportunity without a forbidden printed Karama cost.';
const kullBlock = kullKaramaBlock(g, p, purpose);
@@ -20495,7 +20496,7 @@ function spendKarama(g: Game, p: Player, card: Card, use: KaramaUse, kullOffered
// still-open Harkonnen special promise before a foreign response can park
// the shared reconciler.
if (card.kind === 'special' && card.effect === 'karama' && auctionRows.some(row => {
return (['karamaHarkonnenSpecial', 'karamaEmperorSpecial', 'karamaAtreidesSpecial', 'karamaFremenSpecial'] as const).some(effect => {
return (['karamaHarkonnenSpecial', 'karamaEmperorSpecial', 'karamaAtreidesSpecial', 'karamaFremenSpecial', 'karamaTleilaxuSpecial'] as const).some(effect => {
const stage = row.windowCards?.[effect];
return stage && !stage.closed && windowCardOpportunity(g, effect, stage.source)?.source === stage.source;
});
@@ -22395,6 +22396,19 @@ function emptyFremenSpecialWormTerritory(g: Game, id: string): boolean {
function* nativeWindowCardActions(g: Game, actor: string, effect: WindowCardEffect): Generator<Action> {
if (!windowCardOpportunity(g, effect)) return;
const player = getPlayer(g, actor);
if (effect === 'karamaTleilaxuSpecial') {
if (player.faction !== 'tleilaxu' || g.kullPreview || g.pendingKull || g.semutaPreview ||
g.semutaRecruitsPreview || g.semutaAdvancedOrdinaryPreview || g.truthtrance || g.response ||
g.decision || g.phaseOpening || g.pendingKarama || g.pendingTreacheryDiscard ||
g.pendingNullentropy || g.pendingRevival) return;
for (const card of player.hand.filter(card => card.kind === 'special' && card.effect === 'karama'))
for (const target of g.players) {
const action: Action = { type: 'card', mode: 'special', card: card.id, target: target.id };
try { if (prepareSpecialKaramaIntent(g, actor, action).kind === 'tleilaxu') yield action; }
catch (error) { if (!(error instanceof RuleError)) throw error; }
}
return;
}
if (effect === 'karamaFremenSpecial') {
if (player.faction !== 'fremen' || g.expansions.length || g.nexusCards || g.homeworlds || g.discoveryEnabled ||
g.kullPreview || g.pendingKull || g.semutaPreview || g.semutaRecruitsPreview || g.semutaAdvancedOrdinaryPreview ||
@@ -23808,7 +23822,8 @@ function projectedTurnActionGuide(g: Game, player: Player): { event: string; act
? player.faction === 'harkonnen' ? 'karamaHarkonnenSpecial'
: player.faction === 'emperor' ? 'karamaEmperorSpecial'
: player.faction === 'atreides' ? 'karamaAtreidesSpecial'
: player.faction === 'fremen' ? 'karamaFremenSpecial' : null
: player.faction === 'fremen' ? 'karamaFremenSpecial'
: player.faction === 'tleilaxu' ? 'karamaTleilaxuSpecial' : null
: isWindowCardEffect(held?.effect) ? held.effect : null;
const windows: WindowCardEffect[] = printedWindow ? [printedWindow]
: action.type === 'decision' && action.karama === true ? ['karamaAuction']
@@ -42774,7 +42789,12 @@ function resolveSpecialKaramaEffect(g: Game, p: Player, card: Card, intent: Spec
});
} else if (intent.kind === 'tleilaxu') {
const target = intent.target;
const opportunity = windowCardOpportunity(g, 'karamaTleilaxuSpecial');
if (opportunity && card.kind === 'special' && card.effect === 'karama')
recordNativeTurnActionWindowCard(g, p.id, 'karamaTleilaxuSpecial', opportunity.source);
p.specialKaramaUsed = true;
if (liveTurnActionPromises(g.turnActionPromises ?? [], p.id, g.turn).length)
guardTurnActionPrintedCardCost(g, p, card);
g.revivalPrevention = { player: target, turn: g.turn };
if (g.pendingRevival?.nexusEmperorEvent)
finishNexusEmperorRevival(g, g.pendingRevival, 'denied');