mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Unified Dispell-related bonus selectors
This commit is contained in:
parent
96c17505ae
commit
f6bfba0ced
@ -1188,16 +1188,6 @@ namespace Selector
|
|||||||
dummy.subtype = subtype;
|
dummy.subtype = subtype;
|
||||||
return sel(&dummy);
|
return sel(&dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DLL_LINKAGE positiveSpellEffects(const Bonus *b)
|
|
||||||
{
|
|
||||||
if(b->source == Bonus::SPELL_EFFECT)
|
|
||||||
{
|
|
||||||
CSpell *sp = SpellID(b->sid).toSpell();
|
|
||||||
return sp->isPositive();
|
|
||||||
}
|
|
||||||
return false; //not a spell effect
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const CStack * retreiveStackBattle(const CBonusSystemNode *node)
|
const CStack * retreiveStackBattle(const CBonusSystemNode *node)
|
||||||
|
@ -965,12 +965,20 @@ namespace Selector
|
|||||||
CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID);
|
CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID);
|
||||||
CSelector DLL_LINKAGE sourceTypeSel(Bonus::BonusSource source);
|
CSelector DLL_LINKAGE sourceTypeSel(Bonus::BonusSource source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects all bonuses
|
||||||
|
* Usage example: Selector::all.And(<functor>).And(<functor>)...)
|
||||||
|
*/
|
||||||
extern DLL_LINKAGE CSelector all;
|
extern DLL_LINKAGE CSelector all;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects nothing
|
||||||
|
* Usage example: Selector::none.Or(<functor>).Or(<functor>)...)
|
||||||
|
*/
|
||||||
extern DLL_LINKAGE CSelector none;
|
extern DLL_LINKAGE CSelector none;
|
||||||
|
|
||||||
bool DLL_LINKAGE matchesType(const CSelector &sel, Bonus::BonusType type);
|
bool DLL_LINKAGE matchesType(const CSelector &sel, Bonus::BonusType type);
|
||||||
bool DLL_LINKAGE matchesTypeSubtype(const CSelector &sel, Bonus::BonusType type, TBonusSubtype subtype);
|
bool DLL_LINKAGE matchesTypeSubtype(const CSelector &sel, Bonus::BonusType type, TBonusSubtype subtype);
|
||||||
bool DLL_LINKAGE positiveSpellEffects(const Bonus *b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern DLL_LINKAGE const std::map<std::string, Bonus::BonusType> bonusNameMap;
|
extern DLL_LINKAGE const std::map<std::string, Bonus::BonusType> bonusNameMap;
|
||||||
|
@ -203,7 +203,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(CSelector(DefaultSpellMechanics::dispellSelector).And(CSelector(CureMechanics::dispellSelector)), Selector::all, "CureMechanics::dispellSelector"))
|
if(!obj->canBeHealed() && !canDispell(obj, 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);
|
||||||
@ -213,7 +213,7 @@ ESpellCastProblem::ESpellCastProblem CureMechanics::isImmuneByStack(const ISpell
|
|||||||
void DispellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
void DispellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
||||||
{
|
{
|
||||||
DefaultSpellMechanics::applyBattle(battle, packet);
|
DefaultSpellMechanics::applyBattle(battle, packet);
|
||||||
doDispell(battle, packet, Selector::sourceType(Bonus::SPELL_EFFECT));
|
doDispell(battle, packet, Selector::all);
|
||||||
}
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem DispellMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
ESpellCastProblem::ESpellCastProblem DispellMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
||||||
@ -231,7 +231,7 @@ ESpellCastProblem::ESpellCastProblem DispellMechanics::isImmuneByStack(const ISp
|
|||||||
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(obj->hasBonus(CSelector(DefaultSpellMechanics::dispellSelector), Selector::all, "DefaultSpellMechanics::dispellSelector"))
|
if(canDispell(obj, Selector::all, "DefaultSpellMechanics::dispellSelector"))
|
||||||
return ESpellCastProblem::OK;
|
return ESpellCastProblem::OK;
|
||||||
else
|
else
|
||||||
return ESpellCastProblem::WRONG_SPELL_TARGET;
|
return ESpellCastProblem::WRONG_SPELL_TARGET;
|
||||||
|
@ -745,10 +745,15 @@ void DefaultSpellMechanics::doDispell(BattleInfo * battle, const BattleSpellCast
|
|||||||
for(auto stackID : packet->affectedCres)
|
for(auto stackID : packet->affectedCres)
|
||||||
{
|
{
|
||||||
CStack *s = battle->getStack(stackID);
|
CStack *s = battle->getStack(stackID);
|
||||||
s->popBonuses(CSelector(dispellSelector).And(selector));
|
s->popBonuses(selector.And(dispellSelector));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DefaultSpellMechanics::canDispell(const IBonusBearer * obj, const CSelector & selector, const std::string & cachingStr/* = "" */) const
|
||||||
|
{
|
||||||
|
return obj->hasBonus(selector.And(dispellSelector), Selector::all, cachingStr);
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
auto predicate = [&, this](const CStack * s)->bool
|
auto predicate = [&, this](const CStack * s)->bool
|
||||||
|
@ -72,8 +72,8 @@ 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;
|
||||||
|
bool canDispell(const IBonusBearer * obj, const CSelector & selector, const std::string &cachingStr = "") 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;
|
||||||
|
|
||||||
@ -81,6 +81,8 @@ private:
|
|||||||
void handleMagicMirror(const SpellCastEnvironment * env, SpellCastContext & ctx, std::vector <const CStack*> & reflected) const;
|
void handleMagicMirror(const SpellCastEnvironment * env, SpellCastContext & ctx, std::vector <const CStack*> & reflected) const;
|
||||||
void handleResistance(const SpellCastEnvironment * env, SpellCastContext & ctx) const;
|
void handleResistance(const SpellCastEnvironment * env, SpellCastContext & ctx) const;
|
||||||
|
|
||||||
|
static bool dispellSelector(const Bonus * bonus);
|
||||||
|
|
||||||
friend class SpellCastContext;
|
friend class SpellCastContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,14 +83,24 @@ void DispellHelpfulMechanics::applyBattle(BattleInfo * battle, const BattleSpell
|
|||||||
{
|
{
|
||||||
DefaultSpellMechanics::applyBattle(battle, packet);
|
DefaultSpellMechanics::applyBattle(battle, packet);
|
||||||
|
|
||||||
doDispell(battle, packet, Selector::positiveSpellEffects);
|
doDispell(battle, packet, positiveSpellEffects);
|
||||||
}
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem DispellHelpfulMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
ESpellCastProblem::ESpellCastProblem DispellHelpfulMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
||||||
{
|
{
|
||||||
if(!obj->hasBonus(Selector::positiveSpellEffects, Selector::all, "Selector::positiveSpellEffects"))
|
if(!canDispell(obj, positiveSpellEffects, "DispellHelpfulMechanics::positiveSpellEffects"))
|
||||||
return ESpellCastProblem::NO_SPELLS_TO_DISPEL;
|
return ESpellCastProblem::NO_SPELLS_TO_DISPEL;
|
||||||
|
|
||||||
//use default algorithm only if there is no mechanics-related problem
|
//use default algorithm only if there is no mechanics-related problem
|
||||||
return DefaultSpellMechanics::isImmuneByStack(caster,obj);
|
return DefaultSpellMechanics::isImmuneByStack(caster,obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DispellHelpfulMechanics::positiveSpellEffects(const Bonus *b)
|
||||||
|
{
|
||||||
|
if(b->source == Bonus::SPELL_EFFECT)
|
||||||
|
{
|
||||||
|
CSpell *sp = SpellID(b->sid).toSpell();
|
||||||
|
return sp->isPositive();
|
||||||
|
}
|
||||||
|
return false; //not a spell effect
|
||||||
|
}
|
||||||
|
@ -40,4 +40,6 @@ public:
|
|||||||
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
||||||
|
private:
|
||||||
|
static bool positiveSpellEffects(const Bonus * b);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user