Connect fresh Basic Semuta and Ambassador discards
Initialize the existing neutral Semuta protocol during genuine fresh public bare Basic Richese setup with selected native families. Retain original roster/deck/freshness checks, separate optional/Advanced profiles and unchanged existing saves. Retain the original Ambassador arrival cause and admit clean ordinary shipment/movement CHOAM and Ixian private discard batches, including native BG copies. Keep CHOAM credit committed once; pause before exactly one Ix replacement. Existing owner-only commitment/selection, physical Semuta/full-hand exchange and original entrant continuation remain. Verify original public setup, actual one-spice Semuta auction, ordinary purchase, paid placement, paid shipment and actual movement. Exercise claim/pass controls, busy protection and all four existing legal profiles without strategic tuning. Repair nearby stale tests to acknowledge actual battle outcomes and retain the existing independent-card/Discovery combination. Full modes, wider nested/optional interactions, comprehensive assurance and deployed acceptance remain open. No saved-room/reset/restart/deployment operation.
This commit is contained in:
1 parent
1f3e71fe03
commit
b4a556d5d3
12 files changed
+673
-34
No files matched your search
@@ -6,6 +6,7 @@ import {
|
||||
} from '../game/engine';
|
||||
import { FACTIONS, type FactionId } from '../game/catalog';
|
||||
import { baseDeck } from '../game/cards';
|
||||
import { ecazTreacheryCards } from '../game/ecaz-cards';
|
||||
import { botActions } from '../game/bots';
|
||||
import { DIFFICULTIES, type Difficulty } from '../game/bot-profiles';
|
||||
import { createLeaderSkills } from '../game/leader-skills';
|
||||
@@ -54,7 +55,7 @@ function completedSetup(initial: Game, difficulty: Difficulty = 'Easy') {
|
||||
assert.equal(game.setupStage, undefined);
|
||||
assert.deepEqual(normalizeAutomaticGame(reload(game)), game);
|
||||
const cards = [...game.deck, ...game.discard, ...game.players.flatMap(p => p.hand)].map(card => card.id).sort();
|
||||
assert.deepEqual(cards, baseDeck().map(card => card.id).sort());
|
||||
assert.deepEqual(cards, [...baseDeck(), ...(initial.ecazTreachery ? ecazTreacheryCards() : [])].map(card => card.id).sort());
|
||||
const traitors = [...game.traitorReserve!, ...game.players.flatMap(p => [...p.traitors, ...p.traitorChoices])];
|
||||
assert.equal(new Set(traitors).size, traitors.length);
|
||||
assert.deepEqual(traitors.sort(), game.players.flatMap(p => p.leaders.map(leader => leader.id)).sort());
|
||||
@@ -121,13 +122,20 @@ void test('only the host can select a boolean rules mode, changes clear human re
|
||||
completedSetup(act(ready(game), game.host, { type: 'start' }));
|
||||
});
|
||||
|
||||
void test('unsupported independent cards and Discovery reject the whole start without silently dropping a module', () => {
|
||||
void test('supported independent cards and Discovery preserve both selected modules through public Basic setup', () => {
|
||||
let game = act(lobby(['atreides', 'emperor']), 'atreides',
|
||||
{ type: 'moduleOption', module: 'ecazTreachery', enabled: true });
|
||||
game = act(game, game.host, { type: 'moduleOption', module: 'discoveries', enabled: true });
|
||||
game = ready(game);
|
||||
reject(game, game.host, { type: 'start' });
|
||||
assert.ok(game.players.every(p => !p.hand.length && !p.traitors.length));
|
||||
const before = structuredClone(game), started = act(game, game.host, { type: 'start' });
|
||||
assert.deepEqual(game, before); assert.equal(started.status, 'setup');
|
||||
assert.equal(started.advanced, false); assert.equal(started.ecazTreachery, true);
|
||||
assert.equal(started.discoveryEnabled, true); assert.ok(started.discoveries);
|
||||
assert.ok(started.spiceDeck.some(card => 'discovery' in card && card.discovery));
|
||||
const cards = [...started.deck, ...started.players.flatMap(p => p.hand)];
|
||||
for (const card of ecazTreacheryCards()) assert.ok(cards.some(held => held.id === card.id));
|
||||
assert.equal(started.semutaPreview, undefined);
|
||||
completedSetup(started);
|
||||
});
|
||||
|
||||
void test('Advanced starts require the exact host opt-in and cannot dispatch audit initializers or hidden bypass options', () => {
|
||||
|
||||
Reference in new issue
Block a user