summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--README.rst6
-rw-r--r--dfhack.init-example11
-rw-r--r--plugins/lua/sort/items.lua8
-rw-r--r--plugins/tweak.cpp112
5 files changed, 138 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index ffce93d2..7bcd7513 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 7e8678c9..5801e6b4 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 8a3ec8f2..2e656a60 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 13b62ff9..5c6d4a5b 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 6d0591d1..939c94b3 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 <stdlib.h>
@@ -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 <string> & parameters);
@@ -114,6 +116,13 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
" tweak fast-trade [disable]\n"
" Makes Shift-Enter in the Move Goods to Depot and Trade screens select\n"
" the current item (fully, in case of a stack), and scroll down one line.\n"
+ " tweak military-stable-assign [disable]\n"
+ " Preserve list order and cursor position when assigning to squad,\n"
+ " i.e. stop the rightmost list of the Positions page of the military\n"
+ " screen from constantly jumping to the top.\n"
+ " tweak military-color-assigned [disable]\n"
+ " Color squad candidates already assigned to other squads in brown/green\n"
+ " to make them stand out more in the list.\n"
));
return CR_OK;
}
@@ -540,6 +549,101 @@ struct fast_trade_select_hook : df::viewscreen_tradegoodsst {
IMPLEMENT_VMETHOD_INTERPOSE(fast_trade_select_hook, feed);
+struct military_assign_hook : df::viewscreen_layer_militaryst {
+ typedef df::viewscreen_layer_militaryst interpose_base;
+
+ inline bool inPositionsMode() {
+ return page == Positions && !(in_create_squad || in_new_squad);
+ }
+
+ DEFINE_VMETHOD_INTERPOSE(void, feed, (set<df::interface_key> *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<df::unit*> 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<df::unit*> prev, next;
+ prev.insert(copy.begin(), copy.end());
+ next.insert(cand.begin(), cand.end());
+ std::vector<df::unit*> 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 <string> &parameters)
{
if (vector_get(parameters, 1) == "disable")
@@ -704,6 +808,14 @@ static command_result tweak(color_ostream &out, vector <string> &parameters)
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;