diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index 9117e40de0..486425156b 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -59,6 +59,38 @@ namespace { + template + struct RecordToState + { + using StateType = ESM::ObjectState; + }; + + template <> + struct RecordToState + { + using StateType = ESM::NpcState; + }; + template <> + struct RecordToState + { + using StateType = ESM::CreatureState; + }; + template <> + struct RecordToState + { + using StateType = ESM::DoorState; + }; + template <> + struct RecordToState + { + using StateType = ESM::ContainerState; + }; + template <> + struct RecordToState + { + using StateType = ESM::CreatureLevListState; + }; + template MWWorld::Ptr searchInContainerList(MWWorld::CellRefList& containerList, std::string_view id) { @@ -99,7 +131,7 @@ namespace return MWWorld::Ptr(); } - template + template void writeReferenceCollection (ESM::ESMWriter& writer, const MWWorld::CellRefList& collection) { @@ -120,8 +152,8 @@ namespace // Deleted reference that did not come from a content file -> ignore continue; } - - RecordType state; + using StateType = RecordToState::StateType; + StateType state; iter->save (state); // recordId currently unused @@ -171,13 +203,14 @@ namespace fixRestockingImpl(base, state); } - template + template void readReferenceCollection (ESM::ESMReader& reader, MWWorld::CellRefList& collection, const ESM::CellRef& cref, const std::map& contentFileMap, MWWorld::CellStore* cellstore) { const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); - RecordType state; + using StateType = RecordToState::StateType; + StateType state; state.mRef = cref; state.load(reader); @@ -205,14 +238,14 @@ namespace fixRestocking(record, state); if (state.mVersion < 17) { - if constexpr (std::is_same_v && std::is_same_v) + if constexpr (std::is_same_v) MWWorld::convertMagicEffects(state.mCreatureStats, state.mInventory); - else if constexpr (std::is_same_v&& std::is_same_v) + else if constexpr (std::is_same_v) MWWorld::convertMagicEffects(state.mCreatureStats, state.mInventory, &state.mNpcStats); } else if(state.mVersion < 20) { - if constexpr ((std::is_same_v && std::is_same_v )|| (std::is_same_v&& std::is_same_v)) + if constexpr (std::is_same_v|| std::is_same_v) MWWorld::convertStats(state.mCreatureStats); } @@ -861,27 +894,7 @@ namespace MWWorld void CellStore::writeReferences (ESM::ESMWriter& writer) const { - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); - writeReferenceCollection (writer, get()); + Misc::tupleForEach(this->mCellStoreImp->mRefLists, [&writer](auto& cellRefList) { writeReferenceCollection(writer, cellRefList); }); for (const auto& [base, store] : mMovedToAnotherCell) { @@ -919,48 +932,18 @@ namespace MWWorld continue; } - switch (type) + if (type != 0) { - case ESM::REC_ACTI: - case ESM::REC_ALCH: - case ESM::REC_APPA: - case ESM::REC_ARMO: - case ESM::REC_BOOK: - case ESM::REC_CLOT: - case ESM::REC_INGR: - case ESM::REC_LEVI: - case ESM::REC_LIGH: - case ESM::REC_LOCK: - case ESM::REC_MISC: - case ESM::REC_PROB: - case ESM::REC_REPA: - case ESM::REC_STAT: - case ESM::REC_WEAP: - case ESM::REC_BODY: - Misc::tupleForEach(this->mCellStoreImp->mRefLists, [&reader, this, &cref, &contentFileMap, type](auto&& x) { - recNameSwitcher(x, static_cast(type), [&reader, this, &cref, &contentFileMap](auto& store) { - readReferenceCollection(reader, store, cref, contentFileMap, this); + bool foundCorrespondingStore = false; + Misc::tupleForEach(this->mCellStoreImp->mRefLists, [&reader, this, &cref, &contentFileMap, &foundCorrespondingStore, type](auto&& x) { + recNameSwitcher(x, static_cast(type), [&reader, this, &cref, &contentFileMap, &foundCorrespondingStore](auto& store) { + foundCorrespondingStore = true; + readReferenceCollection(reader, store, cref, contentFileMap, this); }); }); - break; - case ESM::REC_CONT: - readReferenceCollection (reader, get(), cref, contentFileMap, this); - break; - case ESM::REC_CREA: - readReferenceCollection (reader, get(), cref, contentFileMap, this); - break; - case ESM::REC_DOOR: - readReferenceCollection (reader, get(), cref, contentFileMap, this); - break; - case ESM::REC_LEVC: - readReferenceCollection (reader, get(), cref, contentFileMap, this); - break; - case ESM::REC_NPC_: - readReferenceCollection (reader, get(), cref, contentFileMap, this); - break; - default: - - throw std::runtime_error ("unknown type in cell reference section"); + + if (!foundCorrespondingStore) + throw std::runtime_error("unknown type in cell reference section"); } }