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:
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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")
|
||||||
|
Reference in New Issue
Block a user