240 lines
8.3 KiB
JavaScript
240 lines
8.3 KiB
JavaScript
/**
|
|
* 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);
|
|
} else if (worker.workerData.type === 'CLEAR') {
|
|
this.performClearWork(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';
|
|
}
|
|
|
|
performClearWork(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);
|
|
const t = decor.type;
|
|
|
|
// Clear trees, bushes, logs, rocks
|
|
if (t.startsWith('tree') || t.startsWith('bush') || t === 'fallen_log' || t === 'stone' || t.startsWith('small_rock')) {
|
|
terrain.removeDecoration(wd.centerX + dx, wd.centerY + dy);
|
|
|
|
// Give some resources
|
|
if (this.scene.inventorySystem) {
|
|
if (t.startsWith('tree') || t === 'fallen_log' || t.startsWith('bush')) {
|
|
this.scene.inventorySystem.addItem('wood', 1);
|
|
} else {
|
|
this.scene.inventorySystem.addItem('stone', 1);
|
|
}
|
|
}
|
|
|
|
console.log(`🧟🪓 Worker CLEARED ${t}`);
|
|
wd.status = 'WORKING';
|
|
return; // One per tick
|
|
}
|
|
}
|
|
}
|
|
}
|
|
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;
|
|
}
|
|
}
|