/** * HordeWaveSystem.js * ================== * KRVAVA Ε½ETEV - Horde Mode Wave Manager * * Features: * - Wave spawning system * - Difficulty scaling * - Enemy type pools * - Boss waves * - Rewards * * @author NovaFarma Team * @date 2025-12-23 */ export default class HordeWaveSystem { constructor(scene) { this.scene = scene; // Wave state this.currentWave = 0; this.isWaveActive = false; this.waveStartTime = 0; this.enemiesRemaining = 0; this.enemiesKilled = 0; // Spawn points this.spawnPoints = []; this.spawnRadius = 500; // Pixels from player // Wave definitions this.waves = []; // Statistics this.stats = { totalWavesCompleted: 0, totalEnemiesKilled: 0, highestWave: 0, totalRewards: 0 }; console.log('🌊 HordeWaveSystem initialized'); // Generate wave definitions this.generateWaves(); } /** * Generate infinite wave definitions */ generateWaves() { // Pre-generate 100 waves (can generate more on-demand) for (let i = 1; i <= 100; i++) { this.waves.push(this.generateWave(i)); } console.log(`βœ… Generated ${this.waves.length} wave definitions`); } /** * Generate single wave definition */ generateWave(waveNumber) { const wave = { number: waveNumber, enemies: [], isBossWave: waveNumber % 10 === 0, // Every 10th wave is boss rewards: { zlatniki: 10 * waveNumber, xp: 50 * waveNumber, items: [] } }; // Boss wave if (wave.isBossWave) { wave.enemies = this.generateBossWave(waveNumber); } else { // Normal wave wave.enemies = this.generateNormalWave(waveNumber); } return wave; } /** * Generate normal wave enemies */ generateNormalWave(waveNumber) { const enemies = []; // Base enemy count scales with wave const baseCount = 5 + Math.floor(waveNumber * 1.5); // Enemy types unlock progressively const availableTypes = this.getAvailableEnemyTypes(waveNumber); for (let i = 0; i < baseCount; i++) { const enemyType = Phaser.Utils.Array.GetRandom(availableTypes); const enemy = { type: enemyType.id, health: enemyType.baseHealth * (1 + waveNumber * 0.1), // +10% HP per wave damage: enemyType.baseDamage * (1 + waveNumber * 0.05), // +5% damage per wave speed: enemyType.baseSpeed, spawnDelay: i * 500 // Stagger spawns }; enemies.push(enemy); } return enemies; } /** * Generate boss wave */ generateBossWave(waveNumber) { const enemies = []; // Boss const bossLevel = Math.floor(waveNumber / 10); const boss = { type: 'boss_zombie', health: 1000 * bossLevel, damage: 50 * bossLevel, speed: 80, isBoss: true, spawnDelay: 0 }; enemies.push(boss); // Add minions (scales with boss level) const minionCount = 5 + (bossLevel * 2); for (let i = 0; i < minionCount; i++) { const minion = { type: 'elite_zombie', health: 200 * bossLevel, damage: 20 * bossLevel, speed: 120, spawnDelay: 1000 + (i * 500) }; enemies.push(minion); } return enemies; } /** * Get available enemy types for wave */ getAvailableEnemyTypes(waveNumber) { const types = [ // Tier 1: Waves 1-5 { id: 'basic_zombie', tier: 1, baseHealth: 100, baseDamage: 10, baseSpeed: 80 }, { id: 'crawler_zombie', tier: 1, baseHealth: 80, baseDamage: 15, baseSpeed: 100 }, // Tier 2: Waves 6-15 { id: 'runner_zombie', tier: 2, baseHealth: 120, baseDamage: 12, baseSpeed: 150 }, { id: 'spitter_zombie', tier: 2, baseHealth: 90, baseDamage: 20, baseSpeed: 70 }, // Tier 3: Waves 16-30 { id: 'tank_zombie', tier: 3, baseHealth: 300, baseDamage: 25, baseSpeed: 60 }, { id: 'exploder_zombie', tier: 3, baseHealth: 150, baseDamage: 50, baseSpeed: 90 }, // Tier 4: Waves 31-50 { id: 'mutant_zombie', tier: 4, baseHealth: 500, baseDamage: 40, baseSpeed: 110 }, { id: 'alpha_zombie', tier: 4, baseHealth: 800, baseDamage: 60, baseSpeed: 100 }, // Tier 5: Waves 51+ { id: 'nightmare_zombie', tier: 5, baseHealth: 1200, baseDamage: 80, baseSpeed: 130 }, { id: 'omega_zombie', tier: 5, baseHealth: 2000, baseDamage: 100, baseSpeed: 120 } ]; // Filter by tier let availableTier = 1; if (waveNumber >= 51) availableTier = 5; else if (waveNumber >= 31) availableTier = 4; else if (waveNumber >= 16) availableTier = 3; else if (waveNumber >= 6) availableTier = 2; return types.filter(t => t.tier <= availableTier); } /** * Start wave */ startWave(waveNumber = null) { if (this.isWaveActive) { console.log('⚠️ Wave already active!'); return false; } // Use next wave if not specified if (waveNumber === null) { waveNumber = this.currentWave + 1; } // Generate more waves if needed if (waveNumber > this.waves.length) { for (let i = this.waves.length + 1; i <= waveNumber; i++) { this.waves.push(this.generateWave(i)); } } const wave = this.waves[waveNumber - 1]; if (!wave) { console.error(`Wave ${waveNumber} not found!`); return false; } this.currentWave = waveNumber; this.isWaveActive = true; this.waveStartTime = Date.now(); this.enemiesRemaining = wave.enemies.length; this.enemiesKilled = 0; console.log(`🌊 Wave ${waveNumber} ${wave.isBossWave ? 'πŸ‘‘ BOSS ' : ''}starting!`); console.log(` Enemies: ${wave.enemies.length}`); // Spawn enemies this.spawnWaveEnemies(wave); // Show wave notification this.showNotification({ title: wave.isBossWave ? 'πŸ‘‘ BOSS WAVE!' : `Wave ${waveNumber}`, text: `${wave.enemies.length} enemies incoming!`, icon: '🌊' }); return true; } /** * Spawn wave enemies */ spawnWaveEnemies(wave) { wave.enemies.forEach(enemy => { setTimeout(() => { this.spawnEnemy(enemy); }, enemy.spawnDelay || 0); }); } /** * Spawn single enemy */ spawnEnemy(enemyData) { // Get spawn point (random around player) const spawnPoint = this.getRandomSpawnPoint(); // TODO: Create actual enemy sprite console.log(`πŸ‘Ύ Spawning ${enemyData.type} at (${spawnPoint.x}, ${spawnPoint.y})`); // Create enemy using ZombieSystem or EnemySystem // For now, just log const enemy = { ...enemyData, x: spawnPoint.x, y: spawnPoint.y, isAlive: true, currentHealth: enemyData.health }; // TODO: Add to enemy tracking return enemy; } /** * Get random spawn point */ getRandomSpawnPoint() { const playerX = this.scene.player?.x || 0; const playerY = this.scene.player?.y || 0; // Random angle const angle = Math.random() * Math.PI * 2; // Spawn at radius distance const x = playerX + Math.cos(angle) * this.spawnRadius; const y = playerY + Math.sin(angle) * this.spawnRadius; return { x, y }; } /** * Enemy killed callback */ onEnemyKilled(enemy) { if (!this.isWaveActive) return; this.enemiesKilled++; this.enemiesRemaining--; this.stats.totalEnemiesKilled++; console.log(`πŸ’€ Enemy killed! (${this.enemiesKilled}/${this.currentWave ? this.waves[this.currentWave - 1].enemies.length : 0})`); // Check if wave complete if (this.enemiesRemaining <= 0) { this.completeWave(); } } /** * Complete wave */ completeWave() { if (!this.isWaveActive) return; const wave = this.waves[this.currentWave - 1]; const duration = Date.now() - this.waveStartTime; this.isWaveActive = false; this.stats.totalWavesCompleted++; this.stats.highestWave = Math.max(this.stats.highestWave, this.currentWave); console.log(`βœ… Wave ${this.currentWave} complete!`); console.log(` Time: ${Math.floor(duration / 1000)}s`); console.log(` Killed: ${this.enemiesKilled}`); // Grant rewards this.grantWaveRewards(wave); // Show completion notification this.showNotification({ title: 'Wave Complete!', text: `βœ… Wave ${this.currentWave} cleared! Rewards granted!`, icon: 'πŸ†' }); // Auto-start next wave after delay setTimeout(() => { this.showWaveCountdown(); }, 5000); } /** * Grant wave rewards */ grantWaveRewards(wave) { const rewards = wave.rewards; console.log(`🎁 Rewards:`); console.log(` πŸ’° ${rewards.zlatniki} Zlatniki`); console.log(` ⭐ ${rewards.xp} XP`); // TODO: Actually grant rewards to player this.stats.totalRewards += rewards.zlatniki; // Rare loot on boss waves if (wave.isBossWave) { console.log(` πŸ‘‘ BONUS: Boss loot!`); // TODO: Grant rare items } } /** * Show wave countdown */ showWaveCountdown() { const nextWave = this.currentWave + 1; console.log(`⏰ Next wave (${nextWave}) in 10 seconds...`); this.showNotification({ title: 'Next Wave Soon', text: `⏰ Wave ${nextWave} starts in 10 seconds!`, icon: 'βš”οΈ' }); // Auto-start after countdown setTimeout(() => { this.startWave(nextWave); }, 10000); } /** * End horde mode */ endHordeMode() { this.isWaveActive = false; console.log('πŸ›‘ Horde mode ended'); console.log('πŸ“Š Final Stats:'); console.log(` Waves: ${this.stats.totalWavesCompleted}`); console.log(` Kills: ${this.stats.totalEnemiesKilled}`); console.log(` Highest: ${this.stats.highestWave}`); this.showNotification({ title: 'Horde Mode Ended', text: `Survived ${this.stats.highestWave} waves! ${this.stats.totalEnemiesKilled} kills!`, icon: 'πŸ†' }); } /** * Get wave info */ getWaveInfo(waveNumber) { return this.waves[waveNumber - 1]; } /** * Get statistics */ getStats() { return { ...this.stats, currentWave: this.currentWave, isActive: this.isWaveActive }; } /** * Helper: Show notification */ showNotification(notification) { console.log(`πŸ“’ ${notification.icon} ${notification.title}: ${notification.text}`); const ui = this.scene.scene.get('UIScene'); if (ui && ui.showNotification) { ui.showNotification(notification); } } /** * Update system */ update(delta) { if (!this.isWaveActive) return; // Update wave timer, check conditions, etc. // TODO: Implement wave updates } }