diff --git a/tools/editor/editor_app.cpp b/tools/editor/editor_app.cpp index c9929286..ac9ee45f 100644 --- a/tools/editor/editor_app.cpp +++ b/tools/editor/editor_app.cpp @@ -603,6 +603,24 @@ void EditorApp::exportZone(const std::string& outputDir) { objectPlacer_.saveToFile(objPath); } + // Write zone info README + { + std::ofstream readme(base + "/README.txt"); + if (readme) { + readme << "Zone: " << loadedMap_ << "\n"; + readme << "Tile: [" << loadedTileX_ << ", " << loadedTileY_ << "]\n"; + readme << "Objects: " << objectPlacer_.objectCount() << "\n"; + readme << "NPCs: " << npcSpawner_.spawnCount() << "\n"; + readme << "Created with Wowee World Editor\n\n"; + readme << "Files:\n"; + readme << " zone.json - Zone manifest (for client)\n"; + readme << " " << loadedMap_ << ".wdt - Map definition\n"; + readme << " " << loadedMap_ << "_" << loadedTileX_ << "_" << loadedTileY_ << ".adt - Terrain tile\n"; + if (objectPlacer_.objectCount() > 0) readme << " objects.json - Placed M2/WMO objects\n"; + if (npcSpawner_.spawnCount() > 0) readme << " creatures.json - NPC/monster spawns\n"; + } + } + // Write zone manifest (for client loading) ZoneManifest manifest; manifest.mapName = loadedMap_; @@ -696,6 +714,18 @@ void EditorApp::addAdjacentTile(int offsetX, int offsetY) { std::to_string(newX) + "_" + std::to_string(newY) + ".adt"); } +void EditorApp::flyToSelected() { + auto* sel = objectPlacer_.getSelected(); + if (sel) { + camera_.setPosition(sel->position + glm::vec3(0, 0, 30)); + return; + } + auto* npc = npcSpawner_.getSelected(); + if (npc) { + camera_.setPosition(npc->position + glm::vec3(0, 0, 30)); + } +} + void EditorApp::snapSelectedToGround() { auto* sel = objectPlacer_.getSelected(); if (!sel || !terrain_.isLoaded()) return; diff --git a/tools/editor/editor_app.hpp b/tools/editor/editor_app.hpp index 65547ebd..3321c06a 100644 --- a/tools/editor/editor_app.hpp +++ b/tools/editor/editor_app.hpp @@ -72,6 +72,7 @@ public: void setGizmoAxis(TransformAxis axis); void setSkyPreset(int preset); // 0=day, 1=dusk, 2=night void snapSelectedToGround(); + void flyToSelected(); // Multi-tile support void addAdjacentTile(int offsetX, int offsetY); diff --git a/tools/editor/editor_ui.cpp b/tools/editor/editor_ui.cpp index 27d1db9b..64958f31 100644 --- a/tools/editor/editor_ui.cpp +++ b/tools/editor/editor_ui.cpp @@ -560,10 +560,13 @@ void EditorUI::renderObjectPanel(EditorApp& app) { if (changed) app.markObjectsDirty(); - if (ImGui::Button("Snap Ground", ImVec2(100, 0))) + if (ImGui::Button("Snap Ground", ImVec2(75, 0))) app.snapSelectedToGround(); ImGui::SameLine(); - if (ImGui::Button("Delete", ImVec2(100, 0))) placer.deleteSelected(); + if (ImGui::Button("Fly To", ImVec2(55, 0))) + app.flyToSelected(); + ImGui::SameLine(); + if (ImGui::Button("Delete", ImVec2(55, 0))) placer.deleteSelected(); if (ImGui::Button("Duplicate", ImVec2(100, 0))) { std::string dupPath = sel->path; glm::vec3 dupPos = sel->position + glm::vec3(10.0f, 10.0f, 0.0f); @@ -800,6 +803,9 @@ void EditorUI::renderNpcPanel(EditorApp& app) { } ImGui::Separator(); + if (ImGui::Button("Fly To##npc", ImVec2(55, 0))) + app.flyToSelected(); + ImGui::SameLine(); if (ImGui::Button("Duplicate##npc", ImVec2(80, 0))) { CreatureSpawn copy = *sel; copy.position += glm::vec3(10, 10, 0);