From bdf2497f46b5727ac255c24f6b3b49114966376c Mon Sep 17 00:00:00 2001 From: Kelsi Date: Thu, 7 May 2026 11:59:52 -0700 Subject: [PATCH] feat(editor): paint roads to/from selected objects/NPCs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The path tool gains a "Append selected as path point" button that captures the currently-selected entity's world position into pathPoints_. Workflow: place an inn + a town hall, select inn → click append, select town hall → click append, click Apply Path. The road is then drawn between the two object positions. When no object/NPC is selected, the button area shows a hint instead. The button auto-kicks pathCapture_ from None into Waiting* on first use so the user doesn't have to remember the setup sequence. Works with the multi-point polyline path tool from the previous commit — append three or more objects to route a road through them in order. --- tools/editor/editor_ui.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tools/editor/editor_ui.cpp b/tools/editor/editor_ui.cpp index c3ff775b..cdf39983 100644 --- a/tools/editor/editor_ui.cpp +++ b/tools/editor/editor_ui.cpp @@ -1032,6 +1032,40 @@ void EditorUI::renderBrushPanel(EditorApp& app) { ImGui::SliderFloat("Width##path", &pathWidth_, 2.0f, 50.0f); if (pathMode_ == 0) ImGui::SliderFloat("Depth##path", &pathDepth_, 1.0f, 30.0f); + // "Painting roads to/from models" — append the position of + // the currently-selected object or NPC as a path waypoint. + // Common workflow: place inn + town hall, select inn → click + // append, select town hall → click append, click Apply Path. + // The path then runs between them as a road. + const auto* selObj = app.getObjectPlacer().getSelected(); + const auto* selNpc = app.getNpcSpawner().getSelected(); + const char* srcLabel = selObj ? "object" : + selNpc ? "NPC" : nullptr; + glm::vec3 srcPos(0); + if (selObj) srcPos = selObj->position; + else if (selNpc) srcPos = selNpc->position; + if (srcLabel) { + std::string btn = std::string("Append selected ") + srcLabel + + " as path point"; + if (ImGui::Button(btn.c_str(), ImVec2(-1, 0))) { + // setPathPoint only acts when capture is in one of + // its waiting states. If we're idle, kick to + // WaitingStart for the first append; subsequent + // appends progress through Waiting* automatically. + if (pathCapture_ == PathCapture::None) { + pathCapture_ = pathPoints_.empty() + ? PathCapture::WaitingStart + : PathCapture::WaitingMore; + } + setPathPoint(srcPos); + app.showToast("Path point added at selected " + + std::string(srcLabel)); + } + } else { + ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1), + "Select an object or NPC to append its position as a path point."); + } + if (pathCapture_ == PathCapture::None && pathPoints_.empty()) { if (ImGui::Button("Click Start Point", ImVec2(-1, 0))) { pathCapture_ = PathCapture::WaitingStart;