From 8a120837c6bdd8c7c4b466ab7407fa059248b25a Mon Sep 17 00:00:00 2001 From: Su Date: Fri, 1 Apr 2022 04:41:44 +0100 Subject: [PATCH] only designate enough trees to reach max_logs (#2064) * only designate enough trees to reach max_logs * Chop largest trees first --- docs/changelog.txt | 2 ++ plugins/autochop.cpp | 45 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 16419e442..244274b3f 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -53,6 +53,8 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - DFHack log messages now have configurable headers (e.g. timestamp, origin plugin name, etc.) via the ``debugfilter`` command of the `debug` plugin - Script execution log messages (e.g. "Loading script: dfhack_extras.init" can now be controlled with the ``debugfilter`` command. To hide the messages, add this line to your ``dfhack.init`` file: ``debugfilter set Warning core script`` - `manipulator`: Tweak colors to make the cursor easier to locate +- `autochop`: only designate the amount of trees required to reach ``max_logs`` +- `autochop`: preferably designate larger trees over smaller ones ## Documentation - Add more examples to the plugin skeleton files so they are more informative for a newbie diff --git a/plugins/autochop.cpp b/plugins/autochop.cpp index d28cf59b3..04ae8af71 100644 --- a/plugins/autochop.cpp +++ b/plugins/autochop.cpp @@ -18,6 +18,8 @@ #include "df/map_block.h" #include "df/material.h" #include "df/plant.h" +#include "df/plant_tree_info.h" +#include "df/plant_tree_tile.h" #include "df/plant_raw.h" #include "df/tile_dig_designation.h" #include "df/ui.h" @@ -45,6 +47,8 @@ DFHACK_PLUGIN("autochop"); REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(ui); +static int get_log_count(); + static bool autochop_enabled = false; static int min_logs, max_logs; static const int LOG_CAP_MAX = 99999; @@ -288,18 +292,39 @@ static bool skip_plant(const df::plant * plant, bool *restricted) return false; } +static int estimate_logs(const df::plant *plant) +{ + //adapted from code by aljohnston112 @ github + df::plant_tree_tile** tiles = plant->tree_info->body; + df::plant_tree_tile* tilesRow; + + int trunks = 0; + for (int i = 0; i < plant->tree_info->body_height; i++) { + tilesRow = tiles[i]; + for (int j = 0; j < plant->tree_info->dim_y*plant->tree_info->dim_x; j++) { + trunks += tilesRow[j].bits.trunk; + } + } + + return trunks; +} + static int do_chop_designation(bool chop, bool count_only, int *skipped = nullptr) { int count = 0; + int estimated_yield = get_log_count(); + multimap trees_by_size; + if (skipped) { *skipped = 0; } - for (size_t i = 0; i < world->plants.all.size(); i++) - { - const df::plant *plant = world->plants.all[i]; + //get trees + for (auto plant : world->plants.all) + { bool restricted = false; + if (skip_plant(plant, &restricted)) { if (restricted && skipped) @@ -309,6 +334,17 @@ static int do_chop_designation(bool chop, bool count_only, int *skipped = nullpt continue; } + trees_by_size.insert(pair(estimate_logs(plant), plant)); + } + + //designate + for (auto & entry : trees_by_size) + { + const df::plant * plant = entry.second; + + if ((estimated_yield >= max_logs) && chop) + break; + if (!count_only && !watchedBurrows.isValidPos(plant->pos)) continue; @@ -322,7 +358,10 @@ static int do_chop_designation(bool chop, bool count_only, int *skipped = nullpt else { if (Designations::markPlant(plant)) + { + estimated_yield += entry.first; count++; + } } }