diff --git a/config/heroes/castle.json b/config/heroes/castle.json index 89b3bc66f..cdf8b788b 100644 --- a/config/heroes/castle.json +++ b/config/heroes/castle.json @@ -9,9 +9,16 @@ { "skill" : "leadership", "level": "basic" }, { "skill" : "archery", "level": "basic" } ], - "specialties": - [ - { "type":2, "val": 5, "subtype": 1, "info": 0 } + "specialty" : [ + { + "type" : "SECONDARY_SKILL_PREMY", + "subtype" : "skill.archery", + "valueType" : "PERCENT_TO_BASE", + "updater" : { + "type" : "GROWS_WITH_LEVEL", + "parameters" : [100] + } + } ] }, "valeska": diff --git a/config/schemas/bonus.json b/config/schemas/bonus.json index ec103bcb7..80060f076 100644 --- a/config/schemas/bonus.json +++ b/config/schemas/bonus.json @@ -70,6 +70,23 @@ } ] }, + "updater" : { + "description" : "updater", + "type" : "object", + "required" : ["type", "parameters"], + "additionalProperties" : false, + "properties" : { + "type" : { + "type" : "string", + "description" : "type" + }, + "parameters": { + "type" : "array", + "description" : "parameters", + "additionalItems" : true + } + } + }, "sourceID": { "type":"number", "description": "sourceID" diff --git a/lib/HeroBonus.cpp b/lib/HeroBonus.cpp index 291e84bf6..f59d27510 100644 --- a/lib/HeroBonus.cpp +++ b/lib/HeroBonus.cpp @@ -1327,6 +1327,9 @@ DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus) printField(effectRange); #undef printField + if(bonus.updater) + out << "\tUpdater: " << bonus.updater->toString() << "\n"; + return out; } @@ -1571,6 +1574,11 @@ IUpdater::~IUpdater() { } +std::string IUpdater::toString() const +{ + return typeid(*this).name(); +} + ScalingUpdater::ScalingUpdater() : valPer20(0), stepSize(1) { } @@ -1596,6 +1604,13 @@ bool ScalingUpdater::update(Bonus & b, const CBonusSystemNode & context) const return false; } +std::string ScalingUpdater::toString() const +{ + char buf[100]; + sprintf(buf, "ScalingUpdater(valPer20=%d, stepSize=%d)", valPer20, stepSize); + return std::string(buf); +} + std::shared_ptr Bonus::addUpdater(TUpdaterPtr Updater) { updater = Updater; diff --git a/lib/HeroBonus.h b/lib/HeroBonus.h index 3c50dadfa..d60b04fca 100644 --- a/lib/HeroBonus.h +++ b/lib/HeroBonus.h @@ -1024,6 +1024,7 @@ public: virtual ~IUpdater(); virtual bool update(Bonus & b, const CBonusSystemNode & context) const = 0; + virtual std::string toString() const; template void serialize(Handler &h, const int version) { @@ -1046,4 +1047,5 @@ struct DLL_LINKAGE ScalingUpdater : public IUpdater } bool update(Bonus & b, const CBonusSystemNode & context) const override; + virtual std::string toString() const override; }; diff --git a/lib/JsonNode.cpp b/lib/JsonNode.cpp index 09e8d5bd6..2a065a040 100644 --- a/lib/JsonNode.cpp +++ b/lib/JsonNode.cpp @@ -603,6 +603,23 @@ bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b) if (!value->isNull()) b->propagator = parseByMap(bonusPropagatorMap, value, "propagator type "); + value = &ability["updater"]; + if (!value->isNull()) + { + const JsonNode & updaterJson = *value; + if(updaterJson["type"].String() == "GROWS_WITH_LEVEL") + { + std::shared_ptr updater = std::make_shared(); + const JsonVector param = updaterJson["parameters"].Vector(); + updater->valPer20 = param[0].Float(); + if(param.size() > 1) + updater->stepSize = param[1].Float(); + b->addUpdater(updater); + } + else + logMod->warn("Unknown updater type \"%s\"", updaterJson["type"].String()); + } + return true; }