From f98015ae5544b526aab2799796894bd1535f42c4 Mon Sep 17 00:00:00 2001 From: myk002 Date: Tue, 2 Aug 2022 10:42:54 -0700 Subject: [PATCH] ensure we run every N ticks, not frames add more debug messages fix watching/unwatching/forgetting races that aren't in the watchlist --- data/examples/init/onMapLoad_dreamfort.init | 10 ++- plugins/autobutcher.cpp | 67 +++++++++++++++------ plugins/autonestbox.cpp | 14 +++-- 3 files changed, 61 insertions(+), 30 deletions(-) diff --git a/data/examples/init/onMapLoad_dreamfort.init b/data/examples/init/onMapLoad_dreamfort.init index c75620846..05d32134f 100644 --- a/data/examples/init/onMapLoad_dreamfort.init +++ b/data/examples/init/onMapLoad_dreamfort.init @@ -37,17 +37,14 @@ enable automelt # creates manager orders to produce replacements for worn clothing enable tailor -tailor enable # auto-assigns nesting birds to nestbox zones and protects fertile eggs from # being cooked/eaten -enable zone nestboxes -autonestbox start +enable zone autonestbox nestboxes # manages seed stocks enable seedwatch seedwatch all 30 -seedwatch start # ensures important tasks get assigned to workers. # otherwise these job types can get ignored in busy forts. @@ -65,6 +62,7 @@ prioritize -a --reaction-name=TAN_A_HIDE CustomReaction # feel free to change this to "target 0 0 0 0" if you don't expect to want to raise # any animals not listed here -- you can always change it anytime during the game # later if you change your mind. +on-new-fortress enable autobutcher on-new-fortress autobutcher target 2 2 2 2 new # dogs and cats. You should raise the limits for dogs if you will be training them # for hunting or war. @@ -82,5 +80,5 @@ on-new-fortress autobutcher target 2 2 4 2 ALPACA SHEEP LLAMA on-new-fortress autobutcher target 5 5 6 2 PIG # butcher all unprofitable animals on-new-fortress autobutcher target 0 0 0 0 HORSE YAK DONKEY WATER_BUFFALO GOAT CAVY BIRD_DUCK BIRD_GUINEAFOWL -# start it up! -on-new-fortress autobutcher start; autobutcher watch all; autobutcher autowatch +# watch for new animals +on-new-fortress autobutcher autowatch diff --git a/plugins/autobutcher.cpp b/plugins/autobutcher.cpp index 69799207a..0b0d4ffdb 100644 --- a/plugins/autobutcher.cpp +++ b/plugins/autobutcher.cpp @@ -150,7 +150,7 @@ static void set_config_bool(int index, bool value) { } static unordered_map race_to_id; -static size_t cycle_counter = 0; // how many ticks since the last cycle +static int32_t cycle_timestamp = 0; // world->frame_counter at last cycle static size_t DEFAULT_CYCLE_TICKS = 6000; @@ -252,7 +252,7 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan } DFhackCExport command_result plugin_onupdate(color_ostream &out) { - if (is_enabled && ++cycle_counter >= (size_t)get_config_val(CONFIG_CYCLE_TICKS)) + if (is_enabled && world->frame_counter - cycle_timestamp >= get_config_val(CONFIG_CYCLE_TICKS)) autobutcher_cycle(out); return CR_OK; } @@ -663,7 +663,8 @@ static void autobutcher_status(color_ostream &out) { static void autobutcher_target(color_ostream &out, const autobutcher_options &opts) { if (opts.races_new) { - DEBUG(status,out).print("setting targets for new races\n"); + DEBUG(status,out).print("setting targets for new races to fk=%u, mk=%u, fa=%u, ma=%u\n", + opts.fk, opts.mk, opts.fa, opts.ma); set_config_val(CONFIG_DEFAULT_FK, opts.fk); set_config_val(CONFIG_DEFAULT_MK, opts.mk); set_config_val(CONFIG_DEFAULT_FA, opts.fa); @@ -671,7 +672,8 @@ static void autobutcher_target(color_ostream &out, const autobutcher_options &op } if (opts.races_all) { - DEBUG(status,out).print("setting targets for all races on watchlist\n"); + DEBUG(status,out).print("setting targets for all races on watchlist to fk=%u, mk=%u, fa=%u, ma=%u\n", + opts.fk, opts.mk, opts.fa, opts.ma); for (auto w : watched_races) { w.second->fk = opts.fk; w.second->mk = opts.mk; @@ -689,7 +691,6 @@ static void autobutcher_target(color_ostream &out, const autobutcher_options &op int id = race_to_id[*race]; WatchedRace *w; if (!watched_races.count(id)) { - DEBUG(status,out).print("adding new targets for %s\n", race->c_str()); w = new WatchedRace(out, id, true, opts.fk, opts.mk, opts.fa, opts.ma); watched_races.emplace(id, w); } else { @@ -707,8 +708,6 @@ static void autobutcher_modify_watchlist(color_ostream &out, const autobutcher_o unordered_set ids; if (opts.races_all) { - DEBUG(status,out).print("modifying all races on watchlist: %s\n", - opts.command.c_str()); for (auto w : watched_races) ids.emplace(w.first); } @@ -722,13 +721,41 @@ static void autobutcher_modify_watchlist(color_ostream &out, const autobutcher_o } for (int id : ids) { - if (opts.command == "watch") - watched_races[id]->isWatched = true; - else if (opts.command == "unwatch") - watched_races[id]->isWatched = false; + if (opts.command == "watch") { + if (!watched_races.count(id)) { + watched_races.emplace(id, + new WatchedRace(out, id, true, + get_config_val(CONFIG_DEFAULT_FK), + get_config_val(CONFIG_DEFAULT_MK), + get_config_val(CONFIG_DEFAULT_FA), + get_config_val(CONFIG_DEFAULT_MA))); + } + else if (!watched_races[id]->isWatched) { + DEBUG(status,out).print("watching: %s\n", opts.command.c_str()); + watched_races[id]->isWatched = true; + } + } + else if (opts.command == "unwatch") { + if (!watched_races.count(id)) { + watched_races.emplace(id, + new WatchedRace(out, id, false, + get_config_val(CONFIG_DEFAULT_FK), + get_config_val(CONFIG_DEFAULT_MK), + get_config_val(CONFIG_DEFAULT_FA), + get_config_val(CONFIG_DEFAULT_MA))); + } + else if (watched_races[id]->isWatched) { + DEBUG(status,out).print("unwatching: %s\n", opts.command.c_str()); + watched_races[id]->isWatched = false; + } + } else if (opts.command == "forget") { - watched_races[id]->RemoveConfig(out); - watched_races.erase(id); + if (watched_races.count(id)) { + DEBUG(status,out).print("forgetting: %s\n", opts.command.c_str()); + watched_races[id]->RemoveConfig(out); + delete watched_races[id]; + watched_races.erase(id); + } continue; } watched_races[id]->UpdateConfig(out); @@ -776,7 +803,10 @@ static bool isInBuiltCageRoom(df::unit *unit) { } static void autobutcher_cycle(color_ostream &out) { - DEBUG(cycle,out).print("running autobutcher_cycle\n"); + // mark that we have recently run + cycle_timestamp = world->frame_counter; + + DEBUG(cycle,out).print("running autobutcher cycle\n"); // check if there is anything to watch before walking through units vector if (!get_config_bool(CONFIG_AUTOWATCH)) { @@ -850,14 +880,13 @@ static void autobutcher_cycle(color_ostream &out) { } } - int slaughter_count = 0; for (auto w : watched_races) { - int slaughter_subcount = w.second->ProcessUnits(); - slaughter_count += slaughter_subcount; - if (slaughter_subcount) { + int slaughter_count = w.second->ProcessUnits(); + if (slaughter_count) { stringstream ss; - ss << slaughter_subcount; + ss << slaughter_count; string announce = Units::getRaceNamePluralById(w.first) + " marked for slaughter: " + ss.str(); + DEBUG(cycle,out).print("%s\n", announce.c_str()); Gui::showAnnouncement(announce, 2, false); } } diff --git a/plugins/autonestbox.cpp b/plugins/autonestbox.cpp index 10c0e3cd8..668938c2c 100644 --- a/plugins/autonestbox.cpp +++ b/plugins/autonestbox.cpp @@ -73,7 +73,7 @@ static bool set_config_val(int index, int value) { } static bool did_complain = false; // avoids message spam -static size_t cycle_counter = 0; // how many ticks since the last cycle +static int32_t cycle_timestamp = 0; // world->frame_counter at last cycle struct autonestbox_options { // whether to display help @@ -168,8 +168,7 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan } DFhackCExport command_result plugin_onupdate(color_ostream &out) { - if (is_enabled && ++cycle_counter >= - (size_t)get_config_val(CONFIG_CYCLE_TICKS)) + if (is_enabled && world->frame_counter - cycle_timestamp >= get_config_val(CONFIG_CYCLE_TICKS)) autonestbox_cycle(out); return CR_OK; } @@ -342,7 +341,7 @@ static bool assignUnitToZone(color_ostream &out, df::unit *unit, df::building *b df::general_ref_building_civzone_assignedst *ref = createCivzoneRef(); if (!ref) { ERR(cycle,out).print("Could not find a clonable activity zone reference!" - " You need to pen/pasture/pit at least one creature" + " You need to manually pen/pasture/pit at least one creature" " before autonestbox can function.\n"); return false; } @@ -381,6 +380,8 @@ static size_t assign_nestboxes(color_ostream &out) { DEBUG(cycle,out).print("Failed to assign unit to building.\n"); return processed; } + DEBUG(cycle,out).print("assigned unit %d to zone %d\n", + free_unit->id, free_building->id); ++processed; } } while (free_unit && free_building); @@ -406,13 +407,16 @@ static size_t assign_nestboxes(color_ostream &out) { static void autonestbox_cycle(color_ostream &out) { // mark that we have recently run - cycle_counter = 0; + cycle_timestamp = world->frame_counter; + + DEBUG(cycle,out).print("running autonestbox cycle\n"); size_t processed = assign_nestboxes(out); if (processed > 0) { stringstream ss; ss << processed << " nestboxes were assigned."; string announce = ss.str(); + DEBUG(cycle,out).print("%s\n", announce.c_str()); Gui::showAnnouncement(announce, 2, false); out << announce << endl; // can complain again