This commit is contained in:
2025-12-08 00:18:56 +01:00
parent b36cc981d6
commit 7834aee111
10 changed files with 466 additions and 43 deletions

View File

@@ -24,8 +24,17 @@ class NPC {
this.pauseTime = 0;
this.maxPauseTime = 2000;
this.attackCooldownTimer = 0;
this.hp = 20;
this.maxHp = 20;
// Elite Zombie Stats
if (type === 'elite_zombie') {
this.hp = 50; // 2.5x več HP
this.maxHp = 50;
this.moveSpeed = 150; // 50% hitrejši
this.gridMoveTime = 200; // Hitrejši premiki
} else {
this.hp = 20;
this.maxHp = 20;
}
// Kreira sprite
this.createSprite();
@@ -128,6 +137,14 @@ class NPC {
texKey = 'merchant_texture'; // Fallback na proceduralno
}
console.log('🏪 Creating MERCHANT NPC with texture:', texKey);
} else if (this.type === 'elite_zombie') {
// Elite Zombie sprite
if (this.scene.textures.exists('elite_zombie')) {
texKey = 'elite_zombie';
} else {
texKey = 'npc_elite_zombie'; // Fallback na proceduralno
}
console.log('👹 Creating ELITE ZOMBIE with texture:', texKey);
} else if (!this.scene.textures.exists(texKey)) {
TextureGenerator.createNPCSprite(this.scene, texKey, this.type);
}
@@ -144,8 +161,10 @@ class NPC {
if (isAnimated) {
this.sprite.setScale(1.5);
} else {
// Merchant manjši, ostali večji
const scale = (this.type === 'merchant') ? 0.2 : 0.5;
// Scale po tipu
let scale = 0.5; // Default
if (this.type === 'merchant') scale = 0.2;
else if (this.type === 'elite_zombie') scale = 0.2; // Elite manjši
this.sprite.setScale(scale);
}
@@ -206,7 +225,27 @@ class NPC {
}
update(delta) {
// 1. Distance Culling
// 1. Viewport Culling - če sprite ni viden na kameri, preskoči risanje
const camera = this.scene.cameras.main;
if (camera && this.sprite) {
const worldView = camera.worldView;
const isVisible = Phaser.Geom.Rectangle.Overlaps(worldView, this.sprite.getBounds());
if (!isVisible && this.sprite.visible) {
this.sprite.setVisible(false);
if (this.healthBar) {
this.healthBar.setVisible(false);
this.healthBarBg.setVisible(false);
}
if (this.eyesGroup) this.eyesGroup.setVisible(false);
return; // Preskoči AI če ni viden
} else if (isVisible && !this.sprite.visible) {
this.sprite.setVisible(true);
if (this.eyesGroup) this.eyesGroup.setVisible(true);
}
}
// 2. Distance Culling
if (this.scene.player) {
const playerPos = this.scene.player.getPosition();
const dist = Phaser.Math.Distance.Between(this.gridX, this.gridY, playerPos.x, playerPos.y);
@@ -231,7 +270,7 @@ class NPC {
}
}
// 2. Optimization: Update depth ONLY if moving
// 3. Optimization: Update depth ONLY if moving
if (this.isMoving) {
this.updateDepth();
this.updatePosition();
@@ -544,19 +583,73 @@ class NPC {
this.healthBar.fillRect(-16, -70, 32 * percent, 4);
}
// WHITE FLASH Effect
if (this.sprite) {
this.sprite.setTint(0xff0000);
this.scene.time.delayedCall(100, () => {
this.sprite.setTint(0xFFFFFF); // White flash
this.scene.time.delayedCall(50, () => {
if (this.sprite) {
this.sprite.clearTint();
// Re-apply tamed tint if tamed
if (this.state === 'TAMED' || this.state === 'FOLLOW' || this.state === 'STAY') {
this.sprite.setTint(0xAAFFAA);
}
this.sprite.setTint(0xFF0000); // Red flash
this.scene.time.delayedCall(50, () => {
if (this.sprite) {
this.sprite.clearTint();
if (this.state === 'TAMED' || this.state === 'FOLLOW' || this.state === 'STAY') {
this.sprite.setTint(0xAAFFAA);
}
}
});
}
});
}
// KNOCKBACK Effect
if (this.sprite && this.scene.player) {
const knockbackDist = 10;
const angle = Phaser.Math.Angle.Between(
this.scene.player.sprite.x,
this.scene.player.sprite.y,
this.sprite.x,
this.sprite.y
);
const knockX = Math.cos(angle) * knockbackDist;
const knockY = Math.sin(angle) * knockbackDist;
this.scene.tweens.add({
targets: this.sprite,
x: this.sprite.x + knockX,
y: this.sprite.y + knockY,
duration: 100,
yoyo: true,
ease: 'Quad.easeOut'
});
}
// FLOATING DAMAGE NUMBERS
if (this.sprite) {
const dmgTxt = this.scene.add.text(
this.sprite.x,
this.sprite.y - 40,
`-${amount}`,
{
fontSize: '16px',
fontFamily: 'Courier New',
color: '#FF0000',
stroke: '#000',
strokeThickness: 3,
fontStyle: 'bold'
}
);
dmgTxt.setOrigin(0.5);
dmgTxt.setDepth(999999);
this.scene.tweens.add({
targets: dmgTxt,
y: dmgTxt.y - 30,
alpha: 0,
duration: 800,
ease: 'Cubic.easeOut',
onComplete: () => dmgTxt.destroy()
});
}
console.log(`Zombie HP: ${this.hp}`);
if (this.hp <= 0) {
@@ -572,12 +665,19 @@ class NPC {
this.scene.soundManager.playDeath();
}
// Spawn loot - BONE
// Spawn loot - Elite zombies drop better items!
if (this.scene.lootSystem) {
this.scene.lootSystem.spawnLoot(this.gridX, this.gridY, 'item_bone');
const lootItem = (this.type === 'elite_zombie') ? 'item_scrap' : 'item_bone';
this.scene.lootSystem.spawnLoot(this.gridX, this.gridY, lootItem);
// Elite bonus: 50% chance for extra chip
if (this.type === 'elite_zombie' && Math.random() < 0.5) {
this.scene.lootSystem.spawnLoot(this.gridX, this.gridY, 'item_chip');
}
} else if (this.scene.interactionSystem && this.scene.interactionSystem.spawnLoot) {
// Fallback
this.scene.interactionSystem.spawnLoot(this.gridX, this.gridY, 'item_bone');
const lootItem = (this.type === 'elite_zombie') ? 'item_scrap' : 'item_bone';
this.scene.interactionSystem.spawnLoot(this.gridX, this.gridY, lootItem);
}
// Quest Tracking (Kill)