diff --git a/config/objects/rewardableBonusing.json b/config/objects/rewardableBonusing.json index 1c2b6fefa..b88ad1e28 100644 --- a/config/objects/rewardableBonusing.json +++ b/config/objects/rewardableBonusing.json @@ -313,16 +313,26 @@ "rarity" : 40 }, - "onVisitedMessage" : 136, + "onVisitedMessage" : 136, // TODO: alternative message with Cavalier -> Champions upgrade & text ID 139 "visitMode" : "bonus", "selectMode" : "selectFirst", "rewards" : [ + { + "limiter" : { + "creatures" : [ { "type" : "cavalier", "amount" : 1 } ], + }, + "message" : 138, + "movePoints" : 400, + "bonuses" : [ { "type" : "LAND_MOVEMENT", "val" : 400, "duration" : "ONE_WEEK"} ], + "changeCreatures" : { + "cavalier" : "champion" + } + }, { "message" : 137, "movePoints" : 400, "bonuses" : [ { "type" : "LAND_MOVEMENT", "val" : 400, "duration" : "ONE_WEEK"} ] } - // TODO: 2nd reward with Cavalier -> Champions upgrade & text ID 138 ] } } diff --git a/lib/mapObjects/CRewardableConstructor.cpp b/lib/mapObjects/CRewardableConstructor.cpp index 241a9f59b..c02595971 100644 --- a/lib/mapObjects/CRewardableConstructor.cpp +++ b/lib/mapObjects/CRewardableConstructor.cpp @@ -13,6 +13,7 @@ #include "../CRandomGenerator.h" #include "../StringConstants.h" #include "../CCreatureHandler.h" +#include "../CModHandler.h" #include "JsonRandom.h" #include "../IGameCallback.h" @@ -117,6 +118,16 @@ void CRandomRewardObjectInfo::configureReward(CRewardableObject * object, CRando reward.artifacts = JsonRandom::loadArtifacts(source["artifacts"], rng); reward.spells = JsonRandom::loadSpells(source["spells"], rng, spells); reward.creatures = JsonRandom::loadCreatures(source["creatures"], rng); + + for ( auto node : source["changeCreatures"].Struct() ) + { + CreatureID from (VLC->modh->identifiers.getIdentifier (node.second.meta, "creature", node.first) .get()); + CreatureID dest (VLC->modh->identifiers.getIdentifier (node.second.meta, "creature", node.second.String()).get()); + + reward.extraComponents.push_back(Component(Component::CREATURE, dest.getNum(), 0, 0)); + + reward.creaturesChange[from] = dest; + } } void CRandomRewardObjectInfo::configureResetInfo(CRewardableObject * object, CRandomGenerator & rng, CRewardResetInfo & resetParameters, const JsonNode & source) const diff --git a/lib/mapObjects/CRewardableObject.cpp b/lib/mapObjects/CRewardableObject.cpp index f6c15b52e..8f03af5a1 100644 --- a/lib/mapObjects/CRewardableObject.cpp +++ b/lib/mapObjects/CRewardableObject.cpp @@ -337,6 +337,24 @@ void CRewardableObject::grantRewardAfterLevelup(const CRewardVisitInfo & info, c cb->changeSpells(hero, true, spellsToGive); } + if(!info.reward.creaturesChange.empty()) + { + for (auto slot : hero->Slots()) + { + const CStackInstance * heroStack = slot.second; + + for (auto & change : info.reward.creaturesChange) + { + if (heroStack->type->getId() == change.first) + { + StackLocation location(hero, slot.first); + cb->changeStackType(location, change.second.toCreature()); + break; + } + } + } + } + if(!info.reward.creatures.empty()) { CCreatureSet creatures; diff --git a/lib/mapObjects/CRewardableObject.h b/lib/mapObjects/CRewardableObject.h index 069a660c4..6b458f664 100644 --- a/lib/mapObjects/CRewardableObject.h +++ b/lib/mapObjects/CRewardableObject.h @@ -153,6 +153,9 @@ public: std::vector primary; std::map secondary; + /// creatures that will be changed in hero's army + std::map creaturesChange; + /// objects that hero may receive std::vector artifacts; std::vector spells; @@ -198,6 +201,7 @@ public: h & artifacts; h & spells; h & creatures; + h & creaturesChange; } }; diff --git a/lib/mapObjects/JsonRandom.cpp b/lib/mapObjects/JsonRandom.cpp index c9b9e2c88..2299b9c37 100644 --- a/lib/mapObjects/JsonRandom.cpp +++ b/lib/mapObjects/JsonRandom.cpp @@ -32,7 +32,7 @@ namespace JsonRandom if (value.isNumber()) return static_cast(value.Float()); if (!value["amount"].isNull()) - return static_cast(loadValue(value, rng, defaultValue)); + return static_cast(loadValue(value["amount"], rng, defaultValue)); si32 min = static_cast(value["min"].Float()); si32 max = static_cast(value["max"].Float()); return rng.getIntRange(min, max)();