Преглед изворни кода

Magic mirror unified again with normal cast.

AlexVinS пре 9 година
родитељ
комит
838717dfc1
2 измењених фајлова са 99 додато и 109 уклоњено
  1. 89 103
      lib/spells/CDefaultSpellMechanics.cpp
  2. 10 6
      lib/spells/CDefaultSpellMechanics.h

+ 89 - 103
lib/spells/CDefaultSpellMechanics.cpp

@@ -118,19 +118,8 @@ namespace SRSLPraserHelpers
 	}
 }
 
-SpellCastContext::SpellCastContext(const DefaultSpellMechanics * mechanics_, const BattleSpellCastParameters & parameters):
-	mechanics(mechanics_), attackedCres(), sc(), si(), mode(parameters.mode)
-{
-	prepareBattleCast(parameters);
-	logGlobal->debugStream() << "Started spell cast. Spell: " << mechanics->owner->name << "; mode:" << mode;
-}
-
-SpellCastContext::~SpellCastContext()
-{
-	logGlobal->debugStream() << "Finished spell cast. Spell: " << mechanics->owner->name << "; mode:" << mode;
-}
-
-void SpellCastContext::prepareBattleCast(const BattleSpellCastParameters & parameters)
+SpellCastContext::SpellCastContext(const DefaultSpellMechanics * mechanics_, const SpellCastEnvironment * env_, const BattleSpellCastParameters & parameters_):
+	mechanics(mechanics_), env(env_), attackedCres(), sc(), si(), parameters(parameters_), otherHero(nullptr), spellCost(0)
 {
 	sc.side = parameters.casterSide;
 	sc.id = mechanics->owner->id;
@@ -140,6 +129,19 @@ void SpellCastContext::prepareBattleCast(const BattleSpellCastParameters & param
 	sc.castByHero = parameters.mode == ECastingMode::HERO_CASTING;
 	sc.casterStack = (parameters.casterStack ? parameters.casterStack->ID : -1);
 	sc.manaGained = 0;
+
+	//check it there is opponent hero
+	const ui8 otherSide = 1-parameters.casterSide;
+
+	if(parameters.cb->battleHasHero(otherSide))
+		otherHero = parameters.cb->battleGetFightingHero(otherSide);
+
+	logGlobal->debugStream() << "Started spell cast. Spell: " << mechanics->owner->name << "; mode:" << parameters.mode;
+}
+
+SpellCastContext::~SpellCastContext()
+{
+	logGlobal->debugStream() << "Finished spell cast. Spell: " << mechanics->owner->name << "; mode:" << parameters.mode;
 }
 
 void SpellCastContext::addDamageToDisplay(const si32 value)
@@ -152,7 +154,7 @@ void SpellCastContext::setDamageToDisplay(const si32 value)
 	sc.dmgToDisplay = value;
 }
 
-void SpellCastContext::sendCastPacket(const SpellCastEnvironment * env)
+void SpellCastContext::sendCastPacket()
 {
 	for(auto sta : attackedCres)
 	{
@@ -162,6 +164,70 @@ void SpellCastContext::sendCastPacket(const SpellCastEnvironment * env)
 	env->sendAndApply(&sc);
 }
 
+void SpellCastContext::beforeCast()
+{
+	//calculate spell cost
+	if(parameters.mode == ECastingMode::HERO_CASTING)
+	{
+		spellCost = parameters.cb->battleGetSpellCost(mechanics->owner, parameters.casterHero);
+
+		if(nullptr != otherHero) //handle mana channel
+		{
+			int manaChannel = 0;
+			for(const CStack * stack : parameters.cb->battleGetAllStacks(true)) //TODO: shouldn't bonus system handle it somehow?
+			{
+				if(stack->owner == otherHero->tempOwner)
+				{
+					vstd::amax(manaChannel, stack->valOfBonuses(Bonus::MANA_CHANNELING));
+				}
+			}
+			sc.manaGained = (manaChannel * spellCost) / 100;
+		}
+
+		logGlobal->debugStream() << "spellCost: " << spellCost;
+	}
+}
+
+void SpellCastContext::afterCast()
+{
+	sendCastPacket();
+
+	if(parameters.mode == ECastingMode::HERO_CASTING)
+	{
+		//spend mana
+		SetMana sm;
+		sm.absolute = false;
+
+		sm.hid = parameters.casterHero->id;
+		sm.val = -spellCost;
+
+		env->sendAndApply(&sm);
+
+		if(sc.manaGained > 0)
+		{
+			assert(otherHero);
+
+			sm.hid = otherHero->id;
+			sm.val = sc.manaGained;
+			env->sendAndApply(&sm);
+		}
+	}
+	else if (parameters.mode == ECastingMode::CREATURE_ACTIVE_CASTING || parameters.mode == ECastingMode::ENCHANTER_CASTING)
+	{
+		//reduce number of casts remaining
+		assert(parameters.casterStack);
+
+		BattleSetStackProperty ssp;
+		ssp.stackID = parameters.casterStack->ID;
+		ssp.which = BattleSetStackProperty::CASTS;
+		ssp.val = -1;
+		ssp.absolute = false;
+		env->sendAndApply(&ssp);
+	}
+	if(!si.stacks.empty()) //after spellcast info shows
+		env->sendAndApply(&si);
+}
+
 ///DefaultSpellMechanics
 void DefaultSpellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
 {
@@ -196,9 +262,9 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, const B
 		return;
 	}
 
-	std::vector <const CStack*> reflected;//for magic mirror
+	std::vector <const CStack*> reflected, reflectedIgnore;//for magic mirror
 
-	castNormal(env, parameters, reflected);
+	cast(env, parameters, reflected);
 
 	//Magic Mirror effect
 	for(auto & attackedCre : reflected)
@@ -214,7 +280,6 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, const B
 			int targetHex = (*RandomGeneratorUtil::nextItem(mirrorTargets, env->getRandomGenerator()))->position;
 
 			BattleSpellCastParameters mirrorParameters(parameters.cb, attackedCre, owner);
-			mirrorParameters.spellLvl = 0;
 			mirrorParameters.aimToHex(targetHex);
 			mirrorParameters.mode = ECastingMode::MAGIC_MIRROR;
 			mirrorParameters.spellLvl = parameters.spellLvl;
@@ -222,41 +287,16 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, const B
 			mirrorParameters.effectPower = parameters.effectPower;
 			mirrorParameters.effectValue = parameters.effectValue;
 			mirrorParameters.enchantPower = parameters.enchantPower;
-			castMagicMirror(env, mirrorParameters);
+			cast(env, mirrorParameters, reflectedIgnore);
 		}
 	}
 }
 
-void DefaultSpellMechanics::castNormal(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, std::vector <const CStack*> & reflected) const
+void DefaultSpellMechanics::cast(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, std::vector <const CStack*> & reflected) const
 {
-	SpellCastContext ctx(this, parameters);
+	SpellCastContext ctx(this, env, parameters);
 
-	//check it there is opponent hero
-	const ui8 otherSide = 1-parameters.casterSide;
-	const CGHeroInstance * otherHero = nullptr;
-	if(parameters.cb->battleHasHero(otherSide))
-		otherHero = parameters.cb->battleGetFightingHero(otherSide);
-	int spellCost = 0;
-
-	//calculate spell cost
-	if(parameters.mode == ECastingMode::HERO_CASTING)
-	{
-		spellCost = parameters.cb->battleGetSpellCost(owner, parameters.casterHero);
-
-		if(nullptr != otherHero) //handle mana channel
-		{
-			int manaChannel = 0;
-			for(const CStack * stack : parameters.cb->battleGetAllStacks(true)) //TODO: shouldn't bonus system handle it somehow?
-			{
-				if(stack->owner == otherHero->tempOwner)
-				{
-					vstd::amax(manaChannel, stack->valOfBonuses(Bonus::MANA_CHANNELING));
-				}
-			}
-			ctx.sc.manaGained = (manaChannel * spellCost) / 100;
-		}
-	}
-	logGlobal->debugStream() << "spellCost: " << spellCost;
+	ctx.beforeCast();
 
 	ctx.attackedCres = owner->getAffectedStacks(parameters.cb, parameters.mode, parameters.caster, parameters.spellLvl, parameters.getFirstDestinationHex());
 
@@ -264,66 +304,12 @@ void DefaultSpellMechanics::castNormal(const SpellCastEnvironment * env, const B
 
 	handleResistance(env, ctx);
 
-	handleMagicMirror(env, ctx, reflected);
-
-	applyBattleEffects(env, parameters, ctx);
-
-	ctx.sendCastPacket(env);
-
-	if(parameters.mode == ECastingMode::HERO_CASTING)
-	{
-		//spend mana
-		SetMana sm;
-		sm.absolute = false;
-
-		sm.hid = parameters.casterHero->id;
-		sm.val = -spellCost;
-
-		env->sendAndApply(&sm);
-
-		if(ctx.sc.manaGained > 0)
-		{
-			assert(otherHero);
-
-			sm.hid = otherHero->id;
-			sm.val = ctx.sc.manaGained;
-			env->sendAndApply(&sm);
-		}
-	}
-	else if (parameters.mode == ECastingMode::CREATURE_ACTIVE_CASTING || parameters.mode == ECastingMode::ENCHANTER_CASTING)
-	{
-		//reduce number of casts remaining
-		assert(parameters.casterStack);
-
-		BattleSetStackProperty ssp;
-		ssp.stackID = parameters.casterStack->ID;
-		ssp.which = BattleSetStackProperty::CASTS;
-		ssp.val = -1;
-		ssp.absolute = false;
-		env->sendAndApply(&ssp);
-	}
-
-	if(!ctx.si.stacks.empty()) //after spellcast info shows
-		env->sendAndApply(&ctx.si);
-}
-
-void DefaultSpellMechanics::castMagicMirror(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters) const
-{
-	SpellCastContext ctx(this, parameters);
-
-	//calculating affected creatures for all spells
-	ctx.attackedCres = owner->getAffectedStacks(parameters.cb, parameters.mode, parameters.caster, parameters.spellLvl, parameters.getFirstDestinationHex());
-
-	logGlobal->debugStream() << "will affect: " << ctx.attackedCres.size() << " stacks";
-
-	handleResistance(env, ctx);
+	if(parameters.mode != ECastingMode::MAGIC_MIRROR)
+		handleMagicMirror(env, ctx, reflected);
 
 	applyBattleEffects(env, parameters, ctx);
 
-	ctx.sendCastPacket(env);
-
-	if(!ctx.si.stacks.empty()) //after spellcast info shows
-		env->sendAndApply(&ctx.si);
+	ctx.afterCast();
 }
 
 void DefaultSpellMechanics::battleLogSingleTarget(std::vector<std::string> & logLines, const BattleSpellCast * packet,

+ 10 - 6
lib/spells/CDefaultSpellMechanics.h

@@ -19,20 +19,25 @@ class DLL_LINKAGE SpellCastContext
 {
 public:
 	const DefaultSpellMechanics * mechanics;
+	const SpellCastEnvironment * env;
 	std::vector<const CStack *> attackedCres;//must be vector, as in Chain Lightning order matters
 	BattleSpellCast sc;//todo: make private
 	StacksInjured si;
-	ECastingMode::ECastingMode mode;
+	const BattleSpellCastParameters & parameters;
 
-	SpellCastContext(const DefaultSpellMechanics * mechanics_, const BattleSpellCastParameters & parameters);
+	SpellCastContext(const DefaultSpellMechanics * mechanics_, const SpellCastEnvironment * env_, const BattleSpellCastParameters & parameters_);
 	virtual ~SpellCastContext();
 
 	void addDamageToDisplay(const si32 value);
 	void setDamageToDisplay(const si32 value);
 
-	void sendCastPacket(const SpellCastEnvironment * env);
+	void beforeCast();
+	void afterCast();
 private:
-	void prepareBattleCast(const BattleSpellCastParameters & parameters);
+	const CGHeroInstance * otherHero;
+	int spellCost;
+
+	void sendCastPacket();
 };
 
 ///all combat spells
@@ -65,8 +70,7 @@ protected:
 protected:
 	void doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const;
 private:
-	void castNormal(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, std::vector <const CStack*> & reflected) const;
-	void castMagicMirror(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters) const;
+	void cast(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, std::vector <const CStack*> & reflected) const;
 
 	void handleImmunities(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx, std::vector<const CStack *> & stacks) const;
 	void handleMagicMirror(const SpellCastEnvironment * env, SpellCastContext & ctx, std::vector <const CStack*> & reflected) const;