1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

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
This commit is contained in:
AlexVinS 2015-09-16 07:33:36 +03:00
parent c050fde3f9
commit 0fecb40039
4 changed files with 78 additions and 55 deletions

View File

@ -14,6 +14,60 @@
#include "../NetPacks.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
void AntimagicMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
{

View File

@ -12,6 +12,14 @@
#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
{
public:
@ -36,10 +44,10 @@ protected:
void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
};
class DLL_LINKAGE CureMechanics : public DefaultSpellMechanics
class DLL_LINKAGE CureMechanics : public HealingSpellMechanics
{
public:
CureMechanics(CSpell * s): DefaultSpellMechanics(s){};
CureMechanics(CSpell * s): HealingSpellMechanics(s){};
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
};
@ -96,10 +104,10 @@ protected:
};
///all rising spells
class DLL_LINKAGE RisingSpellMechanics : public DefaultSpellMechanics
class DLL_LINKAGE RisingSpellMechanics : public HealingSpellMechanics
{
public:
RisingSpellMechanics(CSpell * s): DefaultSpellMechanics(s){};
RisingSpellMechanics(CSpell * s): HealingSpellMechanics(s){};
};

View File

@ -499,7 +499,7 @@ int DefaultSpellMechanics::calculateDuration(const CGHeroInstance * caster, int
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;
{
@ -508,7 +508,14 @@ void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env,
if(parameters.casterHero->hasBonusOfType(Bonus::MAXED_SPELL, owner->id))
effectLevel = 3;
}
return effectLevel;
}
void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
{
int effectLevel = calculateEffectLevel(parameters);
//applying effects
if(owner->isOffensiveSpell())
{
@ -642,54 +649,7 @@ void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env,
if(!sse.stacks.empty())
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

View File

@ -54,9 +54,10 @@ protected:
virtual void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const;
virtual int calculateDuration(const CGHeroInstance * caster, int usedSpellPower) const;
int calculateEffectLevel(const BattleSpellCastParameters & parameters) const;
///actual adventure cast implementation
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;
};