88#include < PluginManager.h>
99
1010#include < modules/Units.h>
11+ // #include <df/job.h>
1112#include < df/block_square_event_designation_priorityst.h>
1213#include < df/report.h>
1314
@@ -47,30 +48,65 @@ df::coord simulate_area_fall(const df::coord &pos) {
4748 return lowest;
4849}
4950
50- bool ActiveJobManager::has_cavein_conditions (const df::coord &map_pos) const {
51- auto p = map_pos;
52- auto ttype = *Maps::getTileType (p);
53- if (!DFHack::isOpenTerrain (ttype)) {
54- // check shared neighbour for cave-in conditions
55- df::coord neighbours[4 ];
56- get_connected_neighbours (map_pos, neighbours);
57- int connectedness = 4 ;
58- for (auto n: neighbours) {
59- if (!Maps::isValidTilePos (n) || active_dig_sites.count (n) || DFHack::isOpenTerrain (*Maps::getTileType (n))) {
60- connectedness--;
61- }
51+ int count_visibility_grid_neighbourhood (const df::coord &pos) {
52+ // check shared neighbour for cave-in conditions
53+ df::coord neighbours[5 ];
54+ neighbours[0 ]=pos;
55+ get_grid_neighbours (neighbours[0 ], &neighbours[1 ]);
56+ int visible_tiles = 0 ;
57+ for (auto n: neighbours) {
58+ if (bool visible = Maps::isTileVisible (n); visible) {
59+ visible_tiles++;
6260 }
63- if (!connectedness) {
64- // do what?
65- p.z --;
66- if (!Maps::isValidTilePos (p)) return false ;
67- ttype = *Maps::getTileType (p);
68- if (DFHack::isOpenTerrain (ttype) || DFHack::isFloorTerrain (ttype)) {
69- return true ;
61+ }
62+ return visible_tiles;
63+ }
64+
65+ int count_empty_grid_neighbourhood (const df::coord &pos) {
66+ // check shared neighbour for cave-in conditions
67+ df::coord neighbours[5 ];
68+ neighbours[0 ]=pos;
69+ get_grid_neighbours (neighbours[0 ], &neighbours[1 ]);
70+ int empty_tiles = 0 ;
71+ for (auto n: neighbours) {
72+ bool visible = Maps::isTileVisible (n);
73+ if (config.riskaverse && !visible) {
74+ empty_tiles++;
75+ } else if (bool open = DFHack::isOpenTerrain (*Maps::getTileType (n)); open) {
76+ if (!config.require_vision ) {
77+ empty_tiles++;
78+ } else if (visible) {
79+ empty_tiles++;
7080 }
7181 }
7282 }
73- return false ;
83+ return empty_tiles;
84+ }
85+
86+ bool ActiveJobManager::has_cavein_conditions (const df::coord &map_pos) const {
87+ if (!config.riskaverse ) {
88+ return false ;
89+ }
90+ df::coord below{map_pos};
91+ below.z --;
92+ auto v2 = count_visibility_grid_neighbourhood (below);
93+ auto e2 = count_empty_grid_neighbourhood (below);
94+ bool below_risk = false ;
95+ if (config.require_vision ) {
96+ below_risk = v2 >= 4 && e2 >= 4 ;
97+ } else {
98+ below_risk = e2 >= 4 ;
99+ }
100+ if (!below_risk) {
101+ return false ;
102+ }
103+ auto v = count_visibility_grid_neighbourhood (map_pos);
104+ auto e = count_empty_grid_neighbourhood (map_pos);
105+ if (config.require_vision ) {
106+ return v >= 3 && e >= 3 ;
107+ } else {
108+ return e >= 3 ;
109+ }
74110}
75111
76112bool ActiveJobManager::possible_cavein (const df::coord &map_pos) const {
@@ -222,12 +258,12 @@ void ActiveJobManager::on_job_start(df::job* job) {
222258 return ;
223259 }
224260 // if a cavein is possible - we'll try to cancel the job
225- if (possible_cavein (pos)) {
261+ if (has_cavein_conditions (pos)) {
226262 /* todo:
227263 * test if the game crashes or the jobs start polluting the list indefinitely
228264 * prediction is that the jobs will cause the tiles to flash forever
229265 */
230- if (remove_worker (job) == 0 ) { DEBUG (jobs).print (" Unable to remove worker from job." ); }
266+ if (! Job::removeWorker (job)) { WARN (jobs).print (" Unable to remove worker from job." ); }
231267 cancel_queue.emplace (pos);
232268 return ;
233269 }
@@ -261,7 +297,7 @@ void ActiveJobManager::on_job_completed(color_ostream &out, df::job* job) {
261297 return ;
262298 }
263299 // the job can be considered done
264- ChannelManager::Get ().mark_done (ajob.pos );
300+ ChannelManager::Get ().erase (ajob.pos );
265301 ChannelManager::Get ().manage_group (ajob.pos , true , false );
266302 block->designation [Coord (local)].bits .traffic = df::tile_traffic::Normal;
267303 df::coord below (ajob.pos );
@@ -278,14 +314,20 @@ void ActiveJobManager::on_job_completed(color_ostream &out, df::job* job) {
278314}
279315
280316void ActiveJobManager::on_report_event (df::report* report) {
281- int32_t tick = df::global::world->frame_counter ;
282317 switch (report->type ) {
283318 case announcement_type::CANCEL_JOB:
284319 if (config.insta_dig ) {
285- if (report->text .find (" cancels Dig" ) != std::string::npos ||
286- report->text .find (" path" ) != std::string::npos) {
287-
320+ bool valid = false ;
321+ if (ChannelManager::Get ().contains (report->pos )) {
288322 CSP::dignow_queue.emplace (report->pos );
323+ valid = true ;
324+ }
325+ if (ChannelManager::Get ().contains (report->pos2 )) {
326+ CSP::dignow_queue.emplace (report->pos2 );
327+ valid = true ;
328+ }
329+ if (valid) {
330+ WARN (jobs).print (" Report: canceled a channel job. [insta-dig: on]" );
289331 }
290332 DEBUG (plugin).print (" %d, pos: " COORD " , pos2: " COORD " \n %s\n " , report->id , COORDARGS (report->pos ),
291333 COORDARGS (report->pos2 ), report->text .c_str ());
@@ -309,6 +351,7 @@ void ActiveJobManager::on_report_event(df::report* report) {
309351 areaMax.z += 1 ;
310352 std::vector<df::unit*> units;
311353 Units::getUnitsInBox (units, COORDARGS (areaMin), COORDARGS (areaMax));
354+ int32_t tick = df::global::world->frame_counter ;
312355 for (auto unit: units) {
313356 endangered_units[unit->id ] = tick;
314357 DEBUG (plugin).print (" [id %d] was near a cave in.\n " , unit->id );
0 commit comments