Guard Duke grants using public capture uncertainty
Verify and publish checkpoint container / container (push) Successful in 11m21s
Verify and publish checkpoint container / container (push) Successful in 11m21s
This commit is contained in:
1 parent
5f4eeee4f1
commit
57e7611468
15 files changed
+500
-19
No files matched your search
+25
-5
@@ -146,6 +146,8 @@ import { ECAZ_START_FORCES, quoteEcazStartingForces } from './ecaz-setup';
|
||||
import { battleCardSlotEligible, battleCategoryInspectionValue, fixedBattleInspectionMatches, validBattleSlotPair, usesNativeBattleSpecial } from './battle-card-slots';
|
||||
import { HARASS_WITHDRAW_CARD, HarassWithdrawError, isHarassWithdraw, quoteHarassWithdraw, defaultHarassWithdrawAllocation, harassWithdrawNeedsAllocation, type HarassWithdrawSelection, type HarassWithdrawContext, type HarassWithdrawPreview } from './harass-withdraw';
|
||||
import { originalAuctionInspectionLot } from './auction-inspection-source';
|
||||
import { nextDukeCaptureUncertainty } from './duke-capture-uncertainty';
|
||||
import { dukeCaptureUncertaintyBlock, plainAdvancedEcazDukeProfile } from './ecaz-duke-capture-policy';
|
||||
import { discoveryChoices, discoveryStashSignature, type DiscoveryStash } from './discovery-actions';
|
||||
import { createStormSource, validateStormSource, discoveryStormOffer, createDiscoveryStorm, chooseDiscoveryStorm, validateDiscoveryStorm, finishDiscoveryStorm, discoveryStormDistance, discoveryStormSaphoModes, reorderDiscoveryStorm, type StormMovementSource, type DiscoveryStorm } from './discovery-storm';
|
||||
import { completeDiscoveryFlight, discoveryFlightOffer, quoteDiscoveryFlight, validateDiscoveryFlight, type DiscoveryFlightReceipt } from './discovery-flight';
|
||||
@@ -2261,6 +2263,8 @@ export type Game = {
|
||||
cost: number;
|
||||
} | null;
|
||||
dukeVidal?: DukeState;
|
||||
/** Public capture history: absent on legacy games whose past cannot be inferred. */
|
||||
dukeCaptureUncertain?: boolean;
|
||||
dukeAcquisitionTurn?: number;
|
||||
pendingTerrorEntry?: {
|
||||
victoryEvent?: string;
|
||||
@@ -5850,6 +5854,7 @@ export function createGame(
|
||||
version: 0,
|
||||
host: host.id,
|
||||
status: 'lobby',
|
||||
dukeCaptureUncertain: false,
|
||||
kullDefaultPolicy: true,
|
||||
advanced,
|
||||
expansions: [...new Set(expansions)],
|
||||
@@ -25069,6 +25074,8 @@ function ambassadorEffectBlock(
|
||||
if (effect === 'ecaz') {
|
||||
const owner = byFaction(g, 'ecaz');
|
||||
if (!owner) return 'Duke Vidal is unavailable for this acquisition.';
|
||||
const uncertainty = dukeCaptureUncertaintyBlock(g);
|
||||
if (uncertainty) return uncertainty;
|
||||
if (g.players.some((p) => p.leaders.some((l) => l.id === DUKE_VIDAL_ID)))
|
||||
return 'Duke Vidal is unavailable for this acquisition.';
|
||||
return occupiedEcazDukePriority(g) ?? ecazDukeAcquisitionBlock(g, owner.id, beneficiary.id);
|
||||
@@ -27198,8 +27205,10 @@ function ecazAllianceQuote(g: Game, owner: string, entrant: string) {
|
||||
}
|
||||
}
|
||||
function ecazAmbassadorLoanBlock(g: Game, owner: Player, entrant: Player) {
|
||||
const uncertainty = dukeCaptureUncertaintyBlock(g);
|
||||
if (uncertainty) return uncertainty;
|
||||
if (g.advanced && byFaction(g, 'harkonnen') &&
|
||||
!(independentDiscoveryProfile(g) || independentNexusProfile(g) || standaloneE3NexusProfile(g) || pairedE3NexusProfile(g) || mixedE3NexusProfile(g)))
|
||||
!(plainAdvancedEcazDukeProfile(g) || independentDiscoveryProfile(g) || independentNexusProfile(g) || standaloneE3NexusProfile(g) || pairedE3NexusProfile(g) || mixedE3NexusProfile(g)))
|
||||
return 'Advanced Duke loans with Harkonnen capture remain guarded in this profile.';
|
||||
if (owner.ally !== entrant.id || entrant.ally !== owner.id)
|
||||
return 'The new Ecaz alliance is no longer current.';
|
||||
@@ -39157,13 +39166,24 @@ function finishResponse(g: Game, canceled: boolean, settlement?: BureaucratSettl
|
||||
else {
|
||||
const candidates = captureCandidates(g, capture.loser, capture.territory, capture.duke);
|
||||
const selected = shuffle(candidates)[0];
|
||||
const l = selected?.id === DUKE_VIDAL_ID
|
||||
? (g.dukeVidal = captureDuke(g.dukeVidal!, capture.player, capture.loser,
|
||||
g.turn, capture.territory, capture.duke)).leader : selected;
|
||||
if (!l) {
|
||||
if (!selected) {
|
||||
finishBattle(g);
|
||||
return;
|
||||
}
|
||||
// Record only publicly observable capture circumstances, never the
|
||||
// selected concealed identity or the internal released-Duke witness.
|
||||
const publicDuke = projectedSharedDuke(g, '');
|
||||
const publicPlan = g.battle?.revealed ? g.battle.plans[capture.loser] : undefined;
|
||||
const uncertainty = nextDukeCaptureUncertainty(g.dukeCaptureUncertain, {
|
||||
publicController: publicDuke?.controller,
|
||||
loser: capture.loser,
|
||||
revealedLeader: publicPlan ? publicPlan.leader ?? null : undefined,
|
||||
publicPlanKnown: !!publicPlan,
|
||||
});
|
||||
if (uncertainty !== undefined) g.dukeCaptureUncertain = uncertainty;
|
||||
const l = selected?.id === DUKE_VIDAL_ID
|
||||
? (g.dukeVidal = captureDuke(g.dukeVidal!, capture.player, capture.loser,
|
||||
g.turn, capture.territory, capture.duke)).leader : selected;
|
||||
const owner = l.id === DUKE_VIDAL_ID ? getPlayer(g, capture.loser) :
|
||||
g.players.find((player) => player.leaders.includes(l))!;
|
||||
if (l.id !== DUKE_VIDAL_ID) {
|
||||
|
||||
Reference in new issue
Block a user