mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
fix(missions): keep the replay countdown real-time when the speed changes
Moving the replay-speed slider during the pre-launch hold or countdown rescaled the time left to liftoff, so 0.25x turned T-8 into T-32 and 4x into T-2. The speed change now skips a replay that has not lifted off; mission time already flown is still preserved as before.
This commit is contained in:
1 parent
a4d3701c3c
commit
a2c813280e
2 files changed
+49
-1
No files matched your search
@@ -281,7 +281,8 @@ export function createReplay({ state: layerState, services, parts, source }) {
|
|||||||
? layerState._replayPausedAtMs
|
? layerState._replayPausedAtMs
|
||||||
: Date.now();
|
: Date.now();
|
||||||
for (const [launchId, startedAt] of layerState._animationStarts) {
|
for (const [launchId, startedAt] of layerState._animationStarts) {
|
||||||
if (!Number.isFinite(startedAt)) continue;
|
// A countdown runs in real time; rescaling it turned T-8 into T-32 at 0.25x.
|
||||||
|
if (!Number.isFinite(startedAt) || startedAt > now) continue;
|
||||||
const elapsedMissionMs = (now - startedAt) * previousSpeed;
|
const elapsedMissionMs = (now - startedAt) * previousSpeed;
|
||||||
layerState._animationStarts.set(
|
layerState._animationStarts.set(
|
||||||
launchId,
|
launchId,
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import { createState } from './state.js';
|
||||||
|
import { createReplay } from './replay.js';
|
||||||
|
import { createPaths } from './paths.js';
|
||||||
|
|
||||||
|
const noop = () => {};
|
||||||
|
|
||||||
|
function replayRig() {
|
||||||
|
const state = createState({
|
||||||
|
services: {
|
||||||
|
overlays: {
|
||||||
|
setOverlayEntries: noop,
|
||||||
|
setOverlaySourceVisible: noop,
|
||||||
|
clearOverlaySource: noop,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const parts = {};
|
||||||
|
parts.paths = createPaths({ state, parts });
|
||||||
|
return { state, replay: createReplay({ state, parts }) };
|
||||||
|
}
|
||||||
|
|
||||||
|
test('changing replay speed during the countdown keeps its real-time liftoff', (t) => {
|
||||||
|
t.mock.timers.enable({ apis: ['Date'], now: 1_000_000 });
|
||||||
|
const { state, replay } = replayRig();
|
||||||
|
const launch = { launchTime: '2026-07-20T10:00:00Z', timeline: [] };
|
||||||
|
state._animationStarts.set('countdown', 1_008_000); // T-8
|
||||||
|
state._animationStarts.set('flying', 990_000); // 10 s into the mission
|
||||||
|
|
||||||
|
replay.setReplaySpeed(0.25);
|
||||||
|
|
||||||
|
const startedAt = state._animationStarts.get('countdown');
|
||||||
|
assert.equal(startedAt, 1_008_000);
|
||||||
|
const countdown = replay.replayState(
|
||||||
|
launch,
|
||||||
|
startedAt,
|
||||||
|
12,
|
||||||
|
28,
|
||||||
|
5400,
|
||||||
|
state._replaySpeed,
|
||||||
|
Date.now(),
|
||||||
|
);
|
||||||
|
assert.equal(countdown.countdownSeconds, 8);
|
||||||
|
// Mission time already flown is still preserved across the change.
|
||||||
|
assert.equal(state._animationStarts.get('flying'), 960_000);
|
||||||
|
});
|
||||||
Reference in new issue
Block a user