1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-13 01:20:34 +02:00

- Parsing hero specialty is working (though complicated)

- Some obvious fixed for limiters, more work needed
This commit is contained in:
DjWarmonger
2013-01-19 17:38:37 +00:00
parent 97db289d3c
commit 79062eb15c
6 changed files with 63 additions and 16 deletions

View File

@ -9,6 +9,7 @@
#include "BattleHex.h" #include "BattleHex.h"
#include "CModHandler.h" #include "CModHandler.h"
#include "CTownHandler.h" #include "CTownHandler.h"
#include "CObjectHandler.h" //for hero specialty
/* /*
* CHeroHandler.cpp, part of VCMI engine * CHeroHandler.cpp, part of VCMI engine
@ -285,6 +286,7 @@ void CHeroHandler::loadHeroJson(CHero * hero, const JsonNode & node)
hero->spells.insert(spell.Float()); hero->spells.insert(spell.Float());
} }
//deprecated, used only for original spciealties
BOOST_FOREACH(const JsonNode &specialty, node["specialties"].Vector()) BOOST_FOREACH(const JsonNode &specialty, node["specialties"].Vector())
{ {
SSpecialtyInfo spec; SSpecialtyInfo spec;
@ -296,6 +298,18 @@ void CHeroHandler::loadHeroJson(CHero * hero, const JsonNode & node)
hero->spec.push_back(spec); //put a copy of dummy 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(), VLC->modh->identifiers.requestIdentifier("heroClass." + node["class"].String(),
[=](si32 classID) [=](si32 classID)

View File

@ -2,6 +2,7 @@
#include "../lib/ConstTransitivePtr.h" #include "../lib/ConstTransitivePtr.h"
#include "GameConstants.h" #include "GameConstants.h"
#include "HeroBonus.h"
/* /*
* CHeroHandler.h, part of VCMI engine * 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 class DLL_LINKAGE CHero
{ {
public: public:
@ -54,6 +66,7 @@ public:
CHeroClass * heroClass; 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<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<SSpecialtyInfo> spec;
std::vector<SSpecialtyBonus> specialty;
std::set<si32> spells; std::set<si32> spells;
ui8 sex; // default sex: 0=male, 1=female 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 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) 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 & name & biography & specName & specDescr & specTooltip;
h & iconSpecSmall & iconSpecLarge & portraitSmall & portraitLarge; h & iconSpecSmall & iconSpecLarge & portraitSmall & portraitLarge;
} }

View File

@ -1104,6 +1104,20 @@ void CGHeroInstance::initObj() //TODO: use bonus system
attachTo(hs); //do we ever need to detach it? attachTo(hs); //do we ever need to detach it?
specialty.push_back(hs); //will it work? 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 //initialize bonuses
BOOST_FOREACH(auto skill_info, secSkills) BOOST_FOREACH(auto skill_info, secSkills)
updateSkill(skill_info.first, skill_info.second); updateSkill(skill_info.first, skill_info.second);
@ -1133,9 +1147,9 @@ void CGHeroInstance::Updatespecialty() //TODO: calculate special value of bonuse
CCreature * cre = NULL; CCreature * cre = NULL;
int creLevel = 0; int creLevel = 0;
TLimiterPtr limiterNode (b); 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? if (foundLimiter = dynamic_cast<CCreatureTypeLimiter*>(limiterNode.get())) //TODO: more general eveluation of bonuses?
{ {
cre = const_cast<CCreature*>(foundLimiter->creature); cre = const_cast<CCreature*>(foundLimiter->creature);

View File

@ -1321,15 +1321,15 @@ DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus)
} }
Bonus * Bonus::addLimiter(TLimiterPtr Limiter) Bonus * Bonus::addLimiter(TLimiterPtr Limiter)
{ {
if (next) //insert at the beginning of list if (limiter) //insert at the beginning of list
{ {
TLimiterPtr temp = next; TLimiterPtr temp = limiter;
next = Limiter; limiter = Limiter;
next->next = temp; limiter->limiter = temp;
} }
else else
{ {
next = Limiter; limiter = Limiter;
} }
return this; return this;
@ -1436,7 +1436,7 @@ bool CPropagatorNodeType::shouldBeAttached(CBonusSystemNode *dest)
int LimiterDecorator::callNext(const BonusLimitationContext &context) const int LimiterDecorator::callNext(const BonusLimitationContext &context) const
{ {
if (next) if (limiter)
{ {
return (limit(context) || callNext(context)); //either of limiters will cause bonus to drop return (limit(context) || callNext(context)); //either of limiters will cause bonus to drop
} }

View File

@ -37,7 +37,7 @@ typedef boost::function<bool(const Bonus*)> CSelector;
class DLL_LINKAGE LimiterDecorator //follows decorator design pattern class DLL_LINKAGE LimiterDecorator //follows decorator design pattern
{ {
public: 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 limit(const BonusLimitationContext &context) const; //0 - accept bonus; 1 - drop bonus; 2 - delay (drops eventually)
virtual int callNext(const BonusLimitationContext &context) const; virtual int callNext(const BonusLimitationContext &context) const;
@ -47,7 +47,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) 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; si32 additionalInfo;
ui8 effectRange; //if not NO_LIMIT, bonus will be omitted by default ui8 effectRange; //if not NO_LIMIT, bonus will be omitted by default
TLimiterPtr limiter;
TPropagatorPtr propagator; TPropagatorPtr propagator;
TCalculatorPtr calculator; TCalculatorPtr calculator;
@ -309,7 +308,7 @@ struct DLL_LINKAGE Bonus : public LimiterDecorator
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<LimiterDecorator&>(*this); 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) static bool compareByAdditionalInfo(const Bonus *a, const Bonus *b)
@ -366,7 +365,7 @@ struct DLL_LINKAGE Bonus : public LimiterDecorator
Bonus * addLimiter(TLimiterPtr Limiter); Bonus * addLimiter(TLimiterPtr Limiter);
Bonus * addPropagator(TPropagatorPtr Propagator); //returns this for convenient chain-calls 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); DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus);
@ -522,7 +521,7 @@ class DLL_LINKAGE ILimiter : public LimiterDecorator
public: public:
enum EDecision {ACCEPT, DISCARD, NOT_SURE}; enum EDecision {ACCEPT, DISCARD, NOT_SURE};
virtual int limit(const BonusLimitationContext &context) const; virtual int limit(const BonusLimitationContext &context) const OVERRIDE;
virtual ~ILimiter(); virtual ~ILimiter();
template <typename Handler> void serialize(Handler &h, const int version) 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) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<ILimiter&>(*this);
h & creature & includeUpgrades; h & creature & includeUpgrades;
} }
}; };
@ -809,6 +809,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<ILimiter&>(*this);
h & type & subtype & isSubtypeRelevant; h & type & subtype & isSubtypeRelevant;
} }
}; };
@ -824,6 +825,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<ILimiter&>(*this);
h & terrainType; h & terrainType;
} }
}; };
@ -839,6 +841,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<ILimiter&>(*this);
h & faction; h & faction;
} }
}; };
@ -854,6 +857,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<ILimiter&>(*this);
h & alignment; h & alignment;
} }
}; };
@ -869,6 +873,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<ILimiter&>(*this);
h & owner; h & owner;
} }
}; };
@ -884,6 +889,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<ILimiter&>(*this);
h & minRank & maxRank; h & minRank & maxRank;
} }
}; };

View File

@ -1048,7 +1048,7 @@ Bonus * JsonUtils::parseBonus (const JsonNode &ability)
case JsonNode::DATA_STRING: //pre-defined limiters case JsonNode::DATA_STRING: //pre-defined limiters
b->limiter = parseByMap(bonusLimiterMap, &limiter, "limiter type "); b->limiter = parseByMap(bonusLimiterMap, &limiter, "limiter type ");
break; break;
case JsonNode::DATA_STRUCT: //customisable limiters case JsonNode::DATA_STRUCT: //customizable limiters
{ {
shared_ptr<ILimiter> l; shared_ptr<ILimiter> l;
if (limiter["type"].String() == "CREATURE_TYPE_LIMITER") if (limiter["type"].String() == "CREATURE_TYPE_LIMITER")