Compose the Sneak Attack arrival with the Bene Gesserit reactions
A positive Moritani Sneak Attack now resolves its committed Terror entry first — placing the reserve forces and accruing the Heighliners token — and then offers the Bene Gesserit reactions under the same adopted shipment classification used for ordinary off-planet arrivals: an eligible Advanced Intrusion choice when Bene Gesserit fighters stand in the destination, carrying the free spiritual-advisor follow-up, and the advisor shipment itself when the intrusion is declined, with its existing territory, storm and occupancy validation. A zero-force resolution still opens none of them, and the last "Sneak Attack combined with Bene Gesserit arrival reactions" guard is removed rather than left as a duplicate check. This selected order is an implementation interpretation, not a located ruling; the source note, the pending-interpretation registry, the component inventory, the player reference and the status log record it. Evidence: tests/moritani-force-leader.test.ts asserts the post-entry Intrusion offer and the full decline -> advisor decision -> placement chain with nothing left pending; the former gated-interaction pin was replaced by the composed behaviour. Offline suite 7,798/7,798 with typecheck and lint clean, plus the reference guide tests 10/10. No game, seat, saved state or deployment changes.
This commit is contained in:
1 parent
972b781d0a
commit
3bebc68cd5
8 files changed
+96
-26
No files matched your search
@@ -340,17 +340,48 @@ void test('Sneak Attack rejects an altered client sector and accrues Heighliners
|
||||
assert.equal(passed.pendingTerrorEntry, null);
|
||||
});
|
||||
|
||||
void test('Sneak Attack leaves unresolved Bene Gesserit arrival interactions unchanged and permits zero', () => {
|
||||
void test('Sneak Attack resolves the committed entry and then offers the Bene Gesserit arrival reactions', () => {
|
||||
const initial = fixture('sneakAttack', 'beneGesserit');
|
||||
initial.advanced = true;
|
||||
player(initial, 'e').forces = { 'arrakeen:10': 1 };
|
||||
player(initial, 'e').reserves = 19;
|
||||
const revealed = decide(enter(initial), { reveal: true });
|
||||
rejected(revealed, { type: 'decision', amount: 1 });
|
||||
const done = decide(revealed, { amount: 0 });
|
||||
assert.deepEqual(done.players, revealed.players);
|
||||
const done = decide(revealed, { amount: 1 });
|
||||
assert.equal(player(done, 'm').forces['arrakeen:10'], 1);
|
||||
assert.equal(player(done, 'm').reserves, 19);
|
||||
assert.equal(done.pendingTerrorEntry, null);
|
||||
assert.equal(done.decision, null);
|
||||
assert.equal(done.decision?.kind, 'intrusion');
|
||||
assert.equal(done.decision?.player, 'e');
|
||||
const zero = decide(revealed, { amount: 0 });
|
||||
assert.deepEqual(zero.players, revealed.players);
|
||||
assert.equal(zero.pendingTerrorEntry, null);
|
||||
assert.equal(zero.decision, null);
|
||||
});
|
||||
|
||||
void test('declining the Bene Gesserit intrusion still offers the free advisor shipment and completes the entry', () => {
|
||||
const initial = fixture('sneakAttack', 'beneGesserit');
|
||||
initial.advanced = true;
|
||||
player(initial, 'e').forces = { 'arrakeen:10': 1 };
|
||||
player(initial, 'e').reserves = 19;
|
||||
const revealed = decide(enter(initial), { reveal: true });
|
||||
const sneaked = decide(revealed, { amount: 2 });
|
||||
assert.equal(sneaked.decision?.kind, 'intrusion');
|
||||
const declined = applyAction(sneaked, 'e', { type: 'decision', accept: false });
|
||||
assert.equal(declined.decision?.kind, 'advisor');
|
||||
assert.equal(declined.decision?.player, 'e');
|
||||
const offered = applyAction(declined, 'e', {
|
||||
type: 'decision',
|
||||
accept: true,
|
||||
amount: 1,
|
||||
});
|
||||
assert.equal(offered.response ?? null, null);
|
||||
assert.equal(offered.pendingTerrorEntry, null);
|
||||
assert.equal(player(offered, 'm').forces['arrakeen:10'], 2);
|
||||
assert.equal(
|
||||
player(offered, 'e').forces['polar_sink:0'] ?? 0,
|
||||
1,
|
||||
'The declined intrusion still lets the Bene Gesserit send one free reserve force.',
|
||||
);
|
||||
});
|
||||
|
||||
void test('all four AI profiles complete blocked effects by declining instead of retrying illegal choices', () => {
|
||||
|
||||
Reference in new issue
Block a user