From a14e732f0655633922ccf28c48a764257de7138d Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Fri, 13 Sep 2024 17:33:59 -0700 Subject: [PATCH 1/2] check and fix room ownership links --- changelog.txt | 1 + docs/fix/ownership.rst | 17 +++++++++------ fix/ownership.lua | 48 +++++++++++++++++++++++++++++++++--------- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/changelog.txt b/changelog.txt index ae1b4851e7..7444ef3d31 100644 --- a/changelog.txt +++ b/changelog.txt @@ -58,6 +58,7 @@ Template for new versions: - `assign-minecarts`: reassign vehicles to routes where the vehicle has been destroyed (or has otherwise gone missing) - `fix/dry-buckets`: prompt DF to recheck requests for aid (e.g. "bring water" jobs) when a bucket is unclogged and becomes available for use - `exterminate`: show descriptive names for the listed races in addition to their IDs +- `fix/ownership`: now also checks and fixes room ownership links ## Documentation - `gui/embark-anywhere`: add information about how the game determines world tile pathability and instructions for bridging two landmasses diff --git a/docs/fix/ownership.rst b/docs/fix/ownership.rst index 18ee5518a9..a0932ac5c6 100644 --- a/docs/fix/ownership.rst +++ b/docs/fix/ownership.rst @@ -2,15 +2,20 @@ fix/ownership ============= .. dfhack-tool:: - :summary: Fixes instances of units claiming the same item or an item they don't own. - :tags: fort bugfix units + :summary: Fixes ownership links. + :tags: fort bugfix items units -Due to a bug a unit can believe they own an item when they actually do not. +Due to a bug, a unit can believe they own an item when they actually do not. +Additionally, a room can remember that it is owned by a unit, but the unit can +forget that they own the room. -When enabled in `gui/control-panel`, `fix/ownership` will run once a day to check citizens and residents and make sure they don't -mistakenly own an item they shouldn't. +Invalid item ownership links result in units getting stuck in a "Store owned +item" job. Missing room ownership links result in rooms becoming unused by the +nominal owner and unclaimable by any other unit. In particular, nobles and +administrators will not recognize that their room requirements are met. -This should help issues of units getting stuck in a "Store owned item" job. +When enabled in `gui/control-panel`, `fix/ownership` will run once a day to +validate and fix ownership links for items and rooms. Usage ----- diff --git a/fix/ownership.lua b/fix/ownership.lua index b21b818a7e..c98dd42476 100644 --- a/fix/ownership.lua +++ b/fix/ownership.lua @@ -1,24 +1,51 @@ +local utils = require('utils') + -- unit thinks they own the item but the item doesn't hold the proper -- ref that actually makes this true -local function owner_not_recognized() +local function clean_item_ownership() for _,unit in ipairs(dfhack.units.getCitizens()) do for index = #unit.owned_items-1, 0, -1 do - local item = df.item.find(unit.owned_items[index]) - if not item then goto continue end - - for _, ref in ipairs(item.general_refs) do - if df.general_ref_unit_itemownerst:is_instance(ref) then - -- make sure the ref belongs to unit - if ref.unit_id == unit.id then goto continue end + local item_id = unit.owned_items[index] + local item = df.item.find(item_id) + if item then + for _, ref in ipairs(item.general_refs) do + if df.general_ref_unit_itemownerst:is_instance(ref) then + -- make sure the ref belongs to unit + if ref.unit_id == unit.id then goto continue end + end end end - print('Erasing ' .. dfhack.TranslateName(unit.name) .. ' invalid claim on item #' .. item.id) + print(('fix/ownership: Erasing invalid claim on item #%d for %s'):format( + item_id, dfhack.df2console(dfhack.units.getReadableName(unit)))) unit.owned_items:erase(index) ::continue:: end end end +local other = df.global.world.buildings.other +local zone_vecs = { + other.ZONE_BEDROOM, + other.ZONE_OFFICE, + other.ZONE_DINING_HALL, + other.ZONE_TOMB, +} +local function relink_zones() + for _,zones in ipairs(zone_vecs) do + for _,zone in ipairs(zones) do + local unit = zone.assigned_unit + if not unit then goto continue end + if not utils.linear_index(unit.owned_buildings, zone.id, 'id') then + print(('fix/ownership: Restoring %s ownership link for %s'):format( + df.civzone_type[zone:getSubtype()], dfhack.df2console(dfhack.units.getReadableName(unit)))) + dfhack.buildings.setOwner(zone, nil) + dfhack.buildings.setOwner(zone, unit) + end + ::continue:: + end + end +end + local args = {...} if args[1] == "help" then @@ -26,4 +53,5 @@ if args[1] == "help" then return end -owner_not_recognized() +clean_item_ownership() +relink_zones() From b1f21fa5a03c094651571aa7ee5993fee79d07b0 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Fri, 13 Sep 2024 17:35:45 -0700 Subject: [PATCH 2/2] refer to DF bug that this fixes --- docs/fix/ownership.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/fix/ownership.rst b/docs/fix/ownership.rst index a0932ac5c6..44c412db84 100644 --- a/docs/fix/ownership.rst +++ b/docs/fix/ownership.rst @@ -23,3 +23,8 @@ Usage :: fix/ownership + +Links +----- + +Among other issues, this tool fixes :bug:`6578`.