/** * ZOMBIE MINER AUTOMATION SYSTEM * Part of: Mining System Expansion * Created: January 4, 2026 * * Features: * - Hire zombie miners for passive resource generation * - Assign miners to specific mine depths * - Efficiency & loyalty mechanics * - Automated ore collection * - Zombie equipment upgrades */ class ZombieMinerAutomationSystem { constructor(game) { this.game = game; this.player = game.player; // Zombie miners this.zombieMiners = []; this.maxZombieMiners = 10; this.zombieMinerCost = 5000; // Automation settings this.automationActive = false; this.totalYieldPerHour = 0; this.lastCollectionTime = null; // Equipment for zombies this.zombieEquipment = { pickaxe_tier: 1, // 1-5 helmet_lamp: false, // Better visibility oxygen_tank: false, // Deeper mining cart: false // Auto-transport }; } /** * Hire a zombie miner */ hireZombieMiner() { if (this.zombieMiners.length >= this.maxZombieMiners) { return { success: false, message: `Maximum ${this.maxZombieMiners} zombie miners allowed!` }; } if (this.player.money < this.zombieMinerCost) { return { success: false, message: `Need ${this.zombieMinerCost}g to hire zombie miner!` }; } // Hire zombie this.player.money -= this.zombieMinerCost; const miner = { id: `zombie_miner_${this.zombieMiners.length + 1}`, name: this.generateZombieName(), assignedMine: null, assignedDepth: 0, efficiency: 1.0, // 0.5 - 2.0 loyalty: 50, // 0-100 yieldPerHour: 5, // Base yield level: 1, experience: 0 }; this.zombieMiners.push(miner); // Recalculate automation this.updateAutomationYield(); this.game.showMessage( `Hired ${miner.name}! (${this.zombieMiners.length}/${this.maxZombieMiners})` ); return { success: true, miner: miner }; } /** * Generate random zombie miner name */ generateZombieName() { const prefixes = ['Grumpy', 'Rusty', 'Dusty', 'Grumbly', 'Moaning', 'Shuffling']; const suffixes = ['Zed', 'Mort', 'Bones', 'Guts', 'Picks', 'Drills']; const prefix = Phaser.Utils.Array.GetRandom(prefixes); const suffix = Phaser.Utils.Array.GetRandom(suffixes); return `${prefix} ${suffix}`; } /** * Assign zombie miner to specific mine & depth */ assignZombieMiner(minerId, mineId, depth) { const miner = this.zombieMiners.find(m => m.id === minerId); if (!miner) { return { success: false, message: 'Zombie miner not found!' }; } // Check if mine exists const mine = this.game.miningSystem.getMineInfo(mineId); if (!mine) { return { success: false, message: 'Mine not found!' }; } // Check if depth is unlocked const maxDepth = this.game.miningSystem.maxDepthReached || 0; if (depth > maxDepth) { return { success: false, message: `Must explore depth ${depth} first!` }; } // Assign miner miner.assignedMine = mineId; miner.assignedDepth = depth; // Update automation this.updateAutomationYield(); this.game.showMessage( `${miner.name} assigned to ${mine.name} - Depth ${depth}` ); return { success: true }; } /** * Unassign zombie miner (return to surface) */ unassignZombieMiner(minerId) { const miner = this.zombieMiners.find(m => m.id === minerId); if (!miner) { return { success: false }; } miner.assignedMine = null; miner.assignedDepth = 0; // Update automation this.updateAutomationYield(); this.game.showMessage( `${miner.name} returned to surface.` ); return { success: true }; } /** * Update total automation yield */ updateAutomationYield() { let totalYield = 0; this.zombieMiners.forEach(miner => { if (miner.assignedMine && miner.assignedDepth > 0) { // Base yield let hourlyYield = miner.yieldPerHour; // Depth bonus (+10% per 10 levels) const depthBonus = (miner.assignedDepth / 10) * 0.1; hourlyYield *= (1 + depthBonus); // Efficiency factor hourlyYield *= miner.efficiency; // Loyalty factor (50% loyalty = 0.5x yield, 100% = 1.5x yield) const loyaltyFactor = 0.5 + (miner.loyalty / 100); hourlyYield *= loyaltyFactor; // Equipment bonuses if (this.zombieEquipment.pickaxe_tier > 1) { hourlyYield *= (1 + (this.zombieEquipment.pickaxe_tier - 1) * 0.25); } if (this.zombieEquipment.cart) { hourlyYield *= 1.5; // 50% faster collection } totalYield += hourlyYield; } }); this.totalYieldPerHour = Math.floor(totalYield); this.automationActive = (totalYield > 0); } /** * Collect automated mining resources */ collectAutomatedYield() { if (!this.automationActive) { return { success: false, message: 'No zombie miners assigned!' }; } // Calculate time since last collection const hoursSinceLastCollection = this.getHoursSinceLastCollection(); if (hoursSinceLastCollection < 0.1) { return { success: false, message: 'Collected too recently! Wait a bit.' }; } const resources = {}; // Collect from each zombie this.zombieMiners.forEach(miner => { if (miner.assignedMine && miner.assignedDepth > 0) { // Get mine info const mine = this.game.miningSystem.getMineInfo(miner.assignedMine); // Determine ore type based on depth const oreType = this.getOreTypeForDepth(mine, miner.assignedDepth); // Calculate yield const hourlyYield = miner.yieldPerHour * miner.efficiency * (0.5 + miner.loyalty / 100); const amount = Math.floor(hourlyYield * hoursSinceLastCollection); if (amount > 0) { resources[oreType] = (resources[oreType] || 0) + amount; // Grant XP to miner miner.experience += amount; this.checkMinerLevelUp(miner); } } }); // Add resources to inventory let totalCollected = 0; for (const [ore, amount] of Object.entries(resources)) { this.player.inventory.addItem(ore, amount); totalCollected += amount; } // Update last collection time this.lastCollectionTime = this.game.time.currentTime; // Show collection message const resourceList = Object.entries(resources) .map(([ore, amount]) => `${amount}x ${ore}`) .join(', '); this.game.showMessage( `Collected: ${resourceList} (${hoursSinceLastCollection.toFixed(1)}h)` ); return { success: true, resources: resources, totalAmount: totalCollected, hours: hoursSinceLastCollection }; } /** * Get ore type based on mine and depth */ getOreTypeForDepth(mine, depth) { // Logic from mine zones if (depth <= 25) return 'copper_ore'; if (depth <= 50) return 'iron_ore'; if (depth <= 75) return 'gold_ore'; return 'diamond_ore'; } /** * Check if miner levels up */ checkMinerLevelUp(miner) { const xpRequired = miner.level * 100; if (miner.experience >= xpRequired) { miner.level++; miner.experience = 0; // Bonuses per level miner.yieldPerHour += 1; miner.efficiency += 0.05; this.game.showMessage( `${miner.name} leveled up! (Lv.${miner.level})` ); this.updateAutomationYield(); } } /** * Feed zombie miner (restore loyalty) */ feedZombieMiner(minerId, foodType) { const miner = this.zombieMiners.find(m => m.id === minerId); if (!miner) { return { success: false }; } // Check if player has food if (!this.player.inventory.hasItem(foodType)) { return { success: false, message: 'You don\'t have this food!' }; } // Remove food this.player.inventory.removeItem(foodType, 1); // Loyalty bonus based on food quality const loyaltyGain = this.getFoodLoyaltyValue(foodType); miner.loyalty = Math.min(100, miner.loyalty + loyaltyGain); this.game.showMessage( `${miner.name} ate ${foodType}. Loyalty +${loyaltyGain} (${miner.loyalty}/100)` ); // Update automation this.updateAutomationYield(); return { success: true, loyaltyGain: loyaltyGain }; } /** * Get food loyalty value */ getFoodLoyaltyValue(foodType) { const foodValues = { 'brain': 20, // Best food 'meat': 15, 'bread': 10, 'vegetables': 5 }; return foodValues[foodType] || 5; } /** * Upgrade zombie equipment */ upgradeEquipment(equipmentType) { const costs = { pickaxe_tier: 3000, helmet_lamp: 2000, oxygen_tank: 2500, cart: 4000 }; const cost = costs[equipmentType]; if (!cost) { return { success: false, message: 'Invalid equipment!' }; } // Check if already owned (except pickaxe tiers) if (equipmentType !== 'pickaxe_tier') { if (this.zombieEquipment[equipmentType]) { return { success: false, message: 'Already owned!' }; } } else { // Check pickaxe tier limit if (this.zombieEquipment.pickaxe_tier >= 5) { return { success: false, message: 'Pickaxe already max tier!' }; } } // Check money if (this.player.money < cost) { return { success: false, message: `Need ${cost}g!` }; } // Purchase this.player.money -= cost; if (equipmentType === 'pickaxe_tier') { this.zombieEquipment.pickaxe_tier++; } else { this.zombieEquipment[equipmentType] = true; } // Update automation this.updateAutomationYield(); this.game.showMessage( `Upgraded zombie equipment: ${equipmentType}! ${cost}g` ); return { success: true }; } /** * Get hours since last collection */ getHoursSinceLastCollection() { if (!this.lastCollectionTime) { this.lastCollectionTime = this.game.time.currentTime; return 0; } const secondsElapsed = this.game.time.currentTime - this.lastCollectionTime; return secondsElapsed / 3600; } /** * Get automation UI data */ getAutomationUIData() { return { zombieMiners: this.zombieMiners, maxZombieMiners: this.maxZombieMiners, totalYieldPerHour: this.totalYieldPerHour, automationActive: this.automationActive, equipment: this.zombieEquipment, canHireMore: this.zombieMiners.length < this.maxZombieMiners, hireCost: this.zombieMinerCost, hoursSinceCollection: this.getHoursSinceLastCollection() }; } /** * Update (passive decay of loyalty) */ update(deltaTime) { // Loyalty slowly decays if zombies are working this.zombieMiners.forEach(miner => { if (miner.assignedMine && miner.assignedDepth > 0) { // Lose 1 loyalty per hour worked const loyaltyLoss = (deltaTime / 3600); miner.loyalty = Math.max(0, miner.loyalty - loyaltyLoss); } }); // Recalculate if needed if (this.automationActive) { this.updateAutomationYield(); } } }