/** * ZOMBIE WORKER AI SYSTEM * Tamed zombies lahko opravljajo delo (farming, mining) */ class ZombieWorkerSystem { constructor(scene) { this.scene = scene; this.workers = []; } assignWork(zombie, workType, workRadius = 5) { if (!zombie.isTamed) { console.warn('⚠️ Cannot assign work to untamed zombie!'); return false; } zombie.workerData = { type: workType, radius: workRadius, centerX: zombie.gridX, centerY: zombie.gridY, energy: 100, decayRate: 0.5, workTimer: 0, workInterval: 5000, status: 'IDLE', inventory: { seeds: 0, hoe: 0, watering_can: 0, pickaxe: 0 } }; this.workers.push(zombie); console.log(`🧟 Assigned ${zombie.type} as ${workType} worker`); return true; } removeWorker(zombie) { const index = this.workers.indexOf(zombie); if (index > -1) { this.workers.splice(index, 1); zombie.workerData = null; } } update(delta) { this.workers = this.workers.filter(w => this.scene.npcs.includes(w) && w.hp > 0 ); for (const worker of this.workers) { if (!worker.workerData) continue; this.applyDecay(worker, delta); worker.workerData.workTimer += delta; if (worker.workerData.workTimer >= worker.workerData.workInterval) { worker.workerData.workTimer = 0; if (worker.workerData.type === 'FARM') { this.performFarmWork(worker); } else if (worker.workerData.type === 'MINE') { this.performMineWork(worker); } } } } applyDecay(zombie, delta) { const wd = zombie.workerData; wd.energy -= (wd.decayRate * delta) / 1000; if (wd.energy <= 0) { wd.energy = 0; zombie.hp -= (wd.decayRate * delta) / 1000; if (zombie.sprite) zombie.sprite.setTint(0x666666); } if (zombie.hp <= 0) this.onWorkerDeath(zombie); } performFarmWork(zombie) { const wd = zombie.workerData; const terrain = this.scene.terrainSystem; const farming = this.scene.farmingSystem; if (!terrain || !farming) return; // 1. Water/Harvest existing crops if (terrain.cropsMap) { for (let dx = -wd.radius; dx <= wd.radius; dx++) { for (let dy = -wd.radius; dy <= wd.radius; dy++) { const key = `${wd.centerX + dx},${wd.centerY + dy}`; if (terrain.cropsMap.has(key)) { const crop = terrain.cropsMap.get(key); if (!crop.isWatered) { farming.waterCrop(wd.centerX + dx, wd.centerY + dy); console.log(`🧟💧 Worker watered`); wd.status = 'WORKING'; return; } if (crop.stage >= 4) { farming.harvest(wd.centerX + dx, wd.centerY + dy); console.log(`🧟🌾 Worker harvested`); wd.status = 'WORKING'; return; } } } } } // 2. Plant on empty tilled soil (if has seeds) if (wd.inventory.seeds > 0) { for (let dx = -wd.radius; dx <= wd.radius; dx++) { for (let dy = -wd.radius; dy <= wd.radius; dy++) { const tile = terrain.getTile(wd.centerX + dx, wd.centerY + dy); if (tile && tile.isTilled && !tile.hasCrop) { farming.plant(wd.centerX + dx, wd.centerY + dy, 'wheat'); wd.inventory.seeds--; console.log(`🧟🌱 Worker planted (Seeds: ${wd.inventory.seeds})`); wd.status = 'WORKING'; return; } } } } // 3. Till grass/dirt for (let dx = -wd.radius; dx <= wd.radius; dx++) { for (let dy = -wd.radius; dy <= wd.radius; dy++) { const tile = terrain.getTile(wd.centerX + dx, wd.centerY + dy); const typeName = tile?.type?.name || tile?.type; if ((typeName === 'grass' || typeName === 'dirt') && !tile.isTilled) { tile.isTilled = true; if (tile.sprite) tile.sprite.setTint(0x8B4513); console.log(`🧟🔨 Worker tilled soil`); wd.status = 'WORKING'; return; } } } wd.status = 'IDLE'; } performMineWork(zombie) { const wd = zombie.workerData; const terrain = this.scene.terrainSystem; if (!terrain || !terrain.decorationsMap) return; for (let dx = -wd.radius; dx <= wd.radius; dx++) { for (let dy = -wd.radius; dy <= wd.radius; dy++) { const key = `${wd.centerX + dx},${wd.centerY + dy}`; if (terrain.decorationsMap.has(key)) { const decor = terrain.decorationsMap.get(key); if (decor.type === 'stone' || decor.type.includes('rock')) { terrain.removeDecoration(wd.centerX + dx, wd.centerY + dy); if (this.scene.inventorySystem) { this.scene.inventorySystem.addItem('stone', 1); } console.log(`🧟⛏️ Worker mined stone`); wd.status = 'WORKING'; return; } } } } wd.status = 'IDLE'; } onWorkerDeath(zombie) { console.log(`💀 Worker died at ${zombie.gridX},${zombie.gridY}`); if (this.scene.interactionSystem && this.scene.interactionSystem.spawnLoot) { this.scene.interactionSystem.spawnLoot(zombie.gridX, zombie.gridY, 'fertilizer', 1); } if (this.scene.statsSystem) { this.scene.statsSystem.addXP(10); } this.removeWorker(zombie); } feedWorker(zombie, amount = 50) { if (!zombie.workerData) return false; zombie.workerData.energy = Math.min(100, zombie.workerData.energy + amount); if (zombie.sprite) zombie.sprite.clearTint(); console.log(`🍖 Fed worker`); return true; } }