beacon: persist stage-five dissolve progress

This commit is contained in:
Timmy
2026-04-14 07:46:25 -04:00
committed by Alexander Whitestone
parent cff3d1715b
commit 4f0b54a970
4 changed files with 83 additions and 2 deletions

View File

@@ -165,6 +165,8 @@ const G = {
dismantleTriggered: false,
dismantleActive: false,
dismantleStage: 0,
dismantleResourceIndex: 0,
dismantleResourceTimer: 0,
dismantleComplete: false
};

View File

@@ -17,7 +17,7 @@ const Dismantle = {
deferUntilTick: 0,
// Timing: seconds between each dismantle stage
STAGE_INTERVALS: [0, 3.0, 2.5, 2.5, 2.0, 3.5, 2.0, 2.0, 2.5],
STAGE_INTERVALS: [0, 3.0, 2.5, 2.5, 2.0, 6.3, 2.0, 2.0, 2.5],
// The quantum chips effect: resource items disappear one by one
// at specific tick marks within a stage (like Paperclips' quantum chips)
@@ -53,6 +53,8 @@ const Dismantle = {
G.dismantleActive = false;
G.dismantleComplete = false;
G.dismantleStage = 0;
G.dismantleResourceIndex = 0;
G.dismantleResourceTimer = 0;
G.beaconEnding = false;
G.running = true;
@@ -135,6 +137,7 @@ const Dismantle = {
this.resourceSequence = this.getResourceList();
this.resourceIndex = 0;
this.resourceTimer = 0;
this.syncProgress();
log('', false);
log('=== THE UNBUILDING ===', true);
@@ -180,6 +183,7 @@ const Dismantle = {
this.dismantleNextResource();
this.resourceIndex++;
}
this.syncProgress();
}
// Advance to next stage
@@ -195,6 +199,7 @@ const Dismantle = {
*/
advanceStage() {
this.stage++;
this.syncProgress();
if (this.stage <= 8) {
this.renderStage();
@@ -210,6 +215,12 @@ const Dismantle = {
}
},
syncProgress() {
G.dismantleStage = this.stage;
G.dismantleResourceIndex = this.resourceIndex;
G.dismantleResourceTimer = this.resourceTimer;
},
/**
* Disappear the next resource in the sequence.
*/
@@ -446,6 +457,9 @@ const Dismantle = {
this.triggered = false;
this.stage = G.dismantleStage || 1;
G.running = true;
this.resourceSequence = this.getResourceList();
this.resourceIndex = G.dismantleResourceIndex || 0;
this.resourceTimer = G.dismantleResourceTimer || 0;
if (this.stage >= 9) {
this.renderFinal();
@@ -501,6 +515,10 @@ const Dismantle = {
case 8: this.instantHide('log'); break;
}
}
if (this.stage === 5 && this.resourceIndex > 0) {
this.instantHideFirstResources(this.resourceIndex);
}
},
instantHide(id) {
@@ -508,6 +526,16 @@ const Dismantle = {
if (el) el.style.display = 'none';
},
instantHideFirstResources(count) {
const resources = this.getResourceList().slice(0, count);
resources.forEach((r) => {
const el = document.getElementById(r.id);
if (!el) return;
const parent = el.closest('.res');
if (parent) parent.style.display = 'none';
});
},
instantHideActionButtons() {
const actionPanel = document.getElementById('action-panel');
if (!actionPanel) return;

View File

@@ -230,6 +230,8 @@ function saveGame() {
dismantleTriggered: G.dismantleTriggered || false,
dismantleActive: G.dismantleActive || false,
dismantleStage: G.dismantleStage || 0,
dismantleResourceIndex: G.dismantleResourceIndex || 0,
dismantleResourceTimer: G.dismantleResourceTimer || 0,
dismantleComplete: G.dismantleComplete || false,
savedAt: Date.now()
};
@@ -263,7 +265,8 @@ function loadGame() {
'lastEventAt', 'totalEventsResolved', 'buyAmount',
'sprintActive', 'sprintTimer', 'sprintCooldown',
'swarmFlag', 'swarmRate', 'strategicFlag', 'projectsCollapsed',
'dismantleTriggered', 'dismantleActive', 'dismantleStage', 'dismantleComplete'
'dismantleTriggered', 'dismantleActive', 'dismantleStage',
'dismantleResourceIndex', 'dismantleResourceTimer', 'dismantleComplete'
];
G.isLoading = true;

View File

@@ -275,6 +275,54 @@ test('active Unbuilding suppresses pending alignment event UI', () => {
assert.equal(document.getElementById('alignment-ui').style.display, 'none');
});
test('stage five lasts long enough to dissolve every resource card', () => {
const { G, Dismantle } = loadBeacon();
Dismantle.begin();
Dismantle.stage = 5;
Dismantle.tickTimer = 0;
Dismantle.resourceSequence = Dismantle.getResourceList();
Dismantle.resourceIndex = 0;
Dismantle.resourceTimer = 0;
G.dismantleActive = true;
G.dismantleStage = 5;
for (let i = 0; i < 63; i++) Dismantle.tick(0.1);
assert.equal(Dismantle.resourceIndex, Dismantle.resourceSequence.length);
});
test('save/load restores partial stage-five dissolve progress', () => {
const { G, Dismantle, saveGame, loadGame, document } = loadBeacon({ includeRender: true });
G.startedAt = Date.now();
G.dismantleTriggered = true;
G.dismantleActive = true;
G.dismantleStage = 5;
G.dismantleComplete = false;
G.dismantleResourceIndex = 4;
G.dismantleResourceTimer = 4.05;
saveGame();
G.dismantleTriggered = false;
G.dismantleActive = false;
G.dismantleStage = 0;
G.dismantleComplete = false;
G.dismantleResourceIndex = 0;
G.dismantleResourceTimer = 0;
Dismantle.resourceIndex = 0;
Dismantle.resourceTimer = 0;
assert.equal(loadGame(), true);
Dismantle.restore();
assert.equal(Dismantle.resourceIndex, 4);
assert.equal(document.getElementById('r-harmony').closest('.res').style.display, 'none');
assert.equal(document.getElementById('r-ops').closest('.res').style.display, 'none');
assert.notEqual(document.getElementById('r-rescues').closest('.res').style.display, 'none');
});
test('deferring the Unbuilding clears the prompt and allows it to return later', () => {
const { G, Dismantle, document } = loadBeacon();