diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b36eb2525..f549eac686 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,7 @@ Bug #7665: Alchemy menu is missing the ability to deselect and choose different qualities of an apparatus Bug #7675: Successful lock spell doesn't produce a sound Bug #7679: Scene luminance value flashes when toggling shaders + Bug #7712: Casting doesn't support spells and enchantments with no effects Feature #3537: Shader-based water ripples Feature #5492: Let rain and snow collide with statics Feature #6149: Dehardcode Lua API_REVISION diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index bd38174183..1c8aad5447 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -423,17 +423,21 @@ namespace MWGui mSpellBox->setUserString("Spell", spellId.serialize()); mSpellBox->setUserData(MyGUI::Any::Null); - // use the icon of the first effect - const ESM::MagicEffect* effect = MWBase::Environment::get().getESMStore()->get().find( - spell->mEffects.mList.front().mEffectID); - - std::string icon = effect->mIcon; - std::replace(icon.begin(), icon.end(), '/', '\\'); - int slashPos = icon.rfind('\\'); - icon.insert(slashPos + 1, "b_"); - icon = Misc::ResourceHelpers::correctIconPath(icon, MWBase::Environment::get().getResourceSystem()->getVFS()); - - mSpellImage->setSpellIcon(icon); + if (!spell->mEffects.mList.empty()) + { + // use the icon of the first effect + const ESM::MagicEffect* effect = MWBase::Environment::get().getESMStore()->get().find( + spell->mEffects.mList.front().mEffectID); + std::string icon = effect->mIcon; + std::replace(icon.begin(), icon.end(), '/', '\\'); + size_t slashPos = icon.rfind('\\'); + icon.insert(slashPos + 1, "b_"); + icon = Misc::ResourceHelpers::correctIconPath( + icon, MWBase::Environment::get().getResourceSystem()->getVFS()); + mSpellImage->setSpellIcon(icon); + } + else + mSpellImage->setSpellIcon({}); } void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent) diff --git a/apps/openmw/mwgui/itemwidget.cpp b/apps/openmw/mwgui/itemwidget.cpp index 5ee74c6e87..05fff2d40f 100644 --- a/apps/openmw/mwgui/itemwidget.cpp +++ b/apps/openmw/mwgui/itemwidget.cpp @@ -202,7 +202,7 @@ namespace MWGui setIcon(ptr); } - void SpellWidget::setSpellIcon(const std::string& icon) + void SpellWidget::setSpellIcon(std::string_view icon) { if (mFrame && !mCurrentFrame.empty()) { diff --git a/apps/openmw/mwgui/itemwidget.hpp b/apps/openmw/mwgui/itemwidget.hpp index 29b0063203..63837ae92f 100644 --- a/apps/openmw/mwgui/itemwidget.hpp +++ b/apps/openmw/mwgui/itemwidget.hpp @@ -58,7 +58,7 @@ namespace MWGui { MYGUI_RTTI_DERIVED(SpellWidget) public: - void setSpellIcon(const std::string& icon); + void setSpellIcon(std::string_view icon); }; } diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index bdcc4e76d7..a13cfe4d77 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -237,13 +237,15 @@ namespace MWGui params.mNoTarget = false; effects.push_back(params); } - if (MWMechanics::spellIncreasesSkill( - spell)) // display school of spells that contribute to skill progress + // display school of spells that contribute to skill progress + if (MWMechanics::spellIncreasesSkill(spell)) { - MWWorld::Ptr player = MWMechanics::getPlayer(); - const auto& school - = store->get().find(MWMechanics::getSpellSchool(spell, player))->mSchool; - info.text = "#{sSchool}: " + MyGUI::TextIterator::toTagsString(school->mName).asUTF8(); + ESM::RefId id = MWMechanics::getSpellSchool(spell, MWMechanics::getPlayer()); + if (!id.empty()) + { + const auto& school = store->get().find(id)->mSchool; + info.text = "#{sSchool}: " + MyGUI::TextIterator::toTagsString(school->mName).asUTF8(); + } } auto cost = focus->getUserString("SpellCost"); if (!cost.empty() && cost != "0") diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 77bc51423e..262283b365 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1605,7 +1605,7 @@ namespace MWMechanics effects = &spell->mEffects.mList; cast.playSpellCastingEffects(spell); } - if (mCanCast) + if (mCanCast && !effects->empty()) { const ESM::MagicEffect* effect = store.get().find( effects->back().mEffectID); // use last effect of list for color of VFX_Hands @@ -1615,18 +1615,13 @@ namespace MWMechanics const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - if (!effects->empty()) - { - if (mAnimation->getNode("Bip01 L Hand")) - mAnimation->addEffect( - Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), -1, false, - "Bip01 L Hand", effect->mParticle); + if (mAnimation->getNode("Bip01 L Hand")) + mAnimation->addEffect(Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), + -1, false, "Bip01 L Hand", effect->mParticle); - if (mAnimation->getNode("Bip01 R Hand")) - mAnimation->addEffect( - Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), -1, false, - "Bip01 R Hand", effect->mParticle); - } + if (mAnimation->getNode("Bip01 R Hand")) + mAnimation->addEffect(Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), + -1, false, "Bip01 R Hand", effect->mParticle); } const ESM::ENAMstruct& firstEffect = effects->at(0); // first effect used for casting animation diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index de3c2b011d..e6080ce447 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -524,11 +524,9 @@ namespace MWWorld const ESM::Enchantment* enchantment = MWBase::Environment::get().getESMStore()->get().search(enchantmentName); - if (!enchantment) + if (!enchantment || enchantment->mEffects.mList.empty()) return result; - assert(enchantment->mEffects.mList.size()); - const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getESMStore()->get().search( enchantment->mEffects.mList.front().mEffectID); if (!magicEffect)