From 456020fb383da038fd13a2a37499f58faa5cece3 Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Sun, 29 Jan 2023 13:53:50 -0800 Subject: [PATCH 1/8] Adds todo comments to dig-now.cpp for issue #2720 --- plugins/dig-now.cpp | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/plugins/dig-now.cpp b/plugins/dig-now.cpp index 9945ee2b0..6836a6331 100644 --- a/plugins/dig-now.cpp +++ b/plugins/dig-now.cpp @@ -320,8 +320,10 @@ 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)) + if (!is_diggable(map, pos, tt)) { + out.print("dig_tile: not diggable\n"); return false; + } df::tiletype target_type = df::tiletype::Void; switch(designation) { @@ -339,19 +341,23 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, case df::tile_dig_designation::Channel: { DFCoord pos_below(pos.x, pos.y, pos.z-1); + // todo: does can_dig_channel return false? if (can_dig_channel(tt) && map.ensureBlockAt(pos_below) && is_diggable(map, pos_below, map.tiletypeAt(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; + + // todo: what is this chain of dig_tile(below)? + 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) { + // todo: removing ramp? dig_tile(out, map, pos_below, td_below, dug_tiles); + } return true; } } @@ -407,7 +413,7 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, if (target_type == df::tiletype::Void || target_type == tt) return false; - dug_tiles.push_back(dug_tile_info(map, pos)); + dug_tiles.emplace_back(map, pos); dig_type(map, pos, target_type); // let light filter down to newly exposed tiles @@ -606,14 +612,17 @@ static void do_dig(color_ostream &out, std::vector &dug_coords, if (!Maps::getTileBlock(x, y, z)) continue; + // todo: check if tile is in the job list with a dig type + DFCoord pos(x, y, z); df::tile_designation td = map.designationAt(pos); df::tile_occupancy to = map.occupancyAt(pos); - if (td.bits.dig != df::tile_dig_designation::No && - !to.bits.dig_marked) { + if (td.bits.dig != df::tile_dig_designation::No && !to.bits.dig_marked) { std::vector dug_tiles; + + // todo: check why dig_tile doesn't dig the second layer of channels if (dig_tile(out, map, pos, td.bits.dig, dug_tiles)) { - for (auto info : 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); @@ -629,6 +638,7 @@ static void do_dig(color_ostream &out, std::vector &dug_coords, } } } + // todo: check mark mode of smooth designations } else if (td.bits.smooth == 1) { if (smooth_tile(out, map, pos)) { to = map.occupancyAt(pos); @@ -636,9 +646,9 @@ static void do_dig(color_ostream &out, std::vector &dug_coords, 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) { + || 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; From 838acfdf223270c9cdd2936a69cb256d8576287e Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Tue, 7 Feb 2023 16:32:13 -0800 Subject: [PATCH 2/8] Adds a few log lines to dig-now --- plugins/dig-now.cpp | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/plugins/dig-now.cpp b/plugins/dig-now.cpp index 6836a6331..9f961c817 100644 --- a/plugins/dig-now.cpp +++ b/plugins/dig-now.cpp @@ -6,6 +6,7 @@ #include "PluginManager.h" #include "TileTypes.h" #include "LuaTools.h" +#include "Debug.h" #include "modules/Buildings.h" #include "modules/Gui.h" @@ -26,10 +27,23 @@ #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 + +// todo: integrate logging for debugging the layered channel problem + using namespace DFHack; struct boulder_percent_options { @@ -321,10 +335,19 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, df::tiletype tt = map.tiletypeAt(pos); if (!is_diggable(map, pos, tt)) { - out.print("dig_tile: not diggable\n"); + DEBUG(general).print("dig_tile: not diggable\n"); 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) { case df::tile_dig_designation::Default: @@ -344,6 +367,7 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, // todo: does can_dig_channel return false? 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 ")\n",COORDARGS(pos_below)); target_type = df::tiletype::OpenSpace; DFCoord pos_above(pos.x, pos.y, pos.z+1); if (map.ensureBlockAt(pos_above)) { @@ -360,6 +384,8 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, } return true; } + } else { + DEBUG(channels).print("dig_tile: failed to channel at (" COORD ")\n", COORDARGS(pos_below)); } break; } @@ -414,6 +440,7 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, return false; dug_tiles.emplace_back(map, pos); + TRACE(general).print("dig_tile: digging the designation tile at (" COORD ")\n",COORDARGS(pos)); dig_type(map, pos, target_type); // let light filter down to newly exposed tiles @@ -613,6 +640,8 @@ static void do_dig(color_ostream &out, std::vector &dug_coords, continue; // todo: check if tile is in the job list with a dig type + // todo: if it is cancel the job. Then check if the designation is removed on the map + // todo: if the designation does disappear on the map, just rewrite things to queue the designation info that needs to be processed DFCoord pos(x, y, z); df::tile_designation td = map.designationAt(pos); From c990def894429c43df0f977661287489a3d3c406 Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Mon, 13 Feb 2023 17:35:17 -0800 Subject: [PATCH 3/8] Adds a designation buffer in dig-now's processing algorithm This may fix the issue seen when channeling consecutive layers, needs to be tested --- plugins/dig-now.cpp | 123 ++++++++++++++++++++++++++++---------------- 1 file changed, 80 insertions(+), 43 deletions(-) diff --git a/plugins/dig-now.cpp b/plugins/dig-now.cpp index 9f961c817..2f63c54da 100644 --- a/plugins/dig-now.cpp +++ b/plugins/dig-now.cpp @@ -15,6 +15,7 @@ #include "modules/Random.h" #include "modules/Units.h" #include "modules/World.h" +#include "modules/EventManager.h" #include #include @@ -28,6 +29,7 @@ #include #include +#include DFHACK_PLUGIN("dig-now"); REQUIRE_GLOBAL(plotinfo); @@ -46,6 +48,31 @@ namespace DFHack { using namespace DFHack; +struct designation{ + df::coord pos; + df::tile_designation type; + df::tile_occupancy occupancy; + 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); + } + }; +} + struct boulder_percent_options { // percent chance ([0..100]) for creating a boulder for the given rock type uint32_t layer; @@ -367,7 +394,7 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, // todo: does can_dig_channel return false? 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 ")\n",COORDARGS(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)) { @@ -375,17 +402,16 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, } df::tile_dig_designation td_below = map.designationAt(pos_below).bits.dig; - // todo: what is this chain of dig_tile(below)? + // todo: digging to floor below? 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) { - // todo: removing ramp? dig_tile(out, map, pos_below, td_below, dug_tiles); } return true; } } else { - DEBUG(channels).print("dig_tile: failed to channel at (" COORD ")\n", COORDARGS(pos_below)); + DEBUG(channels).print("dig_tile: failed to channel at (" COORD ") [can_dig_channel: false]\n", COORDARGS(pos_below)); } break; } @@ -630,6 +656,7 @@ static void do_dig(color_ostream &out, std::vector &dug_coords, 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) { @@ -646,48 +673,58 @@ 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 (td.bits.dig != df::tile_dig_designation::No && !to.bits.dig_marked) { - std::vector dug_tiles; - - // todo: check why dig_tile doesn't dig the second layer of channels - 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); - } - } - } - // todo: check mark mode of smooth designations - } else if (td.bits.smooth == 1) { - if (smooth_tile(out, map, pos)) { - to = map.occupancyAt(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); + + // 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); } } } + // todo: check mark mode of smooth designations + } else if (td.bits.smooth == 1) { + if (smooth_tile(out, map, pos)) { + to = map.occupancyAt(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); + } } } From 1e21f1ece954e3ff470c0a592228a58acc68db13 Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Mon, 13 Feb 2023 18:02:33 -0800 Subject: [PATCH 4/8] Adds validity checks before adding to the dig-now buffer also adds job cancellation for designation jobs, for testing a solution to issue 2471 --- plugins/dig-now.cpp | 75 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/plugins/dig-now.cpp b/plugins/dig-now.cpp index 2f63c54da..0c9a79462 100644 --- a/plugins/dig-now.cpp +++ b/plugins/dig-now.cpp @@ -16,6 +16,7 @@ #include "modules/Units.h" #include "modules/World.h" #include "modules/EventManager.h" +#include "modules/Job.h" #include #include @@ -30,6 +31,7 @@ #include #include +#include DFHACK_PLUGIN("dig-now"); REQUIRE_GLOBAL(plotinfo); @@ -73,6 +75,56 @@ namespace std { }; } +class DigJobs { +private: + std::unordered_map designations; + std::unordered_map jobs; +public: + void load() { + designations.clear(); + df::job_list_link* node = df::global::world->jobs.list.next; + while (node) { + df::job* job = node->item; + jobs.emplace(job->pos, job); + node = node->next; + switch (job->job_type){ + case df::enums::job_type::Dig: + designations.emplace(job->pos, df::tile_dig_designation::Default); + break; + case df::enums::job_type::DigChannel: + designations.emplace(job->pos, df::tile_dig_designation::Channel); + break; + case df::enums::job_type::CarveRamp: + designations.emplace(job->pos, df::tile_dig_designation::Ramp); + break; + case df::enums::job_type::CarveUpwardStaircase: + designations.emplace(job->pos, df::tile_dig_designation::UpStair); + break; + case df::enums::job_type::CarveDownwardStaircase: + designations.emplace(job->pos, df::tile_dig_designation::DownStair); + break; + case df::enums::job_type::CarveUpDownStaircase: + designations.emplace(job->pos, df::tile_dig_designation::UpDownStair); + break; + default: + break; + } + } + } + void remove(const df::coord &pos) { + if(jobs.count(pos)) { + Job::removeJob(jobs[pos]); + jobs.erase(pos); + } + } + df::tile_dig_designation get(const df::coord &pos) { + if (designations.count(pos)) { + return designations[pos]; + } + return df::enums::tile_dig_designation::No; + } +}; + struct boulder_percent_options { // percent chance ([0..100]) for creating a boulder for the given rock type uint32_t layer; @@ -653,7 +705,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; + DigJobs jobs; + jobs.load(); rng.init(); std::unordered_set buffer; @@ -666,16 +720,25 @@ static void do_dig(color_ostream &out, std::vector &dug_coords, if (!Maps::getTileBlock(x, y, z)) continue; - // todo: check if tile is in the job list with a dig type - // todo: if it is cancel the job. Then check if the designation is removed on the map - // todo: if the designation does disappear on the map, just rewrite things to queue the designation info that needs to be processed - DFCoord pos(x, y, z); df::tile_designation td = map.designationAt(pos); df::tile_occupancy to = map.occupancyAt(pos); + if (jobs.get(pos) != df::enums::tile_dig_designation::No) { + // todo: check if the designation is removed from the map + jobs.remove(pos); + // if it does get removed, then we're gonna buffer the jobs info then remove the job + } + + 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); + // we're only buffering designations, so that processing doesn't affect what we're buffering + buffer.emplace(pos, td, to); + } } } } From 8beb947c82494bf1c08b74b48ef668cc3ace0ad9 Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Wed, 15 Feb 2023 13:03:31 -0800 Subject: [PATCH 5/8] Revises job scanning for dig-now --- plugins/dig-now.cpp | 74 ++++++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/plugins/dig-now.cpp b/plugins/dig-now.cpp index 0c9a79462..68a5361a5 100644 --- a/plugins/dig-now.cpp +++ b/plugins/dig-now.cpp @@ -54,6 +54,7 @@ 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 { @@ -75,40 +76,62 @@ namespace std { }; } -class DigJobs { +class DesignationJobs { private: - std::unordered_map designations; + std::unordered_map designations; std::unordered_map jobs; public: - void load() { + 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; jobs.emplace(job->pos, job); 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 df::enums::job_type::Dig: - designations.emplace(job->pos, df::tile_dig_designation::Default); + case job_type::Dig: + td.bits.dig = tile_dig_designation::Default; break; - case df::enums::job_type::DigChannel: - designations.emplace(job->pos, df::tile_dig_designation::Channel); + case job_type::DigChannel: + td.bits.dig = tile_dig_designation::Channel; break; - case df::enums::job_type::CarveRamp: - designations.emplace(job->pos, df::tile_dig_designation::Ramp); + case job_type::CarveRamp: + td.bits.dig = tile_dig_designation::Ramp; break; - case df::enums::job_type::CarveUpwardStaircase: - designations.emplace(job->pos, df::tile_dig_designation::UpStair); + case job_type::CarveUpwardStaircase: + td.bits.dig = tile_dig_designation::UpStair; break; - case df::enums::job_type::CarveDownwardStaircase: - designations.emplace(job->pos, df::tile_dig_designation::DownStair); + case job_type::CarveDownwardStaircase: + td.bits.dig = tile_dig_designation::DownStair; break; - case df::enums::job_type::CarveUpDownStaircase: - designations.emplace(job->pos, df::tile_dig_designation::UpDownStair); + 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 = 0 < (job->item_category.whole & 18); + to.bits.carve_track_south = 0 < (job->item_category.whole & 19); + to.bits.carve_track_west = 0 < (job->item_category.whole & 20); + to.bits.carve_track_east = 0 < (job->item_category.whole & 21); break; default: break; } + if (ctd != td.whole || cto != to.whole) { + // we found a designation job + designations.emplace(job->pos, designation(job->pos, td, to)); + } } } void remove(const df::coord &pos) { @@ -117,11 +140,14 @@ public: jobs.erase(pos); } } - df::tile_dig_designation get(const df::coord &pos) { + designation get(const df::coord &pos) { if (designations.count(pos)) { return designations[pos]; } - return df::enums::tile_dig_designation::No; + return {}; + } + bool count(const df::coord &pos) { + return jobs.count(pos); } }; @@ -705,9 +731,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; - DigJobs jobs; + DesignationJobs jobs; - jobs.load(); + jobs.load(map); rng.init(); std::unordered_set buffer; @@ -723,13 +749,11 @@ 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.get(pos) != df::enums::tile_dig_designation::No) { - // todo: check if the designation is removed from the map + 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 - } - - if ((td.bits.dig != df::tile_dig_designation::No && !to.bits.dig_marked) + } 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 @@ -772,7 +796,7 @@ static void do_dig(color_ostream &out, std::vector &dug_coords, // todo: check mark mode of smooth designations } else if (td.bits.smooth == 1) { if (smooth_tile(out, map, pos)) { - to = map.occupancyAt(pos); + td = map.designationAt(pos); td.bits.smooth = 0; map.setDesignationAt(pos, td); } From 249c6590069c10eaee251fa2b1b0feb5b056b9f1 Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Wed, 15 Feb 2023 16:16:22 -0800 Subject: [PATCH 6/8] Adds coord validity check for job scanning in dig-now --- plugins/dig-now.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/dig-now.cpp b/plugins/dig-now.cpp index 68a5361a5..4084ca279 100644 --- a/plugins/dig-now.cpp +++ b/plugins/dig-now.cpp @@ -86,6 +86,9 @@ public: df::job_list_link* node = df::global::world->jobs.list.next; while (node) { df::job* job = node->item; + if(!Maps::isValidTilePos(job->pos)) + continue; + jobs.emplace(job->pos, job); node = node->next; df::tile_designation td = map.designationAt(job->pos); From 1fe0bab9d40832fed6f76262d3e8dc4ab3b02163 Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Thu, 16 Feb 2023 17:33:39 -0800 Subject: [PATCH 7/8] Incorporates code review into dig-now PR --- plugins/dig-now.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/plugins/dig-now.cpp b/plugins/dig-now.cpp index 4084ca279..e94cb41da 100644 --- a/plugins/dig-now.cpp +++ b/plugins/dig-now.cpp @@ -46,8 +46,6 @@ namespace DFHack { #define COORD "%" PRIi16 " %" PRIi16 " %" PRIi16 #define COORDARGS(id) id.x, id.y, id.z -// todo: integrate logging for debugging the layered channel problem - using namespace DFHack; struct designation{ @@ -86,10 +84,9 @@ public: df::job_list_link* node = df::global::world->jobs.list.next; while (node) { df::job* job = node->item; - if(!Maps::isValidTilePos(job->pos)) + if(!job || !Maps::isValidTilePos(job->pos)) continue; - jobs.emplace(job->pos, job); node = node->next; df::tile_designation td = map.designationAt(job->pos); df::tile_occupancy to = map.occupancyAt(job->pos); @@ -123,10 +120,10 @@ public: break; } case job_type::CarveTrack: - to.bits.carve_track_north = 0 < (job->item_category.whole & 18); - to.bits.carve_track_south = 0 < (job->item_category.whole & 19); - to.bits.carve_track_west = 0 < (job->item_category.whole & 20); - to.bits.carve_track_east = 0 < (job->item_category.whole & 21); + 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; @@ -134,6 +131,7 @@ public: 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); } } } @@ -472,7 +470,6 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, case df::tile_dig_designation::Channel: { DFCoord pos_below(pos.x, pos.y, pos.z-1); - // todo: does can_dig_channel return false? 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)); @@ -482,8 +479,6 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map, remove_ramp_top(map, pos_above); } df::tile_dig_designation td_below = map.designationAt(pos_below).bits.dig; - - // todo: digging to floor below? 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) { @@ -796,7 +791,6 @@ static void do_dig(color_ostream &out, std::vector &dug_coords, } } } - // todo: check mark mode of smooth designations } else if (td.bits.smooth == 1) { if (smooth_tile(out, map, pos)) { td = map.designationAt(pos); From d18911ca5a78bb8422f6acff01aae4024a3ad0d2 Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Tue, 21 Feb 2023 00:01:15 -0800 Subject: [PATCH 8/8] Update changelog.txt --- docs/changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index 85750890c..031e4ed62 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -42,6 +42,8 @@ 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``: check for stockpile items on block boundary. +- `dig-now`: fixed designations being invalidated after digging prior designations by buffering all designations +- `dig-now`: added scanning the job list for designations that can't be found in the map data ## Misc Improvements - DFHack tool windows that capture mouse clicks (and therefore prevent you from clicking on the "pause" button) now unconditionally pause the game when they open (but you can still unpause with the keyboard if you want to). Examples of this behavior: `gui/quickfort`, `gui/blueprint`, `gui/liquids`