monsterplex/src/util/progress.js

50 lines
1.5 KiB
JavaScript

import { STORAGE_KEY } from '../config.js';
function readAll() {
try {
const raw = localStorage.getItem(STORAGE_KEY);
return raw ? JSON.parse(raw) : {};
} catch (e) {
return {};
}
}
function writeAll(all) {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(all));
} catch (e) {
// localStorage unavailable (e.g. private browsing) - progress just won't persist
}
}
export function isLevelComplete(levelId) {
return Boolean(readAll()[levelId]);
}
// Records a completed run. kidsSaved/kidsTotal are kept (they're how
// "isLevelComplete" and any legacy saves work), and bestScore is the
// player's highest final score - the level select map shows it under each
// cleared node. A run only "counts" if it improves the best on either
// axis, but whichever axis improved wins; both are kept at their max.
export function markLevelComplete(levelId, kidsSaved, kidsTotal, score = null) {
const all = readAll();
const existing = all[levelId] || {};
all[levelId] = {
kidsSaved: Math.max(existing.kidsSaved || 0, kidsSaved),
kidsTotal,
bestScore: Math.max(existing.bestScore || 0, score || 0),
};
writeAll(all);
}
export function getLevelResult(levelId) {
return readAll()[levelId] || null;
}
// The player's best score for a level, or null if none has been recorded
// yet (e.g. a legacy save from before best scores existed).
export function getBestScore(levelId) {
const result = readAll()[levelId];
return result && typeof result.bestScore === 'number' && result.bestScore > 0 ? result.bestScore : null;
}