/** * Galaxy Strike Online - Base System * Manages player base building and customization */ class BaseSystem { constructor(gameEngine) { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.startStep('BaseSystem.constructor', { gameEngineProvided: !!gameEngine }); this.game = gameEngine; // Base configuration this.base = { name: 'Command Center Alpha', level: 1, experience: 0, experienceToNext: 500, rooms: [], decorations: [], power: 100, maxPower: 100, storage: 1000, maxStorage: 1000 }; if (debugLogger) debugLogger.logStep('Base configuration initialized', { baseName: this.base.name, baseLevel: this.base.level, initialPower: this.base.power, maxPower: this.base.maxPower, initialStorage: this.base.storage, maxStorage: this.base.maxStorage }); // Room types this.roomTypes = { command_center: { name: 'Command Center', description: 'Central control room for your operations', size: 'large', powerCost: 20, storageBonus: 0, buildCost: 0, requiredLevel: 1, maxLevel: 1, icon: 'fa-satellite-dish' }, barracks: { name: 'Barracks', description: 'Housing for crew and allies', size: 'medium', powerCost: 10, storageBonus: 100, buildCost: 500, requiredLevel: 2, maxLevel: 5, icon: 'fa-home' }, laboratory: { name: 'Laboratory', description: 'Research facility for new technologies', size: 'medium', powerCost: 15, storageBonus: 50, buildCost: 1000, requiredLevel: 3, maxLevel: 5, icon: 'fa-flask' }, workshop: { name: 'Workshop', description: 'Crafting and equipment modification station', size: 'medium', powerCost: 12, storageBonus: 80, buildCost: 800, requiredLevel: 2, maxLevel: 5, icon: 'fa-hammer' }, storage_bay: { name: 'Storage Bay', description: 'Additional storage for resources and items', size: 'large', powerCost: 5, storageBonus: 500, buildCost: 300, requiredLevel: 1, maxLevel: 10, icon: 'fa-warehouse' }, power_generator: { name: 'Power Generator', description: 'Generates power for base operations', size: 'small', powerCost: -25, storageBonus: 0, buildCost: 600, requiredLevel: 2, maxLevel: 5, icon: 'fa-bolt' }, defense_turret: { name: 'Defense Turret', description: 'Automated defense system', size: 'small', powerCost: 8, storageBonus: 0, buildCost: 400, requiredLevel: 3, maxLevel: 8, icon: 'fa-crosshairs' }, communication_array: { name: 'Communication Array', description: 'Long-range communication and scanning', size: 'medium', powerCost: 10, storageBonus: 20, buildCost: 700, requiredLevel: 4, maxLevel: 3, icon: 'fa-broadcast-tower' }, medical_bay: { name: 'Medical Bay', description: 'Health restoration and crew recovery', size: 'medium', powerCost: 12, storageBonus: 30, buildCost: 900, requiredLevel: 3, maxLevel: 4, icon: 'fa-medkit' }, recreation_room: { name: 'Recreation Room', description: 'Crew morale and relaxation facilities', size: 'small', powerCost: 6, storageBonus: 10, buildCost: 350, requiredLevel: 2, maxLevel: 3, icon: 'fa-gamepad' } }; // Base upgrades this.upgrades = { power_efficiency: { name: 'Power Efficiency', description: 'Reduces power consumption of all rooms', cost: 1000, effect: { powerReduction: 0.1 }, maxLevel: 5, currentLevel: 0 }, storage_expansion: { name: 'Storage Expansion', description: 'Increases inventory slots for item storage', cost: 5000, maxLevel: 10, currentLevel: 0, icon: 'fa-boxes', slotBonus: 5 // +5 slots per level }, automation_systems: { name: 'Automation Systems', description: 'Automated resource collection and processing', cost: 1500, effect: { productionBonus: 0.2 // +20% production }, maxLevel: 5, currentLevel: 0 }, advanced_defenses: { name: 'Advanced Defenses', description: 'Improved base defense systems', cost: 2000, effect: { defenseBonus: 10 }, maxLevel: 3, currentLevel: 0 } }; // Base grid layout (10x10) this.gridSize = 10; this.grid = []; if (debugLogger) debugLogger.logStep('Grid configuration initialized', { gridSize: this.gridSize, gridInitialized: false }); // Initialize grid this.initializeGrid(); if (debugLogger) debugLogger.endStep('BaseSystem.constructor', { roomTypesCount: Object.keys(this.roomTypes).length, upgradesCount: Object.keys(this.upgrades).length, gridSize: this.gridSize, gridInitialized: !!this.grid, baseConfiguration: this.base }); } initializeBaseData() { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.startStep('BaseSystem.initializeBaseData', { oldBaseName: this.base.name, oldBaseLevel: this.base.level }); // Initialize base with default values this.base = { name: 'Command Center Alpha', level: 1, experience: 0, experienceToNext: 500, rooms: [], decorations: [], power: 100, maxPower: 100, storage: 1000, maxStorage: 1000 }; // Initialize resources this.resources = { energy: 100, materials: 50, research: 0 }; if (debugLogger) debugLogger.endStep('BaseSystem.initializeBaseData', { newBaseName: this.base.name, newBaseLevel: this.base.level, roomsCount: this.base.rooms.length, decorationsCount: this.base.decorations.length, resourcesInitialized: this.resources }); } initialize() { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.startStep('BaseSystem.initialize', { currentBaseLevel: this.base.level, roomsCount: this.base.rooms.length }); // Initialize base data if (debugLogger) debugLogger.logStep('Initializing base data'); this.initializeBaseData(); // Initialize inventory bonus slots on game start if (debugLogger) debugLogger.logStep('Updating inventory bonus slots'); this.updateInventoryBonusSlots(); if (debugLogger) debugLogger.endStep('BaseSystem.initialize', { baseDataInitialized: true, inventoryBonusSlotsUpdated: true }); } async initialize() { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.startStep('BaseSystem.asyncInitialize', { currentBaseLevel: this.base.level, roomsCount: this.base.rooms.length }); // Start with command center if (debugLogger) debugLogger.logStep('Adding command center room'); this.addRoom('command_center', 5, 5); // Set up base navigation if (debugLogger) debugLogger.logStep('Setting up base navigation'); this.setupBaseNavigation(); // Initialize ship gallery if (debugLogger) debugLogger.logStep('Initializing ship gallery'); this.initializeShipGallery(); // Initialize starbase system if (debugLogger) debugLogger.logStep('Initializing starbase system'); this.initializeStarbaseSystem(); if (debugLogger) debugLogger.endStep('BaseSystem.asyncInitialize', { commandCenterAdded: true, navigationSetup: true, shipGalleryInitialized: true, starbaseSystemInitialized: true }); } initializeGrid() { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.startStep('BaseSystem.initializeGrid', { gridSize: this.gridSize }); this.grid = []; for (let y = 0; y < this.gridSize; y++) { this.grid[y] = []; for (let x = 0; x < this.gridSize; x++) { this.grid[y][x] = null; } } if (debugLogger) debugLogger.endStep('BaseSystem.initializeGrid', { gridSize: this.gridSize, gridCreated: true, totalCells: this.gridSize * this.gridSize }); } // Room management getRoomAt(x, y) { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.log('BaseSystem.getRoomAt called', { x: x, y: y, gridSize: this.gridSize }); // Check if coordinates are within grid bounds if (x < 0 || x >= this.gridSize || y < 0 || y >= this.gridSize) { if (debugLogger) debugLogger.log('Coordinates out of bounds', { x: x, y: y, gridSize: this.gridSize }); return null; } // Ensure grid exists if (!this.grid || !this.grid[y]) { console.log('[BASE SYSTEM] Grid not properly initialized in getRoomAt'); if (debugLogger) debugLogger.log('Grid not properly initialized', { gridExists: !!this.grid, gridRowExists: !!(this.grid && this.grid[y]), y: y }); return null; } // Get room ID from grid const roomId = this.grid[y][x]; if (!roomId) { if (debugLogger) debugLogger.log('No room at coordinates', { x: x, y: y, roomId: roomId }); return null; } // Find room by ID const room = this.base.rooms.find(r => r.id === roomId) || null; if (debugLogger) debugLogger.log('Room found at coordinates', { x: x, y: y, roomId: roomId, roomFound: !!room, roomName: room ? room.name : null, roomType: room ? room.type : null }); return room; } canBuildRoom(roomType, x, y) { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.startStep('BaseSystem.canBuildRoom', { roomType: roomType, x: x, y: y, currentBaseLevel: this.base.level, currentCredits: this.game.systems.economy.credits, currentRooms: this.base.rooms.length }); const roomTemplate = this.roomTypes[roomType]; if (!roomTemplate) { if (debugLogger) debugLogger.endStep('BaseSystem.canBuildRoom', { success: false, reason: 'Room template not found', roomType: roomType }); return false; } if (debugLogger) debugLogger.logStep('Room template found', { roomName: roomTemplate.name, requiredLevel: roomTemplate.requiredLevel, buildCost: roomTemplate.buildCost, powerCost: roomTemplate.powerCost, maxLevel: roomTemplate.maxLevel }); // Check player level if (this.game.systems.player.stats.level < roomTemplate.requiredLevel) { if (debugLogger) debugLogger.endStep('BaseSystem.canBuildRoom', { success: false, reason: 'Player level too low', playerLevel: this.game.systems.player.stats.level, requiredLevel: roomTemplate.requiredLevel }); return false; } // Check resources if (this.game.systems.economy.credits < roomTemplate.buildCost) { if (debugLogger) debugLogger.endStep('BaseSystem.canBuildRoom', { success: false, reason: 'Insufficient credits', currentCredits: this.game.systems.economy.credits, requiredCredits: roomTemplate.buildCost }); return false; } // Check if room already exists at max level const existingRoom = this.base.rooms.find(r => r.type === roomType); if (existingRoom && existingRoom.level >= roomTemplate.maxLevel) { if (debugLogger) debugLogger.endStep('BaseSystem.canBuildRoom', { success: false, reason: 'Room already at max level', roomType: roomType, currentLevel: existingRoom.level, maxLevel: roomTemplate.maxLevel }); return false; } // Check grid placement const roomSize = this.getRoomSize(roomTemplate.size); if (!this.canPlaceRoom(x, y, roomSize.width, roomSize.height)) { if (debugLogger) debugLogger.endStep('BaseSystem.canBuildRoom', { success: false, reason: 'Cannot place room at location', x: x, y: y, roomSize: roomSize }); return false; } // Check power availability const powerRequirement = roomTemplate.powerCost; if (this.base.power + powerRequirement > this.base.maxPower) { if (debugLogger) debugLogger.endStep('BaseSystem.canBuildRoom', { success: false, reason: 'Insufficient power', currentPower: this.base.power, powerRequirement: powerRequirement, maxPower: this.base.maxPower, totalPowerNeeded: this.base.power + powerRequirement }); return false; } if (debugLogger) debugLogger.endStep('BaseSystem.canBuildRoom', { success: true, roomType: roomType, roomName: roomTemplate.name, x: x, y: y, isUpgrade: !!existingRoom, currentLevel: existingRoom ? existingRoom.level : 0 }); return true; } getRoomSize(size) { const sizes = { small: { width: 1, height: 1 }, medium: { width: 2, height: 2 }, large: { width: 3, height: 3 } }; return sizes[size] || sizes.medium; } canPlaceRoom(x, y, width, height) { // Check bounds if (x < 0 || y < 0 || x + width > this.gridSize || y + height > this.gridSize) { return false; } // Check for collisions for (let dy = 0; dy < height; dy++) { for (let dx = 0; dx < width; dx++) { if (this.grid[y + dy][x + dx] !== null) { return false; } } } return true; } addRoom(roomType, x, y) { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.startStep('BaseSystem.addRoom', { roomType: roomType, x: x, y: y, currentRoomsCount: this.base.rooms.length, currentCredits: this.game.systems.economy.credits }); if (!this.canBuildRoom(roomType, x, y)) { if (debugLogger) debugLogger.endStep('BaseSystem.addRoom', { success: false, reason: 'Cannot build room - failed validation', roomType: roomType, x: x, y: y }); return false; } const roomTemplate = this.roomTypes[roomType]; const roomSize = this.getRoomSize(roomTemplate.size); if (debugLogger) debugLogger.logStep('Room validation passed', { roomName: roomTemplate.name, roomSize: roomSize, buildCost: roomTemplate.buildCost }); // Check if upgrading existing room const existingRoom = this.base.rooms.find(r => r.type === roomType); const isUpgrade = !!existingRoom; if (isUpgrade) { if (debugLogger) debugLogger.logStep('Upgrading existing room', { roomId: existingRoom.id, currentLevel: existingRoom.level, newLevel: existingRoom.level + 1 }); // Upgrade existing room existingRoom.level++; existingRoom.powerCost = roomTemplate.powerCost * existingRoom.level; existingRoom.storageBonus = roomTemplate.storageBonus * existingRoom.level; } else { if (debugLogger) debugLogger.logStep('Creating new room', { roomType: roomType, roomName: roomTemplate.name, x: x, y: y, roomSize: roomSize }); // Create new room const room = { id: Date.now().toString(), type: roomType, name: roomTemplate.name, level: 1, x: x, y: y, width: roomSize.width, height: roomSize.height, powerCost: roomTemplate.powerCost, storageBonus: roomTemplate.storageBonus, icon: roomTemplate.icon, description: roomTemplate.description }; this.base.rooms.push(room); // Place on grid for (let dy = 0; dy < roomSize.height; dy++) { for (let dx = 0; dx < roomSize.width; dx++) { this.grid[y + dy][x + dx] = room.id; } } if (debugLogger) debugLogger.logStep('New room placed on grid', { roomId: room.id, gridPositions: roomSize.width * roomSize.height }); } // Update base stats if (debugLogger) debugLogger.logStep('Updating base stats'); this.updateBaseStats(); // Deduct cost const oldCredits = this.game.systems.economy.credits; this.game.systems.economy.removeCredits(roomTemplate.buildCost); if (debugLogger) debugLogger.logStep('Build cost deducted', { buildCost: roomTemplate.buildCost, oldCredits: oldCredits, newCredits: this.game.systems.economy.credits }); this.game.showNotification(`${roomTemplate.name} ${isUpgrade ? 'upgraded' : 'built'}!`, 'success', 3000); if (debugLogger) debugLogger.endStep('BaseSystem.addRoom', { success: true, roomType: roomType, roomName: roomTemplate.name, isUpgrade: isUpgrade, roomId: isUpgrade ? existingRoom.id : this.base.rooms[this.base.rooms.length - 1].id, newLevel: isUpgrade ? existingRoom.level : 1, finalRoomsCount: this.base.rooms.length, buildCost: roomTemplate.buildCost, finalCredits: this.game.systems.economy.credits }); return true; } removeRoom(roomId) { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.startStep('BaseSystem.removeRoom', { roomId: roomId, currentRoomsCount: this.base.rooms.length }); const roomIndex = this.base.rooms.findIndex(r => r.id === roomId); if (roomIndex === -1) { if (debugLogger) debugLogger.endStep('BaseSystem.removeRoom', { success: false, reason: 'Room not found', roomId: roomId }); return false; } const room = this.base.rooms[roomIndex]; if (debugLogger) debugLogger.logStep('Room found for removal', { roomId: room.id, roomName: room.name, roomType: room.type, roomLevel: room.level, roomPosition: { x: room.x, y: room.y } }); // Don't allow removing command center if (room.type === 'command_center') { this.game.showNotification('Cannot remove Command Center', 'error', 3000); if (debugLogger) debugLogger.endStep('BaseSystem.removeRoom', { success: false, reason: 'Cannot remove command center', roomId: roomId, roomType: room.type }); return false; } // Remove from grid let gridCellsCleared = 0; for (let dy = 0; dy < room.height; dy++) { for (let dx = 0; dx < room.width; dx++) { this.grid[room.y + dy][room.x + dx] = null; gridCellsCleared++; } } if (debugLogger) debugLogger.logStep('Room removed from grid', { gridCellsCleared: gridCellsCleared, roomSize: { width: room.width, height: room.height } }); // Remove from rooms array this.base.rooms.splice(roomIndex, 1); if (debugLogger) debugLogger.logStep('Room removed from rooms array', { removedIndex: roomIndex, remainingRoomsCount: this.base.rooms.length }); // Update base stats if (debugLogger) debugLogger.logStep('Updating base stats after removal'); this.updateBaseStats(); // Refund some resources const refundAmount = Math.floor(this.roomTypes[room.type].buildCost * 0.5); const oldCredits = this.game.systems.economy.credits; this.game.systems.economy.addCredits(refundAmount, 'room_refund'); if (debugLogger) debugLogger.logStep('Refund processed', { refundAmount: refundAmount, oldCredits: oldCredits, newCredits: this.game.systems.economy.credits, originalBuildCost: this.roomTypes[room.type].buildCost, refundPercentage: 0.5 }); this.game.showNotification(`${room.name} removed. Refunded ${refundAmount} credits`, 'info', 3000); if (debugLogger) debugLogger.endStep('BaseSystem.removeRoom', { success: true, roomId: roomId, roomName: room.name, roomType: room.type, refundAmount: refundAmount, finalRoomsCount: this.base.rooms.length, finalCredits: this.game.systems.economy.credits }); return true; } calculateBaseStats() { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.startStep('BaseSystem.calculateBaseStats', { currentRoomsCount: this.base.rooms.length, currentPower: this.base.power, currentMaxPower: this.base.maxPower, currentStorage: this.base.storage, currentMaxStorage: this.base.maxStorage }); let totalPowerCost = 0; let totalStorageBonus = 0; // Calculate power cost and storage bonus from rooms this.base.rooms.forEach(room => { const roomType = this.roomTypes[room.type]; const roomPowerCost = roomType.powerCost * room.level; const roomStorageBonus = roomType.storageBonus * room.level; totalPowerCost += roomPowerCost; totalStorageBonus += roomStorageBonus; if (debugLogger) debugLogger.logStep('Room contribution calculated', { roomId: room.id, roomType: room.type, roomName: room.name, roomLevel: room.level, powerCost: roomPowerCost, storageBonus: roomStorageBonus }); }); // Add upgrade bonuses const storageExpansion = (this.upgrades.storage_expansion?.currentLevel || 0) * (this.upgrades.storage_expansion?.slotBonus || 5); totalStorageBonus += storageExpansion; if (debugLogger) debugLogger.logStep('Upgrade bonuses calculated', { storageExpansionLevel: this.upgrades.storage_expansion?.currentLevel || 0, storageExpansionBonus: storageExpansion, totalStorageBonusWithUpgrades: totalStorageBonus }); const oldPower = this.base.power; const oldMaxPower = this.base.maxPower; const oldStorage = this.base.storage; const oldMaxStorage = this.base.maxStorage; this.base.power = Math.max(0, totalPowerCost); this.base.maxPower = 100 + ((this.upgrades.power_efficiency?.currentLevel || 0) * 20); // Update inventory base slots with storage upgrades if (this.game.systems.inventory) { const newBaseSlots = 30 + totalStorageBonus; // 30 base + storage bonuses const oldBaseSlots = this.game.systems.inventory.baseMaxSlots; this.game.systems.inventory.baseMaxSlots = newBaseSlots; this.game.systems.inventory.updateStarbaseBonusSlots(this.game.systems.inventory.starbaseBonusSlots); if (debugLogger) debugLogger.logStep('Inventory slots updated', { oldBaseSlots: oldBaseSlots, newBaseSlots: newBaseSlots, starbaseBonusSlots: this.game.systems.inventory.starbaseBonusSlots, finalMaxSlots: this.game.systems.inventory.maxSlots }); } // Keep legacy storage for backward compatibility this.base.storage = 1000 + (totalStorageBonus * 100); this.base.maxStorage = this.base.storage; if (debugLogger) debugLogger.endStep('BaseSystem.calculateBaseStats', { powerChanges: { oldPower: oldPower, newPower: this.base.power, oldMaxPower: oldMaxPower, newMaxPower: this.base.maxPower }, storageChanges: { oldStorage: oldStorage, newStorage: this.base.storage, oldMaxStorage: oldMaxStorage, newMaxStorage: this.base.maxStorage }, totals: { totalPowerCost: totalPowerCost, totalStorageBonus: totalStorageBonus, storageExpansionBonus: storageExpansion }, roomsProcessed: this.base.rooms.length }); } // Base upgrades upgradeBase(upgradeId) { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.startStep('BaseSystem.upgradeBase', { upgradeId: upgradeId, currentCredits: this.game.systems.economy.credits, currentUpgradeLevel: this.upgrades[upgradeId] ? this.upgrades[upgradeId].currentLevel : null }); const upgrade = this.upgrades[upgradeId]; if (!upgrade) { if (debugLogger) debugLogger.endStep('BaseSystem.upgradeBase', { success: false, reason: 'Upgrade not found', upgradeId: upgradeId }); return false; } if (debugLogger) debugLogger.logStep('Upgrade found', { upgradeName: upgrade.name, currentLevel: upgrade.currentLevel, maxLevel: upgrade.maxLevel, baseCost: upgrade.cost }); if (upgrade.currentLevel >= upgrade.maxLevel) { this.game.showNotification('Upgrade at maximum level', 'warning', 3000); if (debugLogger) debugLogger.endStep('BaseSystem.upgradeBase', { success: false, reason: 'Upgrade at maximum level', upgradeId: upgradeId, currentLevel: upgrade.currentLevel, maxLevel: upgrade.maxLevel }); return false; } const cost = upgrade.cost * (upgrade.currentLevel + 1); if (this.game.systems.economy.credits < cost) { this.game.showNotification('Not enough credits', 'error', 3000); if (debugLogger) debugLogger.endStep('BaseSystem.upgradeBase', { success: false, reason: 'Insufficient credits', upgradeId: upgradeId, requiredCredits: cost, currentCredits: this.game.systems.economy.credits }); return false; } if (debugLogger) debugLogger.logStep('Upgrade validation passed', { upgradeId: upgradeId, currentLevel: upgrade.currentLevel, newLevel: upgrade.currentLevel + 1, cost: cost }); // Apply upgrade const oldCredits = this.game.systems.economy.credits; this.game.systems.economy.removeCredits(cost); upgrade.currentLevel++; if (debugLogger) debugLogger.logStep('Upgrade applied', { oldCredits: oldCredits, newCredits: this.game.systems.economy.credits, costDeducted: cost, newUpgradeLevel: upgrade.currentLevel }); // Apply effects let statsUpdated = false; if (upgrade.effect.powerReduction) { if (debugLogger) debugLogger.logStep('Applying power reduction effect'); this.updateBaseStats(); statsUpdated = true; } if (upgrade.effect.storageBonus) { if (debugLogger) debugLogger.logStep('Applying storage bonus effect'); this.updateBaseStats(); statsUpdated = true; } if (upgrade.effect.productionBonus) { if (debugLogger) debugLogger.logStep('Applying production bonus effect', { productionBonus: upgrade.effect.productionBonus }); statsUpdated = true; } if (upgrade.effect.defenseBonus) { if (debugLogger) debugLogger.logStep('Applying defense bonus effect', { defenseBonus: upgrade.effect.defenseBonus }); statsUpdated = true; } if (!statsUpdated) { // For upgrades like storage_expansion that don't have effects in the effect object if (debugLogger) debugLogger.logStep('Updating base stats for upgrade'); this.updateBaseStats(); } this.game.showNotification(`${upgrade.name} upgraded to level ${upgrade.currentLevel}!`, 'success', 3000); if (debugLogger) debugLogger.endStep('BaseSystem.upgradeBase', { success: true, upgradeId: upgradeId, upgradeName: upgrade.name, oldLevel: upgrade.currentLevel - 1, newLevel: upgrade.currentLevel, cost: cost, finalCredits: this.game.systems.economy.credits, effectsApplied: statsUpdated }); return true; } // Base production update(deltaTime) { if (this.game.state.paused) { return; } // Auto production from automation systems const autoProductionRate = (this.upgrades.automation_systems?.currentLevel || 0) * 0.05; if (autoProductionRate > 0) { // Use real computer time delta const production = (deltaTime / 1000) * autoProductionRate * 10; // 10 credits per second per level this.game.systems.economy.addCredits(Math.floor(production), 'base_production'); } // Power generation from power generators const powerGenerators = this.base.rooms.filter(r => r.type === 'power_generator'); if (powerGenerators.length > 0) { const powerGeneration = powerGenerators.reduce((total, gen) => total + Math.abs(gen.powerCost), 0); // Power generation would affect other systems } // Research production if ((this.upgrades.research_lab?.currentLevel || 0) > 0) { const researchRate = (this.upgrades.research_lab?.currentLevel || 0) * 0.1; // Research points generation would go here } // Resource processing if ((this.upgrades.resource_processor?.currentLevel || 0) > 0) { const processingRate = (this.upgrades.resource_processor?.currentLevel || 0) * 0.05; // Resource processing would go here } } // UI updates updateUI() { this.setupBaseNavigation(); this.updateBaseDisplay(); this.updateUpgradesList(); this.updateShipGallery(); this.updateStarbaseList(); } // Base Navigation setupBaseNavigation() { const navButtons = document.querySelectorAll('.base-nav-btn'); navButtons.forEach(button => { button.addEventListener('click', () => { const view = button.dataset.view; this.switchBaseView(view); }); }); } switchBaseView(view) { // Hide all views document.querySelectorAll('.base-view-content').forEach(content => { content.classList.add('hidden'); }); // Remove active class from all buttons document.querySelectorAll('.base-nav-btn').forEach(btn => { btn.classList.remove('active'); }); // Show selected view const selectedView = document.getElementById(`base-${view}`); if (selectedView) { selectedView.classList.remove('hidden'); } // Add active class to clicked button const activeBtn = document.querySelector(`[data-view="${view}"]`); if (activeBtn) { activeBtn.classList.add('active'); } // Initialize view-specific content if (view === 'visualization') { this.initializeBaseVisualization(); } else if (view === 'ships') { this.updateShipGallery(); } else if (view === 'starbases') { // Boot the isometric starbase world instead of the old list UI if (typeof _startStarbaseWorld === 'function') { _startStarbaseWorld(); } } else { // Leaving starbases — stop the world loop if (typeof _stopStarbaseWorld === 'function') { _stopStarbaseWorld(); } } } // Base Visualization initializeBaseVisualization() { const canvas = document.getElementById('baseCanvas'); if (!canvas) return; const ctx = canvas.getContext('2d'); // Clear canvas ctx.clearRect(0, 0, canvas.width, canvas.height); // Draw base grid this.drawBaseVisualization(ctx, canvas); // Update info overlay this.updateBaseInfoOverlay(); } drawBaseVisualization(ctx, canvas) { const cellSize = 40; const offsetX = (canvas.width - this.gridSize * cellSize) / 2; const offsetY = (canvas.height - this.gridSize * cellSize) / 2; // Draw grid ctx.strokeStyle = '#333'; ctx.lineWidth = 1; for (let y = 0; y <= this.gridSize; y++) { ctx.beginPath(); ctx.moveTo(offsetX, offsetY + y * cellSize); ctx.lineTo(offsetX + this.gridSize * cellSize, offsetY + y * cellSize); ctx.stroke(); } for (let x = 0; x <= this.gridSize; x++) { ctx.beginPath(); ctx.moveTo(offsetX + x * cellSize, offsetY); ctx.lineTo(offsetX + x * cellSize, offsetY + this.gridSize * cellSize); ctx.stroke(); } // Draw rooms for (let y = 0; y < this.gridSize; y++) { for (let x = 0; x < this.gridSize; x++) { const roomId = this.grid[y][x]; if (roomId) { const room = this.base.rooms.find(r => r.id === roomId); if (room) { this.drawRoom(ctx, room, x, y, cellSize, offsetX, offsetY); } } } } } drawRoom(ctx, room, gridX, gridY, cellSize, offsetX, offsetY) { const x = offsetX + gridX * cellSize; const y = offsetY + gridY * cellSize; // Room colors by type const roomColors = { command_center: '#4CAF50', power_generator: '#FFC107', defense_turret: '#F44336', storage: '#2196F3', research_lab: '#9C27B0', factory: '#FF9800', medical_bay: '#00BCD4', hangar: '#795548' }; const color = roomColors[room.type] || '#666'; // Draw room ctx.fillStyle = color; ctx.fillRect(x + 2, y + 2, cellSize - 4, cellSize - 4); // Draw room border ctx.strokeStyle = '#fff'; ctx.lineWidth = 2; ctx.strokeRect(x + 2, y + 2, cellSize - 4, cellSize - 4); // Draw room icon/initial ctx.fillStyle = '#fff'; ctx.font = 'bold 16px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(room.name.charAt(0), x + cellSize/2, y + cellSize/2); } updateBaseInfoOverlay() { const infoDisplay = document.getElementById('baseInfoDisplay'); if (!infoDisplay) return; const totalRooms = this.base.rooms.length; const powerUsage = this.base.power; const maxPower = this.base.maxPower; const storage = this.base.storage; const maxStorage = this.base.maxStorage; infoDisplay.innerHTML = `
Base Name: ${this.base.name}
Level: ${this.base.level}
Total Rooms: ${totalRooms}
Power Usage: ${powerUsage}/${maxPower}
Storage: ${storage}/${maxStorage}
`; } // Ship Gallery initializeShipGallery() { // Initialize purchased ships array if (!this.purchasedShips) { this.purchasedShips = []; // Add current ship to gallery with proper timestamp ID const player = this.game.systems.player; if (player.ship) { this.purchasedShips.push({ id: Date.now().toString(), // Use timestamp instead of hardcoded 'current_ship' name: player.ship.name || 'Default Ship', class: player.ship.class || 'fighter', level: player.ship.level || 1, stats: { ...player.attributes }, isCurrent: true }); } } } updateShipGallery() { const shipGrid = document.getElementById('shipGrid'); if (!shipGrid) { return; } if (!this.purchasedShips) { this.initializeShipGallery(); } if (!this.purchasedShips || this.purchasedShips.length === 0) { shipGrid.innerHTML = '

No ships purchased yet. Visit the shop to buy ships!

'; return; } shipGrid.innerHTML = ''; this.purchasedShips.forEach(ship => { const shipElement = document.createElement('div'); shipElement.className = `ship-card ${ship.isCurrent ? 'current-ship' : ''}`; shipElement.innerHTML = `

${ship.name}

${ship.isCurrent ? 'Current' : ''}
Class: ${ship.class}
Level: ${ship.level}
Attack: ${ship.stats.attack || 0}
Speed: ${ship.stats.speed || 0}
Defense: ${ship.stats.defense || 0}
${!ship.isCurrent ? ` ` : ''} `; shipGrid.appendChild(shipElement); }); } equipShip(shipId) { const ship = this.purchasedShips.find(s => s.id === shipId); if (!ship) { this.game.showNotification('Ship not found!', 'error', 3000); return; } if (ship.isCurrent) { this.game.showNotification('This ship is already equipped!', 'info', 3000); return; } const player = this.game.systems.player; player.ship.name = ship.name; player.ship.class = ship.class; player.ship.level = ship.level; player.ship.texture = ship.texture; // Copy texture for image display // Apply ship-specific stats (not just attributes) if (ship.stats.health || ship.stats.hull) { const healthValue = ship.stats.health || ship.stats.hull || 100; player.ship.maxHealth = healthValue; player.ship.health = healthValue; } if (ship.stats.attack) { player.ship.attack = ship.stats.attack; } if (ship.stats.defense) { player.ship.defense = ship.stats.defense; } if (ship.stats.speed) { player.ship.speed = ship.stats.speed; } if (ship.stats.criticalChance) { player.ship.criticalChance = ship.stats.criticalChance; } if (ship.stats.criticalDamage) { player.ship.criticalDamage = ship.stats.criticalDamage; } // Also update player attributes for compatibility player.attributes.attack = ship.stats.attack || player.attributes.attack; player.attributes.speed = ship.stats.speed || player.attributes.speed; player.attributes.defense = ship.stats.defense || player.attributes.defense; if (ship.stats.health || ship.stats.hull) { const healthValue = ship.stats.health || ship.stats.hull || 100; player.attributes.maxHealth = healthValue; player.attributes.health = healthValue; } // Update isCurrent flags this.purchasedShips.forEach(s => s.isCurrent = false); ship.isCurrent = true; // Force immediate gallery update after flag changes const shipGrid = document.getElementById('shipGrid'); if (shipGrid) { shipGrid.innerHTML = ''; this.updateShipGallery(); } // Also update ShipSystem's currentShip to keep systems synchronized if (this.game.systems.ship) { // Find or create a ship object in ShipSystem format const shipSystemShip = { id: ship.id, name: ship.name, image: ship.texture || `assets/textures/ships/${ship.class.toLowerCase()}.png`, class: ship.class, level: ship.level, stats: ship.stats, status: 'active', rarity: 'Common' }; // Update ShipSystem's current ship this.game.systems.ship.currentShip = shipSystemShip; // Update the ships array in ShipSystem if needed const existingShipIndex = this.game.systems.ship.ships.findIndex(s => s.id === ship.id); if (existingShipIndex >= 0) { this.game.systems.ship.ships[existingShipIndex].status = 'active'; this.game.systems.ship.ships[existingShipIndex] = shipSystemShip; } else { // Add to ships array if not present this.game.systems.ship.ships.push(shipSystemShip); } // Mark all other ships as inactive this.game.systems.ship.ships.forEach(s => { if (s.id !== ship.id) s.status = 'inactive'; }); } // Only update player UI if in multiplayer mode or game is actively running if (this.game.shouldUpdateGUI()) { player.updateUI(); } this.updateShipGallery(); // Also update ShipSystem display if (this.game.systems.ship && this.game.systems.ship.updateCurrentShipDisplay) { this.game.systems.ship.updateCurrentShipDisplay(); } else { this.updateCurrentShipDisplayDirect(); } // Force save the game to persist the ship change this.game.save().then(() => { // Force complete gallery refresh after save completes const shipGrid = document.getElementById('shipGrid'); if (shipGrid) { shipGrid.innerHTML = ''; // Clear completely this.updateShipGallery(); // Rebuild from scratch } // Force ShipSystem to sync with new current ship if (this.game.systems.ship && this.game.systems.ship.syncWithPlayerShip) { this.game.systems.ship.syncWithPlayerShip(); } }); this.game.showNotification(`Equipped ${ship.name}!`, 'success', 3000); } updateCurrentShipDisplayDirect() { const player = this.game.systems.player; if (!player || !player.ship) { return; } const elements = { currentShipImage: document.getElementById('currentShipImage'), currentShipName: document.getElementById('currentShipName'), currentShipClass: document.getElementById('currentShipClass'), currentShipLevel: document.getElementById('currentShipLevel'), currentShipHealth: document.getElementById('currentShipHealth'), currentShipAttack: document.getElementById('currentShipAttack'), currentShipDefense: document.getElementById('currentShipDefense'), currentShipSpeed: document.getElementById('currentShipSpeed') }; const ship = player.ship; if (elements.currentShipImage) { const imagePath = ship.texture || `assets/textures/ships/${ship.class.toLowerCase()}.png`; console.log(`[DEBUG] Ship image path: ${imagePath}, texture: ${ship.texture}, class: ${ship.class}`); elements.currentShipImage.src = imagePath; // Add error handling for image loading elements.currentShipImage.onerror = function() { console.error(`[DEBUG] Failed to load image: ${imagePath}`); // Fallback to default ship image this.src = 'assets/textures/ships/starter_cruiser.png'; }; } if (elements.currentShipName) elements.currentShipName.textContent = ship.name || 'Unknown Ship'; if (elements.currentShipClass) elements.currentShipClass.textContent = ship.class || 'Unknown'; if (elements.currentShipLevel) elements.currentShipLevel.textContent = ship.level || 1; if (elements.currentShipHealth) elements.currentShipHealth.textContent = `${ship.health}/${ship.maxHealth}`; if (elements.currentShipAttack) elements.currentShipAttack.textContent = ship.attack || 0; if (elements.currentShipDefense) elements.currentShipDefense.textContent = ship.defense || ship.defence || 0; if (elements.currentShipSpeed) elements.currentShipSpeed.textContent = ship.speed || 0; } addShipToGallery(shipData) { this.purchasedShips.push({ id: Date.now().toString(), name: shipData.name, class: shipData.type, level: 1, stats: { ...shipData.stats }, texture: shipData.texture, // Include texture for image display isCurrent: false }); this.updateShipGallery(); } // Starbase System initializeStarbaseSystem() { // Initialize starbase collection if (!this.starbases) { this.starbases = [ { id: 'main_base', name: 'Command Center Alpha', type: 'command', level: 1, location: 'Sector Alpha-1', isMain: true } ]; } // Define available starbase types this.starbaseTypes = { mining: { name: 'Mining Outpost', description: 'Automated mining facility for resource extraction', price: 25000, currency: 'credits', icon: 'fa-hammer', benefits: ['+500 credits/hour', '+50 gems/day', '+5 inventory slots'], requiredLevel: 5, inventoryBonus: 5 }, research: { name: 'Research Station', description: 'Advanced research facility for technology development', price: 50000, currency: 'credits', icon: 'fa-flask', benefits: ['+100 experience/hour', '+10% skill progression', '+10 inventory slots'], requiredLevel: 10, inventoryBonus: 10 }, defense: { name: 'Defense Platform', description: 'Military installation for sector protection', price: 40000, currency: 'credits', icon: 'fa-shield-alt', benefits: ['+15% combat effectiveness', '+100 defense rating'], requiredLevel: 8, inventoryBonus: 8 }, trading: { name: 'Trading Hub', description: 'Commercial center for trade and commerce', price: 75000, currency: 'credits', icon: 'fa-store', benefits: ['+20% shop discounts', '+200 gems/day'], requiredLevel: 12, inventoryBonus: 15 } }; } updateStarbaseList() { const starbaseList = document.getElementById('starbaseList'); if (!starbaseList) return; starbaseList.innerHTML = ''; // Initialize starbases if not exists if (!this.starbases) { this.initializeStarbaseSystem(); } if (!this.starbases || this.starbases.length === 0) { starbaseList.innerHTML = '

No starbases owned yet.

'; return; } this.starbases.forEach(starbase => { const starbaseElement = document.createElement('div'); starbaseElement.className = `starbase-card ${starbase.isMain ? 'main-starbase' : ''}`; starbaseElement.innerHTML = `

${starbase.name}

${starbase.isMain ? 'Main Base' : ''}
Type: ${starbase.type}
Level: ${starbase.level}
Location: ${starbase.location}
${!starbase.isMain ? ` ` : ''}
`; starbaseList.appendChild(starbaseElement); }); } updateStarbasePurchaseList() { const purchaseList = document.getElementById('starbasePurchaseItems'); if (!purchaseList) return; purchaseList.innerHTML = ''; const player = this.game.systems.player; Object.entries(this.starbaseTypes).forEach(([type, starbase]) => { const starbaseElement = document.createElement('div'); starbaseElement.className = 'starbase-purchase-card'; const canAfford = this.game.systems.economy.credits >= starbase.price; const meetsLevel = player.stats.level >= starbase.requiredLevel; const canPurchase = canAfford && meetsLevel; starbaseElement.innerHTML = `

${starbase.name}

${starbase.description}
Benefits:
Cost: ${starbase.price} ${starbase.currency}
Required Level: ${starbase.requiredLevel}
`; purchaseList.appendChild(starbaseElement); }); } purchaseStarbase(type) { const starbaseTemplate = this.starbaseTypes[type]; if (!starbaseTemplate) { this.game.showNotification('Invalid starbase type!', 'error', 3000); return; } const player = this.game.systems.player; const economy = this.game.systems.economy; // Check requirements if (player.stats.level < starbaseTemplate.requiredLevel) { this.game.showNotification(`Level ${starbaseTemplate.requiredLevel} required!`, 'error', 3000); return; } if (economy.credits < starbaseTemplate.price) { this.game.showNotification('Insufficient credits!', 'error', 3000); return; } // Process payment economy.credits -= starbaseTemplate.price; // Create new starbase const newStarbase = { id: Date.now().toString(), name: `${starbaseTemplate.name} ${this.starbases.length}`, type: type, level: 1, location: `Sector ${String.fromCharCode(65 + this.starbases.length)}-${this.starbases.length}`, isMain: false, benefits: starbaseTemplate.benefits }; this.starbases.push(newStarbase); // Apply benefits this.applyStarbaseBenefits(newStarbase); // Only update UI if in multiplayer mode or game is actively running if (this.game.shouldUpdateGUI()) { economy.updateUI(); this.updateStarbaseList(); this.updateStarbasePurchaseList(); } this.game.showNotification(`Purchased ${starbaseTemplate.name}!`, 'success', 4000); } applyStarbaseBenefits(starbase) { // Apply passive benefits based on starbase type switch (starbase.type) { case 'mining': // Start passive credit generation this.startMiningProduction(starbase); // Apply inventory bonus this.updateInventoryBonusSlots(); break; case 'research': // Apply experience bonus this.game.systems.player.experienceMultiplier = (this.game.systems.player.experienceMultiplier || 1) + 0.1; // Apply inventory bonus this.updateInventoryBonusSlots(); break; case 'defense': // Apply defense bonus this.game.systems.player.attributes.defense = Math.floor(this.game.systems.player.attributes.defense * 1.2); // Apply inventory bonus this.updateInventoryBonusSlots(); break; case 'trading': // Apply shop discount this.game.systems.economy.discountMultiplier = 0.85; // Apply inventory bonus this.updateInventoryBonusSlots(); break; } } updateInventoryBonusSlots() { // Calculate total inventory bonus from all owned starbases let totalBonusSlots = 0; if (this.starbases && this.starbases.length > 0) { this.starbases.forEach(starbase => { const starbaseType = this.starbaseTypes[starbase.type]; if (starbaseType && starbaseType.inventoryBonus) { totalBonusSlots += starbaseType.inventoryBonus; } }); } // Update inventory system with new bonus slots if (this.game.systems.inventory) { this.game.systems.inventory.updateStarbaseBonusSlots(totalBonusSlots); } } startMiningProduction(starbase) { // Only start mining if in multiplayer mode or game is actively running const shouldStartMining = window.smartSaveManager?.isMultiplayer || this.game?.isRunning; if (shouldStartMining && !this.miningInterval) { // Set up passive credit generation this.miningInterval = setInterval(() => { this.game.systems.economy.addCredits(500, 'mining_outpost'); }, 3600000); // 1 hour console.log('[BASE SYSTEM] Mining production started'); } else if (!shouldStartMining) { console.log('[BASE SYSTEM] Skipping mining production - not in multiplayer mode'); } } viewStarbaseDetails(starbaseId) { const starbase = this.starbases.find(s => s.id === starbaseId); if (!starbase) return; const details = `

${starbase.name}

Type: ${starbase.type}

Level: ${starbase.level}

Location: ${starbase.location}

${starbase.benefits ? `

Active Benefits:

` : ''} `; if (this.game && this.game.systems && this.game.systems.ui) { this.game.systems.ui.showModal('Starbase Details', details); } } decommissionStarbase(starbaseId) { if (!confirm('Are you sure you want to decommission this starbase? You will receive 50% of its value back.')) { return; } const starbaseIndex = this.starbases.findIndex(s => s.id === starbaseId); if (starbaseIndex === -1) return; const starbase = this.starbases[starbaseIndex]; const refundAmount = Math.floor(this.starbaseTypes[starbase.type].price * 0.5); // Remove starbase this.starbases.splice(starbaseIndex, 1); // Give refund this.game.systems.economy.addCredits(refundAmount, 'starbase_refund'); // Update inventory bonus slots after removal this.updateInventoryBonusSlots(); // Update UI this.updateStarbaseList(); this.updateStarbasePurchaseList(); this.game.showNotification(`Decommissioned ${starbase.name}. Refunded ${refundAmount} credits.`, 'info', 4000); } updateBaseDisplay() { const baseRoomsElement = document.getElementById('baseRooms'); if (!baseRoomsElement) return; // Ensure grid is initialized if (!this.grid || this.grid.length === 0) { console.log('[BASE SYSTEM] Grid not initialized, initializing now'); this.initializeGrid(); } baseRoomsElement.innerHTML = ''; // Create grid container const gridContainer = document.createElement('div'); gridContainer.className = 'base-grid'; // Create grid cells for (let y = 0; y < this.gridSize; y++) { for (let x = 0; x < this.gridSize; x++) { const cell = document.createElement('div'); cell.className = 'base-cell'; cell.dataset.x = x; cell.dataset.y = y; const room = this.getRoomAt(x, y); if (room) { // Check if this is the main cell of the room if (room.x === x && room.y === y) { cell.className += ` room ${room.type}`; cell.innerHTML = `
L${room.level}
`; cell.title = `${room.name} (Level ${room.level})`; } else { // Other cells of the same room are just filled cell.innerHTML = ''; } cell.title = `${room.name} (Level ${room.level})`; } else { cell.className += ' empty'; cell.addEventListener('click', () => this.showRoomBuildMenu(x, y)); } gridContainer.appendChild(cell); } } baseRoomsElement.appendChild(gridContainer); // Add base info with connected inventory storage const baseInfo = document.createElement('div'); baseInfo.className = 'base-info'; // Get inventory information const inventoryInfo = this.game.systems.inventory ? this.game.systems.inventory.getInventoryInfo() : null; baseInfo.innerHTML = `

${this.base.name}

Level: ${this.base.level}
Power: ${this.base.power}/${this.base.maxPower}
Storage: ${inventoryInfo ? `${inventoryInfo.currentSlots}/${inventoryInfo.totalMaxSlots}` : `${this.base.storage}/${this.base.maxStorage}`} slots
${inventoryInfo ? `
Base: ${inventoryInfo.baseMaxSlots} | Starbase Bonus: +${inventoryInfo.starbaseBonusSlots}
` : ''}
`; baseRoomsElement.appendChild(baseInfo); } updateUpgradesList() { const upgradesElement = document.getElementById('baseUpgrades'); if (!upgradesElement) return; upgradesElement.innerHTML = ''; Object.entries(this.upgrades).forEach(([upgradeId, upgrade]) => { const upgradeElement = document.createElement('div'); upgradeElement.className = 'upgrade-item'; const cost = upgrade.cost * (upgrade.currentLevel + 1); const canAfford = this.game.systems.economy.credits >= cost; const isMaxLevel = upgrade.currentLevel >= upgrade.maxLevel; upgradeElement.innerHTML = `
${upgrade.name}
${upgrade.description}
Level: ${upgrade.currentLevel}/${upgrade.maxLevel}
Cost: ${cost} credits
`; upgradesElement.appendChild(upgradeElement); }); } showRoomBuildMenu(x, y) { const availableRooms = Object.entries(this.roomTypes) .filter(([roomType, template]) => template.requiredLevel <= this.game.systems.player.stats.level ) .filter(([roomType, template]) => this.canBuildRoom(roomType, x, y)); if (availableRooms.length === 0) { this.game.showNotification('No rooms available for this location', 'warning', 3000); return; } let menuContent = '

Build Room

'; availableRooms.forEach(([roomType, template]) => { const roomSize = this.getRoomSize(template.size); menuContent += `
${template.name}
Size: ${roomSize.width}x${roomSize.height}
Power: ${template.powerCost > 0 ? '+' : ''}${template.powerCost}
Cost: ${template.buildCost} credits
${template.description}
`; }); menuContent += '
'; } updateUpgradesList() { const upgradesElement = document.getElementById('baseUpgrades'); if (!upgradesElement) return; upgradesElement.innerHTML = ''; Object.entries(this.upgrades).forEach(([upgradeId, upgrade]) => { const upgradeElement = document.createElement('div'); upgradeElement.className = 'upgrade-item'; const cost = upgrade.cost * (upgrade.currentLevel + 1); const canAfford = this.game.systems.economy.credits >= cost; const isMaxLevel = upgrade.currentLevel >= upgrade.maxLevel; upgradeElement.innerHTML = `
${upgrade.name}
${upgrade.description}
Level: ${upgrade.currentLevel}/${upgrade.maxLevel}
Cost: ${cost} credits
`; upgradesElement.appendChild(upgradeElement); }); } showRoomBuildMenu(x, y) { const availableRooms = Object.entries(this.roomTypes) .filter(([roomType, template]) => template.requiredLevel <= this.game.systems.player.stats.level ) .filter(([roomType, template]) => this.canBuildRoom(roomType, x, y)); if (availableRooms.length === 0) { this.game.showNotification('No rooms available for this location', 'warning', 3000); return; } let menuContent = '

Build Room

'; availableRooms.forEach(([roomType, template]) => { const roomSize = this.getRoomSize(template.size); menuContent += `
${template.name}
Size: ${roomSize.width}x${roomSize.height}
Power: ${template.powerCost > 0 ? '+' : ''}${template.powerCost}
Cost: ${template.buildCost} credits
${template.description}
`; }); menuContent += '
'; if (this.game && this.game.systems && this.game.systems.ui) { this.game.systems.ui.showModal('Build Room', menuContent); } } // Save/Load save() { const debugLogger = window.debugLogger; // if (debugLogger) debugLogger.startStep('BaseSystem.save', { // baseName: this.base.name, // baseLevel: this.base.level, // roomsCount: this.base.rooms.length, // gridCellsCount: this.grid.flat().filter(cell => cell !== null).length, // upgradesCount: Object.keys(this.upgrades).length // }); const saveData = { base: this.base, grid: this.grid, upgrades: this.upgrades, purchasedShips: this.purchasedShips || [] }; // if (debugLogger) debugLogger.endStep('BaseSystem.save', { // saveDataSize: JSON.stringify(saveData).length, // baseSaved: { // name: saveData.base.name, // level: saveData.base.level, // roomsCount: saveData.base.rooms.length // }, // gridSaved: { // gridSize: this.gridSize, // occupiedCells: this.grid.flat().filter(cell => cell !== null).length // }, // upgradesSaved: Object.keys(saveData.upgrades).map(id => ({ // id: id, // currentLevel: saveData.upgrades[id].currentLevel // })), // saveData: saveData // }); return saveData; } load(data) { const debugLogger = window.debugLogger; const oldState = { baseName: this.base.name, baseLevel: this.base.level, roomsCount: this.base.rooms.length, upgradesState: Object.keys(this.upgrades).map(id => ({ id: id, currentLevel: this.upgrades[id].currentLevel })) }; if (debugLogger) debugLogger.startStep('BaseSystem.load', { oldState: oldState, loadData: data }); try { if (data.base) { const oldBase = { ...this.base }; this.base = { ...this.base, ...data.base }; if (debugLogger) debugLogger.logStep('Base data loaded', { oldBase: { name: oldBase.name, level: oldBase.level, roomsCount: oldBase.rooms.length }, newBase: { name: this.base.name, level: this.base.level, roomsCount: this.base.rooms.length } }); } if (data.grid) { const oldGrid = this.grid; this.grid = data.grid; if (debugLogger) debugLogger.logStep('Grid data loaded', { oldGridCells: oldGrid.flat().filter(cell => cell !== null).length, newGridCells: this.grid.flat().filter(cell => cell !== null).length, gridSize: this.gridSize }); } if (data.upgrades) { const oldUpgrades = Object.keys(this.upgrades).map(id => ({ id: id, currentLevel: this.upgrades[id].currentLevel })); Object.entries(data.upgrades).forEach(([upgradeId, upgrade]) => { if (this.upgrades[upgradeId]) { Object.assign(this.upgrades[upgradeId], upgrade); if (debugLogger) debugLogger.logStep('Upgrade loaded', { upgradeId: upgradeId, oldLevel: oldUpgrades.find(u => u.id === upgradeId)?.currentLevel || 0, newLevel: this.upgrades[upgradeId].currentLevel }); } }); } // Load purchased ships if (data.purchasedShips) { this.purchasedShips = data.purchasedShips; if (debugLogger) debugLogger.logStep('Purchased ships loaded', { shipsCount: this.purchasedShips.length, shipNames: this.purchasedShips.map(s => s.name) }); // Find the current ship from gallery and sync with player const currentGalleryShip = this.purchasedShips.find(s => s.isCurrent); if (currentGalleryShip) { const player = this.game.systems.player; if (player && player.ship) { console.log('[DEBUG] Syncing player ship with gallery current ship:', currentGalleryShip); // Update player's ship with gallery current ship data player.ship.name = currentGalleryShip.name; player.ship.class = currentGalleryShip.class; player.ship.level = currentGalleryShip.level; player.ship.texture = currentGalleryShip.texture; // Update player attributes with ship stats if (currentGalleryShip.stats) { Object.assign(player.attributes, currentGalleryShip.stats); // Update player.ship properties for consistency player.ship.health = currentGalleryShip.stats.health || currentGalleryShip.stats.hull || 100; player.ship.maxHealth = currentGalleryShip.stats.maxHealth || currentGalleryShip.stats.hull || 100; player.ship.attack = currentGalleryShip.stats.attack || 10; player.ship.defence = currentGalleryShip.stats.defense || currentGalleryShip.stats.defence || 5; player.ship.speed = currentGalleryShip.stats.speed || 10; } console.log('[DEBUG] Player ship updated:', player.ship); console.log('[DEBUG] Player attributes updated:', player.attributes); // Only update UI displays if in multiplayer mode or game is actively running if (this.game.shouldUpdateGUI()) { player.updateUI(); if (this.game.systems.ship && this.game.systems.ship.updateCurrentShipDisplay) { this.game.systems.ship.updateCurrentShipDisplay(); } } } } } // Update base stats after loading if (debugLogger) debugLogger.logStep('Updating base stats after load'); this.updateBaseStats(); // Update ship gallery after loading ships if (data.purchasedShips) { this.updateShipGallery(); } if (debugLogger) debugLogger.endStep('BaseSystem.load', { success: true, oldState: oldState, newState: { baseName: this.base.name, baseLevel: this.base.level, roomsCount: this.base.rooms.length, upgradesState: Object.keys(this.upgrades).map(id => ({ id: id, currentLevel: this.upgrades[id].currentLevel })) }, baseStatsUpdated: true }); } catch (error) { if (debugLogger) debugLogger.errorEvent('BaseSystem.load', error, { oldState: oldState, loadData: data, error: error.message }); throw error; } } reset() { this.baseLevel = 1; this.rooms = {}; // Reset upgrades to initial state this.upgrades = { power_efficiency: { name: 'Power Efficiency', description: 'Reduces power consumption of all rooms', cost: 1000, effect: { powerReduction: 0.1 }, maxLevel: 5, currentLevel: 0 }, storage_expansion: { name: 'Storage Expansion', description: 'Increases inventory slots for item storage', cost: 5000, maxLevel: 10, currentLevel: 0, icon: 'fa-boxes', slotBonus: 5 }, automation_systems: { name: 'Automation Systems', description: 'Automated resource generation and processing', cost: 2500, maxLevel: 10, currentLevel: 0, icon: 'fa-robot' } }; this.resources = { energy: 100, materials: 50, research: 0 }; this.initializeBaseData(); } updateBaseStats() { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.startStep('BaseSystem.updateBaseStats'); // Calculate total power and storage from rooms let totalPower = 0; let totalStorage = 0; this.base.rooms.forEach(room => { const roomTemplate = this.roomTypes[room.type]; if (roomTemplate) { totalPower += roomTemplate.powerGeneration || 0; totalStorage += roomTemplate.storageBonus || 0; } }); // Update base stats this.base.power = Math.max(0, totalPower); this.base.maxStorage = 1000 + totalStorage; // Update UI if available if (this.game.systems.ui && this.game.systems.ui.updateBaseSystem) { this.game.systems.ui.updateBaseSystem(); } // if (debugLogger) debugLogger.endStep('BaseSystem.updateBaseStats', { // totalPower: this.base.power, // maxStorage: this.base.maxStorage, // roomsCount: this.base.rooms.length // }); } }