New tweak: condition-material (fixes bug 9905)

http://www.bay12games.com/dwarves/mantisbt/view.php?id=9905
develop
lethosor 2017-03-28 09:50:38 -04:00
parent aea76b7ef3
commit 78cb4a31b9
5 changed files with 144 additions and 1 deletions

@ -181,6 +181,9 @@ tweak farm-plot-select
# Add Shift-Left/Right controls to import agreement screen
tweak import-priority-category
# Fixes a crash in the work order contition material list (bug 9905).
tweak condition-material
# Misc. UI tweaks
tweak block-labors # Prevents labors that can't be used from being toggled
tweak civ-view-agreement

@ -272,6 +272,7 @@ Subcommands that persist until disabled or DF quits:
reagents.
:block-labors: Prevents labors that can't be used from being toggled
:civ-view-agreement: Fixes overlapping text on the "view agreement" screen
:condition-material: Fixes a crash in the work order contition material list (:bug:`9905`).
:craft-age-wear: Fixes the behavior of crafted items wearing out over time (:bug:`6003`).
With this tweak, items made from cloth and leather will gain a level of
wear every 20 years.

@ -1 +1 @@
Subproject commit 8727ebd74a3f5d90e34a08266a3719e0cd5817d9
Subproject commit 9b834c089efb4657d43a8fa4f8f0822e8224e576

@ -81,6 +81,7 @@
#include "tweaks/advmode-contained.h"
#include "tweaks/block-labors.h"
#include "tweaks/civ-agreement-ui.h"
#include "tweaks/condition-material.h"
#include "tweaks/craft-age-wear.h"
#include "tweaks/eggs-fertile.h"
#include "tweaks/embark-profile-name.h"
@ -183,6 +184,8 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
" Prevents labors that can't be used from being toggled.\n"
" tweak civ-view-agreement\n"
" Fixes overlapping text on the \"view agreement\" screen\n"
" tweak condition-material\n"
" Fixes a crash in the work order contition material list (bug 9905).\n"
" tweak craft-age-wear [disable]\n"
" Makes cloth and leather items wear out at the correct rate (bug 6003).\n"
" tweak embark-profile-name [disable]\n"
@ -246,6 +249,8 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
TWEAK_HOOK("civ-view-agreement", civ_agreement_view_hook, render);
TWEAK_HOOK("condition-material", condition_material_hook, feed);
TWEAK_HOOK("craft-age-wear", craft_age_wear_hook, ageItem);
TWEAK_HOOK("eggs-fertile", egg_fertile_hook, render);

@ -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);