diff --git a/NEWS b/NEWS index ffce93d23..7bcd7513b 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,8 @@ DFHack v0.34.11-r2 (UNRELEASED) - tweak fix-dimensions: fixes subtracting small amounts from stacked liquids etc. - tweak advmode-contained: fixes UI bug in custom reactions with container inputs in advmode. - tweak fast-trade: Shift-Enter for selecting items quckly in Trade and Move to Depot screens. + - tweak military-stable-assign: Stop rightmost list of military->Positions from jumping to top. + - tweak military-color-assigned: In same list, color already assigned units in brown & green. New scripts: - fixnaked: removes thoughts about nakedness. - setfps: set FPS cap at runtime, in case you want slow motion or speed-up. diff --git a/README.rst b/README.rst index 7e8678c9f..5801e6b45 100644 --- a/README.rst +++ b/README.rst @@ -1015,6 +1015,12 @@ Subcommands that persist until disabled or DF quit: reagents. :fast-trade: Makes Shift-Enter in the Move Goods to Depot and Trade screens select the current item (fully, in case of a stack), and scroll down one line. +:military-stable-assign: Preserve list order and cursor position when assigning to squad, + i.e. stop the rightmost list of the Positions page of the military + screen from constantly resetting to the top. +:military-color-assigned: Color squad candidates already assigned to other squads in brown/green + to make them stand out more in the list. + Mode switch and reclaim ======================= diff --git a/dfhack.init-example b/dfhack.init-example index 8a3ec8f29..2e656a609 100644 --- a/dfhack.init-example +++ b/dfhack.init-example @@ -48,6 +48,12 @@ keybinding add Shift-O "job-material OBSIDIAN" keybinding add Shift-T "job-material ORTHOCLASE" keybinding add Shift-G "job-material GLASS_GREEN" +# sort units and items +keybinding add Alt-Shift-N "sort-units name" "sort-items description" +keybinding add Alt-Shift-R "sort-units arrival" +keybinding add Alt-Shift-T "sort-units profession" "sort-items type material" +keybinding add Alt-Shift-Q "sort-units squad_position" "sort-items quality" + # browse linked mechanisms keybinding add Ctrl-M@dwarfmode/QueryBuilding/Some gui/mechanisms @@ -95,3 +101,8 @@ tweak advmode-contained # support Shift-Enter in Trade and Move Goods to Depot screens for faster # selection; it selects the current item or stack and scrolls down one line tweak fast-trade + +# stop the right list in military->positions from resetting to top all the time +tweak military-stable-assign +# in same list, color units already assigned to squads in brown & green +tweak military-color-assigned diff --git a/plugins/lua/sort/items.lua b/plugins/lua/sort/items.lua index 13b62ff9b..5c6d4a5ba 100644 --- a/plugins/lua/sort/items.lua +++ b/plugins/lua/sort/items.lua @@ -23,12 +23,18 @@ orders.description = { end } -orders.quality = { +orders.base_quality = { key = function(item) return item:getQuality() end } +orders.quality = { + key = function(item) + return item:getOverallQuality() + end +} + orders.improvement = { key = function(item) return item:getImprovementQuality() diff --git a/plugins/tweak.cpp b/plugins/tweak.cpp index 6d0591d13..939c94b3b 100644 --- a/plugins/tweak.cpp +++ b/plugins/tweak.cpp @@ -45,6 +45,7 @@ #include "df/reaction_reagent_flags.h" #include "df/viewscreen_layer_assigntradest.h" #include "df/viewscreen_tradegoodsst.h" +#include "df/viewscreen_layer_militaryst.h" #include @@ -61,6 +62,7 @@ using df::global::ui_menu_width; using df::global::ui_area_map_width; using namespace DFHack::Gui; +using Screen::Pen; static command_result tweak(color_ostream &out, vector & parameters); @@ -114,6 +116,13 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector *input)) + { + if (inPositionsMode() && !layer_objects[0]->active) + { + auto pos_list = layer_objects[1]; + auto plist = layer_objects[2]; + auto &cand = positions.candidates; + + // Save the candidate list and cursors + std::vector copy = cand; + int cursor = plist->getListCursor(); + int pos_cursor = pos_list->getListCursor(); + + INTERPOSE_NEXT(feed)(input); + + if (inPositionsMode() && !layer_objects[0]->active) + { + bool is_select = input->count(interface_key::SELECT); + + // Resort the candidate list and restore cursor + // on add to squad OR scroll in the position list. + if (!plist->active || is_select) + { + // Since we don't know the actual sorting order, preserve + // the ordering of the items in the list before keypress. + // This does the right thing even if the list was sorted + // with sort-units. + std::set prev, next; + prev.insert(copy.begin(), copy.end()); + next.insert(cand.begin(), cand.end()); + std::vector out; + + // (old-before-cursor) (new) |cursor| (old-after-cursor) + for (int i = 0; i < cursor && i < (int)copy.size(); i++) + if (next.count(copy[i])) out.push_back(copy[i]); + for (size_t i = 0; i < cand.size(); i++) + if (!prev.count(cand[i])) out.push_back(cand[i]); + int new_cursor = out.size(); + for (int i = cursor; i < (int)copy.size(); i++) + if (next.count(copy[i])) out.push_back(copy[i]); + + cand.swap(out); + plist->setListLength(cand.size()); + if (new_cursor < (int)cand.size()) + plist->setListCursor(new_cursor); + } + + // Preserve the position list index on remove from squad + if (pos_list->active && is_select) + pos_list->setListCursor(pos_cursor); + } + } + else + INTERPOSE_NEXT(feed)(input); + } + + DEFINE_VMETHOD_INTERPOSE(void, render, ()) + { + INTERPOSE_NEXT(render)(); + + if (inPositionsMode()) + { + auto plist = layer_objects[2]; + int x1 = plist->getX1(), y1 = plist->getY1(); + int x2 = plist->getX2(), y2 = plist->getY2(); + int i1 = plist->getFirstVisible(), i2 = plist->getLastVisible(); + + for (int y = y1, i = i1; i <= i2; i++, y++) + { + auto unit = vector_get(positions.candidates, i); + if (!unit || unit->military.squad_index < 0) + continue; + + for (int x = x1; x <= x2; x++) + { + Pen cur_tile = Screen::readTile(x, y); + if (!cur_tile.valid()) continue; + cur_tile.fg = (cur_tile.fg == COLOR_GREY ? COLOR_BROWN : COLOR_GREEN); + Screen::paintTile(cur_tile, x, y); + } + } + } + } +}; + +IMPLEMENT_VMETHOD_INTERPOSE(military_assign_hook, feed); +IMPLEMENT_VMETHOD_INTERPOSE(military_assign_hook, render); + static void enable_hook(color_ostream &out, VMethodInterposeLinkBase &hook, vector ¶meters) { if (vector_get(parameters, 1) == "disable") @@ -704,6 +808,14 @@ static command_result tweak(color_ostream &out, vector ¶meters) enable_hook(out, INTERPOSE_HOOK(fast_trade_assign_hook, feed), parameters); enable_hook(out, INTERPOSE_HOOK(fast_trade_select_hook, feed), parameters); } + else if (cmd == "military-stable-assign") + { + enable_hook(out, INTERPOSE_HOOK(military_assign_hook, feed), parameters); + } + else if (cmd == "military-color-assigned") + { + enable_hook(out, INTERPOSE_HOOK(military_assign_hook, render), parameters); + } else return CR_WRONG_USAGE;