浏览代码

Extract HealingSpellMechanics
* healing effects are too specific to be allowed for any spell
* mixing heal with direct damage does not make sence
* mixing heal with timed effect can be easy allowed if needed

AlexVinS 10 年之前
父节点
当前提交
0fecb40039

+ 54 - 0
lib/spells/BattleSpellMechanics.cpp

@@ -14,6 +14,60 @@
 #include "../NetPacks.h"
 #include "../NetPacks.h"
 #include "../BattleState.h"
 #include "../BattleState.h"
 
 
+///HealingSpellMechanics
+void HealingSpellMechanics::applyBattleEffects(const SpellCastEnvironment* env, BattleSpellCastParameters& parameters, SpellCastContext& ctx) const
+{
+	int effectLevel = calculateEffectLevel(parameters);
+	int hpGained = 0;
+	
+	if(owner->id == SpellID::SACRIFICE)
+	{
+		if(nullptr == parameters.selectedStack)
+			env->complain("No stack to sacrifice.");
+		else
+			hpGained = (parameters.usedSpellPower + parameters.selectedStack->MaxHealth() + owner->getPower(effectLevel)) * parameters.selectedStack->count;
+	}
+	else if(parameters.casterStack)
+	{
+		int unitSpellPower = parameters.casterStack->valOfBonuses(Bonus::SPECIFIC_SPELL_POWER, owner->id.toEnum());
+		if(unitSpellPower)
+			hpGained = parameters.casterStack->count * unitSpellPower; //Archangel
+		else //Faerie Dragon-like effect - commanders(?)
+		{			
+			parameters.usedSpellPower = parameters.casterStack->valOfBonuses(Bonus::CREATURE_SPELL_POWER) * parameters.casterStack->count / 100;
+			hpGained = parameters.usedSpellPower * owner->power + owner->getPower(effectLevel);
+		}
+	}
+	else
+	{
+		hpGained = parameters.usedSpellPower * owner->power + owner->getPower(effectLevel); //???
+	}
+	StacksHealedOrResurrected shr;
+	shr.lifeDrain = false;
+	shr.tentHealing = false;
+
+	const bool resurrect = owner->isRisingSpell();
+	for(auto & attackedCre : ctx.attackedCres)
+	{
+		StacksHealedOrResurrected::HealInfo hi;
+		hi.stackID = (attackedCre)->ID;
+		if (parameters.casterStack) //casted by creature
+		{
+			hi.healedHP = attackedCre->calculateHealedHealthPoints(hpGained, resurrect);
+		}
+		else
+		{
+			int stackHPgained = parameters.casterHero->getSpellBonus(owner, hpGained, attackedCre); 
+			hi.healedHP = attackedCre->calculateHealedHealthPoints(stackHPgained, resurrect);		
+		}
+			
+		hi.lowLevelResurrection = (effectLevel <= 1) && (owner->id == SpellID::RESURRECTION);
+		shr.healedStacks.push_back(hi);
+	}
+	if(!shr.healedStacks.empty())
+		env->sendAndApply(&shr);	
+}
+
 ///AntimagicMechanics
 ///AntimagicMechanics
 void AntimagicMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
 void AntimagicMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
 {
 {

+ 12 - 4
lib/spells/BattleSpellMechanics.h

@@ -12,6 +12,14 @@
 
 
 #include "CDefaultSpellMechanics.h"
 #include "CDefaultSpellMechanics.h"
 
 
+class DLL_LINKAGE HealingSpellMechanics : public DefaultSpellMechanics
+{
+public:
+	HealingSpellMechanics(CSpell * s): DefaultSpellMechanics(s){};	
+protected:
+	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
+};
+
 class DLL_LINKAGE AntimagicMechanics : public DefaultSpellMechanics
 class DLL_LINKAGE AntimagicMechanics : public DefaultSpellMechanics
 {
 {
 public:
 public:
@@ -36,10 +44,10 @@ protected:
 	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
 	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
 };
 };
 
 
-class DLL_LINKAGE CureMechanics : public DefaultSpellMechanics
+class DLL_LINKAGE CureMechanics : public HealingSpellMechanics
 {
 {
 public:
 public:
-	CureMechanics(CSpell * s): DefaultSpellMechanics(s){};
+	CureMechanics(CSpell * s): HealingSpellMechanics(s){};
 
 
 	void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
 	void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
 };
 };
@@ -96,10 +104,10 @@ protected:
 };
 };
 
 
 ///all rising spells
 ///all rising spells
-class DLL_LINKAGE RisingSpellMechanics : public DefaultSpellMechanics
+class DLL_LINKAGE RisingSpellMechanics : public HealingSpellMechanics
 {
 {
 public:
 public:
-	RisingSpellMechanics(CSpell * s): DefaultSpellMechanics(s){};
+	RisingSpellMechanics(CSpell * s): HealingSpellMechanics(s){};
 
 
 };
 };
 
 

+ 9 - 49
lib/spells/CDefaultSpellMechanics.cpp

@@ -499,7 +499,7 @@ int DefaultSpellMechanics::calculateDuration(const CGHeroInstance * caster, int
 		return caster->getPrimSkillLevel(PrimarySkill::SPELL_POWER) + caster->valOfBonuses(Bonus::SPELL_DURATION);
 		return caster->getPrimSkillLevel(PrimarySkill::SPELL_POWER) + caster->valOfBonuses(Bonus::SPELL_DURATION);
 }
 }
 
 
-void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
+int DefaultSpellMechanics::calculateEffectLevel(const BattleSpellCastParameters& parameters) const
 {
 {
 	int effectLevel = parameters.spellLvl;
 	int effectLevel = parameters.spellLvl;
 	{
 	{
@@ -508,7 +508,14 @@ void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env,
 			if(parameters.casterHero->hasBonusOfType(Bonus::MAXED_SPELL, owner->id))
 			if(parameters.casterHero->hasBonusOfType(Bonus::MAXED_SPELL, owner->id))
 				effectLevel = 3;
 				effectLevel = 3;
 	}
 	}
+	
+	return effectLevel;	
+}
+
 
 
+void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
+{
+	int effectLevel = calculateEffectLevel(parameters);
 	//applying effects
 	//applying effects
 	if(owner->isOffensiveSpell())
 	if(owner->isOffensiveSpell())
 	{
 	{
@@ -642,54 +649,7 @@ void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env,
 		if(!sse.stacks.empty())
 		if(!sse.stacks.empty())
 			env->sendAndApply(&sse);
 			env->sendAndApply(&sse);
 
 
-	}
-
-	if(owner->isHealingSpell())
-	{
-		int hpGained = 0;
-		if(parameters.casterStack)
-		{
-			int unitSpellPower = parameters.casterStack->valOfBonuses(Bonus::SPECIFIC_SPELL_POWER, owner->id.toEnum());
-			if(unitSpellPower)
-				hpGained = parameters.casterStack->count * unitSpellPower; //Archangel
-			else //Faerie Dragon-like effect - commanders(?)
-			{			
-				parameters.usedSpellPower = parameters.casterStack->valOfBonuses(Bonus::CREATURE_SPELL_POWER) * parameters.casterStack->count / 100;
-				hpGained = parameters.usedSpellPower * owner->power + owner->getPower(effectLevel);
-			}
-		}
-		else
-		{
-			if (owner->id == SpellID::SACRIFICE && parameters.selectedStack)
-				hpGained = (parameters.usedSpellPower + parameters.selectedStack->MaxHealth() + owner->getPower(effectLevel)) * parameters.selectedStack->count;
-			else
-				hpGained = parameters.usedSpellPower * owner->power + owner->getPower(effectLevel); //???
-		}
-		StacksHealedOrResurrected shr;
-		shr.lifeDrain = false;
-		shr.tentHealing = false;
-
-		const bool resurrect = owner->isRisingSpell();
-		for(auto & attackedCre : ctx.attackedCres)
-		{
-			StacksHealedOrResurrected::HealInfo hi;
-			hi.stackID = (attackedCre)->ID;
-			if (parameters.casterStack) //casted by creature
-			{
-				hi.healedHP = attackedCre->calculateHealedHealthPoints(hpGained, resurrect);
-			}
-			else
-			{
-				int stackHPgained = parameters.casterHero->getSpellBonus(owner, hpGained, attackedCre); 
-				hi.healedHP = attackedCre->calculateHealedHealthPoints(stackHPgained, resurrect);		
-			}
-				
-			hi.lowLevelResurrection = (effectLevel <= 1) && (owner->id == SpellID::RESURRECTION);
-			shr.healedStacks.push_back(hi);
-		}
-		if(!shr.healedStacks.empty())
-			env->sendAndApply(&shr);
-	}
+	}	
 }
 }
 
 
 std::vector<BattleHex> DefaultSpellMechanics::rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes) const
 std::vector<BattleHex> DefaultSpellMechanics::rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes) const

+ 3 - 2
lib/spells/CDefaultSpellMechanics.h

@@ -54,9 +54,10 @@ protected:
 	virtual void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const;
 	virtual void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const;
 
 
 	virtual int calculateDuration(const CGHeroInstance * caster, int usedSpellPower) const;
 	virtual int calculateDuration(const CGHeroInstance * caster, int usedSpellPower) const;
-
+	int calculateEffectLevel(const BattleSpellCastParameters & parameters) const;
+	
 	///actual adventure cast implementation
 	///actual adventure cast implementation
 	virtual ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const;
 	virtual ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const;
 	
 	
-	void doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const;
+	void doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const;	
 };
 };