AlexVinS 9 gadi atpakaļ
vecāks
revīzija
1ce4675df6

+ 8 - 2
lib/spells/CDefaultSpellMechanics.cpp

@@ -262,13 +262,19 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, const B
 		return;
 	}
 
-	std::vector <const CStack*> reflected, reflectedIgnore;//for magic mirror
+	std::vector <const CStack*> reflected;//for magic mirror
 
 	cast(env, parameters, reflected);
 
 	//Magic Mirror effect
 	for(auto & attackedCre : reflected)
 	{
+		if(parameters.mode == ECastingMode::MAGIC_MIRROR)
+		{
+			logGlobal->error("Magic mirror recurrence!");
+			return;
+		}
+
 		TStacks mirrorTargets = parameters.cb->battleGetStacksIf([this, parameters](const CStack * battleStack)
 		{
 			//Get all enemy stacks. Magic mirror can reflect to immune creature (with no effect)
@@ -287,7 +293,7 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, const B
 			mirrorParameters.effectPower = parameters.effectPower;
 			mirrorParameters.effectValue = parameters.effectValue;
 			mirrorParameters.enchantPower = parameters.enchantPower;
-			cast(env, mirrorParameters, reflectedIgnore);
+			mirrorParameters.cast(env);
 		}
 	}
 }

+ 18 - 17
lib/spells/ISpellMechanics.cpp

@@ -34,15 +34,26 @@ BattleSpellCastParameters::Destination::Destination(const BattleHex & destinatio
 
 }
 
-BattleSpellCastParameters::BattleSpellCastParameters(const BattleInfo * cb, const ISpellCaster * caster, const CSpell * spell)
-	: cb(cb), caster(caster), casterColor(caster->getOwner()), casterSide(cb->whatSide(casterColor)),
+BattleSpellCastParameters::BattleSpellCastParameters(const BattleInfo * cb, const ISpellCaster * caster, const CSpell * spell_)
+	: spell(spell_), cb(cb), caster(caster), casterColor(caster->getOwner()), casterSide(cb->whatSide(casterColor)),
 	casterHero(nullptr),
 	mode(ECastingMode::HERO_CASTING), casterStack(nullptr),
 	spellLvl(-1),  effectLevel(-1), effectPower(0), enchantPower(0), effectValue(0)
 {
 	casterStack = dynamic_cast<const CStack *>(caster);
 	casterHero = dynamic_cast<const CGHeroInstance *>(caster);
-	prepare(spell);
+
+	spellLvl = caster->getSpellSchoolLevel(spell);
+	effectLevel = caster->getEffectLevel(spell);
+	effectPower = caster->getEffectPower(spell);
+	effectValue = caster->getEffectValue(spell);
+	enchantPower = caster->getEnchantPower(spell);
+
+	vstd::amax(spellLvl, 0);
+	vstd::amax(effectLevel, 0);
+	vstd::amax(enchantPower, 0);
+	vstd::amax(enchantPower, 0);
+	vstd::amax(effectValue, 0);
 }
 
 void BattleSpellCastParameters::aimToHex(const BattleHex& destination)
@@ -58,24 +69,14 @@ void BattleSpellCastParameters::aimToStack(const CStack * destination)
 		destinations.push_back(Destination(destination));
 }
 
-BattleHex BattleSpellCastParameters::getFirstDestinationHex() const
+void BattleSpellCastParameters::cast(const SpellCastEnvironment * env)
 {
-	return destinations.at(0).hexValue;
+	spell->battleCast(env, *this);
 }
 
-void BattleSpellCastParameters::prepare(const CSpell * spell)
+BattleHex BattleSpellCastParameters::getFirstDestinationHex() const
 {
-	spellLvl = caster->getSpellSchoolLevel(spell);
-	effectLevel = caster->getEffectLevel(spell);
-	effectPower = caster->getEffectPower(spell);
-	effectValue = caster->getEffectValue(spell);
-	enchantPower = caster->getEnchantPower(spell);
-
-	vstd::amax(spellLvl, 0);
-	vstd::amax(effectLevel, 0);
-	vstd::amax(enchantPower, 0);
-	vstd::amax(enchantPower, 0);
-	vstd::amax(effectValue, 0);
+	return destinations.at(0).hexValue;
 }
 
 ///ISpellMechanics

+ 5 - 3
lib/spells/ISpellMechanics.h

@@ -45,11 +45,15 @@ public:
 		const BattleHex hexValue;
 	};
 
-	BattleSpellCastParameters(const BattleInfo * cb, const ISpellCaster * caster, const CSpell * spell);
+	BattleSpellCastParameters(const BattleInfo * cb, const ISpellCaster * caster, const CSpell * spell_);
 	void aimToHex(const BattleHex & destination);
 	void aimToStack(const CStack * destination);
+
+	void cast(const SpellCastEnvironment * env);
+
 	BattleHex getFirstDestinationHex() const;
 
+	const CSpell * spell;
 	const BattleInfo * cb;
 	const ISpellCaster * caster;
 	const PlayerColor casterColor;
@@ -71,8 +75,6 @@ public:
 	int enchantPower;
 	///for Archangel-like casting
 	int effectValue;
-private:
-	void prepare(const CSpell * spell);
 };
 
 struct DLL_LINKAGE SpellTargetingContext

+ 6 - 6
server/CGameHandler.cpp

@@ -4171,7 +4171,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 				parameters.effectLevel = parameters.spellLvl;
 				parameters.mode = ECastingMode::CREATURE_ACTIVE_CASTING;
 				parameters.aimToHex(destination);//todo: allow multiple destinations
-				spell->battleCast(spellEnv, parameters);
+				parameters.cast(spellEnv);
 			}
 			sendAndApply(&end_action);
 			break;
@@ -4382,7 +4382,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
 			StartAction start_action(ba);
 			sendAndApply(&start_action); //start spell casting
 
-			s->battleCast(spellEnv, parameters);
+			parameters.cast(spellEnv);
 
 			sendAndApply(&end_action);
 			if( !gs->curB->battleGetStackByID(gs->curB->activeStack))
@@ -4523,7 +4523,7 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
 					parameters.aimToHex(BattleHex::INVALID);
 					parameters.mode = ECastingMode::ENCHANTER_CASTING;
 
-					spell->battleCast(spellEnv, parameters);
+					parameters.cast(spellEnv);
 
 					//todo: move to mechanics
 					BattleSetStackProperty ssp;
@@ -5233,7 +5233,7 @@ void CGameHandler::attackCasting(const BattleAttack & bat, Bonus::BonusType atta
 				parameters.aimToStack(oneOfAttacked);
 				parameters.mode = ECastingMode::AFTER_ATTACK_CASTING;
 
-				spell->battleCast(spellEnv, parameters);
+				parameters.cast(spellEnv);
 			}
 		}
 	}
@@ -5262,7 +5262,7 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
 		parameters.effectPower = power;
 		parameters.mode = ECastingMode::AFTER_ATTACK_CASTING;
 
-		spell->battleCast(this->spellEnv, parameters);
+		parameters.cast(spellEnv);
 	};
 
 	attackCasting(bat, Bonus::SPELL_AFTER_ATTACK, attacker);
@@ -5568,7 +5568,7 @@ void CGameHandler::runBattle()
 				parameters.aimToHex(BattleHex::INVALID);
 				parameters.mode = ECastingMode::PASSIVE_CASTING;
 				parameters.enchantPower = b->val;
-				spell->battleCast(spellEnv, parameters);
+				parameters.cast(spellEnv);
 			}
 		}
 	}