Compare commits
4 Commits
fix/issue-
...
am/16-1776
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40f1d0005a | ||
|
|
30342ec575 | ||
|
|
7e05a93d5e | ||
|
|
aa88937509 |
@@ -167,7 +167,6 @@ const G = {
|
||||
dismantleStage: 0,
|
||||
dismantleResourceIndex: 0,
|
||||
dismantleResourceTimer: 0,
|
||||
dismantleDeferUntilAt: 0,
|
||||
dismantleComplete: false
|
||||
};
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ const Dismantle = {
|
||||
tickTimer: 0,
|
||||
active: false,
|
||||
triggered: false,
|
||||
deferUntilAt: 0,
|
||||
deferUntilTick: 0,
|
||||
|
||||
// Timing: seconds between each dismantle stage
|
||||
STAGE_INTERVALS: [0, 3.0, 2.5, 2.5, 2.0, 6.3, 2.0, 2.0, 2.5],
|
||||
@@ -39,8 +39,7 @@ const Dismantle = {
|
||||
*/
|
||||
checkTrigger() {
|
||||
if (this.triggered || G.dismantleTriggered || this.active || G.dismantleActive || G.dismantleComplete) return;
|
||||
const deferUntilAt = G.dismantleDeferUntilAt || this.deferUntilAt || 0;
|
||||
if (Date.now() < deferUntilAt) return;
|
||||
if ((G.tick || 0) < (this.deferUntilTick || 0)) return;
|
||||
if (!this.isEligible()) return;
|
||||
this.offerChoice();
|
||||
},
|
||||
@@ -56,7 +55,6 @@ const Dismantle = {
|
||||
G.dismantleStage = 0;
|
||||
G.dismantleResourceIndex = 0;
|
||||
G.dismantleResourceTimer = 0;
|
||||
G.dismantleDeferUntilAt = 0;
|
||||
G.beaconEnding = false;
|
||||
G.running = true;
|
||||
|
||||
@@ -109,8 +107,7 @@ const Dismantle = {
|
||||
this.clearChoice();
|
||||
this.triggered = false;
|
||||
G.dismantleTriggered = false;
|
||||
this.deferUntilAt = Date.now() + 5000;
|
||||
G.dismantleDeferUntilAt = this.deferUntilAt;
|
||||
this.deferUntilTick = (G.tick || 0) + 50;
|
||||
log('The Beacon waits. It will ask again.');
|
||||
},
|
||||
|
||||
@@ -120,14 +117,12 @@ const Dismantle = {
|
||||
begin() {
|
||||
this.active = true;
|
||||
this.triggered = false;
|
||||
this.deferUntilAt = 0;
|
||||
this.stage = 1;
|
||||
this.tickTimer = 0;
|
||||
G.dismantleTriggered = false;
|
||||
G.dismantleActive = true;
|
||||
G.dismantleStage = 1;
|
||||
G.dismantleComplete = false;
|
||||
G.dismantleDeferUntilAt = 0;
|
||||
G.beaconEnding = false;
|
||||
G.running = true; // keep tick running for dismantle
|
||||
|
||||
@@ -461,7 +456,6 @@ const Dismantle = {
|
||||
this.active = true;
|
||||
this.triggered = false;
|
||||
this.stage = G.dismantleStage || 1;
|
||||
this.deferUntilAt = G.dismantleDeferUntilAt || 0;
|
||||
G.running = true;
|
||||
this.resourceSequence = this.getResourceList();
|
||||
this.resourceIndex = G.dismantleResourceIndex || 0;
|
||||
@@ -481,11 +475,6 @@ const Dismantle = {
|
||||
this.triggered = true;
|
||||
this.renderChoice();
|
||||
}
|
||||
|
||||
// Restore defer cooldown even if not triggered
|
||||
if (G.dismantleDeferUntilAt > 0) {
|
||||
this.deferUntilAt = G.dismantleDeferUntilAt;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -422,11 +422,6 @@ 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();
|
||||
|
||||
@@ -35,7 +35,7 @@ window.addEventListener('load', function () {
|
||||
if (G.driftEnding) {
|
||||
G.running = false;
|
||||
renderDriftEnding();
|
||||
} else if (typeof Dismantle !== 'undefined' && (G.dismantleTriggered || G.dismantleActive || G.dismantleComplete || G.dismantleDeferUntilAt > 0)) {
|
||||
} else if (typeof Dismantle !== 'undefined' && (G.dismantleTriggered || G.dismantleActive || G.dismantleComplete)) {
|
||||
Dismantle.restore();
|
||||
} else if (G.beaconEnding) {
|
||||
G.running = false;
|
||||
|
||||
@@ -232,7 +232,6 @@ function saveGame() {
|
||||
dismantleStage: G.dismantleStage || 0,
|
||||
dismantleResourceIndex: G.dismantleResourceIndex || 0,
|
||||
dismantleResourceTimer: G.dismantleResourceTimer || 0,
|
||||
dismantleDeferUntilAt: G.dismantleDeferUntilAt || 0,
|
||||
dismantleComplete: G.dismantleComplete || false,
|
||||
savedAt: Date.now()
|
||||
};
|
||||
@@ -267,7 +266,7 @@ function loadGame() {
|
||||
'sprintActive', 'sprintTimer', 'sprintCooldown',
|
||||
'swarmFlag', 'swarmRate', 'strategicFlag', 'projectsCollapsed',
|
||||
'dismantleTriggered', 'dismantleActive', 'dismantleStage',
|
||||
'dismantleResourceIndex', 'dismantleResourceTimer', 'dismantleDeferUntilAt', 'dismantleComplete'
|
||||
'dismantleResourceIndex', 'dismantleResourceTimer', 'dismantleComplete'
|
||||
];
|
||||
|
||||
G.isLoading = true;
|
||||
|
||||
@@ -208,8 +208,6 @@ 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,
|
||||
@@ -331,6 +329,7 @@ test('deferring the Unbuilding clears the prompt and allows it to return later',
|
||||
G.totalCode = 1_000_000_000;
|
||||
G.phase = 6;
|
||||
G.pactFlag = 1;
|
||||
G.tick = 0;
|
||||
|
||||
Dismantle.checkTrigger();
|
||||
assert.equal(G.dismantleTriggered, true);
|
||||
@@ -339,44 +338,15 @@ test('deferring the Unbuilding clears the prompt and allows it to return later',
|
||||
assert.equal(G.dismantleTriggered, false);
|
||||
assert.equal(document.getElementById('alignment-ui').innerHTML, '');
|
||||
|
||||
Dismantle.deferUntilAt = Date.now() + 1000;
|
||||
G.dismantleDeferUntilAt = Dismantle.deferUntilAt;
|
||||
G.tick = (Dismantle.deferUntilTick || 0) - 0.1;
|
||||
Dismantle.checkTrigger();
|
||||
assert.equal(G.dismantleTriggered, false);
|
||||
|
||||
Dismantle.deferUntilAt = Date.now() - 1;
|
||||
G.dismantleDeferUntilAt = Dismantle.deferUntilAt;
|
||||
G.tick = (Dismantle.deferUntilTick || 0) + 1;
|
||||
Dismantle.checkTrigger();
|
||||
assert.equal(G.dismantleTriggered, true);
|
||||
});
|
||||
|
||||
test('defer cooldown survives save and reload', () => {
|
||||
const { G, Dismantle, saveGame, loadGame } = loadBeacon({ includeRender: true });
|
||||
|
||||
G.startedAt = Date.now();
|
||||
G.totalCode = 1_000_000_000;
|
||||
G.phase = 6;
|
||||
G.pactFlag = 1;
|
||||
|
||||
Dismantle.checkTrigger();
|
||||
Dismantle.defer();
|
||||
assert.ok((Dismantle.deferUntilAt || 0) > Date.now());
|
||||
|
||||
saveGame();
|
||||
|
||||
G.dismantleTriggered = false;
|
||||
G.dismantleActive = false;
|
||||
G.dismantleComplete = false;
|
||||
G.dismantleDeferUntilAt = 0;
|
||||
Dismantle.triggered = false;
|
||||
Dismantle.deferUntilAt = 0;
|
||||
|
||||
assert.equal(loadGame(), true);
|
||||
Dismantle.checkTrigger();
|
||||
|
||||
assert.equal(G.dismantleTriggered, false);
|
||||
});
|
||||
|
||||
test('save and load preserve dismantle progress', () => {
|
||||
const { G, saveGame, loadGame } = loadBeacon({ includeRender: true });
|
||||
|
||||
@@ -411,68 +381,4 @@ test('restore re-renders an offered but not-yet-started Unbuilding prompt', () =
|
||||
Dismantle.restore();
|
||||
|
||||
assert.match(document.getElementById('alignment-ui').innerHTML, /THE UNBUILDING/);
|
||||
});
|
||||
|
||||
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), []);
|
||||
});
|
||||
|
||||
test('defer cooldown persists after save/load when dismantleTriggered is false', () => {
|
||||
const { G, Dismantle, saveGame, loadGame } = loadBeacon({ includeRender: true });
|
||||
|
||||
G.startedAt = Date.now();
|
||||
G.totalCode = 1_000_000_000;
|
||||
G.phase = 6;
|
||||
G.pactFlag = 1;
|
||||
|
||||
// Trigger the Unbuilding
|
||||
Dismantle.checkTrigger();
|
||||
assert.equal(G.dismantleTriggered, true);
|
||||
|
||||
// Defer it
|
||||
Dismantle.defer();
|
||||
assert.equal(G.dismantleTriggered, false);
|
||||
assert.ok((Dismantle.deferUntilAt || 0) > Date.now());
|
||||
assert.ok((G.dismantleDeferUntilAt || 0) > Date.now());
|
||||
|
||||
// Save the game
|
||||
saveGame();
|
||||
|
||||
// Clear state (simulate reload)
|
||||
G.dismantleTriggered = false;
|
||||
G.dismantleActive = false;
|
||||
G.dismantleComplete = false;
|
||||
G.dismantleDeferUntilAt = 0;
|
||||
Dismantle.triggered = false;
|
||||
Dismantle.deferUntilAt = 0;
|
||||
|
||||
// Load the game
|
||||
assert.equal(loadGame(), true);
|
||||
Dismantle.restore(); // Call restore to restore defer cooldown
|
||||
|
||||
// The cooldown should be restored
|
||||
assert.ok((Dismantle.deferUntilAt || 0) > Date.now(), 'deferUntilAt should be restored');
|
||||
assert.ok((G.dismantleDeferUntilAt || 0) > Date.now(), 'G.dismantleDeferUntilAt should be restored');
|
||||
|
||||
// checkTrigger should not trigger because cooldown is active
|
||||
Dismantle.checkTrigger();
|
||||
assert.equal(G.dismantleTriggered, false, 'dismantleTriggered should remain false during cooldown');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user