This commit is contained in:
2025-12-07 21:31:44 +01:00
parent 4a0ca267ea
commit 974141c08c
52 changed files with 2485 additions and 397 deletions

View File

@@ -242,6 +242,8 @@ class NPC {
handlePassiveAI(delta) {
if (this.state === 'TAMED' || this.state === 'FOLLOW') {
// Defensive behavior - attack nearby enemy zombies
this.defendPlayer();
this.followPlayer();
return;
}
@@ -253,6 +255,56 @@ class NPC {
}
}
defendPlayer() {
if (!this.scene.npcs || this.attackCooldownTimer > 0) return;
// Find nearest enemy zombie
let nearestEnemy = null;
let minDist = 6; // Defense radius
for (const npc of this.scene.npcs) {
if (npc === this || npc.state === 'TAMED' || npc.state === 'FOLLOW') continue;
if (npc.type !== 'zombie') continue;
const dist = Phaser.Math.Distance.Between(this.gridX, this.gridY, npc.gridX, npc.gridY);
if (dist < minDist) {
minDist = dist;
nearestEnemy = npc;
}
}
if (nearestEnemy) {
// Attack if close enough
if (minDist <= 1.5) {
this.attackEnemy(nearestEnemy);
} else {
// Move towards enemy
this.moveTowards(nearestEnemy.gridX, nearestEnemy.gridY);
}
}
}
attackEnemy(target) {
if (this.attackCooldownTimer > 0) return;
this.attackCooldownTimer = 1500;
console.log('🧟❤️ Tamed Zombie DEFENDS!');
// Attack Animation
if (this.sprite) {
this.scene.tweens.add({
targets: this.sprite,
y: this.sprite.y - 10,
yoyo: true, duration: 100, repeat: 1
});
}
// Deal Damage
if (target && target.takeDamage) {
target.takeDamage(15); // Tamed zombies hit harder!
}
}
handleAggressiveAI(delta) {
if (!this.scene.player) return;
@@ -289,6 +341,49 @@ class NPC {
}
moveTowards(targetX, targetY) {
// Optimization: if very close, use direct movement (collision checks handled by isValidMove)
const dist = Phaser.Math.Distance.Between(this.gridX, this.gridY, targetX, targetY);
// Use pathfinding for longer distances
if (dist > 2 && this.scene.pathfinding) {
// Check if we need to recalc path (target changed or no path)
const targetKey = `${targetX},${targetY}`;
if (!this.currentPath || this.pathTargetKey !== targetKey || this.currentPath.length === 0) {
// Recalc path (Async Worker)
if (!this.isWaitingForPath) {
this.isWaitingForPath = true;
this.scene.pathfinding.findPath(this.gridX, this.gridY, targetX, targetY, (path) => {
this.isWaitingForPath = false;
this.currentPath = path;
this.pathTargetKey = targetKey;
// Process path once received
if (this.currentPath && this.currentPath.length > 0) {
// Remove start node if it's current pos
if (this.currentPath[0].x === this.gridX && this.currentPath[0].y === this.gridY) {
this.currentPath.shift();
}
}
});
} else {
return; // Wait for path
}
}
// Follow Path
if (this.currentPath && this.currentPath.length > 0) {
const step = this.currentPath[0];
// Move there
this.moveToGrid(step.x, step.y);
// Remove step
this.currentPath.shift();
return;
}
}
// Fallback: Direct Movement (Dumb AI)
const dx = Math.sign(targetX - this.gridX);
const dy = Math.sign(targetY - this.gridY);
let nextX = this.gridX + dx;
@@ -415,6 +510,16 @@ class NPC {
takeDamage(amount) {
this.hp -= amount;
// Hit Sound
if (this.scene.soundManager) {
this.scene.soundManager.playHit();
}
// Blood Splash Effect
if (this.scene.particleEffects) {
this.scene.particleEffects.bloodSplash(this.sprite.x, this.sprite.y - 20);
}
// Show Health Bar
if (this.healthBar) {
this.healthBar.setVisible(true);
@@ -449,6 +554,12 @@ class NPC {
die() {
console.log('🧟💀 Zombie DEAD');
// Death Sound
if (this.scene.soundManager) {
this.scene.soundManager.playDeath();
}
// Spawn loot - BONE
if (this.scene.lootSystem) {
this.scene.lootSystem.spawnLoot(this.gridX, this.gridY, 'item_bone');
@@ -456,6 +567,12 @@ class NPC {
// Fallback
this.scene.interactionSystem.spawnLoot(this.gridX, this.gridY, 'item_bone');
}
// Quest Tracking (Kill)
if (this.scene.questSystem) {
this.scene.questSystem.trackAction(this.type);
}
this.destroy();
const idx = this.scene.npcs.indexOf(this);
@@ -496,6 +613,33 @@ class NPC {
this.addTamedEyes();
}
interact() {
console.log('🗣️ Inteacting with NPC:', this.type);
// Quest Check
if (this.scene.questSystem) {
const availableQuest = this.scene.questSystem.getAvailableQuest(this.type);
if (availableQuest) {
console.log('Quest Available from NPC!');
// Open Dialog UI
const ui = this.scene.scene.get('UIScene');
if (ui && ui.showQuestDialog) {
ui.showQuestDialog(availableQuest, () => {
this.scene.questSystem.startQuest(availableQuest.id);
});
return;
}
}
}
// Default behavior (Emote)
this.showEmote('👋');
// Small jump or animation?
if (this.sprite) {
this.scene.tweens.add({ targets: this.sprite, y: this.sprite.y - 10, yoyo: true, duration: 100 });
}
}
addTamedEyes() {
if (this.eyesGroup) return;