diff --git a/docs/changelog.txt b/docs/changelog.txt index 8730c9c446..df0b37b533 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -65,6 +65,7 @@ Template for new versions: - `aquifer`: make ``--skip-top`` and top-relative ``--levels`` take effect for the ``drain``, ``convert``, and ``add`` actions instead of being silently ignored - `autodump`: ``destroy`` no longer leaves the contents of destroyed containers in limbo or crashes when destroying unit-held items - `timestream`: deal properly with units who have breathing difficulties +- `buildingplan`: fix "Unlink all" only unlinking some mechanisms (or crashing) when freeing mechanisms from the building ## Misc Improvements - Added ``Coord2d`` and ``Coord3d`` C++ templates, providing a standard set operations for 2-tuples and 3-tuples of any numeric type diff --git a/plugins/lua/buildingplan/unlink_mechanisms.lua b/plugins/lua/buildingplan/unlink_mechanisms.lua index 81bd0fdabe..d6a676fdd1 100644 --- a/plugins/lua/buildingplan/unlink_mechanisms.lua +++ b/plugins/lua/buildingplan/unlink_mechanisms.lua @@ -402,8 +402,17 @@ function MechLinkOverlay:ask_unlink_all() local free_src = (saved_mode % 2 == 1) local free_dst = (saved_mode // 2 > 0) + -- freeing a mechanism removes it from contained_items and shifts the + -- indices of the entries after it, so resolve items before mutating + local items = {} for _, idx in ipairs(self.links) do - local item = self.building.contained_items[idx].item + local entry = self.building.contained_items[idx] + if entry then + table.insert(items, entry.item) + end + end + + for _, item in ipairs(items) do local target = get_mech_target(item) if target then