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).develop
parent
e2301ecae7
commit
2597aeab0e
@ -0,0 +1,75 @@
|
||||
// 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, 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<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, 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);
|
Loading…
Reference in New Issue