phase 11 part1

This commit is contained in:
2025-12-08 12:30:15 +01:00
parent 3336b59e7d
commit 07f0752d81
15 changed files with 1383 additions and 133 deletions

View File

@@ -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;
}
}