diff --git a/docs/Plugins.rst b/docs/Plugins.rst index b0621a373..d3c0b10be 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -2838,17 +2838,18 @@ Options: dig-now ======= -Instantly completes dig designations, modifying map tiles and creating boulders, -ores, and gems as if a miner were doing the mining or engraving. By default, all -dig designations on the map are completed and boulder generation follows -standard game rules, but the behavior is configurable. +Instantly completes dig designations for soil, rock, and mineral tiles, +modifying tile shapes and creating boulders, ores, and gems as if a miner were +doing the mining or engraving. By default, the entire map is processed and +boulder generation follows standard game rules, but the behavior is +configurable. Note that no units will get mining or engraving experience for the dug/engraved tiles. -Currently, trees are not chopped down and any designated trees or roots will be -ignored. Engravings are also not automatically generated by this plugin as they -depend on the skill and creative choices of individual engravers. +Surface tiles, trees, and roots will be ignored. Engravings are also not +automatically generated by this plugin as they depend on the skill and creative +choices of individual engravers. Usage:: diff --git a/plugins/dig-now.cpp b/plugins/dig-now.cpp index 3e293c0c7..15e9edebd 100644 --- a/plugins/dig-now.cpp +++ b/plugins/dig-now.cpp @@ -11,6 +11,7 @@ #include "modules/Maps.h" #include "modules/MapCache.h" #include "modules/Random.h" +#include "modules/Units.h" #include "modules/World.h" #include @@ -272,7 +273,6 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, std::vector &dug_tiles) { df::tiletype tt = map.tiletypeAt(pos); - // TODO: handle tree trunks, roots, and surface tiles df::tiletype_material tile_mat = tileMaterial(tt); if (!isGroundMaterial(tile_mat)) return false; @@ -593,7 +593,7 @@ static void create_boulders(color_ostream &out, DFCoord dump_pos; if (Maps::isValidTilePos(options.dump_pos)) { dump_pos = simulate_fall(options.dump_pos); - if (!Maps::isValidTilePos(dump_pos)) + if (!Maps::ensureTileBlock(dump_pos)) out.printerr("Invalid dump tile coordinates! Ensure the --dump" " option specifies an open, non-wall tile."); } @@ -627,7 +627,7 @@ static void create_boulders(color_ostream &out, for (size_t i = 0; i < num_items; ++i) { DFCoord pos = Maps::isValidTilePos(dump_pos) ? dump_pos : simulate_fall(coords[i]); - if (!Maps::isValidTilePos(pos)) { + if (!Maps::ensureTileBlock(pos)) { out.printerr( "unable to place boulder generated at (%d, %d, %d)\n", coords[i].x, coords[i].y, coords[i].z); @@ -652,11 +652,43 @@ static void flood_unhide(color_ostream &out, const DFCoord &pos) { Lua::SafeCall(out, L, 1, 0); } -static void unhide_dug_tiles(color_ostream &out, +static void post_process_dug_tiles(color_ostream &out, const std::vector &dug_coords) { - for (DFCoord pos : dug_coords) + for (DFCoord pos : dug_coords) { if (Maps::getTileDesignation(pos)->bits.hidden) flood_unhide(out, pos); + + df::tile_occupancy &to = *Maps::getTileOccupancy(pos); + if (to.bits.unit or to.bits.item) { + DFCoord resting_pos = simulate_fall(pos); + if (resting_pos == pos) + continue; + + if (!Maps::ensureTileBlock(resting_pos)) { + out.printerr("No valid tile beneath (%d, %d, %d); can't move" + " units and items to floor", + pos.x, pos.y, pos.z); + continue; + } + + if (to.bits.unit) { + std::vector units; + Units::getUnitsInBox(units, pos.x, pos.y, pos.z, + pos.x, pos.y, pos.z); + for (auto unit : units) + Units::teleport(unit, resting_pos); + } + + if (to.bits.item) { + for (auto item : world->items.other.IN_PLAY) { + if (item->pos == pos and item->flags.bits.on_ground) + item->moveToGround( + resting_pos.x, resting_pos.y, resting_pos.z); + } + } + } + + } } static bool get_options(color_ostream &out, @@ -721,7 +753,7 @@ command_result dig_now(color_ostream &out, std::vector ¶ms) { do_dig(out, dug_coords, item_coords, options); create_boulders(out, item_coords, options); - unhide_dug_tiles(out, dug_coords); + post_process_dug_tiles (out, dug_coords); // force the game to recompute its walkability cache world->reindex_pathfinding = true;