using System.Collections.Frozen;
using System.Collections.Generic;
namespace AcDream.Core.Audio;
///
/// Retail's AdminEnvirons code → interface table,
/// from the switch in CPlayerSystem::Handle_Admin__Environs @
/// 0x0055DE20 (0x0055E07F..0x0055E2C7). Each case plays
/// SoundManager::PlaySoundFromCenter(Sound_UI_*, GetUISoundTable()) after
/// checking that the local player physics object and the UI table both exist.
///
///
/// This is what players remember as dungeon "music": the server drives the
/// chanting, drums, whispers and thunder through these codes. It is not a music
/// system — retail has none — but it is the atmosphere channel.
///
///
///
/// An explicit table, deliberately. The environ code and the SoundType
/// differ by 0x11 for most of the run, but NOT uniformly: codes 0x73 and
/// 0x74 have no case at all (retail falls through and plays nothing), so
/// 0x75 lands on UI_Squeal (0x84) rather than the 0x86 arithmetic
/// would give. Retail's switch is explicit; porting it as an offset would
/// mis-map every code from 0x75 up.
///
///
public static class EnvironSoundCueMap
{
private static readonly FrozenDictionary Map =
new Dictionary
{
[0x65u] = SoundId.UI_Roar,
[0x66u] = SoundId.UI_Bell,
[0x67u] = SoundId.UI_Chant1,
[0x68u] = SoundId.UI_Chant2,
[0x69u] = SoundId.UI_DarkWhispers1,
[0x6Au] = SoundId.UI_DarkWhispers2,
[0x6Bu] = SoundId.UI_DarkLaugh,
[0x6Cu] = SoundId.UI_DarkWind,
[0x6Du] = SoundId.UI_DarkSpeech,
[0x6Eu] = SoundId.UI_Drums,
[0x6Fu] = SoundId.UI_GhostSpeak,
[0x70u] = SoundId.UI_Breathing,
[0x71u] = SoundId.UI_Howl,
[0x72u] = SoundId.UI_LostSouls,
// 0x73 and 0x74: no case in retail's switch — nothing plays.
[0x75u] = SoundId.UI_Squeal,
[0x76u] = SoundId.UI_Thunder1,
[0x77u] = SoundId.UI_Thunder2,
[0x78u] = SoundId.UI_Thunder3,
[0x79u] = SoundId.UI_Thunder4,
[0x7Au] = SoundId.UI_Thunder5,
[0x7Bu] = SoundId.UI_Thunder6,
}.ToFrozenDictionary();
///
/// Map an AdminEnvirons change type to its interface sound, or false
/// when retail's switch has no case for it (including 0x73/0x74
/// inside the run, and every code outside it).
///
public static bool TryGetSound(uint changeType, out SoundId sound) =>
Map.TryGetValue(changeType, out sound);
/// Every code retail has a case for. Diagnostic and test use.
public static IReadOnlyCollection Codes => Map.Keys;
}