|
@@ -99,6 +99,11 @@ JsonNode ILimiter::toJsonNode() const
|
|
|
|
|
|
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,6 +148,11 @@ 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)
|
|
|
{
|
|
@@ -231,6 +241,11 @@ 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);
|
|
@@ -266,6 +281,10 @@ void UnitOnHexLimiter::acceptUpdater(IUpdater& visitor)
|
|
|
visitor.visitLimiter(*this);
|
|
|
}
|
|
|
|
|
|
+TLimiterPtr UnitOnHexLimiter::clone() const
|
|
|
+{
|
|
|
+ return std::make_shared<UnitOnHexLimiter>(*this);
|
|
|
+}
|
|
|
|
|
|
CreatureTerrainLimiter::CreatureTerrainLimiter()
|
|
|
: terrainType(ETerrainId::NATIVE_TERRAIN)
|
|
@@ -351,6 +370,11 @@ void CreatureTerrainLimiter::acceptUpdater(IUpdater & visitor)
|
|
|
visitor.visitLimiter(*this);
|
|
|
}
|
|
|
|
|
|
+TLimiterPtr CreatureTerrainLimiter::clone() const
|
|
|
+{
|
|
|
+ return std::make_shared<CreatureTerrainLimiter>(*this);
|
|
|
+}
|
|
|
+
|
|
|
FactionLimiter::FactionLimiter(FactionID creatureFaction)
|
|
|
: faction(creatureFaction)
|
|
|
{
|
|
@@ -401,6 +425,11 @@ 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)
|
|
@@ -440,6 +469,11 @@ void CreatureLevelLimiter::acceptUpdater(IUpdater& visitor)
|
|
|
visitor.visitLimiter(*this);
|
|
|
}
|
|
|
|
|
|
+TLimiterPtr CreatureLevelLimiter::clone() const
|
|
|
+{
|
|
|
+ return std::make_shared<CreatureLevelLimiter>(*this);
|
|
|
+}
|
|
|
+
|
|
|
CreatureAlignmentLimiter::CreatureAlignmentLimiter(EAlignment Alignment)
|
|
|
: alignment(Alignment)
|
|
|
{
|
|
@@ -484,6 +518,11 @@ 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)
|
|
|
{
|
|
@@ -514,6 +553,12 @@ 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))
|
|
|
{
|
|
@@ -522,6 +567,8 @@ OppositeSideLimiter::OppositeSideLimiter(PlayerColor Owner):
|
|
|
ILimiter::EDecision OppositeSideLimiter::limit(const BonusLimitationContext & context) const
|
|
|
{
|
|
|
auto contextOwner = context.node.getOwner();
|
|
|
+ if (contextOwner == PlayerColor::UNFLAGGABLE)
|
|
|
+ contextOwner = PlayerColor::NEUTRAL;
|
|
|
auto decision = (owner == contextOwner || owner == PlayerColor::CANNOT_DETERMINE) ? ILimiter::EDecision::DISCARD : ILimiter::EDecision::ACCEPT;
|
|
|
return decision;
|
|
|
}
|
|
@@ -531,6 +578,11 @@ 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):
|
|
@@ -585,6 +637,15 @@ 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
|
|
|
{
|
|
@@ -612,6 +673,15 @@ 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
|
|
|
{
|
|
@@ -641,4 +711,13 @@ 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
|