Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix gui/autodump dumping into walls, etc. #1242

Merged
merged 13 commits into from
Jul 31, 2024
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Template for new versions:
- `prioritize`: fix incorrect loading of persisted data on some OS types
- `list-waves`: no longer gets confused by units that leave the map and then return (e.g. squads who go out on raids)
- `fix/dead-units`: fix error when removing dead units from burrows and the unit with the greatest ID was dead
- `gui/autodump`: fix dumping into invalid tiles, creating item projectiles that get destroyed

## Misc Improvements
- `build-now`: if `suspendmanager` is running, run an unsuspend cycle immediately before scanning for buildings to build
Expand Down
50 changes: 43 additions & 7 deletions gui/autodump.lua
Original file line number Diff line number Diff line change
Expand Up @@ -306,14 +306,50 @@ function Autodump:onRenderFrame(dc, rect)
end
end

local function tile_props(pos, tt) --Returns is_ground, is_open_air
local shape_attrs = df.tiletype_shape.attrs[df.tiletype.attrs[tt].shape]
if shape_attrs.walkable then --TODO: don't dump on statues, etc.?
Bumber64 marked this conversation as resolved.
Show resolved Hide resolved
return true, false --Floor, stair, or ramp
elseif shape_attrs.basic_shape == df.tiletype_shape_basic.Wall then
return false, false --Wall or fortification
end

local _, occ = dfhack.maps.getTileFlags(pos)
if occ.building == df.tile_building_occ.None or
occ.building == df.tile_building_occ.Planned or
occ.building == df.tile_building_occ.Passable or
occ.building == df.tile_building_occ.Well then
return false, true --Item can fall safely through; any other may delete item projectile
elseif occ.building == df.tile_building_occ.Floored then
return true, false --Lowered bridge, forbidden hatch, etc.
elseif occ.building == df.tile_building_occ.Dynamic then
local bld = dfhack.buildings.findAtTile(pos) --Unforbidden hatch, etc.
return (bld and (bld._type == df.building_hatchst or
bld._type == df.building_grate_floorst or
bld._type == df.building_bars_floorst)), false
end
return false, false --Don't trust it
end

function Autodump:do_dump(pos)
pos = pos or dfhack.gui.getMousePos()
if not pos then return end
local tileattrs = df.tiletype.attrs[dfhack.maps.getTileType(pos)]
local basic_shape = df.tiletype_shape.attrs[tileattrs.shape].basic_shape
local on_ground = basic_shape == df.tiletype_shape_basic.Floor or
basic_shape == df.tiletype_shape_basic.Stair or
basic_shape == df.tiletype_shape_basic.Ramp
if not pos then
print('No cursor')
Bumber64 marked this conversation as resolved.
Show resolved Hide resolved
return
end

local tt = dfhack.maps.getTileType(pos)
if not tt then
print('No map block')
Bumber64 marked this conversation as resolved.
Show resolved Hide resolved
return
end

local on_ground, in_air = tile_props(pos, tt)
if not (on_ground or in_air) then
print('Dump tile blocked')
Bumber64 marked this conversation as resolved.
Show resolved Hide resolved
return
end

local items = #self.selected_items.list > 0 and self.selected_items.list or self.dump_items
local mark_as_forbidden = self.subviews.mark_as_forbidden:getOptionValue()
print(('teleporting %d items'):format(#items))
Expand All @@ -330,7 +366,7 @@ function Autodump:do_dump(pos)
if mark_as_forbidden then
item.flags.forbid = true
end
if not on_ground then
if in_air then
dfhack.items.makeProjectile(item)
end
else
Expand Down