diff --git a/public/assets/themes/default/audio/voice/welcome_rookie.mp3 b/public/assets/themes/default/audio/voice/welcome_rookie.mp3 new file mode 100644 index 0000000..47bee00 Binary files /dev/null and b/public/assets/themes/default/audio/voice/welcome_rookie.mp3 differ diff --git a/src/levels/level1.ts b/src/levels/level1.ts index 36744b6..3721915 100644 --- a/src/levels/level1.ts +++ b/src/levels/level1.ts @@ -431,7 +431,7 @@ export class Level1 implements Level { log.info('[Level1] _missionBrief object:', this._missionBrief); log.info('[Level1] Ship exists:', !!this._ship); log.info('[Level1] Ship ID in scene:', DefaultScene.MainScene.getNodeById('Ship') !== null); - this._missionBrief.initialize(); + this._missionBrief.initialize(this._audioEngine); log.info('[Level1] ========== MISSION BRIEF INITIALIZATION COMPLETE =========='); log.debug('Mission brief initialized'); diff --git a/src/services/cloudLevelService.ts b/src/services/cloudLevelService.ts index c602720..9262e61 100644 --- a/src/services/cloudLevelService.ts +++ b/src/services/cloudLevelService.ts @@ -28,6 +28,7 @@ export interface CloudLevelEntry { createdAt: string; updatedAt: string; reviewNotes?: string; + missionBriefAudio?: string; } /** @@ -55,6 +56,7 @@ interface LevelRow { created_at: string; updated_at: string; review_notes?: string; + mission_brief_audio?: string; } /** @@ -93,6 +95,7 @@ function rowToEntry(row: LevelRow): CloudLevelEntry { createdAt: row.created_at, updatedAt: row.updated_at, reviewNotes: row.review_notes, + missionBriefAudio: row.mission_brief_audio, }; } diff --git a/src/ui/hud/missionBrief.ts b/src/ui/hud/missionBrief.ts index c5daa9e..bcaaa97 100644 --- a/src/ui/hud/missionBrief.ts +++ b/src/ui/hud/missionBrief.ts @@ -8,6 +8,7 @@ import { } from "@babylonjs/gui"; import { DefaultScene } from "../../core/defaultScene"; import {MeshBuilder, Vector3, Observable, Observer} from "@babylonjs/core"; +import type { AudioEngineV2, StaticSound } from "@babylonjs/core"; import log from '../../core/logger'; import { LevelConfig } from "../../levels/config/levelConfig"; import { CloudLevelEntry } from "../../services/cloudLevelService"; @@ -22,11 +23,14 @@ export class MissionBrief { private _isVisible: boolean = false; private _onStartCallback: (() => void) | null = null; private _triggerObserver: Observer | null = null; + private _audioEngine: AudioEngineV2 | null = null; + private _currentSound: StaticSound | null = null; /** * Initialize the mission brief as a fullscreen overlay */ - public initialize(): void { + public initialize(audioEngine?: AudioEngineV2): void { + this._audioEngine = audioEngine || null; log.info('[MissionBrief] ========== INITIALIZE CALLED =========='); const scene = DefaultScene.MainScene; log.info('[MissionBrief] Scene exists:', !!scene); @@ -232,6 +236,21 @@ export class MissionBrief { this._container.isVisible = true; this._isVisible = true; + // Play mission brief audio if specified + if (directoryEntry?.missionBriefAudio && this._audioEngine) { + log.info('[MissionBrief] Playing audio:', directoryEntry.missionBriefAudio); + this._audioEngine.createSoundAsync( + "missionBriefAudio", + directoryEntry.missionBriefAudio, + { loop: false, volume: 1.0 } + ).then(sound => { + this._currentSound = sound; + sound.play(); + }).catch(err => { + log.error('[MissionBrief] Failed to load audio:', err); + }); + } + log.info('[MissionBrief] ========== CONTAINER NOW VISIBLE =========='); log.info('[MissionBrief] Container.isVisible:', this._container.isVisible); log.info('[MissionBrief] _isVisible flag:', this._isVisible); @@ -298,6 +317,10 @@ export class MissionBrief { * Clean up resources */ public dispose(): void { + if (this._currentSound) { + this._currentSound.dispose(); + this._currentSound = null; + } if (this._advancedTexture) { this._advancedTexture.dispose(); this._advancedTexture = null; @@ -305,6 +328,7 @@ export class MissionBrief { this._container = null; this._onStartCallback = null; this._triggerObserver = null; + this._audioEngine = null; this._isVisible = false; log.debug('[MissionBrief] Disposed'); } diff --git a/supabase/schema.sql b/supabase/schema.sql index 30019cc..da48ecf 100644 --- a/supabase/schema.sql +++ b/supabase/schema.sql @@ -138,6 +138,7 @@ create table public.levels tags text[] default '{}'::text[], config jsonb not null, mission_brief text[] default '{}'::text[], + mission_brief_audio text, level_type text default 'private'::text not null constraint valid_level_type check (level_type = ANY