diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 0ffcef2f8..87f462d6f 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1239,7 +1239,7 @@ namespace MWMechanics // Update bound effects // Note: in vanilla MW multiple bound items of the same type can be created by different spells. // As these extra copies are kinda useless this may or may not be important. - static std::map boundItemsMap; + static std::map boundItemsMap; if (boundItemsMap.empty()) { boundItemsMap[ESM::MagicEffect::BoundBattleAxe] = "sMagicBoundBattleAxeID"; @@ -1255,28 +1255,30 @@ namespace MWMechanics boundItemsMap[ESM::MagicEffect::BoundSpear] = "sMagicBoundSpearID"; } - for (std::map::iterator it = boundItemsMap.begin(); it != boundItemsMap.end(); ++it) + if(ptr.getClass().hasInventoryStore(ptr)) { - bool found = creatureStats.mBoundItems.find(it->first) != creatureStats.mBoundItems.end(); - float magnitude = effects.get(it->first).getMagnitude(); - if (found != (magnitude > 0)) + for (const auto& [effect, itemGmst] : boundItemsMap) { - if (magnitude > 0) - creatureStats.mBoundItems.insert(it->first); - else - creatureStats.mBoundItems.erase(it->first); - - std::string itemGmst = it->second; - std::string item = MWBase::Environment::get().getWorld()->getStore().get().find( - itemGmst)->mValue.getString(); - - magnitude > 0 ? addBoundItem(item, ptr) : removeBoundItem(item, ptr); - - if (it->first == ESM::MagicEffect::BoundGloves) + bool found = creatureStats.mBoundItems.find(effect) != creatureStats.mBoundItems.end(); + float magnitude = effects.get(effect).getMagnitude(); + if (found != (magnitude > 0)) { - item = MWBase::Environment::get().getWorld()->getStore().get().find( - "sMagicBoundRightGauntletID")->mValue.getString(); + if (magnitude > 0) + creatureStats.mBoundItems.insert(effect); + else + creatureStats.mBoundItems.erase(effect); + + std::string item = MWBase::Environment::get().getWorld()->getStore().get().find( + itemGmst)->mValue.getString(); + magnitude > 0 ? addBoundItem(item, ptr) : removeBoundItem(item, ptr); + + if (effect == ESM::MagicEffect::BoundGloves) + { + item = MWBase::Environment::get().getWorld()->getStore().get().find( + "sMagicBoundRightGauntletID")->mValue.getString(); + magnitude > 0 ? addBoundItem(item, ptr) : removeBoundItem(item, ptr); + } } } } diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 4bc0b9a58..c6561af96 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -601,6 +601,28 @@ namespace MWMechanics mAiSequence.readState(state.mAiSequence); mMagicEffects.readState(state.mMagicEffects); + // Rebuild the bound item cache + for(int effectId = ESM::MagicEffect::BoundDagger; effectId <= ESM::MagicEffect::BoundGloves; effectId++) + { + if(mMagicEffects.get(effectId).getMagnitude() > 0) + mBoundItems.insert(effectId); + else + { + // Check active spell effects + // We can't use mActiveSpells::getMagicEffects here because it doesn't include expired effects + auto spell = std::find_if(mActiveSpells.begin(), mActiveSpells.end(), [&] (const auto& spell) + { + const auto& effects = spell.second.mEffects; + return std::find_if(effects.begin(), effects.end(), [&] (const auto& effect) + { + return effect.mEffectId == effectId; + }) != effects.end(); + }); + if(spell != mActiveSpells.end()) + mBoundItems.insert(effectId); + } + } + mSummonedCreatures = state.mSummonedCreatureMap; mSummonGraveyard = state.mSummonGraveyard;