From 3d7435c520712092e770c728e61868bd684a6277 Mon Sep 17 00:00:00 2001 From: AlexVinS Date: Fri, 18 Sep 2015 07:54:28 +0300 Subject: [PATCH] Introduced absolute specific spell immunity. --- config/artifacts.json | 6 ++++-- config/creatures/dungeon.json | 12 ++++++++---- lib/CCreatureHandler.cpp | 8 ++++++++ lib/spells/CSpellHandler.cpp | 25 +++++++++++++++++-------- 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/config/artifacts.json b/config/artifacts.json index e9fd13f55..ac3daabc2 100644 --- a/config/artifacts.json +++ b/config/artifacts.json @@ -1313,7 +1313,8 @@ "subtype" : 35, "type" : "SPELL_IMMUNITY", "val" : 0, - "valueType" : "BASE_NUMBER" + "valueType" : "BASE_NUMBER", + "addInfo" : 1 } ], "index" : 92, @@ -1819,7 +1820,8 @@ "subtype" : "spell.armageddon", "type" : "SPELL_IMMUNITY", "val" : 0, - "valueType" : "BASE_NUMBER" + "valueType" : "BASE_NUMBER", + "addInfo" : 1 }, { "subtype" : "primSkill.attack", diff --git a/config/creatures/dungeon.json b/config/creatures/dungeon.json index 56d9a2809..d7b129754 100644 --- a/config/creatures/dungeon.json +++ b/config/creatures/dungeon.json @@ -9,12 +9,14 @@ "blindImmunity" : { "type" : "SPELL_IMMUNITY", - "subtype" : "spell.blind" + "subtype" : "spell.blind", + "addInfo" : 1 }, "petrifyImmunity" : { "type" : "SPELL_IMMUNITY", - "subtype" : "spell.stoneGaze" + "subtype" : "spell.stoneGaze", + "addInfo" : 1 } }, "upgrades": ["infernalTroglodyte"], @@ -42,12 +44,14 @@ "blindImmunity" : { "type" : "SPELL_IMMUNITY", - "subtype" : "spell.blind" + "subtype" : "spell.blind", + "addInfo" : 1 }, "petrifyImmunity" : { "type" : "SPELL_IMMUNITY", - "subtype" : "spell.stoneGaze" + "subtype" : "spell.stoneGaze", + "addInfo" : 1 } }, "graphics" : diff --git a/lib/CCreatureHandler.cpp b/lib/CCreatureHandler.cpp index 39557185f..2f30d3c48 100644 --- a/lib/CCreatureHandler.cpp +++ b/lib/CCreatureHandler.cpp @@ -853,34 +853,42 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars case 'B': //Blind b.type = Bonus::SPELL_IMMUNITY; b.subtype = SpellID::BLIND; + b.additionalInfo = 0;//normal immunity break; case 'H': //Hypnotize b.type = Bonus::SPELL_IMMUNITY; b.subtype = SpellID::HYPNOTIZE; + b.additionalInfo = 0;//normal immunity break; case 'I': //Implosion b.type = Bonus::SPELL_IMMUNITY; b.subtype = SpellID::IMPLOSION; + b.additionalInfo = 0;//normal immunity break; case 'K': //Berserk b.type = Bonus::SPELL_IMMUNITY; b.subtype = SpellID::BERSERK; + b.additionalInfo = 0;//normal immunity break; case 'M': //Meteor Shower b.type = Bonus::SPELL_IMMUNITY; b.subtype = SpellID::METEOR_SHOWER; + b.additionalInfo = 0;//normal immunity break; case 'N': //dispell beneficial spells b.type = Bonus::SPELL_IMMUNITY; b.subtype = SpellID::DISPEL_HELPFUL_SPELLS; + b.additionalInfo = 0;//normal immunity break; case 'R': //Armageddon b.type = Bonus::SPELL_IMMUNITY; b.subtype = SpellID::ARMAGEDDON; + b.additionalInfo = 0;//normal immunity break; case 'S': //Slow b.type = Bonus::SPELL_IMMUNITY; b.subtype = SpellID::SLOW; + b.additionalInfo = 0;//normal immunity break; case '6': case '7': diff --git a/lib/spells/CSpellHandler.cpp b/lib/spells/CSpellHandler.cpp index 7f7e4cd45..b8a833345 100644 --- a/lib/spells/CSpellHandler.cpp +++ b/lib/spells/CSpellHandler.cpp @@ -419,16 +419,25 @@ ESpellCastProblem::ESpellCastProblem CSpell::internalIsImmune(const ISpellCaster return ESpellCastProblem::STACK_IMMUNE_TO_SPELL; } - //spell-based spell immunity (only ANTIMAGIC in OH3) is treated as absolute - std::stringstream cachingStr; - cachingStr << "type_" << Bonus::LEVEL_SPELL_IMMUNITY << "source_" << Bonus::SPELL_EFFECT; - - TBonusListPtr levelImmunitiesFromSpell = obj->getBonuses(Selector::type(Bonus::LEVEL_SPELL_IMMUNITY).And(Selector::sourceType(Bonus::SPELL_EFFECT)), cachingStr.str()); - - if(levelImmunitiesFromSpell->size() > 0 && levelImmunitiesFromSpell->totalValue() >= level && level) { - return ESpellCastProblem::STACK_IMMUNE_TO_SPELL; + //spell-based spell immunity (only ANTIMAGIC in OH3) is treated as absolute + std::stringstream cachingStr; + cachingStr << "type_" << Bonus::LEVEL_SPELL_IMMUNITY << "source_" << Bonus::SPELL_EFFECT; + + TBonusListPtr levelImmunitiesFromSpell = obj->getBonuses(Selector::type(Bonus::LEVEL_SPELL_IMMUNITY).And(Selector::sourceType(Bonus::SPELL_EFFECT)), cachingStr.str()); + + if(levelImmunitiesFromSpell->size() > 0 && levelImmunitiesFromSpell->totalValue() >= level && level) + { + return ESpellCastProblem::STACK_IMMUNE_TO_SPELL; + } } + { + //SPELL_IMMUNITY absolute case + std::stringstream cachingStr; + cachingStr << "type_" << Bonus::SPELL_IMMUNITY << "subtype_" << id.toEnum() << "addInfo_1"; + if(obj->hasBonus(Selector::typeSubtypeInfo(Bonus::SPELL_IMMUNITY, id.toEnum(), 1), cachingStr.str())) + return ESpellCastProblem::STACK_IMMUNE_TO_SPELL; + } //check receptivity if (isPositive() && obj->hasBonusOfType(Bonus::RECEPTIVE)) //accept all positive spells