diff --git a/plugins/channel-safely/channel-groups.cpp b/plugins/channel-safely/channel-groups.cpp index 52f7e6c40..8f7f4b117 100644 --- a/plugins/channel-safely/channel-groups.cpp +++ b/plugins/channel-safely/channel-groups.cpp @@ -119,7 +119,13 @@ void ChannelGroups::scan_one(const df::coord &map_pos) { } // builds groupings of adjacent channel designations -void ChannelGroups::scan() { +void ChannelGroups::scan(bool full_scan) { + static std::default_random_engine RNG(0); + static std::bernoulli_distribution sometimes_scanFULLY(0.15); + if (!full_scan) { + full_scan = sometimes_scanFULLY(RNG); + } + // save current jobs, then clear and load the current jobs std::set last_jobs; for (auto &pos : jobs) { @@ -138,9 +144,6 @@ void ChannelGroups::scan() { remove(pos); } - static std::default_random_engine RNG(0); - static std::bernoulli_distribution optimizing(0.75); // fixing OpenSpace as designated - DEBUG(groups).print(" scan()\n"); // foreach block for (int32_t z = mapz - 1; z >= 0; --z) { @@ -149,7 +152,7 @@ void ChannelGroups::scan() { // the block if (df::map_block* block = Maps::getBlock(bx, by, z)) { // skip this block? - if (!block->flags.bits.designated && !group_blocks.count(block) && optimizing(RNG)) { + if (!full_scan && !block->flags.bits.designated) { continue; } // foreach tile @@ -165,7 +168,7 @@ void ChannelGroups::scan() { jobs.erase(map_pos); } block->designation[lx][ly].bits.dig = df::tile_dig_designation::No; - } else if (is_dig_designation(block->designation[lx][ly])) { + } else if (is_dig_designation(block->designation[lx][ly]) || block->occupancy[lx][ly].bits.dig_marked) { for (df::block_square_event* event: block->block_events) { if (auto evT = virtual_cast(event)) { // we want to let the user keep some designations free of being managed diff --git a/plugins/channel-safely/channel-safely-plugin.cpp b/plugins/channel-safely/channel-safely-plugin.cpp index d291c0efc..8af90c335 100644 --- a/plugins/channel-safely/channel-safely-plugin.cpp +++ b/plugins/channel-safely/channel-safely-plugin.cpp @@ -1,7 +1,7 @@ /* Prevent channeling down into known open space. Author: Josh Cooper Created: Aug. 4 2020 -Updated: Nov. 6 2022 +Updated: Nov. 28 2022 Enable plugin: -> build groups @@ -225,10 +225,10 @@ namespace CSP { active_workers.clear(); } - void UnpauseEvent(){ + void UnpauseEvent(bool full_scan = false){ CoreSuspender suspend; // we need exclusive access to df memory and this call stack doesn't already have a lock INFO(monitor).print("UnpauseEvent()\n"); - ChannelManager::Get().build_groups(); + ChannelManager::Get().build_groups(full_scan); ChannelManager::Get().manage_groups(); ChannelManager::Get().debug(); INFO(monitor).print("UnpauseEvent() exits\n"); @@ -566,9 +566,12 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan } break; case SC_MAP_LOADED: + case SC_WORLD_LOADED: // cache the map size Maps::getSize(mapx, mapy, mapz); - case SC_WORLD_LOADED: + CSP::ClearData(); + ChannelManager::Get().build_groups(true); + break; case SC_WORLD_UNLOADED: case SC_MAP_UNLOADED: CSP::ClearData(); @@ -587,11 +590,11 @@ DFhackCExport command_result plugin_onupdate(color_ostream &out, state_change_ev command_result channel_safely(color_ostream &out, std::vector ¶meters) { if (!parameters.empty()) { if (parameters[0] == "runonce") { - CSP::UnpauseEvent(); + CSP::UnpauseEvent(true); return DFHack::CR_OK; } else if (parameters[0] == "rebuild") { ChannelManager::Get().destroy_groups(); - ChannelManager::Get().build_groups(); + ChannelManager::Get().build_groups(true); } if (parameters.size() >= 2 && parameters.size() <= 3) { bool state = false; diff --git a/plugins/channel-safely/include/channel-groups.h b/plugins/channel-safely/include/channel-groups.h index 7547e2564..8e3224c98 100644 --- a/plugins/channel-safely/include/channel-groups.h +++ b/plugins/channel-safely/include/channel-groups.h @@ -39,7 +39,7 @@ protected: public: explicit ChannelGroups(ChannelJobs &jobs) : jobs(jobs) { groups.reserve(200); } void scan_one(const df::coord &map_pos); - void scan(); + void scan(bool full_scan = false); void clear(); void remove(const df::coord &map_pos); Groups::const_iterator find(const df::coord &map_pos) const; diff --git a/plugins/channel-safely/include/channel-manager.h b/plugins/channel-safely/include/channel-manager.h index 0cd3abfac..323ce8468 100644 --- a/plugins/channel-safely/include/channel-manager.h +++ b/plugins/channel-safely/include/channel-manager.h @@ -23,7 +23,7 @@ public: return instance; } - void build_groups() { groups.scan(); debug(); } + void build_groups(bool full_scan = false) { groups.scan(full_scan); debug(); } void destroy_groups() { groups.clear(); debug(); } void manage_groups(); void manage_group(const df::coord &map_pos, bool set_marker_mode = false, bool marker_mode = false);