/** * ZOMBIE SCOUT SKILLS SYSTEM * Skill tree with active/passive abilities * Integrates with ZombieScoutLevelingSystem */ export class ZombieScoutSkills { constructor(scene) { this.scene = scene; // Skill trees this.skills = new Map(); this.unlockedSkills = new Set(); this.activeSkills = new Map(); // Currently equipped active skills // Skill categories this.categories = ['digging', 'combat', 'utility']; this.init(); } init() { this.initializeSkillTree(); } /** * Initialize all available skills */ initializeSkillTree() { // DIGGING SKILLS this.registerSkill({ id: 'speed_dig', name: 'Speed Dig', category: 'digging', type: 'active', unlockLevel: 10, cooldown: 30000, // 30 seconds duration: 10000, // 10 seconds description: 'Dig 50% faster for 10 seconds', effect: () => this.activateSpeedDig() }); this.registerSkill({ id: 'deep_scan', name: 'Deep Scan', category: 'digging', type: 'passive', unlockLevel: 5, description: 'Reveal buried items within 5 tiles', effect: () => this.enableDeepScan() }); this.registerSkill({ id: 'treasure_sense', name: 'Treasure Sense', category: 'digging', type: 'active', unlockLevel: 15, cooldown: 60000, // 60 seconds description: 'Reveal all buried treasure on screen', effect: () => this.activateTreasureSense() }); // COMBAT SKILLS this.registerSkill({ id: 'basic_attack', name: 'Claw Swipe', category: 'combat', type: 'active', unlockLevel: 5, cooldown: 2000, // 2 seconds damage: 10, description: 'Basic melee attack dealing 10 damage', effect: () => this.performBasicAttack() }); this.registerSkill({ id: 'leap_attack', name: 'Leap Attack', category: 'combat', type: 'active', unlockLevel: 12, cooldown: 8000, // 8 seconds damage: 25, description: 'Leap at enemy dealing 25 damage', effect: () => this.performLeapAttack() }); this.registerSkill({ id: 'tank_stance', name: 'Undead Resilience', category: 'combat', type: 'passive', unlockLevel: 8, description: '+20% damage resistance', effect: () => this.enableTankStance() }); // UTILITY SKILLS this.registerSkill({ id: 'scout_speed', name: 'Scout Sprint', category: 'utility', type: 'active', unlockLevel: 7, cooldown: 20000, // 20 seconds duration: 5000, // 5 seconds description: 'Move 100% faster for 5 seconds', effect: () => this.activateScoutSpeed() }); this.registerSkill({ id: 'pack_mule', name: 'Pack Mule', category: 'utility', type: 'passive', unlockLevel: 6, description: '+10 inventory slots', effect: () => this.enablePackMule() }); this.registerSkill({ id: 'night_vision', name: 'Night Vision', category: 'utility', type: 'passive', unlockLevel: 10, description: 'See in darkness without penalty', effect: () => this.enableNightVision() }); } /** * Register a skill in the system */ registerSkill(skillData) { this.skills.set(skillData.id, { ...skillData, unlocked: false, active: false, lastUsed: 0 }); } /** * Unlock skill (called when level requirement met) */ unlockSkill(skillId) { const skill = this.skills.get(skillId); if (!skill) return false; const scoutLevel = this.scene.zombieScoutLeveling?.currentLevel || 1; // Check level requirement if (scoutLevel < skill.unlockLevel) { console.warn(`Scout level ${scoutLevel} too low for ${skill.name} (requires ${skill.unlockLevel})`); return false; } skill.unlocked = true; this.unlockedSkills.add(skillId); // Auto-activate passive skills if (skill.type === 'passive') { skill.effect(); } // Notification this.scene.uiSystem?.showNotification( `Skill Unlocked: ${skill.name}!`, 'skill_unlock', { description: skill.description } ); console.log(`✨ Unlocked skill: ${skill.name}`); return true; } /** * Use active skill */ useSkill(skillId) { const skill = this.skills.get(skillId); if (!skill || !skill.unlocked || skill.type !== 'active') return false; // Check cooldown const now = Date.now(); const timeSinceLastUse = now - skill.lastUsed; if (timeSinceLastUse < skill.cooldown) { const remainingCooldown = Math.ceil((skill.cooldown - timeSinceLastUse) / 1000); console.log(`Skill on cooldown: ${remainingCooldown}s remaining`); return false; } // Activate skill skill.lastUsed = now; skill.effect(); // UI feedback this.scene.uiSystem?.showSkillActivation(skill.name, skill.cooldown); console.log(`🔥 Activated: ${skill.name}`); return true; } /** * SKILL EFFECTS */ activateSpeedDig() { const scout = this.scene.zombieScout; if (!scout) return; scout.digSpeed *= 1.5; // 50% faster // VFX this.scene.vfxSystem?.playEffect('speed_buff', scout.x, scout.y); // Restore after duration this.scene.time.delayedCall(10000, () => { scout.digSpeed /= 1.5; console.log('Speed Dig expired'); }); } enableDeepScan() { // Enable passive treasure detection this.scene.gameState.buffs.treasure_detection_range = 5; console.log('Deep Scan enabled: 5 tile range'); } activateTreasureSense() { // Reveal all buried items on screen this.scene.treasureSystem?.revealAllTreasures(); // VFX: Screen pulse this.scene.cameras.main.flash(500, 255, 215, 0, true); console.log('Treasure Sense activated: All treasures revealed'); } performBasicAttack() { const scout = this.scene.zombieScout; if (!scout) return; // Find nearest enemy const enemy = this.findNearestEnemy(scout, 50); if (!enemy) { console.log('No enemy in range'); return; } // Deal damage enemy.takeDamage(10); // VFX this.scene.vfxSystem?.playEffect('claw_swipe', enemy.x, enemy.y); this.scene.soundSystem?.play('zombie_attack'); console.log('Basic attack: 10 damage'); } performLeapAttack() { const scout = this.scene.zombieScout; if (!scout) return; // Find nearest enemy const enemy = this.findNearestEnemy(scout, 150); if (!enemy) return; // Leap animation this.scene.tweens.add({ targets: scout, x: enemy.x, y: enemy.y - 20, duration: 300, ease: 'Quad.easeOut', onComplete: () => { // Deal damage on landing enemy.takeDamage(25); this.scene.vfxSystem?.playEffect('impact', enemy.x, enemy.y); this.scene.cameras.main.shake(200, 0.008); } }); console.log('Leap attack: 25 damage'); } enableTankStance() { const scout = this.scene.zombieScout; if (scout) { scout.damageResistance = (scout.damageResistance || 0) + 0.2; // +20% console.log('Undead Resilience enabled: +20% damage resistance'); } } activateScoutSpeed() { const scout = this.scene.zombieScout; if (!scout) return; scout.moveSpeed *= 2; // 100% faster // VFX: Speed trails this.scene.vfxSystem?.playEffect('speed_trail', scout.x, scout.y, { duration: 5000 }); // Restore after duration this.scene.time.delayedCall(5000, () => { scout.moveSpeed /= 2; console.log('Scout Sprint expired'); }); } enablePackMule() { this.scene.inventorySystem?.addInventorySlots(10); console.log('Pack Mule enabled: +10 inventory slots'); } enableNightVision() { this.scene.gameState.buffs.night_vision = true; console.log('Night Vision enabled: Full visibility at night'); } /** * Helper: Find nearest enemy */ findNearestEnemy(from, maxDistance) { let nearest = null; let minDist = maxDistance; // Search for enemies in scene const enemies = this.scene.enemies || []; enemies.forEach(enemy => { const dist = Phaser.Math.Distance.Between(from.x, from.y, enemy.x, enemy.y); if (dist < minDist) { minDist = dist; nearest = enemy; } }); return nearest; } /** * Get unlocked skills by category */ getSkillsByCategory(category) { return Array.from(this.skills.values()) .filter(s => s.category === category && s.unlocked); } /** * Get all unlocked skills */ getUnlockedSkills() { return Array.from(this.skills.values()).filter(s => s.unlocked); } /** * Check skill availability */ isSkillAvailable(skillId) { const skill = this.skills.get(skillId); if (!skill || !skill.unlocked) return false; if (skill.type === 'passive') return true; const now = Date.now(); return (now - skill.lastUsed) >= skill.cooldown; } /** * Get skill cooldown remaining */ getCooldownRemaining(skillId) { const skill = this.skills.get(skillId); if (!skill) return 0; const now = Date.now(); const elapsed = now - skill.lastUsed; const remaining = Math.max(0, skill.cooldown - elapsed); return Math.ceil(remaining / 1000); // Return in seconds } /** * Save/Load */ getSaveData() { return { unlockedSkills: Array.from(this.unlockedSkills), skillCooldowns: Array.from(this.skills.entries()).map(([id, skill]) => ({ id, lastUsed: skill.lastUsed })) }; } loadSaveData(data) { this.unlockedSkills = new Set(data.unlockedSkills || []); // Restore cooldowns data.skillCooldowns?.forEach(({ id, lastUsed }) => { const skill = this.skills.get(id); if (skill) { skill.lastUsed = lastUsed; skill.unlocked = this.unlockedSkills.has(id); } }); // Re-apply passive skills this.unlockedSkills.forEach(skillId => { const skill = this.skills.get(skillId); if (skill && skill.type === 'passive') { skill.effect(); } }); } }