phase 11 part1
This commit is contained in:
@@ -1,50 +1,202 @@
|
||||
/**
|
||||
* ZOMBIE WORKER AI SYSTEM
|
||||
* Tamed zombies lahko opravljajo delo (farming, mining)
|
||||
*/
|
||||
class ZombieWorkerSystem {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.workers = []; // Array of tamed zombies (NPC objects)
|
||||
|
||||
console.log('🧟 ZombieWorkerSystem: Initialized');
|
||||
this.workers = [];
|
||||
}
|
||||
|
||||
registerWorker(npc) {
|
||||
if (!this.workers.includes(npc)) {
|
||||
this.workers.push(npc);
|
||||
npc.workerStats = {
|
||||
energy: 100, // Energija (pada ob delu)
|
||||
decay: 0, // Razpadanje (0-100%, 100% = smrt)
|
||||
xp: 0, // Izkušnje zombija
|
||||
level: 1,
|
||||
task: 'IDLE' // IDLE, FARM, MINE, GUARD, FOLLOW
|
||||
};
|
||||
console.log(`🧟 Zombie ${this.workers.length} registered as Worker!`);
|
||||
assignWork(zombie, workType, workRadius = 5) {
|
||||
if (!zombie.isTamed) {
|
||||
console.warn('⚠️ Cannot assign work to untamed zombie!');
|
||||
return false;
|
||||
}
|
||||
|
||||
// UI Feedback
|
||||
this.scene.events.emit('show-floating-text', {
|
||||
x: npc.sprite.x,
|
||||
y: npc.sprite.y - 50,
|
||||
text: "New Worker!",
|
||||
color: "#00FF00"
|
||||
});
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
unregisterWorker(npc) {
|
||||
const idx = this.workers.indexOf(npc);
|
||||
if (idx > -1) {
|
||||
this.workers.splice(idx, 1);
|
||||
console.log('🧟 Zombie Worker removed.');
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update(time, delta) {
|
||||
// Update logic for all workers (e.g. decay, energy regen if sleeping)
|
||||
// This is called every frame, so keep it light.
|
||||
applyDecay(zombie, delta) {
|
||||
const wd = zombie.workerData;
|
||||
wd.energy -= (wd.decayRate * delta) / 1000;
|
||||
|
||||
// Example: Decay tick every 10 seconds (handled by timer, or simplified here)
|
||||
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);
|
||||
}
|
||||
|
||||
// Assign a task to all idle workers or specific one
|
||||
assignTask(taskName, targetPos) {
|
||||
// TODO: Poišči prostega delavca in mu daj nalogo
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user