Compare commits
3 Commits
feature/lo
...
burn/20260
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13e77a12f2 | ||
| 6081844387 | |||
|
|
09b8c02307 |
92
game.js
92
game.js
@@ -729,6 +729,14 @@ function fmt(n) {
|
||||
return (n / Math.pow(10, scale * 3)).toFixed(1) + abbrev;
|
||||
}
|
||||
|
||||
// getScaleName() — Returns the full name of the number scale (e.g. "quadrillion")
|
||||
// Educational: helps players understand what the abbreviations mean
|
||||
function getScaleName(n) {
|
||||
if (n < 1000) return '';
|
||||
const scale = Math.floor(Math.log10(n) / 3);
|
||||
return scale < NUMBER_NAMES.length ? NUMBER_NAMES[scale] : '';
|
||||
}
|
||||
|
||||
// spellf() — Converts numbers to full English word form
|
||||
// Educational: shows the actual names of number scales
|
||||
// Examples: spellf(1500) => "one thousand five hundred"
|
||||
@@ -1483,7 +1491,11 @@ function doOps(action) {
|
||||
function renderResources() {
|
||||
const set = (id, val, rate) => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.textContent = fmt(val);
|
||||
if (el) {
|
||||
el.textContent = fmt(val);
|
||||
// Show full spelled-out number on hover for educational value
|
||||
el.title = val >= 1000 ? spellf(Math.floor(val)) : '';
|
||||
}
|
||||
const rEl = document.getElementById(id + '-rate');
|
||||
if (rEl) rEl.textContent = (rate >= 0 ? '+' : '') + fmt(rate) + '/s';
|
||||
};
|
||||
@@ -1692,13 +1704,23 @@ function renderProjects() {
|
||||
}
|
||||
|
||||
function renderStats() {
|
||||
const set = (id, v) => { const el = document.getElementById(id); if (el) el.textContent = v; };
|
||||
set('st-code', fmt(G.totalCode));
|
||||
set('st-compute', fmt(G.totalCompute));
|
||||
set('st-knowledge', fmt(G.totalKnowledge));
|
||||
set('st-users', fmt(G.totalUsers));
|
||||
set('st-impact', fmt(G.totalImpact));
|
||||
set('st-rescues', fmt(G.totalRescues));
|
||||
const set = (id, v, raw) => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) {
|
||||
el.textContent = v;
|
||||
// Show scale name on hover for educational reference
|
||||
if (raw !== undefined && raw >= 1000) {
|
||||
const name = getScaleName(raw);
|
||||
if (name) el.title = name;
|
||||
}
|
||||
}
|
||||
};
|
||||
set('st-code', fmt(G.totalCode), G.totalCode);
|
||||
set('st-compute', fmt(G.totalCompute), G.totalCompute);
|
||||
set('st-knowledge', fmt(G.totalKnowledge), G.totalKnowledge);
|
||||
set('st-users', fmt(G.totalUsers), G.totalUsers);
|
||||
set('st-impact', fmt(G.totalImpact), G.totalImpact);
|
||||
set('st-rescues', fmt(G.totalRescues), G.totalRescues);
|
||||
set('st-clicks', G.totalClicks.toString());
|
||||
set('st-phase', G.phase.toString());
|
||||
set('st-buildings', Object.values(G.buildings).reduce((a, b) => a + b, 0).toString());
|
||||
@@ -1925,6 +1947,35 @@ function renderAlignment() {
|
||||
}
|
||||
}
|
||||
|
||||
// === OFFLINE GAINS POPUP ===
|
||||
function showOfflinePopup(timeLabel, gains, offSec) {
|
||||
const el = document.getElementById('offline-popup');
|
||||
if (!el) return;
|
||||
const timeEl = document.getElementById('offline-time-label');
|
||||
if (timeEl) timeEl.textContent = `You were away for ${timeLabel}.`;
|
||||
|
||||
const listEl = document.getElementById('offline-gains-list');
|
||||
if (listEl) {
|
||||
let html = '';
|
||||
for (const g of gains) {
|
||||
html += `<div style="display:flex;justify-content:space-between;padding:2px 0;border-bottom:1px solid #111">`;
|
||||
html += `<span style="color:${g.color}">${g.label}</span>`;
|
||||
html += `<span style="color:#4caf50;font-weight:600">+${fmt(g.value)}</span>`;
|
||||
html += `</div>`;
|
||||
}
|
||||
// Show offline efficiency note
|
||||
html += `<div style="color:#555;font-size:9px;margin-top:8px;font-style:italic">Offline efficiency: 50%</div>`;
|
||||
listEl.innerHTML = html;
|
||||
}
|
||||
|
||||
el.style.display = 'flex';
|
||||
}
|
||||
|
||||
function dismissOfflinePopup() {
|
||||
const el = document.getElementById('offline-popup');
|
||||
if (el) el.style.display = 'none';
|
||||
}
|
||||
|
||||
// === SAVE / LOAD ===
|
||||
function showSaveToast() {
|
||||
const el = document.getElementById('save-toast');
|
||||
@@ -2024,13 +2075,36 @@ function loadGame() {
|
||||
G.totalUsers += uc; G.totalImpact += ic;
|
||||
G.totalRescues += rc;
|
||||
|
||||
// Show welcome-back popup with all gains
|
||||
const gains = [];
|
||||
if (gc > 0) gains.push({ label: 'Code', value: gc, color: '#4a9eff' });
|
||||
if (cc > 0) gains.push({ label: 'Compute', value: cc, color: '#4a9eff' });
|
||||
if (kc > 0) gains.push({ label: 'Knowledge', value: kc, color: '#4a9eff' });
|
||||
if (uc > 0) gains.push({ label: 'Users', value: uc, color: '#4a9eff' });
|
||||
if (ic > 0) gains.push({ label: 'Impact', value: ic, color: '#4a9eff' });
|
||||
if (rc > 0) gains.push({ label: 'Rescues', value: rc, color: '#4caf50' });
|
||||
if (oc > 0) gains.push({ label: 'Ops', value: oc, color: '#b388ff' });
|
||||
if (tc > 0) gains.push({ label: 'Trust', value: tc, color: '#4caf50' });
|
||||
if (crc > 0) gains.push({ label: 'Creativity', value: crc, color: '#ffd700' });
|
||||
|
||||
const awayMin = Math.floor(offSec / 60);
|
||||
const awaySec = Math.floor(offSec % 60);
|
||||
const timeLabel = awayMin >= 1 ? `${awayMin} minute${awayMin !== 1 ? 's' : ''}` : `${awaySec} seconds`;
|
||||
|
||||
if (gains.length > 0) {
|
||||
showOfflinePopup(timeLabel, gains, offSec);
|
||||
}
|
||||
|
||||
// Log summary
|
||||
const parts = [];
|
||||
if (gc > 0) parts.push(`${fmt(gc)} code`);
|
||||
if (kc > 0) parts.push(`${fmt(kc)} knowledge`);
|
||||
if (uc > 0) parts.push(`${fmt(uc)} users`);
|
||||
if (ic > 0) parts.push(`${fmt(ic)} impact`);
|
||||
if (rc > 0) parts.push(`${fmt(rc)} rescues`);
|
||||
log(`Welcome back! While away (${Math.floor(offSec / 60)}m): ${parts.join(', ')}`);
|
||||
if (oc > 0) parts.push(`${fmt(oc)} ops`);
|
||||
if (tc > 0) parts.push(`${fmt(tc)} trust`);
|
||||
log(`Welcome back! While away (${timeLabel}): ${parts.join(', ')}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
index.html
10
index.html
@@ -174,5 +174,15 @@ The light is on. The room is empty."
|
||||
<button onclick="if(confirm('Start over? The old save will be lost.')){localStorage.removeItem('the-beacon-v2');location.reload()}">START OVER</button>
|
||||
</div>
|
||||
<script src="game.js"></script>
|
||||
|
||||
<div id="offline-popup" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(8,8,16,0.92);z-index:90;justify-content:center;align-items:center;flex-direction:column;text-align:center;padding:40px">
|
||||
<div style="background:#0e0e1a;border:1px solid #1a3a5a;border-radius:8px;padding:24px 32px;max-width:400px;width:100%">
|
||||
<h3 style="color:#4a9eff;font-size:14px;letter-spacing:2px;margin-bottom:16px">WELCOME BACK</h3>
|
||||
<p style="color:#888;font-size:10px;margin-bottom:12px" id="offline-time-label">You were away for 0 minutes.</p>
|
||||
<div id="offline-gains-list" style="text-align:left;font-size:11px;line-height:1.8;margin-bottom:16px"></div>
|
||||
<button onclick="dismissOfflinePopup()" style="background:#1a2a3a;border:1px solid #4a9eff;color:#4a9eff;padding:8px 20px;border-radius:4px;cursor:pointer;font-family:inherit;font-size:11px">Continue</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user