feat(editor): in-editor "Audit Spawns Against Terrain" menu

EditorApp::auditSpawnsAgainstTerrain(threshold) counts every
creature + object whose Z is more than `threshold` yards off the
sampled terrain. Returns the issue count; non-mutating.

Generate menu gets a new "Audit Spawns Against Terrain" item that
runs the audit at the default 5y threshold and shows a toast: a
clean count if everything's fine, or the issue count + a hint to
run "Snap All" if not. Surfaces placement bugs without dropping
to the CLI.

Pairs with the existing "Snap All Spawns to Ground" so the
workflow stays inside the editor: audit → see count → snap →
audit again.
This commit is contained in:
Kelsi 2026-05-07 15:47:26 -07:00
parent 6c84a8da6c
commit 6a7ea6dcfc
3 changed files with 42 additions and 0 deletions

View file

@ -403,6 +403,19 @@ void EditorUI::renderMenuBar(EditorApp& app) {
ImGui::SetTooltip(
"Re-snap every creature + object's Z to actual terrain height.\n"
"Run after terrain edits to fix floating/buried spawns.");
if (ImGui::MenuItem("Audit Spawns Against Terrain", nullptr, false,
app.hasTerrainLoaded())) {
int issues = app.auditSpawnsAgainstTerrain(5.0f);
if (issues == 0)
app.showToast("Audit clean — every spawn within 5y of terrain");
else
app.showToast(std::to_string(issues) +
" spawn(s) more than 5y off terrain — try Snap All");
}
if (ImGui::IsItemHovered())
ImGui::SetTooltip(
"Count spawns whose Z is more than 5y off terrain.\n"
"Surfaces placement bugs without modifying anything.");
if (ImGui::MenuItem("Clear All Objects/NPCs", nullptr, false, app.hasTerrainLoaded())) {
if (app.getObjectPlacer().objectCount() > 0 || app.getNpcSpawner().spawnCount() > 0)
app.clearAllObjects();