From ca46da8b048dbc1f88499307ab312589576290d0 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 29 Sep 2019 13:08:52 +0400 Subject: [PATCH] Do not stack initially added scripted items (bug #5136) --- CHANGELOG.md | 1 + apps/openmw/mwworld/containerstore.cpp | 78 +++++++++++++++----------- apps/openmw/mwworld/containerstore.hpp | 1 + 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1ac9fa79e..aaf052d053 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -140,6 +140,7 @@ Bug #5124: Arrow remains attached to actor if pulling animation was cancelled Bug #5126: Swimming creatures without RunForward animations are motionless during combat Bug #5134: Doors rotation by "Lock" console command is inconsistent + Bug #5136: LegionUniform script: can not access local variables Bug #5137: Textures with Clamp Mode set to Clamp instead of Wrap are too dark outside the boundaries Bug #5149: Failing lock pick attempts isn't always a crime Bug #5155: Lock/unlock behavior differs from vanilla diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 8c17dc0a9d..76555de02c 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -477,50 +477,64 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std:: int count, bool topLevel, const std::string& levItem) { if (count == 0) return; //Don't restock with nothing. - try { + try + { ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id, count); - - if (ref.getPtr().getTypeName()==typeid (ESM::ItemLevList).name()) + if (ref.getPtr().getClass().getScript(ref.getPtr()).empty()) { - const ESM::ItemLevList* levItemList = ref.getPtr().get()->mBase; - - if (topLevel && std::abs(count) > 1 && levItemList->mFlags & ESM::ItemLevList::Each) - { - for (int i=0; i 0 ? 1 : -1, true, levItemList->mId); - return; - } - else - { - std::string itemId = MWMechanics::getLevelledItem(ref.getPtr().get()->mBase, false); - if (itemId.empty()) - return; - addInitialItem(itemId, owner, count, false, levItemList->mId); - } + addInitialItemImp(ref.getPtr(), owner, count, topLevel, levItem); } else { - // A negative count indicates restocking items - // For a restocking levelled item, remember what we spawned so we can delete it later when the merchant restocks - if (!levItem.empty() && count < 0) - { - //If there is no item in map, insert it - std::map, int>::iterator itemInMap = - mLevelledItemMap.insert(std::make_pair(std::make_pair(id, levItem), 0)).first; - //Update spawned count - itemInMap->second += std::abs(count); - } - count = std::abs(count); - - ref.getPtr().getCellRef().setOwner(owner); - addImp (ref.getPtr(), count); + // Adding just one item per time to make sure there isn't a stack of scripted items + for (int i = 0; i < abs(count); i++) + addInitialItemImp(ref.getPtr(), owner, count < 0 ? -1 : 1, topLevel, levItem); } } catch (const std::exception& e) { Log(Debug::Warning) << "Warning: MWWorld::ContainerStore::addInitialItem: " << e.what(); } +} + +void MWWorld::ContainerStore::addInitialItemImp(const MWWorld::Ptr& ptr, const std::string& owner, + int count, bool topLevel, const std::string& levItem) +{ + if (ptr.getTypeName()==typeid (ESM::ItemLevList).name()) + { + const ESM::ItemLevList* levItemList = ptr.get()->mBase; + + if (topLevel && std::abs(count) > 1 && levItemList->mFlags & ESM::ItemLevList::Each) + { + for (int i=0; i 0 ? 1 : -1, true, levItemList->mId); + return; + } + else + { + std::string itemId = MWMechanics::getLevelledItem(ptr.get()->mBase, false); + if (itemId.empty()) + return; + addInitialItem(itemId, owner, count, false, levItemList->mId); + } + } + else + { + // A negative count indicates restocking items + // For a restocking levelled item, remember what we spawned so we can delete it later when the merchant restocks + if (!levItem.empty() && count < 0) + { + //If there is no item in map, insert it + std::map, int>::iterator itemInMap = + mLevelledItemMap.insert(std::make_pair(std::make_pair(ptr.getCellRef().getRefId(), levItem), 0)).first; + //Update spawned count + itemInMap->second += std::abs(count); + } + count = std::abs(count); + ptr.getCellRef().setOwner(owner); + addImp (ptr, count); + } } void MWWorld::ContainerStore::restock (const ESM::InventoryList& items, const MWWorld::Ptr& ptr, const std::string& owner) diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index b06e8b8ce6..1e1e4a844e 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -94,6 +94,7 @@ namespace MWWorld mutable bool mWeightUpToDate; ContainerStoreIterator addImp (const Ptr& ptr, int count); void addInitialItem (const std::string& id, const std::string& owner, int count, bool topLevel=true, const std::string& levItem = ""); + void addInitialItemImp (const MWWorld::Ptr& ptr, const std::string& owner, int count, bool topLevel=true, const std::string& levItem = ""); template ContainerStoreIterator getState (CellRefList& collection,