Forráskód Böngészése

- Parsing hero specialty is working (though complicated)
- Some obvious fixed for limiters, more work needed

DjWarmonger 12 éve
szülő
commit
79062eb15c
6 módosított fájl, 63 hozzáadás és 16 törlés
  1. 14 0
      lib/CHeroHandler.cpp
  2. 14 1
      lib/CHeroHandler.h
  3. 16 2
      lib/CObjectHandler.cpp
  4. 6 6
      lib/HeroBonus.cpp
  5. 12 6
      lib/HeroBonus.h
  6. 1 1
      lib/JsonNode.cpp

+ 14 - 0
lib/CHeroHandler.cpp

@@ -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)

+ 14 - 1
lib/CHeroHandler.h

@@ -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;
 	}

+ 16 - 2
lib/CObjectHandler.cpp

@@ -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);

+ 6 - 6
lib/HeroBonus.cpp

@@ -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
 	}

+ 12 - 6
lib/HeroBonus.h

@@ -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;
 	}
 };

+ 1 - 1
lib/JsonNode.cpp

@@ -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")