diff --git a/dev/neutral.test.mjs b/dev/neutral.test.mjs index 3875a68..9b19584 100644 --- a/dev/neutral.test.mjs +++ b/dev/neutral.test.mjs @@ -185,15 +185,19 @@ function harness() { scene.physics.add.existing(ship); ship.radius = 12; ship.stop = () => {}; - const combat = new CombatSystem(scene, { ship }); - return { scene, ship, combat }; + const activeFlips = []; + const combat = new CombatSystem(scene, { + ship, + onActiveChange: (a) => activeFlips.push(a), + }); + return { scene, ship, combat, activeFlips }; } const ids = neutralTypeIds(); // ---------------------------------------------------------------- roster + escort { - const { ship, combat } = harness(); + const { ship, combat, activeFlips } = harness(); const base = config.section('combat.neutral', {}); check('config: the escort window is data (neutral.escortMin/escortMax = 10–15 s)', base.escortMin === 10 && base.escortMax === 15); @@ -240,6 +244,11 @@ const ids = neutralTypeIds(); check('despawn: broken escorts off-screen are collected (encounter ends)', combat.allies.length === 0); check('active: over when the last escort is off-screen', combat.active === false); + // The seam the scene hangs the deck/soundtrack swap on (GameScene + // _setCombatBar — combat bar out, normal deck + deep-space music back) + // must fire on the break-off cull, not only on a kill. + check('seam: onActiveChange flips true→false when the last escort leaves the screen', + JSON.stringify(activeFlips) === '[true,false]'); } // ---------------------------------------------------------------- engage diff --git a/js/combat/CombatSystem.js b/js/combat/CombatSystem.js index 9110fe5..ca9b0b8 100644 --- a/js/combat/CombatSystem.js +++ b/js/combat/CombatSystem.js @@ -650,6 +650,11 @@ export class CombatSystem { } } this.allies = this.allies.filter((a) => !a.gone && !a._removed); + // The last escort off-screen (with the pack spent) is the encounter + // OVER — the flip back to the normal deck/soundtrack rides the same + // seam as a kill (killEnemy/killAlly already fire it; the break-off + // cull is the ending that was missing it). + this._setActive(); } // 2) AUTO-FIRE: the nearest VISIBLE hostile in range (game.autoFire).