1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
/*
* Updaters.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "Updaters.h"
#include "Limiters.h"
#include "../json/JsonNode.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../CStack.h"
VCMI_LIB_NAMESPACE_BEGIN
std::shared_ptr<Bonus> IUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const
{
return b;
}
std::string IUpdater::toString() const
{
return typeid(*this).name();
}
JsonNode IUpdater::toJsonNode() const
{
return JsonNode();
}
GrowsWithLevelUpdater::GrowsWithLevelUpdater(int valPer20, int stepSize) : valPer20(valPer20), stepSize(stepSize)
{
}
std::shared_ptr<Bonus> GrowsWithLevelUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const
{
if(context.getNodeType() == CBonusSystemNode::HERO)
{
int level = dynamic_cast<const CGHeroInstance &>(context).level;
int steps = stepSize ? level / stepSize : level;
//rounding follows format for HMM3 creature specialty bonus
int newVal = (valPer20 * steps + 19) / 20;
//return copy of bonus with updated val
auto newBonus = std::make_shared<Bonus>(*b);
newBonus->val = newVal;
return newBonus;
}
return b;
}
std::string GrowsWithLevelUpdater::toString() const
{
return boost::str(boost::format("GrowsWithLevelUpdater(valPer20=%d, stepSize=%d)") % valPer20 % stepSize);
}
JsonNode GrowsWithLevelUpdater::toJsonNode() const
{
JsonNode root;
root["type"].String() = "GROWS_WITH_LEVEL";
root["parameters"].Vector().emplace_back(valPer20);
if(stepSize > 1)
root["parameters"].Vector().emplace_back(stepSize);
return root;
}
std::shared_ptr<Bonus> TimesHeroLevelUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const
{
if(context.getNodeType() == CBonusSystemNode::HERO)
{
int level = dynamic_cast<const CGHeroInstance &>(context).level;
auto 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 JsonNode("TIMES_HERO_LEVEL");
}
ArmyMovementUpdater::ArmyMovementUpdater():
base(20),
divider(3),
multiplier(10),
max(700)
{
}
ArmyMovementUpdater::ArmyMovementUpdater(int base, int divider, int multiplier, int max):
base(base),
divider(divider),
multiplier(multiplier),
max(max)
{
}
std::shared_ptr<Bonus> ArmyMovementUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const
{
return b;
}
std::string ArmyMovementUpdater::toString() const
{
return "ArmyMovementUpdater";
}
JsonNode ArmyMovementUpdater::toJsonNode() const
{
JsonNode root;
root["type"].String() = "ARMY_MOVEMENT";
root["parameters"].Vector().emplace_back(base);
root["parameters"].Vector().emplace_back(divider);
root["parameters"].Vector().emplace_back(multiplier);
root["parameters"].Vector().emplace_back(max);
return root;
}
std::shared_ptr<Bonus> TimesStackLevelUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const
{
if(context.getNodeType() == CBonusSystemNode::STACK_INSTANCE || context.getNodeType() == CBonusSystemNode::COMMANDER)
{
int level = dynamic_cast<const CStackInstance &>(context).getLevel();
auto newBonus = std::make_shared<Bonus>(*b);
newBonus->val *= level;
return newBonus;
}
else if(context.getNodeType() == CBonusSystemNode::STACK_BATTLE)
{
const auto & stack = dynamic_cast<const CStack &>(context);
//update if stack doesn't have an instance (summons, war machines)
if(stack.base == nullptr)
{
int level = stack.unitType()->getLevel();
auto newBonus = std::make_shared<Bonus>(*b);
newBonus->val *= level;
return newBonus;
}
// If these are not handled here, the final outcome may potentially be incorrect.
else
{
int level = dynamic_cast<const CStackInstance*>(stack.base)->getLevel();
auto newBonus = std::make_shared<Bonus>(*b);
newBonus->val *= level;
return newBonus;
}
}
return b;
}
std::string TimesStackLevelUpdater::toString() const
{
return "TimesStackLevelUpdater";
}
JsonNode TimesStackLevelUpdater::toJsonNode() const
{
return JsonNode("TIMES_STACK_LEVEL");
}
std::string OwnerUpdater::toString() const
{
return "OwnerUpdater";
}
JsonNode OwnerUpdater::toJsonNode() const
{
return JsonNode("BONUS_OWNER_UPDATER");
}
std::shared_ptr<Bonus> OwnerUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const
{
auto owner = context.getOwner();
if(owner == PlayerColor::UNFLAGGABLE)
owner = PlayerColor::NEUTRAL;
std::shared_ptr<Bonus> updated =
std::make_shared<Bonus>(*b);
updated->limiter = std::make_shared<OppositeSideLimiter>(owner);
return updated;
}
VCMI_LIB_NAMESPACE_END
|