diff --git a/plugins/tweak.cpp b/plugins/tweak.cpp index 61f122d53..cf6326936 100644 --- a/plugins/tweak.cpp +++ b/plugins/tweak.cpp @@ -683,6 +683,55 @@ static bool can_spar(df::unit *unit) { (!unit->job.current_job || unit->job.current_job != job_type::Rest); } +static bool has_spar_inventory(df::unit *unit, df::job_skill skill) +{ + using namespace df::enums::job_skill; + + auto type = ENUM_ATTR(job_skill, type, skill); + + if (type == job_skill_class::MilitaryWeapon) + { + for (size_t i = 0; i < unit->inventory.size(); i++) + { + auto item = unit->inventory[i]; + if (item->mode == df::unit_inventory_item::Weapon && + item->item->getMeleeSkill() == skill) + return true; + } + + return false; + } + + switch (skill) { + case THROW: + case RANGED_COMBAT: + return false; + + case SHIELD: + for (size_t i = 0; i < unit->inventory.size(); i++) + { + auto item = unit->inventory[i]; + if (item->mode == df::unit_inventory_item::Weapon && + item->item->getType() == item_type::SHIELD) + return true; + } + return false; + + case ARMOR: + for (size_t i = 0; i < unit->inventory.size(); i++) + { + auto item = unit->inventory[i]; + if (item->mode == df::unit_inventory_item::Worn && + item->item->isArmorNotClothing()) + return true; + } + return false; + + default: + return true; + } +} + struct military_training_ct_hook : df::activity_event_combat_trainingst { typedef df::activity_event_combat_trainingst interpose_base; @@ -740,7 +789,7 @@ struct military_training_ct_hook : df::activity_event_combat_trainingst { maxv = xp; best = j; } - if (can_spar(unit)) + if (can_spar(unit) && has_spar_inventory(unit, sd->skill)) spar++; } @@ -750,7 +799,8 @@ struct military_training_ct_hook : df::activity_event_combat_trainingst { if ((maxv - minv) < 64*15 && spar == units.size() && random_int(20) >= 5 + (maxv-minv)/64) { - out.print("Replacing demonstration with sparring.\n"); + out.print("Replacing %s demonstration (xp %d-%d) with sparring.\n", + ENUM_KEY_STR(job_skill, sd->skill).c_str(), minv, maxv); if (auto spar = df::allocate()) { @@ -772,7 +822,8 @@ struct military_training_ct_hook : df::activity_event_combat_trainingst { // If the teacher has less xp than somebody else, switch if (best >= 0 && maxv > cur_xp) { - out.print("Replacing teacher %d (%d xp) with %d (%d xp)\n", + out.print("Replacing %s teacher %d (%d xp) with %d (%d xp)\n", + ENUM_KEY_STR(job_skill, sd->skill).c_str(), sd->unit_id, cur_xp, units[best], maxv); sd->hist_figure_id = sd->participants.histfigs[best];