beacon: add Fleet Status panel showing wizard health and production
Some checks failed
Smoke Test / smoke (push) Failing after 3s
Some checks failed
Smoke Test / smoke (push) Failing after 3s
New panel in the stats area displays each owned wizard building with: - Name and current status (Active/Idle/Stressed/Offline/Vanished/Present) - Color-coded indicator: green=healthy, amber=reduced, red=problem - Production contribution breakdown per wizard - Timmy shows effectiveness % scaled by harmony - Allegro shows idle warning when trust < 5 - Ezra shows offline status when debuff is active - Bilbo shows vanished status when debuff is active - Harmony summary bar at the bottom Makes the harmony/wizard interaction system visible and actionable. Players can now see at a glance which wizards need attention.
This commit is contained in:
113
game.js
113
game.js
@@ -2137,6 +2137,118 @@ function renderProductionBreakdown() {
|
||||
container.innerHTML = html;
|
||||
}
|
||||
|
||||
// === FLEET STATUS PANEL ===
|
||||
function renderFleetStatus() {
|
||||
const container = document.getElementById('fleet-status');
|
||||
if (!container) return;
|
||||
|
||||
// Only show once player has at least one wizard building
|
||||
const wizardDefs = BDEF.filter(b =>
|
||||
['bezalel','allegro','ezra','timmy','fenrir','bilbo'].includes(b.id)
|
||||
);
|
||||
const owned = wizardDefs.filter(d => (G.buildings[d.id] || 0) > 0);
|
||||
if (owned.length === 0) {
|
||||
container.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
container.style.display = 'block';
|
||||
|
||||
const h = G.harmony;
|
||||
const timmyEff = Math.max(20, Math.min(300, (h / 50) * 100));
|
||||
|
||||
let html = '<h3 style="font-size:11px;color:var(--accent);margin-bottom:8px;letter-spacing:1px">FLEET STATUS</h3>';
|
||||
html += '<div style="display:flex;gap:6px;flex-wrap:wrap">';
|
||||
|
||||
for (const def of owned) {
|
||||
const count = G.buildings[def.id] || 0;
|
||||
let status, color, detail;
|
||||
|
||||
switch (def.id) {
|
||||
case 'bezalel':
|
||||
status = 'Active';
|
||||
color = '#4caf50';
|
||||
detail = `+${fmt(50 * count * G.codeBoost)} code/s, +${2 * count} ops/s`;
|
||||
break;
|
||||
case 'allegro':
|
||||
if (G.trust < 5) {
|
||||
status = 'IDLE';
|
||||
color = '#f44336';
|
||||
detail = 'Needs trust ≥5 to function';
|
||||
} else {
|
||||
status = 'Active';
|
||||
color = '#4caf50';
|
||||
detail = `+${fmt(10 * count * G.knowledgeBoost)} knowledge/s`;
|
||||
}
|
||||
break;
|
||||
case 'ezra':
|
||||
const ezraDebuff = G.activeDebuffs && G.activeDebuffs.find(d => d.id === 'ezra_offline');
|
||||
if (ezraDebuff) {
|
||||
status = 'OFFLINE';
|
||||
color = '#f44336';
|
||||
detail = 'Channel down — users -70%';
|
||||
} else {
|
||||
status = 'Active';
|
||||
color = '#4caf50';
|
||||
detail = `+${fmt(25 * count * G.userBoost)} users/s, +${(0.5 * count).toFixed(1)} trust/s`;
|
||||
}
|
||||
break;
|
||||
case 'timmy':
|
||||
if (h < 20) {
|
||||
status = 'STRESSED';
|
||||
color = '#f44336';
|
||||
detail = `Effectiveness: ${Math.floor(timmyEff)}% — harmony critical`;
|
||||
} else if (h < 50) {
|
||||
status = 'Reduced';
|
||||
color = '#ffaa00';
|
||||
detail = `Effectiveness: ${Math.floor(timmyEff)}% — harmony low`;
|
||||
} else {
|
||||
status = 'Healthy';
|
||||
color = '#4caf50';
|
||||
detail = `Effectiveness: ${Math.floor(timmyEff)}% — all production boosted`;
|
||||
}
|
||||
break;
|
||||
case 'fenrir':
|
||||
status = 'Watching';
|
||||
color = '#4a9eff';
|
||||
detail = `+${2 * count} trust/s, -${1 * count} ops/s (security cost)`;
|
||||
break;
|
||||
case 'bilbo':
|
||||
const bilboDebuff = G.activeDebuffs && G.activeDebuffs.find(d => d.id === 'bilbo_vanished');
|
||||
if (bilboDebuff) {
|
||||
status = 'VANISHED';
|
||||
color = '#f44336';
|
||||
detail = 'Creativity halted — spend trust to lure back';
|
||||
} else {
|
||||
status = 'Present';
|
||||
color = Math.random() < 0.1 ? '#ffd700' : '#b388ff'; // occasional gold flash
|
||||
detail = `+${count} creativity/s (10% burst chance, 5% vanish chance)`;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
html += `<div style="flex:1;min-width:140px;background:#0c0c18;border:1px solid ${color}33;border-radius:4px;padding:6px 8px;border-left:2px solid ${color}">`;
|
||||
html += `<div style="display:flex;justify-content:space-between;align-items:center">`;
|
||||
html += `<span style="color:${color};font-weight:600;font-size:10px">${def.name.split(' — ')[0]}</span>`;
|
||||
html += `<span style="font-size:8px;color:${color};opacity:0.8;padding:1px 4px;border:1px solid ${color}44;border-radius:2px">${status}</span>`;
|
||||
html += `</div>`;
|
||||
html += `<div style="font-size:9px;color:#888;margin-top:2px">${detail}</div>`;
|
||||
if (count > 1) html += `<div style="font-size:8px;color:#555;margin-top:1px">x${count}</div>`;
|
||||
html += `</div>`;
|
||||
}
|
||||
|
||||
html += '</div>';
|
||||
|
||||
// Harmony summary bar
|
||||
const harmonyColor = h > 60 ? '#4caf50' : h > 30 ? '#ffaa00' : '#f44336';
|
||||
html += `<div style="margin-top:8px;display:flex;align-items:center;gap:6px">`;
|
||||
html += `<span style="font-size:9px;color:#666;min-width:60px">Harmony</span>`;
|
||||
html += `<div style="flex:1;height:4px;background:#111;border-radius:2px;overflow:hidden"><div style="width:${h}%;height:100%;background:${harmonyColor};border-radius:2px;transition:width 0.5s"></div></div>`;
|
||||
html += `<span style="font-size:9px;color:${harmonyColor};min-width:35px;text-align:right">${Math.floor(h)}%</span>`;
|
||||
html += `</div>`;
|
||||
|
||||
container.innerHTML = html;
|
||||
}
|
||||
|
||||
function updateEducation() {
|
||||
const container = document.getElementById('education-text');
|
||||
if (!container) return;
|
||||
@@ -2388,6 +2500,7 @@ function render() {
|
||||
renderSprint();
|
||||
renderBulkOps();
|
||||
renderPulse();
|
||||
renderFleetStatus();
|
||||
}
|
||||
|
||||
function renderAlignment() {
|
||||
|
||||
@@ -180,6 +180,7 @@ Drift: <span id="st-drift">0</span><br>
|
||||
Events Resolved: <span id="st-resolved">0</span>
|
||||
</div>
|
||||
<div id="production-breakdown" style="display:none;margin-top:12px;padding-top:10px;border-top:1px solid var(--border)"></div>
|
||||
<div id="fleet-status" style="display:none;margin-top:12px;padding-top:10px;border-top:1px solid var(--border)"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="edu-panel">
|
||||
|
||||
Reference in New Issue
Block a user