diff --git a/docs/changelog.txt b/docs/changelog.txt index 57daef38c..9ee7ff102 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -42,7 +42,6 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `autodump`: changed behaviour to only change ``dump`` and ``forbid`` flags if an item is successfully dumped. -@ `autochop`: generate default names for burrows with no assigned names - ``Buildings::StockpileIterator``: fix check for stockpile items on block boundary. -- `dig-now`: fixed multi-layer channel designations only channeling every second layer - `tailor`: block making clothing sized for toads; make replacement clothing orders use the size of the wearer, not the size of the garment -@ `confirm`: fix fps drop when enabled @@ -52,7 +51,6 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `showmood`: now shows the number of items needed for cloth and bars in addition to the technically correct but always confusing "total dimension" (150 per bar or 10,000 per cloth) -@ Stopped mouse clicks from affecting the map when a click on a DFHack screen dismisses the window - `confirm`: configuration data is now persisted globally. -- `dig-now`: added handling of dig designations that have been converted into active jobs - `tailor`: add support for adamantine cloth (off by default); improve logging ## Documentation diff --git a/plugins/dig-now.cpp b/plugins/dig-now.cpp index e94cb41da..6227f44f5 100644 --- a/plugins/dig-now.cpp +++ b/plugins/dig-now.cpp @@ -6,7 +6,6 @@ #include "PluginManager.h" #include "TileTypes.h" #include "LuaTools.h" -#include "Debug.h" #include "modules/Buildings.h" #include "modules/Gui.h" @@ -15,8 +14,6 @@ #include "modules/Random.h" #include "modules/Units.h" #include "modules/World.h" -#include "modules/EventManager.h" -#include "modules/Job.h" #include #include @@ -29,129 +26,12 @@ #include #include -#include -#include -#include - DFHACK_PLUGIN("dig-now"); REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(world); -// Debugging -namespace DFHack { - DBG_DECLARE(dignow, general, DebugCategory::LINFO); - DBG_DECLARE(dignow, channels, DebugCategory::LINFO); -} - -#define COORD "%" PRIi16 " %" PRIi16 " %" PRIi16 -#define COORDARGS(id) id.x, id.y, id.z - using namespace DFHack; -struct designation{ - df::coord pos; - df::tile_designation type; - df::tile_occupancy occupancy; - designation() = default; - designation(const df::coord &c, const df::tile_designation &td, const df::tile_occupancy &to) : pos(c), type(td), occupancy(to) {} - - bool operator==(const designation &rhs) const { - return pos == rhs.pos; - } - - bool operator!=(const designation &rhs) const { - return !(rhs == *this); - } -}; - -namespace std { - template<> - struct hash { - std::size_t operator()(const designation &c) const { - std::hash hash_coord; - return hash_coord(c.pos); - } - }; -} - -class DesignationJobs { -private: - std::unordered_map designations; - std::unordered_map jobs; -public: - void load(MapExtras::MapCache &map) { - designations.clear(); - df::job_list_link* node = df::global::world->jobs.list.next; - while (node) { - df::job* job = node->item; - if(!job || !Maps::isValidTilePos(job->pos)) - continue; - - node = node->next; - df::tile_designation td = map.designationAt(job->pos); - df::tile_occupancy to = map.occupancyAt(job->pos); - const auto ctd = td.whole; - const auto cto = to.whole; - switch (job->job_type){ - case job_type::Dig: - td.bits.dig = tile_dig_designation::Default; - break; - case job_type::DigChannel: - td.bits.dig = tile_dig_designation::Channel; - break; - case job_type::CarveRamp: - td.bits.dig = tile_dig_designation::Ramp; - break; - case job_type::CarveUpwardStaircase: - td.bits.dig = tile_dig_designation::UpStair; - break; - case job_type::CarveDownwardStaircase: - td.bits.dig = tile_dig_designation::DownStair; - break; - case job_type::CarveUpDownStaircase: - td.bits.dig = tile_dig_designation::UpDownStair; - break; - case job_type::DetailWall: - case job_type::DetailFloor: { - df::tiletype tt = map.tiletypeAt(job->pos); - if (tileSpecial(tt) != df::tiletype_special::SMOOTH) { - td.bits.smooth = 1; - } - break; - } - case job_type::CarveTrack: - to.bits.carve_track_north = (job->item_category.whole >> 18) & 1; - to.bits.carve_track_south = (job->item_category.whole >> 19) & 1; - to.bits.carve_track_west = (job->item_category.whole >> 20) & 1; - to.bits.carve_track_east = (job->item_category.whole >> 21) & 1; - break; - default: - break; - } - if (ctd != td.whole || cto != to.whole) { - // we found a designation job - designations.emplace(job->pos, designation(job->pos, td, to)); - jobs.emplace(job->pos, job); - } - } - } - void remove(const df::coord &pos) { - if(jobs.count(pos)) { - Job::removeJob(jobs[pos]); - jobs.erase(pos); - } - } - designation get(const df::coord &pos) { - if (designations.count(pos)) { - return designations[pos]; - } - return {}; - } - bool count(const df::coord &pos) { - return jobs.count(pos); - } -}; - struct boulder_percent_options { // percent chance ([0..100]) for creating a boulder for the given rock type uint32_t layer; @@ -440,19 +320,8 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, std::vector &dug_tiles) { df::tiletype tt = map.tiletypeAt(pos); - if (!is_diggable(map, pos, tt)) { - DEBUG(general).print("dig_tile: not diggable\n"); + if (!is_diggable(map, pos, tt)) return false; - } - - /** The algorithm process seems to be: - * for each tile - * check for a designation - * if a designation exists send it to dig_tile - * - * dig_tile (below) then digs the layer below the channel designated tile - * thereby changing it and causing its designation to be lost - * */ df::tiletype target_type = df::tiletype::Void; switch(designation) { @@ -472,22 +341,19 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, DFCoord pos_below(pos.x, pos.y, pos.z-1); if (can_dig_channel(tt) && map.ensureBlockAt(pos_below) && is_diggable(map, pos_below, map.tiletypeAt(pos_below))) { - TRACE(channels).print("dig_tile: channeling at (" COORD ") [can_dig_channel: true]\n",COORDARGS(pos_below)); target_type = df::tiletype::OpenSpace; DFCoord pos_above(pos.x, pos.y, pos.z+1); - if (map.ensureBlockAt(pos_above)) { + if (map.ensureBlockAt(pos_above)) remove_ramp_top(map, pos_above); - } - df::tile_dig_designation td_below = map.designationAt(pos_below).bits.dig; - if (dig_tile(out, map, pos_below, df::tile_dig_designation::Ramp, dug_tiles)) { + df::tile_dig_designation td_below = + map.designationAt(pos_below).bits.dig; + if (dig_tile(out, map, pos_below, + df::tile_dig_designation::Ramp, dug_tiles)) { clean_ramps(map, pos_below); - if (td_below == df::tile_dig_designation::Default) { + if (td_below == df::tile_dig_designation::Default) dig_tile(out, map, pos_below, td_below, dug_tiles); - } return true; } - } else { - DEBUG(channels).print("dig_tile: failed to channel at (" COORD ") [can_dig_channel: false]\n", COORDARGS(pos_below)); } break; } @@ -541,8 +407,7 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, if (target_type == df::tiletype::Void || target_type == tt) return false; - dug_tiles.emplace_back(map, pos); - TRACE(general).print("dig_tile: digging the designation tile at (" COORD ")\n",COORDARGS(pos)); + dug_tiles.push_back(dug_tile_info(map, pos)); dig_type(map, pos, target_type); // let light filter down to newly exposed tiles @@ -729,12 +594,9 @@ static void do_dig(color_ostream &out, std::vector &dug_coords, item_coords_t &item_coords, const dig_now_options &options) { MapExtras::MapCache map; Random::MersenneRNG rng; - DesignationJobs jobs; - jobs.load(map); rng.init(); - std::unordered_set buffer; // go down levels instead of up so stacked ramps behave as expected for (int16_t z = options.end.z; z >= options.start.z; --z) { for (int16_t y = options.start.y; y <= options.end.y; ++y) { @@ -747,68 +609,46 @@ static void do_dig(color_ostream &out, std::vector &dug_coords, DFCoord pos(x, y, z); df::tile_designation td = map.designationAt(pos); df::tile_occupancy to = map.occupancyAt(pos); - if (jobs.count(pos)) { - buffer.emplace(jobs.get(pos)); - jobs.remove(pos); - // if it does get removed, then we're gonna buffer the jobs info then remove the job - } else if ((td.bits.dig != df::tile_dig_designation::No && !to.bits.dig_marked) - || td.bits.smooth == 1 - || to.bits.carve_track_north == 1 - || to.bits.carve_track_east == 1 - || to.bits.carve_track_south == 1 - || to.bits.carve_track_west == 1) { - - // we're only buffering designations, so that processing doesn't affect what we're buffering - buffer.emplace(pos, td, to); - } - } - } - } - - // process designations - for(auto &d : buffer) { - auto pos = d.pos; - auto td = d.type; - auto to = d.occupancy; - - if (td.bits.dig != df::tile_dig_designation::No && !to.bits.dig_marked) { - std::vector dug_tiles; - - if (dig_tile(out, map, pos, td.bits.dig, dug_tiles)) { - for (auto info: dug_tiles) { - td = map.designationAt(info.pos); - td.bits.dig = df::tile_dig_designation::No; - map.setDesignationAt(info.pos, td); - - dug_coords.push_back(info.pos); - refresh_adjacent_smooth_walls(map, info.pos); - if (info.imat < 0) - continue; - if (produces_item(options.boulder_percents, - map, rng, info)) { - auto k = std::make_pair(info.itype, info.imat); - item_coords[k].push_back(info.pos); + if (td.bits.dig != df::tile_dig_designation::No && + !to.bits.dig_marked) { + std::vector dug_tiles; + if (dig_tile(out, map, pos, td.bits.dig, dug_tiles)) { + for (auto info : dug_tiles) { + td = map.designationAt(info.pos); + td.bits.dig = df::tile_dig_designation::No; + map.setDesignationAt(info.pos, td); + + dug_coords.push_back(info.pos); + refresh_adjacent_smooth_walls(map, info.pos); + if (info.imat < 0) + continue; + if (produces_item(options.boulder_percents, + map, rng, info)) { + auto k = std::make_pair(info.itype, info.imat); + item_coords[k].push_back(info.pos); + } + } + } + } else if (td.bits.smooth == 1) { + if (smooth_tile(out, map, pos)) { + td = map.designationAt(pos); + td.bits.smooth = 0; + map.setDesignationAt(pos, td); + } + } else if (to.bits.carve_track_north == 1 + || to.bits.carve_track_east == 1 + || to.bits.carve_track_south == 1 + || to.bits.carve_track_west == 1) { + if (carve_tile(map, pos, to)) { + to = map.occupancyAt(pos); + to.bits.carve_track_north = 0; + to.bits.carve_track_east = 0; + to.bits.carve_track_south = 0; + to.bits.carve_track_west = 0; + map.setOccupancyAt(pos, to); } } } - } else if (td.bits.smooth == 1) { - if (smooth_tile(out, map, pos)) { - td = map.designationAt(pos); - td.bits.smooth = 0; - map.setDesignationAt(pos, td); - } - } else if (to.bits.carve_track_north == 1 - || to.bits.carve_track_east == 1 - || to.bits.carve_track_south == 1 - || to.bits.carve_track_west == 1) { - if (carve_tile(map, pos, to)) { - to = map.occupancyAt(pos); - to.bits.carve_track_north = 0; - to.bits.carve_track_east = 0; - to.bits.carve_track_south = 0; - to.bits.carve_track_west = 0; - map.setOccupancyAt(pos, to); - } } }