diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index cc20ce0a5d..d31669e91a 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -277,9 +277,17 @@ namespace return; } - Log(Debug::Warning) << "Warning: Dropping reference to " << state.mRef.mRefID - << " (invalid content file link)"; - return; + // Note: we preserve RefNum when picking up or dropping an item. So if this RefNum is not found + // in this cell in content files, it doesn't mean that the instance is invalid. + // But non-storable item are always stored in saves together with their original cell. + // If a non-storable item references a content file, but is not found in this content file, + // we should drop it. + if (!MWWorld::ContainerStore::isStorableType()) + { + Log(Debug::Warning) << "Warning: Dropping reference to " << state.mRef.mRefID + << " (invalid content file link)"; + return; + } } // new reference diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 253df39567..1948c07ae5 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -99,6 +99,19 @@ namespace MWWorld static const ESM::RefId sGoldId; + static constexpr bool isStorableType(unsigned int t) + { + return t == ESM::Potion::sRecordId || t == ESM::Apparatus::sRecordId || t == ESM::Armor::sRecordId + || t == ESM::Book::sRecordId || t == ESM::Clothing::sRecordId || t == ESM::Ingredient::sRecordId + || t == ESM::Light::sRecordId || t == ESM::Lockpick::sRecordId || t == ESM::Miscellaneous::sRecordId + || t == ESM::Probe::sRecordId || t == ESM::Repair::sRecordId || t == ESM::Weapon::sRecordId; + } + template + static constexpr bool isStorableType() + { + return isStorableType(T::sRecordId); + } + protected: ContainerStoreListener* mListener;