feat(editor): zone audio configuration panel

- Zone manifest gains audio fields: musicTrack, ambienceDay,
  ambienceNight, musicVolume, ambienceVolume
- Serialized to/from zone.json under "audio" key
- Info panel: collapsable "Zone Audio" section with text inputs for
  music/ambience paths and volume sliders
- Preset selector: Elwynn Forest, Durotar, Darkshore, Dungeon, None
- ZoneManifest stored persistently on EditorApp so audio settings
  survive between exports (was recreated each save)
- Custom zones can now specify their own background music and ambient
  soundscapes via zone.json
This commit is contained in:
Kelsi 2026-05-05 15:48:49 -07:00
parent 36dc9ddef7
commit 2136727c68
5 changed files with 76 additions and 1 deletions

View file

@ -44,6 +44,17 @@ bool ZoneManifest::save(const std::string& path) const {
if (hasCreatures) files["creatures"] = "creatures.json";
j["files"] = files;
// Audio configuration
if (!musicTrack.empty() || !ambienceDay.empty()) {
nlohmann::json audio;
if (!musicTrack.empty()) audio["music"] = musicTrack;
if (!ambienceDay.empty()) audio["ambienceDay"] = ambienceDay;
if (!ambienceNight.empty()) audio["ambienceNight"] = ambienceNight;
audio["musicVolume"] = musicVolume;
audio["ambienceVolume"] = ambienceVolume;
j["audio"] = audio;
}
std::ofstream f(path);
if (!f) { LOG_ERROR("Failed to write zone manifest: ", path); return false; }
f << j.dump(2) << "\n";
@ -76,6 +87,16 @@ bool ZoneManifest::load(const std::string& path) {
}
}
// Audio configuration
if (j.contains("audio")) {
const auto& a = j["audio"];
musicTrack = a.value("music", "");
ambienceDay = a.value("ambienceDay", "");
ambienceNight = a.value("ambienceNight", "");
musicVolume = a.value("musicVolume", 0.7f);
ambienceVolume = a.value("ambienceVolume", 0.5f);
}
return !mapName.empty();
} catch (const std::exception& e) {
LOG_ERROR("Failed to parse zone manifest: ", e.what());