Activate approved normal Mentat and document Emperor gift ruling
This commit is contained in:
1 parent
eb63967b5c
commit
d1ba8e0c7e
40 files changed
+270
-138
No files matched your search
@@ -161,6 +161,10 @@ void test('CHOAM prepaid ally support consumes its original donor pool and exclu
|
||||
const donorFunds = donor.spice;
|
||||
const enemyFunds = enemy.spice;
|
||||
game = applyAction(game, owner.id, { type: 'chooseBattle', territory: 'wind_pass', target: enemy.id });
|
||||
if (game.decision?.kind === 'mentatQuestion')
|
||||
game = applyAction(game, game.decision.player, {
|
||||
type: 'decision', event: game.decision.event, decline: true,
|
||||
});
|
||||
while (game.decision?.kind === 'leaderSkillVisibility')
|
||||
game = applyAction(game, game.decision.player,
|
||||
{ type: 'leaderSkillVisibility', event: game.decision.event, hide: true });
|
||||
|
||||
@@ -153,7 +153,6 @@ void test('the explicit preview keeps expansion, module and separate development
|
||||
game => { game.discoveryEnabled = true; },
|
||||
game => { game.leaderSkills = createLeaderSkills(() => 0.25); },
|
||||
game => { game.ecazTreachery = true; },
|
||||
game => { game.mentatQuestionPreview = true; },
|
||||
game => { game.moritaniAssassinatePreview = true; },
|
||||
];
|
||||
for (const change of changes) {
|
||||
|
||||
@@ -120,6 +120,31 @@ void test('Bureaucrat requires two other players and tracks the unique physical
|
||||
!bureaucratPaymentModeSupported({ expansions: ['choam'], homeworlds: {} }),
|
||||
);
|
||||
});
|
||||
|
||||
void test('Emperor gifts keep private amounts and do not consume Bureaucrat before a later qualifying payment', () => {
|
||||
let game = bureaucratPaymentGame({ advanced: true });
|
||||
bureaucratPlayer(game, 'e').ally = 'g';
|
||||
bureaucratPlayer(game, 'g').ally = 'e';
|
||||
takeBureaucratCard(game, 'p', 'Karama');
|
||||
const pending = applyAction(game, 'e', { type: 'emperorGift', amount: 7 });
|
||||
assert.equal(pending.response?.kind, 'emperorGift');
|
||||
for (const id of ['b', 'p'])
|
||||
assert.equal(viewGame(pending, id).response!.amount, undefined);
|
||||
for (const id of ['e', 'g'])
|
||||
assert.equal(viewGame(pending, id).response!.amount, 7);
|
||||
game = allowBureaucratIncome(bureaucratReload(pending));
|
||||
assert.equal(bureaucratPlayer(game, 'e').spice, 23);
|
||||
assert.equal(bureaucratPlayer(game, 'g').spice, 37);
|
||||
assert.equal(bureaucratPlayer(game, 'b').spice, 30);
|
||||
assert.equal(game.decision, null);
|
||||
assert.equal(viewGame(game, 'b').bureaucrat.usedThisPhase, false);
|
||||
const paid = applyAction(game, 'p', bribe);
|
||||
assert.equal(paid.decision?.kind, 'bureaucratPayment');
|
||||
const redirected = choose(paid);
|
||||
assert.equal(bureaucratPlayer(redirected, 'p').spice, 25);
|
||||
assert.equal(bureaucratPlayer(redirected, 'e').bribes, 3);
|
||||
assert.equal(viewGame(redirected, 'b').bureaucrat.usedThisPhase, true);
|
||||
});
|
||||
for (const advanced of [false, true])
|
||||
for (const choam of [false, true])
|
||||
void test(`single-payer ${choam ? 'CHOAM' : 'base'} ${advanced ? 'Advanced' : 'Basic'} shipment diverts two after payment without replaying arrival`, () => {
|
||||
|
||||
@@ -61,6 +61,8 @@ export function stagedMarketGhola(
|
||||
game = actChoamGhola(game, owner, { type: 'chooseBattle', territory: 'wind_pass', target: opponent });
|
||||
for (let step = 0; step < 30; step++) {
|
||||
if (game.response) game = passChoamGholaResponses(game);
|
||||
else if (game.decision?.kind === 'mentatQuestion')
|
||||
game = actChoamGhola(game, game.decision.player, { type: 'decision', event: game.decision.event, decline: true });
|
||||
else if (game.decision?.kind === 'leaderSkillVisibility')
|
||||
game = actChoamGhola(game, game.decision.player, { type: 'leaderSkillVisibility', event: game.decision.event, hide: true });
|
||||
else if (game.battle?.preparation)
|
||||
|
||||
@@ -410,6 +410,12 @@ void test('a real concealed Planetologist green Special is discarded once after
|
||||
territory: 'arrakeen',
|
||||
target: 'a',
|
||||
});
|
||||
if (game.decision?.kind === 'mentatQuestion')
|
||||
game = applyAction(game, game.decision.player, {
|
||||
type: 'decision',
|
||||
event: game.decision.event,
|
||||
decline: true,
|
||||
});
|
||||
while (game.decision?.kind === 'leaderSkillVisibility') {
|
||||
const decision = game.decision;
|
||||
game = applyAction(game, decision.player, {
|
||||
|
||||
@@ -54,10 +54,9 @@ void test('Discovery cannot redeal started components or silently remove another
|
||||
void test('Discovery Skills cannot silently drop unsupported native families or unrelated modules and previews', () => {
|
||||
const unsupported = lobby(['ixians', 'ecaz', 'guild'], ['ix', 'ecaz']);
|
||||
assert.throws(() => initializeLeaderSkillsGameForAudit(unsupported), RuleError);
|
||||
const overlays = Array.from({ length: 3 }, () => lobby(['guild', 'emperor', 'harkonnen'], []));
|
||||
const overlays = Array.from({ length: 2 }, () => lobby(['guild', 'emperor', 'harkonnen'], []));
|
||||
overlays[0].advanced = false; overlays[0].strongholdCards = createStrongholdCards();
|
||||
overlays[1].mentatQuestionPreview = true;
|
||||
overlays[2].spiceBankerIncomePreview = true;
|
||||
overlays[1].spiceBankerIncomePreview = true;
|
||||
for (const game of overlays) assert.throws(() => initializeLeaderSkillsGameForAudit(game), RuleError);
|
||||
const two = lobby(['guild', 'emperor'], []); two.techTokens = createTechTokens();
|
||||
assert.throws(() => initializeLeaderSkillsGameForAudit(two), RuleError);
|
||||
|
||||
@@ -69,7 +69,6 @@ for (const advanced of [false, true]) for (const tech of [false, true]) {
|
||||
assert.equal(f.game.richeseCache!.some(c => c.id === f.green), false);
|
||||
assert.ok(f.game.richeseCache!.length > 0, 'Two-turn bounded recipes do not bypass the exhausted-cache ruling.');
|
||||
assert.equal(f.game.spiceBankerIncomePreview, undefined);
|
||||
assert.equal(f.game.mentatQuestionPreview, undefined);
|
||||
if (tech) {
|
||||
assert.deepEqual(f.setup.techTokens, createTechTokens());
|
||||
assert.ok(TECH_TOKENS.every(token => f.afterFirstStorm.techTokens![token.id].owner !== null));
|
||||
|
||||
@@ -582,7 +582,6 @@ void test('selected genuine three-player Advanced base sample fails honestly, re
|
||||
const snapshot = join(first, 'failed-base-3-advanced.json');
|
||||
for (const field of [
|
||||
'ecazTreachery',
|
||||
'mentatQuestionPreview',
|
||||
'moritaniAssassinatePreview',
|
||||
'moritaniAssassinate',
|
||||
'moritaniAssassinateResume',
|
||||
|
||||
@@ -217,7 +217,7 @@ export function createDiscoveryNativeE2SkillsFixture(options: DiscoveryNativeE2S
|
||||
joinGame(game, newPlayer(faction, faction, faction));
|
||||
assert.deepEqual(game.expansions, ['choam']);
|
||||
if (options.advanced !== undefined) assert.equal(game.advanced, options.advanced);
|
||||
assert.ok(!game.homeworlds && !game.nexusCards && !game.spiceBankerIncomePreview && !game.mentatQuestionPreview);
|
||||
assert.ok(!game.homeworlds && !game.nexusCards && !game.spiceBankerIncomePreview);
|
||||
assert.ok(game.status === 'lobby' || game.status === 'setup' && game.turn === 1 && game.phase === 0 &&
|
||||
game.leaderSkills?.assignments.length === 0 && game.players.every(p =>
|
||||
p.hand.length <= (p.faction === 'harkonnen' ? 2 : 1) && p.traitors.length === 0 && p.traitorChoices.length === 0),
|
||||
|
||||
@@ -149,7 +149,7 @@ export function initializeDiscoveryNativeE3Skills(options: DiscoveryNativeE3Skil
|
||||
assert.ok(game.players.every(p => ['moritani', 'guild', 'atreides', 'emperor', 'fremen', 'beneGesserit',
|
||||
...(advanced ? [] : ['harkonnen'])].includes(p.faction)));
|
||||
assert.ok(!strongholds || advanced);
|
||||
assert.ok(!game.nexusCards && !game.homeworlds && !game.ecazTreachery && !game.spiceBankerIncomePreview && !game.mentatQuestionPreview);
|
||||
assert.ok(!game.nexusCards && !game.homeworlds && !game.ecazTreachery && !game.spiceBankerIncomePreview);
|
||||
if (game.status === 'lobby') {
|
||||
if (!!game.techTokens !== tech) game = applyAction(game, game.host, { type: 'techTokens', enabled: tech });
|
||||
if (!!game.strongholdCards !== strongholds) game = applyAction(game, game.host, { type: 'strongholdCards', enabled: strongholds });
|
||||
|
||||
@@ -117,7 +117,7 @@ export function initializeDiscoveryStandaloneNexusE3Skills(options: DiscoverySta
|
||||
assert.ok(advanced || native !== 'ecaz' || game.players.length % 2 === 0, 'Basic odd-seat Ecaz remains source guarded.');
|
||||
assert.ok(!strongholds || advanced);
|
||||
assert.ok(!game.homeworlds && !game.ecazTreachery && !game.advancedPreview && !game.semutaPreview &&
|
||||
!game.spiceBankerIncomePreview && !game.mentatQuestionPreview);
|
||||
!game.spiceBankerIncomePreview);
|
||||
if (game.status === 'lobby') {
|
||||
if (!!game.techTokens !== tech) game = applyAction(game, game.host, { type: 'techTokens', enabled: tech });
|
||||
if (!!game.strongholdCards !== strongholds) game = applyAction(game, game.host, { type: 'strongholdCards', enabled: strongholds });
|
||||
|
||||
@@ -46,6 +46,7 @@ export function nextMoritaniSkillsModulesStep(game: Game): StrongholdFactionsNat
|
||||
return nextStrongholdFactionsNativeStep(game);
|
||||
const d = game.decision;
|
||||
if (d?.kind === 'leaderSkillVisibility') return { actor: d.player, action: { type: 'leaderSkillVisibility', event: d.event, hide: false } };
|
||||
if (d?.kind === 'mentatQuestion') return { actor: d.player, action: { type: 'decision', event: d.event, decline: true } };
|
||||
if (d?.kind === 'moritaniSetup') {
|
||||
const action = moritaniSkillsModulesPolicy(game, d.player)[0]; assert.ok(action);
|
||||
return { actor: d.player, action };
|
||||
|
||||
@@ -10,14 +10,13 @@ export const NATIVE_MENTAT_FAMILIES = ['ixians','tleilaxu','choam','moritani'] a
|
||||
export type NativeMentatFamily = typeof NATIVE_MENTAT_FAMILIES[number];
|
||||
|
||||
/** Real native setup/assignment and Storm; conserved rule-unit battle position. */
|
||||
export function nativeMentatBattle(family: NativeMentatFamily, matching = true, preview = true, begin = true): Game {
|
||||
export function nativeMentatBattle(family: NativeMentatFamily, matching = true, begin = true): Game {
|
||||
const options = {requestedSkill:'mentat' as const};
|
||||
let game = family === 'ixians' ? completedIxSkillsGame(options)
|
||||
: family === 'tleilaxu' ? completedTleilaxuSkillsGame(options)
|
||||
: family === 'choam' ? completedChoamSkillsGame(options)
|
||||
: completedMoritaniSkillsGame(options);
|
||||
game = finishToMovement(game);
|
||||
if (preview) game.mentatQuestionPreview = true;
|
||||
const owner = game.players.find(p => p.faction === family)!;
|
||||
const target = game.players.find(p => p.faction === 'emperor')!;
|
||||
for (const p of game.players) {
|
||||
|
||||
@@ -57,6 +57,8 @@ function open(game: Game, territory = 'wind_pass') {
|
||||
game = act(game, 'i', { type: 'chooseBattle', territory, target: 'e' });
|
||||
for (let step = 0; step < 30; step++) {
|
||||
if (game.response) game = passResponses(game);
|
||||
else if (game.decision?.kind === 'mentatQuestion')
|
||||
game = act(game, game.decision.player, { type: 'decision', event: game.decision.event, decline: true });
|
||||
else if (game.decision?.kind === 'leaderSkillVisibility')
|
||||
game = act(game, game.decision.player, { type: 'leaderSkillVisibility', event: game.decision.event, hide: true });
|
||||
else if (game.battle?.preparation)
|
||||
|
||||
@@ -136,6 +136,7 @@ function clearBattlePreparation(state: Game): Game {
|
||||
let g = state;
|
||||
while (
|
||||
g.decision?.kind === 'leaderSkillVisibility' ||
|
||||
g.decision?.kind === 'mentatQuestion' ||
|
||||
g.decision?.kind === 'fullPlanOffer' ||
|
||||
g.battle?.preparation
|
||||
)
|
||||
@@ -145,6 +146,12 @@ function clearBattlePreparation(state: Game): Game {
|
||||
event: g.decision.event,
|
||||
hide: false,
|
||||
});
|
||||
else if (g.decision?.kind === 'mentatQuestion')
|
||||
g = applyAction(g, g.decision.player, {
|
||||
type: 'decision',
|
||||
event: g.decision.event,
|
||||
decline: true,
|
||||
});
|
||||
else if (g.decision?.kind === 'fullPlanOffer')
|
||||
g = applyAction(g, g.decision.player, {
|
||||
type: 'decision',
|
||||
|
||||
@@ -182,6 +182,12 @@ function battleFor(
|
||||
territory: 'arrakeen',
|
||||
target: 'e',
|
||||
});
|
||||
if (next.decision?.kind === 'mentatQuestion')
|
||||
next = applyAction(next, next.decision.player, {
|
||||
type: 'decision',
|
||||
event: next.decision.event,
|
||||
decline: true,
|
||||
});
|
||||
while (next.decision?.kind === 'leaderSkillVisibility') {
|
||||
const decision = next.decision;
|
||||
next = applyAction(next, decision.player, {
|
||||
@@ -404,6 +410,12 @@ void test('a Voice that forbids the last alternate Cheap Hero automatically conc
|
||||
territory: 'arrakeen',
|
||||
target: 'b',
|
||||
});
|
||||
if (g.decision?.kind === 'mentatQuestion')
|
||||
g = applyAction(g, g.decision.player, {
|
||||
type: 'decision',
|
||||
event: g.decision.event,
|
||||
decline: true,
|
||||
});
|
||||
while (g.decision?.kind === 'leaderSkillVisibility')
|
||||
g = applyAction(g, g.decision.player, {
|
||||
type: 'leaderSkillVisibility',
|
||||
@@ -513,6 +525,12 @@ void test('Ghola revival during an unfinished battle preserves its power stage t
|
||||
territory: 'carthag',
|
||||
target: 'e',
|
||||
});
|
||||
if (g.decision?.kind === 'mentatQuestion')
|
||||
g = applyAction(g, g.decision.player, {
|
||||
type: 'decision',
|
||||
event: g.decision.event,
|
||||
decline: true,
|
||||
});
|
||||
while (g.decision?.kind === 'leaderSkillVisibility')
|
||||
g = applyAction(g, g.decision.player, {
|
||||
type: 'leaderSkillVisibility',
|
||||
|
||||
@@ -381,6 +381,17 @@ void test('battle death and Ghola revival preserve one private replacement skill
|
||||
territory: 'arrakeen',
|
||||
target: bg.id,
|
||||
});
|
||||
if (game.decision?.kind === 'mentatQuestion') {
|
||||
const owner = f.auths.findIndex(
|
||||
(auth) => auth.playerId === game.decision!.player,
|
||||
);
|
||||
assert.ok(owner >= 0);
|
||||
game = await act(f, owner, {
|
||||
type: 'decision',
|
||||
event: game.decision.event,
|
||||
decline: true,
|
||||
});
|
||||
}
|
||||
while (game.decision?.kind === 'leaderSkillVisibility') {
|
||||
const owner = f.auths.findIndex(
|
||||
(auth) => auth.playerId === game.decision!.player,
|
||||
|
||||
@@ -34,14 +34,12 @@ export function mentatQuestionGame({
|
||||
cards = ['Crysknife', 'Snooper'],
|
||||
begin = true,
|
||||
captured = false,
|
||||
preview = true,
|
||||
}: {
|
||||
advanced?: boolean;
|
||||
choam?: boolean;
|
||||
cards?: string[];
|
||||
begin?: boolean;
|
||||
captured?: boolean;
|
||||
preview?: boolean;
|
||||
} = {}): Game {
|
||||
const native = choam ? 'richese' : 'emperor';
|
||||
let game = createGame(
|
||||
@@ -57,8 +55,6 @@ export function mentatQuestionGame({
|
||||
joinGame(game, newPlayer('o', 'Observer', 'guild'));
|
||||
for (const player of game.players)
|
||||
game = applyAction(game, player.id, { type: 'ready' });
|
||||
// Server-only review fixture opt-in; ordinary Leader Skills starts remain unchanged.
|
||||
if (preview) game.mentatQuestionPreview = true;
|
||||
const index = LEADER_SKILL_CARDS.findIndex((card) => card.id === 'mentat');
|
||||
let cursor = LEADER_SKILL_CARDS.length - 1;
|
||||
mock.method(globalThis.crypto, 'getRandomValues', (array: Uint32Array) => {
|
||||
|
||||
@@ -107,38 +107,16 @@ void test('Mentat names exact printed/default weapons and validates physical han
|
||||
assert.throws(() => mentatHand(ixDeck().slice(0, 1), []));
|
||||
});
|
||||
|
||||
void test('Mentat requires a private preview opt-in and never exposes or accepts that flag through a player view or action', () => {
|
||||
void test('fresh supported Leader Skills battles offer a private Mentat question without a separate opt-in', () => {
|
||||
for (const advanced of [false, true])
|
||||
for (const choam of [false, true]) {
|
||||
const ordinary = mentatQuestionGame({ advanced, choam, preview: false });
|
||||
assert.equal(ordinary.mentatQuestionPreview, undefined);
|
||||
assert.equal(ordinary.battle!.mentatQuestionVersion, undefined);
|
||||
assert.equal(ordinary.battle!.mentatQuestion, undefined);
|
||||
assert.equal(ordinary.decision?.kind, 'leaderSkillVisibility');
|
||||
assert.equal(viewGame(ordinary, 'a').mentat.pending, null);
|
||||
assert.equal(
|
||||
applyAction(ordinary, 'a', {
|
||||
type: 'advanceBots',
|
||||
mentatQuestionPreview: true,
|
||||
}).mentatQuestionPreview,
|
||||
undefined,
|
||||
);
|
||||
const game = mentatReload(mentatQuestionGame({ advanced, choam }));
|
||||
assert.equal(game.battle!.mentatQuestionVersion, 1);
|
||||
assert.equal(normalizeAutomaticGame(game).decision?.kind, 'mentatQuestion');
|
||||
assert.equal(viewGame(game, 'a').mentat.pending!.stage, 'name');
|
||||
assert.deepEqual(viewGame(game, 'd').mentat.pending!.weapons, []);
|
||||
assert.deepEqual(viewGame(game, 'o').mentat.history, []);
|
||||
}
|
||||
const preview = mentatReload(mentatQuestionGame());
|
||||
assert.equal(preview.mentatQuestionPreview, true);
|
||||
assert.equal(
|
||||
normalizeAutomaticGame(preview).decision?.kind,
|
||||
'mentatQuestion',
|
||||
);
|
||||
for (const id of ['a', 'd', 'o'])
|
||||
assert.equal('mentatQuestionPreview' in viewGame(preview, id), false);
|
||||
delete preview.mentatQuestionPreview;
|
||||
for (const operation of [
|
||||
() => viewGame(preview, 'a'),
|
||||
() => normalizeAutomaticGame(preview),
|
||||
() => applyAction(preview, 'a', { type: 'advanceBots' }),
|
||||
])
|
||||
assert.throws(operation);
|
||||
});
|
||||
|
||||
for (const advanced of [false, true])
|
||||
@@ -430,6 +408,19 @@ void test('legacy unmarked battles are not reopened and later new battles receiv
|
||||
viewGame(normalizeAutomaticGame(mentatReload(legacy)), 'a').mentat.pending,
|
||||
null,
|
||||
);
|
||||
const continued = finishPowers(normalizeAutomaticGame(mentatReload(legacy)));
|
||||
assert.equal(continued.battle!.event, legacy.battle!.event);
|
||||
assert.equal(continued.battle!.mentatQuestionVersion, undefined);
|
||||
assert.equal(continued.battle!.mentatQuestion, undefined);
|
||||
assert.equal(continued.decision, null);
|
||||
assert.deepEqual(viewGame(continued, 'a').mentat.history, []);
|
||||
const planned = applyAction(continued, 'a', {
|
||||
type: 'battlePlan',
|
||||
dial: 0,
|
||||
leader: 'emperor-0',
|
||||
});
|
||||
assert.ok(planned.battle!.plans.a);
|
||||
assert.equal(planned.battle!.mentatQuestion, undefined);
|
||||
let game = finishPowers(ask(mentatQuestionGame()));
|
||||
const original = game.battle!.mentatQuestionEvent;
|
||||
game = applyAction(game, 'a', {
|
||||
|
||||
@@ -85,7 +85,9 @@ function openBattle(state: Game, owner = 'm', opponent = 'e', hide = true): Game
|
||||
if (g.decision?.kind === 'leaderSkillVisibility') {
|
||||
const d = g.decision;
|
||||
g = act(g, d.player, { type: 'leaderSkillVisibility', event: d.event, hide: d.player === owner ? hide : true });
|
||||
} else if (g.decision?.kind === 'mentatQuestion' || g.decision?.kind === 'fullPlanOffer') {
|
||||
} else if (g.decision?.kind === 'mentatQuestion') {
|
||||
g = act(g, g.decision.player, { type: 'decision', event: g.decision.event, decline: true });
|
||||
} else if (g.decision?.kind === 'fullPlanOffer') {
|
||||
g = act(g, g.decision.player, { type: 'decision', decline: true });
|
||||
} else if (g.battle?.preparation) {
|
||||
g = act(g, g.battle.preparation.owner, { type: 'declineBattlePower' });
|
||||
|
||||
@@ -6,10 +6,7 @@ import {DIFFICULTIES} from '../game/bot-profiles';
|
||||
import {NATIVE_MENTAT_FAMILIES,nativeMentatBattle} from './fixture-native-mentat';
|
||||
|
||||
for (const family of NATIVE_MENTAT_FAMILIES) {
|
||||
void test(`${family} Mentat requires an explicit preview and resumes native posture after a matching or fallback answer`,()=>{
|
||||
const ordinary = nativeMentatBattle(family,true,false);
|
||||
assert.equal(ordinary.battle!.mentatQuestion,undefined);
|
||||
assert.equal(ordinary.decision!.kind,'leaderSkillVisibility');
|
||||
void test(`${family} Mentat asks normally and resumes native posture after a matching or fallback answer`,()=>{
|
||||
for (const matching of [true,false]) {
|
||||
let game = nativeMentatBattle(family,matching);
|
||||
assert.equal(game.decision!.kind,'mentatQuestion');
|
||||
|
||||
@@ -32,6 +32,7 @@ function open(g: Game, owner = 't', opponent = 'e') {
|
||||
g = act(g, owner, { type: 'chooseBattle', territory: 'wind_pass', target: opponent });
|
||||
for (let i = 0; i < 30; i++) {
|
||||
if (g.response) g = act(g, g.players.find(p => !g.response!.passed.includes(p.id))!.id, { type: 'passResponse' });
|
||||
else if (g.decision?.kind === 'mentatQuestion') g = act(g, g.decision.player, { type: 'decision', event: g.decision.event, decline: true });
|
||||
else if (g.decision?.kind === 'leaderSkillVisibility') g = act(g, g.decision.player, { type: 'leaderSkillVisibility', event: g.decision.event, hide: true });
|
||||
else if (g.battle?.preparation) g = act(g, g.battle.preparation.owner, { type: 'declineBattlePower' });
|
||||
else break;
|
||||
|
||||
@@ -29,6 +29,8 @@ function open(g: Game, owner = 't') {
|
||||
g = act(g, owner, { type: 'chooseBattle', territory: 'wind_pass', target: 'e' });
|
||||
for (let i = 0; i < 30; i++) {
|
||||
if (g.response) g = act(g, g.players.find(p => !g.response!.passed.includes(p.id))!.id, { type: 'passResponse' });
|
||||
else if (g.decision?.kind === 'mentatQuestion')
|
||||
g = act(g, g.decision.player, { type: 'decision', event: g.decision.event, decline: true });
|
||||
else if (g.decision?.kind === 'leaderSkillVisibility')
|
||||
g = act(g, g.decision.player, { type: 'leaderSkillVisibility', event: g.decision.event, hide: true });
|
||||
else if (g.battle?.preparation) g = act(g, g.battle.preparation.owner, { type: 'declineBattlePower' });
|
||||
|
||||
@@ -63,6 +63,8 @@ function killedOriginalSkill(owner: 't' | 'a' = 't'): Game {
|
||||
game = act(game, owner, { type: 'chooseBattle', territory: 'wind_pass', target: 'e' });
|
||||
for (let step = 0; step < 20; step++) {
|
||||
if (game.response) game = passWindow(game);
|
||||
else if (game.decision?.kind === 'mentatQuestion')
|
||||
game = act(game, game.decision.player, { type: 'decision', event: game.decision.event, decline: true });
|
||||
else if (game.decision?.kind === 'leaderSkillVisibility') {
|
||||
const decision = game.decision;
|
||||
game = act(game, decision.player, {
|
||||
|
||||
Reference in new issue
Block a user