mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	- Parsing hero specialty is working (though complicated)
- Some obvious fixed for limiters, more work needed
This commit is contained in:
		| @@ -9,6 +9,7 @@ | ||||
| #include "BattleHex.h" | ||||
| #include "CModHandler.h" | ||||
| #include "CTownHandler.h" | ||||
| #include "CObjectHandler.h" //for hero specialty | ||||
|  | ||||
| /* | ||||
|  * CHeroHandler.cpp, part of VCMI engine | ||||
| @@ -285,6 +286,7 @@ void CHeroHandler::loadHeroJson(CHero * hero, const JsonNode & node) | ||||
| 		hero->spells.insert(spell.Float()); | ||||
| 	} | ||||
|  | ||||
| 	//deprecated, used only for original spciealties | ||||
| 	BOOST_FOREACH(const JsonNode &specialty, node["specialties"].Vector()) | ||||
| 	{ | ||||
| 		SSpecialtyInfo spec; | ||||
| @@ -296,6 +298,18 @@ void CHeroHandler::loadHeroJson(CHero * hero, const JsonNode & node) | ||||
|  | ||||
| 		hero->spec.push_back(spec); //put a copy of dummy | ||||
| 	} | ||||
| 	//new format, using bonus system | ||||
| 	BOOST_FOREACH(const JsonNode &specialty, node["specialty"].Vector()) | ||||
| 	{ | ||||
| 		SSpecialtyBonus hs; | ||||
| 		hs.growsWithLevel = specialty["growsWithLevel"].Bool(); | ||||
| 		BOOST_FOREACH (const JsonNode & bonus, specialty["bonuses"].Vector()) | ||||
| 		{ | ||||
| 			auto b = JsonUtils::parseBonus(bonus); | ||||
| 			hs.bonuses.push_back (b); | ||||
| 		} | ||||
| 		hero->specialty.push_back (hs); //now, how to get CGHeroInstance from it? | ||||
| 	} | ||||
|  | ||||
| 	VLC->modh->identifiers.requestIdentifier("heroClass." + node["class"].String(), | ||||
| 	[=](si32 classID) | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| #include "../lib/ConstTransitivePtr.h" | ||||
| #include "GameConstants.h" | ||||
| #include "HeroBonus.h" | ||||
|  | ||||
| /* | ||||
|  * CHeroHandler.h, part of VCMI engine | ||||
| @@ -31,6 +32,17 @@ struct SSpecialtyInfo | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| struct SSpecialtyBonus | ||||
| /// temporary hold | ||||
| { | ||||
| 	ui8 growsWithLevel; | ||||
| 	BonusList bonuses; | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & growsWithLevel & bonuses; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CHero | ||||
| { | ||||
| public: | ||||
| @@ -54,6 +66,7 @@ public: | ||||
| 	CHeroClass * heroClass; | ||||
| 	std::vector<std::pair<ui8,ui8> > secSkillsInit; //initial secondary skills; first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert) | ||||
| 	std::vector<SSpecialtyInfo> spec; | ||||
| 	std::vector<SSpecialtyBonus> specialty; | ||||
| 	std::set<si32> spells; | ||||
| 	ui8 sex; // default sex: 0=male, 1=female | ||||
| 	ui8 special; // hero is special and won't be placed in game (unless preset on map), e.g. campaign heroes | ||||
| @@ -73,7 +86,7 @@ public: | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & ID & imageIndex & initialArmy & heroClass & secSkillsInit & spec & spells & sex; | ||||
| 		h & ID & imageIndex & initialArmy & heroClass & secSkillsInit & spec & specialty & spells & sex; | ||||
| 		h & name & biography & specName & specDescr & specTooltip; | ||||
| 		h & iconSpecSmall & iconSpecLarge & portraitSmall & portraitLarge; | ||||
| 	} | ||||
|   | ||||
| @@ -1104,6 +1104,20 @@ void CGHeroInstance::initObj() //TODO: use bonus system | ||||
| 	attachTo(hs); //do we ever need to detach it? | ||||
| 	specialty.push_back(hs); //will it work? | ||||
|  | ||||
| 	BOOST_FOREACH (auto hs2, type->specialty) //copy active (probably growing) bonuses from hero prootype to hero object | ||||
| 	{ | ||||
| 		HeroSpecial * hs = new HeroSpecial(); | ||||
| 		hs->setNodeType(CBonusSystemNode::specialty); | ||||
| 		BOOST_FOREACH (auto bonus, hs2.bonuses) | ||||
| 		{ | ||||
| 			hs->addNewBonus (bonus); | ||||
| 		} | ||||
| 		hs->growsWithLevel = hs2.growsWithLevel; | ||||
|  | ||||
| 		attachTo(hs); //do we ever need to detach it? | ||||
| 		specialty.push_back(hs); //will it work? | ||||
| 	} | ||||
|  | ||||
| 	//initialize bonuses | ||||
| 	BOOST_FOREACH(auto skill_info, secSkills) | ||||
| 		updateSkill(skill_info.first, skill_info.second); | ||||
| @@ -1133,9 +1147,9 @@ void CGHeroInstance::Updatespecialty() //TODO: calculate special value of bonuse | ||||
| 						CCreature * cre = NULL; | ||||
| 						int creLevel = 0; | ||||
| 						TLimiterPtr limiterNode (b); | ||||
| 						while (limiterNode->next) | ||||
| 						while (limiterNode->limiter) | ||||
| 						{ | ||||
| 							limiterNode = limiterNode->next; //search list | ||||
| 							limiterNode = limiterNode->limiter; //search list | ||||
| 							if (foundLimiter = dynamic_cast<CCreatureTypeLimiter*>(limiterNode.get())) //TODO: more general eveluation of bonuses? | ||||
| 							{ | ||||
| 								cre = const_cast<CCreature*>(foundLimiter->creature); | ||||
|   | ||||
| @@ -1321,15 +1321,15 @@ DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus) | ||||
| } | ||||
| Bonus * Bonus::addLimiter(TLimiterPtr Limiter) | ||||
| { | ||||
| 	if (next) //insert at the beginning of list | ||||
| 	if (limiter) //insert at the beginning of list | ||||
| 	{ | ||||
| 		TLimiterPtr temp = next; | ||||
| 		next = Limiter; | ||||
| 		next->next = temp; | ||||
| 		TLimiterPtr temp = limiter; | ||||
| 		limiter = Limiter; | ||||
| 		limiter->limiter = temp; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		next = Limiter; | ||||
| 		limiter = Limiter; | ||||
| 	} | ||||
| 	return this; | ||||
|  | ||||
| @@ -1436,7 +1436,7 @@ bool CPropagatorNodeType::shouldBeAttached(CBonusSystemNode *dest) | ||||
|  | ||||
| int LimiterDecorator::callNext(const BonusLimitationContext &context) const | ||||
| { | ||||
| 	if (next) | ||||
| 	if (limiter) | ||||
| 	{ | ||||
| 		return (limit(context) || callNext(context)); //either of limiters will cause bonus to drop | ||||
| 	} | ||||
|   | ||||
| @@ -37,7 +37,7 @@ typedef boost::function<bool(const Bonus*)> CSelector; | ||||
| class DLL_LINKAGE LimiterDecorator //follows decorator design pattern | ||||
| { | ||||
| public: | ||||
| 	TLimiterPtr next; //forms a list | ||||
| 	TLimiterPtr limiter; //forms a list | ||||
|  | ||||
| 	virtual int limit(const BonusLimitationContext &context) const; //0 - accept bonus; 1 - drop bonus; 2 - delay (drops eventually) | ||||
| 	virtual int callNext(const BonusLimitationContext &context) const; | ||||
| @@ -47,7 +47,7 @@ public: | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & next; | ||||
| 		h & limiter; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| @@ -283,7 +283,6 @@ struct DLL_LINKAGE Bonus : public LimiterDecorator | ||||
| 	si32 additionalInfo; | ||||
| 	ui8 effectRange; //if not NO_LIMIT, bonus will be omitted by default | ||||
|  | ||||
| 	TLimiterPtr limiter; | ||||
| 	TPropagatorPtr propagator; | ||||
| 	TCalculatorPtr calculator; | ||||
|  | ||||
| @@ -309,7 +308,7 @@ struct DLL_LINKAGE Bonus : public LimiterDecorator | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & static_cast<LimiterDecorator&>(*this); | ||||
| 		h & duration & type & subtype & source & val & sid & description & additionalInfo & turnsRemain & valType & effectRange & limiter & propagator; | ||||
| 		h & duration & type & subtype & source & val & sid & description & additionalInfo & turnsRemain & valType & effectRange & propagator; | ||||
| 	} | ||||
|  | ||||
| 	static bool compareByAdditionalInfo(const Bonus *a, const Bonus *b) | ||||
| @@ -366,7 +365,7 @@ struct DLL_LINKAGE Bonus : public LimiterDecorator | ||||
|  | ||||
| 	Bonus * addLimiter(TLimiterPtr Limiter); | ||||
| 	Bonus * addPropagator(TPropagatorPtr Propagator); //returns this for convenient chain-calls | ||||
| 	int limit(const BonusLimitationContext &context) const; //for backward compatibility | ||||
| 	int limit(const BonusLimitationContext &context) const OVERRIDE; //for backward compatibility | ||||
| }; | ||||
|  | ||||
| DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus); | ||||
| @@ -522,7 +521,7 @@ class DLL_LINKAGE ILimiter : public LimiterDecorator | ||||
| public: | ||||
| 	enum EDecision {ACCEPT, DISCARD, NOT_SURE}; | ||||
|  | ||||
| 	virtual int limit(const BonusLimitationContext &context) const; | ||||
| 	virtual int limit(const BonusLimitationContext &context) const OVERRIDE; | ||||
| 	virtual ~ILimiter(); | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| @@ -791,6 +790,7 @@ public: | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & static_cast<ILimiter&>(*this); | ||||
| 		h & creature & includeUpgrades; | ||||
| 	} | ||||
| }; | ||||
| @@ -809,6 +809,7 @@ public: | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & static_cast<ILimiter&>(*this); | ||||
| 		h & type & subtype & isSubtypeRelevant; | ||||
| 	} | ||||
| }; | ||||
| @@ -824,6 +825,7 @@ public: | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & static_cast<ILimiter&>(*this); | ||||
| 		h & terrainType; | ||||
| 	} | ||||
| }; | ||||
| @@ -839,6 +841,7 @@ public: | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & static_cast<ILimiter&>(*this); | ||||
| 		h & faction; | ||||
| 	} | ||||
| }; | ||||
| @@ -854,6 +857,7 @@ public: | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & static_cast<ILimiter&>(*this); | ||||
| 		h & alignment; | ||||
| 	} | ||||
| }; | ||||
| @@ -869,6 +873,7 @@ public: | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & static_cast<ILimiter&>(*this); | ||||
| 		h & owner; | ||||
| 	} | ||||
| }; | ||||
| @@ -884,6 +889,7 @@ public: | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & static_cast<ILimiter&>(*this); | ||||
| 		h & minRank & maxRank; | ||||
| 	} | ||||
| }; | ||||
|   | ||||
| @@ -1048,7 +1048,7 @@ Bonus * JsonUtils::parseBonus (const JsonNode &ability) | ||||
| 				case JsonNode::DATA_STRING: //pre-defined limiters | ||||
| 					b->limiter = parseByMap(bonusLimiterMap, &limiter, "limiter type "); | ||||
| 					break; | ||||
| 				case JsonNode::DATA_STRUCT: //customisable limiters | ||||
| 				case JsonNode::DATA_STRUCT: //customizable limiters | ||||
| 					{ | ||||
| 						shared_ptr<ILimiter> l; | ||||
| 						if (limiter["type"].String() == "CREATURE_TYPE_LIMITER") | ||||
|   | ||||
		Reference in New Issue
	
	Block a user