mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
vcmi: slightly rework limiters
1. Add vector to aggregates 2. Rework CreatureFactionLimiter to FactionLimiter
This commit is contained in:
parent
7326980bd4
commit
dd196f2aa8
@ -569,9 +569,9 @@ void CTownHandler::loadSpecialBuildingBonuses(const JsonNode & source, BonusList
|
||||
|
||||
if(bonus->limiter != nullptr)
|
||||
{
|
||||
auto * limPtr = dynamic_cast<CreatureFactionLimiter *>(bonus->limiter.get());
|
||||
auto * limPtr = dynamic_cast<FactionLimiter *>(bonus->limiter.get());
|
||||
|
||||
if(limPtr != nullptr && limPtr->faction == FactionID::ANY)
|
||||
if(limPtr != nullptr && limPtr->faction == FactionID::DEFAULT)
|
||||
limPtr->faction = building->town->faction->getId();
|
||||
}
|
||||
//JsonUtils::parseBuildingBonus produces UNKNOWN type propagator instead of empty.
|
||||
|
@ -188,7 +188,7 @@ std::string PlayerColor::getStrCap(bool L10n) const
|
||||
}
|
||||
|
||||
const FactionID FactionID::NONE = FactionID(-2);
|
||||
const FactionID FactionID::ANY = FactionID(-1);
|
||||
const FactionID FactionID::DEFAULT = FactionID(-1);
|
||||
const FactionID FactionID::CASTLE = FactionID(0);
|
||||
const FactionID FactionID::RAMPART = FactionID(1);
|
||||
const FactionID FactionID::TOWER = FactionID(2);
|
||||
@ -206,7 +206,7 @@ si32 FactionID::decode(const std::string & identifier)
|
||||
if(rawId)
|
||||
return rawId.get();
|
||||
else
|
||||
return FactionID::ANY;
|
||||
return FactionID::DEFAULT;
|
||||
}
|
||||
|
||||
std::string FactionID::encode(const si32 index)
|
||||
|
@ -443,7 +443,7 @@ class FactionID : public BaseForID<FactionID, int32_t>
|
||||
INSTID_LIKE_CLASS_COMMON(FactionID, si32)
|
||||
|
||||
DLL_LINKAGE static const FactionID NONE;
|
||||
DLL_LINKAGE static const FactionID ANY;
|
||||
DLL_LINKAGE static const FactionID DEFAULT;
|
||||
DLL_LINKAGE static const FactionID CASTLE;
|
||||
DLL_LINKAGE static const FactionID RAMPART;
|
||||
DLL_LINKAGE static const FactionID TOWER;
|
||||
|
@ -75,7 +75,8 @@ const std::map<std::string, TLimiterPtr> bonusLimiterMap =
|
||||
{"DRAGON_NATURE", std::make_shared<HasAnotherBonusLimiter>(Bonus::DRAGON_NATURE)},
|
||||
{"IS_UNDEAD", std::make_shared<HasAnotherBonusLimiter>(Bonus::UNDEAD)},
|
||||
{"CREATURE_NATIVE_TERRAIN", std::make_shared<CreatureTerrainLimiter>()},
|
||||
{"CREATURE_FACTION", std::make_shared<CreatureFactionLimiter>()},
|
||||
{"CREATURE_FACTION", std::make_shared<AllOfLimiter>(std::initializer_list<TLimiterPtr>{std::make_shared<CreatureLevelLimiter>(), std::make_shared<FactionLimiter>()})},
|
||||
{"SAME_FACTION", std::make_shared<FactionLimiter>()},
|
||||
{"CREATURES_ONLY", std::make_shared<CreatureLevelLimiter>()},
|
||||
{"OPPOSITE_SIDE", std::make_shared<OppositeSideLimiter>()},
|
||||
};
|
||||
@ -2366,30 +2367,46 @@ JsonNode CreatureTerrainLimiter::toJsonNode() const
|
||||
return root;
|
||||
}
|
||||
|
||||
CreatureFactionLimiter::CreatureFactionLimiter(FactionID creatureFaction)
|
||||
FactionLimiter::FactionLimiter(FactionID creatureFaction)
|
||||
: faction(creatureFaction)
|
||||
{
|
||||
}
|
||||
|
||||
ILimiter::EDecision CreatureFactionLimiter::limit(const BonusLimitationContext &context) const
|
||||
ILimiter::EDecision FactionLimiter::limit(const BonusLimitationContext &context) const
|
||||
{
|
||||
const CCreature *c = retrieveCreature(&context.node);
|
||||
auto accept = c && (c->getFactionIndex() == faction || faction == FactionID::ANY);
|
||||
return accept ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD; //drop bonus for non-creatures or non-native residents
|
||||
const auto * bearer = dynamic_cast<const INativeTerrainProvider*>(&context.node);
|
||||
|
||||
if(bearer)
|
||||
{
|
||||
if(faction != FactionID::DEFAULT)
|
||||
return bearer->getFaction() == faction ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
|
||||
|
||||
switch(context.b->source)
|
||||
{
|
||||
case Bonus::CREATURE_ABILITY:
|
||||
return faction == CreatureID(context.b->sid).toCreature()->getFaction() ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
|
||||
|
||||
case Bonus::TOWN_STRUCTURE:
|
||||
return faction == FactionID(Bonus::getHighFromSid32(context.b->sid)) ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
|
||||
|
||||
//TODO: other sources of bonuses
|
||||
}
|
||||
}
|
||||
return ILimiter::EDecision::DISCARD; //Discard by default
|
||||
}
|
||||
|
||||
std::string CreatureFactionLimiter::toString() const
|
||||
std::string FactionLimiter::toString() const
|
||||
{
|
||||
boost::format fmt("CreatureFactionLimiter(faction=%s)");
|
||||
boost::format fmt("FactionLimiter(faction=%s)");
|
||||
fmt % VLC->factions()->getByIndex(faction)->getJsonKey();
|
||||
return fmt.str();
|
||||
}
|
||||
|
||||
JsonNode CreatureFactionLimiter::toJsonNode() const
|
||||
JsonNode FactionLimiter::toJsonNode() const
|
||||
{
|
||||
JsonNode root(JsonNode::JsonType::DATA_STRUCT);
|
||||
|
||||
root["type"].String() = "CREATURE_FACTION_LIMITER";
|
||||
root["type"].String() = "FACTION_LIMITER";
|
||||
root["parameters"].Vector().push_back(JsonUtils::stringNode(VLC->factions()->getByIndex(faction)->getJsonKey()));
|
||||
|
||||
return root;
|
||||
@ -2498,23 +2515,13 @@ ILimiter::EDecision StackOwnerLimiter::limit(const BonusLimitationContext &conte
|
||||
return ILimiter::EDecision::DISCARD;
|
||||
}
|
||||
|
||||
StackOwnerLimiter::StackOwnerLimiter()
|
||||
: owner(-1)
|
||||
{
|
||||
}
|
||||
|
||||
StackOwnerLimiter::StackOwnerLimiter(const PlayerColor & Owner):
|
||||
owner(Owner)
|
||||
{
|
||||
}
|
||||
|
||||
OppositeSideLimiter::OppositeSideLimiter():
|
||||
owner(PlayerColor::CANNOT_DETERMINE)
|
||||
{
|
||||
}
|
||||
|
||||
OppositeSideLimiter::OppositeSideLimiter(const PlayerColor & Owner):
|
||||
owner(Owner)
|
||||
OppositeSideLimiter::OppositeSideLimiter(PlayerColor Owner):
|
||||
owner(std::move(Owner))
|
||||
{
|
||||
}
|
||||
|
||||
@ -2527,6 +2534,11 @@ ILimiter::EDecision OppositeSideLimiter::limit(const BonusLimitationContext & co
|
||||
|
||||
// Aggregate/Boolean Limiters
|
||||
|
||||
AggregateLimiter::AggregateLimiter(std::vector<TLimiterPtr> limiters):
|
||||
limiters(std::move(limiters))
|
||||
{
|
||||
}
|
||||
|
||||
void AggregateLimiter::add(const TLimiterPtr & limiter)
|
||||
{
|
||||
if(limiter)
|
||||
@ -2548,6 +2560,11 @@ const std::string & AllOfLimiter::getAggregator() const
|
||||
return aggregator;
|
||||
}
|
||||
|
||||
AllOfLimiter::AllOfLimiter(std::vector<TLimiterPtr> limiters):
|
||||
AggregateLimiter(limiters)
|
||||
{
|
||||
}
|
||||
|
||||
ILimiter::EDecision AllOfLimiter::limit(const BonusLimitationContext & context) const
|
||||
{
|
||||
bool wasntSure = false;
|
||||
@ -2570,6 +2587,11 @@ const std::string & AnyOfLimiter::getAggregator() const
|
||||
return aggregator;
|
||||
}
|
||||
|
||||
AnyOfLimiter::AnyOfLimiter(std::vector<TLimiterPtr> limiters):
|
||||
AggregateLimiter(limiters)
|
||||
{
|
||||
}
|
||||
|
||||
ILimiter::EDecision AnyOfLimiter::limit(const BonusLimitationContext & context) const
|
||||
{
|
||||
bool wasntSure = false;
|
||||
@ -2592,6 +2614,11 @@ const std::string & NoneOfLimiter::getAggregator() const
|
||||
return aggregator;
|
||||
}
|
||||
|
||||
NoneOfLimiter::NoneOfLimiter(std::vector<TLimiterPtr> limiters):
|
||||
AggregateLimiter(limiters)
|
||||
{
|
||||
}
|
||||
|
||||
ILimiter::EDecision NoneOfLimiter::limit(const BonusLimitationContext & context) const
|
||||
{
|
||||
bool wasntSure = false;
|
||||
|
@ -523,6 +523,16 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
|
||||
return (high << 16) + low;
|
||||
}
|
||||
|
||||
STRONG_INLINE static ui32 getHighFromSid32(ui32 sid)
|
||||
{
|
||||
return sid >> 16;
|
||||
}
|
||||
|
||||
STRONG_INLINE static ui32 getLowFromSid32(ui32 sid)
|
||||
{
|
||||
return sid & 0x0000FFFF;
|
||||
}
|
||||
|
||||
std::string Description(boost::optional<si32> customValue = {}) const;
|
||||
JsonNode toJsonNode() const;
|
||||
std::string nameForBonus() const; // generate suitable name for bonus - e.g. for storing in json struct
|
||||
@ -996,6 +1006,7 @@ class DLL_LINKAGE AggregateLimiter : public ILimiter
|
||||
protected:
|
||||
std::vector<TLimiterPtr> limiters;
|
||||
virtual const std::string & getAggregator() const = 0;
|
||||
AggregateLimiter(std::vector<TLimiterPtr> limiters = {});
|
||||
public:
|
||||
void add(const TLimiterPtr & limiter);
|
||||
JsonNode toJsonNode() const override;
|
||||
@ -1012,6 +1023,7 @@ class DLL_LINKAGE AllOfLimiter : public AggregateLimiter
|
||||
protected:
|
||||
const std::string & getAggregator() const override;
|
||||
public:
|
||||
AllOfLimiter(std::vector<TLimiterPtr> limiters = {});
|
||||
static const std::string aggregator;
|
||||
EDecision limit(const BonusLimitationContext & context) const override;
|
||||
};
|
||||
@ -1021,6 +1033,7 @@ class DLL_LINKAGE AnyOfLimiter : public AggregateLimiter
|
||||
protected:
|
||||
const std::string & getAggregator() const override;
|
||||
public:
|
||||
AnyOfLimiter(std::vector<TLimiterPtr> limiters = {});
|
||||
static const std::string aggregator;
|
||||
EDecision limit(const BonusLimitationContext & context) const override;
|
||||
};
|
||||
@ -1030,6 +1043,7 @@ class DLL_LINKAGE NoneOfLimiter : public AggregateLimiter
|
||||
protected:
|
||||
const std::string & getAggregator() const override;
|
||||
public:
|
||||
NoneOfLimiter(std::vector<TLimiterPtr> limiters = {});
|
||||
static const std::string aggregator;
|
||||
EDecision limit(const BonusLimitationContext & context) const override;
|
||||
};
|
||||
@ -1127,11 +1141,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CreatureFactionLimiter : public ILimiter //applies only to creatures of given faction
|
||||
class DLL_LINKAGE FactionLimiter : public ILimiter //applies only to creatures of given faction
|
||||
{
|
||||
public:
|
||||
FactionID faction;
|
||||
CreatureFactionLimiter(FactionID faction = FactionID::ANY);
|
||||
FactionLimiter(FactionID faction = FactionID::DEFAULT);
|
||||
|
||||
EDecision limit(const BonusLimitationContext &context) const override;
|
||||
std::string toString() const override;
|
||||
@ -1165,8 +1179,7 @@ class DLL_LINKAGE StackOwnerLimiter : public ILimiter //applies only to creature
|
||||
{
|
||||
public:
|
||||
PlayerColor owner;
|
||||
StackOwnerLimiter();
|
||||
StackOwnerLimiter(const PlayerColor & Owner);
|
||||
StackOwnerLimiter(const PlayerColor & Owner = PlayerColor::NEUTRAL);
|
||||
|
||||
EDecision limit(const BonusLimitationContext &context) const override;
|
||||
|
||||
@ -1181,8 +1194,7 @@ class DLL_LINKAGE OppositeSideLimiter : public ILimiter //applies only to creatu
|
||||
{
|
||||
public:
|
||||
PlayerColor owner;
|
||||
OppositeSideLimiter();
|
||||
OppositeSideLimiter(const PlayerColor & Owner);
|
||||
OppositeSideLimiter(PlayerColor Owner = PlayerColor::CANNOT_DETERMINE);
|
||||
|
||||
EDecision limit(const BonusLimitationContext &context) const override;
|
||||
|
||||
|
@ -749,9 +749,9 @@ std::shared_ptr<ILimiter> JsonUtils::parseLimiter(const JsonNode & limiter)
|
||||
else
|
||||
return std::make_shared<CreatureAlignmentLimiter>(static_cast<EAlignment>(alignment));
|
||||
}
|
||||
else if(limiterType == "CREATURE_FACTION_LIMITER")
|
||||
else if(limiterType == "FACTION_LIMITER")
|
||||
{
|
||||
std::shared_ptr<CreatureFactionLimiter> factionLimiter = std::make_shared<CreatureFactionLimiter>();
|
||||
std::shared_ptr<FactionLimiter> factionLimiter = std::make_shared<FactionLimiter>();
|
||||
VLC->modh->identifiers.requestIdentifier("faction", parameters[0], [=](si32 faction)
|
||||
{
|
||||
factionLimiter->faction = FactionID(faction);
|
||||
|
@ -179,7 +179,7 @@ void registerTypesMapObjects2(Serializer &s)
|
||||
s.template registerType<ILimiter, CCreatureTypeLimiter>();
|
||||
s.template registerType<ILimiter, HasAnotherBonusLimiter>();
|
||||
s.template registerType<ILimiter, CreatureTerrainLimiter>();
|
||||
s.template registerType<ILimiter, CreatureFactionLimiter>();
|
||||
s.template registerType<ILimiter, FactionLimiter>();
|
||||
s.template registerType<ILimiter, CreatureLevelLimiter>();
|
||||
s.template registerType<ILimiter, CreatureAlignmentLimiter>();
|
||||
s.template registerType<ILimiter, RankRangeLimiter>();
|
||||
|
Loading…
Reference in New Issue
Block a user