diff --git a/lib/BattleState.cpp b/lib/BattleState.cpp index cc794ed13..b6aa4b322 100644 --- a/lib/BattleState.cpp +++ b/lib/BattleState.cpp @@ -1170,6 +1170,17 @@ bool CStack::canBeHealed() const && !hasBonusOfType(Bonus::SIEGE_WEAPON); } +ui32 CStack::calculateHealedHealthPoints(ui32 toHeal, const bool resurrect) const +{ + if(!resurrect && !alive()) + { + logGlobal->warnStream() <<"Attempt to heal corpse detected."; + return 0; + } + + return std::min(toHeal, MaxHealth() - firstHPleft + (resurrect ? baseAmount * MaxHealth() : 0)); +} + ui8 CStack::getSpellSchoolLevel(const CSpell * spell, int * outSelectedSchool) const { int skill = valOfBonuses(Selector::typeSubtype(Bonus::SPELLCASTER, spell->id)); diff --git a/lib/BattleState.h b/lib/BattleState.h index 6dc5bc1a6..512d03e46 100644 --- a/lib/BattleState.h +++ b/lib/BattleState.h @@ -203,6 +203,8 @@ public: bool waited(int turn = 0) const; bool canMove(int turn = 0) const; //if stack can move bool canBeHealed() const; //for first aid tent - only harmed stacks that are not war machines + ///returns actual heal value based on internal state + ui32 calculateHealedHealthPoints(ui32 toHeal, const bool resurrect) const; ui32 level() const; si32 magicResistance() const override; //include aura of resistance static void stackEffectToFeature(std::vector & sf, const Bonus & sse); diff --git a/lib/spells/CDefaultSpellMechanics.cpp b/lib/spells/CDefaultSpellMechanics.cpp index 55ce59abc..3e6ddf138 100644 --- a/lib/spells/CDefaultSpellMechanics.cpp +++ b/lib/spells/CDefaultSpellMechanics.cpp @@ -517,10 +517,9 @@ ui32 DefaultSpellMechanics::calculateHealedHP(const CGHeroInstance* caster, cons else healedHealth = spellPowerSkill * owner->power + levelPower; //??? healedHealth = caster->getSpellBonus(owner, healedHealth, stack); - return std::min(healedHealth, stack->MaxHealth() - stack->firstHPleft + (owner->isRisingSpell() ? stack->baseAmount * stack->MaxHealth() : 0)); + return stack->calculateHealedHealthPoints(healedHealth, owner->isRisingSpell()); } - void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const { int effectLevel = parameters.spellLvl; @@ -675,7 +674,10 @@ void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env, if(unitSpellPower) hpGained = parameters.casterStack->count * unitSpellPower; //Archangel else //Faerie Dragon-like effect - unused so far + { parameters.usedSpellPower = parameters.casterStack->valOfBonuses(Bonus::CREATURE_SPELL_POWER) * parameters.casterStack->count / 100; + hpGained = parameters.usedSpellPower * owner->power + owner->getPower(effectLevel); + } } StacksHealedOrResurrected shr; shr.lifeDrain = false; @@ -687,21 +689,11 @@ void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env, if (parameters.casterStack) //casted by creature { const bool resurrect = owner->isRisingSpell(); - if (hpGained) - { - //archangel - hi.healedHP = std::min(hpGained, attackedCre->MaxHealth() - attackedCre->firstHPleft + (resurrect ? attackedCre->baseAmount * attackedCre->MaxHealth() : 0)); - } - else - { - //any typical spell (commander's cure or animate dead) - int healedHealth = parameters.usedSpellPower * owner->power + owner->getPower(effectLevel); - hi.healedHP = std::min(healedHealth, attackedCre->MaxHealth() - attackedCre->firstHPleft + (resurrect ? attackedCre->baseAmount * attackedCre->MaxHealth() : 0)); - } + hi.healedHP = attackedCre->calculateHealedHealthPoints(hpGained, resurrect); } else hi.healedHP = calculateHealedHP(parameters.casterHero, attackedCre, parameters.selectedStack); //Casted by hero - hi.lowLevelResurrection = (effectLevel <= 1) && (owner->id != SpellID::ANIMATE_DEAD); + hi.lowLevelResurrection = (effectLevel <= 1) && (owner->id == SpellID::RESURRECTION); shr.healedStacks.push_back(hi); } if(!shr.healedStacks.empty())