mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
Dispell fixes
This commit is contained in:
parent
d5fb3b62e6
commit
7ce33bc07a
@ -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
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user