burn: add export/import save and keyboard shortcut help overlay (#47)
- Export button copies save JSON to clipboard - Import button prompts for pasted save data, validates, and reloads - Press ? to toggle hotkey overlay showing all keyboard shortcuts - Press Escape to close the overlay - Styling matches the existing cyber-monastic aesthetic
This commit is contained in:
67
game.js
67
game.js
@@ -2131,6 +2131,65 @@ function saveGame() {
|
||||
showSaveToast();
|
||||
}
|
||||
|
||||
|
||||
// === EXPORT / IMPORT ===
|
||||
function exportSave() {
|
||||
const raw = localStorage.getItem('the-beacon-v2');
|
||||
if (!raw) { log('No save data to export.'); return; }
|
||||
navigator.clipboard.writeText(raw).then(() => {
|
||||
log('Save data copied to clipboard.');
|
||||
showExportToast('Save copied to clipboard');
|
||||
}).catch(() => {
|
||||
// Fallback: select in a temporary textarea
|
||||
const ta = document.createElement('textarea');
|
||||
ta.value = raw;
|
||||
document.body.appendChild(ta);
|
||||
ta.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(ta);
|
||||
log('Save data copied to clipboard (fallback).');
|
||||
showExportToast('Save copied to clipboard');
|
||||
});
|
||||
}
|
||||
|
||||
function importSave() {
|
||||
const input = prompt('Paste save data:');
|
||||
if (!input || !input.trim()) return;
|
||||
try {
|
||||
const data = JSON.parse(input.trim());
|
||||
// Validate: must have expected keys
|
||||
if (typeof data.code !== 'number' || typeof data.phase !== 'number') {
|
||||
log('Invalid save data: missing required fields.');
|
||||
return;
|
||||
}
|
||||
localStorage.setItem('the-beacon-v2', input.trim());
|
||||
log('Save data imported. Reloading...');
|
||||
showExportToast('Save imported — reloading');
|
||||
setTimeout(() => location.reload(), 800);
|
||||
} catch (e) {
|
||||
log('Invalid save data: not valid JSON.');
|
||||
}
|
||||
}
|
||||
|
||||
function showExportToast(msg) {
|
||||
const el = document.getElementById('save-toast');
|
||||
if (!el) return;
|
||||
el.textContent = msg;
|
||||
el.style.display = 'block';
|
||||
requestAnimationFrame(() => { el.style.opacity = '1'; });
|
||||
setTimeout(() => {
|
||||
el.style.opacity = '0';
|
||||
setTimeout(() => { el.style.display = 'none'; }, 500);
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
function toggleHotkeyHelp() {
|
||||
const el = document.getElementById('hotkey-overlay');
|
||||
if (!el) return;
|
||||
el.style.display = el.style.display === 'flex' ? 'none' : 'flex';
|
||||
}
|
||||
|
||||
|
||||
function loadGame() {
|
||||
const raw = localStorage.getItem('the-beacon-v2');
|
||||
if (!raw) return false;
|
||||
@@ -2308,4 +2367,12 @@ window.addEventListener('keydown', function (e) {
|
||||
else setBuyAmount(1);
|
||||
}
|
||||
if (e.code === 'KeyS') activateSprint();
|
||||
if (e.code === 'Slash' && e.shiftKey) {
|
||||
e.preventDefault();
|
||||
toggleHotkeyHelp();
|
||||
}
|
||||
if (e.code === 'Escape') {
|
||||
const el = document.getElementById('hotkey-overlay');
|
||||
if (el) el.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user