Offer first-death Kwisatz Haderach through the Tleilaxu Ambassador

This commit is contained in:
Quintine committed 2026-10-12 23:20:37 +11:00
1 parent bbf27c4f3d
commit d14f3d1717
11 files changed
+397 -19

No files matched your search

+36
View File
@@ -0,0 +1,36 @@
import type { Game, Player } from './engine';
import type { Leader } from './cards';
type Context = Pick<Game, 'advanced'>;
type Beneficiary = Pick<Player, 'faction' | 'leaders' | 'kwisatz' | 'battleLosses'>;
export type TleilaxuAmbassadorLeaderChoice = { id: string; name: string; strength: number };
const ownFirstDeath = (player: Beneficiary, leader: Leader) =>
leader.faction === player.faction && leader.dead && leader.deaths === 1 &&
!leader.capturedBy && !leader.gholaBy;
/** Base p17 revives KH like a leader without adding it to the ordinary roster.
* Native KH death records start at cycle1; every existing return advances that
* marker. Repeat-return/ordinary-quota interpretation remains outside this grant. */
function firstKwisatz(context: Context, player: Beneficiary): boolean {
return context.advanced && player.faction === 'atreides' && player.battleLosses >= 7 &&
player.kwisatz?.dead === true && (player.kwisatz.revivalCycle ?? 1) === 1;
}
/** Return the actual own identity, never a foreign disc or a cloned physical leader. */
export function tleilaxuAmbassadorLeaderSelection(
context: Context, player: Beneficiary, id: unknown,
): Leader | 'kwisatz' | null {
if (id === 'kwisatz') return firstKwisatz(context, player) ? 'kwisatz' : null;
return player.leaders.find(leader => leader.id === id && ownFirstDeath(player, leader)) ?? null;
}
export function tleilaxuAmbassadorLeaderChoices(
context: Context, player: Beneficiary,
): TleilaxuAmbassadorLeaderChoice[] {
const choices: TleilaxuAmbassadorLeaderChoice[] = [];
for (const leader of player.leaders)
if (ownFirstDeath(player, leader)) choices.push({ id: leader.id, name: leader.name, strength: leader.strength });
if (firstKwisatz(context, player)) choices.push({ id: 'kwisatz', name: 'Kwisatz Haderach', strength: 2 });
return choices;
}