206 lines
7.5 KiB
JavaScript
206 lines
7.5 KiB
JavaScript
/**
|
|
* Cosmic Garden - Prestige UI Manager
|
|
* Handles all prestige-related UI rendering and interactions
|
|
*/
|
|
|
|
const PrestigeUI = {
|
|
/**
|
|
* Initialize the prestige UI
|
|
*/
|
|
init() {
|
|
this.renderPrestigeUpgrades();
|
|
this.setupEventListeners();
|
|
this.update();
|
|
},
|
|
|
|
/**
|
|
* Setup event listeners
|
|
*/
|
|
setupEventListeners() {
|
|
// Prestige button
|
|
document.getElementById('prestige-btn')?.addEventListener('click', () => {
|
|
const essenceGain = PRESTIGE.calculateEssence();
|
|
|
|
if (essenceGain > 0) {
|
|
if (confirm(
|
|
`Prestige now to earn ${essenceGain} Stellar Essence?\n\n` +
|
|
`You will keep your prestige upgrades and essence.\n` +
|
|
`All buildings, upgrades, and stardust will be reset.`
|
|
)) {
|
|
PRESTIGE.prestige();
|
|
}
|
|
} else {
|
|
UI.showNotification('Need more stardust to prestige!', 'warning');
|
|
}
|
|
});
|
|
|
|
// Tab switching for prestige tab
|
|
document.querySelectorAll('.tab-btn').forEach(btn => {
|
|
btn.addEventListener('click', (e) => {
|
|
const tab = e.target.dataset.tab;
|
|
if (tab === 'prestige') {
|
|
this.renderPrestigeUpgrades();
|
|
}
|
|
});
|
|
});
|
|
|
|
// Buy Max prestige upgrades button - buy every affordable prestige
|
|
// upgrade at once, paid from Stellar Essence.
|
|
const buyMaxBtn = document.getElementById('buy-all-prestige');
|
|
if (buyMaxBtn) {
|
|
buyMaxBtn.addEventListener('click', () => {
|
|
Game.buyMaxPrestigeUpgrades();
|
|
});
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Render prestige upgrade cards
|
|
*/
|
|
renderPrestigeUpgrades() {
|
|
const container = document.getElementById('prestige-upgrades-list');
|
|
if (!container) return;
|
|
|
|
container.innerHTML = '';
|
|
|
|
for (const [id, upgrade] of Object.entries(PRESTIGE_UPGRADES)) {
|
|
const card = document.createElement('div');
|
|
card.className = 'prestige-upgrade-card';
|
|
card.id = `prestige-upgrade-${id}`;
|
|
|
|
const purchased = Game.state.prestigeUpgrades?.includes(id);
|
|
const canAfford = (Game.state.stellarEssence || 0) >= upgrade.cost;
|
|
|
|
card.classList.toggle('purchased', purchased);
|
|
card.classList.toggle('locked', !purchased && !canAfford);
|
|
|
|
card.innerHTML = `
|
|
<div class=\"prestige-upgrade-name\">${upgrade.icon} ${upgrade.name}</div>
|
|
<div class=\"prestige-upgrade-desc\">${upgrade.description}</div>
|
|
<div class=\"prestige-upgrade-cost\">${purchased ? '✓ Owned' : `${upgrade.cost} ✦`}</div>
|
|
`;
|
|
|
|
if (!purchased && canAfford) {
|
|
card.addEventListener('click', () => {
|
|
PRESTIGE.buyUpgrade(id);
|
|
});
|
|
}
|
|
|
|
container.appendChild(card);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Update prestige display
|
|
*/
|
|
update() {
|
|
// Essence count
|
|
const essenceEl = document.getElementById('prestige-essence-count');
|
|
if (essenceEl) {
|
|
essenceEl.textContent = Game.state.stellarEssence || 0;
|
|
}
|
|
|
|
// Multiplier display
|
|
const multiplierEl = document.getElementById('prestige-multiplier');
|
|
if (multiplierEl) {
|
|
const multiplier = PRESTIGE.getMultiplier();
|
|
const percent = Math.round((multiplier - 1) * 100);
|
|
multiplierEl.textContent = `+${percent}%`;
|
|
}
|
|
|
|
// Next prestige essence
|
|
const nextEl = document.getElementById('prestige-next-essence');
|
|
if (nextEl) {
|
|
const nextEssence = PRESTIGE.calculateEssence();
|
|
nextEl.textContent = nextEssence;
|
|
}
|
|
|
|
// Prestige progress bar: how far total stardust is toward the next
|
|
// Stellar Essence level. essence(e) = floor(sqrt(totalStardust/1e6)),
|
|
// so tier e needs e^2*1M stardust and tier (e+1) needs (e+1)^2*1M.
|
|
this.updatePrestigeProgress();
|
|
|
|
// Update prestige button state
|
|
const prestigeBtn = document.getElementById('prestige-btn');
|
|
if (prestigeBtn) {
|
|
const canPrestige = PRESTIGE.calculateEssence() > 0;
|
|
prestigeBtn.disabled = !canPrestige;
|
|
prestigeBtn.classList.toggle('can-prestige', canPrestige);
|
|
}
|
|
|
|
// Update prestige upgrades list if visible
|
|
const prestigeTab = document.getElementById('prestige-tab');
|
|
if (prestigeTab?.classList.contains('active')) {
|
|
this.renderPrestigeUpgrades();
|
|
}
|
|
|
|
// Show/hide the "Buy Max" button based on whether any unowned prestige
|
|
// upgrade is currently affordable with Stellar Essence. Read-only.
|
|
this.updateBuyMaxPrestigeButton();
|
|
},
|
|
|
|
/**
|
|
* Update the prestige progress bar showing how close total stardust is to
|
|
* earning the next Stellar Essence. essence level e = floor(sqrt(totalStardust/1e6)),
|
|
* so tier e begins at e^2*1M and tier (e+1) begins at (e+1)^2*1M; the bar
|
|
* fills linearly across that tier's stardust range and resets to 0% exactly
|
|
* when a new essence level is reached. Read-only: mutates only DOM.
|
|
*/
|
|
updatePrestigeProgress() {
|
|
const totalStardust = Game.state.totalStardust || 0;
|
|
const e = Math.floor(Math.sqrt(totalStardust / 1e6));
|
|
const tierFloor = e * e * 1e6;
|
|
const tierCeil = (e + 1) * (e + 1) * 1e6;
|
|
const progress = Math.min(1, Math.max(0, (totalStardust - tierFloor) / (tierCeil - tierFloor)));
|
|
|
|
const fillEl = document.getElementById('prestige-progress-fill');
|
|
if (fillEl) {
|
|
const pct = Math.round(progress * 100);
|
|
fillEl.style.width = `${pct}%`;
|
|
// Only apply the pulsing glow while there is progress to show, so a
|
|
// freshly-emptied bar (e.g. right after prestige) sits still.
|
|
fillEl.classList.toggle('filling', pct > 0 && pct < 100);
|
|
}
|
|
|
|
const pctLabel = document.getElementById('prestige-progress-pct');
|
|
if (pctLabel) {
|
|
pctLabel.textContent = `${Math.round(progress * 100)}%`;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Show/hide and enable/disable the "Buy Max" prestige-upgrades button
|
|
* depending on whether at least one unowned, requirement-met prestige
|
|
* upgrade is currently affordable with Stellar Essence. Read of game state
|
|
* only; never mutates it. Mirrors Game.buyMaxPrestigeUpgrades /
|
|
* PRESTIGE.buyUpgrade semantics.
|
|
*/
|
|
updateBuyMaxPrestigeButton() {
|
|
const btn = document.getElementById('buy-all-prestige');
|
|
if (!btn) return;
|
|
|
|
let affordableAny = false;
|
|
for (const [id, upgrade] of Object.entries(PRESTIGE_UPGRADES)) {
|
|
if ((Game.state.prestigeUpgrades || []).includes(id)) continue;
|
|
if ((Game.state.stellarEssence || 0) < upgrade.cost) continue;
|
|
if (upgrade.requirements) {
|
|
let met = true;
|
|
for (const [reqId, reqCount] of Object.entries(upgrade.requirements)) {
|
|
if ((Game.state.buildings[reqId] || 0) < reqCount) {
|
|
met = false;
|
|
break;
|
|
}
|
|
}
|
|
if (!met) continue;
|
|
}
|
|
affordableAny = true;
|
|
break;
|
|
}
|
|
|
|
btn.style.display = affordableAny ? '' : 'none';
|
|
btn.disabled = !affordableAny;
|
|
},
|
|
};
|
|
|
|
window.PrestigeUI = PrestigeUI;
|