feat(editor): map browser for loading existing WoW zones

- Load Map Tile dialog now shows a searchable list of all available
  maps from the manifest (Azeroth, Kalimdor, Outland, dungeons, etc.)
- Click a map name to select it, then pick tile X/Y coordinates
- Helpful tile range hints shown below coordinates
- Maps indexed from WDT files in the manifest on startup
- Foundation for loading and modifying sections of existing WoW maps
This commit is contained in:
Kelsi 2026-05-05 06:01:42 -07:00
parent 5ccc61f144
commit a6b8cd75f6
3 changed files with 42 additions and 4 deletions

View file

@ -75,6 +75,20 @@ void AssetBrowser::initialize(pipeline::AssetManager* am) {
}
}
// Scan for available maps (WDT files)
std::set<std::string> mapSet;
for (const auto& [path, entry] : entries) {
if (path.starts_with("world\\maps\\") && path.ends_with(".wdt")) {
auto firstSlash = path.find('\\', 11); // after "world\\maps\\"
if (firstSlash != std::string::npos) {
std::string mapName = path.substr(11, firstSlash - 11);
mapSet.insert(mapName);
}
}
}
mapNames_.assign(mapSet.begin(), mapSet.end());
std::sort(mapNames_.begin(), mapNames_.end());
std::sort(textures_.begin(), textures_.end(),
[](const AssetEntry& a, const AssetEntry& b) { return a.wowPath < b.wowPath; });
std::sort(m2Models_.begin(), m2Models_.end(),

View file

@ -27,6 +27,8 @@ public:
const std::vector<std::string>& getM2Directories() const { return m2Dirs_; }
const std::vector<std::string>& getWMODirectories() const { return wmoDirs_; }
const std::vector<std::string>& getMapNames() const { return mapNames_; }
bool isInitialized() const { return initialized_; }
private:
@ -39,6 +41,7 @@ private:
std::vector<std::string> textureDirs_;
std::vector<std::string> m2Dirs_;
std::vector<std::string> wmoDirs_;
std::vector<std::string> mapNames_;
bool initialized_ = false;
};

View file

@ -305,14 +305,35 @@ void EditorUI::renderNewTerrainDialog(EditorApp& /*app*/) {
ImGui::End();
}
void EditorUI::renderLoadDialog(EditorApp& /*app*/) {
ImGui::SetNextWindowSize(ImVec2(350, 180), ImGuiCond_FirstUseEver);
if (ImGui::Begin("Load ADT", &showLoadDialog_)) {
ImGui::InputText("Map Name", loadMapNameBuf_, sizeof(loadMapNameBuf_));
void EditorUI::renderLoadDialog(EditorApp& app) {
ImGui::SetNextWindowSize(ImVec2(400, 380), ImGuiCond_FirstUseEver);
if (ImGui::Begin("Load Map Tile", &showLoadDialog_)) {
// Map browser
auto& maps = app.getAssetBrowser().getMapNames();
static char mapFilter[64] = "";
ImGui::InputText("Search Maps", mapFilter, sizeof(mapFilter));
std::string filter(mapFilter);
std::transform(filter.begin(), filter.end(), filter.begin(),
[](unsigned char c) { return std::tolower(c); });
ImGui::BeginChild("MapList", ImVec2(0, 180), true);
for (const auto& m : maps) {
if (!filter.empty() && m.find(filter) == std::string::npos) continue;
bool selected = (m == std::string(loadMapNameBuf_));
if (ImGui::Selectable(m.c_str(), selected))
std::strncpy(loadMapNameBuf_, m.c_str(), sizeof(loadMapNameBuf_) - 1);
}
ImGui::EndChild();
ImGui::Text("Selected: %s", loadMapNameBuf_);
ImGui::InputInt("Tile X", &loadTileX_);
ImGui::InputInt("Tile Y", &loadTileY_);
loadTileX_ = std::max(0, std::min(63, loadTileX_));
loadTileY_ = std::max(0, std::min(63, loadTileY_));
ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1),
"Azeroth: 28-50 range. Kalimdor: 20-50 range.");
ImGui::Spacing();
if (ImGui::Button("Load", ImVec2(120, 0))) { loadRequested_ = true; showLoadDialog_ = false; }
ImGui::SameLine();