|
|
@@ -57,22 +57,34 @@ protected:
|
|
|
virtual bool check(const Mechanics * m, const battle::Unit * target) const = 0;
|
|
|
};
|
|
|
|
|
|
-class BonusCondition : public TargetConditionItemBase
|
|
|
+class SelectorCondition : public TargetConditionItemBase
|
|
|
{
|
|
|
public:
|
|
|
- BonusCondition(BonusTypeID type_)
|
|
|
- : type(type_)
|
|
|
+ SelectorCondition(const CSelector & csel):
|
|
|
+ sel(csel)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ SelectorCondition(const CSelector & csel, si32 minVal, si32 maxVal):
|
|
|
+ sel(csel),
|
|
|
+ minVal(minVal),
|
|
|
+ maxVal(maxVal)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
protected:
|
|
|
bool check(const Mechanics * m, const battle::Unit * target) const override
|
|
|
{
|
|
|
- return target->hasBonus(Selector::type()(type));
|
|
|
+ if(target->hasBonus(sel)) {
|
|
|
+ auto b = target->valOfBonuses(sel,"");
|
|
|
+ return b >= minVal && b <= maxVal;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
- BonusTypeID type;
|
|
|
+ CSelector sel;
|
|
|
+ si32 minVal = std::numeric_limits<si32>::min();
|
|
|
+ si32 maxVal = std::numeric_limits<si32>::max();
|
|
|
};
|
|
|
|
|
|
class CreatureCondition : public TargetConditionItemBase
|
|
|
@@ -318,8 +330,16 @@ public:
|
|
|
|
|
|
auto it = bonusNameMap.find(identifier);
|
|
|
if(it != bonusNameMap.end())
|
|
|
- return std::make_shared<BonusCondition>(it->second);
|
|
|
- else
|
|
|
+ return std::make_shared<SelectorCondition>(Selector::type()(it->second));
|
|
|
+
|
|
|
+ auto params = BonusParams(identifier, "", -1);
|
|
|
+ if(params.isConverted)
|
|
|
+ {
|
|
|
+ if(params.valRelevant)
|
|
|
+ return std::make_shared<SelectorCondition>(params.toSelector(), params.val, params.val);
|
|
|
+ return std::make_shared<SelectorCondition>(params.toSelector());
|
|
|
+ }
|
|
|
+
|
|
|
logMod->error("Invalid bonus type %s in spell target condition.", identifier);
|
|
|
}
|
|
|
else if(type == "creature")
|
|
|
@@ -352,6 +372,26 @@ public:
|
|
|
return Object();
|
|
|
}
|
|
|
|
|
|
+ Object createFromJsonStruct(const JsonNode & jsonStruct) const override
|
|
|
+ {
|
|
|
+ auto type = jsonStruct["type"].String();
|
|
|
+ auto parameters = jsonStruct["parameters"];
|
|
|
+ if(type == "selector")
|
|
|
+ {
|
|
|
+ auto minVal = std::numeric_limits<si32>::min();
|
|
|
+ auto maxVal = std::numeric_limits<si32>::max();
|
|
|
+ if(parameters["minVal"].isNumber())
|
|
|
+ minVal = parameters["minVal"].Integer();
|
|
|
+ if(parameters["maxVal"].isNumber())
|
|
|
+ maxVal = parameters["maxVal"].Integer();
|
|
|
+ auto sel = JsonUtils::parseSelector(parameters);
|
|
|
+ return std::make_shared<SelectorCondition>(sel, minVal, maxVal);
|
|
|
+ }
|
|
|
+
|
|
|
+ logMod->error("Invalid type %s in spell target condition.", type);
|
|
|
+ return Object();
|
|
|
+ }
|
|
|
+
|
|
|
Object createReceptiveFeature() const override
|
|
|
{
|
|
|
static std::shared_ptr<TargetConditionItem> condition = std::make_shared<ReceptiveFeatureCondition>();
|
|
|
@@ -463,16 +503,24 @@ void TargetCondition::loadConditions(const JsonNode & source, bool exclusive, bo
|
|
|
isAbsolute = true;
|
|
|
else if(value.String() == "normal")
|
|
|
isAbsolute = false;
|
|
|
+ else if(value.isStruct()) //assume conditions have a new struct format
|
|
|
+ isAbsolute = value["absolute"].Bool();
|
|
|
else
|
|
|
continue;
|
|
|
|
|
|
- std::string scope;
|
|
|
- std::string type;
|
|
|
- std::string identifier;
|
|
|
+ std::shared_ptr<TargetConditionItem> item;
|
|
|
+ if(value.isStruct())
|
|
|
+ item = itemFactory->createFromJsonStruct(value);
|
|
|
+ else
|
|
|
+ {
|
|
|
+ std::string scope;
|
|
|
+ std::string type;
|
|
|
+ std::string identifier;
|
|
|
|
|
|
- CModHandler::parseIdentifier(keyValue.first, scope, type, identifier);
|
|
|
+ CModHandler::parseIdentifier(keyValue.first, scope, type, identifier);
|
|
|
|
|
|
- std::shared_ptr<TargetConditionItem> item = itemFactory->createConfigurable(scope, type, identifier);
|
|
|
+ std::shared_ptr<TargetConditionItem> item = itemFactory->createConfigurable(scope, type, identifier);
|
|
|
+ }
|
|
|
|
|
|
if(item)
|
|
|
{
|