diff --git a/js/engine.js b/js/engine.js index 4eb1d2c..8825632 100644 --- a/js/engine.js +++ b/js/engine.js @@ -422,6 +422,11 @@ function buyProject(id) { if (!G.completedProjects) G.completedProjects = []; G.completedProjects.push(pDef.id); G.activeProjects = G.activeProjects.filter(aid => aid !== pDef.id); + + // Final ReCKoning choices should end with no unrelated active research left behind. + if (pDef.id === 'p_reckoning_147' || pDef.id === 'p_reckoning_148') { + G.activeProjects = []; + } } updateRates(); diff --git a/tests/dismantle.test.cjs b/tests/dismantle.test.cjs index 5603195..3d20b3e 100644 --- a/tests/dismantle.test.cjs +++ b/tests/dismantle.test.cjs @@ -208,6 +208,8 @@ showSaveToast = () => {}; this.__exports = { G, Dismantle, + PDEFS: typeof PDEFS !== 'undefined' ? PDEFS : null, + buyProject: typeof buyProject === 'function' ? buyProject : null, tick, renderAlignment: typeof renderAlignment === 'function' ? renderAlignment : null, saveGame: typeof saveGame === 'function' ? saveGame : null, @@ -452,3 +454,25 @@ test('defer cooldown persists after save/load when dismantleTriggered is false', Dismantle.checkTrigger(); assert.equal(G.dismantleTriggered, false, 'dismantleTriggered should remain false during cooldown'); }); + +test('completing the final ReCKoning choice clears unrelated active projects', () => { + const { G, PDEFS, buyProject } = loadBeacon(); + + G.beaconEnding = true; + G.activeProjects = ['p_wire_budget', 'p_reckoning_148']; + G.completedProjects = []; + G.trust = 10; + + PDEFS.push({ + id: 'p_reckoning_148', + name: 'Rest', + desc: 'Final ReCKoning choice', + cost: {}, + trigger: () => false, + effect: () => {}, + }); + + buyProject('p_reckoning_148'); + + assert.deepEqual(Array.from(G.activeProjects), []); +});