diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index 2a71659742..994798b0bb 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -205,4 +205,22 @@ namespace MWMechanics } mSpellsChanged = true; } + + void ActiveSpells::purge(const std::string &actorHandle) + { + for (TContainer::iterator it = mSpells.begin(); it != mSpells.end(); ++it) + { + for (std::vector::iterator effectIt = it->second.mEffects.begin(); + effectIt != it->second.mEffects.end();) + { + const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().get().find(effectIt->mKey.mId); + if (effect->mData.mFlags & ESM::MagicEffect::CasterLinked + && it->second.mCasterHandle == actorHandle) + effectIt = it->second.mEffects.erase(effectIt); + else + effectIt++; + } + } + mSpellsChanged = true; + } } diff --git a/apps/openmw/mwmechanics/activespells.hpp b/apps/openmw/mwmechanics/activespells.hpp index 2ddb4ec556..7a40afb4cb 100644 --- a/apps/openmw/mwmechanics/activespells.hpp +++ b/apps/openmw/mwmechanics/activespells.hpp @@ -90,6 +90,9 @@ namespace MWMechanics /// Remove all active effects, if roll succeeds (for each effect) void purgeAll (float chance); + /// Remove all effects with CASTER_LINKED flag that were cast by \a actorHandle + void purge (const std::string& actorHandle); + bool isSpellActive (std::string id) const; ///< case insensitive diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 468a218927..6f710988e8 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -814,6 +814,13 @@ namespace MWMechanics stats.setMagicEffects(MWMechanics::MagicEffects()); calculateCreatureStatModifiers(iter->first, 0); + // Make sure spell effects with CasterLinked flag are removed + for(PtrControllerMap::iterator iter2(mActors.begin());iter2 != mActors.end();++iter2) + { + MWMechanics::ActiveSpells& spells = iter2->first.getClass().getCreatureStats(iter2->first).getActiveSpells(); + spells.purge(iter->first.getRefData().getHandle()); + } + ++mDeathCount[cls.getId(iter->first)]; if(cls.isEssential(iter->first)) diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index be67b65928..a0e91791ba 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -164,8 +164,9 @@ namespace MWMechanics ActiveSpells::Effect effect_ = effect; effect_.mMagnitude *= -1; effects.push_back(effect_); + // Also make sure to set casterHandle = target, so that the effect on the caster gets purged when the target dies caster.getClass().getCreatureStats(caster).getActiveSpells().addSpell("", true, - effects, mSourceName, caster.getRefData().getHandle()); + effects, mSourceName, target.getRefData().getHandle()); } } } @@ -224,7 +225,7 @@ namespace MWMechanics target.getClass().getCreatureStats(target).getActiveSpells().addSpell(mId, mStack, appliedLastingEffects, mSourceName, caster.getRefData().getHandle()); - if (anyHarmfulEffect && target.getClass().isActor() + if (anyHarmfulEffect && target.getClass().isActor() && target != caster && target.getClass().getCreatureStats(target).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30) MWBase::Environment::get().getMechanicsManager()->commitCrime(caster, target, MWBase::MechanicsManager::OT_Assault); }