1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

vcmi: add UnitOnHex limiter

Bonus will be accepted, if unit stands in listed hexes
This commit is contained in:
Konstantin 2023-03-28 02:14:18 +03:00
parent ffe24627e7
commit 4c08e6a0f9
4 changed files with 61 additions and 1 deletions

View File

@ -76,7 +76,8 @@ const std::map<std::string, TLimiterPtr> bonusLimiterMap =
{"IS_UNDEAD", std::make_shared<HasAnotherBonusLimiter>(Bonus::UNDEAD)},
{"CREATURE_NATIVE_TERRAIN", std::make_shared<CreatureTerrainLimiter>()},
{"CREATURE_FACTION", std::make_shared<CreatureFactionLimiter>()},
{"OPPOSITE_SIDE", std::make_shared<OppositeSideLimiter>()}
{"OPPOSITE_SIDE", std::make_shared<OppositeSideLimiter>()},
{"UNIT_ON_HEXES", std::make_shared<UnitOnHexLimiter>()}
};
const std::map<std::string, TPropagatorPtr> bonusPropagatorMap =
@ -2268,6 +2269,35 @@ JsonNode HasAnotherBonusLimiter::toJsonNode() const
return root;
}
ILimiter::EDecision UnitOnHexLimiter::limit(const BonusLimitationContext &context) const
{
const auto * stack = retrieveStackBattle(&context.node);
if(!stack)
return ILimiter::EDecision::DISCARD;
auto accept = false;
for (const auto & hex : stack->getHexes())
accept |= !!applicableHexes.count(hex);
return accept ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
}
UnitOnHexLimiter::UnitOnHexLimiter(const std::set<BattleHex> & applicableHexes):
applicableHexes(applicableHexes)
{
}
JsonNode UnitOnHexLimiter::toJsonNode() const
{
JsonNode root(JsonNode::JsonType::DATA_STRUCT);
root["type"].String() = "UNIT_ON_HEXES";
for(const auto & hex : applicableHexes)
root["parameters"].Vector().push_back(JsonUtils::intNode(hex));
return root;
}
bool IPropagator::shouldBeAttached(CBonusSystemNode *dest)
{
return false;

View File

@ -11,6 +11,7 @@
#include "GameConstants.h"
#include "JsonNode.h"
#include "battle/BattleHex.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -1191,6 +1192,22 @@ public:
}
};
class DLL_LINKAGE UnitOnHexLimiter : public ILimiter //works only on selected hexes
{
public:
std::set<BattleHex> applicableHexes;
UnitOnHexLimiter(const std::set<BattleHex> & applicableHexes = {});
EDecision limit(const BonusLimitationContext &context) const override;
JsonNode toJsonNode() const override;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<ILimiter&>(*this);
h & applicableHexes;
}
};
namespace Selector
{
extern DLL_LINKAGE CSelectFieldEqual<Bonus::BonusType> & type();

View File

@ -20,6 +20,7 @@
#include "CGeneralTextHandler.h"
#include "JsonDetail.h"
#include "StringConstants.h"
#include "battle/BattleHex.h"
namespace
{
@ -770,6 +771,17 @@ std::shared_ptr<ILimiter> JsonUtils::parseLimiter(const JsonNode & limiter)
}
return terrainLimiter;
}
else if(limiterType == "UNIT_ON_HEXES") {
auto hexLimiter = std::make_shared<UnitOnHexLimiter>();
if(!parameters.empty())
{
for (const auto & parameter: parameters){
if(parameter.isNumber())
hexLimiter->applicableHexes.insert(BattleHex(parameter.Integer()));
}
}
return hexLimiter;
}
else
{
logMod->error("Error: invalid customizable limiter type %s.", limiterType);

View File

@ -183,6 +183,7 @@ void registerTypesMapObjects2(Serializer &s)
s.template registerType<ILimiter, CreatureAlignmentLimiter>();
s.template registerType<ILimiter, RankRangeLimiter>();
s.template registerType<ILimiter, StackOwnerLimiter>();
s.template registerType<ILimiter, UnitOnHexLimiter>();
// s.template registerType<CBonusSystemNode>();
s.template registerType<CBonusSystemNode, CArtifact>();