From a6b8cd75f6e44e823a25dce01f3d50d49386faeb Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 5 May 2026 06:01:42 -0700 Subject: [PATCH] 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 --- tools/editor/asset_browser.cpp | 14 ++++++++++++++ tools/editor/asset_browser.hpp | 3 +++ tools/editor/editor_ui.cpp | 29 +++++++++++++++++++++++++---- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/tools/editor/asset_browser.cpp b/tools/editor/asset_browser.cpp index 338f1ec6..1046e4fd 100644 --- a/tools/editor/asset_browser.cpp +++ b/tools/editor/asset_browser.cpp @@ -75,6 +75,20 @@ void AssetBrowser::initialize(pipeline::AssetManager* am) { } } + // Scan for available maps (WDT files) + std::set 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(), diff --git a/tools/editor/asset_browser.hpp b/tools/editor/asset_browser.hpp index 27591c3e..914d9d8c 100644 --- a/tools/editor/asset_browser.hpp +++ b/tools/editor/asset_browser.hpp @@ -27,6 +27,8 @@ public: const std::vector& getM2Directories() const { return m2Dirs_; } const std::vector& getWMODirectories() const { return wmoDirs_; } + const std::vector& getMapNames() const { return mapNames_; } + bool isInitialized() const { return initialized_; } private: @@ -39,6 +41,7 @@ private: std::vector textureDirs_; std::vector m2Dirs_; std::vector wmoDirs_; + std::vector mapNames_; bool initialized_ = false; }; diff --git a/tools/editor/editor_ui.cpp b/tools/editor/editor_ui.cpp index c5e8daa9..ff5c4f63 100644 --- a/tools/editor/editor_ui.cpp +++ b/tools/editor/editor_ui.cpp @@ -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();