// ===== Admin Mode Setup ===== // Admin mode flags window.isAdminMode = true; window.adminPlayerId = 'admin_dev'; // Create complete UI replacement window.UI = { elements: {}, init: function() { console.log('Admin: Using stub UI'); }, setUpgradeHandlers: function(handlers) { // Store handlers for admin to call window.adminUpgradeHandlers = handlers; }, update: function(state, config) { // Update admin info display if it exists if (document.getElementById('admin-mass')) { updateAdminInfo(); } }, formatMass: function(mass, options) { if (options && options.forceSolarMass) { var solarMasses = mass / CONFIG.SOLAR_MASS_KG; return solarMasses.toFixed(3) + ' M☉'; } if (mass >= 1e18) return (mass / 1e18).toFixed(2) + ' Et'; if (mass >= 1e15) return (mass / 1e15).toFixed(2) + ' Pt'; if (mass >= 1e12) return (mass / 1e12).toFixed(2) + ' Tt'; if (mass >= 1e9) return (mass / 1e9).toFixed(2) + ' Gt'; if (mass >= 1e6) return (mass / 1e6).toFixed(2) + ' Mt'; if (mass >= 1e3) return (mass / 1e3).toFixed(2) + ' tonnes'; return mass.toFixed(0) + ' kg'; }, updateMassDisplay: function() {}, updateUpgradeDisplay: function() {}, updateTotalLevel: function() {}, formatTime: function(ms) { var seconds = Math.floor(ms / 1000); var minutes = Math.floor(seconds / 60); var hours = Math.floor(minutes / 60); var days = Math.floor(hours / 24); if (days > 0) return days + 'd ' + (hours % 24) + 'h'; if (hours > 0) return hours + 'h ' + (minutes % 60) + 'm'; if (minutes > 0) return minutes + 'm'; return seconds + 's'; }, formatAge: function(ms) { var days = Math.floor(ms / (24 * 60 * 60 * 1000)); var hours = Math.floor((ms % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000)); if (days > 0) return days + 'd ' + hours + 'h old'; if (hours > 0) return hours + 'h old'; return 'New'; } }; window.UI.updateActiveObjects = function() { if (window.gameAsteroids) { var el = document.getElementById('admin-objects'); if (el) el.textContent = window.gameAsteroids.length; } }; // ===== Wait for game to load ===== window.addEventListener('load', function() { // Override Server.init if (window.Server) { var originalInit = Server.init; Server.init = function() { this.playerId = window.adminPlayerId; Storage.setCookie('playerId', this.playerId, 365); console.log('Admin mode: Player ID =', this.playerId); } // Override checkpoint to do nothing Server.checkpoint = function() { console.log('Admin: Checkpoint skipped'); return Promise.resolve({ success: true }); }; } // Toggle admin panel var toggleBtn = document.getElementById('admin-toggle'); if (toggleBtn) { toggleBtn.addEventListener('click', function() { var panel = document.getElementById('admin-panel'); panel.classList.toggle('collapsed'); this.textContent = panel.classList.contains('collapsed') ? '▲' : '▼'; }); } console.log('%c[ADMIN MODE ENABLED]', 'color: #64c8ff; font-weight: bold; font-size: 14px;'); }); // ===== Admin Functions ===== // Spawn objects function adminSpawn(type) { if (!window.Game || !Game.getState) { console.error('Game not initialized'); return; } var canvas = document.getElementById('space'); var blackHole = window.gameBlackHole; if (!blackHole) { console.error('Black hole not available'); return; } window.gameAsteroids.push(new Asteroid(type, blackHole, canvas)); console.log('Spawned:', type); } // Set upgrade levels function adminSetLevel(upgradeType) { if (!window.Game || !Game.getState) return; var state = Game.getState(); var inputId = 'admin-' + upgradeType + '-level'; var input = document.getElementById(inputId); if (!input) return; var level = parseInt(input.value) || 0; switch(upgradeType) { case 'asteroid': state.asteroidUpgradeLevel = level; state.asteroidUpgradeCost = Math.floor( CONFIG.ASTEROID_BASE_COST * Math.pow(CONFIG.UPGRADE_COST_MULTIPLIER_ASTER, level) ); if (level >= 25) state.cometUnlocked = true; break; case 'comet': state.cometUpgradeLevel = level; state.cometUpgradeCost = Math.floor( CONFIG.COMET_BASE_COST * Math.pow(CONFIG.UPGRADE_COST_MULTIPLIER, level) ); if (level >= 20) state.planetUnlocked = true; break; case 'planet': state.planetUpgradeLevel = level; state.planetUpgradeCost = Math.floor( CONFIG.PLANET_BASE_COST * Math.pow(CONFIG.UPGRADE_COST_MULTIPLIER, level) ); if (level >= 15) state.giantUnlocked = true; break; case 'giant': state.giantUpgradeLevel = level; state.giantUpgradeCost = Math.floor( CONFIG.GIANT_BASE_COST * Math.pow(CONFIG.UPGRADE_COST_MULTIPLIER, level) ); break; } UI.update(state, CONFIG); console.log('Set', upgradeType, 'level to:', level); } // Add mass function adminAddMass(amount) { if (!window.Game || !Game.getState) return; var state = Game.getState(); if (!amount) { var input = document.getElementById('admin-mass-input'); amount = input ? (parseFloat(input.value) || 0) : 0; } state.blackHoleTotalMass += amount; state.totalMassConsumedEver += amount; state.totalMassConsumed += amount; // Update black hole size var solarMasses = state.blackHoleTotalMass / CONFIG.SOLAR_MASS_KG; if (window.gameBlackHole) { window.gameBlackHole.radius = CONFIG.INITIAL_BLACK_HOLE_RADIUS + (solarMasses - CONFIG.INITIAL_BLACK_HOLE_MASS); } UI.update(state, CONFIG); console.log('Added mass:', UI.formatMass(amount)); } // Toggle unlocks function adminToggleUnlock(type) { if (!window.Game || !Game.getState) return; var state = Game.getState(); switch(type) { case 'comet': state.cometUnlocked = !state.cometUnlocked; break; case 'planet': state.planetUnlocked = !state.planetUnlocked; break; case 'giant': state.giantUnlocked = !state.giantUnlocked; break; } UI.update(state, CONFIG); console.log(type + ' unlocked:', state[type + 'Unlocked']); } // Game state management function adminSaveGame() { if (!window.Game || !Game.getState || !window.Server) return; Server.checkpoint(Game.getState()); console.log('Game saved'); showSuccessNotification('Game saved'); } function adminLoadGame() { location.reload(); } function adminResetGame() { if (confirm('Reset game state? This will delete all progress.')) { Storage.resetGame(); } } function adminExportState() { if (!window.Game || !Game.getState) return; var state = Game.getState(); var json = JSON.stringify(state, null, 2); var blob = new Blob([json], { type: 'application/json' }); var url = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = 'game-state-' + Date.now() + '.json'; a.click(); URL.revokeObjectURL(url); console.log('Exported game state'); } function adminImportState() { var input = document.createElement('input'); input.type = 'file'; input.accept = 'application/json'; input.onchange = function(e) { var file = e.target.files[0]; if (!file) return; var reader = new FileReader(); reader.onload = function(event) { try { var importedState = JSON.parse(event.target.result); var currentState = Game.getState(); for (var key in importedState) { currentState[key] = importedState[key]; } UI.update(currentState, CONFIG); console.log('Imported game state'); showSuccessNotification('State imported'); } catch (err) { console.error('Failed to import:', err); showErrorNotification('Invalid JSON file'); } }; reader.readAsText(file); }; input.click(); } // Update admin info display function updateAdminInfo() { if (!window.Game || !Game.getState) return; var state = Game.getState(); var el = document.getElementById('admin-player-id'); if (el && window.Server) el.textContent = Server.playerId; el = document.getElementById('admin-mass'); if (el) el.textContent = UI.formatMass(state.blackHoleTotalMass, {forceSolarMass: true}); el = document.getElementById('admin-total-level'); if (el) { el.textContent = state.asteroidUpgradeLevel + state.cometUpgradeLevel + state.planetUpgradeLevel + state.giantUpgradeLevel; } el = document.getElementById('admin-asteroids'); if (el) el.textContent = state.asteroidSpawnCount; el = document.getElementById('admin-objects'); if (el) el.textContent = window.gameAsteroids ? window.gameAsteroids.length : 0; } // Update info every second setInterval(updateAdminInfo, 1000); setTimeout(updateAdminInfo, 500);