From 2597aeab0e4dd2a3ab4ba8f368e59e713669d09a Mon Sep 17 00:00:00 2001 From: Quietust Date: Tue, 2 Jun 2020 09:10:25 -0600 Subject: [PATCH] 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