mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
spells: rework isMagical()
Now it is a flag of a spell, and not a target condition. This fixes resistance to bind effect
This commit is contained in:
@@ -233,6 +233,10 @@
|
|||||||
"special":{
|
"special":{
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Special spell. Can be given only by Bonus::SPELL"
|
"description": "Special spell. Can be given only by Bonus::SPELL"
|
||||||
|
},
|
||||||
|
"nonMagical":{
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Non-magical ability. Usually used by some creatures. Should not be affected by sorcery and generic magic resistance. School resistances apply. Examples: dendroid bind, efreet fire shield."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -119,6 +119,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
|
"nonMagical" : true,
|
||||||
"indifferent": true
|
"indifferent": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
"flags" : {
|
"flags" : {
|
||||||
"damage": true,
|
"damage": true,
|
||||||
"negative": true,
|
"negative": true,
|
||||||
|
"nonMagical" : true,
|
||||||
"special": true
|
"special": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
@@ -82,10 +83,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
|
"nonMagical" : true,
|
||||||
"indifferent": true
|
"indifferent": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
"nonMagical" : true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rampartMoatTrigger" :
|
"rampartMoatTrigger" :
|
||||||
@@ -123,6 +124,7 @@
|
|||||||
"flags" : {
|
"flags" : {
|
||||||
"damage": true,
|
"damage": true,
|
||||||
"negative": true,
|
"negative": true,
|
||||||
|
"nonMagical" : true,
|
||||||
"special": true
|
"special": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
@@ -171,10 +173,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
|
"nonMagical" : true,
|
||||||
"indifferent": true
|
"indifferent": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
"nonMagical" : true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"towerMoat": {
|
"towerMoat": {
|
||||||
@@ -223,10 +225,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
|
"nonMagical" : true,
|
||||||
"indifferent": true
|
"indifferent": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
"nonMagical" : true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"infernoMoatTrigger" :
|
"infernoMoatTrigger" :
|
||||||
@@ -264,6 +266,7 @@
|
|||||||
"flags" : {
|
"flags" : {
|
||||||
"damage": true,
|
"damage": true,
|
||||||
"negative": true,
|
"negative": true,
|
||||||
|
"nonMagical" : true,
|
||||||
"special": true
|
"special": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
@@ -312,10 +315,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
|
"nonMagical" : true,
|
||||||
"indifferent": true
|
"indifferent": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
"nonMagical" : true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"necropolisMoatTrigger" :
|
"necropolisMoatTrigger" :
|
||||||
@@ -353,6 +356,7 @@
|
|||||||
"flags" : {
|
"flags" : {
|
||||||
"damage": true,
|
"damage": true,
|
||||||
"negative": true,
|
"negative": true,
|
||||||
|
"nonMagical" : true,
|
||||||
"special": true
|
"special": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
@@ -401,10 +405,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
|
"nonMagical" : true,
|
||||||
"indifferent": true
|
"indifferent": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
"nonMagical" : true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dungeonMoatTrigger" :
|
"dungeonMoatTrigger" :
|
||||||
@@ -442,6 +446,7 @@
|
|||||||
"flags" : {
|
"flags" : {
|
||||||
"damage": true,
|
"damage": true,
|
||||||
"negative": true,
|
"negative": true,
|
||||||
|
"nonMagical" : true,
|
||||||
"special": true
|
"special": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
@@ -490,10 +495,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
|
"nonMagical" : true,
|
||||||
"indifferent": true
|
"indifferent": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
"nonMagical" : true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"strongholdMoatTrigger" :
|
"strongholdMoatTrigger" :
|
||||||
@@ -531,6 +536,7 @@
|
|||||||
"flags" : {
|
"flags" : {
|
||||||
"damage": true,
|
"damage": true,
|
||||||
"negative": true,
|
"negative": true,
|
||||||
|
"nonMagical" : true,
|
||||||
"special": true
|
"special": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
@@ -579,10 +585,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
|
"nonMagical" : true,
|
||||||
"indifferent": true
|
"indifferent": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
"nonMagical" : true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fortressMoatTrigger" :
|
"fortressMoatTrigger" :
|
||||||
@@ -620,6 +626,7 @@
|
|||||||
"flags" : {
|
"flags" : {
|
||||||
"damage": true,
|
"damage": true,
|
||||||
"negative": true,
|
"negative": true,
|
||||||
|
"nonMagical" : true,
|
||||||
"special": true
|
"special": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
@@ -668,10 +675,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
|
"nonMagical" : true,
|
||||||
"indifferent": true
|
"indifferent": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
"nonMagical" : true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -93,10 +93,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
|
"nonMagical" : true,
|
||||||
"positive": true
|
"positive": true
|
||||||
},
|
},
|
||||||
"targetCondition" : {
|
"targetCondition" : {
|
||||||
"nonMagical" : true,
|
|
||||||
"noneOf" : {
|
"noneOf" : {
|
||||||
"bonus.SIEGE_WEAPON" : "absolute"
|
"bonus.SIEGE_WEAPON" : "absolute"
|
||||||
}
|
}
|
||||||
@@ -179,10 +179,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
|
"nonMagical" : true,
|
||||||
"indifferent": true
|
"indifferent": true
|
||||||
},
|
|
||||||
"targetCondition" : {
|
|
||||||
"nonMagical" : true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cyclopsShot" : {
|
"cyclopsShot" : {
|
||||||
@@ -227,10 +225,8 @@
|
|||||||
"expert" : {}
|
"expert" : {}
|
||||||
},
|
},
|
||||||
"flags" : {
|
"flags" : {
|
||||||
|
"nonMagical" : true,
|
||||||
"indifferent": true
|
"indifferent": true
|
||||||
},
|
|
||||||
"targetCondition" : {
|
|
||||||
"nonMagical" : true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -41,6 +41,7 @@ public:
|
|||||||
virtual bool isDamage() const = 0;
|
virtual bool isDamage() const = 0;
|
||||||
virtual bool isOffensive() const = 0;
|
virtual bool isOffensive() const = 0;
|
||||||
virtual bool isSpecial() const = 0;
|
virtual bool isSpecial() const = 0;
|
||||||
|
virtual bool isMagical() const = 0; //Should this spell considered as magical effect or as ability (like dendroid's bind)
|
||||||
|
|
||||||
virtual void forEachSchool(const SchoolCallback & cb) const = 0;
|
virtual void forEachSchool(const SchoolCallback & cb) const = 0;
|
||||||
virtual const std::string & getCastSound() const = 0;
|
virtual const std::string & getCastSound() const = 0;
|
||||||
|
@@ -360,7 +360,7 @@ void BattleSpellMechanics::beforeCast(BattleSpellCast & sc, vstd::RNG & rng, con
|
|||||||
|
|
||||||
auto filterResisted = [&, this](const battle::Unit * unit) -> bool
|
auto filterResisted = [&, this](const battle::Unit * unit) -> bool
|
||||||
{
|
{
|
||||||
if(isNegativeSpell())
|
if(isNegativeSpell() && isMagicalEffect())
|
||||||
{
|
{
|
||||||
//magic resistance
|
//magic resistance
|
||||||
const int prob = std::min(unit->magicResistance(), 100); //probability of resistance in %
|
const int prob = std::min(unit->magicResistance(), 100); //probability of resistance in %
|
||||||
|
@@ -97,6 +97,7 @@ CSpell::CSpell():
|
|||||||
damage(false),
|
damage(false),
|
||||||
offensive(false),
|
offensive(false),
|
||||||
special(true),
|
special(true),
|
||||||
|
nonMagical(false),
|
||||||
targetType(spells::AimType::NO_TARGET)
|
targetType(spells::AimType::NO_TARGET)
|
||||||
{
|
{
|
||||||
levels.resize(GameConstants::SPELL_SCHOOL_LEVELS);
|
levels.resize(GameConstants::SPELL_SCHOOL_LEVELS);
|
||||||
@@ -236,6 +237,11 @@ bool CSpell::isCreatureAbility() const
|
|||||||
return creatureAbility;
|
return creatureAbility;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSpell::isMagical() const
|
||||||
|
{
|
||||||
|
return !nonMagical;
|
||||||
|
}
|
||||||
|
|
||||||
bool CSpell::isPositive() const
|
bool CSpell::isPositive() const
|
||||||
{
|
{
|
||||||
return positiveness == POSITIVE;
|
return positiveness == POSITIVE;
|
||||||
@@ -751,6 +757,8 @@ CSpell * CSpellHandler::loadFromJson(const std::string & scope, const JsonNode &
|
|||||||
|
|
||||||
spell->damage = flags["damage"].Bool(); //do this before "offensive"
|
spell->damage = flags["damage"].Bool(); //do this before "offensive"
|
||||||
|
|
||||||
|
spell->nonMagical = flags["nonMagical"].Bool();
|
||||||
|
|
||||||
if(flags["offensive"].Bool())
|
if(flags["offensive"].Bool())
|
||||||
{
|
{
|
||||||
spell->setIsOffensive(true);
|
spell->setIsOffensive(true);
|
||||||
|
@@ -246,6 +246,7 @@ public:
|
|||||||
bool isPositive() const override;
|
bool isPositive() const override;
|
||||||
bool isNegative() const override;
|
bool isNegative() const override;
|
||||||
bool isNeutral() const override;
|
bool isNeutral() const override;
|
||||||
|
bool isMagical() const override;
|
||||||
|
|
||||||
bool isDamage() const override;
|
bool isDamage() const override;
|
||||||
bool isOffensive() const override;
|
bool isOffensive() const override;
|
||||||
@@ -297,6 +298,7 @@ public:
|
|||||||
h & levels;
|
h & levels;
|
||||||
h & school;
|
h & school;
|
||||||
h & animationInfo;
|
h & animationInfo;
|
||||||
|
h & nonMagical;
|
||||||
}
|
}
|
||||||
friend class CSpellHandler;
|
friend class CSpellHandler;
|
||||||
friend class Graphics;
|
friend class Graphics;
|
||||||
@@ -338,6 +340,7 @@ private:
|
|||||||
bool damage;
|
bool damage;
|
||||||
bool offensive;
|
bool offensive;
|
||||||
bool special;
|
bool special;
|
||||||
|
bool nonMagical; //For creature abilities like bind
|
||||||
|
|
||||||
std::string attributes; //reference only attributes //todo: remove or include in configuration format, currently unused
|
std::string attributes; //reference only attributes //todo: remove or include in configuration format, currently unused
|
||||||
|
|
||||||
|
@@ -617,6 +617,11 @@ bool BaseMechanics::isPositiveSpell() const
|
|||||||
return owner->isPositive();
|
return owner->isPositive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BaseMechanics::isMagicalEffect() const
|
||||||
|
{
|
||||||
|
return owner->isMagical();
|
||||||
|
}
|
||||||
|
|
||||||
int64_t BaseMechanics::adjustEffectValue(const battle::Unit * target) const
|
int64_t BaseMechanics::adjustEffectValue(const battle::Unit * target) const
|
||||||
{
|
{
|
||||||
return owner->adjustRawDamage(caster, target, getEffectValue());
|
return owner->adjustRawDamage(caster, target, getEffectValue());
|
||||||
|
@@ -228,6 +228,7 @@ public:
|
|||||||
|
|
||||||
virtual bool isNegativeSpell() const = 0;
|
virtual bool isNegativeSpell() const = 0;
|
||||||
virtual bool isPositiveSpell() const = 0;
|
virtual bool isPositiveSpell() const = 0;
|
||||||
|
virtual bool isMagicalEffect() const = 0;
|
||||||
|
|
||||||
virtual int64_t adjustEffectValue(const battle::Unit * target) const = 0;
|
virtual int64_t adjustEffectValue(const battle::Unit * target) const = 0;
|
||||||
virtual int64_t applySpellBonus(int64_t value, const battle::Unit * target) const = 0;
|
virtual int64_t applySpellBonus(int64_t value, const battle::Unit * target) const = 0;
|
||||||
@@ -288,6 +289,7 @@ public:
|
|||||||
|
|
||||||
bool isNegativeSpell() const override;
|
bool isNegativeSpell() const override;
|
||||||
bool isPositiveSpell() const override;
|
bool isPositiveSpell() const override;
|
||||||
|
bool isMagicalEffect() const override;
|
||||||
|
|
||||||
int64_t adjustEffectValue(const battle::Unit * target) const override;
|
int64_t adjustEffectValue(const battle::Unit * target) const override;
|
||||||
int64_t applySpellBonus(int64_t value, const battle::Unit * target) const override;
|
int64_t applySpellBonus(int64_t value, const battle::Unit * target) const override;
|
||||||
|
@@ -114,6 +114,10 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
bool check(const Mechanics * m, const battle::Unit * target) const override
|
bool check(const Mechanics * m, const battle::Unit * target) const override
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if(!m->isMagicalEffect()) //Always pass on non-magical
|
||||||
|
return true;
|
||||||
|
|
||||||
std::stringstream cachingStr;
|
std::stringstream cachingStr;
|
||||||
cachingStr << "type_" << Bonus::LEVEL_SPELL_IMMUNITY << "addInfo_1";
|
cachingStr << "type_" << Bonus::LEVEL_SPELL_IMMUNITY << "addInfo_1";
|
||||||
|
|
||||||
@@ -189,6 +193,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
bool check(const Mechanics * m, const battle::Unit * target) const override
|
bool check(const Mechanics * m, const battle::Unit * target) const override
|
||||||
{
|
{
|
||||||
|
if(!m->isMagicalEffect()) //Always pass on non-magical
|
||||||
|
return true;
|
||||||
TConstBonusListPtr levelImmunities = target->getBonuses(Selector::type()(Bonus::LEVEL_SPELL_IMMUNITY));
|
TConstBonusListPtr levelImmunities = target->getBonuses(Selector::type()(Bonus::LEVEL_SPELL_IMMUNITY));
|
||||||
return levelImmunities->size() == 0 ||
|
return levelImmunities->size() == 0 ||
|
||||||
levelImmunities->totalValue() < m->getSpellLevel() ||
|
levelImmunities->totalValue() < m->getSpellLevel() ||
|
||||||
@@ -426,7 +432,6 @@ bool TargetCondition::isReceptive(const Mechanics * m, const battle::Unit * targ
|
|||||||
|
|
||||||
void TargetCondition::serializeJson(JsonSerializeFormat & handler, const ItemFactory * itemFactory)
|
void TargetCondition::serializeJson(JsonSerializeFormat & handler, const ItemFactory * itemFactory)
|
||||||
{
|
{
|
||||||
bool isNonMagical = false;
|
|
||||||
if(handler.saving)
|
if(handler.saving)
|
||||||
{
|
{
|
||||||
logGlobal->error("Spell target condition saving is not supported");
|
logGlobal->error("Spell target condition saving is not supported");
|
||||||
@@ -438,17 +443,12 @@ void TargetCondition::serializeJson(JsonSerializeFormat & handler, const ItemFac
|
|||||||
negation.clear();
|
negation.clear();
|
||||||
|
|
||||||
absolute.push_back(itemFactory->createAbsoluteSpell());
|
absolute.push_back(itemFactory->createAbsoluteSpell());
|
||||||
|
|
||||||
handler.serializeBool("nonMagical", isNonMagical);
|
|
||||||
if(!isNonMagical)
|
|
||||||
{
|
|
||||||
absolute.push_back(itemFactory->createAbsoluteLevel());
|
absolute.push_back(itemFactory->createAbsoluteLevel());
|
||||||
normal.push_back(itemFactory->createElemental());
|
normal.push_back(itemFactory->createElemental());
|
||||||
normal.push_back(itemFactory->createNormalLevel());
|
normal.push_back(itemFactory->createNormalLevel());
|
||||||
normal.push_back(itemFactory->createNormalSpell());
|
normal.push_back(itemFactory->createNormalSpell());
|
||||||
negation.push_back(itemFactory->createReceptiveFeature());
|
negation.push_back(itemFactory->createReceptiveFeature());
|
||||||
negation.push_back(itemFactory->createImmunityNegation());
|
negation.push_back(itemFactory->createImmunityNegation());
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
auto anyOf = handler.enterStruct("anyOf");
|
auto anyOf = handler.enterStruct("anyOf");
|
||||||
|
Reference in New Issue
Block a user