summaryrefslogtreecommitdiff
path: root/plugins/sort.cpp
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-05-18 19:18:49 +0400
committerAlexander Gavrilov2012-05-18 19:18:49 +0400
commit4aa6dbdd005c8930f2ae972e780caa3fde97f854 (patch)
treef29f5027d6a827c25a7123e4f946d82c3976cd46 /plugins/sort.cpp
parente2f39368b17bbc9d6b380faed7ceb52b1bd8eb2d (diff)
downloaddfhack-4aa6dbdd005c8930f2ae972e780caa3fde97f854.tar.gz
dfhack-4aa6dbdd005c8930f2ae972e780caa3fde97f854.tar.bz2
dfhack-4aa6dbdd005c8930f2ae972e780caa3fde97f854.tar.xz
Support sorting items in the trade screens.
Caveat: sorts items in containers independently from the container.
Diffstat (limited to 'plugins/sort.cpp')
-rw-r--r--plugins/sort.cpp134
1 files changed, 125 insertions, 9 deletions
diff --git a/plugins/sort.cpp b/plugins/sort.cpp
index 9d63b2c6..430fb719 100644
--- a/plugins/sort.cpp
+++ b/plugins/sort.cpp
@@ -18,9 +18,12 @@
#include "df/viewscreen_layer_workshop_profilest.h"
#include "df/viewscreen_layer_noblelistst.h"
#include "df/viewscreen_layer_overall_healthst.h"
+#include "df/viewscreen_layer_assigntradest.h"
+#include "df/viewscreen_tradegoodsst.h"
#include "df/viewscreen_dwarfmodest.h"
#include "df/viewscreen_petst.h"
#include "df/layer_object_listst.h"
+#include "df/assign_trade_status.h"
#include "MiscUtils.h"
@@ -42,8 +45,10 @@ using df::global::ui_building_assign_units;
using df::global::ui_building_assign_items;
static bool unit_list_hotkey(df::viewscreen *top);
+static bool item_list_hotkey(df::viewscreen *top);
static command_result sort_units(color_ostream &out, vector <string> & parameters);
+static command_result sort_items(color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("sort");
@@ -59,6 +64,16 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
" name, age, arrival, squad, squad_position, profession\n"
"The orderings are defined in hack/lua/plugins/sort/*.lua\n"
));
+ commands.push_back(PluginCommand(
+ "sort-items", "Sort the visible item list.", sort_items, item_list_hotkey,
+ " sort-items order [order...]\n"
+ " Sort the item list using the given sequence of comparisons.\n"
+ " The '<' prefix for an order makes undefined values sort first.\n"
+ " The '>' prefix reverses the sort order for defined values.\n"
+ " Item order examples:\n"
+ " description, material, wear, type, quality\n"
+ "The orderings are defined in hack/lua/plugins/sort/*.lua\n"
+ ));
return CR_OK;
}
@@ -179,7 +194,7 @@ bool compute_order(color_ostream &out, lua_State *L, int base, std::vector<unsig
static bool ParseSpec(color_ostream &out, lua_State *L, const char *type, vector<string> &params)
{
- if (!parse_ordering_spec(out, L, "units", params))
+ if (!parse_ordering_spec(out, L, type, params))
{
out.printerr("Invalid ordering specification for %s.\n", type);
return false;
@@ -191,6 +206,20 @@ static bool ParseSpec(color_ostream &out, lua_State *L, const char *type, vector
#define PARSE_SPEC(type, params) \
if (!ParseSpec(*pout, L, type, params)) return false;
+static bool prepare_sort(color_ostream *pout, lua_State *L)
+{
+ if (L)
+ {
+ if (!Lua::PushModulePublic(*pout, L, "plugins.sort", "make_sort_order"))
+ {
+ pout->printerr("Cannot access the sorter function.\n");
+ return false;
+ }
+ }
+
+ return true;
+}
+
static void sort_null_first(vector<string> &parameters)
{
vector_insert_at(parameters, 0, std::string("<exists"));
@@ -206,14 +235,8 @@ static bool maybe_sort_units(color_ostream *pout, lua_State *L,
{
Lua::StackUnwinder top(L);
- if (L)
- {
- if (!Lua::PushModulePublic(*pout, L, "plugins.sort", "make_sort_order"))
- {
- pout->printerr("Cannot access the sorter function.\n");
- return false;
- }
- }
+ if (!prepare_sort(pout, L))
+ return false;
std::vector<unsigned> order;
@@ -526,3 +549,96 @@ static command_result sort_units(color_ostream &out, vector <string> &parameters
return CR_OK;
}
+
+static bool maybe_sort_items(color_ostream *pout, lua_State *L,
+ df::viewscreen *screen, vector<string> &parameters)
+{
+ Lua::StackUnwinder top(L);
+
+ if (!prepare_sort(pout, L))
+ return false;
+
+ std::vector<unsigned> order;
+
+ if (auto trade = strict_virtual_cast<df::viewscreen_tradegoodsst>(screen))
+ {
+ if (!L) return true;
+
+ PARSE_SPEC("items", parameters);
+
+ if (trade->in_right_pane)
+ {
+ if (compute_order(*pout, L, top, &order, trade->broker_items))
+ {
+ reorder_cursor(&trade->broker_cursor, order);
+ reorder_vector(&trade->broker_items, order);
+ reorder_vector(&trade->broker_selected, order);
+ reorder_vector(&trade->broker_count, order);
+ }
+ }
+ else
+ {
+ if (compute_order(*pout, L, top, &order, trade->trader_items))
+ {
+ reorder_cursor(&trade->trader_cursor, order);
+ reorder_vector(&trade->trader_items, order);
+ reorder_vector(&trade->trader_selected, order);
+ reorder_vector(&trade->trader_count, order);
+ }
+ }
+
+ return true;
+ }
+ else if (auto bring = strict_virtual_cast<df::viewscreen_layer_assigntradest>(screen))
+ {
+ auto list1 = getLayerList(bring, 0);
+ auto list2 = getLayerList(bring, 1);
+ if (!list1 || !list2 || !list2->bright)
+ return false;
+
+ int list_idx = vector_get(bring->visible_lists, list1->cursor, (int16_t)-1);
+ unsigned num_lists = sizeof(bring->lists)/sizeof(std::vector<int32_t>);
+ if (unsigned(list_idx) >= num_lists)
+ return false;
+
+ if (!L) return true;
+
+ PARSE_SPEC("items", parameters);
+
+ auto &vec = bring->lists[list_idx];
+
+ std::vector<df::item*> items;
+ for (size_t i = 0; i < vec.size(); i++)
+ items.push_back(bring->info[vec[i]]->item);
+
+ if (compute_order(*pout, L, top, &order, items))
+ {
+ reorder_cursor(&list2->cursor, order);
+ reorder_vector(&vec, order);
+ }
+
+ return true;
+ }
+ else
+ return false;
+}
+
+static bool item_list_hotkey(df::viewscreen *screen)
+{
+ vector<string> dummy;
+ return maybe_sort_items(NULL, NULL, screen, dummy);
+}
+
+static command_result sort_items(color_ostream &out, vector <string> &parameters)
+{
+ if (parameters.empty())
+ return CR_WRONG_USAGE;
+
+ auto L = Lua::Core::State;
+ auto screen = Core::getInstance().getTopViewscreen();
+
+ if (!maybe_sort_items(&out, L, screen, parameters))
+ return CR_WRONG_USAGE;
+
+ return CR_OK;
+}