From 124ff5a54a3c01a197941b8e889f0989836bbdee Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 5 May 2026 06:05:33 -0700 Subject: [PATCH] feat(editor): tile availability checker, NPC marker diagnostics - Load dialog shows green "Tile found" / red "Tile not found" indicator by checking the manifest before you attempt to load - NPC marker build/render diagnostic logging to trace rendering issues - Map browser and tile checker work together for easy existing zone loading --- tools/editor/editor_ui.cpp | 16 ++++++++++++++-- tools/editor/editor_viewport.cpp | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/tools/editor/editor_ui.cpp b/tools/editor/editor_ui.cpp index ff5c4f63..4cfa2400 100644 --- a/tools/editor/editor_ui.cpp +++ b/tools/editor/editor_ui.cpp @@ -331,8 +331,20 @@ void EditorUI::renderLoadDialog(EditorApp& app) { 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."); + // Check if the selected tile exists + { + std::string testPath = std::string("world\\maps\\") + loadMapNameBuf_ + "\\" + + loadMapNameBuf_ + "_" + std::to_string(loadTileX_) + "_" + + std::to_string(loadTileY_) + ".adt"; + std::string lower = testPath; + std::transform(lower.begin(), lower.end(), lower.begin(), + [](unsigned char c) { return std::tolower(c); }); + bool exists = app.getAssetManager()->getManifest().hasEntry(lower); + if (exists) + ImGui::TextColored(ImVec4(0.3f, 0.9f, 0.3f, 1), "Tile found in manifest"); + else + ImGui::TextColored(ImVec4(0.9f, 0.4f, 0.3f, 1), "Tile not found — try different coords"); + } ImGui::Spacing(); if (ImGui::Button("Load", ImVec2(120, 0))) { loadRequested_ = true; showLoadDialog_ = false; } diff --git a/tools/editor/editor_viewport.cpp b/tools/editor/editor_viewport.cpp index 44f9f6e3..fdad0b54 100644 --- a/tools/editor/editor_viewport.cpp +++ b/tools/editor/editor_viewport.cpp @@ -279,6 +279,7 @@ void EditorViewport::rebuildObjects(const std::vector& objects, v.pos[0]=x; v.pos[1]=y; v.pos[2]=z+h; verts.push_back(v); } npcMarkerVertCount_ = static_cast(verts.size()); + LOG_INFO("NPC markers: ", npcs.size(), " npcs -> ", npcMarkerVertCount_, " verts"); VkBufferCreateInfo bi{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; bi.size = verts.size() * sizeof(MV); bi.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; @@ -429,6 +430,8 @@ void EditorViewport::render(VkCommandBuffer cmd) { if (npcMarkerVB_ && npcMarkerVertCount_ > 0) { auto* wp = waterRenderer_.getPipeline(); auto* wl = waterRenderer_.getPipelineLayout(); + static bool loggedOnce = false; + if (!loggedOnce) { loggedOnce = true; LOG_INFO("NPC render: vb=", (wp?"ok":"null"), " layout=", (wl?"ok":"null"), " verts=", npcMarkerVertCount_); } if (wp && wl) { vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, wp); vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, wl,