Session 13: Save Slot Preview (footer shows each slot's stardust, buildings, achievements, last-saved; hover to preview)
This commit is contained in:
+76
@@ -637,6 +637,82 @@ const Game = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Build a lightweight preview of a given save slot WITHOUT mutating the
|
||||
* live game state. Returns an object describing what that slot holds:
|
||||
* - present: whether the slot has any saved data
|
||||
* - stardust: current (live) stardust production/sec for the slot
|
||||
* - totalStardust: lifetime stardust earned in the slot
|
||||
* - buildings: total number of buildings owned in the slot
|
||||
* - achievements: count/total of achievements unlocked in the slot
|
||||
* - prestigeCount: how many times the slot has been prestiged
|
||||
* - lastSaved: human-readable "time ago" string for the slot's save time
|
||||
* An empty/unreadable slot returns present:false with zeroed fields.
|
||||
*/
|
||||
getSlotPreview(slot) {
|
||||
const data = this.loadSlot(slot);
|
||||
if (!data) {
|
||||
return {
|
||||
present: false,
|
||||
stardust: 0,
|
||||
totalStardust: 0,
|
||||
buildings: 0,
|
||||
achievements: [0, 33],
|
||||
prestigeCount: 0,
|
||||
lastSaved: 'never'
|
||||
};
|
||||
}
|
||||
|
||||
const buildingCount = Object.values(data.buildings || {})
|
||||
.reduce((sum, c) => sum + (Number(c) || 0), 0);
|
||||
|
||||
let timeAgo = 'never';
|
||||
if (typeof data.lastSaveTime === 'number') {
|
||||
const secs = Math.max(0, Math.floor((Date.now() - data.lastSaveTime) / 1000));
|
||||
timeAgo = this.formatTimeAgo(secs);
|
||||
}
|
||||
|
||||
return {
|
||||
present: true,
|
||||
stardust: Number(data.stardust) || 0,
|
||||
totalStardust: Number(data.totalStardust) || 0,
|
||||
buildings: buildingCount,
|
||||
achievements: [
|
||||
Array.isArray(data.achievements) ? data.achievements.length : 0,
|
||||
33
|
||||
],
|
||||
prestigeCount: Number(data.prestigeCount) || 0,
|
||||
lastSaved: timeAgo
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Format a number of seconds as a compact "time ago" string
|
||||
* (e.g. "just now", "1m ago", "3h ago", "2d ago"). Used by slot previews.
|
||||
*/
|
||||
formatTimeAgo(secs) {
|
||||
if (secs < 5) return 'just now';
|
||||
|
||||
// Largest units first; each entry is [thresholdSeconds, label].
|
||||
const buckets = [
|
||||
[365 * 86400, 'y'],
|
||||
[30 * 86400, 'mo'],
|
||||
[86400, 'd'],
|
||||
[3600, 'h'],
|
||||
[60, 'm']
|
||||
];
|
||||
|
||||
for (const [threshold, label] of buckets) {
|
||||
if (secs >= threshold) {
|
||||
const value = Math.floor(secs / threshold);
|
||||
return `${value}${label} ago`;
|
||||
}
|
||||
}
|
||||
|
||||
// Below one minute.
|
||||
return `${Math.max(1, secs)}s ago`;
|
||||
},
|
||||
|
||||
/**
|
||||
* Switch the active save slot. Persists the selection and reloads that
|
||||
* slot's data from localStorage into the live game state, preserving
|
||||
|
||||
Reference in New Issue
Block a user