Skip to content

Commit

Permalink
Merge pull request #1304 from myk002/myk_ownership
Browse files Browse the repository at this point in the history
[fix/ownership] check and fix room ownership links
  • Loading branch information
myk002 authored Sep 14, 2024
2 parents 5ca93b9 + b1f21fa commit 49f9c7f
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 16 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 16 additions & 6 deletions docs/fix/ownership.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,29 @@ 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
-----

::

fix/ownership

Links
-----

Among other issues, this tool fixes :bug:`6578`.
48 changes: 38 additions & 10 deletions fix/ownership.lua
Original file line number Diff line number Diff line change
@@ -1,29 +1,57 @@
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
print(dfhack.script_help())
return
end

owner_not_recognized()
clean_item_ownership()
relink_zones()

0 comments on commit 49f9c7f

Please sign in to comment.