orbit/js/utils/Sfx.js

47 lines
1.9 KiB
JavaScript

import { config } from '../config/Config.js';
/**
* The shared SFX voice (data/sfx.json).
*
* Scenes expose a `playSfx(name)` method (MenuScene / GameScene) that
* delegates here, and UI components call it through the scene seam
* (`this.scene.playSfx?.('ui_hover')`) — one voice, one place (the same
* rule ConfirmOverlay follows for the construct ticks).
*
* Convention: `name` is the data/sfx.json key, and the asset is queued
* as `sfx_<name>` (the play name resolves to the cache key directly —
* the same rule the existing construct/scan/… voices follow).
*
* Guards, in order: the master switch (sfx.enabled), the sound manager
* (absent in headless), and the audio cache — v4 (Giedi) quirk:
* `sound.play()` THROWS on a key that never loaded, and
* `cache.hasAudio()` does not exist in this build, so we check
* `cache.audio.has()` directly. The game never blocks or warns on sound.
*/
export function playSfxOn(scene, name, o = {}) {
if (!scene || !config.get('sfx.enabled', true)) return;
const snd = scene.sound;
if (!snd || typeof snd.play !== 'function') return;
const key = `sfx_${name}`;
if (scene.cache && scene.cache.audio && typeof scene.cache.audio.has === 'function' && !scene.cache.audio.has(key)) return;
snd.play(key, { volume: config.get('sfx.volume', 0.55), ...o });
}
/**
* Stop one of the configured SFX by its data/sfx.json key (a no-op when
* it isn't playing). v4 (Giedi) API: the manager stops BY KEY —
* `sound.stop()` does not exist in this build.
*/
export function stopSfxOn(scene, name) {
const snd = scene && scene.sound;
if (!snd || typeof snd.stopByKey !== 'function') return;
snd.stopByKey(`sfx_${name}`);
}
/** Is one of the configured SFX playing right now? (false when unsure). */
export function sfxPlayingOn(scene, name) {
const snd = scene && scene.sound;
if (!snd || typeof snd.isPlaying !== 'function') return false;
return snd.isPlaying(`sfx_${name}`) === true;
}