Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Template for new versions:
- `bodyswap`: fix "invalid argument count" when the target unit has no nemesis record
- `fix/loyaltycascade`: guard against citizens that are not historical figures and emit a warning.
- `gui/siegemanager`: fix nil index if there are no siege engines on the map
- `item`: the ``reachable``/``unreachable`` filters no longer count installed building parts, and now treat loose contents of unwalkable buildings (like bolts loaded in a bolt thrower) as reachable when a citizen can stand next to the building

## Misc Improvements
- `caravan`: the ``Bring goods to depot``, ``Trade``, and ``Assign items for display`` overlays now allow searching for items with non-ASCII characters in their description
Expand Down
34 changes: 30 additions & 4 deletions item.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,38 @@ end
--- @return boolean
function fastReachable(item,wgroups)
local x, y, z = dfhack.items.getPosition(item)
if x then -- item has a valid position
local igroup = dfhack.maps.getWalkableGroup(xyz2pos(x, y, z))
return not not wgroups[igroup]
else
if not x then
return false -- item has no valid position (e.g., inside inventories)
end
local igroup = dfhack.maps.getWalkableGroup(xyz2pos(x, y, z))
if wgroups[igroup] then
return true
end
-- items on unwalkable building tiles can still be retrieved by standing
-- next to the building, unless they are installed parts (use_mode PERM)
local bld = dfhack.items.getHolderBuilding(item) or
dfhack.buildings.findAtTile(xyz2pos(x, y, z))
if not bld or bld:getType() == df.building_type.Construction then
return false
end
if df.building_actual:is_instance(bld) then
for _, ci in ipairs(bld.contained_items) do
if ci.item == item then
if ci.use_mode == df.building_item_role_type.PERM then
return false
end
break
end
end
end
for bx = bld.x1 - 1, bld.x2 + 1 do
for by = bld.y1 - 1, bld.y2 + 1 do
if wgroups[dfhack.maps.getWalkableGroup(xyz2pos(bx, by, bld.z))] then
return true
end
end
end
return false
end

--- @return table<integer,boolean>
Expand Down