diff --git a/NEWS.rst b/NEWS.rst index 9fde6a0cc..9a5b0c40b 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -105,6 +105,7 @@ Fixes Misc Improvements ----------------- +- `autochop`: Can now edit log minimum/maximum directly and remove limit entirely - `autolabor`, `autohauler`, `manipulator`: Added support for new jobs/labors/skills - `colonies`: now implemented by a script - `createitem`: Can now create items anywhere without specifying a unit, as long as a unit exists on the map diff --git a/plugins/autochop.cpp b/plugins/autochop.cpp index cbb5db0b3..1d972c588 100644 --- a/plugins/autochop.cpp +++ b/plugins/autochop.cpp @@ -44,6 +44,7 @@ REQUIRE_GLOBAL(ui); static bool autochop_enabled = false; static int min_logs, max_logs; +static const int LOG_CAP_MAX = 99999; static bool wait_for_threshold; static PersistentDataItem config_autochop; @@ -157,6 +158,18 @@ private: static WatchedBurrows watchedBurrows; +static int string_to_int(string s, int default_ = 0) +{ + try + { + return std::stoi(s); + } + catch (std::exception&) + { + return default_; + } +} + static void save_config() { config_autochop.val() = watchedBurrows.getSerialisedIds(); @@ -359,6 +372,7 @@ class ViewscreenAutochop : public dfhack_viewscreen public: ViewscreenAutochop() { + edit_mode = EDIT_NONE; burrows_column.multiselect = true; burrows_column.setTitle("Burrows"); burrows_column.bottom_margin = 3; @@ -415,6 +429,46 @@ public: void feed(set *input) { + if (edit_mode != EDIT_NONE) + { + string entry = int_to_string(edit_mode == EDIT_MIN ? min_logs : max_logs); + if (input->count(interface_key::LEAVESCREEN) || input->count(interface_key::SELECT)) + { + if (edit_mode == EDIT_MIN) + max_logs = std::max(min_logs, max_logs); + else if (edit_mode == EDIT_MAX) + min_logs = std::min(min_logs, max_logs); + edit_mode = EDIT_NONE; + } + else if (input->count(interface_key::STRING_A000)) + { + if (!entry.empty()) + entry.erase(entry.size() - 1); + } + else if (entry.size() < 5) + { + for (auto k = input->begin(); k != input->end(); ++k) + { + char ch = char(Screen::keyToChar(*k)); + if (ch >= '0' && ch <= '9') + entry += ch; + } + } + + switch (edit_mode) + { + case EDIT_MIN: + min_logs = string_to_int(entry); + break; + case EDIT_MAX: + max_logs = string_to_int(entry); + break; + default: break; + } + + return; + } + bool key_processed = false; message.clear(); switch (selected_column) @@ -456,6 +510,19 @@ public: message = "Trees unmarked: " + int_to_string(count); marked_tree_count = do_chop_designation(false, true); } + else if (input->count(interface_key::CUSTOM_N)) + { + edit_mode = EDIT_MIN; + } + else if (input->count(interface_key::CUSTOM_M)) + { + edit_mode = EDIT_MAX; + } + else if (input->count(interface_key::CUSTOM_SHIFT_N)) + { + min_logs = LOG_CAP_MAX + 1; + max_logs = LOG_CAP_MAX + 1; + } else if (input->count(interface_key::CUSTOM_H)) { change_min_logs(-1); @@ -537,8 +604,38 @@ public: OutputHotkeyString(x, y, "Toggle Burrow", "Enter", true, left_margin); if (autochop_enabled) { - OutputLabelString(x, y, "Min Logs", "hjHJ", int_to_string(min_logs), true, left_margin); - OutputLabelString(x, y, "Max Logs", "klKL", int_to_string(max_logs), true, left_margin); + using namespace df::enums::interface_key; + const struct { + const char *caption; + int count; + bool in_edit; + df::interface_key key; + df::interface_key skeys[4]; + } rows[] = { + {"Min Logs: ", min_logs, edit_mode == EDIT_MIN, CUSTOM_N, {CUSTOM_H, CUSTOM_J, CUSTOM_SHIFT_H, CUSTOM_SHIFT_J}}, + {"Max Logs: ", max_logs, edit_mode == EDIT_MAX, CUSTOM_M, {CUSTOM_K, CUSTOM_L, CUSTOM_SHIFT_K, CUSTOM_SHIFT_L}} + }; + for (size_t i = 0; i < sizeof(rows)/sizeof(rows[0]); ++i) + { + auto row = rows[i]; + OutputHotkeyString(x, y, row.caption, row.key); + auto prev_x = x; + if (row.in_edit) + OutputString(COLOR_LIGHTCYAN, x, y, int_to_string(row.count) + "_"); + else if (row.count <= LOG_CAP_MAX) + OutputString(COLOR_LIGHTGREEN, x, y, int_to_string(row.count)); + else + OutputString(COLOR_LIGHTBLUE, x, y, "Unlimited"); + if (edit_mode == EDIT_NONE) + { + x = std::max(x, prev_x + 10); + for (size_t j = 0; j < sizeof(row.skeys)/sizeof(row.skeys[0]); ++j) + OutputString(COLOR_LIGHTGREEN, x, y, DFHack::Screen::getKeyDisplay(row.skeys[j])); + OutputString(COLOR_WHITE, x, y, ": Step"); + } + OutputString(COLOR_WHITE, x, y, "", true, left_margin); + } + OutputHotkeyString(x, y, "No limit", CUSTOM_SHIFT_N, true, left_margin); } ++y; @@ -565,6 +662,7 @@ private: int marked_tree_count; MapExtras::MapCache mcache; string message; + enum { EDIT_NONE, EDIT_MIN, EDIT_MAX } edit_mode; void validateColumn() {