void CGHeroInstance::recreateSecondarySkillsBonuses() { auto secondarySkillsBonuses = getBonuses(Selector::sourceType(Bonus::SECONDARY_SKILL)); for(auto bonus : *secondarySkillsBonuses) removeBonus(bonus); for(auto skill_info : secSkills) updateSkill(SecondarySkill(skill_info.first), skill_info.second); }
void CArmedInstance::updateMoraleBonusFromArmy() { if(!validTypes(false)) //object not randomized, don't bother return; auto b = getExportedBonusList().getFirst(Selector::sourceType(Bonus::ARMY).And(Selector::type(Bonus::MORALE))); if(!b) { b = std::make_shared<Bonus>(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, 0, -1); addNewBonus(b); } //number of alignments and presence of undead std::set<TFaction> factions; bool hasUndead = false; for(auto slot : Slots()) { const CStackInstance * inst = slot.second; const CCreature * creature = VLC->creh->creatures[inst->getCreatureID()]; factions.insert(creature->faction); // Check for undead flag instead of faction (undead mummies are neutral) hasUndead |= inst->hasBonusOfType(Bonus::UNDEAD); } size_t factionsInArmy = factions.size(); //town garrison seems to take both sets into account // Take Angelic Alliance troop-mixing freedom of non-evil units into account. if (hasBonusOfType(Bonus::NONEVIL_ALIGNMENT_MIX)) { size_t mixableFactions = 0; for(TFaction f : factions) { if (VLC->townh->factions[f]->alignment != EAlignment::EVIL) mixableFactions++; } if (mixableFactions > 0) factionsInArmy -= mixableFactions - 1; } if(factionsInArmy == 1) { b->val = +1; b->description = VLC->generaltexth->arraytxt[115]; //All troops of one alignment +1 b->description = b->description.substr(0, b->description.size()-3);//trim "+1" } else if (!factions.empty()) // no bonus from empty garrison { b->val = 2 - factionsInArmy; b->description = boost::str(boost::format(VLC->generaltexth->arraytxt[114]) % factionsInArmy % b->val); //Troops of %d alignments %d b->description = b->description.substr(0, b->description.size()-2);//trim value } boost::algorithm::trim(b->description); CBonusSystemNode::treeHasChanged(); //-1 modifier for any Undead unit in army const ui8 UNDEAD_MODIFIER_ID = -2; auto undeadModifier = getExportedBonusList().getFirst(Selector::source(Bonus::ARMY, UNDEAD_MODIFIER_ID)); if(hasUndead) { if(!undeadModifier) { undeadModifier = std::make_shared<Bonus>(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, -1, UNDEAD_MODIFIER_ID, VLC->generaltexth->arraytxt[116]); undeadModifier->description = undeadModifier->description.substr(0, undeadModifier->description.size()-2);//trim value addNewBonus(undeadModifier); } } else if(undeadModifier) removeBonus(undeadModifier); }