Honor Caladan auction knowledge in Truthtrance
Verify and publish checkpoint container / container (push) Canceled after 0s

This commit is contained in:
Quintine committed 2026-10-29 19:03:34 +11:00
1 parent 34f533ae8d
commit 4ec4f843a7
13 files changed
+241 -25

No files matched your search

+16 -8
View File
@@ -3,6 +3,7 @@ import { leaders, SPICE_CARDS } from './cards';
import { gameTerritories, territory } from './board';
import { TRUTH_CARD_NAMES } from './truthtrance-card-names';
import { battleCategoryInspectionValue } from './battle-card-slots';
import { originalAuctionInspectionLot } from './auction-inspection-source';
import type { Game, Player } from './engine';
type Comparison = 'eq' | 'gte' | 'lte';
@@ -98,17 +99,24 @@ export function parseKnowledgeFact(value: unknown): KnowledgeFact {
}
export function truthKnowledgeOf(
g: Pick<Game, 'phase' | 'turn' | 'advanced' | 'stormDials' | 'stormDialers' | 'stormCard' | 'stormCardKnown' | 'spicePeekKnown' | 'spiceDeck' | 'auction' | 'richeseAuction' | 'richeseCache' | 'richesePeekKnown' | 'richeseOfferedCard' | 'ixAuction' | 'ixAuctionKnown' | 'homeworldOccupationPreview' | 'battle' | 'players' | 'dukeVidal' | 'mobileStronghold' | 'discoveries'>,
g: Pick<Game, 'phase' | 'turn' | 'advanced' | 'stormDials' | 'stormDialers' | 'stormCard' | 'stormCardKnown' | 'spicePeekKnown' | 'spiceDeck' | 'auction' | 'richeseAuction' | 'richeseCache' | 'richesePeekKnown' | 'richeseOfferedCard' | 'ixAuction' | 'ixAuctionKnown' | 'homeworldOccupationPreview' | 'homeworldAuctionInspection' | 'battle' | 'players' | 'dukeVidal' | 'mobileStronghold' | 'discoveries'>,
p: Pick<Player, 'id' | 'faction' | 'prediction'>,
): TruthKnowledge {
const dial = g.stormDials[p.id];
const peek = g.phase === 5 && p.faction === 'atreides' && g.spicePeekKnown
? g.spiceDeck[0] : undefined;
const lot = g.phase === 3 && p.faction === 'atreides' && !g.richeseAuction && !g.ixAuction ? g.auction : null;
// The private lot is read only after the same inspection entitlement used by
// the ordinary auction view has resolved successfully for this faction.
const richeseLot = g.phase === 3 && g.advanced && p.faction === 'atreides' &&
g.richeseAuction?.source === 'blackMarket' && !g.richeseAuction.outcome && g.richesePeekKnown
// Match the private auction projection's original-lot and audience checks.
// The occupied share may succeed even if native Atreides was canceled.
const source = g.phase === 3 && g.homeworldOccupationPreview ? originalAuctionInspectionLot(g) : null;
const receipt = g.homeworldAuctionInspection;
const occupied = !!source && !!receipt && receipt.lot === source && receipt.occupiedKnown === true &&
p.id !== receipt.native && Array.isArray(receipt.audience) && receipt.audience.includes(p.id) &&
g.players.some(seat => seat.id === p.id);
const lot = g.phase === 3 && !g.richeseAuction && !g.ixAuction &&
((p.faction === 'atreides' && g.auction?.peekKnown) || occupied) ? g.auction : null;
const richeseLot = g.phase === 3 && g.advanced &&
g.richeseAuction?.source === 'blackMarket' && !g.richeseAuction.outcome &&
((p.faction === 'atreides' && g.richesePeekKnown) || occupied)
? g.richeseAuction : null;
// The offered copy is only valid for this actual lot. Older frames can
// recover the still-reserved physical card from the seller's hand.
@@ -116,7 +124,7 @@ export function truthKnowledgeOf(
? g.richeseOfferedCard : richeseLot
? g.players.find(seat => seat.id === richeseLot.owner)?.hand.find(card => card.id === richeseLot.cardId)
: undefined;
const lotName = lot?.peekKnown ? lot.cards[lot.index]?.name : offered?.name;
const lotName = lot ? lot.cards[lot.index]?.name : offered?.name;
// A Richese cache lot is public in Basic and Advanced; it is not the
// owner's private cache inventory or an Advanced Black Market card.
const cacheLot = g.phase === 3 && g.players.some(seat => seat.id === p.id) &&
@@ -216,7 +224,7 @@ export function knowledgeFactText(fact: KnowledgeFact): string {
if (fact.kind === 'presciencePeek')
return `the ${fact.field} you observed through battle Prescience is ${fact.field === 'dial' ? fact.value : fact.name}`;
if (fact.kind === 'auctionPeek')
return `the current auction card you inspected as Atreides is ${fact.name}`;
return `the current auction card you inspected is ${fact.name}`;
if (fact.kind === 'cacheLot')
return `the current public Richese cache auction card is ${fact.name}`;
if (fact.kind === 'ixPoolPeek')