Browse Source

Dispell fixes

AlexVinS 9 năm trước cách đây
mục cha
commit
7ce33bc07a

+ 9 - 15
lib/spells/BattleSpellMechanics.cpp

@@ -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
 }
 

+ 22 - 14
lib/spells/CDefaultSpellMechanics.cpp

@@ -719,30 +719,38 @@ ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::isImmuneByStack(cons
 	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();
-		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;
-		}
+	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
+{
 	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);

+ 1 - 0
lib/spells/CDefaultSpellMechanics.h

@@ -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;