Connect Semuta to Moritani initial battle discards
This commit is contained in:
1 parent
d0e4c177e4
commit
0406fc1869
10 files changed
+283
-15
No files matched your search
@@ -156,6 +156,9 @@ export type BattleResolutionInput = {
|
||||
physicalCards: readonly { id: string }[];
|
||||
pendingAuditorPresent: boolean;
|
||||
pendingRetentionPresent: boolean;
|
||||
/** Selected Basic Semuta serialization: dispose mandatory loser cards before
|
||||
* reserving the eligible native Moritani ally-retention choices. */
|
||||
nativeMoritaniEarlyMandatoryDiscard?: boolean;
|
||||
/** Open the same loser window regardless of private Moritani Nexus custody. */
|
||||
nexusMoritani?: boolean;
|
||||
};
|
||||
@@ -966,16 +969,17 @@ function calculate(input: BattleResolutionInput): BattleResolutionQuote {
|
||||
const loser = winner === a ? d : a,
|
||||
loserPlayed = loser === a ? played.attacker : played.defender;
|
||||
const retainablePlayed = loserPlayed.filter(
|
||||
(selected) => !mandatorySkillDiscard(loser, selected),
|
||||
);
|
||||
const eligible = retainablePlayed.filter(
|
||||
(selected) =>
|
||||
canRetainBattleCard(
|
||||
card(loser, selected)!,
|
||||
ac || dc,
|
||||
!!loser.poisonTooth,
|
||||
),
|
||||
!mandatorySkillDiscard(loser, selected) &&
|
||||
(!input.nativeMoritaniEarlyMandatoryDiscard || !moritani ||
|
||||
canRetainBattleCard(
|
||||
card(loser, selected)!,
|
||||
ac || dc,
|
||||
!!loser.poisonTooth,
|
||||
)),
|
||||
);
|
||||
const eligible = retainablePlayed.filter((selected) =>
|
||||
canRetainBattleCard(card(loser, selected)!, ac || dc, !!loser.poisonTooth));
|
||||
if (
|
||||
moritani &&
|
||||
loser.id !== moritani.id &&
|
||||
|
||||
+5
-3
@@ -9188,13 +9188,13 @@ function treacheryDiscardIntegrity(g: Game) {
|
||||
'The committed Kaitain discard no longer matches its payment and closing opportunity.');
|
||||
} else throw new RuleError('Unknown saved discard continuation.');
|
||||
if (pending.reaction && g.moritaniRetention &&
|
||||
(continuation.kind === 'winnerMandatoryDiscard' ||
|
||||
(continuation.kind === 'battleResolved' || continuation.kind === 'winnerMandatoryDiscard' ||
|
||||
(continuation.kind === 'battleCleanup' && continuation.source === 'winner'))) {
|
||||
const retention = g.moritaniRetention;
|
||||
const owner = getPlayer(g, retention.owner), loser = getPlayer(g, retention.player);
|
||||
requireRule(!g.advanced && retention.source === undefined && retention.stage === 'choose' &&
|
||||
owner.faction === 'moritani' && owner.ally === loser.id && loser.ally === owner.id,
|
||||
'The pending native allied retention no longer matches the preceding winner discard.');
|
||||
'The pending native allied retention no longer matches the preceding battle discard.');
|
||||
currentBattleAftermathQuote(g);
|
||||
}
|
||||
}
|
||||
@@ -9393,7 +9393,8 @@ function semutaOfferSupported(
|
||||
continuation.kind === 'battleResolved') &&
|
||||
((g.pendingWinnerDiscards && continuation.kind !== 'battleResolved') ||
|
||||
(g.moritaniRetention && (g.advanced || g.moritaniRetention.source !== undefined ||
|
||||
g.moritaniRetention.stage !== 'choose' || continuation.kind === 'battleResolved')) ||
|
||||
g.moritaniRetention.stage !== 'choose' ||
|
||||
(continuation.kind === 'battleResolved' && !bareBasicSemutaProfile(g)))) ||
|
||||
g.pendingIxSubstitution)) return false;
|
||||
if (continuation.kind === 'terrorDiscard' &&
|
||||
(!childTerrorDiscard && (continuation.entry.resume !== 'none' ||
|
||||
@@ -32487,6 +32488,7 @@ function currentBattleResolutionInput(g: Game, canceledVoter?: string): BattleRe
|
||||
physicalCards: physicalTreacheryCards(g),
|
||||
pendingAuditorPresent: !!g.pendingAuditor,
|
||||
pendingRetentionPresent: !!g.moritaniRetention,
|
||||
nativeMoritaniEarlyMandatoryDiscard: !!g.semutaPreview && bareBasicSemutaProfile(g),
|
||||
nexusMoritani: !!g.nexusCards?.cards && !byFaction(g, 'moritani'),
|
||||
...(b.stoneAllocation ? { stoneAllocations: b.stoneAllocation.selections } : {}),
|
||||
};
|
||||
|
||||
+1
-1
@@ -1343,7 +1343,7 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
'Mandatory and winner battle discards also pause before a native Auditor opportunity. Claim or Continue preserves the original survival limit and opponent-used card identities, then eligibility and the full cancellation price use the current opposing hand. A card acquired from the other combatant can be eligible if the audited player did not use it. Payment or private inspection resumes once; only CHOAM receives the historical snapshot.',
|
||||
'Fresh three-through-six-seat Basic/Advanced Richese games with CHOAM and optional Ix may retain original unused Tech Tokens under the existing native roster prerequisites. Mandatory and winner discards now offer Semuta before the original winner takes one loser-owned token. Claim or Continue leaves every token and income ledger in place until original cleanup finishes; the winner’s selected award still precedes Face Dance. Advanced may additionally retain original unused Stronghold Cards at two through six seats; combining Tech requires three through six. The six separate public module cards remain unowned until the actual final Mentat assignment, using the board after effects such as Gamont. Neither Semuta claim nor its original closing CHOAM continuation awards a Stronghold Card early. Original Leader Skills require the explicit entry described below; other overlays and the separate Basic Moritani entry remain excluded.',
|
||||
'A mandatory loser-card discard may also offer Semuta while the original winner’s compulsory used card remains reserved. For native Ixians, claim or Continue settles the original casualties, then restores the one-for-one Suboid/Cyborg substitution and its Karama response. The winning used Poison Tooth is not discarded until substitution or decline finishes; only then is that physical Tooth a separate fresh target before optional winner cleanup.',
|
||||
'In the Basic native Moritani entry, winner compulsory/optional card discards may pause before the losing ally’s original retention choice. After that ally chooses one eligible played card or declines, native Karama finishes first; the completed unkept-card batch then offers Semuta. A kept or unrelated hand card is never a target. Multiple fresh cards require commitment and one private selection; taking a winner’s card does not add it to the original retention pool. Advanced Moritani, Nexus retention and unresolved casualty parents remain separate.',
|
||||
'In the Basic native Moritani entry, mandatory loser cards such as Cheap Hero are discarded first and may offer Semuta before winner cleanup and the losing ally’s original retention choice. After the ally chooses one eligible played card or declines, native Karama finishes first; the completed unkept-card batch offers Semuta separately. This split ordering is provisional. A kept or unrelated hand card is never a target. Multiple cards in the same fresh batch require commitment and one private selection; taking a discarded card does not add it to the retention pool. Advanced Moritani, Nexus retention and unresolved casualty parents remain separate.',
|
||||
'A printed Karama canceling native Harkonnen capture, CHOAM Auditor or quoted battle income, Ixian casualty substitution, or Basic Moritani allied retention now offers that exact public cost before the original cancellation finishes. Claim or Continue restores the saved response and cancels once. Acquiring the cost card cannot restore a captive, inspect a hand, pay the canceled income, exchange casualties or keep the proposed allied card. Later native card cleanup and markets still finish; Worthless conversion, other cancellations and module combinations remain separate.',
|
||||
'A printed-role Karama stopping Richese’s compulsory cache auction or allied card gift also offers its exact used cost before prevention completes. Claim or Continue resumes that original prevention once. The cache keeps its cards and frozen ordinary count, including any completed Black Market reduction; a prevented gift stays with Richese and its original parent resumes. Recovering Karama does not repeat the attempt, transfer the gift or replay a paid purchase. Existing gift retry protection remains.',
|
||||
'When Semuta itself was proposed as the now-prevented allied gift, its donor may spend it to claim that counter’s used cost. Prevention first retains Semuta and restores the original parent; the same committed response then spends Semuta and takes the cost, without a second prevention or transfer to the ally. Passing keeps Semuta. Other commitments remain enforced.',
|
||||
|
||||
Reference in new issue
Block a user