New tweak: condition-material (fixes bug 9905)
http://www.bay12games.com/dwarves/mantisbt/view.php?id=9905develop
parent
aea76b7ef3
commit
78cb4a31b9
@ -1 +1 @@
|
||||
Subproject commit 8727ebd74a3f5d90e34a08266a3719e0cd5817d9
|
||||
Subproject commit 9b834c089efb4657d43a8fa4f8f0822e8224e576
|
@ -0,0 +1,134 @@
|
||||
#include "df/viewscreen_workquota_conditionst.h"
|
||||
|
||||
using namespace DFHack;
|
||||
|
||||
struct condition_material_hook : df::viewscreen_workquota_conditionst {
|
||||
typedef df::viewscreen_workquota_conditionst interpose_base;
|
||||
typedef df::viewscreen_workquota_conditionst T_screen;
|
||||
|
||||
struct T_order_mat_data {
|
||||
std::vector<std::string*> list_entries;
|
||||
std::vector<int16_t> list_unk1;
|
||||
std::vector<int32_t> list_unk2;
|
||||
std::vector<int16_t> list_unk3;
|
||||
std::vector<int16_t> list_visible;
|
||||
};
|
||||
|
||||
static std::map<df::viewscreen_workquota_conditionst*, T_order_mat_data*> order_mat_data;
|
||||
|
||||
static void register_screen(T_screen *scr)
|
||||
{
|
||||
if (order_mat_data.find(scr) != order_mat_data.end())
|
||||
{
|
||||
unregister_screen(scr);
|
||||
}
|
||||
auto data = new T_order_mat_data;
|
||||
data->list_entries = scr->list_entries;
|
||||
data->list_unk1 = scr->list_unk1;
|
||||
data->list_unk2 = scr->list_unk2;
|
||||
data->list_unk3 = scr->list_unk3;
|
||||
data->list_visible = scr->list_visible;
|
||||
order_mat_data[scr] = data;
|
||||
}
|
||||
|
||||
static void unregister_screen(T_screen *scr)
|
||||
{
|
||||
if (order_mat_data.find(scr) != order_mat_data.end() && order_mat_data[scr])
|
||||
{
|
||||
T_order_mat_data *data = order_mat_data[scr];
|
||||
scr->list_entries = data->list_entries;
|
||||
scr->list_unk1 = data->list_unk1;
|
||||
scr->list_unk2 = data->list_unk2;
|
||||
scr->list_unk3 = data->list_unk3;
|
||||
scr->list_visible = data->list_visible;
|
||||
delete data;
|
||||
order_mat_data.erase(scr);
|
||||
}
|
||||
}
|
||||
|
||||
void apply_filter()
|
||||
{
|
||||
if (order_mat_data.find(this) != order_mat_data.end() && order_mat_data[this])
|
||||
{
|
||||
list_idx = 0;
|
||||
T_order_mat_data *data = order_mat_data[this];
|
||||
// keep the first item ("no material") around, because attempts to delete it
|
||||
// result in it still being displayed first, regardless of list_entries[0]
|
||||
list_entries.resize(1);
|
||||
list_unk1.resize(1);
|
||||
list_unk2.resize(1);
|
||||
list_unk3.resize(1);
|
||||
list_visible.resize(1);
|
||||
// skip "no material" here
|
||||
for (size_t i = 1; i < data->list_entries.size(); i++)
|
||||
{
|
||||
// cap it at 32767 elements to be safe
|
||||
if (list_entries.size() >= INT16_MAX)
|
||||
{
|
||||
break;
|
||||
}
|
||||
std::string *s = data->list_entries[i];
|
||||
if (s->find(filter) != std::string::npos)
|
||||
{
|
||||
list_entries.push_back(data->list_entries[i]);
|
||||
list_unk1.push_back(data->list_unk1[i]);
|
||||
list_unk2.push_back(data->list_unk2[i]);
|
||||
list_unk3.push_back(data->list_unk3[i]);
|
||||
// this should be small enough to fit in an int16_t
|
||||
list_visible.push_back(int16_t(list_entries.size() - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_VMETHOD_INTERPOSE(void, feed, (std::set<df::interface_key> *input))
|
||||
{
|
||||
using namespace df::enums::interface_key;
|
||||
if (mode == T_mode::Material)
|
||||
{
|
||||
for (auto key : *input)
|
||||
{
|
||||
if (key == LEAVESCREEN || key == SELECT)
|
||||
{
|
||||
INTERPOSE_NEXT(feed)(input);
|
||||
unregister_screen(this);
|
||||
return;
|
||||
}
|
||||
else if (key == STANDARDSCROLL_UP || key == STANDARDSCROLL_DOWN ||
|
||||
key == STANDARDSCROLL_PAGEUP || key == STANDARDSCROLL_PAGEDOWN)
|
||||
{
|
||||
INTERPOSE_NEXT(feed)(input);
|
||||
}
|
||||
int ch = Screen::keyToChar(key);
|
||||
if (ch != -1)
|
||||
{
|
||||
if (ch == 0)
|
||||
{
|
||||
if (!filter.empty())
|
||||
{
|
||||
filter.erase(filter.size() - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
filter += tolower(char(ch));
|
||||
}
|
||||
apply_filter();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
INTERPOSE_NEXT(feed)(input);
|
||||
if (mode == T_mode::Material)
|
||||
{
|
||||
register_screen(this);
|
||||
apply_filter();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::map<df::viewscreen_workquota_conditionst*, condition_material_hook::T_order_mat_data*> condition_material_hook::order_mat_data;
|
||||
|
||||
IMPLEMENT_VMETHOD_INTERPOSE(condition_material_hook, feed);
|
Loading…
Reference in New Issue