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

Dispell fixes

This commit is contained in:
AlexVinS 2016-09-29 16:50:33 +03:00
parent d5fb3b62e6
commit 7ce33bc07a
3 changed files with 32 additions and 29 deletions

View File

@ -194,7 +194,7 @@ bool CureMechanics::dispellSelector(const Bonus * b)
ESpellCastProblem::ESpellCastProblem CureMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
{
//Selector method name is ok as cashing string. --AVS
if(!obj->canBeHealed() && !obj->hasBonus(dispellSelector, "CureMechanics::dispellSelector"))
if(!obj->canBeHealed() && !obj->hasBonus(CSelector(DefaultSpellMechanics::dispellSelector).And(CSelector(CureMechanics::dispellSelector)), "CureMechanics::dispellSelector"))
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
return DefaultSpellMechanics::isImmuneByStack(caster, obj);
@ -209,11 +209,10 @@ void DispellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast *
ESpellCastProblem::ESpellCastProblem DispellMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
{
{
//just in case
if(!obj->alive())
return ESpellCastProblem::WRONG_SPELL_TARGET;
}
//just in case
if(!obj->alive())
return ESpellCastProblem::WRONG_SPELL_TARGET;
//DISPELL ignores all immunities, except specific absolute immunity
{
//SPELL_IMMUNITY absolute case
@ -222,16 +221,11 @@ ESpellCastProblem::ESpellCastProblem DispellMechanics::isImmuneByStack(const ISp
if(obj->hasBonus(Selector::typeSubtypeInfo(Bonus::SPELL_IMMUNITY, owner->id.toEnum(), 1), cachingStr.str()))
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
}
{
std::stringstream cachingStr;
cachingStr << "source_" << Bonus::SPELL_EFFECT;
if(obj->hasBonus(Selector::sourceType(Bonus::SPELL_EFFECT), cachingStr.str()))
{
return ESpellCastProblem::OK;
}
}
return ESpellCastProblem::WRONG_SPELL_TARGET;
if(obj->hasBonus(CSelector(DefaultSpellMechanics::dispellSelector), "DefaultSpellMechanics::dispellSelector"))
return ESpellCastProblem::OK;
else
return ESpellCastProblem::WRONG_SPELL_TARGET;
//any other immunities are ignored - do not execute default algorithm
}

View File

@ -719,30 +719,38 @@ ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::isImmuneByStack(cons
return owner->internalIsImmune(caster, obj);
}
bool DefaultSpellMechanics::dispellSelector(const Bonus * bonus)
{
const CSpell * sourceSpell = bonus->sourceSpell();
if(sourceSpell != nullptr)
{
//Special case: DISRUPTING_RAY is "immune" to dispell
//Other even PERMANENT effects can be removed (f.e. BIND)
if(sourceSpell->id == SpellID::DISRUPTING_RAY)
return false;
//Special case:do not remove lifetime marker
if(sourceSpell->id == SpellID::CLONE)
return false;
//stack may have inherited effects
if(sourceSpell->isAdventureSpell())
return false;
return true;
}
//not spell effect
return false;
}
void DefaultSpellMechanics::doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const
{
auto localSelector = [](const Bonus * bonus)
{
const CSpell * sourceSpell = bonus->sourceSpell();
if(sourceSpell != nullptr)
{
//Special case: DISRUPTING_RAY is "immune" to dispell
//Other even PERMANENT effects can be removed (f.e. BIND)
if(sourceSpell->id == SpellID::DISRUPTING_RAY)
return false;
}
return true;
};
for(auto stackID : packet->affectedCres)
{
CStack *s = battle->getStack(stackID);
s->popBonuses(CSelector(localSelector).And(selector));
s->popBonuses(CSelector(dispellSelector).And(selector));
}
}
void DefaultSpellMechanics::handleImmunities(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx, std::vector<const CStack*> & stacks) const
{
//now handle immunities
auto predicate = [&, this](const CStack * s)->bool
{
bool hitDirectly = ctx.ti.alwaysHitDirectly && s->coversPos(ctx.destination);

View File

@ -72,6 +72,7 @@ protected:
virtual std::vector<const CStack *> calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const;
protected:
static bool dispellSelector(const Bonus * bonus);
void doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const;
private:
void cast(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, std::vector <const CStack*> & reflected) const;