mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Unified Dispell-related bonus selectors
This commit is contained in:
		| @@ -1188,16 +1188,6 @@ namespace Selector | ||||
| 		dummy.subtype = subtype; | ||||
| 		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) | ||||
|   | ||||
| @@ -965,12 +965,20 @@ namespace Selector | ||||
| 	CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID); | ||||
| 	CSelector DLL_LINKAGE sourceTypeSel(Bonus::BonusSource source); | ||||
|  | ||||
| 	/** | ||||
| 	 * Selects all bonuses | ||||
| 	 * Usage example: Selector::all.And(<functor>).And(<functor>)...) | ||||
| 	 */ | ||||
| 	extern DLL_LINKAGE CSelector all; | ||||
|  | ||||
| 	/** | ||||
| 	 * Selects nothing | ||||
| 	 * Usage example: Selector::none.Or(<functor>).Or(<functor>)...) | ||||
| 	 */ | ||||
| 	extern DLL_LINKAGE CSelector none; | ||||
|  | ||||
| 	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 positiveSpellEffects(const Bonus *b); | ||||
| } | ||||
|  | ||||
| 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 | ||||
| { | ||||
| 	//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 DefaultSpellMechanics::isImmuneByStack(caster, obj); | ||||
| @@ -213,7 +213,7 @@ ESpellCastProblem::ESpellCastProblem CureMechanics::isImmuneByStack(const ISpell | ||||
| void DispellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const | ||||
| { | ||||
| 	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 | ||||
| @@ -231,7 +231,7 @@ ESpellCastProblem::ESpellCastProblem DispellMechanics::isImmuneByStack(const ISp | ||||
| 			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; | ||||
| 	else | ||||
| 		return ESpellCastProblem::WRONG_SPELL_TARGET; | ||||
|   | ||||
| @@ -745,10 +745,15 @@ void DefaultSpellMechanics::doDispell(BattleInfo * battle, const BattleSpellCast | ||||
| 	for(auto stackID : packet->affectedCres) | ||||
| 	{ | ||||
| 		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 | ||||
| { | ||||
| 	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; | ||||
|  | ||||
| protected: | ||||
| 	static bool dispellSelector(const Bonus * bonus); | ||||
| 	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: | ||||
| 	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 handleResistance(const SpellCastEnvironment * env, SpellCastContext & ctx) const; | ||||
|  | ||||
| 	static bool dispellSelector(const Bonus * bonus); | ||||
|  | ||||
| 	friend class SpellCastContext; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -83,14 +83,24 @@ void DispellHelpfulMechanics::applyBattle(BattleInfo * battle, const BattleSpell | ||||
| { | ||||
| 	DefaultSpellMechanics::applyBattle(battle, packet); | ||||
|  | ||||
| 	doDispell(battle, packet, Selector::positiveSpellEffects); | ||||
| 	doDispell(battle, packet, positiveSpellEffects); | ||||
| } | ||||
|  | ||||
| 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; | ||||
|  | ||||
| 	//use default algorithm only if there is no mechanics-related problem | ||||
| 	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; | ||||
|  | ||||
| 	ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override; | ||||
| private: | ||||
| 	 static bool positiveSpellEffects(const Bonus * b); | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user