From 4d11949048728558e36c78ed1d294692863e3632 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 04:23:39 -0700 Subject: [PATCH] fix(editor): preserve PlacedObject uniqueId across JSON save/load uniqueId was always regenerated on load, so re-saving the same zone produced a different uniqueId per placement each time. Since syncToTerrain copies obj.uniqueId into MDDF/MODF, the ADT also rotated uniqueIds across cycles. Now JSON stores uniqueId, the loader reads it back when present (falling back to nextUniqueId() for legacy files), and uniqueIdCounter_ is bumped past any loaded value so future placements never collide. --- tools/editor/object_placer.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tools/editor/object_placer.cpp b/tools/editor/object_placer.cpp index 8b807114..bc0c7d0c 100644 --- a/tools/editor/object_placer.cpp +++ b/tools/editor/object_placer.cpp @@ -263,7 +263,8 @@ bool ObjectPlacer::saveToFile(const std::string& path) const { {"path", o.path}, {"pos", {o.position.x, o.position.y, o.position.z}}, {"rot", {o.rotation.x, o.rotation.y, o.rotation.z}}, - {"scale", o.scale} + {"scale", o.scale}, + {"uniqueId", o.uniqueId} }); } @@ -306,7 +307,16 @@ bool ObjectPlacer::loadFromFile(const std::string& path) { } if (!obj.path.empty()) { - obj.uniqueId = nextUniqueId(); + // Preserve original uniqueId from JSON if present so ADT round-trip + // is stable. Bump uniqueIdCounter_ past any loaded value to avoid + // collisions with future placements. + if (jo.contains("uniqueId")) { + obj.uniqueId = jo["uniqueId"].get(); + if (obj.uniqueId >= uniqueIdCounter_) + uniqueIdCounter_ = obj.uniqueId + 1; + } else { + obj.uniqueId = nextUniqueId(); + } objects_.push_back(obj); } }