mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
vcmi: selector-based target conditions
For now, allows us to define target conditions by selector and even by minimal and maximal value of bonuses. Convert Bonus condition to Selector condition. Allow structures inside TargetCondition struct.
This commit is contained in:
parent
0540e1531d
commit
1e7875cb36
@ -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)
|
||||
{
|
||||
|
@ -51,6 +51,7 @@ public:
|
||||
virtual Object createNormalSpell() const = 0;
|
||||
|
||||
virtual Object createConfigurable(std::string scope, std::string type, std::string identifier) const = 0;
|
||||
virtual Object createFromJsonStruct(const JsonNode & jsonStruct) const = 0;
|
||||
|
||||
virtual Object createReceptiveFeature() const = 0;
|
||||
virtual Object createImmunityNegation() const = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user