1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-09-16 09:26:28 +02:00

Make bonus limiters/updaters/propagators const

All pointers held by bonus itself are now const.

To support OppositeSideLimiter (the only stateful limiter) bonuses now
hold their player owner instead.

No changes in functionality or mods
This commit is contained in:
Ivan Savenko
2025-06-03 19:23:40 +03:00
parent 4fda657296
commit 20f0b51912
11 changed files with 55 additions and 245 deletions

View File

@@ -274,17 +274,14 @@ std::shared_ptr<Bonus> Bonus::addLimiter(const TLimiterPtr & Limiter)
{
if (limiter)
{
//If we already have limiter list, retrieve it
auto limiterList = std::dynamic_pointer_cast<AllOfLimiter>(limiter);
if(!limiterList)
{
//Create a new limiter list with old limiter and the new one will be pushed later
limiterList = std::make_shared<AllOfLimiter>();
limiterList->add(limiter);
limiter = limiterList;
}
auto newLimiterList = std::make_shared<AllOfLimiter>();
auto oldLimiterList = std::dynamic_pointer_cast<const AllOfLimiter>(limiter);
limiterList->add(Limiter);
if(oldLimiterList)
newLimiterList->limiters = oldLimiterList->limiters;
newLimiterList->add(Limiter);
limiter = newLimiterList;
}
else
{

View File

@@ -33,9 +33,9 @@ using BonusSubtypeID = VariantIdentifier<BonusCustomSubtype, SpellID, CreatureID
using BonusSourceID = VariantIdentifier<BonusCustomSource, SpellID, CreatureID, ArtifactID, CampaignScenarioID, SecondarySkill, HeroTypeID, Obj, ObjectInstanceID, BuildingTypeUniqueID, BattleField>;
using TBonusListPtr = std::shared_ptr<BonusList>;
using TConstBonusListPtr = std::shared_ptr<const BonusList>;
using TLimiterPtr = std::shared_ptr<ILimiter>;
using TPropagatorPtr = std::shared_ptr<IPropagator>;
using TUpdaterPtr = std::shared_ptr<IUpdater>;
using TLimiterPtr = std::shared_ptr<const ILimiter>;
using TPropagatorPtr = std::shared_ptr<const IPropagator>;
using TUpdaterPtr = std::shared_ptr<const IUpdater>;
class DLL_LINKAGE CAddInfo : public std::vector<si32>
{
@@ -59,15 +59,15 @@ public:
struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>, public Serializeable
{
BonusDuration::Type duration = BonusDuration::PERMANENT; //uses BonusDuration values - 2 bytes
si16 turnsRemain = 0; //used if duration is N_TURNS, N_DAYS or ONE_WEEK
si32 val = 0;
si16 turnsRemain = 0; //used if duration is N_TURNS, N_DAYS or ONE_WEEK
BonusValueType valType = BonusValueType::ADDITIVE_VALUE; // 1 byte
BonusSource source = BonusSource::OTHER; //source type" uses BonusSource values - what gave that bonus - 1 byte
BonusSource targetSourceType = BonusSource::OTHER;//Bonuses of what origin this amplifies, uses BonusSource values. Needed for PERCENT_TO_TARGET_TYPE. - 1 byte
BonusType type = BonusType::NONE; //uses BonusType values - says to what is this bonus - 1 byte
BonusLimitEffect effectRange = BonusLimitEffect::NO_LIMIT; // 1 byte
// 3 bytes padding
// 1 bytes padding
BonusSubtypeID subtype;
BonusSourceID sid; //source id: id of object/artifact/spell
@@ -82,6 +82,7 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>, public Se
ImagePath customIconPath;
MetaString description;
PlayerColor bonusOwner = PlayerColor::CANNOT_DETERMINE;
Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, BonusSourceID sourceID);
Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, BonusSourceID sourceID, BonusSubtypeID subtype);

View File

@@ -97,13 +97,6 @@ JsonNode ILimiter::toJsonNode() const
return root;
}
void ILimiter::acceptUpdater(IUpdater& visitor) {}
TLimiterPtr ILimiter::clone() const
{
throw std::runtime_error("Clone not implemented for this limiter");
}
ILimiter::EDecision CCreatureTypeLimiter::limit(const BonusLimitationContext &context) const
{
const CCreature *c = retrieveCreature(&context.node);
@@ -143,16 +136,6 @@ JsonNode CCreatureTypeLimiter::toJsonNode() const
return root;
}
void CCreatureTypeLimiter::acceptUpdater(IUpdater & visitor)
{
visitor.visitLimiter(*this);
}
TLimiterPtr CCreatureTypeLimiter::clone() const
{
return std::make_shared<CCreatureTypeLimiter>(*this);
}
HasAnotherBonusLimiter::HasAnotherBonusLimiter( BonusType bonus )
: type(bonus), isSubtypeRelevant(false), isSourceRelevant(false), isSourceIDRelevant(false)
{
@@ -236,16 +219,6 @@ JsonNode HasAnotherBonusLimiter::toJsonNode() const
return root;
}
void HasAnotherBonusLimiter::acceptUpdater(IUpdater & visitor)
{
visitor.visitLimiter(*this);
}
TLimiterPtr HasAnotherBonusLimiter::clone() const
{
return std::make_shared<HasAnotherBonusLimiter>(*this);
}
ILimiter::EDecision UnitOnHexLimiter::limit(const BonusLimitationContext &context) const
{
const auto * stack = retrieveStackBattle(&context.node);
@@ -276,16 +249,6 @@ JsonNode UnitOnHexLimiter::toJsonNode() const
return root;
}
void UnitOnHexLimiter::acceptUpdater(IUpdater& visitor)
{
visitor.visitLimiter(*this);
}
TLimiterPtr UnitOnHexLimiter::clone() const
{
return std::make_shared<UnitOnHexLimiter>(*this);
}
CreatureTerrainLimiter::CreatureTerrainLimiter()
: terrainType(ETerrainId::NATIVE_TERRAIN)
{
@@ -365,16 +328,6 @@ JsonNode CreatureTerrainLimiter::toJsonNode() const
return root;
}
void CreatureTerrainLimiter::acceptUpdater(IUpdater & visitor)
{
visitor.visitLimiter(*this);
}
TLimiterPtr CreatureTerrainLimiter::clone() const
{
return std::make_shared<CreatureTerrainLimiter>(*this);
}
FactionLimiter::FactionLimiter(FactionID creatureFaction)
: faction(creatureFaction)
{
@@ -420,16 +373,6 @@ JsonNode FactionLimiter::toJsonNode() const
return root;
}
void FactionLimiter::acceptUpdater(IUpdater & visitor)
{
visitor.visitLimiter(*this);
}
TLimiterPtr FactionLimiter::clone() const
{
return std::make_shared<FactionLimiter>(*this);
}
CreatureLevelLimiter::CreatureLevelLimiter(uint32_t minLevel, uint32_t maxLevel) :
minLevel(minLevel),
maxLevel(maxLevel)
@@ -464,16 +407,6 @@ JsonNode CreatureLevelLimiter::toJsonNode() const
return root;
}
void CreatureLevelLimiter::acceptUpdater(IUpdater& visitor)
{
visitor.visitLimiter(*this);
}
TLimiterPtr CreatureLevelLimiter::clone() const
{
return std::make_shared<CreatureLevelLimiter>(*this);
}
CreatureAlignmentLimiter::CreatureAlignmentLimiter(EAlignment Alignment)
: alignment(Alignment)
{
@@ -513,16 +446,6 @@ JsonNode CreatureAlignmentLimiter::toJsonNode() const
return root;
}
void CreatureAlignmentLimiter::acceptUpdater(IUpdater & visitor)
{
visitor.visitLimiter(*this);
}
TLimiterPtr CreatureAlignmentLimiter::clone() const
{
return std::make_shared<CreatureAlignmentLimiter>(*this);
}
RankRangeLimiter::RankRangeLimiter(ui8 Min, ui8 Max)
:minRank(Min), maxRank(Max)
{
@@ -548,41 +471,20 @@ ILimiter::EDecision RankRangeLimiter::limit(const BonusLimitationContext &contex
return ILimiter::EDecision::NOT_APPLICABLE;
}
void RankRangeLimiter::acceptUpdater(IUpdater & visitor)
{
visitor.visitLimiter(*this);
}
TLimiterPtr RankRangeLimiter::clone() const
{
return std::make_shared<RankRangeLimiter>(*this);
}
OppositeSideLimiter::OppositeSideLimiter(PlayerColor Owner):
owner(std::move(Owner))
OppositeSideLimiter::OppositeSideLimiter()
{
}
ILimiter::EDecision OppositeSideLimiter::limit(const BonusLimitationContext & context) const
{
auto contextOwner = context.node.getOwner();
PlayerColor contextOwner = context.node.getOwner();
PlayerColor bonusOwner = context.b.bonusOwner;
if (contextOwner == PlayerColor::UNFLAGGABLE)
contextOwner = PlayerColor::NEUTRAL;
auto decision = (owner == contextOwner || owner == PlayerColor::CANNOT_DETERMINE) ? ILimiter::EDecision::DISCARD : ILimiter::EDecision::ACCEPT;
auto decision = (bonusOwner == contextOwner || bonusOwner == PlayerColor::CANNOT_DETERMINE) ? ILimiter::EDecision::DISCARD : ILimiter::EDecision::ACCEPT;
return decision;
}
void OppositeSideLimiter::acceptUpdater(IUpdater & visitor)
{
visitor.visitLimiter(*this);
}
TLimiterPtr OppositeSideLimiter::clone() const
{
return std::make_shared<OppositeSideLimiter>(*this);
}
// Aggregate/Boolean Limiters
AggregateLimiter::AggregateLimiter(std::vector<TLimiterPtr> limiters):
@@ -605,11 +507,6 @@ JsonNode AggregateLimiter::toJsonNode() const
return result;
}
void AggregateLimiter::acceptUpdater(IUpdater & visitor)
{
visitor.visitLimiter(*this);
}
const std::string AllOfLimiter::aggregator = "allOf";
const std::string & AllOfLimiter::getAggregator() const
{
@@ -637,15 +534,6 @@ ILimiter::EDecision AllOfLimiter::limit(const BonusLimitationContext & context)
return wasntSure ? ILimiter::EDecision::NOT_SURE : ILimiter::EDecision::ACCEPT;
}
TLimiterPtr AllOfLimiter::clone() const
{
std::vector<TLimiterPtr> clonedLimiters;
clonedLimiters.reserve(limiters.size());
for (const auto& limiter : limiters)
clonedLimiters.push_back(limiter->clone());
return std::make_shared<AllOfLimiter>(clonedLimiters);
}
const std::string AnyOfLimiter::aggregator = "anyOf";
const std::string & AnyOfLimiter::getAggregator() const
{
@@ -673,15 +561,6 @@ ILimiter::EDecision AnyOfLimiter::limit(const BonusLimitationContext & context)
return wasntSure ? ILimiter::EDecision::NOT_SURE : ILimiter::EDecision::DISCARD;
}
TLimiterPtr AnyOfLimiter::clone() const
{
std::vector<TLimiterPtr> clonedLimiters;
clonedLimiters.reserve(limiters.size());
for (const auto& limiter : limiters)
clonedLimiters.push_back(limiter->clone());
return std::make_shared<AnyOfLimiter>(clonedLimiters);
}
const std::string NoneOfLimiter::aggregator = "noneOf";
const std::string & NoneOfLimiter::getAggregator() const
{
@@ -711,13 +590,4 @@ ILimiter::EDecision NoneOfLimiter::limit(const BonusLimitationContext & context)
return wasntSure ? ILimiter::EDecision::NOT_SURE : ILimiter::EDecision::ACCEPT;
}
TLimiterPtr NoneOfLimiter::clone() const
{
std::vector<TLimiterPtr> clonedLimiters;
clonedLimiters.reserve(limiters.size());
for (const auto& limiter : limiters)
clonedLimiters.push_back(limiter->clone());
return std::make_shared<NoneOfLimiter>(clonedLimiters);
}
VCMI_LIB_NAMESPACE_END

View File

@@ -44,8 +44,6 @@ public:
virtual EDecision limit(const BonusLimitationContext &context) const; //0 - accept bonus; 1 - drop bonus; 2 - delay (drops eventually)
virtual std::string toString() const;
virtual JsonNode toJsonNode() const;
virtual void acceptUpdater(IUpdater & visitor);
virtual TLimiterPtr clone() const;
template <typename Handler> void serialize(Handler &h)
{
@@ -61,7 +59,6 @@ public:
std::vector<TLimiterPtr> limiters;
void add(const TLimiterPtr & limiter);
JsonNode toJsonNode() const override;
void acceptUpdater(IUpdater & visitor) override;
template <typename Handler> void serialize(Handler & h)
{
@@ -78,7 +75,6 @@ public:
AllOfLimiter(std::vector<TLimiterPtr> limiters = {});
static const std::string aggregator;
EDecision limit(const BonusLimitationContext & context) const override;
TLimiterPtr clone() const override;
};
class DLL_LINKAGE AnyOfLimiter : public AggregateLimiter
@@ -89,7 +85,6 @@ public:
AnyOfLimiter(std::vector<TLimiterPtr> limiters = {});
static const std::string aggregator;
EDecision limit(const BonusLimitationContext & context) const override;
TLimiterPtr clone() const override;
};
class DLL_LINKAGE NoneOfLimiter : public AggregateLimiter
@@ -100,7 +95,6 @@ public:
NoneOfLimiter(std::vector<TLimiterPtr> limiters = {});
static const std::string aggregator;
EDecision limit(const BonusLimitationContext & context) const override;
TLimiterPtr clone() const override;
};
class DLL_LINKAGE CCreatureTypeLimiter : public ILimiter //affect only stacks of given creature (and optionally it's upgrades)
@@ -116,8 +110,6 @@ public:
EDecision limit(const BonusLimitationContext &context) const override;
std::string toString() const override;
JsonNode toJsonNode() const override;
void acceptUpdater(IUpdater & visitor) override;
TLimiterPtr clone() const override;
template <typename Handler> void serialize(Handler &h)
{
@@ -146,8 +138,6 @@ public:
EDecision limit(const BonusLimitationContext &context) const override;
std::string toString() const override;
JsonNode toJsonNode() const override;
void acceptUpdater(IUpdater & visitor) override;
TLimiterPtr clone() const override;
template <typename Handler> void serialize(Handler &h)
{
@@ -172,8 +162,6 @@ public:
EDecision limit(const BonusLimitationContext &context) const override;
std::string toString() const override;
JsonNode toJsonNode() const override;
void acceptUpdater(IUpdater & visitor) override;
TLimiterPtr clone() const override;
template <typename Handler> void serialize(Handler &h)
{
@@ -193,8 +181,6 @@ public:
EDecision limit(const BonusLimitationContext &context) const override;
std::string toString() const override;
JsonNode toJsonNode() const override;
void acceptUpdater(IUpdater & visitor) override;
TLimiterPtr clone() const override;
template <typename Handler> void serialize(Handler &h)
{
@@ -213,8 +199,6 @@ public:
EDecision limit(const BonusLimitationContext &context) const override;
std::string toString() const override;
JsonNode toJsonNode() const override;
void acceptUpdater(IUpdater & visitor) override;
TLimiterPtr clone() const override;
template <typename Handler> void serialize(Handler &h)
{
@@ -232,8 +216,6 @@ public:
EDecision limit(const BonusLimitationContext &context) const override;
std::string toString() const override;
JsonNode toJsonNode() const override;
void acceptUpdater(IUpdater & visitor) override;
TLimiterPtr clone() const override;
template <typename Handler> void serialize(Handler &h)
{
@@ -245,17 +227,18 @@ public:
class DLL_LINKAGE OppositeSideLimiter : public ILimiter //applies only to creatures of enemy army during combat
{
public:
PlayerColor owner;
OppositeSideLimiter(PlayerColor Owner = PlayerColor::CANNOT_DETERMINE);
OppositeSideLimiter();
EDecision limit(const BonusLimitationContext &context) const override;
void acceptUpdater(IUpdater & visitor) override;
TLimiterPtr clone() const override;
template <typename Handler> void serialize(Handler &h)
{
h & static_cast<ILimiter&>(*this);
h & owner;
if (!h.hasFeature(Handler::Version::OPPOSITE_SIDE_LIMITER_OWNER))
{
PlayerColor owner;
h & owner;
}
}
};
@@ -268,8 +251,6 @@ public:
RankRangeLimiter();
RankRangeLimiter(ui8 Min, ui8 Max = 255);
EDecision limit(const BonusLimitationContext &context) const override;
void acceptUpdater(IUpdater & visitor) override;
TLimiterPtr clone() const override;
template <typename Handler> void serialize(Handler &h)
{
@@ -287,8 +268,6 @@ public:
UnitOnHexLimiter(const BattleHexArray & applicableHexes = {});
EDecision limit(const BonusLimitationContext &context) const override;
JsonNode toJsonNode() const override;
void acceptUpdater(IUpdater& visitor) override;
TLimiterPtr clone() const override;
template <typename Handler> void serialize(Handler &h)
{

View File

@@ -24,7 +24,7 @@ const std::map<std::string, TPropagatorPtr> bonusPropagatorMap =
{"GLOBAL_EFFECT", std::make_shared<CPropagatorNodeType>(CBonusSystemNode::GLOBAL_EFFECTS)}
}; //untested
bool IPropagator::shouldBeAttached(CBonusSystemNode *dest)
bool IPropagator::shouldBeAttached(CBonusSystemNode *dest) const
{
return false;
}
@@ -44,9 +44,9 @@ CBonusSystemNode::ENodeTypes CPropagatorNodeType::getPropagatorType() const
return nodeType;
}
bool CPropagatorNodeType::shouldBeAttached(CBonusSystemNode *dest)
bool CPropagatorNodeType::shouldBeAttached(CBonusSystemNode *dest) const
{
return nodeType == dest->getNodeType();
}
VCMI_LIB_NAMESPACE_END
VCMI_LIB_NAMESPACE_END

View File

@@ -22,7 +22,7 @@ class DLL_LINKAGE IPropagator : public Serializeable
{
public:
virtual ~IPropagator() = default;
virtual bool shouldBeAttached(CBonusSystemNode *dest);
virtual bool shouldBeAttached(CBonusSystemNode *dest) const;
virtual CBonusSystemNode::ENodeTypes getPropagatorType() const;
template <typename Handler> void serialize(Handler &h)
@@ -35,7 +35,7 @@ class DLL_LINKAGE CPropagatorNodeType : public IPropagator
public:
CPropagatorNodeType(CBonusSystemNode::ENodeTypes NodeType = CBonusSystemNode::ENodeTypes::UNKNOWN);
bool shouldBeAttached(CBonusSystemNode *dest) override;
bool shouldBeAttached(CBonusSystemNode *dest) const override;
CBonusSystemNode::ENodeTypes getPropagatorType() const override;
template <typename Handler> void serialize(Handler &h)

View File

@@ -18,7 +18,7 @@
VCMI_LIB_NAMESPACE_BEGIN
std::shared_ptr<Bonus> IUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context)
std::shared_ptr<Bonus> IUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const
{
return b;
}
@@ -33,27 +33,11 @@ JsonNode IUpdater::toJsonNode() const
return JsonNode();
}
void IUpdater::visitLimiter(AggregateLimiter& limiter)
{
for (auto& limit : limiter.limiters)
limit->acceptUpdater(*this);
}
void IUpdater::visitLimiter(CCreatureTypeLimiter& limiter) {}
void IUpdater::visitLimiter(HasAnotherBonusLimiter& limiter) {}
void IUpdater::visitLimiter(CreatureTerrainLimiter& limiter) {}
void IUpdater::visitLimiter(CreatureLevelLimiter& limiter) {}
void IUpdater::visitLimiter(FactionLimiter& limiter) {}
void IUpdater::visitLimiter(CreatureAlignmentLimiter& limiter) {}
void IUpdater::visitLimiter(OppositeSideLimiter& limiter) {}
void IUpdater::visitLimiter(RankRangeLimiter& limiter) {}
void IUpdater::visitLimiter(UnitOnHexLimiter& limiter) {}
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)
std::shared_ptr<Bonus> GrowsWithLevelUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const
{
if(context.getNodeType() == CBonusSystemNode::HERO)
{
@@ -86,7 +70,7 @@ JsonNode GrowsWithLevelUpdater::toJsonNode() const
return root;
}
std::shared_ptr<Bonus> TimesHeroLevelUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context)
std::shared_ptr<Bonus> TimesHeroLevelUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const
{
if(context.getNodeType() == CBonusSystemNode::HERO)
{
@@ -108,7 +92,7 @@ JsonNode TimesHeroLevelUpdater::toJsonNode() const
return JsonNode("TIMES_HERO_LEVEL");
}
std::shared_ptr<Bonus> TimesHeroLevelDivideStackLevelUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context)
std::shared_ptr<Bonus> TimesHeroLevelDivideStackLevelUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const
{
if(context.getNodeType() == CBonusSystemNode::HERO)
{
@@ -137,7 +121,7 @@ std::shared_ptr<Bonus> TimesStackLevelUpdater::apply(const std::shared_ptr<Bonus
return newBonus;
}
std::shared_ptr<Bonus> TimesStackLevelUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context)
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)
{
@@ -181,7 +165,7 @@ std::shared_ptr<Bonus> DivideStackLevelUpdater::apply(const std::shared_ptr<Bonu
return newBonus;
}
std::shared_ptr<Bonus> DivideStackLevelUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context)
std::shared_ptr<Bonus> DivideStackLevelUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const
{
if(context.getNodeType() == CBonusSystemNode::STACK_INSTANCE || context.getNodeType() == CBonusSystemNode::COMMANDER)
{
@@ -223,24 +207,17 @@ JsonNode OwnerUpdater::toJsonNode() const
return JsonNode("BONUS_OWNER_UPDATER");
}
std::shared_ptr<Bonus> OwnerUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context)
std::shared_ptr<Bonus> OwnerUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const
{
owner = context.getOwner();
PlayerColor owner = context.getOwner();
if(owner == PlayerColor::UNFLAGGABLE)
owner = PlayerColor::NEUTRAL;
std::shared_ptr<Bonus> updated =
std::make_shared<Bonus>(*b);
updated->limiter = b->limiter->clone();
if (updated->limiter)
updated->limiter->acceptUpdater(*this);
updated->bonusOwner = owner;
return updated;
}
void OwnerUpdater::visitLimiter(OppositeSideLimiter& limiter)
{
limiter.owner = owner;
}
VCMI_LIB_NAMESPACE_END

View File

@@ -32,21 +32,10 @@ class DLL_LINKAGE IUpdater : public Serializeable
public:
virtual ~IUpdater() = default;
virtual std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context);
virtual std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const;
virtual std::string toString() const;
virtual JsonNode toJsonNode() const;
virtual void visitLimiter(AggregateLimiter & limiter);
virtual void visitLimiter(CCreatureTypeLimiter& limiter);
virtual void visitLimiter(HasAnotherBonusLimiter & limiter);
virtual void visitLimiter(CreatureTerrainLimiter & limiter);
virtual void visitLimiter(CreatureLevelLimiter & limiter);
virtual void visitLimiter(FactionLimiter & limiter);
virtual void visitLimiter(CreatureAlignmentLimiter & limiter) ;
virtual void visitLimiter(OppositeSideLimiter & limiter);
virtual void visitLimiter(RankRangeLimiter & limiter);
virtual void visitLimiter(UnitOnHexLimiter & limiter);
template <typename Handler> void serialize(Handler & h)
{
}
@@ -68,7 +57,7 @@ public:
h & stepSize;
}
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) override;
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const override;
std::string toString() const override;
JsonNode toJsonNode() const override;
};
@@ -81,7 +70,7 @@ public:
h & static_cast<IUpdater &>(*this);
}
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) override;
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const override;
std::string toString() const override;
JsonNode toJsonNode() const override;
};
@@ -95,7 +84,7 @@ public:
h & static_cast<IUpdater &>(*this);
}
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) override;
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const override;
std::string toString() const override;
JsonNode toJsonNode() const override;
};
@@ -109,7 +98,7 @@ public:
h & static_cast<IUpdater &>(*this);
}
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) override;
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const override;
std::string toString() const override;
JsonNode toJsonNode() const override;
};
@@ -128,26 +117,22 @@ public:
: divideStackLevel(std::make_shared<DivideStackLevelUpdater>())
{}
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) override;
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const override;
std::string toString() const override;
JsonNode toJsonNode() const override;
};
class DLL_LINKAGE OwnerUpdater : public IUpdater
{
protected:
PlayerColor owner;
public:
template <typename Handler> void serialize(Handler& h)
{
h & static_cast<IUpdater &>(*this);
}
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus>& b, const CBonusSystemNode& context) override;
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus>& b, const CBonusSystemNode& context) const override;
std::string toString() const override;
JsonNode toJsonNode() const override;
void visitLimiter(OppositeSideLimiter& limiter) override;
};
VCMI_LIB_NAMESPACE_END

View File

@@ -399,13 +399,13 @@ static BonusParams convertDeprecatedBonus(const JsonNode &ability)
static TUpdaterPtr parseUpdater(const JsonNode & updaterJson)
{
const std::map<std::string, std::function<TUpdaterPtr()>> bonusUpdaterMap =
const std::map<std::string, std::shared_ptr<IUpdater>> bonusUpdaterMap =
{
{"TIMES_HERO_LEVEL", std::make_shared<TimesHeroLevelUpdater>},
{"TIMES_HERO_LEVEL_DIVIDE_STACK_LEVEL", std::make_shared<TimesHeroLevelDivideStackLevelUpdater>},
{"DIVIDE_STACK_LEVEL", std::make_shared<DivideStackLevelUpdater>},
{"TIMES_STACK_LEVEL", std::make_shared<TimesStackLevelUpdater>},
{"BONUS_OWNER_UPDATER", std::make_shared<OwnerUpdater>}
{"TIMES_HERO_LEVEL", std::make_shared<TimesHeroLevelUpdater>()},
{"TIMES_HERO_LEVEL_DIVIDE_STACK_LEVEL", std::make_shared<TimesHeroLevelDivideStackLevelUpdater>()},
{"DIVIDE_STACK_LEVEL", std::make_shared<DivideStackLevelUpdater>()},
{"TIMES_STACK_LEVEL", std::make_shared<TimesStackLevelUpdater>()},
{"BONUS_OWNER_UPDATER", std::make_shared<OwnerUpdater>()}
};
switch(updaterJson.getType())
@@ -414,7 +414,7 @@ static TUpdaterPtr parseUpdater(const JsonNode & updaterJson)
{
auto it = bonusUpdaterMap.find(updaterJson.String());
if (it != bonusUpdaterMap.end())
return it->second();
return it->second;
logGlobal->error("Unknown bonus updater type '%s'", updaterJson.String());
return nullptr;
@@ -458,7 +458,7 @@ std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonVector & ability_vec)
return b;
}
std::shared_ptr<ILimiter> JsonUtils::parseLimiter(const JsonNode & limiter)
std::shared_ptr<const ILimiter> JsonUtils::parseLimiter(const JsonNode & limiter)
{
switch(limiter.getType())
{

View File

@@ -24,7 +24,7 @@ namespace JsonUtils
std::shared_ptr<Bonus> parseBonus(const JsonVector & ability_vec);
std::shared_ptr<Bonus> parseBonus(const JsonNode & ability, const TextIdentifier & descriptionID = "");
bool parseBonus(const JsonNode & ability, Bonus * placement, const TextIdentifier & descriptionID = "");
std::shared_ptr<ILimiter> parseLimiter(const JsonNode & limiter);
std::shared_ptr<const ILimiter> parseLimiter(const JsonNode & limiter);
CSelector parseSelector(const JsonNode &ability);
}

View File

@@ -44,8 +44,9 @@ enum class ESerializationVersion : int32_t
RANDOMIZATION_REWORK, // random rolls logic has been moved to server
CUSTOM_BONUS_ICONS, // support for custom icons in bonuses
SERVER_STATISTICS, // statistics now only saved on server
OPPOSITE_SIDE_LIMITER_OWNER, // opposite side limiter no longer stores owner in itself
CURRENT = SERVER_STATISTICS,
CURRENT = OPPOSITE_SIDE_LIMITER_OWNER,
};
static_assert(ESerializationVersion::MINIMAL <= ESerializationVersion::CURRENT, "Invalid serialization version definition!");