mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-27 22:49:25 +02:00
Dispell fixes
This commit is contained in:
@@ -194,7 +194,7 @@ bool CureMechanics::dispellSelector(const Bonus * b)
|
|||||||
ESpellCastProblem::ESpellCastProblem CureMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
ESpellCastProblem::ESpellCastProblem CureMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
||||||
{
|
{
|
||||||
//Selector method name is ok as cashing string. --AVS
|
//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 ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
||||||
|
|
||||||
return DefaultSpellMechanics::isImmuneByStack(caster, obj);
|
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
|
ESpellCastProblem::ESpellCastProblem DispellMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
||||||
{
|
{
|
||||||
{
|
|
||||||
//just in case
|
//just in case
|
||||||
if(!obj->alive())
|
if(!obj->alive())
|
||||||
return ESpellCastProblem::WRONG_SPELL_TARGET;
|
return ESpellCastProblem::WRONG_SPELL_TARGET;
|
||||||
}
|
|
||||||
//DISPELL ignores all immunities, except specific absolute immunity
|
//DISPELL ignores all immunities, except specific absolute immunity
|
||||||
{
|
{
|
||||||
//SPELL_IMMUNITY absolute case
|
//SPELL_IMMUNITY absolute case
|
||||||
@@ -222,15 +221,10 @@ ESpellCastProblem::ESpellCastProblem DispellMechanics::isImmuneByStack(const ISp
|
|||||||
if(obj->hasBonus(Selector::typeSubtypeInfo(Bonus::SPELL_IMMUNITY, owner->id.toEnum(), 1), cachingStr.str()))
|
if(obj->hasBonus(Selector::typeSubtypeInfo(Bonus::SPELL_IMMUNITY, owner->id.toEnum(), 1), cachingStr.str()))
|
||||||
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
std::stringstream cachingStr;
|
|
||||||
cachingStr << "source_" << Bonus::SPELL_EFFECT;
|
|
||||||
|
|
||||||
if(obj->hasBonus(Selector::sourceType(Bonus::SPELL_EFFECT), cachingStr.str()))
|
if(obj->hasBonus(CSelector(DefaultSpellMechanics::dispellSelector), "DefaultSpellMechanics::dispellSelector"))
|
||||||
{
|
|
||||||
return ESpellCastProblem::OK;
|
return ESpellCastProblem::OK;
|
||||||
}
|
else
|
||||||
}
|
|
||||||
return ESpellCastProblem::WRONG_SPELL_TARGET;
|
return ESpellCastProblem::WRONG_SPELL_TARGET;
|
||||||
//any other immunities are ignored - do not execute default algorithm
|
//any other immunities are ignored - do not execute default algorithm
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -719,10 +719,8 @@ ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::isImmuneByStack(cons
|
|||||||
return owner->internalIsImmune(caster, obj);
|
return owner->internalIsImmune(caster, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultSpellMechanics::doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const
|
bool DefaultSpellMechanics::dispellSelector(const Bonus * bonus)
|
||||||
{
|
{
|
||||||
auto localSelector = [](const Bonus * bonus)
|
|
||||||
{
|
|
||||||
const CSpell * sourceSpell = bonus->sourceSpell();
|
const CSpell * sourceSpell = bonus->sourceSpell();
|
||||||
if(sourceSpell != nullptr)
|
if(sourceSpell != nullptr)
|
||||||
{
|
{
|
||||||
@@ -730,19 +728,29 @@ void DefaultSpellMechanics::doDispell(BattleInfo * battle, const BattleSpellCast
|
|||||||
//Other even PERMANENT effects can be removed (f.e. BIND)
|
//Other even PERMANENT effects can be removed (f.e. BIND)
|
||||||
if(sourceSpell->id == SpellID::DISRUPTING_RAY)
|
if(sourceSpell->id == SpellID::DISRUPTING_RAY)
|
||||||
return false;
|
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;
|
return true;
|
||||||
};
|
}
|
||||||
|
//not spell effect
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefaultSpellMechanics::doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const
|
||||||
|
{
|
||||||
for(auto stackID : packet->affectedCres)
|
for(auto stackID : packet->affectedCres)
|
||||||
{
|
{
|
||||||
CStack *s = battle->getStack(stackID);
|
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
|
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
|
auto predicate = [&, this](const CStack * s)->bool
|
||||||
{
|
{
|
||||||
bool hitDirectly = ctx.ti.alwaysHitDirectly && s->coversPos(ctx.destination);
|
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;
|
virtual std::vector<const CStack *> calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
static bool dispellSelector(const Bonus * bonus);
|
||||||
void doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const;
|
void doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const;
|
||||||
private:
|
private:
|
||||||
void cast(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, std::vector <const CStack*> & reflected) const;
|
void cast(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, std::vector <const CStack*> & reflected) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user