From 1d1ce2de7b332c25de68eb6e4847063ed91ee6eb Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Fri, 26 Jan 2024 17:15:41 +0100 Subject: [PATCH] Use the correct id to absorb enchantments --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/activespells.cpp | 34 ++++++++++++++---------- apps/openmw/mwmechanics/activespells.hpp | 1 + apps/openmw/mwmechanics/spelleffects.cpp | 10 +++---- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b014ca0389..a2fbdc6eaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -133,6 +133,7 @@ Bug #7765: OpenMW-CS: Touch Record option is broken Bug #7770: Sword of the Perithia: Script execution failure Bug #7780: Non-ASCII texture paths in NIF files don't work + Bug #7796: Absorbed enchantments don't restore magicka Feature #2566: Handle NAM9 records for manual cell references Feature #3537: Shader-based water ripples Feature #5173: Support for NiFogProperty diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index a9c669fce5..937e7a6658 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -174,6 +174,25 @@ namespace MWMechanics mWorsenings = -1; } + ESM::RefId ActiveSpells::ActiveSpellParams::getEnchantment() const + { + // Enchantment id is not stored directly. Instead the enchanted item is stored. + const auto& store = MWBase::Environment::get().getESMStore(); + switch (store->find(mId)) + { + case ESM::REC_ARMO: + return store->get().find(mId)->mEnchant; + case ESM::REC_BOOK: + return store->get().find(mId)->mEnchant; + case ESM::REC_CLOT: + return store->get().find(mId)->mEnchant; + case ESM::REC_WEAP: + return store->get().find(mId)->mEnchant; + default: + return {}; + } + } + void ActiveSpells::update(const MWWorld::Ptr& ptr, float duration) { if (mIterating) @@ -438,21 +457,8 @@ namespace MWMechanics if (store->get().search(id) == nullptr) return false; - // Enchantment id is not stored directly. Instead the enchanted item is stored. return std::find_if(mSpells.begin(), mSpells.end(), [&](const auto& spell) { - switch (store->find(spell.mId)) - { - case ESM::REC_ARMO: - return store->get().find(spell.mId)->mEnchant == id; - case ESM::REC_BOOK: - return store->get().find(spell.mId)->mEnchant == id; - case ESM::REC_CLOT: - return store->get().find(spell.mId)->mEnchant == id; - case ESM::REC_WEAP: - return store->get().find(spell.mId)->mEnchant == id; - default: - return false; - } + return spell.getEnchantment() == id; }) != mSpells.end(); } diff --git a/apps/openmw/mwmechanics/activespells.hpp b/apps/openmw/mwmechanics/activespells.hpp index 87497d9d7a..a505b8990a 100644 --- a/apps/openmw/mwmechanics/activespells.hpp +++ b/apps/openmw/mwmechanics/activespells.hpp @@ -73,6 +73,7 @@ namespace MWMechanics const std::string& getDisplayName() const { return mDisplayName; } ESM::RefNum getItem() const { return mItem; } + ESM::RefId getEnchantment() const; // Increments worsenings count and sets the next timestamp void worsen(); diff --git a/apps/openmw/mwmechanics/spelleffects.cpp b/apps/openmw/mwmechanics/spelleffects.cpp index ebf9933cfc..8c415949f5 100644 --- a/apps/openmw/mwmechanics/spelleffects.cpp +++ b/apps/openmw/mwmechanics/spelleffects.cpp @@ -279,7 +279,8 @@ namespace return false; } - void absorbSpell(const ESM::RefId& spellId, const MWWorld::Ptr& caster, const MWWorld::Ptr& target) + void absorbSpell(const MWMechanics::ActiveSpells::ActiveSpellParams& spellParams, const MWWorld::Ptr& caster, + const MWWorld::Ptr& target) { const auto& esmStore = *MWBase::Environment::get().getESMStore(); const ESM::Static* absorbStatic = esmStore.get().find(ESM::RefId::stringRefId("VFX_Absorb")); @@ -287,15 +288,14 @@ namespace if (animation && !absorbStatic->mModel.empty()) animation->addEffect(Misc::ResourceHelpers::correctMeshPath(absorbStatic->mModel), ESM::MagicEffect::indexToName(ESM::MagicEffect::SpellAbsorption), false); - const ESM::Spell* spell = esmStore.get().search(spellId); int spellCost = 0; - if (spell) + if (const ESM::Spell* spell = esmStore.get().search(spellParams.getId())) { spellCost = MWMechanics::calcSpellCost(*spell); } else { - const ESM::Enchantment* enchantment = esmStore.get().search(spellId); + const ESM::Enchantment* enchantment = esmStore.get().search(spellParams.getEnchantment()); if (enchantment) spellCost = MWMechanics::getEffectiveEnchantmentCastCost(*enchantment, caster); } @@ -342,7 +342,7 @@ namespace { if (canAbsorb && Misc::Rng::roll0to99(prng) < activeEffect.mMagnitude) { - absorbSpell(spellParams.getId(), caster, target); + absorbSpell(spellParams, caster, target); return MWMechanics::MagicApplicationResult::Type::REMOVED; } }