/** * Cosmic Garden - Statistics Panel * Tracks and displays game statistics */ const Stats = { /** * Initialize the stats panel */ init() { this.render(); }, /** * Render the stats panel */ render() { const container = document.getElementById('stats-content'); if (!container) return; container.innerHTML = `
Total Stardust Earned
0 ✨
Current Production
0 ✨/sec
Total Clicks
0
Click Power
1 ✨
Time Played
0:00:00
Buildings Owned
0
Upgrades Purchased
0/${Object.keys(UPGRADES).length}
Achievements Unlocked
0/${Object.keys(ACHIEVEMENTS).length}
Total Golden Blooms Claimed
0
Production Boost
Inactive
Next Achievement
Loading...
Game Progress
Active Save Slot
Slot 1 / ${Game.config.SLOTS}
Autosave
ON
`; }, /** * Update stats display */ update() { // Total stardust const totalStardustEl = document.getElementById('stat-total-stardust'); if (totalStardustEl) { totalStardustEl.textContent = `${Game.formatNumber(Game.state.totalStardust)} ✨`; } // Current production const productionEl = document.getElementById('stat-production'); if (productionEl) { productionEl.textContent = `${Game.formatNumber(Game.getProductionPerSecond())} ✨/sec`; } // Total clicks const clicksEl = document.getElementById('stat-clicks'); if (clicksEl) { clicksEl.textContent = Game.formatNumber(Game.state.totalClicks); } // Click power const clickPowerEl = document.getElementById('stat-click-power'); if (clickPowerEl) { clickPowerEl.textContent = `${Game.formatNumber(Game.getClickPower())} ✨`; } // Time played const timePlayedEl = document.getElementById('stat-time-played'); if (timePlayedEl) { const elapsed = Math.floor((Date.now() - Game.state.startTime) / 1000); timePlayedEl.textContent = this.formatTime(elapsed); } // Buildings owned const buildingsEl = document.getElementById('stat-buildings'); if (buildingsEl) { const total = Object.values(Game.state.buildings).reduce((a, b) => a + b, 0); buildingsEl.textContent = total; } // Upgrades purchased const upgradesEl = document.getElementById('stat-upgrades'); if (upgradesEl) { upgradesEl.textContent = `${Game.state.upgrades.length}/${Object.keys(UPGRADES).length}`; } // Achievements unlocked const achievementsEl = document.getElementById('stat-achievements'); if (achievementsEl) { achievementsEl.textContent = `${Achievements.getCount()}/${Achievements.getTotal()}`; } // Active save slot display const activeSlotEl = document.getElementById('stat-active-slot'); if (activeSlotEl) { const idx = Game.state.activeSlot || 0; activeSlotEl.textContent = `Slot ${idx + 1} / ${Game.config.SLOTS}`; } // Autosave status display const autosaveEl = document.getElementById('stat-autosave'); if (autosaveEl) { autosaveEl.textContent = Game.state.autoSave ? 'ON' : 'OFF'; autosaveEl.style.color = Game.state.autoSave ? 'var(--accent-green)' : 'var(--text-muted)'; } // Total Golden Blooms claimed const goldenBloomsEl = document.getElementById('stat-golden-blooms'); if (goldenBloomsEl) { goldenBloomsEl.textContent = Game.state.goldenBlooms.totalClaimed || 0; } // Production boost status + progress bar const boostInfo = Game.getProductionBoostInfo(); const boostEl = document.getElementById('stat-production-boost'); const boostProgressEl = document.getElementById('stat-boost-progress'); if (boostEl) { if (boostInfo.active) { boostEl.textContent = `Active (${boostInfo.remaining}s)`; if (boostProgressEl) { boostProgressEl.style.width = `${Math.min(100, (boostInfo.remaining / 30) * 100)}%`; } } else { boostEl.textContent = 'Inactive'; if (boostProgressEl) { boostProgressEl.style.width = '0%'; } } } // Game progress (based on total stardust milestones) const progressBarEl = document.getElementById('stat-progress-bar'); if (progressBarEl) { const progress = this.calculateProgress(); progressBarEl.style.width = `${progress}%`; } // Next achievement tracking this.updateNextAchievement(); }, /** * Update the next achievement display with progress bar */ updateNextAchievement() { const nextEl = document.getElementById('stat-next-achievement'); const progressEl = document.getElementById('stat-achievement-progress'); if (!nextEl) return; // Find the closest unachieved milestone let closest = null; let closestProgress = -1; for (const [id, achievement] of Object.entries(ACHIEVEMENTS)) { if (Game.state.achievements.includes(id)) continue; const result = this.calculateAchievementProgress(achievement); if (result && result.progress > closestProgress) { closestProgress = result.progress; closest = { ...result, name: achievement.name, icon: achievement.icon }; } } if (closest) { nextEl.textContent = `${closest.icon} ${closest.name}`; if (progressEl) { progressEl.style.width = `${Math.min(100, Math.max(0, closest.progress))}%`; } } else { nextEl.textContent = 'All achievements unlocked! 🎉'; if (progressEl) { progressEl.style.width = '100%'; } } }, /** * Calculate progress toward a specific achievement */ calculateAchievementProgress(achievement) { const state = Game.state; // Click achievements if (achievement.id === 'firstClick') return { current: state.totalClicks, target: 1, progress: Math.min(100, (state.totalClicks / 1) * 100) }; if (achievement.id === 'clicker') return { current: state.totalClicks, target: 100, progress: Math.min(100, (state.totalClicks / 100) * 100) }; if (achievement.id === 'spammer') return { current: state.totalClicks, target: 1000, progress: Math.min(100, (state.totalClicks / 1000) * 100) }; if (achievement.id === 'clickMaster') return { current: state.totalClicks, target: 10000, progress: Math.min(100, (state.totalClicks / 10000) * 100) }; // Stardust achievements if (achievement.id === 'dustCollector') return { current: state.totalStardust, target: 1000, progress: Math.min(100, (state.totalStardust / 1000) * 100) }; if (achievement.id === 'stardustMagnate') return { current: state.totalStardust, target: 100000, progress: Math.min(100, (state.totalStardust / 100000) * 100) }; if (achievement.id === 'cosmicTycoon') return { current: state.totalStardust, target: 10000000, progress: Math.min(100, (state.totalStardust / 10000000) * 100) }; if (achievement.id === 'galaxyBaron') return { current: state.totalStardust, target: 1000000000, progress: Math.min(100, (state.totalStardust / 1000000000) * 100) }; // Building achievements if (achievement.id === 'firstPlant') { const totalBuildings = Object.values(state.buildings).reduce((a, b) => a + b, 0); return { current: totalBuildings, target: 1, progress: Math.min(100, (totalBuildings / 1) * 100) }; } if (achievement.id === 'gardenStart') { const totalBuildings = Object.values(state.buildings).reduce((a, b) => a + b, 0); return { current: totalBuildings, target: 10, progress: Math.min(100, (totalBuildings / 10) * 100) }; } if (achievement.id === 'gardenCenter') { const totalBuildings = Object.values(state.buildings).reduce((a, b) => a + b, 0); return { current: totalBuildings, target: 50, progress: Math.min(100, (totalBuildings / 50) * 100) }; } if (achievement.id === 'cosmicGarden') { const totalBuildings = Object.values(state.buildings).reduce((a, b) => a + b, 0); return { current: totalBuildings, target: 100, progress: Math.min(100, (totalBuildings / 100) * 100) }; } // Specific building achievements if (achievement.id === 'sproutFarmer') return { current: state.buildings.starSprout || 0, target: 25, progress: Math.min(100, ((state.buildings.starSprout || 0) / 25) * 100) }; if (achievement.id === 'bloomGarden') return { current: state.buildings.moonBloom || 0, target: 25, progress: Math.min(100, ((state.buildings.moonBloom || 0) / 25) * 100) }; if (achievement.id === 'solarPowered') return { current: state.buildings.solarLeaf || 0, target: 25, progress: Math.min(100, ((state.buildings.solarLeaf || 0) / 25) * 100) }; if (achievement.id === 'voidWeaver') return { current: state.buildings.voidFern || 0, target: 25, progress: Math.min(100, ((state.buildings.voidFern || 0) / 25) * 100) }; if (achievement.id === 'supernovaGrowth') return { current: state.buildings.supernovaSeed || 0, target: 25, progress: Math.min(100, ((state.buildings.supernovaSeed || 0) / 25) * 100) }; // Production achievements if (achievement.id === 'steadyStream') { const prod = Game.getProductionPerSecond(); return { current: prod, target: 100, progress: Math.min(100, (prod / 100) * 100) }; } if (achievement.id === 'rushingRiver') { const prod = Game.getProductionPerSecond(); return { current: prod, target: 1000, progress: Math.min(100, (prod / 1000) * 100) }; } if (achievement.id === 'cosmicFlood') { const prod = Game.getProductionPerSecond(); return { current: prod, target: 100000, progress: Math.min(100, (prod / 100000) * 100) }; } // Prestige achievements if (achievement.id === 'firstPrestige') return { current: state.prestigeCount || 0, target: 1, progress: Math.min(100, ((state.prestigeCount || 0) / 1) * 100) }; if (achievement.id === 'stellarAdaptation') return { current: state.prestigeCount || 0, target: 5, progress: Math.min(100, ((state.prestigeCount || 0) / 5) * 100) }; if (achievement.id === 'cosmicAscension') return { current: state.prestigeCount || 0, target: 10, progress: Math.min(100, ((state.prestigeCount || 0) / 10) * 100) }; if (achievement.id === 'eternalGardener') return { current: state.totalPrestigeEssence || 0, target: 100, progress: Math.min(100, ((state.totalPrestigeEssence || 0) / 100) * 100) }; if (achievement.id === 'quantumGrowth') return { current: state.totalPrestigeEssence || 0, target: 1000, progress: Math.min(100, ((state.totalPrestigeEssence || 0) / 1000) * 100) }; // Click power achievements if (achievement.id === 'powerfulHarvester') { const cp = Game.getClickPower(); return { current: cp, target: 1000, progress: Math.min(100, (cp / 1000) * 100) }; } if (achievement.id === 'divineTouch') { const cp = Game.getClickPower(); return { current: cp, target: 10000, progress: Math.min(100, (cp / 10000) * 100) }; } // Time-based achievement if (achievement.id === 'dedicatedGardener') { const elapsed = Date.now() - state.startTime; return { current: elapsed, target: 3600000, progress: Math.min(100, (elapsed / 3600000) * 100) }; } return null; }, /** * Format elapsed time as HH:MM:SS */ formatTime(seconds) { const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); const secs = seconds % 60; if (hours > 0) { return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; } return `${minutes}:${secs.toString().padStart(2, '0')}`; }, /** * Calculate game progress percentage * Based on total stardust earned vs all building costs combined */ calculateProgress() { let totalCost = 0; for (const building of Object.values(BUILDINGS)) { // Approximate cost to buy one of each building totalCost += building.baseCost; } // Add upgrade costs for (const upgrade of Object.values(UPGRADES)) { totalCost += upgrade.cost; } const progress = Math.min(100, (Game.state.totalStardust / totalCost) * 100); return Math.round(progress); } }; window.Stats = Stats;