diff --git a/lib/GameConstants.h b/lib/GameConstants.h index 620f32b95..cd681bfc0 100644 --- a/lib/GameConstants.h +++ b/lib/GameConstants.h @@ -414,7 +414,8 @@ namespace ECastingMode { HERO_CASTING, AFTER_ATTACK_CASTING, //also includes cast before attack MAGIC_MIRROR, CREATURE_ACTIVE_CASTING, ENCHANTER_CASTING, - SPELL_LIKE_ATTACK + SPELL_LIKE_ATTACK, + PASSIVE_CASTING//f.e. opening battle spells }; } diff --git a/lib/spells/BattleSpellMechanics.cpp b/lib/spells/BattleSpellMechanics.cpp index 294093525..a8a4eccf2 100644 --- a/lib/spells/BattleSpellMechanics.cpp +++ b/lib/spells/BattleSpellMechanics.cpp @@ -27,10 +27,8 @@ void HealingSpellMechanics::applyBattleEffects(const SpellCastEnvironment* env, for(auto & attackedCre : ctx.attackedCres) { StacksHealedOrResurrected::HealInfo hi; - hi.stackID = (attackedCre)->ID; - int stackHPgained = hpGained; - if(ctx.caster != nullptr) - stackHPgained = ctx.caster->getSpellBonus(owner, hpGained, attackedCre); + hi.stackID = (attackedCre)->ID; + int stackHPgained = ctx.caster->getSpellBonus(owner, hpGained, attackedCre); hi.healedHP = attackedCre->calculateHealedHealthPoints(stackHPgained, resurrect); hi.lowLevelResurrection = (healLevel == EHealLevel::RESURRECT); shr.healedStacks.push_back(hi); diff --git a/lib/spells/CDefaultSpellMechanics.cpp b/lib/spells/CDefaultSpellMechanics.cpp index e680649f3..f9b352684 100644 --- a/lib/spells/CDefaultSpellMechanics.cpp +++ b/lib/spells/CDefaultSpellMechanics.cpp @@ -230,15 +230,17 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS //check it there is opponent hero const ui8 otherSide = 1-parameters.casterSide; - const CGHeroInstance * otherHero = parameters.cb->battleGetFightingHero(otherSide); + const CGHeroInstance * otherHero = nullptr; + if(parameters.cb->battleHasHero(otherSide)) + otherHero = parameters.cb->battleGetFightingHero(otherSide); int spellCost = 0; //calculate spell cost - if(parameters.casterHero) + if(parameters.mode == ECastingMode::HERO_CASTING) { spellCost = parameters.cb->battleGetSpellCost(owner, parameters.casterHero); - if(parameters.mode == ECastingMode::HERO_CASTING && nullptr != otherHero) //handle mana channel + 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? @@ -303,8 +305,16 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS ctx.effectValue = 0; if(parameters.casterStack) ctx.caster = parameters.casterStack; + else if(parameters.casterHero) + ctx.caster = parameters.casterHero; else if(parameters.mode == ECastingMode::HERO_CASTING) ctx.caster = parameters.cb->battleGetFightingHero(parameters.casterSide); + + if(ctx.caster == nullptr) + { + env->complain("No spell-caster provided."); + return; + } if(parameters.casterStack) { @@ -325,7 +335,7 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS env->sendAndApply(&sc); //spend mana - if(parameters.casterHero) + if(parameters.mode == ECastingMode::HERO_CASTING) { SetMana sm; sm.absolute = false; @@ -527,9 +537,9 @@ void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env, { BattleStackAttacked bsa; if(spellDamage != 0) - bsa.damageAmount = owner->adjustRawDamage(parameters.casterHero, attackedCre, spellDamage) >> chainLightningModifier; + bsa.damageAmount = owner->adjustRawDamage(ctx.caster, attackedCre, spellDamage) >> chainLightningModifier; else - bsa.damageAmount = owner->calculateDamage(parameters.casterHero, attackedCre, ctx.effectLevel, ctx.effectPower) >> chainLightningModifier; + bsa.damageAmount = owner->calculateDamage(ctx.caster, attackedCre, ctx.effectLevel, ctx.effectPower) >> chainLightningModifier; ctx.sc.dmgToDisplay += bsa.damageAmount; @@ -888,7 +898,7 @@ void DefaultSpellMechanics::prepareBattleCast(const BattleSpellCastParameters& p sc.skill = parameters.spellLvl; sc.tile = parameters.destination; sc.dmgToDisplay = 0; - sc.castByHero = nullptr != parameters.casterHero; + sc.castByHero = parameters.mode == ECastingMode::HERO_CASTING; sc.casterStack = (parameters.casterStack ? parameters.casterStack->ID : -1); sc.manaGained = 0; } diff --git a/lib/spells/CSpellHandler.cpp b/lib/spells/CSpellHandler.cpp index baab35045..fe43b01a1 100644 --- a/lib/spells/CSpellHandler.cpp +++ b/lib/spells/CSpellHandler.cpp @@ -390,8 +390,7 @@ int CSpell::adjustRawDamage(const ISpellCaster * caster, const CStack * affected } } - if(nullptr != caster) //todo: make sure that caster always present - ret = caster->getSpellBonus(this, ret, affectedCreature); + ret = caster->getSpellBonus(this, ret, affectedCreature); return ret; } diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 65dfc2707..38820fe94 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -5290,8 +5290,8 @@ void CGameHandler::runBattle() parameters.destination = BattleHex::INVALID; parameters.casterSide = i; parameters.casterColor = h->tempOwner; - parameters.casterHero = nullptr; - parameters.mode = ECastingMode::HERO_CASTING; + parameters.casterHero = h; + parameters.mode = ECastingMode::PASSIVE_CASTING; parameters.casterStack = nullptr; parameters.selectedStack = nullptr;