From 09f573c6ee3e4260a8c8787bd8741f7af26245e1 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 01:27:50 -0700 Subject: [PATCH] feat(editor): patrol UI shows loop length and per-point wait time editor The patrol list now shows total loop distance and gives each waypoint a draggable wait-time field (0-60s). Helps tune patrol pacing without re-saving the JSON manually. --- tools/editor/editor_ui.cpp | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/tools/editor/editor_ui.cpp b/tools/editor/editor_ui.cpp index 7250b5c5..ab2b551e 100644 --- a/tools/editor/editor_ui.cpp +++ b/tools/editor/editor_ui.cpp @@ -1958,18 +1958,34 @@ void EditorUI::renderNpcPanel(EditorApp& app) { } } if (!sel->patrolPath.empty()) { - ImGui::BeginChild("PatrolList", ImVec2(0, 80), true); + // Compute total loop distance so users can see how long the cycle is. + float totalDist = 0.0f; + glm::vec3 prev = sel->position; + for (const auto& wp : sel->patrolPath) { + totalDist += glm::length(wp.position - prev); + prev = wp.position; + } + if (sel->patrolPath.size() >= 2) + totalDist += glm::length(sel->position - prev); + ImGui::TextDisabled("Loop length: %.0f units", totalDist); + + ImGui::BeginChild("PatrolList", ImVec2(0, 110), true); for (int pi = 0; pi < static_cast(sel->patrolPath.size()); pi++) { auto& pp = sel->patrolPath[pi]; - char lbl[64]; - std::snprintf(lbl, sizeof(lbl), "P%d (%.0f,%.0f,%.0f) %.1fs", - pi, pp.position.x, pp.position.y, pp.position.z, - pp.waitTimeMs / 1000.0f); - ImGui::Text("%s", lbl); + ImGui::PushID(pi); + ImGui::Text("P%d (%.0f,%.0f,%.0f)", + pi, pp.position.x, pp.position.y, pp.position.z); ImGui::SameLine(); - char delBtn[16]; std::snprintf(delBtn, sizeof(delBtn), "X##p%d", pi); - if (ImGui::SmallButton(delBtn)) + if (ImGui::SmallButton("X")) { sel->patrolPath.erase(sel->patrolPath.begin() + pi--); + ImGui::PopID(); + continue; + } + ImGui::SetNextItemWidth(80); + float waitS = pp.waitTimeMs / 1000.0f; + if (ImGui::DragFloat("wait s", &waitS, 0.25f, 0.0f, 60.0f, "%.1fs")) + pp.waitTimeMs = std::max(0.0f, waitS) * 1000.0f; + ImGui::PopID(); } ImGui::EndChild(); if (ImGui::Button("Clear Path##patrol"))