From e8a9567be30fb35e78e252bf52e95bcebe76a109 Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Wed, 15 Jul 2015 19:39:01 +0300 Subject: [PATCH] Move DELE handling to CellRef record --- apps/openmw/mwworld/cellreflist.hpp | 2 +- apps/openmw/mwworld/cellstore.cpp | 58 ++++++++++++++--------------- apps/openmw/mwworld/cellstore.hpp | 2 +- components/esm/cellref.cpp | 21 +++++++++++ components/esm/cellref.hpp | 4 ++ components/esm/loadcell.cpp | 12 ++---- components/esm/loadcell.hpp | 3 +- 7 files changed, 59 insertions(+), 43 deletions(-) diff --git a/apps/openmw/mwworld/cellreflist.hpp b/apps/openmw/mwworld/cellreflist.hpp index 49197d167..0ce603224 100644 --- a/apps/openmw/mwworld/cellreflist.hpp +++ b/apps/openmw/mwworld/cellreflist.hpp @@ -22,7 +22,7 @@ namespace MWWorld /// and the build will fail with an ugly three-way cyclic header dependence /// so we need to pass the instantiation of the method to the linker, when /// all methods are known. - void load (ESM::CellRef &ref, bool deleted, const MWWorld::ESMStore &esmStore); + void load (ESM::CellRef &ref, const MWWorld::ESMStore &esmStore); LiveRef *find (const std::string& name) { diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index b33a6f8db..a51672581 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -147,7 +147,7 @@ namespace MWWorld { template - void CellRefList::load(ESM::CellRef &ref, bool deleted, const MWWorld::ESMStore &esmStore) + void CellRefList::load(ESM::CellRef &ref, const MWWorld::ESMStore &esmStore) { const MWWorld::Store &store = esmStore.get(); @@ -158,7 +158,7 @@ namespace MWWorld LiveRef liveCellRef (ref, ptr); - if (deleted) + if (ref.mIsDeleted) liveCellRef.mData.setDeleted(true); if (iter != mList.end()) @@ -374,10 +374,9 @@ namespace MWWorld ESM::CellRef ref; // Get each reference in turn - bool deleted = false; - while (mCell->getNextRef (esm[index], ref, deleted)) + while (mCell->getNextRef (esm[index], ref)) { - if (deleted) + if (ref.mIsDeleted) continue; // Don't list reference if it was moved to a different cell. @@ -420,8 +419,7 @@ namespace MWWorld ref.mRefNum.mContentFile = ESM::RefNum::RefNum_NoContentFile; // Get each reference in turn - bool deleted = false; - while(mCell->getNextRef(esm[index], ref, deleted)) + while(mCell->getNextRef(esm[index], ref)) { // Don't load reference if it was moved to a different cell. ESM::MovedCellRefTracker::const_iterator iter = @@ -430,7 +428,7 @@ namespace MWWorld continue; } - loadRef (ref, deleted, store); + loadRef (ref, store); } } @@ -439,7 +437,7 @@ namespace MWWorld { ESM::CellRef &ref = const_cast(*it); - loadRef (ref, false, store); + loadRef (ref, store); } } @@ -468,32 +466,32 @@ namespace MWWorld return Ptr(); } - void CellStore::loadRef (ESM::CellRef& ref, bool deleted, const ESMStore& store) + void CellStore::loadRef (ESM::CellRef& ref, const ESMStore& store) { Misc::StringUtils::toLower (ref.mRefID); switch (store.find (ref.mRefID)) { - case ESM::REC_ACTI: mActivators.load(ref, deleted, store); break; - case ESM::REC_ALCH: mPotions.load(ref, deleted, store); break; - case ESM::REC_APPA: mAppas.load(ref, deleted, store); break; - case ESM::REC_ARMO: mArmors.load(ref, deleted, store); break; - case ESM::REC_BOOK: mBooks.load(ref, deleted, store); break; - case ESM::REC_CLOT: mClothes.load(ref, deleted, store); break; - case ESM::REC_CONT: mContainers.load(ref, deleted, store); break; - case ESM::REC_CREA: mCreatures.load(ref, deleted, store); break; - case ESM::REC_DOOR: mDoors.load(ref, deleted, store); break; - case ESM::REC_INGR: mIngreds.load(ref, deleted, store); break; - case ESM::REC_LEVC: mCreatureLists.load(ref, deleted, store); break; - case ESM::REC_LEVI: mItemLists.load(ref, deleted, store); break; - case ESM::REC_LIGH: mLights.load(ref, deleted, store); break; - case ESM::REC_LOCK: mLockpicks.load(ref, deleted, store); break; - case ESM::REC_MISC: mMiscItems.load(ref, deleted, store); break; - 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_WEAP: mWeapons.load(ref, deleted, store); break; + case ESM::REC_ACTI: mActivators.load(ref, store); break; + case ESM::REC_ALCH: mPotions.load(ref,store); break; + case ESM::REC_APPA: mAppas.load(ref, store); break; + case ESM::REC_ARMO: mArmors.load(ref, store); break; + case ESM::REC_BOOK: mBooks.load(ref, store); break; + case ESM::REC_CLOT: mClothes.load(ref, store); break; + case ESM::REC_CONT: mContainers.load(ref, store); break; + case ESM::REC_CREA: mCreatures.load(ref, store); break; + case ESM::REC_DOOR: mDoors.load(ref, store); break; + case ESM::REC_INGR: mIngreds.load(ref, store); break; + case ESM::REC_LEVC: mCreatureLists.load(ref, store); break; + case ESM::REC_LEVI: mItemLists.load(ref, store); break; + case ESM::REC_LIGH: mLights.load(ref, store); break; + case ESM::REC_LOCK: mLockpicks.load(ref, store); break; + case ESM::REC_MISC: mMiscItems.load(ref, store); break; + case ESM::REC_NPC_: mNpcs.load(ref, store); break; + case ESM::REC_PROB: mProbes.load(ref, store); break; + case ESM::REC_REPA: mRepairs.load(ref, store); break; + case ESM::REC_STAT: mStatics.load(ref, store); break; + case ESM::REC_WEAP: mWeapons.load(ref, store); break; case 0: std::cerr << "Cell reference " + ref.mRefID + " not found!\n"; break; diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index f879343d9..5caa4eeea 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -214,7 +214,7 @@ namespace MWWorld void loadRefs(const MWWorld::ESMStore &store, std::vector &esm); - void loadRef (ESM::CellRef& ref, bool deleted, const ESMStore& store); + void loadRef (ESM::CellRef& ref, const ESMStore& store); ///< Make case-adjustments to \a ref and insert it into the respective container. /// /// Invalid \a ref objects are silently dropped. diff --git a/components/esm/cellref.cpp b/components/esm/cellref.cpp index c3b889df5..e43a37b66 100644 --- a/components/esm/cellref.cpp +++ b/components/esm/cellref.cpp @@ -3,6 +3,17 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "util.hpp" + +ESM::CellRef::CellRef() + : mScale(1.0f), + mFactionRank(-2), + mEnchantmentCharge(-1), + mGoldValue(1), + mChargeInt(-1), + mLockLevel(0), + mIsDeleted(false) +{} void ESM::RefNum::load (ESMReader& esm, bool wide) { @@ -27,6 +38,7 @@ void ESM::RefNum::save (ESMWriter &esm, bool wide, const std::string& tag) const void ESM::CellRef::load (ESMReader& esm, bool wideRefNum) { + mIsDeleted = false; loadId(esm, wideRefNum); loadData(esm); } @@ -97,6 +109,8 @@ void ESM::CellRef::loadData(ESMReader &esm) if (esm.isNextSub("NAM0")) esm.skipHSub(); + + mIsDeleted = readDeleSubRecord (esm); } void ESM::CellRef::save (ESMWriter &esm, bool wideRefNum, bool inInventory) const @@ -149,6 +163,11 @@ void ESM::CellRef::save (ESMWriter &esm, bool wideRefNum, bool inInventory) cons if (!inInventory) esm.writeHNT("DATA", mPos, 24); + + if (mIsDeleted) + { + writeDeleSubRecord(esm); + } } void ESM::CellRef::blank() @@ -178,6 +197,8 @@ void ESM::CellRef::blank() mPos.pos[i] = 0; mPos.rot[i] = 0; } + + mIsDeleted = false; } bool ESM::operator== (const RefNum& left, const RefNum& right) diff --git a/components/esm/cellref.hpp b/components/esm/cellref.hpp index e9959611b..553dbaae3 100644 --- a/components/esm/cellref.hpp +++ b/components/esm/cellref.hpp @@ -99,6 +99,10 @@ namespace ESM // Position and rotation of this object within the cell Position mPos; + bool mIsDeleted; + + CellRef(); + /// Calls loadId and loadData void load (ESMReader& esm, bool wideRefNum = false); diff --git a/components/esm/loadcell.cpp b/components/esm/loadcell.cpp index 86b4e4edb..67701a5b7 100644 --- a/components/esm/loadcell.cpp +++ b/components/esm/loadcell.cpp @@ -177,7 +177,7 @@ std::string Cell::getDescription() const } } -bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted, bool ignoreMoves, MovedCellRef *mref) +bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool ignoreMoves, MovedCellRef *mref) { // TODO: Try and document reference numbering, I don't think this has been done anywhere else. if (!esm.hasMoreSubs()) @@ -206,14 +206,6 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted, bool ignoreMo // Identify references belonging to a parent file and adapt the ID accordingly. adjustRefNum (ref.mRefNum, esm); - if (esm.isNextSub("DELE")) - { - esm.skipHSub(); - deleted = true; - } - else - deleted = false; - return true; } @@ -244,6 +236,8 @@ bool Cell::getNextMVRF(ESMReader &esm, MovedCellRef &mref) mAmbi.mSunlight = 0; mAmbi.mFog = 0; mAmbi.mFogDensity = 0; + + mIsDeleted = false; } CellId Cell::getCellId() const diff --git a/components/esm/loadcell.hpp b/components/esm/loadcell.hpp index bf65c5fa8..a1a758e3b 100644 --- a/components/esm/loadcell.hpp +++ b/components/esm/loadcell.hpp @@ -163,8 +163,7 @@ struct Cell reuse one memory location without blanking it between calls. */ /// \param ignoreMoves ignore MVRF record and read reference like a regular CellRef. - static bool getNextRef(ESMReader &esm, - CellRef &ref, bool& deleted, bool ignoreMoves = false, MovedCellRef *mref = 0); + static bool getNextRef(ESMReader &esm, CellRef &ref, bool ignoreMoves = false, MovedCellRef *mref = 0); /* This fetches an MVRF record, which is used to track moved references. * Since they are comparably rare, we use a separate method for this.