Skip to content

Commit 6dabac1

Browse files
authored
Merge pull request #1625 from Alistair-Afton/fix-item-building-reachability
item: items in unwalkable buildings are reachable from adjacent tiles
2 parents fe4805b + 997f9ee commit 6dabac1

2 files changed

Lines changed: 31 additions & 4 deletions

File tree

‎changelog.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Template for new versions:
4545
- `fix/loyaltycascade`: guard against citizens that are not historical figures and emit a warning.
4646
- `gui/settings-manager`: preserve built-in work details added after saved settings were created
4747
- `gui/siegemanager`: fix nil index if there are no siege engines on the map
48+
- `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
4849

4950
## Misc Improvements
5051
- `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

‎item.lua‎

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,38 @@ end
2121
--- @return boolean
2222
function fastReachable(item,wgroups)
2323
local x, y, z = dfhack.items.getPosition(item)
24-
if x then -- item has a valid position
25-
local igroup = dfhack.maps.getWalkableGroup(xyz2pos(x, y, z))
26-
return not not wgroups[igroup]
27-
else
24+
if not x then
25+
return false -- item has no valid position (e.g., inside inventories)
26+
end
27+
local igroup = dfhack.maps.getWalkableGroup(xyz2pos(x, y, z))
28+
if wgroups[igroup] then
29+
return true
30+
end
31+
-- items on unwalkable building tiles can still be retrieved by standing
32+
-- next to the building, unless they are installed parts (use_mode PERM)
33+
local bld = dfhack.items.getHolderBuilding(item) or
34+
dfhack.buildings.findAtTile(xyz2pos(x, y, z))
35+
if not bld or bld:getType() == df.building_type.Construction then
2836
return false
2937
end
38+
if df.building_actual:is_instance(bld) then
39+
for _, ci in ipairs(bld.contained_items) do
40+
if ci.item == item then
41+
if ci.use_mode == df.building_item_role_type.PERM then
42+
return false
43+
end
44+
break
45+
end
46+
end
47+
end
48+
for bx = bld.x1 - 1, bld.x2 + 1 do
49+
for by = bld.y1 - 1, bld.y2 + 1 do
50+
if wgroups[dfhack.maps.getWalkableGroup(xyz2pos(bx, by, bld.z))] then
51+
return true
52+
end
53+
end
54+
end
55+
return false
3056
end
3157

3258
--- @return table<integer,boolean>

0 commit comments

Comments
 (0)