From 7d0483d7ad24a72847c11330af2e9cd0ce200b21 Mon Sep 17 00:00:00 2001 From: fredzio Date: Fri, 11 Jun 2021 05:53:40 +0200 Subject: [PATCH] Cast spell even if target Ptr is empty. It happens when enchanted arrows hit water or ground. --- apps/openmw/mwmechanics/spellcasting.cpp | 37 ++++++++++++------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 142914c35..5a367b502 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -60,10 +60,8 @@ namespace MWMechanics void CastSpell::inflict(const MWWorld::Ptr &target, const MWWorld::Ptr &caster, const ESM::EffectList &effects, ESM::RangeType range, bool reflected, bool exploded) { - if (target.isEmpty()) - return; - - if (target.getClass().isActor()) + const bool targetIsActor = !target.isEmpty() && target.getClass().isActor(); + if (targetIsActor) { // Early-out for characters that have departed. const auto& stats = target.getClass().getCreatureStats(target); @@ -85,7 +83,7 @@ namespace MWMechanics return; const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().search (mId); - if (spell && target.getClass().isActor() && (spell->mData.mType == ESM::Spell::ST_Disease || spell->mData.mType == ESM::Spell::ST_Blight)) + if (spell && targetIsActor && (spell->mData.mType == ESM::Spell::ST_Disease || spell->mData.mType == ESM::Spell::ST_Blight)) { int requiredResistance = (spell->mData.mType == ESM::Spell::ST_Disease) ? ESM::MagicEffect::ResistCommonDisease @@ -108,13 +106,13 @@ namespace MWMechanics // This is required for Weakness effects in a spell to apply to any subsequent effects in the spell. // Otherwise, they'd only apply after the whole spell was added. MagicEffects targetEffects; - if (target.getClass().isActor()) + if (targetIsActor) targetEffects += target.getClass().getCreatureStats(target).getMagicEffects(); bool castByPlayer = (!caster.isEmpty() && caster == getPlayer()); ActiveSpells targetSpells; - if (target.getClass().isActor()) + if (targetIsActor) targetSpells = target.getClass().getCreatureStats(target).getActiveSpells(); bool canCastAnEffect = false; // For bound equipment.If this remains false @@ -126,7 +124,7 @@ namespace MWMechanics int currentEffectIndex = 0; for (std::vector::const_iterator effectIt (effects.mList.begin()); - effectIt != effects.mList.end(); ++effectIt, ++currentEffectIndex) + !target.isEmpty() && effectIt != effects.mList.end(); ++effectIt, ++currentEffectIndex) { if (effectIt->mRange != range) continue; @@ -270,7 +268,7 @@ namespace MWMechanics } // Re-casting a summon effect will remove the creature from previous castings of that effect. - if (isSummoningEffect(effectIt->mEffectID) && target.getClass().isActor()) + if (isSummoningEffect(effectIt->mEffectID) && targetIsActor) { CreatureStats& targetStats = target.getClass().getCreatureStats(target); ESM::SummonKey key(effectIt->mEffectID, mId, currentEffectIndex); @@ -313,16 +311,19 @@ namespace MWMechanics if (!exploded) MWBase::Environment::get().getWorld()->explodeSpell(mHitPosition, effects, caster, target, range, mId, mSourceName, mFromProjectile); - if (!reflectedEffects.mList.empty()) - inflict(caster, target, reflectedEffects, range, true, exploded); - - if (!appliedLastingEffects.empty()) + if (!target.isEmpty()) { - int casterActorId = -1; - if (!caster.isEmpty() && caster.getClass().isActor()) - casterActorId = caster.getClass().getCreatureStats(caster).getActorId(); - target.getClass().getCreatureStats(target).getActiveSpells().addSpell(mId, mStack, appliedLastingEffects, - mSourceName, casterActorId); + if (!reflectedEffects.mList.empty()) + inflict(caster, target, reflectedEffects, range, true, exploded); + + if (!appliedLastingEffects.empty()) + { + int casterActorId = -1; + if (!caster.isEmpty() && caster.getClass().isActor()) + casterActorId = caster.getClass().getCreatureStats(caster).getActorId(); + target.getClass().getCreatureStats(target).getActiveSpells().addSpell(mId, mStack, appliedLastingEffects, + mSourceName, casterActorId); + } } }