// 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 *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, 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 (size_t 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, 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 (size_t 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);