From 1e21f1ece954e3ff470c0a592228a58acc68db13 Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Mon, 13 Feb 2023 18:02:33 -0800 Subject: [PATCH] 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); + } } } }