Enrich zone music from AreaTable/ZoneMusic/SoundEntries DBC chain

Add ZoneManager::enrichFromDBC() which walks AreaTable.dbc (field 8 = ZoneMusicId)
→ ZoneMusic.dbc (fields 6/7 = day/night SoundEntryIds) → SoundEntries.dbc
(fields 3-12 = files, field 23 = DirectoryBase) and appends MPQ music paths for
all zones in the DBC, covering ~2300+ areas vs the previous ~15 hardcoded entries.

Existing hardcoded paths are preserved as the primary pool; DBC paths are added
only if not already present. Called from Renderer::init() after initialize().
This commit is contained in:
Kelsi 2026-03-09 16:04:52 -07:00
parent 46f2c0df85
commit 43b9ecd857
3 changed files with 93 additions and 1 deletions

View file

@ -6,6 +6,7 @@
#include <vector>
namespace wowee {
namespace pipeline { class AssetManager; }
namespace game {
struct ZoneInfo {
@ -18,6 +19,10 @@ class ZoneManager {
public:
void initialize();
// Supplement zone music paths using AreaTable → ZoneMusic → SoundEntries DBC chain.
// Safe to call after initialize(); idempotent and additive (does not remove existing paths).
void enrichFromDBC(pipeline::AssetManager* assets);
uint32_t getZoneId(int tileX, int tileY) const;
const ZoneInfo* getZoneInfo(uint32_t zoneId) const;
std::string getRandomMusic(uint32_t zoneId);

View file

@ -1,4 +1,5 @@
#include "game/zone_manager.hpp"
#include "pipeline/asset_manager.hpp"
#include "core/logger.hpp"
#include <cstdlib>
#include <ctime>
@ -479,5 +480,88 @@ std::vector<std::string> ZoneManager::getAllMusicPaths() const {
return out;
}
void ZoneManager::enrichFromDBC(pipeline::AssetManager* assets) {
if (!assets) return;
auto areaDbc = assets->loadDBC("AreaTable.dbc");
auto zoneMusicDbc = assets->loadDBC("ZoneMusic.dbc");
auto soundDbc = assets->loadDBC("SoundEntries.dbc");
if (!areaDbc || !areaDbc->isLoaded()) {
LOG_WARNING("ZoneManager::enrichFromDBC: AreaTable.dbc not available");
return;
}
if (!zoneMusicDbc || !zoneMusicDbc->isLoaded()) {
LOG_WARNING("ZoneManager::enrichFromDBC: ZoneMusic.dbc not available");
return;
}
if (!soundDbc || !soundDbc->isLoaded()) {
LOG_WARNING("ZoneManager::enrichFromDBC: SoundEntries.dbc not available");
return;
}
// Build MPQ paths from a SoundEntries record.
// Fields 3-12 = File[0..9], field 23 = DirectoryBase.
auto getSoundPaths = [&](uint32_t soundId) -> std::vector<std::string> {
if (soundId == 0) return {};
int32_t idx = soundDbc->findRecordById(soundId);
if (idx < 0) return {};
uint32_t row = static_cast<uint32_t>(idx);
if (soundDbc->getFieldCount() < 24) return {};
std::string dir = soundDbc->getString(row, 23);
std::vector<std::string> paths;
for (uint32_t f = 3; f <= 12; ++f) {
std::string name = soundDbc->getString(row, f);
if (name.empty()) continue;
paths.push_back(dir.empty() ? name : dir + "\\" + name);
}
return paths;
};
const uint32_t numAreas = areaDbc->getRecordCount();
const uint32_t areaFields = areaDbc->getFieldCount();
if (areaFields < 9) {
LOG_WARNING("ZoneManager::enrichFromDBC: AreaTable.dbc has too few fields (", areaFields, ")");
return;
}
uint32_t zonesEnriched = 0;
for (uint32_t i = 0; i < numAreas; ++i) {
uint32_t zoneId = areaDbc->getUInt32(i, 0);
uint32_t zoneMusicId = areaDbc->getUInt32(i, 8);
if (zoneId == 0 || zoneMusicId == 0) continue;
int32_t zmIdx = zoneMusicDbc->findRecordById(zoneMusicId);
if (zmIdx < 0) continue;
uint32_t zmRow = static_cast<uint32_t>(zmIdx);
if (zoneMusicDbc->getFieldCount() < 8) continue;
uint32_t daySoundId = zoneMusicDbc->getUInt32(zmRow, 6);
uint32_t nightSoundId = zoneMusicDbc->getUInt32(zmRow, 7);
std::vector<std::string> newPaths;
for (const auto& p : getSoundPaths(daySoundId)) newPaths.push_back(p);
for (const auto& p : getSoundPaths(nightSoundId)) newPaths.push_back(p);
if (newPaths.empty()) continue;
auto& zone = zones[zoneId];
if (zone.id == 0) zone.id = zoneId;
// Append paths not already present (preserve hardcoded entries).
for (const auto& path : newPaths) {
bool found = false;
for (const auto& existing : zone.musicPaths) {
if (existing == path) { found = true; break; }
}
if (!found) {
zone.musicPaths.push_back(path);
++zonesEnriched;
}
}
}
LOG_INFO("Zone music enriched from DBC: ", zones.size(), " zones, ", zonesEnriched, " paths added");
}
} // namespace game
} // namespace wowee

View file

@ -706,9 +706,12 @@ bool Renderer::initialize(core::Window* win) {
lightingManager = std::make_unique<LightingManager>();
[[maybe_unused]] auto* assetManager = core::Application::getInstance().getAssetManager();
// Create zone manager
// Create zone manager; enrich music paths from DBC if available
zoneManager = std::make_unique<game::ZoneManager>();
zoneManager->initialize();
if (assetManager) {
zoneManager->enrichFromDBC(assetManager);
}
// Initialize AudioEngine (singleton)
if (!audio::AudioEngine::instance().initialize()) {