diff --git a/apps/openmw/mwrender/groundcover.cpp b/apps/openmw/mwrender/groundcover.cpp index 11a155f9f..049118c90 100644 --- a/apps/openmw/mwrender/groundcover.cpp +++ b/apps/openmw/mwrender/groundcover.cpp @@ -13,6 +13,17 @@ namespace MWRender { + std::string getGroundcoverModel(int type, const std::string& id, const MWWorld::ESMStore& store) + { + switch (type) + { + case ESM::REC_STAT: + return store.get().searchStatic(id)->mModel; + default: + return std::string(); + } + } + void GroundcoverUpdater::setWindSpeed(float windSpeed) { mWindSpeed = windSpeed; @@ -217,15 +228,17 @@ namespace MWRender while(cell->getNextRef(esm[index], ref, deleted)) { if (deleted) continue; - Misc::StringUtils::lowerCaseInPlace(ref.mRefID); - std::string model; - if (!store.isGroundcover(ref.mRefID, model)) continue; - if (model.empty()) continue; + if (!ref.mRefNum.fromGroundcoverFile()) continue; if (!calculator.isInstanceEnabled()) continue; if (!isInChunkBorders(ref, minBound, maxBound)) continue; + Misc::StringUtils::lowerCaseInPlace(ref.mRefID); + int type = store.findStatic(ref.mRefID); + std::string model = getGroundcoverModel(type, ref.mRefID, store); + if (model.empty()) continue; model = "meshes/" + model; + instances[model].emplace_back(ref, model); } } diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index 478fde0f8..b85358c20 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -373,7 +373,6 @@ namespace MWRender std::map refs; std::vector esm; const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - for (int cellX = startCell.x(); cellX < startCell.x() + size; ++cellX) { for (int cellY = startCell.y(); cellY < startCell.y() + size; ++cellY) @@ -398,7 +397,7 @@ namespace MWRender int type = store.findStatic(ref.mRefID); if (!typeFilter(type,size>=2)) continue; if (deleted) { refs.erase(ref.mRefNum); continue; } - if (store.isGroundcover(ref.mRefID)) continue; + if (ref.mRefNum.fromGroundcoverFile()) continue; refs[ref.mRefNum] = ref; } } diff --git a/apps/openmw/mwworld/cellpreloader.cpp b/apps/openmw/mwworld/cellpreloader.cpp index 937491f62..421de4a7d 100644 --- a/apps/openmw/mwworld/cellpreloader.cpp +++ b/apps/openmw/mwworld/cellpreloader.cpp @@ -1,5 +1,6 @@ #include "cellpreloader.hpp" +#include #include #include @@ -36,12 +37,7 @@ namespace MWWorld virtual bool operator()(const MWWorld::Ptr& ptr) { - if (ptr.getTypeName()==typeid (ESM::Static).name()) - { - const MWWorld::LiveCellRef *ref = ptr.get(); - if (ref->mBase->mIsGroundcover) - return true; - } + if (ptr.getCellRef().getRefNum().fromGroundcoverFile()) return true; ptr.getClass().getModelsToPreload(ptr, mOut); diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index d8e2eb65f..7ca35a1df 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -169,18 +169,6 @@ namespace namespace MWWorld { - template - bool CellRefList::ignoreInstance (const X* ptr) - { - return false; - } - - template <> - bool CellRefList::ignoreInstance (const ESM::Static* ptr) - { - return ptr->mIsGroundcover; - } - template void CellRefList::load(ESM::CellRef &ref, bool deleted, const MWWorld::ESMStore &esmStore) { @@ -188,8 +176,6 @@ namespace MWWorld if (const X *ptr = store.search (ref.mRefID)) { - if (ignoreInstance(ptr)) return; - typename std::list::iterator iter = std::find(mList.begin(), mList.end(), ref.mRefNum); @@ -700,7 +686,11 @@ namespace MWWorld case ESM::REC_NPC_: mNpcs.load(ref, deleted, store); break; case ESM::REC_PROB: mProbes.load(ref, deleted, store); break; case ESM::REC_REPA: mRepairs.load(ref, deleted, store); break; - case ESM::REC_STAT: mStatics.load(ref, deleted, store); break; + case ESM::REC_STAT: + { + if (ref.mRefNum.fromGroundcoverFile()) return; + mStatics.load(ref, deleted, store); break; + } case ESM::REC_WEAP: mWeapons.load(ref, deleted, store); break; case ESM::REC_BODY: mBodyParts.load(ref, deleted, store); break; diff --git a/apps/openmw/mwworld/contentloader.hpp b/apps/openmw/mwworld/contentloader.hpp index b559df083..b529ae9db 100644 --- a/apps/openmw/mwworld/contentloader.hpp +++ b/apps/openmw/mwworld/contentloader.hpp @@ -21,7 +21,7 @@ struct ContentLoader { } - virtual void load(const boost::filesystem::path& filepath, int& index, bool isGroundcover) + virtual void load(const boost::filesystem::path& filepath, int& index) { Log(Debug::Info) << "Loading content file " << filepath.string(); mListener.setLabel(MyGUI::TextIterator::toTagsString(filepath.string())); diff --git a/apps/openmw/mwworld/esmloader.cpp b/apps/openmw/mwworld/esmloader.cpp index c96618215..46b806582 100644 --- a/apps/openmw/mwworld/esmloader.cpp +++ b/apps/openmw/mwworld/esmloader.cpp @@ -15,15 +15,15 @@ EsmLoader::EsmLoader(MWWorld::ESMStore& store, std::vector& read { } -void EsmLoader::load(const boost::filesystem::path& filepath, int& index, bool isGroundcover) +void EsmLoader::load(const boost::filesystem::path& filepath, int& index) { - ContentLoader::load(filepath.filename(), index, isGroundcover); + ContentLoader::load(filepath.filename(), index); ESM::ESMReader lEsm; lEsm.setEncoder(mEncoder); lEsm.setIndex(index); lEsm.setGlobalReaderList(&mEsm); - lEsm.open(filepath.string(), isGroundcover); + lEsm.open(filepath.string()); mEsm[index] = lEsm; mStore.load(mEsm[index], &mListener); } diff --git a/apps/openmw/mwworld/esmloader.hpp b/apps/openmw/mwworld/esmloader.hpp index cc4c15a15..506105beb 100644 --- a/apps/openmw/mwworld/esmloader.hpp +++ b/apps/openmw/mwworld/esmloader.hpp @@ -25,7 +25,7 @@ struct EsmLoader : public ContentLoader EsmLoader(MWWorld::ESMStore& store, std::vector& readers, ToUTF8::Utf8Encoder* encoder, Loading::Listener& listener); - void load(const boost::filesystem::path& filepath, int& index, bool isGroundcover) override; + void load(const boost::filesystem::path& filepath, int& index) override; private: std::vector& mEsm; diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 2731d7eb1..90bc80b48 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -190,15 +190,6 @@ void ESMStore::setUp(bool validateRecords) { validate(); countRecords(); - - if (mGroundcovers.empty()) - { - for (const ESM::Static& record : mStatics) - { - if (record.mIsGroundcover) - mGroundcovers[record.mId] = record.mModel; - } - } } } diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index 18bb95580..d69c56d8c 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -75,7 +75,6 @@ namespace MWWorld // maps the id name to the record type. std::map mIds; std::map mStaticIds; - std::map mGroundcovers; std::map mRefCount; @@ -122,22 +121,6 @@ namespace MWWorld return it->second; } - bool isGroundcover(const std::string &id, std::string &model) const - { - std::map::const_iterator it = mGroundcovers.find(id); - if (it == mGroundcovers.end()) { - return false; - } - model = it->second; - return true; - } - - bool isGroundcover(const std::string &id) const - { - std::map::const_iterator it = mGroundcovers.find(id); - return (it != mGroundcovers.end()); - } - ESMStore() : mDynamicCount(0) { diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 93d1a799c..98af121a5 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -103,12 +103,12 @@ namespace MWWorld return mLoaders.insert(std::make_pair(extension, loader)).second; } - void load(const boost::filesystem::path& filepath, int& index, bool isGroundcover) override + void load(const boost::filesystem::path& filepath, int& index) override { LoadersContainer::iterator it(mLoaders.find(Misc::StringUtils::lowerCase(filepath.extension().string()))); if (it != mLoaders.end()) { - it->second->load(filepath, index, isGroundcover); + it->second->load(filepath, index); } else { @@ -2951,7 +2951,7 @@ namespace MWWorld const Files::MultiDirCollection& col = fileCollections.getCollection(filename.extension().string()); if (col.doesExist(file)) { - contentLoader.load(col.getPath(file), idx, false); + contentLoader.load(col.getPath(file), idx); } else { @@ -2961,13 +2961,15 @@ namespace MWWorld idx++; } + ESM::GroundcoverIndex = idx; + for (const std::string &file : groundcover) { boost::filesystem::path filename(file); const Files::MultiDirCollection& col = fileCollections.getCollection(filename.extension().string()); if (col.doesExist(file)) { - contentLoader.load(col.getPath(file), idx, true); + contentLoader.load(col.getPath(file), idx); } else { diff --git a/components/esm/cellref.cpp b/components/esm/cellref.cpp index 4b9852d65..b4d6ac7a7 100644 --- a/components/esm/cellref.cpp +++ b/components/esm/cellref.cpp @@ -5,6 +5,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +namespace ESM +{ + int GroundcoverIndex = std::numeric_limits::max(); +} + void ESM::RefNum::load (ESMReader& esm, bool wide, const std::string& tag) { if (wide) diff --git a/components/esm/cellref.hpp b/components/esm/cellref.hpp index 5bb7fbc53..c2f7ff6de 100644 --- a/components/esm/cellref.hpp +++ b/components/esm/cellref.hpp @@ -12,6 +12,7 @@ namespace ESM class ESMReader; const int UnbreakableLock = std::numeric_limits::max(); + extern int GroundcoverIndex; struct RefNum { @@ -25,6 +26,10 @@ namespace ESM enum { RefNum_NoContentFile = -1 }; inline bool hasContentFile() const { return mContentFile != RefNum_NoContentFile; } inline void unset() { mIndex = 0; mContentFile = RefNum_NoContentFile; } + + // Note: this method should not be used for objects with invalid RefNum + // (for example, for objects from disabled plugins in savegames). + inline bool fromGroundcoverFile() const { return mContentFile >= GroundcoverIndex; } }; /* Cell reference. This represents ONE object (of many) inside the diff --git a/components/esm/esmreader.cpp b/components/esm/esmreader.cpp index 63d2f4d4f..1b6eca734 100644 --- a/components/esm/esmreader.cpp +++ b/components/esm/esmreader.cpp @@ -25,7 +25,6 @@ ESMReader::ESMReader() , mGlobalReaderList(nullptr) , mEncoder(nullptr) , mFileSize(0) - , mIsGroundcoverFile(false) { clearCtx(); } @@ -81,10 +80,8 @@ void ESMReader::openRaw(const std::string& filename) openRaw(Files::openConstrainedFileStream(filename.c_str()), filename); } -void ESMReader::open(Files::IStreamPtr _esm, const std::string &name, bool isGroundcover) +void ESMReader::open(Files::IStreamPtr _esm, const std::string &name) { - mIsGroundcoverFile = isGroundcover; - openRaw(_esm, name); if (getRecName() != "TES3") @@ -95,9 +92,9 @@ void ESMReader::open(Files::IStreamPtr _esm, const std::string &name, bool isGro mHeader.load (*this); } -void ESMReader::open(const std::string &file, bool isGroundcover) +void ESMReader::open(const std::string &file) { - open (Files::openConstrainedFileStream (file.c_str ()), file, isGroundcover); + open (Files::openConstrainedFileStream (file.c_str ()), file); } int64_t ESMReader::getHNLong(const char *name) diff --git a/components/esm/esmreader.hpp b/components/esm/esmreader.hpp index 600cd497b..c660b0dda 100644 --- a/components/esm/esmreader.hpp +++ b/components/esm/esmreader.hpp @@ -31,7 +31,6 @@ public: int getVer() const { return mHeader.mData.version; } int getRecordCount() const { return mHeader.mData.records; } - bool isGroundcoverFile() const { return mIsGroundcoverFile; } float getFVer() const { return (mHeader.mData.version == VER_12) ? 1.2f : 1.3f; } const std::string getAuthor() const { return mHeader.mData.author; } const std::string getDesc() const { return mHeader.mData.desc; } @@ -67,9 +66,9 @@ public: /// Load ES file from a new stream, parses the header. Closes the /// currently open file first, if any. - void open(Files::IStreamPtr _esm, const std::string &name, bool isGroundcover = false); + void open(Files::IStreamPtr _esm, const std::string &name); - void open(const std::string &file, bool isGroundcover = false); + void open(const std::string &file); void openRaw(const std::string &filename); @@ -290,8 +289,6 @@ private: ToUTF8::Utf8Encoder* mEncoder; size_t mFileSize; - - bool mIsGroundcoverFile; }; } #endif diff --git a/components/esm/loadstat.cpp b/components/esm/loadstat.cpp index 85e366f1c..6c9de22bd 100644 --- a/components/esm/loadstat.cpp +++ b/components/esm/loadstat.cpp @@ -37,8 +37,6 @@ namespace ESM if (!hasName) esm.fail("Missing NAME subrecord"); - - mIsGroundcover = esm.isGroundcoverFile(); } void Static::save(ESMWriter &esm, bool isDeleted) const { diff --git a/components/esm/loadstat.hpp b/components/esm/loadstat.hpp index da94c4b8d..3d9144040 100644 --- a/components/esm/loadstat.hpp +++ b/components/esm/loadstat.hpp @@ -28,8 +28,6 @@ struct Static std::string mId, mModel; - bool mIsGroundcover = false; - void load(ESMReader &esm, bool &isDeleted); void save(ESMWriter &esm, bool isDeleted = false) const;