/** * CompleteAudioIntegration.js * * MASTER AUDIO SYSTEM - Everything integrated! * * Features: * - AI Voice playback (Gronk, Ana, Kai) * - Farm animal SFX (proximity-based) * - Combat sounds (zombie_hit, zombie_death, player_hurt) * - Ambient (city noise, farm wind) * - Interactive (generator hum, chalkboard) * - Xbox haptics for all audio events * - Character-specific typewriter blips * * Created: Jan 10, 2026 * Author: David "HIPO" Kotnik * Studio: Hipodevil666 Studiosβ„’ */ export default class CompleteAudioIntegration { constructor(scene) { this.scene = scene; // Audio categories this.voices = {}; this.sfx = {}; this.ambient = {}; this.interactive = {}; // State tracking this.currentAmbient = null; this.generatorHumActive = false; // Haptic support this.hapticEnabled = true; console.log('πŸŽ™οΈ Complete Audio Integration initialized!'); } /** * Preload all audio assets */ preloadAssets() { const scene = this.scene; // === AI VOICES (Character-specific) === console.log('πŸ“‚ Loading AI Voices...'); // Gronk (8 phrases) for (let i = 1; i <= 8; i++) { scene.load.audio(`gronk_phrase_${i}`, `assets/audio/voice/gronk/gronk_phrase_${String(i).padStart(2, '0')}.ogg`); } // Ana (8 phrases) for (let i = 1; i <= 8; i++) { scene.load.audio(`ana_phrase_${i}`, `assets/audio/voice/ana/ana_phrase_${String(i).padStart(2, '0')}.ogg`); } // Kai (8 phrases) for (let i = 1; i <= 8; i++) { scene.load.audio(`kai_phrase_${i}`, `assets/audio/voice/kai/kai_phrase_${String(i).padStart(2, '0')}.ogg`); } // === FARM ANIMAL SFX === console.log('πŸ“‚ Loading Farm Animals...'); scene.load.audio('sfx_sheep', 'assets/audio/animals/sheep.ogg'); scene.load.audio('sfx_pig', 'assets/audio/animals/pig.ogg'); scene.load.audio('sfx_chicken', 'assets/audio/animals/chicken.ogg'); scene.load.audio('sfx_horse', 'assets/audio/animals/horse.ogg'); scene.load.audio('sfx_goat', 'assets/audio/animals/goat.ogg'); scene.load.audio('sfx_cow', 'assets/audio/animals/cow.ogg'); // === COMBAT SFX === console.log('πŸ“‚ Loading Combat Sounds...'); scene.load.audio('sfx_zombie_hit', 'assets/audio/combat/zombie_hit.ogg'); scene.load.audio('sfx_zombie_death', 'assets/audio/combat/zombie_death.ogg'); scene.load.audio('sfx_player_hurt', 'assets/audio/combat/player_hurt.ogg'); // === AMBIENT LOOPS === console.log('πŸ“‚ Loading Ambient...'); scene.load.audio('ambient_city_noise', 'assets/audio/ambient/city_noise_loop.ogg'); scene.load.audio('ambient_farm_wind', 'assets/audio/ambient/wind_loop.ogg'); scene.load.audio('ambient_crickets', 'assets/audio/ambient/crickets_loop.ogg'); // === INTERACTIVE SFX === console.log('πŸ“‚ Loading Interactive...'); scene.load.audio('sfx_generator_hum', 'assets/audio/interactive/electric_hum_loop.ogg'); scene.load.audio('sfx_chalkboard', 'assets/audio/interactive/chalkboard_writing.ogg'); scene.load.audio('sfx_uv_buzz', 'assets/audio/interactive/uv_light_buzz.ogg'); // === TYPEWRITER BLIPS (Character-specific pitch) === scene.load.audio('blip_gronk', 'assets/audio/ui/typewriter_low.ogg'); // Low pitch scene.load.audio('blip_ana', 'assets/audio/ui/typewriter_mid.ogg'); // Mid pitch scene.load.audio('blip_kai', 'assets/audio/ui/typewriter_high.ogg'); // High pitch scene.load.audio('blip_npc', 'assets/audio/ui/typewriter_normal.ogg'); // Normal pitch console.log('βœ… All audio assets queued for loading!'); } /** * Initialize audio after preload complete */ initialize() { const scene = this.scene; console.log('🎡 Initializing audio objects...'); // === AI VOICES === this.voices = { gronk: [], ana: [], kai: [] }; for (let i = 1; i <= 8; i++) { this.voices.gronk.push(scene.sound.add(`gronk_phrase_${i}`, { volume: 0.8 })); this.voices.ana.push(scene.sound.add(`ana_phrase_${i}`, { volume: 0.7 })); this.voices.kai.push(scene.sound.add(`kai_phrase_${i}`, { volume: 0.75 })); } // === FARM ANIMALS === this.sfx.animals = { sheep: scene.sound.add('sfx_sheep', { volume: 0.4 }), pig: scene.sound.add('sfx_pig', { volume: 0.4 }), chicken: scene.sound.add('sfx_chicken', { volume: 0.35 }), horse: scene.sound.add('sfx_horse', { volume: 0.5 }), goat: scene.sound.add('sfx_goat', { volume: 0.4 }), cow: scene.sound.add('sfx_cow', { volume: 0.45 }) }; // === COMBAT === this.sfx.combat = { zombieHit: scene.sound.add('sfx_zombie_hit', { volume: 0.6 }), zombieDeath: scene.sound.add('sfx_zombie_death', { volume: 0.7 }), playerHurt: scene.sound.add('sfx_player_hurt', { volume: 0.8 }) }; // === AMBIENT === this.ambient = { cityNoise: scene.sound.add('ambient_city_noise', { loop: true, volume: 0.15 }), farmWind: scene.sound.add('ambient_farm_wind', { loop: true, volume: 0.2 }), crickets: scene.sound.add('ambient_crickets', { loop: true, volume: 0.25 }) }; // === INTERACTIVE === this.interactive = { generatorHum: scene.sound.add('sfx_generator_hum', { loop: true, volume: 0 }), // Starts at 0 chalkboard: scene.sound.add('sfx_chalkboard', { volume: 0.5 }), uvBuzz: scene.sound.add('sfx_uv_buzz', { loop: true, volume: 0 }) }; // === TYPEWRITER BLIPS === this.sfx.blips = { gronk: scene.sound.add('blip_gronk', { volume: 0.15 }), ana: scene.sound.add('blip_ana', { volume: 0.12 }), kai: scene.sound.add('blip_kai', { volume: 0.13 }), npc: scene.sound.add('blip_npc', { volume: 0.1 }) }; console.log('βœ… Complete Audio Integration ready!'); } /** * Play AI voice for character with haptic feedback */ playVoice(character, phraseNumber, onComplete = null) { const voices = this.voices[character]; if (!voices || !voices[phraseNumber - 1]) { console.warn(`⚠️ Voice not found: ${character} phrase ${phraseNumber}`); return; } const voice = voices[phraseNumber - 1]; console.log(`πŸŽ™οΈ Playing voice: ${character.toUpperCase()} phrase ${phraseNumber}`); // Play voice voice.play(); // Haptic feedback (gentle pulse for voice) this.vibrateLight(); // On complete callback if (onComplete) { voice.once('complete', onComplete); } } /** * Play combat sound with strong haptic */ playCombatSound(type) { const sound = this.sfx.combat[type]; if (!sound) { console.warn(`⚠️ Combat sound not found: ${type}`); return; } sound.play(); // Strong haptic for combat this.vibrateStrong(type === 'playerHurt' ? 400 : 200); console.log(`βš”οΈ Combat sound: ${type}`); } /** * Play farm animal sound (proximity-based random) */ playAnimalSound(animalType, position) { const sound = this.sfx.animals[animalType]; if (!sound || sound.isPlaying) return; // Check proximity to player const player = this.scene.player; if (!player) return; const distance = Phaser.Math.Distance.Between( player.x, player.y, position.x, position.y ); // Only play if within 500px if (distance < 500) { sound.play(); console.log(`πŸ„ Animal sound: ${animalType} (distance: ${Math.floor(distance)}px)`); } } /** * Start ambient for location */ playAmbient(location) { // Stop current ambient if (this.currentAmbient) { this.currentAmbient.stop(); } let ambient = null; switch (location) { case 'city': case 'town': ambient = this.ambient.cityNoise; break; case 'farm': case 'grassland': ambient = this.ambient.farmWind; break; case 'night': ambient = this.ambient.crickets; break; } if (ambient) { ambient.play(); this.currentAmbient = ambient; console.log(`🌍 Ambient: ${location}`); } } /** * Update generator hum based on proximity */ updateGeneratorHum(playerX, playerY, generatorX, generatorY) { const distance = Phaser.Math.Distance.Between( playerX, playerY, generatorX, generatorY ); const maxDistance = 800; // Max hearing distance const minDistance = 100; // Full volume distance let volume = 0; if (distance < maxDistance) { if (distance < minDistance) { volume = 0.6; // Max volume } else { // Fade based on distance volume = 0.6 * (1 - (distance - minDistance) / (maxDistance - minDistance)); } } // Update volume smoothly if (!this.generatorHumActive && volume > 0) { this.interactive.generatorHum.play(); this.generatorHumActive = true; } else if (this.generatorHumActive && volume === 0) { this.interactive.generatorHum.stop(); this.generatorHumActive = false; } this.interactive.generatorHum.setVolume(volume); } /** * Update UV light buzz (basement proximity) */ updateUVBuzz(playerX, playerY, uvLightX, uvLightY) { const distance = Phaser.Math.Distance.Between( playerX, playerY, uvLightX, uvLightY ); const maxDistance = 300; const volume = distance < maxDistance ? 0.3 * (1 - distance / maxDistance) : 0; this.interactive.uvBuzz.setVolume(volume); if (volume > 0 && !this.interactive.uvBuzz.isPlaying) { this.interactive.uvBuzz.play(); } else if (volume === 0 && this.interactive.uvBuzz.isPlaying) { this.interactive.uvBuzz.stop(); } } /** * Play chalkboard writing sound (Zombie Statistician) */ playChalkboard() { this.interactive.chalkboard.play(); // Light haptic for chalkboard this.vibrateLight(); console.log('✏️ Chalkboard sound played!'); } /** * Get typewriter blip for character */ getTypewriterBlip(character) { return this.sfx.blips[character] || this.sfx.blips.npc; } /** * Light haptic feedback (voice, minor events) */ vibrateLight() { this.vibrate(100, 0.3, 0.5); } /** * Strong haptic feedback (combat, impacts) */ vibrateStrong(duration = 300) { this.vibrate(duration, 0.7, 1.0); } /** * Xbox controller vibration */ vibrate(duration, weakMagnitude, strongMagnitude) { if (!this.hapticEnabled) return; const scene = this.scene; if (scene.input.gamepad && scene.input.gamepad.total > 0) { const pad = scene.input.gamepad.getPad(0); if (pad && pad.vibration) { pad.vibration.playEffect('dual-rumble', { startDelay: 0, duration: duration, weakMagnitude: weakMagnitude, strongMagnitude: strongMagnitude }); } } } /** * Update system (called in scene update loop) */ update(time, delta, playerX, playerY) { // Update proximity-based sounds // (Generator and UV lights) // This would be called with actual positions from game } /** * Cleanup */ destroy() { // Stop all sounds if (this.currentAmbient) { this.currentAmbient.stop(); } if (this.generatorHumActive) { this.interactive.generatorHum.stop(); } if (this.interactive.uvBuzz.isPlaying) { this.interactive.uvBuzz.stop(); } console.log('πŸ”‡ Complete Audio Integration destroyed!'); } }