Esempio n. 1
0
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);

}
Esempio n. 2
0
void CGHeroInstance::initHero()
{
	assert(validTypes(true));
	if(!type)
		type = VLC->heroh->heroes[subID];

	if (ID == Obj::HERO)
		appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->id)->getTemplates().front();

	if(!vstd::contains(spells, SpellID::PRESET)) //hero starts with a spell
	{
		for(auto spellID : type->spells)
			spells.insert(spellID);
	}
	else //remove placeholder
		spells -= SpellID::PRESET;

	if(!getArt(ArtifactPosition::MACH4) && !getArt(ArtifactPosition::SPELLBOOK) && type->haveSpellBook) //no catapult means we haven't read pre-existent set -> use default rules for spellbook
		putArtifact(ArtifactPosition::SPELLBOOK, CArtifactInstance::createNewArtifactInstance(0));

	if(!getArt(ArtifactPosition::MACH4))
		putArtifact(ArtifactPosition::MACH4, CArtifactInstance::createNewArtifactInstance(3)); //everyone has a catapult

	if(portrait < 0 || portrait == 255)
		portrait = type->imageIndex;
	if(!hasBonus(Selector::sourceType(Bonus::HERO_BASE_SKILL)))
	{
		for(int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
		{
			pushPrimSkill(static_cast<PrimarySkill::PrimarySkill>(g), type->heroClass->primarySkillInitial[g]);
		}
	}
	if(secSkills.size() == 1 && secSkills[0] == std::pair<SecondarySkill,ui8>(SecondarySkill::DEFAULT, -1)) //set secondary skills to default
		secSkills = type->secSkillsInit;
	if (!name.length())
		name = type->name;

	if (sex == 0xFF)//sex is default
		sex = type->sex;

	setFormation(false);
	if (!stacksCount()) //standard army//initial army
	{
		initArmy();
	}
	assert(validTypes());

	level = 1;
	if(exp == 0xffffffff)
	{
		initExp();
	}
	else
	{
		levelUpAutomatically();
	}

	if (VLC->modh->modules.COMMANDERS && !commander)
	{
		commander = new CCommanderInstance(type->heroClass->commander->idNumber);
		commander->setArmyObj (castToArmyObj()); //TODO: separate function for setting commanders
		commander->giveStackExp (exp); //after our exp is set
	}

	if (mana < 0)
		mana = manaLimit();
}