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
2 changes: 2 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ 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`: prevent dumping into walls or invalid map area, as well as selecting in unallocated blocks
- `gui/autodump`: set proper projectile flags to prevent items from being destroyed

## Misc Improvements
- `build-now`: if `suspendmanager` is running, run an unsuspend cycle immediately before scanning for buildings to build
Expand Down
5 changes: 3 additions & 2 deletions docs/gui/autodump.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ This is a general point and click interface for teleporting or destroying
items. By default, it will teleport items you have marked for dumping, but if
you draw boxes around items on the map, it will act on the selected items
instead. Double-click anywhere on the map to teleport the items there. Be wary
(or excited) that if you teleport the items into an unsupported position (e.g.
mid-air), then they will become projectiles and fall.
(or excited) that if you teleport the items into an unsupported position
(e.g., mid-air), then they will become projectiles and fall. Items may not be
teleported into walls or hidden tiles.

There are options to include or exclude forbidden items, items that are
currently tagged as being used by an active job, and items dropped by traders.
Expand Down
38 changes: 30 additions & 8 deletions gui/autodump.lua
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ function Autodump:select_box(bounds)
for x=bounds.x1,bounds.x2 do
local block = dfhack.maps.getTileBlock(xyz2pos(x, y, z))
local block_str = tostring(block)
if not seen_blocks[block_str] then
if block and not seen_blocks[block_str] then
seen_blocks[block_str] = true
self:select_items_in_block(block, bounds)
end
Expand Down Expand Up @@ -308,12 +308,26 @@ 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 --We check this before calling
qerror('Autodump:do_dump called with bad pos!')
end

local tt = dfhack.maps.getTileType(pos)
if not (tt and dfhack.maps.isTileVisible(pos)) then
dfhack.printerr('Dump tile not visible! Must be in a revealed area of map.')
return
end

local on_ground
local shape = df.tiletype.attrs[tt].shape
local shape_attrs = df.tiletype_shape.attrs[shape]
if shape_attrs.walkable or shape == df.tiletype_shape.FORTIFICATION then
on_ground = true --Floor, stair, ramp, or fortification
elseif shape_attrs.basic_shape == df.tiletype_shape_basic.Wall then
dfhack.printerr('Dump tile blocked! Can\'t dump inside walls.') --Wall or brook bed
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 @@ -331,7 +345,15 @@ function Autodump:do_dump(pos)
item.flags.forbid = true
end
if not on_ground then
dfhack.items.makeProjectile(item)
local proj = dfhack.items.makeProjectile(item)
if proj then
proj.flags.no_impact_destroy = true
proj.flags.bouncing = true
proj.flags.piercing = true
proj.flags.parabolic = true
proj.flags.no_adv_pause = true
proj.flags.no_collide = true
myk002 marked this conversation as resolved.
Show resolved Hide resolved
end
end
else
print(('Could not move item: %s from (%d, %d, %d)'):format(
Expand Down