diff --git a/CHANGELOG.md b/CHANGELOG.md index 0da3ba67d..f5c63a892 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ 0.46.0 ------ + Bug #2969: Scripted items can stack Bug #2987: Editor: some chance and AI data fields can overflow Bug #3623: Fix HiDPI on Windows Bug #4411: Reloading a saved game while falling prevents damage in some cases diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index cf12d12c3..8a25f0c01 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -64,7 +64,19 @@ namespace MWScript || ::Misc::StringUtils::ciEqual(item, "gold_100")) item = "gold_001"; - MWWorld::Ptr itemPtr = *ptr.getClass().getContainerStore (ptr).add (item, count, ptr); + MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr); + // Create a Ptr for the first added item to recover the item name later + MWWorld::Ptr itemPtr = *store.add (item, 1, ptr); + if (itemPtr.getClass().getScript(itemPtr).empty()) + { + store.add (item, count-1, ptr); + } + else + { + // Adding just one item per time to make sure there isn't a stack of scripted items + for (int i = 1; i < count; i++) + store.add (item, 1, ptr); + } // Spawn a messagebox (only for items added to player's inventory and if player is talking to someone) if (ptr == MWBase::Environment::get().getWorld ()->getPlayerPtr() ) @@ -143,8 +155,13 @@ namespace MWScript std::string itemName; for (MWWorld::ConstContainerStoreIterator iter(store.cbegin()); iter != store.cend(); ++iter) + { if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item)) + { itemName = iter->getClass().getName(*iter); + break; + } + } int numRemoved = store.remove(item, count, ptr); diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index ee3089901..6725fb935 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -246,7 +246,9 @@ bool MWWorld::ContainerStore::stacks(const ConstPtr& ptr1, const ConstPtr& ptr2) && ptr1.getClass().getRemainingUsageTime(ptr1) == ptr2.getClass().getRemainingUsageTime(ptr2) - && cls1.getScript(ptr1) == cls2.getScript(ptr2) + // Items with scripts never stack + && cls1.getScript(ptr1).empty() + && cls2.getScript(ptr2).empty() // item that is already partly used up never stacks && (!cls1.hasItemHealth(ptr1) || ( @@ -306,7 +308,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr item.getCellRef().unsetRefNum(); // destroy link to content file std::string script = item.getClass().getScript(item); - if(script != "") + if (!script.empty()) { if (actorPtr == player) {