Expand Basic bribe windows and fix marker guidance
Verify and publish checkpoint container / container (push) Successful in 11m0s
Verify and publish checkpoint container / container (push) Successful in 11m0s
This commit is contained in:
1 parent
7fccd62814
commit
9dc339e726
8 files changed
+362
-26
No files matched your search
+25
-22
@@ -17484,10 +17484,10 @@ function bribePaymentPreservesPromises(g: Game, p: Player, recipient: string, am
|
||||
* advancing their pending state. Existing whole-promise planners retain their
|
||||
* original timing boundary until those compositions are implemented. */
|
||||
function basicBribeInterrupt(g: Game, p: Player): boolean {
|
||||
if (g.status !== 'playing' || g.advanced || g.expansions.length > 1 ||
|
||||
if (g.status !== 'playing' || g.advanced ||
|
||||
g.inflation?.side === 'double' || g.techTokens || g.strongholdCards || g.leaderSkills ||
|
||||
g.homeworlds || g.nexusCards || g.discoveryEnabled || g.sandtrout || g.coalitionState ||
|
||||
g.ecazTreachery || g.semutaPreview || g.semutaRecruitsPreview || g.truthtrance ||
|
||||
g.homeworlds || g.nexusCards || g.discoveryEnabled || g.discoveries || g.discoveryStash || g.greatMaker || g.sandtrout || g.coalitionState ||
|
||||
g.ecazTreachery || g.semutaRecruitsPreview || g.truthtrance ||
|
||||
g.pendingKarama || g.pendingKull || g.pendingTreacheryDiscard || g.pendingNullentropy ||
|
||||
g.bureaucratPayments?.pending || g.battle || g.pendingRicheseGift || g.pendingShipment ||
|
||||
g.pendingGuildTransport || g.pendingArrivalOverlap || g.pendingAmbassador || g.pendingEmperorAuctionGift ||
|
||||
@@ -17507,32 +17507,35 @@ function basicBribeInterrupt(g: Game, p: Player): boolean {
|
||||
(g.pledgePromises ?? []).some(row => row.player === p.id && row.turn === g.turn && !row.fulfilled && !row.released) ||
|
||||
(g.deals ?? []).some(row => row.status === 'active' && row.payment?.payer === p.id && row.paymentStatus === 'pending')) return false;
|
||||
const classic = ['atreides', 'beneGesserit', 'emperor', 'fremen', 'guild', 'harkonnen'];
|
||||
if (!g.expansions.length) {
|
||||
if (g.phaseOpening || !g.players.every(seat => classic.includes(seat.faction)) ||
|
||||
Object.entries(g).some(([key, value]) => key.startsWith('pending') &&
|
||||
(Array.isArray(value) ? value.length > 0 : value !== null && value !== undefined && value !== false))) return false;
|
||||
const nativeRoster = !g.expansions.length
|
||||
? g.players.every(seat => classic.includes(seat.faction)) : selectedPhaseModuleRoster(g);
|
||||
if (nativeRoster && !g.phaseOpening && !g.choamMarket && !g.ixAuction &&
|
||||
!Object.entries(g).some(([key, value]) => key.startsWith('pending') &&
|
||||
(Array.isArray(value) ? value.length > 0 : value !== null && value !== undefined && value !== false))) {
|
||||
if (g.decision?.kind === 'auctionPayment' && !g.response)
|
||||
return g.phase === 3 && !!g.auction && !g.richeseAuction && !g.currentAuctionSale &&
|
||||
g.auction.bidder === g.decision.player && !!g.auction.cards[g.auction.index];
|
||||
const response = g.response;
|
||||
if (!response || g.decision || !Array.isArray(response.passed) ||
|
||||
if (response && (g.decision || !Array.isArray(response.passed) ||
|
||||
new Set(response.passed).size !== response.passed.length ||
|
||||
response.passed.some(id => !g.players.some(seat => seat.id === id))) return false;
|
||||
const owner = g.players.find(seat => seat.id === response.owner);
|
||||
const keys = Object.keys(response).sort().join(',');
|
||||
if (response.kind === 'atreidesAuction') return keys === 'kind,owner,passed' && g.phase === 3 &&
|
||||
owner?.faction === 'atreides' && !!g.auction && !g.richeseAuction && !g.currentAuctionSale &&
|
||||
!!g.auction.cards[g.auction.index];
|
||||
if (response.kind === 'fremenRevivalGrant') {
|
||||
if (keys !== 'fremenGrant,kind,owner,passed,recipient' || g.phase !== 4 || owner?.faction !== 'fremen' ||
|
||||
!response.fremenGrant || response.fremenGrant.owner !== response.owner ||
|
||||
response.fremenGrant.recipient !== response.recipient) return false;
|
||||
try { validateFremenRevivalGrant(g, response.fremenGrant); return true; }
|
||||
catch (error) { if (error instanceof FremenRevivalGrantError) return false; throw error; }
|
||||
response.passed.some(id => !g.players.some(seat => seat.id === id)))) return false;
|
||||
if (response) {
|
||||
const owner = g.players.find(seat => seat.id === response.owner);
|
||||
const keys = Object.keys(response).sort().join(',');
|
||||
if (response.kind === 'atreidesAuction') return keys === 'kind,owner,passed' && g.phase === 3 &&
|
||||
owner?.faction === 'atreides' && !!g.auction && !g.richeseAuction && !g.currentAuctionSale &&
|
||||
!!g.auction.cards[g.auction.index];
|
||||
if (response.kind === 'fremenRevivalGrant') {
|
||||
if (keys !== 'fremenGrant,kind,owner,passed,recipient' || g.phase !== 4 || owner?.faction !== 'fremen' ||
|
||||
!response.fremenGrant || response.fremenGrant.owner !== response.owner ||
|
||||
response.fremenGrant.recipient !== response.recipient) return false;
|
||||
try { validateFremenRevivalGrant(g, response.fremenGrant); return true; }
|
||||
catch (error) { if (error instanceof FremenRevivalGrantError) return false; throw error; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (g.response) return false;
|
||||
if (g.response || g.expansions.length !== 1 || g.semutaPreview) return false;
|
||||
if (g.expansions[0] === 'ix') return !!g.phaseOpening && !!g.amalWindowOpen && !g.decision &&
|
||||
g.players.every(seat => [...classic, 'ixians', 'tleilaxu'].includes(seat.faction));
|
||||
const extortion = g.moritaniExtortion, decision = g.decision;
|
||||
|
||||
+1
-1
@@ -296,7 +296,7 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
steps: [
|
||||
'Open Bribes beneath the table. Choose a non-allied faction and a positive whole amount, then use the named Pay button. The amount is public and leaves your supply immediately. A message or promise alone does not pay spice.',
|
||||
'The recipient keeps paid spice separately until the next Mentat opening. A payment after the current opening waits for next turn’s opening. Your incoming bribes are shown separately from your spendable supply; they cannot fund bids, shipments or another bribe yet.',
|
||||
'You may pay out of turn when no decision or response is pending, including during Mentat after opening collection. In supported Basic classic games, direct bribes can also interrupt a normal auction-payment decision, Atreides auction inspection or Fremen allied-revival grant. Supported Basic Ix and Moritani games also allow payments during the Amal opening or an Extortion choice. The original parent and its passes remain pending. You cannot bribe yourself or your ally, or while Inflation shows Double. Emperor gifts to allies use their own power controls.',
|
||||
'You may pay out of turn when no decision or response is pending, including during Mentat after opening collection. In supported Basic games with classic or selected native expansion factions, direct bribes can also interrupt a normal auction-payment decision, Atreides auction inspection or Fremen allied-revival grant. Supported Basic Ix and Moritani games also allow payments during the Amal opening or an Extortion choice. The original parent and its passes remain pending. You cannot bribe yourself or your ally, or while Inflation shows Double. Emperor gifts to allies use their own power controls.',
|
||||
'Your payment limit excludes reserved spending and preserves binding Truthtrance answers. If an alliance, pending decision or available supply changes, recheck the recipient and amount. A rejected payment does not change the game.',
|
||||
'In the Basic group preview, group allies are excluded from ordinary bribes and nonallied deals. Existing agreements remain recorded and can be released; a deferred bribe to a newly allied recipient stays pending while it is unavailable, subject to its original deadline.',
|
||||
'A qualifying Bureaucrat may divert two spice to the Bank without reducing the payer’s cost. The remainder stays deferred. Unsupported combinations remain unavailable and do not imply an official rule prohibition.',
|
||||
|
||||
Reference in new issue
Block a user