mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Fixed #484. Preliminary support for bonus limiters/
This commit is contained in:
		| @@ -48,6 +48,7 @@ | ||||
| #ifdef _WIN32 | ||||
| #include "SDL_syswm.h" | ||||
| #endif | ||||
| #include <boost/foreach.hpp> | ||||
|  | ||||
| #if __MINGW32__ | ||||
| #undef main | ||||
| @@ -427,6 +428,19 @@ void processCommand(const std::string &message) | ||||
| 		if(const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(adventureInt->selection)) | ||||
| 			tlog0 << h->movement << "; max: " << h->maxMovePoints(true) << "/" << h->maxMovePoints(false) << std::endl; | ||||
| 	} | ||||
| 	else if(cn == "bonuses") | ||||
| 	{ | ||||
| 		tlog0 << "Bonuses of " << adventureInt->selection->getHoverText() << std::endl | ||||
| 			<< adventureInt->selection->bonuses << std::endl; | ||||
|  | ||||
| 		tlog0 << "\nInherited bonuses:\n"; | ||||
| 		TCNodes parents; | ||||
| 		adventureInt->selection->getParents(parents); | ||||
| 		BOOST_FOREACH(const CBonusSystemNode *parent, parents) | ||||
| 		{ | ||||
| 			tlog0 << "\nBonuses from " << typeid(*parent).name() << std::endl << parent->bonuses << std::endl; | ||||
| 		} | ||||
| 	} | ||||
| 	else if(client && client->serv && client->serv->connected) //send to server | ||||
| 	{ | ||||
| 		PlayerMessage pm(LOCPLINT->playerID,message); | ||||
|   | ||||
| @@ -128,6 +128,12 @@ void CCreature::addBonus(int val, int type, int subtype /*= -1*/) | ||||
| 	bonuses.push_back(added); | ||||
| } | ||||
|  | ||||
| bool CCreature::isMyUpgrade(const CCreature *anotherCre) const | ||||
| { | ||||
| 	//TODO upgrade of upgrade? | ||||
| 	return vstd::contains(upgrades, anotherCre->idNumber); | ||||
| } | ||||
|  | ||||
| int readNumber(int & befi, int & i, int andame, std::string & buf) //helper function for void CCreatureHandler::loadCreatures() and loadUnitAnimInfo() | ||||
| { | ||||
| 	befi=i; | ||||
| @@ -338,11 +344,6 @@ void CCreatureHandler::loadCreatures() | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	// Map types names | ||||
| #define BONUS_NAME(x) ( #x, Bonus::x ) | ||||
| 	static const std::map<std::string, int> type_list = map_list_of BONUS_LIST; | ||||
| #undef BONUS_NAME | ||||
|  | ||||
| 	////second part of reading cr_abils.txt//// | ||||
| 	bool contReading = true; | ||||
| 	while(contReading) //main reading loop | ||||
| @@ -363,10 +364,10 @@ void CCreatureHandler::loadCreatures() | ||||
| 				reader >> creatureID; | ||||
| 				reader >> type; | ||||
|  | ||||
| 				std::map<std::string, int>::const_iterator it = type_list.find(type); | ||||
| 				std::map<std::string, int>::const_iterator it = bonusNameMap.find(type); | ||||
| 				CCreature *cre = creatures[creatureID]; | ||||
|  | ||||
| 				if (it == type_list.end())  | ||||
| 				if (it == bonusNameMap.end())  | ||||
| 				{ | ||||
| 					if(type == "DOUBLE_WIDE") | ||||
| 						cre->doubleWide = true; | ||||
| @@ -403,8 +404,8 @@ void CCreatureHandler::loadCreatures() | ||||
| 				std::string type; | ||||
| 				reader >> creatureID; | ||||
| 				reader >> type; | ||||
| 				std::map<std::string, int>::const_iterator it = type_list.find(type); | ||||
| 				if (it == type_list.end()) | ||||
| 				std::map<std::string, int>::const_iterator it = bonusNameMap.find(type); | ||||
| 				if (it == bonusNameMap.end()) | ||||
| 				{ | ||||
| 					if(type == "DOUBLE_WIDE") | ||||
| 						creatures[creatureID]->doubleWide = false; | ||||
|   | ||||
| @@ -55,9 +55,11 @@ public: | ||||
| 	bool isEvil () const; | ||||
| 	si32 maxAmount(const std::vector<si32> &res) const; //how many creatures can be bought | ||||
| 	static int getQuantityID(const int & quantity); //0 - a few, 1 - several, 2 - pack, 3 - lots, 4 - horde, 5 - throng, 6 - swarm, 7 - zounds, 8 - legion | ||||
| 	bool isMyUpgrade(const CCreature *anotherCre) const; | ||||
|  | ||||
| 	void addBonus(int val, int type, int subtype = -1); | ||||
|  | ||||
|  | ||||
| 	template<typename RanGen> | ||||
| 	int getRandomAmount(RanGen &ranGen) | ||||
| 	{ | ||||
|   | ||||
| @@ -973,50 +973,60 @@ void CGHeroInstance::initObj() | ||||
| 		{ | ||||
| 			case 1:// creature speciality | ||||
| 				{ | ||||
| 					speciality.growthsWithLevel = true; | ||||
|  | ||||
| 					bonus.type = Bonus::SPECIAL_CREATURE_LEV; // general info to indicate type of growing bonus | ||||
| 					bonus.additionalInfo = it->additionalinfo; //base creature ID | ||||
| 					speciality.bonuses.push_back (bonus); | ||||
|  | ||||
| 					std::vector<CCreature*>* creatures = &VLC->creh->creatures; | ||||
| 					int creLevel = (*creatures)[it->additionalinfo]->level; | ||||
| 					const CCreature &specCreature = *VLC->creh->creatures[it->additionalinfo]; //creature in which we have specialty | ||||
|  | ||||
| 					int creLevel = specCreature.level; | ||||
| 					if(!creLevel) //TODO: set fixed level for War Machines | ||||
| 					{ | ||||
| 						if(it->additionalinfo == 146) | ||||
| 							creLevel = 5; //treat ballista as 5-level | ||||
| 						else | ||||
| 						{ | ||||
| 							tlog2 << "Warning: unknown level of " << (*creatures)[it->additionalinfo]->namePl << std::endl; | ||||
| 							tlog2 << "Warning: unknown level of " << specCreature.namePl << std::endl; | ||||
| 							continue; | ||||
| 						} | ||||
| 					} | ||||
|  | ||||
| 					speciality.growthsWithLevel = true; | ||||
| 					bonus.type = Bonus::PRIMARY_SKILL; //TODO: limit to specific creature type | ||||
| 					bonus.valType = Bonus::ADDITIVE_VALUE; | ||||
| 					bonus.subtype = 1; //attack | ||||
| 					bonus.val = level * (*creatures)[it->additionalinfo]->attack / creLevel /20; | ||||
| 					speciality.bonuses.push_back (bonus); | ||||
| 					bonus.subtype = 2; //defense | ||||
| 					bonus.val = level * (*creatures)[it->additionalinfo]->defence / creLevel /20; | ||||
| 					speciality.bonuses.push_back (bonus); | ||||
| 					bonus.type = Bonus::STACKS_SPEED; | ||||
| 					bonus.val = 1; //+1 speed | ||||
| 					speciality.bonuses.push_back (bonus); | ||||
| 					for (std::set<ui32>::iterator i = (*creatures)[it->additionalinfo]->upgrades.begin(); | ||||
| 						i != VLC->creh->creatures[it->additionalinfo]->upgrades.end(); i++) | ||||
| 					{ | ||||
| 						bonus.val = (*i); // for all direct upgrades of that creature | ||||
| 					int levelFactor = level / creLevel; //round down | ||||
| 					double primSkillModifier = levelFactor / 20.0; | ||||
|  | ||||
| 					bonus.limiter = new CCreatureTypeLimiter(specCreature); | ||||
| 					bonus.type = Bonus::PRIMARY_SKILL;  | ||||
| 						bonus.subtype = 1; //attack | ||||
| 						bonus.val = level * (*creatures)[*i]->attack / (*creatures)[*i]->level /20; | ||||
| 					bonus.valType = Bonus::ADDITIVE_VALUE; | ||||
|  | ||||
| 					bonus.subtype = PrimarySkill::ATTACK; | ||||
| 					bonus.val = std::ceil(primSkillModifier * specCreature.attack); | ||||
| 					speciality.bonuses.push_back (bonus); | ||||
| 						bonus.subtype = 2; //defense | ||||
| 						bonus.val = level * (*creatures)[*i]->defence / (*creatures)[*i]->level /20; | ||||
|  | ||||
| 					bonus.subtype = PrimarySkill::DEFENSE; | ||||
| 					bonus.val = std::ceil(primSkillModifier * specCreature.defence); | ||||
| 					speciality.bonuses.push_back (bonus); | ||||
|  | ||||
| 					bonus.type = Bonus::STACKS_SPEED; | ||||
| 					bonus.val = 1; //+1 speed | ||||
| 					speciality.bonuses.push_back (bonus); | ||||
| 					} | ||||
|  | ||||
| // 					for (std::set<ui32>::iterator i = (*creatures)[it->additionalinfo]->upgrades.begin(); | ||||
| // 						i != VLC->creh->creatures[it->additionalinfo]->upgrades.end(); i++) | ||||
| // 					{ | ||||
| // 						bonus.val = (*i); // for all direct upgrades of that creature | ||||
| // 						bonus.type = Bonus::PRIMARY_SKILL; | ||||
| // 						bonus.subtype = 1; //attack | ||||
| // 						bonus.val = level * (*creatures)[*i]->attack / (*creatures)[*i]->level /20; | ||||
| // 						speciality.bonuses.push_back (bonus); | ||||
| // 						bonus.subtype = 2; //defense | ||||
| // 						bonus.val = level * (*creatures)[*i]->defence / (*creatures)[*i]->level /20; | ||||
| // 						speciality.bonuses.push_back (bonus); | ||||
| // 						bonus.type = Bonus::STACKS_SPEED; | ||||
| // 						bonus.val = 1; //+1 speed | ||||
| // 						speciality.bonuses.push_back (bonus); | ||||
| // 					} | ||||
| 				} | ||||
| 				break; | ||||
| 			case 2://secondary skill | ||||
|   | ||||
| @@ -252,6 +252,7 @@ void CStackInstance::init() | ||||
| 	type = NULL; | ||||
| 	idRand = -1; | ||||
| 	armyObj = NULL; | ||||
| 	nodeType = STACK; | ||||
| } | ||||
|  | ||||
| int CStackInstance::getQuantityID() const  | ||||
|   | ||||
| @@ -117,11 +117,11 @@ class CObjectCaller : public IObjectCaller | ||||
| public: | ||||
| 	void preInit() | ||||
| 	{ | ||||
| 		T::preInit(); | ||||
| 		//T::preInit(); | ||||
| 	} | ||||
| 	void postInit() | ||||
| 	{ | ||||
| 		T::postInit(); | ||||
| 		//T::postInit(); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| @@ -148,14 +148,14 @@ public: | ||||
|  | ||||
| 	void preInit() | ||||
| 	{ | ||||
| 		for (size_t i = 0; i < apps.size(); i++) | ||||
| 			apps[i]->preInit(); | ||||
| // 		for (size_t i = 0; i < apps.size(); i++) | ||||
| // 			apps[i]->preInit(); | ||||
| 	} | ||||
|  | ||||
| 	void postInit() | ||||
| 	{ | ||||
| 		for (size_t i = 0; i < apps.size(); i++) | ||||
| 			apps[i]->postInit(); | ||||
| // 		for (size_t i = 0; i < apps.size(); i++) | ||||
| // 			apps[i]->postInit(); | ||||
| 	} | ||||
| } *objCaller = NULL; | ||||
|  | ||||
| @@ -2365,7 +2365,7 @@ int3 CGameState::guardingCreaturePosition (int3 pos) const | ||||
| 			if (map->isInTheMap(pos))  | ||||
| 			{ | ||||
| 				TerrainTile &tile = map->terrain[pos.x][pos.y][pos.z]; | ||||
| 				if (tile.visitable)  | ||||
| 				if (tile.visitable && (tile.tertype == TerrainTile::water) == (posTile.tertype == TerrainTile::water))  | ||||
| 				{ | ||||
| 					BOOST_FOREACH (CGObjectInstance* obj, tile.visitableObjects)  | ||||
| 					{ | ||||
|   | ||||
| @@ -5,10 +5,16 @@ | ||||
| #include "../hch/CSpellHandler.h" | ||||
| #include <sstream> | ||||
| #include "../hch/CCreatureHandler.h" | ||||
| #include <boost/assign/list_of.hpp> | ||||
| #include "CCreatureSet.h" | ||||
|  | ||||
| #define FOREACH_CONST_PARENT(pname, source) 	TCNodes parents; getParents(parents, source); BOOST_FOREACH(const CBonusSystemNode *pname, parents) | ||||
| #define FOREACH_PARENT(pname, source) 	TNodes parents; getParents(parents, source); BOOST_FOREACH(CBonusSystemNode *pname, parents) | ||||
|  | ||||
| #define BONUS_NAME(x) ( #x, Bonus::x ) | ||||
| 	DLL_EXPORT const std::map<std::string, int> bonusNameMap = boost::assign::map_list_of BONUS_LIST; | ||||
| #undef BONUS_NAME | ||||
|  | ||||
| int DLL_EXPORT BonusList::totalValue() const | ||||
| { | ||||
| 	int base = 0; | ||||
| @@ -75,6 +81,19 @@ void DLL_EXPORT BonusList::getBonuses(BonusList &out, const CSelector &selector, | ||||
| 			out.push_back(*i); | ||||
| } | ||||
|  | ||||
| void BonusList::limit(const CBonusSystemNode &node) | ||||
| { | ||||
| 	for(const_iterator i = begin(); i != end(); i++) | ||||
| 	{ | ||||
| 		if(i->limiter && i->limiter->limit(*i, node)) | ||||
| 		{ | ||||
| 			const_iterator toErase = i; | ||||
| 			i--; | ||||
| 			erase(toErase); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int CBonusSystemNode::valOfBonuses(Bonus::BonusType type, int subtype /*= -1*/) const | ||||
| { | ||||
| 	CSelector s = Selector::type(type); | ||||
| @@ -161,6 +180,9 @@ void CBonusSystemNode::getBonuses(BonusList &out, const CSelector &selector, con | ||||
| 	bonuses.getBonuses(out, selector); | ||||
| 	FOREACH_CONST_PARENT(p, root ? root : this) | ||||
| 		p->getBonuses(out, selector, root ? root : this); | ||||
| 	 | ||||
| 	if(!root) | ||||
| 		out.limit(*this); | ||||
| } | ||||
|  | ||||
| BonusList CBonusSystemNode::getBonuses(const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const | ||||
| @@ -175,6 +197,9 @@ void CBonusSystemNode::getBonuses(BonusList &out, const CSelector &selector, con | ||||
| 	bonuses.getBonuses(out, selector, limit); | ||||
| 	FOREACH_CONST_PARENT(p, root ? root : this) | ||||
| 		p->getBonuses(out, selector, limit, root ? root : this); | ||||
|  | ||||
| 	if(!root) | ||||
| 		out.limit(*this); | ||||
| } | ||||
|  | ||||
| BonusList CBonusSystemNode::getBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= NULL*/) const | ||||
| @@ -245,6 +270,16 @@ ui16 CBonusSystemNode::MaxHealth() const | ||||
| 	return valOfBonuses(Bonus::STACK_HEALTH); | ||||
| } | ||||
|  | ||||
| CBonusSystemNode::CBonusSystemNode() | ||||
| { | ||||
| 	nodeType = UNKNOWN; | ||||
| } | ||||
|  | ||||
| CBonusSystemNode::~CBonusSystemNode() | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| int NBonus::valOf(const CBonusSystemNode *obj, Bonus::BonusType type, int subtype /*= -1*/) | ||||
| { | ||||
| 	if(obj) | ||||
| @@ -347,3 +382,64 @@ namespace Selector | ||||
| 		return sel(dummy); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| DLL_EXPORT std::ostream & operator<<(std::ostream &out, const BonusList &bonusList) | ||||
| { | ||||
| 	int i = 0; | ||||
| 	BOOST_FOREACH(const Bonus &b, bonusList) | ||||
| 	{ | ||||
| 		out << "Bonus " << i++ << "\n" << b << std::endl; | ||||
| 	} | ||||
| 	return out; | ||||
| } | ||||
|  | ||||
| DLL_EXPORT std::ostream & operator<<(std::ostream &out, const Bonus &bonus) | ||||
| { | ||||
| 	for(std::map<std::string, int>::const_iterator i = bonusNameMap.begin(); i != bonusNameMap.end(); i++) | ||||
| 		if(i->second == bonus.type) | ||||
| 			out << "\tType: " << i->first << " \t"; | ||||
|  | ||||
| #define printField(field) out << "\t" #field ": " << (int)bonus.field << "\n" | ||||
| 	printField(val); | ||||
| 	printField(subtype); | ||||
| 	printField(duration); | ||||
| 	printField(source); | ||||
| 	printField(id); | ||||
| 	printField(additionalInfo); | ||||
| 	printField(turnsRemain); | ||||
| 	printField(valType); | ||||
| 	printField(effectRange); | ||||
| #undef printField | ||||
|  | ||||
| 	return out; | ||||
| } | ||||
|  | ||||
| ILimiter::~ILimiter() | ||||
| { | ||||
| } | ||||
|  | ||||
| bool ILimiter::limit(const Bonus &b, const CBonusSystemNode &node) const /*return true to drop the bonus */ | ||||
| { | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool CCreatureTypeLimiter::limit(const Bonus &b, const CBonusSystemNode &node) const | ||||
| { | ||||
| 	if(node.nodeType != CBonusSystemNode::STACK) | ||||
| 		return true; | ||||
|  | ||||
| 	const CCreature *c = (static_cast<const CStackInstance *>(&node))->type; | ||||
|  | ||||
| 	return c != creature   &&   (!includeUpgrades || !creature->isMyUpgrade(c)); //drop bonus if it's not our creature and (we dont check upgrades or its not our upgrade) | ||||
| } | ||||
|  | ||||
| CCreatureTypeLimiter::CCreatureTypeLimiter(const CCreature &Creature, ui8 IncludeUpgrades /*= true*/) | ||||
| 	:creature(&Creature), includeUpgrades(IncludeUpgrades) | ||||
| { | ||||
| } | ||||
|  | ||||
| CCreatureTypeLimiter::CCreatureTypeLimiter() | ||||
| { | ||||
| 	creature = NULL; | ||||
| 	includeUpgrades = false; | ||||
| } | ||||
| @@ -19,17 +19,17 @@ | ||||
| typedef ui8 TBonusType; | ||||
| typedef si32 TBonusSubtype; | ||||
|  | ||||
|  | ||||
| class CCreature; | ||||
| class CSpell; | ||||
| struct Bonus; | ||||
| class CBonusSystemNode; | ||||
| class ILimiter; | ||||
|  | ||||
| typedef std::vector<std::pair<int,std::string> > TModDescr; //modifiers values and their descriptions | ||||
| typedef std::set<CBonusSystemNode*> TNodes; | ||||
| typedef std::set<const CBonusSystemNode*> TCNodes; | ||||
| typedef boost::function<bool(const Bonus&)> CSelector; | ||||
|  | ||||
|  | ||||
| namespace PrimarySkill | ||||
| { | ||||
| 	enum { ATTACK, DEFENSE, SPELL_POWER, KNOWLEDGE}; | ||||
| @@ -223,6 +223,8 @@ struct DLL_EXPORT Bonus | ||||
| 	si32 additionalInfo; | ||||
| 	ui8 effectRange; //if not NO_LIMIT, bonus will be ommitted by default | ||||
|  | ||||
| 	ILimiter *limiter; | ||||
|  | ||||
| 	std::string description;  | ||||
|  | ||||
| 	Bonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype=-1) | ||||
| @@ -232,6 +234,7 @@ struct DLL_EXPORT Bonus | ||||
| 		turnsRemain = 0; | ||||
| 		valType = ADDITIVE_VALUE; | ||||
| 		effectRange = NO_LIMIT; | ||||
| 		limiter = NULL; | ||||
| 	} | ||||
| 	Bonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, si32 Subtype=-1, ui8 ValType = ADDITIVE_VALUE) | ||||
| 		:duration(Dur), type(Type), subtype(Subtype), source(Src), val(Val), id(ID), valType(ValType) | ||||
| @@ -239,6 +242,7 @@ struct DLL_EXPORT Bonus | ||||
| 		additionalInfo = -1; | ||||
| 		turnsRemain = 0; | ||||
| 		effectRange = NO_LIMIT; | ||||
| 		limiter = NULL; | ||||
| 	} | ||||
| 	Bonus() | ||||
| 	{ | ||||
| @@ -247,6 +251,7 @@ struct DLL_EXPORT Bonus | ||||
| 		turnsRemain = 0; | ||||
| 		valType = ADDITIVE_VALUE; | ||||
| 		effectRange = NO_LIMIT; | ||||
| 		limiter = NULL; | ||||
| 	} | ||||
|  | ||||
| // 	//comparison | ||||
| @@ -263,7 +268,7 @@ struct DLL_EXPORT Bonus | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & duration & type & subtype & source & val & id & description & additionalInfo & turnsRemain & valType & effectRange; | ||||
| 		h & duration & type & subtype & source & val & id & description & additionalInfo & turnsRemain & valType & effectRange & limiter; | ||||
| 	} | ||||
|  | ||||
| 	static bool OneDay(const Bonus &hb) | ||||
| @@ -307,6 +312,8 @@ struct DLL_EXPORT Bonus | ||||
| 	std::string Description() const; | ||||
| }; | ||||
|  | ||||
| DLL_EXPORT std::ostream & operator<<(std::ostream &out, const Bonus &bonus); | ||||
|  | ||||
| class BonusList : public std::list<Bonus> | ||||
| { | ||||
| public: | ||||
| @@ -319,16 +326,35 @@ public: | ||||
| 	DLL_EXPORT Bonus * getFirst(const CSelector &select); | ||||
| 	DLL_EXPORT const Bonus * getFirst(const CSelector &select) const; | ||||
|  | ||||
| 	void limit(const CBonusSystemNode &node); //erases bonuses using limitor | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & static_cast<std::list<Bonus>&>(*this); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| DLL_EXPORT std::ostream & operator<<(std::ostream &out, const BonusList &bonusList); | ||||
|  | ||||
| class DLL_EXPORT ILimiter | ||||
| { | ||||
| public: | ||||
| 	virtual ~ILimiter(); | ||||
|  | ||||
| 	virtual bool limit(const Bonus &b, const CBonusSystemNode &node) const; //return true to drop the bonus | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{} | ||||
| }; | ||||
|  | ||||
| class DLL_EXPORT CBonusSystemNode | ||||
| { | ||||
| public: | ||||
| 	BonusList bonuses; | ||||
| 	ui8 nodeType; | ||||
|  | ||||
| 	CBonusSystemNode(); | ||||
| 	virtual ~CBonusSystemNode(); | ||||
|  | ||||
| 	//new bonusing node interface | ||||
| 	// * selector is predicate that tests if HeroBonus matches our criteria | ||||
| @@ -366,8 +392,13 @@ public: | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & bonuses; | ||||
| 		h & bonuses & nodeType; | ||||
| 	} | ||||
|  | ||||
| 	enum ENodeTypes | ||||
| 	{ | ||||
| 		UNKNOWN, STACK | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| namespace NBonus | ||||
| @@ -450,6 +481,23 @@ public: | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| class CCreatureTypeLimiter : public ILimiter //affect only stacks of given creature (and optionally it's upgrades) | ||||
| { | ||||
| public: | ||||
| 	const CCreature *creature; | ||||
| 	ui8 includeUpgrades; | ||||
|  | ||||
| 	CCreatureTypeLimiter(); | ||||
| 	CCreatureTypeLimiter(const CCreature &Creature, ui8 IncludeUpgrades = true); | ||||
|  | ||||
| 	bool limit(const Bonus &b, const CBonusSystemNode &node) const; | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & creature & includeUpgrades; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| namespace Selector | ||||
| { | ||||
| 	extern DLL_EXPORT CSelectFieldEqual<TBonusType> type; | ||||
| @@ -466,3 +514,5 @@ namespace Selector | ||||
| 	bool DLL_EXPORT matchesType(const CSelector &sel, TBonusType type); | ||||
| 	bool DLL_EXPORT matchesTypeSubtype(const CSelector &sel, TBonusType type, TBonusSubtype subtype); | ||||
| } | ||||
|  | ||||
| extern DLL_EXPORT const std::map<std::string, int> bonusNameMap; | ||||
| @@ -20,6 +20,7 @@ | ||||
| template<typename Serializer> DLL_EXPORT | ||||
| void registerTypes1(Serializer &s) | ||||
| { | ||||
| 	//map objects | ||||
| 	s.template registerType<CGHeroPlaceholder>(); | ||||
| 	s.template registerType<CGHeroInstance>(); | ||||
| 	s.template registerType<CGTownInstance>(); | ||||
| @@ -64,6 +65,9 @@ void registerTypes1(Serializer &s) | ||||
| 	s.template registerType<CGLighthouse>(); | ||||
| 	s.template registerType<CGMarket>(); | ||||
| 	s.template registerType<CGBlackMarket>(); | ||||
| 	//end of objects | ||||
| 	s.template registerType<ILimiter>(); | ||||
| 	s.template registerType<CCreatureTypeLimiter>(); | ||||
| } | ||||
|  | ||||
| template<typename Serializer> DLL_EXPORT  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user