diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index ba8f5aa61..d007ff981 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -61,11 +61,15 @@ namespace MWWorld while (mCell->getNextRef (esm[index], ref)) { std::string lowerCase; + if (ref.mDeleted) { + // Right now, don't do anything. Wehere is "listRefs" actually used, anyway? + // Skipping for now... + continue; + } std::transform (ref.mRefID.begin(), ref.mRefID.end(), std::back_inserter (lowerCase), (int(*)(int)) std::tolower); - // TODO: Fully support deletion of references. mIds.push_back (lowerCase); } } @@ -97,7 +101,6 @@ namespace MWWorld std::transform (ref.mRefID.begin(), ref.mRefID.end(), std::back_inserter (lowerCase), (int(*)(int)) std::tolower); - // TODO: Fully support deletion of references. int rec = store.find(ref.mRefID); ref.mRefID = lowerCase; diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index cf09496e8..2b25faa70 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -59,6 +59,13 @@ namespace MWWorld /// on miss void load(ESM::CellRef &ref, const MWWorld::ESMStore &esmStore) { + // Skip this when reference was deleted. + // TODO: Support respawning references, in this case, we need to track it somehow. + if (ref.mDeleted) { + mList.erase(ref.mRefnum); + return; + } + // for throwing exception on unhandled record type const MWWorld::Store &store = esmStore.get(); const X *ptr = store.search(ref.mRefID); diff --git a/components/esm/esmreader.hpp b/components/esm/esmreader.hpp index 732dbe9bc..df4c1919e 100644 --- a/components/esm/esmreader.hpp +++ b/components/esm/esmreader.hpp @@ -119,6 +119,14 @@ public: getHT(x); } + template + void getHNOT(X &x, const char* name, int size) + { + assert(sizeof(X) == size); + if(isNextSub(name)) + getHT(x); + } + int64_t getHNLong(const char *name); // Get data of a given type/size, including subrecord header diff --git a/components/esm/loadcell.cpp b/components/esm/loadcell.cpp index b7f27b08d..aafe629e6 100644 --- a/components/esm/loadcell.cpp +++ b/components/esm/loadcell.cpp @@ -213,7 +213,24 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref) // missing ref.mScale = 1.0; esm.getHNOT(ref.mScale, "XSCL"); - + + // TODO: support loading references from saves, there are tons of keys not recognized yet. + // The following is just an incomplete list. + if (esm.isNextSub("ACTN")) + esm.skipHSub(); + if (esm.isNextSub("STPR")) + esm.skipHSub(); + if (esm.isNextSub("ACDT")) + esm.skipHSub(); + if (esm.isNextSub("ACSC")) + esm.skipHSub(); + if (esm.isNextSub("ACSL")) + esm.skipHSub(); + if (esm.isNextSub("CHRD")) + esm.skipHSub(); + else if (esm.isNextSub("CRED")) // ??? + esm.skipHSub(); + ref.mOwner = esm.getHNOString("ANAM"); ref.mGlob = esm.getHNOString("BNAM"); ref.mSoul = esm.getHNOString("XSOL"); @@ -251,7 +268,7 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref) esm.getHNOT(ref.mUnam, "UNAM"); esm.getHNOT(ref.mFltv, "FLTV"); - esm.getHNT(ref.mPos, "DATA", 24); + esm.getHNOT(ref.mPos, "DATA", 24); // Number of references in the cell? Maximum once in each cell, // but not always at the beginning, and not always right. In other @@ -265,6 +282,13 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref) esm.getHT(ref.mNam0); //esm.getHNOT(NAM0, "NAM0"); } + + if (esm.isNextSub("DELE")) { + esm.skipHSub(); + ref.mDeleted = 2; // Deleted, will not respawn. + // TODO: find out when references do respawn. + } else + ref.mDeleted = 0; return true; } diff --git a/components/esm/loadcell.hpp b/components/esm/loadcell.hpp index ccfdcadd8..dff5a3338 100644 --- a/components/esm/loadcell.hpp +++ b/components/esm/loadcell.hpp @@ -70,6 +70,9 @@ public: // No idea - occurs ONCE in Morrowind.esm, for an activator char mUnam; + + // Track deleted references. 0 - not deleted, 1 - deleted, but respawns, 2 - deleted and does not respawn. + int mDeleted; // Occurs in Tribunal.esm, eg. in the cell "Mournhold, Plaza // Brindisi Dorom", where it has the value 100. Also only for