Resume Richese auctions after Distrans Semuta reaction
Verify and publish checkpoint container / container (push) Successful in 11m24s
Verify and publish checkpoint container / container (push) Successful in 11m24s
This commit is contained in:
1 parent
ccc4c7bb40
commit
f8078ed5e2
9 files changed
+245
-56
No files matched your search
+28
-4
@@ -1734,6 +1734,8 @@ export type Game = {
|
||||
}
|
||||
| {
|
||||
kind: 'distransDiscard';
|
||||
/** Present on new special-auction reactions; older saves omit it. */
|
||||
auctionBinding?: string;
|
||||
owner: string;
|
||||
recipient: string;
|
||||
transferred: string;
|
||||
@@ -5485,9 +5487,17 @@ function distransBlock(g: Game, owner: Player, card: Card): string | null {
|
||||
special.acted.length > 0 || Object.keys(special.sealed).length > 0));
|
||||
if (started && (g.response || g.decision || g.pendingKarama || g.phaseOpening || g.pendingTreacheryDiscard))
|
||||
return 'Finish the pending auction interaction before playing Distrans.';
|
||||
// A special-lot Semuta continuation still needs an auction-bound resume.
|
||||
if (started && special && (g.semutaPreview || g.semutaAdvancedOrdinaryPreview || g.semutaRecruitsPreview))
|
||||
return 'Distrans between special-auction bids is unavailable with the Semuta preview.';
|
||||
if (started && special && (g.semutaPreview || g.semutaAdvancedOrdinaryPreview || g.semutaRecruitsPreview)) {
|
||||
const auctionBinding = distransSpecialAuctionBinding(g);
|
||||
const continuation: DistransDiscardContinuation = {
|
||||
kind: 'distransDiscard', owner: owner.id, recipient: owner.id, transferred: '', card: card.id,
|
||||
auctionBinding, resume: { response: g.response, decision: g.decision,
|
||||
pendingKarama: g.pendingKarama, phaseOpening: g.phaseOpening }, stateSignature: '',
|
||||
};
|
||||
if (!auctionBinding || !semutaOfferSupported(g, continuation,
|
||||
[{ card, discardedBy: owner.id, publicFace: true }]))
|
||||
return 'Finish the special auction before playing Distrans in this Semuta interaction.';
|
||||
}
|
||||
return distransAuctionBlock(g);
|
||||
}
|
||||
function validateDistrans(
|
||||
@@ -6443,6 +6453,14 @@ type DistransDiscardContinuation = Extract<
|
||||
NonNullable<Game['pendingTreacheryDiscard']>['continuation'],
|
||||
{ kind: 'distransDiscard' }
|
||||
>;
|
||||
/** Preserve the physical special lot and its committed funds through Semuta. */
|
||||
function distransSpecialAuctionBinding(g: Game): string | undefined {
|
||||
if (g.phase !== 3 || !g.richeseAuction || g.auction || g.ixAuction || g.currentAuctionSale ||
|
||||
distransAuctionBlock(g)) return undefined;
|
||||
return JSON.stringify({ turn: g.turn, phase: g.phase, active: g.active, order: g.order,
|
||||
auction: g.richeseAuction, bidding: g.richeseBidding, funding: g.richeseFunding,
|
||||
aid: g.aid, players: g.players.map(p => ({ id: p.id, spice: p.spice, ally: p.ally })) });
|
||||
}
|
||||
function distransDiscardSignature(g: Game, c: DistransDiscardContinuation) {
|
||||
const owner = getPlayer(g, c.owner), recipient = getPlayer(g, c.recipient);
|
||||
return JSON.stringify({
|
||||
@@ -6451,6 +6469,7 @@ function distransDiscardSignature(g: Game, c: DistransDiscardContinuation) {
|
||||
turn: g.turn, phase: g.phase, active: g.active,
|
||||
ownerHand: owner.hand.map(card => card.id),
|
||||
recipientHand: recipient.hand.map(card => card.id),
|
||||
...(c.auctionBinding === undefined ? {} : { auctionBinding: c.auctionBinding }),
|
||||
});
|
||||
}
|
||||
type SaphoTruthOrderDiscardContinuation = Extract<
|
||||
@@ -8338,6 +8357,7 @@ function treacheryDiscardIntegrity(g: Game) {
|
||||
!g.discard.some(card => card.id === c.transferred) &&
|
||||
!c.resume.response && !c.resume.decision &&
|
||||
!c.resume.pendingKarama && !c.resume.phaseOpening &&
|
||||
(c.auctionBinding === undefined || c.auctionBinding === distransSpecialAuctionBinding(g)) &&
|
||||
c.stateSignature === distransDiscardSignature(g, c),
|
||||
'The completed private Distrans transfer no longer matches its fresh discard.',
|
||||
);
|
||||
@@ -9703,6 +9723,9 @@ function semutaOfferSupported(
|
||||
!!continuation.richeseLotEvent && continuation.richeseLotEvent === g.richeseAuction?.event;
|
||||
const richeseBoxDiscard = supportedRicheseTruthLot(g) && continuation.kind === 'nullentropyDiscard' &&
|
||||
continuation.auctionBinding?.kind === 'richese';
|
||||
const richeseDistransDiscard = continuation.kind === 'distransDiscard' &&
|
||||
continuation.auctionBinding !== undefined &&
|
||||
continuation.auctionBinding === distransSpecialAuctionBinding(g);
|
||||
if (continuation.kind === 'truthtranceDiscard' &&
|
||||
['bribe', 'bribeExpression', 'mixedBribe'].includes(continuation.record.question.kind) &&
|
||||
(!continuation.bribeBinding || !bareBasicSemutaProfile(g) || !bribePromiseModeSupported(g))) return false;
|
||||
@@ -10129,7 +10152,7 @@ function semutaOfferSupported(
|
||||
(advisorDiscard || auctionCostDiscard || bonusDiscard || auctionAdvantageDiscard || richeseGiftDiscard || bgDiscard || continuation.kind === 'specialKaramaDiscard' || continuation.kind === 'saphoAuctionDiscard' ||
|
||||
continuation.kind === 'ixAllyCard' ||
|
||||
(continuation.kind === 'karamaIncomeDiscard' &&
|
||||
continuation.use.response.kind === 'emperorIncome') || richeseTruthDiscard || richeseBoxDiscard || !g.richeseAuction) &&
|
||||
continuation.use.response.kind === 'emperorIncome') || richeseTruthDiscard || richeseBoxDiscard || richeseDistransDiscard || !g.richeseAuction) &&
|
||||
(richeseGiftDiscard || combatDiscard || alliedTraitorDiscard || occupyDiscard || continuation.kind === 'saphoAggressorDiscard' ||
|
||||
(continuation.kind === 'saphoTruthOrderDiscard' && !!continuation.battleEvent &&
|
||||
g.phase === 6 && g.battle?.event === continuation.battleEvent && !g.battle.revealed && !g.battle.preparation &&
|
||||
@@ -44258,6 +44281,7 @@ function applyActionInner(
|
||||
g.semutaRecruitsPreview && basicIndependentRecruitsSemutaProfile(g)) && !g.pendingTreacheryDiscard) {
|
||||
const continuation: DistransDiscardContinuation = {
|
||||
kind: 'distransDiscard', owner: p.id, recipient: recipient.id,
|
||||
...(distransSpecialAuctionBinding(g) === undefined ? {} : { auctionBinding: distransSpecialAuctionBinding(g) }),
|
||||
transferred: result.transferred.id, card: result.discarded.id,
|
||||
resume: { response: g.response, decision: g.decision,
|
||||
pendingKarama: g.pendingKarama, phaseOpening: g.phaseOpening },
|
||||
|
||||
Reference in new issue
Block a user