1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-23 00:28:08 +02:00

added TimesHeroLevelUpdater; renamed ScalingUpdater to GrowsWithLevelUpdater

This commit is contained in:
Henning Koehler
2017-09-19 10:08:28 +12:00
parent 2abbe5ab19
commit 552bad08b3
8 changed files with 115 additions and 47 deletions

View File

@ -14,10 +14,8 @@
"archery" : { "archery" : {
"subtype" : "skill.archery", "subtype" : "skill.archery",
"type" : "SECONDARY_SKILL_PREMY", "type" : "SECONDARY_SKILL_PREMY",
"updater" : { "updater" : "TIMES_HERO_LEVEL",
"parameters" : [ 100 ], "val" : 5,
"type" : "GROWS_WITH_LEVEL"
},
"valueType" : "PERCENT_TO_BASE" "valueType" : "PERCENT_TO_BASE"
} }
} }

View File

@ -71,6 +71,11 @@
] ]
}, },
"updater" : { "updater" : {
"anyOf" : [
{
"type" : "string"
},
{
"description" : "updater", "description" : "updater",
"type" : "object", "type" : "object",
"required" : ["type", "parameters"], "required" : ["type", "parameters"],
@ -86,6 +91,8 @@
"additionalItems" : true "additionalItems" : true
} }
} }
}
]
}, },
"sourceID": { "sourceID": {
"type":"number", "type":"number",

View File

@ -115,7 +115,7 @@
"additionalItems" : true "additionalItems" : true
}, },
"specialty": { "specialty": {
"oneOf" : [ "anyOf" : [
{ {
"type":"array", "type":"array",
"description": "Description of hero specialty using bonus system (deprecated)", "description": "Description of hero specialty using bonus system (deprecated)",

View File

@ -408,12 +408,12 @@ std::vector<std::shared_ptr<Bonus>> SpecialtyInfoToBonuses(const SSpecialtyInfo
int stepSize = specCreature.level ? specCreature.level : 5; int stepSize = specCreature.level ? specCreature.level : 5;
bonus->subtype = PrimarySkill::ATTACK; bonus->subtype = PrimarySkill::ATTACK;
bonus->updater.reset(new ScalingUpdater(specCreature.getAttack(false), stepSize)); bonus->updater.reset(new GrowsWithLevelUpdater(specCreature.getAttack(false), stepSize));
result.push_back(bonus); result.push_back(bonus);
bonus = std::make_shared<Bonus>(*bonus); bonus = std::make_shared<Bonus>(*bonus);
bonus->subtype = PrimarySkill::DEFENSE; bonus->subtype = PrimarySkill::DEFENSE;
bonus->updater.reset(new ScalingUpdater(specCreature.getDefence(false), stepSize)); bonus->updater.reset(new GrowsWithLevelUpdater(specCreature.getDefence(false), stepSize));
result.push_back(bonus); result.push_back(bonus);
} }
break; break;
@ -421,8 +421,7 @@ std::vector<std::shared_ptr<Bonus>> SpecialtyInfoToBonuses(const SSpecialtyInfo
bonus->type = Bonus::SECONDARY_SKILL_PREMY; bonus->type = Bonus::SECONDARY_SKILL_PREMY;
bonus->valType = Bonus::PERCENT_TO_BASE; bonus->valType = Bonus::PERCENT_TO_BASE;
bonus->subtype = spec.subtype; bonus->subtype = spec.subtype;
bonus->val = 0; bonus->updater.reset(new TimesHeroLevelUpdater());
bonus->updater.reset(new ScalingUpdater(spec.val * 20));
result.push_back(bonus); result.push_back(bonus);
break; break;
case 3: //spell damage bonus, level dependent but calculated elsewhere case 3: //spell damage bonus, level dependent but calculated elsewhere
@ -548,8 +547,7 @@ std::vector<std::shared_ptr<Bonus>> SpecialtyBonusToBonuses(const SSpecialtyBonu
break; // ignore - used to be overwritten based on SPECIAL_SECONDARY_SKILL break; // ignore - used to be overwritten based on SPECIAL_SECONDARY_SKILL
case Bonus::SPECIAL_SECONDARY_SKILL: case Bonus::SPECIAL_SECONDARY_SKILL:
newBonus->type = Bonus::SECONDARY_SKILL_PREMY; newBonus->type = Bonus::SECONDARY_SKILL_PREMY;
newBonus->updater = std::make_shared<ScalingUpdater>(newBonus->val * 20); newBonus->updater = std::make_shared<TimesHeroLevelUpdater>();
newBonus->val = 0; // for json printing
result.push_back(newBonus); result.push_back(newBonus);
break; break;
case Bonus::PRIMARY_SKILL: case Bonus::PRIMARY_SKILL:
@ -561,7 +559,7 @@ std::vector<std::shared_ptr<Bonus>> SpecialtyBonusToBonuses(const SSpecialtyBonu
const CCreature * cre = creatureLimiter->creature; const CCreature * cre = creatureLimiter->creature;
int creStat = newBonus->subtype == PrimarySkill::ATTACK ? cre->getAttack(false) : cre->getDefence(false); int creStat = newBonus->subtype == PrimarySkill::ATTACK ? cre->getAttack(false) : cre->getDefence(false);
int creLevel = cre->level ? cre->level : 5; int creLevel = cre->level ? cre->level : 5;
newBonus->updater = std::make_shared<ScalingUpdater>(creStat, creLevel); newBonus->updater = std::make_shared<GrowsWithLevelUpdater>(creStat, creLevel);
} }
result.push_back(newBonus); result.push_back(newBonus);
} }

View File

@ -81,6 +81,11 @@ const std::map<std::string, TPropagatorPtr> bonusPropagatorMap =
{"GLOBAL_EFFECT", std::make_shared<CPropagatorNodeType>(CBonusSystemNode::GLOBAL_EFFECTS)} {"GLOBAL_EFFECT", std::make_shared<CPropagatorNodeType>(CBonusSystemNode::GLOBAL_EFFECTS)}
}; //untested }; //untested
const std::map<std::string, TUpdaterPtr> bonusUpdaterMap =
{
{"TIMES_HERO_LEVEL", std::make_shared<TimesHeroLevelUpdater>()}
};
///CBonusProxy ///CBonusProxy
CBonusProxy::CBonusProxy(const IBonusBearer * Target, CSelector Selector) CBonusProxy::CBonusProxy(const IBonusBearer * Target, CSelector Selector)
: cachedLast(0), : cachedLast(0),
@ -1712,20 +1717,30 @@ IUpdater::~IUpdater()
{ {
} }
const std::shared_ptr<Bonus> IUpdater::update(const std::shared_ptr<Bonus> b, const CBonusSystemNode & context) const
{
return b;
}
std::string IUpdater::toString() const std::string IUpdater::toString() const
{ {
return typeid(*this).name(); return typeid(*this).name();
} }
ScalingUpdater::ScalingUpdater() : valPer20(0), stepSize(1) JsonNode IUpdater::toJsonNode() const
{
return JsonNode(JsonNode::JsonType::DATA_NULL);
}
GrowsWithLevelUpdater::GrowsWithLevelUpdater() : valPer20(0), stepSize(1)
{ {
} }
ScalingUpdater::ScalingUpdater(int valPer20, int stepSize) : valPer20(valPer20), stepSize(stepSize) GrowsWithLevelUpdater::GrowsWithLevelUpdater(int valPer20, int stepSize) : valPer20(valPer20), stepSize(stepSize)
{ {
} }
const std::shared_ptr<Bonus> ScalingUpdater::update(const std::shared_ptr<Bonus> b, const CBonusSystemNode & context) const const std::shared_ptr<Bonus> GrowsWithLevelUpdater::update(const std::shared_ptr<Bonus> b, const CBonusSystemNode & context) const
{ {
if(context.getNodeType() == CBonusSystemNode::HERO) if(context.getNodeType() == CBonusSystemNode::HERO)
{ {
@ -1741,14 +1756,14 @@ const std::shared_ptr<Bonus> ScalingUpdater::update(const std::shared_ptr<Bonus>
return b; return b;
} }
std::string ScalingUpdater::toString() const std::string GrowsWithLevelUpdater::toString() const
{ {
char buf[100]; char buf[100];
sprintf(buf, "ScalingUpdater(valPer20=%d, stepSize=%d)", valPer20, stepSize); sprintf(buf, "GrowsWithLevelUpdater(valPer20=%d, stepSize=%d)", valPer20, stepSize);
return std::string(buf); return std::string(buf);
} }
JsonNode ScalingUpdater::toJsonNode() const JsonNode GrowsWithLevelUpdater::toJsonNode() const
{ {
JsonNode root(JsonNode::JsonType::DATA_STRUCT); JsonNode root(JsonNode::JsonType::DATA_STRUCT);
@ -1759,3 +1774,29 @@ JsonNode ScalingUpdater::toJsonNode() const
return root; return root;
} }
TimesHeroLevelUpdater::TimesHeroLevelUpdater()
{
}
const std::shared_ptr<Bonus> TimesHeroLevelUpdater::update(const std::shared_ptr<Bonus> b, const CBonusSystemNode & context) const
{
if(context.getNodeType() == CBonusSystemNode::HERO)
{
int level = static_cast<const CGHeroInstance &>(context).level;
std::shared_ptr<Bonus> newBonus = std::make_shared<Bonus>(*b);
newBonus->val *= level;
return newBonus;
}
return b;
}
std::string TimesHeroLevelUpdater::toString() const
{
return "TimesHeroLevelUpdater";
}
JsonNode TimesHeroLevelUpdater::toJsonNode() const
{
return JsonUtils::stringNode("TIMES_HERO_LEVEL");
}

View File

@ -1013,7 +1013,7 @@ extern DLL_LINKAGE const std::map<std::string, ui16> bonusDurationMap;
extern DLL_LINKAGE const std::map<std::string, Bonus::LimitEffect> bonusLimitEffect; extern DLL_LINKAGE const std::map<std::string, Bonus::LimitEffect> bonusLimitEffect;
extern DLL_LINKAGE const std::map<std::string, TLimiterPtr> bonusLimiterMap; extern DLL_LINKAGE const std::map<std::string, TLimiterPtr> bonusLimiterMap;
extern DLL_LINKAGE const std::map<std::string, TPropagatorPtr> bonusPropagatorMap; extern DLL_LINKAGE const std::map<std::string, TPropagatorPtr> bonusPropagatorMap;
extern DLL_LINKAGE const std::map<std::string, TUpdaterPtr> bonusUpdaterMap;
// BonusList template that requires full interface of CBonusSystemNode // BonusList template that requires full interface of CBonusSystemNode
template <class InputIterator> template <class InputIterator>
@ -1030,23 +1030,23 @@ class DLL_LINKAGE IUpdater
public: public:
virtual ~IUpdater(); virtual ~IUpdater();
virtual const std::shared_ptr<Bonus> update(const std::shared_ptr<Bonus> b, const CBonusSystemNode & context) const = 0; virtual const std::shared_ptr<Bonus> update(const std::shared_ptr<Bonus> b, const CBonusSystemNode & context) const;
virtual std::string toString() const; virtual std::string toString() const;
virtual JsonNode toJsonNode() const = 0; virtual JsonNode toJsonNode() const;
template <typename Handler> void serialize(Handler & h, const int version) template <typename Handler> void serialize(Handler & h, const int version)
{ {
} }
}; };
class DLL_LINKAGE ScalingUpdater : public IUpdater class DLL_LINKAGE GrowsWithLevelUpdater : public IUpdater
{ {
public: public:
int valPer20; int valPer20;
int stepSize; int stepSize;
ScalingUpdater(); GrowsWithLevelUpdater();
ScalingUpdater(int valPer20, int stepSize = 1); GrowsWithLevelUpdater(int valPer20, int stepSize = 1);
template <typename Handler> void serialize(Handler & h, const int version) template <typename Handler> void serialize(Handler & h, const int version)
{ {
@ -1059,3 +1059,18 @@ public:
virtual std::string toString() const override; virtual std::string toString() const override;
virtual JsonNode toJsonNode() const override; virtual JsonNode toJsonNode() const override;
}; };
class DLL_LINKAGE TimesHeroLevelUpdater : public IUpdater
{
public:
TimesHeroLevelUpdater();
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<IUpdater &>(*this);
}
const std::shared_ptr<Bonus> update(const std::shared_ptr<Bonus> b, const CBonusSystemNode & context) const override;
virtual std::string toString() const override;
virtual JsonNode toJsonNode() const override;
};

View File

@ -651,9 +651,15 @@ bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b)
if(!value->isNull()) if(!value->isNull())
{ {
const JsonNode & updaterJson = *value; const JsonNode & updaterJson = *value;
switch(updaterJson.getType())
{
case JsonNode::JsonType::DATA_STRING:
b->addUpdater(parseByMap(bonusUpdaterMap, &updaterJson, "updater type "));
break;
case JsonNode::JsonType::DATA_STRUCT:
if(updaterJson["type"].String() == "GROWS_WITH_LEVEL") if(updaterJson["type"].String() == "GROWS_WITH_LEVEL")
{ {
std::shared_ptr<ScalingUpdater> updater = std::make_shared<ScalingUpdater>(); std::shared_ptr<GrowsWithLevelUpdater> updater = std::make_shared<GrowsWithLevelUpdater>();
const JsonVector param = updaterJson["parameters"].Vector(); const JsonVector param = updaterJson["parameters"].Vector();
updater->valPer20 = param[0].Integer(); updater->valPer20 = param[0].Integer();
if(param.size() > 1) if(param.size() > 1)
@ -662,6 +668,8 @@ bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b)
} }
else else
logMod->warn("Unknown updater type \"%s\"", updaterJson["type"].String()); logMod->warn("Unknown updater type \"%s\"", updaterJson["type"].String());
break;
}
} }
return true; return true;

View File

@ -136,7 +136,8 @@ void registerTypesMapObjectTypes(Serializer &s)
#undef REGISTER_GENERIC_HANDLER #undef REGISTER_GENERIC_HANDLER
s.template registerType<IUpdater, ScalingUpdater>(); s.template registerType<IUpdater, GrowsWithLevelUpdater>();
s.template registerType<IUpdater, TimesHeroLevelUpdater>();
//new types (other than netpacks) must register here //new types (other than netpacks) must register here
//order of type registration is critical for loading old savegames //order of type registration is critical for loading old savegames
} }