Merge remote-tracking branch 'quietust/reaction-gloves' into develop

develop
lethosor 2020-07-16 22:40:49 -04:00
commit 89c24ac8be
No known key found for this signature in database
GPG Key ID: 76A269552F4F58C1
4 changed files with 89 additions and 0 deletions

@ -335,6 +335,7 @@ Subcommands that persist until disabled or DF quits:
:stone-status-all: Adds an option to toggle the economic status of all stones :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 :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 :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: .. _fix-armory:

@ -33,6 +33,9 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
# Future # Future
## New Tweaks
- `tweak` reaction-gloves: adds an option to make reactions produce gloves in sets with correct handedness
## Fixes ## Fixes
- Fixed a segfault when attempting to start a headless session with a graphical PRINT_MODE setting - Fixed a segfault when attempting to start a headless session with a graphical PRINT_MODE setting
- Fixed an issue with the macOS launcher failing to un-quarantine some files - Fixed an issue with the macOS launcher failing to un-quarantine some files

@ -59,6 +59,7 @@
#include "df/reaction.h" #include "df/reaction.h"
#include "df/reaction_reagent_itemst.h" #include "df/reaction_reagent_itemst.h"
#include "df/reaction_reagent_flags.h" #include "df/reaction_reagent_flags.h"
#include "df/reaction_product_itemst.h"
#include "df/viewscreen_setupdwarfgamest.h" #include "df/viewscreen_setupdwarfgamest.h"
#include "df/viewscreen_layer_assigntradest.h" #include "df/viewscreen_layer_assigntradest.h"
#include "df/viewscreen_tradegoodsst.h" #include "df/viewscreen_tradegoodsst.h"
@ -106,6 +107,7 @@
#include "tweaks/stone-status-all.h" #include "tweaks/stone-status-all.h"
#include "tweaks/title-start-rename.h" #include "tweaks/title-start-rename.h"
#include "tweaks/tradereq-pet-gender.h" #include "tweaks/tradereq-pet-gender.h"
#include "tweaks/reaction-gloves.h"
using std::set; using std::set;
using std::vector; using std::vector;
@ -250,6 +252,8 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
" Adds a safe rename option to the title screen \"Start Playing\" menu\n" " Adds a safe rename option to the title screen \"Start Playing\" menu\n"
" tweak tradereq-pet-gender [disable]\n" " tweak tradereq-pet-gender [disable]\n"
" Displays the gender of pets in the trade request list\n" " Displays the gender of pets in the trade request list\n"
" tweak reaction-gloves [disable]\n"
" Changes custom reactions to produce gloves in sets with correct handedness\n"
// " tweak military-training [disable]\n" // " tweak military-training [disable]\n"
// " Speed up melee squad training, removing inverse dependency on unit count.\n" // " Speed up melee squad training, removing inverse dependency on unit count.\n"
)); ));
@ -332,6 +336,8 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
TWEAK_HOOK("tradereq-pet-gender", pet_gender_hook, render); TWEAK_HOOK("tradereq-pet-gender", pet_gender_hook, render);
TWEAK_HOOK("reaction-gloves", reaction_gloves_hook, produce);
return CR_OK; return CR_OK;
} }

@ -0,0 +1,79 @@
// Workaround for DF bug #6273 - adjust all custom reactions to produce GLOVES items in sets with correct handedness
// It also analyzes the body plan of the unit performing the reaction, so Antmen will get 4 gloves instead of 2
// If a reaction tries to produce either 1 glove or 2 gloves, it will produce a single set
// Otherwise, it will multiply the number of products by the number of hands
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<df::reaction_product*> *out_products, std::vector<df::item*> *out_items,
std::vector<df::reaction_reagent*> *in_reag, std::vector<df::item*> *in_items,
int32_t quantity, df::job_skill skill, int32_t quality,
df::historical_entity *entity, df::world_site *site, std::vector<void *> *unk_2))
{
if (item_type != df::item_type::GLOVES)
{
INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, quality, entity, 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<df::item*> 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, 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
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);