From 2597aeab0e4dd2a3ab4ba8f368e59e713669d09a Mon Sep 17 00:00:00 2001 From: Quietust Date: Tue, 2 Jun 2020 09:10:25 -0600 Subject: [PATCH 1/3] Add a new tweak, "reaction-gloves" When enabled, custom reactions will begin to produce gloves in sets, based on the number of hands the job performer's race has, and set the Handedness flags accordingly. The "createitem" plugin already contains a simpler workaround (which doesn't check body plan but instead just produces pairs), but it shouldn't trigger when this tweak is enabled (unless you use it on a creature which has been modded to only have "neutral" hands). --- plugins/tweak/tweak.cpp | 6 +++ plugins/tweak/tweaks/reaction-gloves.h | 75 ++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 plugins/tweak/tweaks/reaction-gloves.h diff --git a/plugins/tweak/tweak.cpp b/plugins/tweak/tweak.cpp index 49d96cc74..13e08f174 100644 --- a/plugins/tweak/tweak.cpp +++ b/plugins/tweak/tweak.cpp @@ -59,6 +59,7 @@ #include "df/reaction.h" #include "df/reaction_reagent_itemst.h" #include "df/reaction_reagent_flags.h" +#include "df/reaction_product_itemst.h" #include "df/viewscreen_setupdwarfgamest.h" #include "df/viewscreen_layer_assigntradest.h" #include "df/viewscreen_tradegoodsst.h" @@ -106,6 +107,7 @@ #include "tweaks/stone-status-all.h" #include "tweaks/title-start-rename.h" #include "tweaks/tradereq-pet-gender.h" +#include "tweaks/reaction-gloves.h" using std::set; using std::vector; @@ -250,6 +252,8 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector *out_products, std::vector *out_items, std::vector *in_reag, std::vector *in_items, int32_t quantity, df::job_skill skill, df::historical_entity *entity, int32_t unk_1, df::world_site *site, void *unk_2)) + { + if (item_type != df::item_type::GLOVES) + { + INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, entity, unk_1, site, unk_2); + return; + } + + // Examine creator unit's body plan, see how many hands it has + // Count left hands and right hands, as well as "neutral" hands for compatibility + int num_hands = 0, num_left = 0, num_right = 0; + for (int i = 0; i < unit->body.body_plan->body_parts.size(); i++) + { + df::body_part_raw *part = unit->body.body_plan->body_parts[i]; + if (part->flags.is_set(df::body_part_raw_flags::GRASP)) + { + num_hands++; + if (part->flags.is_set(df::body_part_raw_flags::LEFT)) + num_left++; + if (part->flags.is_set(df::body_part_raw_flags::RIGHT)) + num_right++; + } + } + + std::vector out_items_temp; + int old_count = count; + + // If the reaction product's count is set to 1 or 2, set it to the number of hands + // Otherwise, *multiply* it by the number of hands (and multiply the left/right counts accordingly) + if (count <= 2) + count = num_hands; + else + { + num_left *= count; + num_right *= count; + count *= num_hands; + } + + INTERPOSE_NEXT(produce)(unit, out_products, &out_items_temp, in_reag, in_items, quantity, skill, entity, unk_1, site, unk_2); + count = old_count; + + // If the reaction was somehow asked to produce multiple sets (due to excess inputs), multiply the outputs too + num_left *= quantity; + num_right *= quantity; + + // Iterate across the output gloves, set their handedness, then append them to the actual out_items list for DF + for (int i = 0; i < out_items_temp.size(); i++) + { + // Do left gloves first, then right gloves, then "neutral" ones last + // This is important for the "createitem" plugin, which contains similar workaround logic + if (num_left > 0) + { + out_items_temp[i]->setGloveHandedness(1); + --num_left; + } + else if (num_right > 0) + { + out_items_temp[i]->setGloveHandedness(2); + --num_right; + } + out_items->push_back(out_items_temp[i]); + } + } +}; + +IMPLEMENT_VMETHOD_INTERPOSE(reaction_gloves_hook, produce); \ No newline at end of file From c2776c20b97db44b0d18662627d88b69b252c1ed Mon Sep 17 00:00:00 2001 From: Quietust Date: Tue, 2 Jun 2020 09:56:42 -0600 Subject: [PATCH 2/3] Update changelog --- docs/Plugins.rst | 1 + docs/changelog.txt | 3 +++ 2 files changed, 4 insertions(+) diff --git a/docs/Plugins.rst b/docs/Plugins.rst index 421e5e81b..37e568167 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -332,6 +332,7 @@ Subcommands that persist until disabled or DF quits: :stone-status-all: Adds an option to toggle the economic status of all stones :title-start-rename: Adds a safe rename option to the title screen "Start Playing" menu :tradereq-pet-gender: Displays pet genders on the trade request screen +:reaction-gloves: Fixes reactions to produce gloves in sets with correct handedness .. _fix-armory: diff --git a/docs/changelog.txt b/docs/changelog.txt index c165ff855..c0e9b5440 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -39,6 +39,9 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: # Future +## New Tweaks +- `tweak` reaction-gloves: adds an option to make reactions produce gloves in sets with correct handedness + ## Fixes - Fixed a segfault when attempting to start a headless session with a graphical PRINT_MODE setting - `labormanager`: fixed handling of new jobs in 0.47 From 3dcde1554a1a93b860eb972e60d898e84b24818d Mon Sep 17 00:00:00 2001 From: Quietust Date: Tue, 23 Jun 2020 13:36:00 -0600 Subject: [PATCH 3/3] Update xml, fix reaction_product::produce() parms --- plugins/tweak/tweaks/reaction-gloves.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/tweak/tweaks/reaction-gloves.h b/plugins/tweak/tweaks/reaction-gloves.h index 6ef3c6ccf..82890239c 100644 --- a/plugins/tweak/tweaks/reaction-gloves.h +++ b/plugins/tweak/tweaks/reaction-gloves.h @@ -7,11 +7,15 @@ struct reaction_gloves_hook : df::reaction_product_itemst { typedef df::reaction_product_itemst interpose_base; - DEFINE_VMETHOD_INTERPOSE(void, produce, (df::unit *unit, std::vector *out_products, std::vector *out_items, std::vector *in_reag, std::vector *in_items, int32_t quantity, df::job_skill skill, df::historical_entity *entity, int32_t unk_1, df::world_site *site, void *unk_2)) + DEFINE_VMETHOD_INTERPOSE(void, produce, (df::unit *unit, + std::vector *out_products, std::vector *out_items, + std::vector *in_reag, std::vector *in_items, + int32_t quantity, df::job_skill skill, int32_t quality, + df::historical_entity *entity, df::world_site *site, std::vector *unk_2)) { if (item_type != df::item_type::GLOVES) { - INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, entity, unk_1, site, unk_2); + INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, quality, entity, site, unk_2); return; } @@ -45,7 +49,7 @@ struct reaction_gloves_hook : df::reaction_product_itemst { count *= num_hands; } - INTERPOSE_NEXT(produce)(unit, out_products, &out_items_temp, in_reag, in_items, quantity, skill, entity, unk_1, site, unk_2); + INTERPOSE_NEXT(produce)(unit, out_products, &out_items_temp, in_reag, in_items, quantity, skill, quality, entity, site, unk_2); count = old_count; // If the reaction was somehow asked to produce multiple sets (due to excess inputs), multiply the outputs too