diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index 90d29f686..9d8fe60c3 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -295,6 +295,30 @@ namespace MWMechanics mSpellsChanged = true; } + /* + Start of tes3mp addition + + Allow the purging of an effect for a specific arg (attribute or skill) + */ + void ActiveSpells::purgeEffectByArg(short effectId, int effectArg) + { + for (TContainer::iterator it = mSpells.begin(); it != mSpells.end(); ++it) + { + for (std::vector::iterator effectIt = it->second.mEffects.begin(); + effectIt != it->second.mEffects.end();) + { + if (effectIt->mEffectId == effectId && effectIt->mArg == effectArg) + effectIt = it->second.mEffects.erase(effectIt); + else + ++effectIt; + } + } + mSpellsChanged = true; + } + /* + End of tes3mp addition + */ + void ActiveSpells::clear() { mSpells.clear(); diff --git a/apps/openmw/mwmechanics/activespells.hpp b/apps/openmw/mwmechanics/activespells.hpp index a19c8a51d..7f4c8ea3f 100644 --- a/apps/openmw/mwmechanics/activespells.hpp +++ b/apps/openmw/mwmechanics/activespells.hpp @@ -94,6 +94,16 @@ namespace MWMechanics /// Remove all effects with CASTER_LINKED flag that were cast by \a casterActorId void purge (int casterActorId); + /* + Start of tes3mp addition + + Allow the purging of an effect for a specific arg (attribute or skill) + */ + void purgeEffectByArg(short effectId, int effectArg); + /* + End of tes3mp addition + */ + /// Remove all spells void clear(); diff --git a/apps/openmw/mwmp/LocalPlayer.cpp b/apps/openmw/mwmp/LocalPlayer.cpp index ba2115969..b6eb85711 100644 --- a/apps/openmw/mwmp/LocalPlayer.cpp +++ b/apps/openmw/mwmp/LocalPlayer.cpp @@ -19,6 +19,7 @@ #include "../mwinput/inputmanagerimp.hpp" +#include "../mwmechanics/activespells.hpp" #include "../mwmechanics/aitravel.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/mechanicsmanagerimp.hpp" @@ -790,6 +791,12 @@ void LocalPlayer::setAttributes() for (int i = 0; i < 8; ++i) { + // If the server wants to clear our attribute's non-zero modifier, we need to remove + // the spell effect causing it, to avoid an infinite loop where the effect keeps resetting + // the modifier + if (creatureStats.mAttributes[i].mMod == 0 && ptrCreatureStats->getAttribute(i).getModifier() > 0) + ptrCreatureStats->getActiveSpells().purgeEffectByArg(ESM::MagicEffect::FortifyAttribute, i); + attributeValue.readState(creatureStats.mAttributes[i]); ptrCreatureStats->setAttribute(i, attributeValue); }