Compose standalone E3 Skills and independent cards with native power defaults

Restore fresh Ecaz coalition and Advanced Moritani initialization; retain printed native continuations and selected-family card eligibility. Validate Mentat fallback hands against explicitly selected independent cards. Frozen25-file274/274, types/lint/build and genuine runtime/mobile entry proofs pass. No save retrofit or deployment.
This commit is contained in:
Quintine committed 2026-10-17 20:36:01 +11:00
1 parent 2ad947af54
commit fde44baab5
25 files changed
+1838 -103

No files matched your search

+1 -9
View File
@@ -1,6 +1,6 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import {applyAction,viewGame,initializeMoritaniAssassinateGameForAudit,createGame,newPlayer,joinGame,type Game} from '../game/engine';
import {applyAction,viewGame,type Game} from '../game/engine';
import {DIFFICULTIES} from '../game/bot-profiles';
import {assassinationGame,stageAssassinationBattle,prepareAssassinationBattle,resolveAssassinationBattle,assassinationChoice,assassinationToMentat,assassinationPhysical,assassinationRejects,assassinationActions} from './moritani-assassinate-fixture';
import {advanceToNextStorm,finishToMovement} from './fixture-advanced-source';
@@ -122,14 +122,6 @@ void test('saved assassination receipts and cleanup obligations fail closed afte
assert.throws(()=>viewGame(missing,'m'));
});
void test('the explicit preview refuses Basic and exceptional-faction lobbies without mutation',()=>{
for(const [advanced,opponent] of [[false,'guild'],[true,'harkonnen'],[true,'ecaz']] as const){
const g=createGame('ASSAINIT',newPlayer('m','Moritani','moritani'),advanced,['ecaz']);
joinGame(g,newPlayer('x','Opponent',opponent));for(const p of g.players)p.ready=true;
const before=structuredClone(g);assert.throws(()=>initializeMoritaniAssassinateGameForAudit(g));assert.deepEqual(g,before);
}
});
void test('a sealed normal traitor call does not publish the assassination guard before the other voter replies',()=>{
const prepared=prepareAssassinationBattle(stageAssassinationBattle(assassinationGame(),'guild-0'));
const called=applyAction(prepared,'m',{type:'traitorCall',call:true});