diff --git a/CHANGELOG.md b/CHANGELOG.md index 34ea5acc9d..da42274f49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -133,6 +133,7 @@ Bug #6799: Game crashes if an NPC has no Class attached Bug #6849: ImageButton texture is not scaled properly Bug #6895: Removing a negative number of items from a script, makes the script terminate with an error + Bug #6901: Morrowind.exe soul gem usage discrepancy Feature #890: OpenMW-CS: Column filtering Feature #1465: "Reset" argument for AI functions Feature #2491: Ability to make OpenMW "portable" diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index be5cf9c143..3aa5544b74 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -203,9 +203,12 @@ namespace MWClass std::unique_ptr Miscellaneous::use (const MWWorld::Ptr& ptr, bool force) const { - if (ptr.getCellRef().getSoul().empty() || !MWBase::Environment::get().getWorld()->getStore().get().search(ptr.getCellRef().getSoul())) - return std::make_unique(); - return std::make_unique(ptr); + const std::string soulgemPrefix = "misc_soulgem"; + + if (::Misc::StringUtils::ciCompareLen(ptr.getCellRef().getRefId(), soulgemPrefix, soulgemPrefix.length()) == 0) + return std::make_unique(ptr); + + return std::make_unique(); } bool Miscellaneous::canSell (const MWWorld::ConstPtr& item, int npcServices) const diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index 742cfb1828..8699d3dfe4 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -304,11 +304,40 @@ namespace MWScript MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore (ptr); MWWorld::ContainerStoreIterator it = invStore.begin(); - for (; it != invStore.end(); ++it) + + // With soul gems we prefer filled ones. + + const std::string soulgemPrefix = "misc_soulgem"; + + if (::Misc::StringUtils::ciCompareLen(item, soulgemPrefix, soulgemPrefix.length()) == 0) { - if (::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item)) - break; + it = invStore.end(); + + for (auto it_any = invStore.begin(); it_any != invStore.end(); ++it_any) + { + if (::Misc::StringUtils::ciEqual(it_any->getCellRef().getRefId(), item)) + { + if (!it_any->getCellRef().getSoul().empty() && + MWBase::Environment::get().getWorld()->getStore().get().search(it_any->getCellRef().getSoul())) + { + it = it_any; + break; + } + else if (it == invStore.end()) + it = it_any; + } + } } + + else + { + for (; it != invStore.end(); ++it) + { + if (::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item)) + break; + } + } + if (it == invStore.end()) { MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), item, 1); diff --git a/apps/openmw/mwworld/actionsoulgem.cpp b/apps/openmw/mwworld/actionsoulgem.cpp index f7823dabaa..b416581fa7 100644 --- a/apps/openmw/mwworld/actionsoulgem.cpp +++ b/apps/openmw/mwworld/actionsoulgem.cpp @@ -1,10 +1,15 @@ #include "actionsoulgem.hpp" +#include + #include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwworld/esmstore.hpp" + namespace MWWorld { @@ -23,7 +28,23 @@ namespace MWWorld MWBase::Environment::get().getWindowManager()->messageBox("#{sInventoryMessage5}"); return; } - MWBase::Environment::get().getWindowManager()->showSoulgemDialog(getTarget()); + + const auto& target = getTarget(); + const std::string targetSoul = target.getCellRef().getSoul(); + + if (targetSoul.empty()) + { + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage32}"); + return; + } + + if (!MWBase::Environment::get().getWorld()->getStore().get().search(targetSoul)) + { + Log(Debug::Warning) << "Soul '" << targetSoul << "' not found (item: '" << target.getCellRef().getRefId() << "')"; + return; + } + + MWBase::Environment::get().getWindowManager()->showSoulgemDialog(target); }