diff --git a/apps/openmw/mwworld/cellreflist.hpp b/apps/openmw/mwworld/cellreflist.hpp index 0ce603224..49197d167 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, const MWWorld::ESMStore &esmStore); + void load (ESM::CellRef &ref, bool deleted, 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 a51672581..e9f9c5cd1 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, const MWWorld::ESMStore &esmStore) + void CellRefList::load(ESM::CellRef &ref, bool deleted, const MWWorld::ESMStore &esmStore) { const MWWorld::Store &store = esmStore.get(); @@ -158,7 +158,7 @@ namespace MWWorld LiveRef liveCellRef (ref, ptr); - if (ref.mIsDeleted) + if (deleted) liveCellRef.mData.setDeleted(true); if (iter != mList.end()) @@ -374,9 +374,10 @@ namespace MWWorld ESM::CellRef ref; // Get each reference in turn - while (mCell->getNextRef (esm[index], ref)) + bool deleted = false; + while (mCell->getNextRef (esm[index], ref, deleted)) { - if (ref.mIsDeleted) + if (deleted) continue; // Don't list reference if it was moved to a different cell. @@ -419,7 +420,8 @@ namespace MWWorld ref.mRefNum.mContentFile = ESM::RefNum::RefNum_NoContentFile; // Get each reference in turn - while(mCell->getNextRef(esm[index], ref)) + bool deleted = false; + while(mCell->getNextRef(esm[index], ref, deleted)) { // Don't load reference if it was moved to a different cell. ESM::MovedCellRefTracker::const_iterator iter = @@ -428,7 +430,7 @@ namespace MWWorld continue; } - loadRef (ref, store); + loadRef (ref, deleted, store); } } @@ -437,7 +439,7 @@ namespace MWWorld { ESM::CellRef &ref = const_cast(*it); - loadRef (ref, store); + loadRef (ref, false, store); } } @@ -466,32 +468,32 @@ namespace MWWorld return Ptr(); } - void CellStore::loadRef (ESM::CellRef& ref, const ESMStore& store) + void CellStore::loadRef (ESM::CellRef& ref, bool deleted, const ESMStore& store) { Misc::StringUtils::toLower (ref.mRefID); switch (store.find (ref.mRefID)) { - 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 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 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 5caa4eeea..f879343d9 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, const ESMStore& store); + void loadRef (ESM::CellRef& ref, bool deleted, 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/apps/openmw/mwworld/globals.cpp b/apps/openmw/mwworld/globals.cpp index 668a33f09..87070a712 100644 --- a/apps/openmw/mwworld/globals.cpp +++ b/apps/openmw/mwworld/globals.cpp @@ -92,7 +92,11 @@ namespace MWWorld if (type==ESM::REC_GLOB) { ESM::Global global; - global.load(reader); + bool isDeleted = false; + + // This readRecord() method is used when reading a saved game. + // Deleted globals can't appear there, so isDeleted will be ignored here. + global.load(reader, isDeleted); Misc::StringUtils::toLower(global.mId); Collection::iterator iter = mVariables.find (global.mId); diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index 55fb43e00..cd9290bfc 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -66,7 +66,9 @@ namespace MWWorld void IndexedStore::load(ESM::ESMReader &esm) { T record; - record.load(esm); + bool isDeleted = false; + + record.load(esm, isDeleted); // Try to overwrite existing record std::pair ret = mStatic.insert(std::make_pair(record.mIndex, record)); @@ -187,14 +189,16 @@ namespace MWWorld RecordId Store::load(ESM::ESMReader &esm) { T record; - record.load(esm); + bool isDeleted = false; + + record.load(esm, isDeleted); Misc::StringUtils::toLower(record.mId); std::pair inserted = mStatic.insert(std::make_pair(record.mId, record)); if (inserted.second) mShared.push_back(&inserted.first->second); - return RecordId(record.mId, record.mIsDeleted); + return RecordId(record.mId, isDeleted); } template void Store::setUp() @@ -324,10 +328,12 @@ namespace MWWorld RecordId Store::read(ESM::ESMReader& reader) { T record; - record.load (reader); + bool isDeleted = false; + + record.load (reader, isDeleted); insert (record); - return RecordId(record.mId, record.mIsDeleted); + return RecordId(record.mId, isDeleted); } // LandTexture @@ -370,7 +376,9 @@ namespace MWWorld RecordId Store::load(ESM::ESMReader &esm, size_t plugin) { ESM::LandTexture lt; - lt.load(esm); + bool isDeleted = false; + + lt.load(esm, isDeleted); // Make sure we have room for the structure if (plugin >= mStatic.size()) { @@ -383,7 +391,7 @@ namespace MWWorld // Store it ltexl[lt.mIndex] = lt; - return RecordId(lt.mId, lt.mIsDeleted); + return RecordId(lt.mId, isDeleted); } RecordId Store::load(ESM::ESMReader &esm) { @@ -449,7 +457,9 @@ namespace MWWorld RecordId Store::load(ESM::ESMReader &esm) { ESM::Land *ptr = new ESM::Land(); - ptr->load(esm); + bool isDeleted = false; + + ptr->load(esm, isDeleted); // Same area defined in multiple plugins? -> last plugin wins // Can't use search() because we aren't sorted yet - is there any other way to speed this up? @@ -465,7 +475,7 @@ namespace MWWorld mStatic.push_back(ptr); - return RecordId(); // No ID and can't be deleted (for now) + return RecordId("", isDeleted); } void Store::setUp() { @@ -617,12 +627,12 @@ namespace MWWorld // All cells have a name record, even nameless exterior cells. ESM::Cell cell; - cell.loadName(esm); - std::string idLower = Misc::StringUtils::lowerCase(cell.mName); + bool isDeleted = false; - // Load the (x,y) coordinates of the cell, if it is an exterior cell, + // Load the (x,y) coordinates of the cell, if it is an exterior cell, // so we can find the cell we need to merge with - cell.loadData(esm); + cell.loadNameAndData(esm, isDeleted); + std::string idLower = Misc::StringUtils::lowerCase(cell.mName); if(cell.mData.mFlags & ESM::Cell::Interior) { @@ -690,7 +700,8 @@ namespace MWWorld mExt[std::make_pair(cell.mData.mX, cell.mData.mY)] = cell; } } - return RecordId("", cell.mIsDeleted); + + return RecordId(cell.mName, isDeleted); } Store::iterator Store::intBegin() const { @@ -849,7 +860,9 @@ namespace MWWorld RecordId Store::load(ESM::ESMReader &esm) { ESM::Pathgrid pathgrid; - pathgrid.load(esm); + bool isDeleted = false; + + pathgrid.load(esm, isDeleted); // Unfortunately the Pathgrid record model does not specify whether the pathgrid belongs to an interior or exterior cell. // For interior cells, mCell is the cell name, but for exterior cells it is either the cell name or if that doesn't exist, the cell's region name. @@ -872,7 +885,7 @@ namespace MWWorld ret.first->second = pathgrid; } - return RecordId(); // No ID and can't be deleted (for now) + return RecordId("", isDeleted); } size_t Store::getSize() const { @@ -1027,22 +1040,24 @@ namespace MWWorld inline RecordId Store::load(ESM::ESMReader &esm) { // The original letter case of a dialogue ID is saved, because it's printed ESM::Dialogue dialogue; + bool isDeleted = false; + dialogue.loadId(esm); std::string idLower = Misc::StringUtils::lowerCase(dialogue.mId); std::map::iterator found = mStatic.find(idLower); if (found == mStatic.end()) { - dialogue.loadData(esm); + dialogue.loadData(esm, isDeleted); mStatic.insert(std::make_pair(idLower, dialogue)); } else { - found->second.loadData(esm); + found->second.loadData(esm, isDeleted); dialogue = found->second; } - return RecordId(dialogue.mId, dialogue.mIsDeleted); + return RecordId(dialogue.mId, isDeleted); } @@ -1052,7 +1067,9 @@ namespace MWWorld template <> inline RecordId Store::load(ESM::ESMReader &esm) { ESM::Script script; - script.load(esm); + bool isDeleted = false; + + script.load(esm, isDeleted); Misc::StringUtils::toLower(script.mId); std::pair inserted = mStatic.insert(std::make_pair(script.mId, script)); @@ -1061,7 +1078,7 @@ namespace MWWorld else inserted.first->second = script; - return RecordId(script.mId, script.mIsDeleted); + return RecordId(script.mId, isDeleted); } @@ -1072,7 +1089,9 @@ namespace MWWorld inline RecordId Store::load(ESM::ESMReader &esm) { ESM::StartScript script; - script.load(esm); + bool isDeleted = false; + + script.load(esm, isDeleted); Misc::StringUtils::toLower(script.mId); std::pair inserted = mStatic.insert(std::make_pair(script.mId, script)); @@ -1081,36 +1100,7 @@ namespace MWWorld else inserted.first->second = script; - return RecordId(script.mId); - } - - // GameSetting - // Need to specialize load() and read() methods, because GameSetting can't - // be deleted (has no mIsDeleted flag) - //========================================================================= - - template <> - inline RecordId Store::load(ESM::ESMReader &reader) - { - ESM::GameSetting setting; - setting.load(reader); - Misc::StringUtils::toLower(setting.mId); - - std::pair inserted = mStatic.insert(std::make_pair(setting.mId, setting)); - if (inserted.second) - mShared.push_back(&inserted.first->second); - - return RecordId(setting.mId); - } - - template <> - inline RecordId Store::read(ESM::ESMReader &reader) - { - ESM::GameSetting setting; - setting.load(reader); - insert(setting); - - return RecordId(setting.mId); + return RecordId(script.mId, isDeleted); } }