1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-24 03:47:18 +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 "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)

View File

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

View File

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

View File

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

View File

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

View File

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