diff --git a/include/game/zone_manager.hpp b/include/game/zone_manager.hpp index 281aad16..0df3a842 100644 --- a/include/game/zone_manager.hpp +++ b/include/game/zone_manager.hpp @@ -6,6 +6,7 @@ #include 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); diff --git a/src/game/zone_manager.cpp b/src/game/zone_manager.cpp index de7d2bfa..10921baf 100644 --- a/src/game/zone_manager.cpp +++ b/src/game/zone_manager.cpp @@ -1,4 +1,5 @@ #include "game/zone_manager.hpp" +#include "pipeline/asset_manager.hpp" #include "core/logger.hpp" #include #include @@ -479,5 +480,88 @@ std::vector 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 { + if (soundId == 0) return {}; + int32_t idx = soundDbc->findRecordById(soundId); + if (idx < 0) return {}; + uint32_t row = static_cast(idx); + if (soundDbc->getFieldCount() < 24) return {}; + std::string dir = soundDbc->getString(row, 23); + std::vector 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(zmIdx); + if (zoneMusicDbc->getFieldCount() < 8) continue; + + uint32_t daySoundId = zoneMusicDbc->getUInt32(zmRow, 6); + uint32_t nightSoundId = zoneMusicDbc->getUInt32(zmRow, 7); + + std::vector 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 diff --git a/src/rendering/renderer.cpp b/src/rendering/renderer.cpp index e0bff734..78d8e45a 100644 --- a/src/rendering/renderer.cpp +++ b/src/rendering/renderer.cpp @@ -706,9 +706,12 @@ bool Renderer::initialize(core::Window* win) { lightingManager = std::make_unique(); [[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(); zoneManager->initialize(); + if (assetManager) { + zoneManager->enrichFromDBC(assetManager); + } // Initialize AudioEngine (singleton) if (!audio::AudioEngine::instance().initialize()) {