Files
Dune/game/atreides-full-plan.ts
Quintine 61828150b9 Keep Atreides special inspection available until plan reveal
Allow native Advanced use after declining the first offer, including a sealed
target. Reuse projected card/target permission in persistent controls and
minimal bots; retain sealed plans and finish target-last public reveal once.

Source: authorized supplied physical27 F. Ordinary preparation priority and
target-first ordering remain provisional; no new reading acknowledgement.

Verified: 11 affected offline files126/126, types/lint, production build, five
actual control/gameplay/GameTable SSR journeys and eight legal profile paths.
No saved-room, D1, reset, restart or deployment operation.
2026-10-24 18:49:22 +11:00

51 lines
2.3 KiB
TypeScript

import type { FactionId } from './catalog';
import type { Action, GameView } from './engine';
/** Timing needs only public commitment status, never the hidden plan contents. */
export type AtreidesFullPlanContext = {
status: string;
phase: number;
advanced: boolean;
owner: { id: string; faction: FactionId; specialKaramaUsed?: boolean };
blocked?: string | null;
battle: null | {
attacker: string;
defender: string;
revealed: boolean;
preparing: boolean;
fullPlan: boolean;
};
};
/** Supplied revised rules, physical p27 F: before Battle Plans are revealed.
* The original offer is a convenience, not a deadline. A sealed plan stays fixed.
* Voice/ordinary Prescience keep their existing preparation priority.
*/
export function quoteAtreidesFullPlan(context: AtreidesFullPlanContext) {
const { owner, battle } = context;
let blocked: string | null = null;
if (!context.advanced) blocked = 'Special Karama powers require the Advanced game.';
else if (owner.faction !== 'atreides') blocked = 'Only native Atreides may use this special Karama.';
else if (context.status !== 'playing' || context.phase !== 6 || !battle)
blocked = 'Use special prescience during a battle before plans are revealed.';
else if (owner.specialKaramaUsed || battle.fullPlan)
blocked = 'Your special Karama power has already been used this game.';
else if (battle.revealed) blocked = 'The Battle Plans have already been revealed.';
else if (battle.preparing)
blocked = 'Finish battle preparation before using special prescience.';
else if (context.blocked) blocked = context.blocked;
return { blocked, targets: battle ? [battle.attacker, battle.defender] : [] };
}
/** Reuse the existing own/allied inspection preference, without strategy tuning. */
export function atreidesFullPlanAction(game: GameView): Action | null {
const offer = game.atreidesFullPlan;
if (!offer || offer.blocked || !offer.cards.length) return null;
const me = game.players.find(player => player.id === game.me);
if (!me) return null;
const beneficiary = offer.targets.includes(me.id) ? me.id : me.ally;
if (!beneficiary || !offer.targets.includes(beneficiary)) return null;
const target = offer.targets.find(player => player !== beneficiary);
return target ? { type: 'card', mode: 'special', card: offer.cards[0], target } : null;
}