Implements plugin: channel-safely v1.1b

develop
Josh Cooper 2022-11-28 17:10:55 -08:00
parent 344ed4312b
commit 3999ed5c72
4 changed files with 20 additions and 14 deletions

@ -119,7 +119,13 @@ void ChannelGroups::scan_one(const df::coord &map_pos) {
} }
// builds groupings of adjacent channel designations // 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 // save current jobs, then clear and load the current jobs
std::set<df::coord> last_jobs; std::set<df::coord> last_jobs;
for (auto &pos : jobs) { for (auto &pos : jobs) {
@ -138,9 +144,6 @@ void ChannelGroups::scan() {
remove(pos); 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"); DEBUG(groups).print(" scan()\n");
// foreach block // foreach block
for (int32_t z = mapz - 1; z >= 0; --z) { for (int32_t z = mapz - 1; z >= 0; --z) {
@ -149,7 +152,7 @@ void ChannelGroups::scan() {
// the block // the block
if (df::map_block* block = Maps::getBlock(bx, by, z)) { if (df::map_block* block = Maps::getBlock(bx, by, z)) {
// skip this block? // skip this block?
if (!block->flags.bits.designated && !group_blocks.count(block) && optimizing(RNG)) { if (!full_scan && !block->flags.bits.designated) {
continue; continue;
} }
// foreach tile // foreach tile
@ -165,7 +168,7 @@ void ChannelGroups::scan() {
jobs.erase(map_pos); jobs.erase(map_pos);
} }
block->designation[lx][ly].bits.dig = df::tile_dig_designation::No; 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) { for (df::block_square_event* event: block->block_events) {
if (auto evT = virtual_cast<df::block_square_event_designation_priorityst>(event)) { if (auto evT = virtual_cast<df::block_square_event_designation_priorityst>(event)) {
// we want to let the user keep some designations free of being managed // we want to let the user keep some designations free of being managed

@ -1,7 +1,7 @@
/* Prevent channeling down into known open space. /* Prevent channeling down into known open space.
Author: Josh Cooper Author: Josh Cooper
Created: Aug. 4 2020 Created: Aug. 4 2020
Updated: Nov. 6 2022 Updated: Nov. 28 2022
Enable plugin: Enable plugin:
-> build groups -> build groups
@ -225,10 +225,10 @@ namespace CSP {
active_workers.clear(); 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 CoreSuspender suspend; // we need exclusive access to df memory and this call stack doesn't already have a lock
INFO(monitor).print("UnpauseEvent()\n"); INFO(monitor).print("UnpauseEvent()\n");
ChannelManager::Get().build_groups(); ChannelManager::Get().build_groups(full_scan);
ChannelManager::Get().manage_groups(); ChannelManager::Get().manage_groups();
ChannelManager::Get().debug(); ChannelManager::Get().debug();
INFO(monitor).print("UnpauseEvent() exits\n"); INFO(monitor).print("UnpauseEvent() exits\n");
@ -566,9 +566,12 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan
} }
break; break;
case SC_MAP_LOADED: case SC_MAP_LOADED:
case SC_WORLD_LOADED:
// cache the map size // cache the map size
Maps::getSize(mapx, mapy, mapz); Maps::getSize(mapx, mapy, mapz);
case SC_WORLD_LOADED: CSP::ClearData();
ChannelManager::Get().build_groups(true);
break;
case SC_WORLD_UNLOADED: case SC_WORLD_UNLOADED:
case SC_MAP_UNLOADED: case SC_MAP_UNLOADED:
CSP::ClearData(); 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<std::string> &parameters) { command_result channel_safely(color_ostream &out, std::vector<std::string> &parameters) {
if (!parameters.empty()) { if (!parameters.empty()) {
if (parameters[0] == "runonce") { if (parameters[0] == "runonce") {
CSP::UnpauseEvent(); CSP::UnpauseEvent(true);
return DFHack::CR_OK; return DFHack::CR_OK;
} else if (parameters[0] == "rebuild") { } else if (parameters[0] == "rebuild") {
ChannelManager::Get().destroy_groups(); ChannelManager::Get().destroy_groups();
ChannelManager::Get().build_groups(); ChannelManager::Get().build_groups(true);
} }
if (parameters.size() >= 2 && parameters.size() <= 3) { if (parameters.size() >= 2 && parameters.size() <= 3) {
bool state = false; bool state = false;

@ -39,7 +39,7 @@ protected:
public: public:
explicit ChannelGroups(ChannelJobs &jobs) : jobs(jobs) { groups.reserve(200); } explicit ChannelGroups(ChannelJobs &jobs) : jobs(jobs) { groups.reserve(200); }
void scan_one(const df::coord &map_pos); void scan_one(const df::coord &map_pos);
void scan(); void scan(bool full_scan = false);
void clear(); void clear();
void remove(const df::coord &map_pos); void remove(const df::coord &map_pos);
Groups::const_iterator find(const df::coord &map_pos) const; Groups::const_iterator find(const df::coord &map_pos) const;

@ -23,7 +23,7 @@ public:
return instance; 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 destroy_groups() { groups.clear(); debug(); }
void manage_groups(); void manage_groups();
void manage_group(const df::coord &map_pos, bool set_marker_mode = false, bool marker_mode = false); void manage_group(const df::coord &map_pos, bool set_marker_mode = false, bool marker_mode = false);