/** * SMART ZOMBIE SYSTEM * Manages zombie intelligence levels (Lv1-10), independent AI, follower commands, and team construction. * * Features: * - Lv1-4: Helpers (resource finding, carry materials, warn danger) * - Lv5-7: Assistants (repair assistance +25% speed, material delivery AI) * - Lv8-10: INDEPENDENT AI (build/repair alone, auto-detect damage, teach others) * - Follower System: 10 zombie followers with commands (Stop, Help, Attack, Home) * - Team Construction: Lv10 leader + multi-zombie mega-projects */ class SmartZombieSystem { constructor(scene) { this.scene = scene; // Zombie intelligence data this.zombies = new Map(); // zombieId -> zombie data this.followers = []; // Active followers (max 10) this.independentWorkers = []; // Lv8+ zombies working autonomously this.teams = []; // Construction teams (Lv10 leader + team) // Commands this.followerCommands = ['STOP', 'HELP', 'ATTACK', 'HOME']; this.currentCommand = 'HELP'; // Default command // AI Task Queue this.taskQueue = []; // {type, position, priority, assignedZombie} // Intelligence Levels this.intelligenceLevels = { 1: { name: 'Curious', abilities: ['ping_resources', 'carry_light'] }, 2: { name: 'Aware', abilities: ['carry_medium', 'warn_danger'] }, 3: { name: 'Helper', abilities: ['gather_resources', 'follow_player'] }, 4: { name: 'Assistant', abilities: ['detect_ores', 'organize_storage'] }, 5: { name: 'Skilled', abilities: ['repair_assist', 'deliver_materials'] }, 6: { name: 'Expert', abilities: ['craft_assist', 'defend_farm'] }, 7: { name: 'Advanced', abilities: ['build_assist', 'teach_lv1_3'] }, 8: { name: 'INDEPENDENT', abilities: ['build_alone', 'repair_alone', 'auto_detect_damage'] }, 9: { name: 'MASTER', abilities: ['teach_all', 'lead_team', 'optimize_tasks'] }, 10: { name: 'GENIUS', abilities: ['mega_projects', 'invent_blueprints', 'immortal_knowledge'] } }; console.log('🧠 Smart Zombie System initialized!'); } /** * Create or upgrade a zombie */ createZombie(name, level = 1, position = { x: 0, y: 0 }) { const zombieId = `zombie_${Date.now()}_${Math.random()}`; const zombie = { id: zombieId, name: name, level: Math.min(level, 10), position: position, status: 'idle', // idle, working, following, patrolling currentTask: null, experience: 0, experienceToNext: this.getExpRequired(level), abilities: this.getAbilities(level), inventory: [], loyalty: 50, // 0-100 energy: 100, // 0-100 sprite: null // Will be set when rendered }; this.zombies.set(zombieId, zombie); console.log(`🧟 Created ${name} (Lv${level}) - ${this.intelligenceLevels[level].name}`); // Auto-assign if Lv8+ if (level >= 8) { this.makeIndependent(zombieId); } return zombieId; } /** * Get required XP for next level */ getExpRequired(level) { return 100 * level * level; // 100, 400, 900, 1600, etc. } /** * Get abilities for a level */ getAbilities(level) { const abilities = []; for (let i = 1; i <= level; i++) { abilities.push(...this.intelligenceLevels[i].abilities); } return [...new Set(abilities)]; // Remove duplicates } /** * Add experience to a zombie */ addExperience(zombieId, amount) { const zombie = this.zombies.get(zombieId); if (!zombie) return; zombie.experience += amount; // Level up? while (zombie.experience >= zombie.experienceToNext && zombie.level < 10) { zombie.level++; zombie.experience -= zombie.experienceToNext; zombie.experienceToNext = this.getExpRequired(zombie.level + 1); zombie.abilities = this.getAbilities(zombie.level); console.log(`⬆️ ${zombie.name} leveled up to Lv${zombie.level}!`); this.scene.events.emit('show-floating-text', { x: zombie.position.x, y: zombie.position.y - 50, text: `LEVEL UP! Lv${zombie.level}`, color: '#FFD700' }); // Auto-assign if reached Lv8 if (zombie.level === 8) { this.makeIndependent(zombieId); } } } /** * Make a zombie independent (Lv8+) */ makeIndependent(zombieId) { const zombie = this.zombies.get(zombieId); if (!zombie || zombie.level < 8) return false; if (!this.independentWorkers.includes(zombieId)) { this.independentWorkers.push(zombieId); zombie.status = 'independent'; console.log(`🤖 ${zombie.name} is now INDEPENDENT!`); this.scene.events.emit('notification', { title: 'Independent Worker!', message: `${zombie.name} can now work autonomously!`, icon: '🤖' }); } return true; } /** * Add zombie to follower group (max 10) */ addFollower(zombieId) { if (this.followers.length >= 10) { console.log('❌ Maximum 10 followers!'); return false; } const zombie = this.zombies.get(zombieId); if (!zombie) return false; if (!this.followers.includes(zombieId)) { this.followers.push(zombieId); zombie.status = 'following'; console.log(`➕ ${zombie.name} joined your followers!`); return true; } return false; } /** * Remove zombie from followers */ removeFollower(zombieId) { const index = this.followers.indexOf(zombieId); if (index > -1) { this.followers.splice(index, 1); const zombie = this.zombies.get(zombieId); if (zombie) { zombie.status = 'idle'; console.log(`➖ ${zombie.name} left your followers.`); } return true; } return false; } /** * Send command to all followers */ commandFollowers(command) { if (!this.followerCommands.includes(command)) { console.log(`❌ Invalid command: ${command}`); return; } this.currentCommand = command; this.followers.forEach(zombieId => { const zombie = this.zombies.get(zombieId); if (!zombie) return; switch (command) { case 'STOP': zombie.status = 'idle'; zombie.currentTask = null; break; case 'HELP': zombie.status = 'helping'; this.assignHelpTask(zombieId); break; case 'ATTACK': zombie.status = 'combat'; this.assignCombatTask(zombieId); break; case 'HOME': zombie.status = 'returning'; this.sendHome(zombieId); break; } }); console.log(`📢 Commanded ${this.followers.length} followers: ${command}`); this.scene.events.emit('notification', { title: 'Follower Command', message: `${this.followers.length} zombies: ${command}`, icon: '📢' }); } /** * Assign help task (gather, repair, build) */ assignHelpTask(zombieId) { const zombie = this.zombies.get(zombieId); if (!zombie) return; // Find nearest task from queue const task = this.findNearestTask(zombie.position); if (task) { zombie.currentTask = task; task.assignedZombie = zombieId; console.log(`🛠️ ${zombie.name} assigned to ${task.type}`); } else { // Follow player and gather resources zombie.currentTask = { type: 'gather', target: 'player' }; } } /** * Assign combat task */ assignCombatTask(zombieId) { const zombie = this.zombies.get(zombieId); if (!zombie) return; zombie.currentTask = { type: 'defend', target: 'player', radius: 200 }; console.log(`⚔️ ${zombie.name} defending!`); } /** * Send zombie home */ sendHome(zombieId) { const zombie = this.zombies.get(zombieId); if (!zombie) return; zombie.currentTask = { type: 'return_home', target: { x: 0, y: 0 } }; console.log(`🏠 ${zombie.name} returning home.`); } /** * Find nearest task for zombie */ findNearestTask(position) { if (this.taskQueue.length === 0) return null; let nearest = null; let minDist = Infinity; this.taskQueue.forEach(task => { if (task.assignedZombie) return; // Already assigned const dist = Phaser.Math.Distance.Between( position.x, position.y, task.position.x, task.position.y ); if (dist < minDist) { minDist = dist; nearest = task; } }); return nearest; } /** * Add task to queue */ addTask(type, position, priority = 1) { const task = { id: `task_${Date.now()}`, type: type, // 'build', 'repair', 'gather', 'mine' position: position, priority: priority, assignedZombie: null, progress: 0, required: 100 }; this.taskQueue.push(task); // Auto-assign to independent workers this.autoAssignIndependentWorkers(); return task.id; } /** * Auto-assign tasks to independent workers (Lv8+) */ autoAssignIndependentWorkers() { this.independentWorkers.forEach(zombieId => { const zombie = this.zombies.get(zombieId); if (!zombie || zombie.currentTask) return; const task = this.findNearestTask(zombie.position); if (task && zombie.abilities.includes('build_alone') || zombie.abilities.includes('repair_alone')) { zombie.currentTask = task; task.assignedZombie = zombieId; console.log(`🤖 Independent: ${zombie.name} auto-assigned to ${task.type}`); } }); } /** * Create construction team (Lv10 leader required) */ createTeam(leaderZombieId, memberZombieIds) { const leader = this.zombies.get(leaderZombieId); if (!leader || leader.level < 10) { console.log('❌ Team leader must be Lv10!'); return null; } const members = memberZombieIds .map(id => this.zombies.get(id)) .filter(z => z && z.level >= 5); if (members.length === 0) { console.log('❌ Need at least 1 Lv5+ member!'); return null; } const teamId = `team_${Date.now()}`; const team = { id: teamId, leader: leaderZombieId, members: memberZombieIds, status: 'ready', currentProject: null, efficiency: 1.0 + (members.length * 0.15) // +15% per member }; this.teams.push(team); console.log(`👥 Team created! Leader: ${leader.name}, Members: ${members.length}, Efficiency: ${team.efficiency}x`); this.scene.events.emit('notification', { title: 'Team Created!', message: `${leader.name}'s team (${members.length} members) is ready!`, icon: '👥' }); return teamId; } /** * Assign mega-project to team */ assignMegaProject(teamId, projectType, position) { const team = this.teams.find(t => t.id === teamId); if (!team) return false; const project = { type: projectType, // 'mega_barn', 'fortress', 'factory' position: position, progress: 0, required: 1000, // Mega projects take time efficiency: team.efficiency }; team.currentProject = project; team.status = 'working'; console.log(`🏗️ Team assigned to ${projectType}! Efficiency: ${team.efficiency}x`); return true; } /** * Update all zombies (called every frame) */ update(delta) { // Update followers this.followers.forEach(zombieId => { const zombie = this.zombies.get(zombieId); if (!zombie) return; this.updateZombie(zombie, delta); }); // Update independent workers this.independentWorkers.forEach(zombieId => { const zombie = this.zombies.get(zombieId); if (!zombie) return; this.updateZombie(zombie, delta); }); // Update teams this.teams.forEach(team => { if (team.status === 'working' && team.currentProject) { team.currentProject.progress += delta * 0.01 * team.efficiency; if (team.currentProject.progress >= team.currentProject.required) { this.completeMegaProject(team); } } }); } /** * Update individual zombie */ updateZombie(zombie, delta) { if (!zombie.currentTask) return; const task = zombie.currentTask; switch (task.type) { case 'build': case 'repair': this.progressTask(zombie, task, delta); break; case 'gather': this.gatherResources(zombie, delta); break; case 'defend': this.defendArea(zombie); break; case 'return_home': this.moveToHome(zombie); break; } // Drain energy zombie.energy = Math.max(0, zombie.energy - delta * 0.001); } /** * Progress on a task */ progressTask(zombie, task, delta) { const speedBonus = zombie.level >= 5 ? 1.25 : 1.0; task.progress += delta * 0.02 * speedBonus; if (task.progress >= task.required) { this.completeTask(zombie, task); } } /** * Complete a task */ completeTask(zombie, task) { console.log(`✅ ${zombie.name} completed ${task.type}!`); // Award XP this.addExperience(zombie.id, 50 + (task.priority * 10)); // Remove from queue const index = this.taskQueue.indexOf(task); if (index > -1) { this.taskQueue.splice(index, 1); } zombie.currentTask = null; // Find next task if independent if (zombie.status === 'independent') { this.autoAssignIndependentWorkers(); } } /** * Gather resources */ gatherResources(zombie, delta) { // Simple resource gathering simulation if (Math.random() < 0.01) { const resources = ['wood', 'stone', 'iron_ore']; const resource = resources[Math.floor(Math.random() * resources.length)]; zombie.inventory.push(resource); console.log(`📦 ${zombie.name} gathered ${resource}`); } } /** * Defend area around player/target */ defendArea(zombie) { // Detect nearby enemies (placeholder) // In real game, would check for hostile entities } /** * Move zombie to home position */ moveToHome(zombie) { const target = zombie.currentTask.target; const dist = Phaser.Math.Distance.Between( zombie.position.x, zombie.position.y, target.x, target.y ); if (dist < 10) { zombie.status = 'idle'; zombie.currentTask = null; console.log(`🏠 ${zombie.name} arrived home.`); } else { // Move toward home (simplified) const angle = Phaser.Math.Angle.Between( zombie.position.x, zombie.position.y, target.x, target.y ); zombie.position.x += Math.cos(angle) * 2; zombie.position.y += Math.sin(angle) * 2; } } /** * Complete mega-project */ completeMegaProject(team) { console.log(`🏆 Mega-project ${team.currentProject.type} COMPLETE!`); const leader = this.zombies.get(team.leader); if (leader) { this.addExperience(leader.id, 500); } team.members.forEach(memberId => { this.addExperience(memberId, 200); }); this.scene.events.emit('notification', { title: 'Mega-Project Complete!', message: `${team.currentProject.type} is finished!`, icon: '🏆' }); team.currentProject = null; team.status = 'ready'; } /** * Get zombie stats */ getZombieStats(zombieId) { const zombie = this.zombies.get(zombieId); if (!zombie) return null; return { name: zombie.name, level: zombie.level, intelligence: this.intelligenceLevels[zombie.level].name, abilities: zombie.abilities, status: zombie.status, energy: Math.round(zombie.energy), loyalty: zombie.loyalty, experience: `${zombie.experience}/${zombie.experienceToNext}`, inventory: zombie.inventory.length }; } }