mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-21 20:11:34 +00:00
Store refactor: Now way easier to create new stores, a good chunk of it is automated, only simple macros are used now
The case of indexedStores remains an issue, because they can't be stored with the rest because they don't inherit of store base
This commit is contained in:
parent
a78db85178
commit
1ed2244298
2 changed files with 247 additions and 382 deletions
|
@ -188,59 +188,19 @@ AddStoreType(ESM::Attribute);
|
||||||
|
|
||||||
static const int sRecordTypeCount = sRecordTypeCounter;
|
static const int sRecordTypeCount = sRecordTypeCounter;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
|
||||||
struct ESMStoreImp
|
struct ESMStoreImp
|
||||||
{
|
{
|
||||||
Store<ESM::Activator> mActivators;
|
//These 3 don't inherit from store base
|
||||||
Store<ESM::Potion> mPotions;
|
Store<ESM::MagicEffect> mMagicEffect;
|
||||||
Store<ESM::Apparatus> mAppas;
|
Store<ESM::Skill> mSkills;
|
||||||
Store<ESM::Armor> mArmors;
|
Store<ESM::Attribute> mAttributes;
|
||||||
Store<ESM::BodyPart> mBodyParts;
|
|
||||||
Store<ESM::Book> mBooks;
|
|
||||||
Store<ESM::BirthSign> mBirthSigns;
|
|
||||||
Store<ESM::Class> mClasses;
|
|
||||||
Store<ESM::Clothing> mClothes;
|
|
||||||
Store<ESM::Container> mContainers;
|
|
||||||
Store<ESM::Creature> mCreatures;
|
|
||||||
Store<ESM::Dialogue> mDialogs;
|
|
||||||
Store<ESM::Door> mDoors;
|
|
||||||
Store<ESM::Enchantment> mEnchants;
|
|
||||||
Store<ESM::Faction> mFactions;
|
|
||||||
Store<ESM::Global> mGlobals;
|
|
||||||
Store<ESM::Ingredient> mIngreds;
|
|
||||||
Store<ESM::CreatureLevList> mCreatureLists;
|
|
||||||
Store<ESM::ItemLevList> mItemLists;
|
|
||||||
Store<ESM::Light> mLights;
|
|
||||||
Store<ESM::Lockpick> mLockpicks;
|
|
||||||
Store<ESM::Miscellaneous> mMiscItems;
|
|
||||||
Store<ESM::NPC> mNpcs;
|
|
||||||
Store<ESM::Probe> mProbes;
|
|
||||||
Store<ESM::Race> mRaces;
|
|
||||||
Store<ESM::Region> mRegions;
|
|
||||||
Store<ESM::Repair> mRepairs;
|
|
||||||
Store<ESM::SoundGenerator> mSoundGens;
|
|
||||||
Store<ESM::Sound> mSounds;
|
|
||||||
Store<ESM::Spell> mSpells;
|
|
||||||
Store<ESM::StartScript> mStartScripts;
|
|
||||||
Store<ESM::Static> mStatics;
|
|
||||||
Store<ESM::Weapon> mWeapons;
|
|
||||||
|
|
||||||
Store<ESM::GameSetting> mGameSettings;
|
std::map<int, int> mESM3RecordToRecordId;
|
||||||
Store<ESM::Script> mScripts;
|
|
||||||
|
|
||||||
// Lists that need special rules
|
|
||||||
Store<ESM::Cell> mCells;
|
|
||||||
Store<ESM::Land> mLands;
|
|
||||||
Store<ESM::LandTexture> mLandTextures;
|
|
||||||
Store<ESM::Pathgrid> mPathgrids;
|
|
||||||
|
|
||||||
Store<ESM::MagicEffect> mMagicEffects;
|
|
||||||
Store<ESM::Skill> mSkills;
|
|
||||||
|
|
||||||
// Special entry which is hardcoded and not loaded from an ESM
|
|
||||||
Store<ESM::Attribute> mAttributes;
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static const T* ESM3StoreInsert(ESMStore& stores, const T &toInsert)
|
static const T* ESM3StoreInsert(ESMStore& stores, const T &toInsert)
|
||||||
|
@ -258,10 +218,11 @@ namespace MWWorld
|
||||||
record.mId = id;
|
record.mId = id;
|
||||||
|
|
||||||
T *ptr = store.insert(record);
|
T *ptr = store.insert(record);
|
||||||
for (ESMStore::iterator it = stores.mStores.begin(); it != stores.mStores.end(); ++it) {
|
auto esm3RecordType_find = stores.mStoreImp->mESM3RecordToRecordId.find(GetRecordTypeId(T));
|
||||||
if (it->second == &store) {
|
|
||||||
stores.mIds[ptr->mId] = it->first;
|
if (esm3RecordType_find != stores.mStoreImp->mESM3RecordToRecordId.end())
|
||||||
}
|
{
|
||||||
|
stores.mIds[ptr->mId] = esm3RecordType_find->first;
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
@ -271,10 +232,10 @@ namespace MWWorld
|
||||||
Store<T> &store = const_cast<Store<T> &>( stores.get<T>());
|
Store<T> &store = const_cast<Store<T> &>( stores.get<T>());
|
||||||
|
|
||||||
T *ptr = store.insert(x);
|
T *ptr = store.insert(x);
|
||||||
for (ESMStore::iterator it = stores.mStores.begin(); it != stores.mStores.end(); ++it) {
|
auto esm3RecordType_find = stores.mStoreImp->mESM3RecordToRecordId.find(GetRecordTypeId(T));
|
||||||
if (it->second == &store) {
|
if (esm3RecordType_find != stores.mStoreImp->mESM3RecordToRecordId.end())
|
||||||
stores.mIds[ptr->mId] = it->first;
|
{
|
||||||
}
|
stores.mIds[ptr->mId] = esm3RecordType_find->first;
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
@ -293,60 +254,161 @@ namespace MWWorld
|
||||||
T record = x;
|
T record = x;
|
||||||
|
|
||||||
T *ptr = store.insertStatic(record);
|
T *ptr = store.insertStatic(record);
|
||||||
for (ESMStore::iterator it = stores.mStores.begin(); it != stores.mStores.end(); ++it) {
|
auto esm3RecordType_find = stores.mStoreImp->mESM3RecordToRecordId.find(GetRecordTypeId(T));
|
||||||
if (it->second == &store) {
|
if (esm3RecordType_find != stores.mStoreImp->mESM3RecordToRecordId.end())
|
||||||
stores.mIds[ptr->mId] = it->first;
|
{
|
||||||
}
|
stores.mIds[ptr->mId] = esm3RecordType_find->first;
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ESMStoreImp()
|
||||||
|
{
|
||||||
|
mESM3RecordToRecordId[ESM::REC_ACTI] = GetRecordTypeId(ESM::Activator);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_ALCH] = GetRecordTypeId(ESM::Potion);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_APPA] = GetRecordTypeId(ESM::Apparatus);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_ARMO] = GetRecordTypeId(ESM::Armor);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_BODY] = GetRecordTypeId(ESM::BodyPart);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_BOOK] = GetRecordTypeId(ESM::Book);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_BSGN] = GetRecordTypeId(ESM::BirthSign);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_CELL] = GetRecordTypeId(ESM::Cell);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_CLAS] = GetRecordTypeId(ESM::Class);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_CLOT] = GetRecordTypeId(ESM::Clothing);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_CONT] = GetRecordTypeId(ESM::Container);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_CREA] = GetRecordTypeId(ESM::Creature);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_DIAL] = GetRecordTypeId(ESM::Dialogue);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_DOOR] = GetRecordTypeId(ESM::Door);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_ENCH] = GetRecordTypeId(ESM::Enchantment);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_FACT] = GetRecordTypeId(ESM::Faction);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_GLOB] = GetRecordTypeId(ESM::Global);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_GMST] = GetRecordTypeId(ESM::GameSetting);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_INGR] = GetRecordTypeId(ESM::Ingredient);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_LAND] = GetRecordTypeId(ESM::Land);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_LEVC] = GetRecordTypeId(ESM::CreatureLevList);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_LEVI] = GetRecordTypeId(ESM::ItemLevList);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_LIGH] = GetRecordTypeId(ESM::Light);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_LOCK] = GetRecordTypeId(ESM::Lockpick);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_LTEX] = GetRecordTypeId(ESM::LandTexture);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_MISC] = GetRecordTypeId(ESM::Miscellaneous);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_NPC_] = GetRecordTypeId(ESM::NPC);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_PGRD] = GetRecordTypeId(ESM::Pathgrid);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_PROB] = GetRecordTypeId(ESM::Probe);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_RACE] = GetRecordTypeId(ESM::Race);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_REGN] = GetRecordTypeId(ESM::Region);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_REPA] = GetRecordTypeId(ESM::Repair);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_SCPT] = GetRecordTypeId(ESM::Script);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_SNDG] = GetRecordTypeId(ESM::SoundGenerator);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_SOUN] = GetRecordTypeId(ESM::Sound);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_SPEL] = GetRecordTypeId(ESM::Spell);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_SSCR] = GetRecordTypeId(ESM::StartScript);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_STAT] = GetRecordTypeId(ESM::Static);
|
||||||
|
mESM3RecordToRecordId[ESM::REC_WEAP] = GetRecordTypeId(ESM::Weapon);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define defineGetters(__Type) template <> const Store<__Type>& ESMStore::get<__Type>() const { return static_cast<const Store<__Type>&>(*mStores[GetRecordTypeId(__Type)]); } \
|
||||||
|
template <> Store<__Type>& ESMStore::getWritable<__Type>() { return static_cast<Store<__Type>&>(*mStores[GetRecordTypeId(__Type)]); }
|
||||||
|
|
||||||
|
defineGetters(ESM::Activator);
|
||||||
|
defineGetters(ESM::Potion);
|
||||||
|
defineGetters(ESM::Apparatus);
|
||||||
|
defineGetters(ESM::Armor);
|
||||||
|
defineGetters(ESM::BodyPart);
|
||||||
|
defineGetters(ESM::Book);
|
||||||
|
defineGetters(ESM::BirthSign);
|
||||||
|
defineGetters(ESM::Class);
|
||||||
|
defineGetters(ESM::Clothing);
|
||||||
|
defineGetters(ESM::Container);
|
||||||
|
defineGetters(ESM::Creature);
|
||||||
|
defineGetters(ESM::Dialogue);
|
||||||
|
defineGetters(ESM::Door);
|
||||||
|
defineGetters(ESM::Enchantment);
|
||||||
|
defineGetters(ESM::Faction);
|
||||||
|
defineGetters(ESM::Global);
|
||||||
|
defineGetters(ESM::Ingredient);
|
||||||
|
defineGetters(ESM::CreatureLevList);
|
||||||
|
defineGetters(ESM::ItemLevList);
|
||||||
|
defineGetters(ESM::Light);
|
||||||
|
defineGetters(ESM::Lockpick);
|
||||||
|
defineGetters(ESM::Miscellaneous);
|
||||||
|
defineGetters(ESM::NPC);
|
||||||
|
defineGetters(ESM::Probe);
|
||||||
|
defineGetters(ESM::Race);
|
||||||
|
defineGetters(ESM::Region);
|
||||||
|
defineGetters(ESM::Repair);
|
||||||
|
defineGetters(ESM::SoundGenerator);
|
||||||
|
defineGetters(ESM::Sound);
|
||||||
|
defineGetters(ESM::Spell);
|
||||||
|
defineGetters(ESM::StartScript);
|
||||||
|
defineGetters(ESM::Static);
|
||||||
|
defineGetters(ESM::Weapon);
|
||||||
|
defineGetters(ESM::GameSetting);
|
||||||
|
defineGetters(ESM::Script);
|
||||||
|
defineGetters(ESM::Cell);
|
||||||
|
defineGetters(ESM::Land);
|
||||||
|
defineGetters(ESM::LandTexture);
|
||||||
|
defineGetters(ESM::Pathgrid);
|
||||||
|
#undef defineGetters
|
||||||
|
template <> const Store<ESM::MagicEffect>& ESMStore::get<ESM::MagicEffect>() const { return mStoreImp->mMagicEffect; }
|
||||||
|
template <> Store<ESM::MagicEffect>& ESMStore::getWritable<ESM::MagicEffect>() { return mStoreImp->mMagicEffect; }
|
||||||
|
|
||||||
|
template <> const Store<ESM::Skill>& ESMStore::get<ESM::Skill>() const { return mStoreImp->mSkills; }
|
||||||
|
template <> Store<ESM::Skill>& ESMStore::getWritable<ESM::Skill>() { return mStoreImp->mSkills; }
|
||||||
|
|
||||||
|
template <> const Store<ESM::Attribute>& ESMStore::get<ESM::Attribute>() const { return mStoreImp->mAttributes; }
|
||||||
|
template <> Store<ESM::Attribute>& ESMStore::getWritable<ESM::Attribute>() { return mStoreImp->mAttributes; }
|
||||||
|
|
||||||
ESMStore::ESMStore()
|
ESMStore::ESMStore()
|
||||||
{
|
{
|
||||||
|
mStores.resize(sRecordTypeCount);
|
||||||
|
#define createStore(__Type) mStores[GetRecordTypeId(__Type)] = std::make_unique<Store<__Type>>();
|
||||||
|
|
||||||
|
createStore(ESM::Activator);
|
||||||
|
createStore(ESM::Potion);
|
||||||
|
createStore(ESM::Apparatus);
|
||||||
|
createStore(ESM::Armor);
|
||||||
|
createStore(ESM::BodyPart);
|
||||||
|
createStore(ESM::Book);
|
||||||
|
createStore(ESM::BirthSign);
|
||||||
|
createStore(ESM::Class);
|
||||||
|
createStore(ESM::Clothing);
|
||||||
|
createStore(ESM::Container);
|
||||||
|
createStore(ESM::Creature);
|
||||||
|
createStore(ESM::Dialogue);
|
||||||
|
createStore(ESM::Door);
|
||||||
|
createStore(ESM::Enchantment);
|
||||||
|
createStore(ESM::Faction);
|
||||||
|
createStore(ESM::Global);
|
||||||
|
createStore(ESM::Ingredient);
|
||||||
|
createStore(ESM::CreatureLevList);
|
||||||
|
createStore(ESM::ItemLevList);
|
||||||
|
createStore(ESM::Light);
|
||||||
|
createStore(ESM::Lockpick);
|
||||||
|
createStore(ESM::Miscellaneous);
|
||||||
|
createStore(ESM::NPC);
|
||||||
|
createStore(ESM::Probe);
|
||||||
|
createStore(ESM::Race);
|
||||||
|
createStore(ESM::Region);
|
||||||
|
createStore(ESM::Repair);
|
||||||
|
createStore(ESM::SoundGenerator);
|
||||||
|
createStore(ESM::Sound);
|
||||||
|
createStore(ESM::Spell);
|
||||||
|
createStore(ESM::StartScript);
|
||||||
|
createStore(ESM::Static);
|
||||||
|
createStore(ESM::Weapon);
|
||||||
|
createStore(ESM::GameSetting);
|
||||||
|
createStore(ESM::Script);
|
||||||
|
createStore(ESM::Cell);
|
||||||
|
createStore(ESM::Land);
|
||||||
|
createStore(ESM::LandTexture);
|
||||||
|
createStore(ESM::Pathgrid);
|
||||||
|
#undef createStore
|
||||||
|
|
||||||
mStoreImp = std::make_unique<ESMStoreImp>();
|
mStoreImp = std::make_unique<ESMStoreImp>();
|
||||||
mDynamicCount = 0;
|
mDynamicCount = 0;
|
||||||
mStores[ESM::REC_ACTI] = &mStoreImp->mActivators;
|
|
||||||
mStores[ESM::REC_ALCH] = &mStoreImp->mPotions;
|
|
||||||
mStores[ESM::REC_APPA] = &mStoreImp->mAppas;
|
|
||||||
mStores[ESM::REC_ARMO] = &mStoreImp->mArmors;
|
|
||||||
mStores[ESM::REC_BODY] = &mStoreImp->mBodyParts;
|
|
||||||
mStores[ESM::REC_BOOK] = &mStoreImp->mBooks;
|
|
||||||
mStores[ESM::REC_BSGN] = &mStoreImp->mBirthSigns;
|
|
||||||
mStores[ESM::REC_CELL] = &mStoreImp->mCells;
|
|
||||||
mStores[ESM::REC_CLAS] = &mStoreImp->mClasses;
|
|
||||||
mStores[ESM::REC_CLOT] = &mStoreImp->mClothes;
|
|
||||||
mStores[ESM::REC_CONT] = &mStoreImp->mContainers;
|
|
||||||
mStores[ESM::REC_CREA] = &mStoreImp->mCreatures;
|
|
||||||
mStores[ESM::REC_DIAL] = &mStoreImp->mDialogs;
|
|
||||||
mStores[ESM::REC_DOOR] = &mStoreImp->mDoors;
|
|
||||||
mStores[ESM::REC_ENCH] = &mStoreImp->mEnchants;
|
|
||||||
mStores[ESM::REC_FACT] = &mStoreImp->mFactions;
|
|
||||||
mStores[ESM::REC_GLOB] = &mStoreImp->mGlobals;
|
|
||||||
mStores[ESM::REC_GMST] = &mStoreImp->mGameSettings;
|
|
||||||
mStores[ESM::REC_INGR] = &mStoreImp->mIngreds;
|
|
||||||
mStores[ESM::REC_LAND] = &mStoreImp->mLands;
|
|
||||||
mStores[ESM::REC_LEVC] = &mStoreImp->mCreatureLists;
|
|
||||||
mStores[ESM::REC_LEVI] = &mStoreImp->mItemLists;
|
|
||||||
mStores[ESM::REC_LIGH] = &mStoreImp->mLights;
|
|
||||||
mStores[ESM::REC_LOCK] = &mStoreImp->mLockpicks;
|
|
||||||
mStores[ESM::REC_LTEX] = &mStoreImp->mLandTextures;
|
|
||||||
mStores[ESM::REC_MISC] = &mStoreImp->mMiscItems;
|
|
||||||
mStores[ESM::REC_NPC_] = &mStoreImp->mNpcs;
|
|
||||||
mStores[ESM::REC_PGRD] = &mStoreImp->mPathgrids;
|
|
||||||
mStores[ESM::REC_PROB] = &mStoreImp->mProbes;
|
|
||||||
mStores[ESM::REC_RACE] = &mStoreImp->mRaces;
|
|
||||||
mStores[ESM::REC_REGN] = &mStoreImp->mRegions;
|
|
||||||
mStores[ESM::REC_REPA] = &mStoreImp->mRepairs;
|
|
||||||
mStores[ESM::REC_SCPT] = &mStoreImp->mScripts;
|
|
||||||
mStores[ESM::REC_SNDG] = &mStoreImp->mSoundGens;
|
|
||||||
mStores[ESM::REC_SOUN] = &mStoreImp->mSounds;
|
|
||||||
mStores[ESM::REC_SPEL] = &mStoreImp->mSpells;
|
|
||||||
mStores[ESM::REC_SSCR] = &mStoreImp->mStartScripts;
|
|
||||||
mStores[ESM::REC_STAT] = &mStoreImp->mStatics;
|
|
||||||
mStores[ESM::REC_WEAP] = &mStoreImp->mWeapons;
|
|
||||||
|
|
||||||
mStoreImp->mPathgrids.setCells(mStoreImp->mCells);
|
getWritable<ESM::Pathgrid>().setCells(getWritable<ESM::Cell>());
|
||||||
}
|
}
|
||||||
|
|
||||||
ESMStore::~ESMStore()
|
ESMStore::~ESMStore()
|
||||||
|
@ -355,8 +417,8 @@ namespace MWWorld
|
||||||
|
|
||||||
void ESMStore::clearDynamic()
|
void ESMStore::clearDynamic()
|
||||||
{
|
{
|
||||||
for (std::map<int, StoreBase *>::iterator it = mStores.begin(); it != mStores.end(); ++it)
|
for (std::vector<std::unique_ptr< StoreBase >>::iterator it = mStores.begin(); it != mStores.end(); ++it)
|
||||||
it->second->clearDynamic();
|
(*it)->clearDynamic();
|
||||||
|
|
||||||
movePlayerRecord();
|
movePlayerRecord();
|
||||||
}
|
}
|
||||||
|
@ -383,7 +445,7 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener, ESM::Dialo
|
||||||
// Land texture loading needs to use a separate internal store for each plugin.
|
// Land texture loading needs to use a separate internal store for each plugin.
|
||||||
// We set the number of plugins here so we can properly verify if valid plugin
|
// We set the number of plugins here so we can properly verify if valid plugin
|
||||||
// indices are being passed to the LandTexture Store retrieval methods.
|
// indices are being passed to the LandTexture Store retrieval methods.
|
||||||
mStoreImp->mLandTextures.resize(esm.getIndex()+1);
|
getWritable<ESM::LandTexture>().resize(esm.getIndex()+1);
|
||||||
|
|
||||||
// Loop through all records
|
// Loop through all records
|
||||||
while(esm.hasMoreRecs())
|
while(esm.hasMoreRecs())
|
||||||
|
@ -397,9 +459,9 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener, ESM::Dialo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look up the record type.
|
// Look up the record type.
|
||||||
std::map<int, StoreBase *>::iterator it = mStores.find(n.toInt());
|
std::map<int, int>::iterator it = mStoreImp->mESM3RecordToRecordId.find(n.toInt());
|
||||||
|
|
||||||
if (it == mStores.end()) {
|
if (it == mStoreImp->mESM3RecordToRecordId.end()) {
|
||||||
if (n.toInt() == ESM::REC_INFO) {
|
if (n.toInt() == ESM::REC_INFO) {
|
||||||
if (dialogue)
|
if (dialogue)
|
||||||
{
|
{
|
||||||
|
@ -411,9 +473,9 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener, ESM::Dialo
|
||||||
esm.skipRecord();
|
esm.skipRecord();
|
||||||
}
|
}
|
||||||
} else if (n.toInt() == ESM::REC_MGEF) {
|
} else if (n.toInt() == ESM::REC_MGEF) {
|
||||||
mStoreImp->mMagicEffects.load (esm);
|
getWritable<ESM::MagicEffect>().load (esm);
|
||||||
} else if (n.toInt() == ESM::REC_SKIL) {
|
} else if (n.toInt() == ESM::REC_SKIL) {
|
||||||
mStoreImp->mSkills.load (esm);
|
getWritable<ESM::Skill>().load (esm);
|
||||||
}
|
}
|
||||||
else if (n.toInt() == ESM::REC_FILT || n.toInt() == ESM::REC_DBGP)
|
else if (n.toInt() == ESM::REC_FILT || n.toInt() == ESM::REC_DBGP)
|
||||||
{
|
{
|
||||||
|
@ -431,15 +493,15 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener, ESM::Dialo
|
||||||
throw std::runtime_error("Unknown record: " + n.toString());
|
throw std::runtime_error("Unknown record: " + n.toString());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
RecordId id = it->second->load(esm);
|
RecordId id = mStores[ it->second]->load(esm);
|
||||||
if (id.mIsDeleted)
|
if (id.mIsDeleted)
|
||||||
{
|
{
|
||||||
it->second->eraseStatic(id.mId);
|
mStores[ it->second]->eraseStatic(id.mId);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n.toInt() == ESM::REC_DIAL) {
|
if (n.toInt() == ESM::REC_DIAL) {
|
||||||
dialogue = const_cast<ESM::Dialogue*>(mStoreImp->mDialogs.find(id.mId));
|
dialogue = const_cast<ESM::Dialogue*>(getWritable<ESM::Dialogue>().find(id.mId));
|
||||||
} else {
|
} else {
|
||||||
dialogue = nullptr;
|
dialogue = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -479,14 +541,14 @@ void ESMStore::setUp()
|
||||||
{
|
{
|
||||||
mIds.clear();
|
mIds.clear();
|
||||||
|
|
||||||
std::map<int, StoreBase *>::iterator storeIt = mStores.begin();
|
std::map<int, int>::iterator storeIt = mStoreImp->mESM3RecordToRecordId.begin();
|
||||||
for (; storeIt != mStores.end(); ++storeIt) {
|
for (; storeIt != mStoreImp->mESM3RecordToRecordId.end(); ++storeIt) {
|
||||||
storeIt->second->setUp();
|
mStores[storeIt->second]->setUp();
|
||||||
|
|
||||||
if (isCacheableRecord(storeIt->first))
|
if (isCacheableRecord(storeIt->first))
|
||||||
{
|
{
|
||||||
std::vector<std::string> identifiers;
|
std::vector<std::string> identifiers;
|
||||||
storeIt->second->listIdentifier(identifiers);
|
mStores[storeIt->second]->listIdentifier(identifiers);
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator record = identifiers.begin(); record != identifiers.end(); ++record)
|
for (std::vector<std::string>::const_iterator record = identifiers.begin(); record != identifiers.end(); ++record)
|
||||||
mIds[*record] = storeIt->first;
|
mIds[*record] = storeIt->first;
|
||||||
|
@ -497,10 +559,10 @@ void ESMStore::setUp()
|
||||||
for (const auto& [k, v] : mIds)
|
for (const auto& [k, v] : mIds)
|
||||||
mStaticIds.emplace(Misc::StringUtils::lowerCase(k), v);
|
mStaticIds.emplace(Misc::StringUtils::lowerCase(k), v);
|
||||||
|
|
||||||
mStoreImp->mSkills.setUp();
|
getWritable<ESM::Skill>().setUp();
|
||||||
mStoreImp->mMagicEffects.setUp();
|
getWritable<ESM::MagicEffect>().setUp();;
|
||||||
mStoreImp->mAttributes.setUp();
|
getWritable<ESM::Attribute>().setUp();
|
||||||
mStoreImp->mDialogs.setUp();
|
getWritable<ESM::Dialogue>().setUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESMStore::validateRecords(ESM::ReadersCache& readers)
|
void ESMStore::validateRecords(ESM::ReadersCache& readers)
|
||||||
|
@ -517,9 +579,10 @@ void ESMStore::countAllCellRefs(ESM::ReadersCache& readers)
|
||||||
return;
|
return;
|
||||||
std::vector<Ref> refs;
|
std::vector<Ref> refs;
|
||||||
std::vector<std::string> refIDs;
|
std::vector<std::string> refIDs;
|
||||||
for(auto it = mStoreImp->mCells.intBegin(); it != mStoreImp->mCells.intEnd(); ++it)
|
Store<ESM::Cell> Cells = getWritable < ESM::Cell>();
|
||||||
|
for(auto it = Cells.intBegin(); it != Cells.intEnd(); ++it)
|
||||||
readRefs(*it, refs, refIDs, readers);
|
readRefs(*it, refs, refIDs, readers);
|
||||||
for(auto it = mStoreImp->mCells.extBegin(); it != mStoreImp->mCells.extEnd(); ++it)
|
for(auto it = Cells.extBegin(); it != Cells.extEnd(); ++it)
|
||||||
readRefs(*it, refs, refIDs, readers);
|
readRefs(*it, refs, refIDs, readers);
|
||||||
const auto lessByRefNum = [] (const Ref& l, const Ref& r) { return l.mRefNum < r.mRefNum; };
|
const auto lessByRefNum = [] (const Ref& l, const Ref& r) { return l.mRefNum < r.mRefNum; };
|
||||||
std::stable_sort(refs.begin(), refs.end(), lessByRefNum);
|
std::stable_sort(refs.begin(), refs.end(), lessByRefNum);
|
||||||
|
@ -548,17 +611,19 @@ int ESMStore::getRefCount(std::string_view id) const
|
||||||
|
|
||||||
void ESMStore::validate()
|
void ESMStore::validate()
|
||||||
{
|
{
|
||||||
std::vector<ESM::NPC> npcsToReplace = getNPCsToReplace(mStoreImp->mFactions, mStoreImp->mClasses, mStoreImp->mNpcs.mStatic);
|
auto& NPCs = getWritable<ESM::NPC>();
|
||||||
|
std::vector<ESM::NPC> npcsToReplace = getNPCsToReplace(getWritable<ESM::Faction>(), getWritable<ESM::Class>(), NPCs.mStatic);
|
||||||
|
|
||||||
for (const ESM::NPC &npc : npcsToReplace)
|
for (const ESM::NPC &npc : npcsToReplace)
|
||||||
{
|
{
|
||||||
mStoreImp->mNpcs.eraseStatic(npc.mId);
|
NPCs.eraseStatic(npc.mId);
|
||||||
mStoreImp->mNpcs.insertStatic(npc);
|
NPCs.insertStatic(npc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate spell effects for invalid arguments
|
// Validate spell effects for invalid arguments
|
||||||
std::vector<ESM::Spell> spellsToReplace;
|
std::vector<ESM::Spell> spellsToReplace;
|
||||||
for (ESM::Spell spell : mStoreImp->mSpells)
|
auto& Spells = getWritable<ESM::Spell>();
|
||||||
|
for (ESM::Spell spell : Spells)
|
||||||
{
|
{
|
||||||
if (spell.mEffects.mList.empty())
|
if (spell.mEffects.mList.empty())
|
||||||
continue;
|
continue;
|
||||||
|
@ -567,7 +632,7 @@ void ESMStore::validate()
|
||||||
auto iter = spell.mEffects.mList.begin();
|
auto iter = spell.mEffects.mList.begin();
|
||||||
while (iter != spell.mEffects.mList.end())
|
while (iter != spell.mEffects.mList.end())
|
||||||
{
|
{
|
||||||
const ESM::MagicEffect* mgef = mStoreImp->mMagicEffects.search(iter->mEffectID);
|
const ESM::MagicEffect* mgef = getWritable<ESM::MagicEffect>().search(iter->mEffectID);
|
||||||
if (!mgef)
|
if (!mgef)
|
||||||
{
|
{
|
||||||
Log(Debug::Verbose) << "Spell '" << spell.mId << "' has an invalid effect (index " << iter->mEffectID << ") present. Dropping the effect.";
|
Log(Debug::Verbose) << "Spell '" << spell.mId << "' has an invalid effect (index " << iter->mEffectID << ") present. Dropping the effect.";
|
||||||
|
@ -614,31 +679,35 @@ void ESMStore::validate()
|
||||||
|
|
||||||
for (const ESM::Spell &spell : spellsToReplace)
|
for (const ESM::Spell &spell : spellsToReplace)
|
||||||
{
|
{
|
||||||
mStoreImp->mSpells.eraseStatic(spell.mId);
|
Spells.eraseStatic(spell.mId);
|
||||||
mStoreImp->mSpells.insertStatic(spell);
|
Spells.insertStatic(spell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESMStore::movePlayerRecord()
|
void ESMStore::movePlayerRecord()
|
||||||
{
|
{
|
||||||
auto player = mStoreImp->mNpcs.find("player");
|
auto& NPCs = getWritable<ESM::NPC>();
|
||||||
mStoreImp->mNpcs.insert(*player);
|
auto player = NPCs.find("player");
|
||||||
|
NPCs.insert(*player);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESMStore::validateDynamic()
|
void ESMStore::validateDynamic()
|
||||||
{
|
{
|
||||||
std::vector<ESM::NPC> npcsToReplace = getNPCsToReplace(mStoreImp->mFactions, mStoreImp->mClasses, mStoreImp->mNpcs.mDynamic);
|
auto& NPCs = getWritable<ESM::NPC>();
|
||||||
|
auto& scripts = getWritable<ESM::Script>();
|
||||||
|
|
||||||
|
std::vector<ESM::NPC> npcsToReplace = getNPCsToReplace(getWritable<ESM::Faction>(), getWritable<ESM::Class>(), NPCs.mDynamic);
|
||||||
|
|
||||||
for (const ESM::NPC &npc : npcsToReplace)
|
for (const ESM::NPC &npc : npcsToReplace)
|
||||||
mStoreImp->mNpcs.insert(npc);
|
NPCs.insert(npc);
|
||||||
|
|
||||||
removeMissingScripts(mStoreImp->mScripts, mStoreImp->mArmors.mDynamic);
|
removeMissingScripts(scripts, getWritable<ESM::Armor>().mDynamic);
|
||||||
removeMissingScripts(mStoreImp->mScripts, mStoreImp->mBooks.mDynamic);
|
removeMissingScripts(scripts, getWritable<ESM::Book>().mDynamic);
|
||||||
removeMissingScripts(mStoreImp->mScripts, mStoreImp->mClothes.mDynamic);
|
removeMissingScripts(scripts, getWritable<ESM::Clothing>().mDynamic);
|
||||||
removeMissingScripts(mStoreImp->mScripts, mStoreImp->mWeapons.mDynamic);
|
removeMissingScripts(scripts, getWritable<ESM::Weapon>().mDynamic);
|
||||||
|
|
||||||
removeMissingObjects(mStoreImp->mCreatureLists);
|
removeMissingObjects(getWritable<ESM::CreatureLevList>());
|
||||||
removeMissingObjects(mStoreImp->mItemLists);
|
removeMissingObjects(getWritable<ESM::ItemLevList>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leveled lists can be modified by scripts. This removes items that no longer exist (presumably because the plugin was removed) from modified lists
|
// Leveled lists can be modified by scripts. This removes items that no longer exist (presumably because the plugin was removed) from modified lists
|
||||||
|
@ -663,19 +732,20 @@ void ESMStore::removeMissingObjects(Store<T>& store)
|
||||||
int ESMStore::countSavedGameRecords() const
|
int ESMStore::countSavedGameRecords() const
|
||||||
{
|
{
|
||||||
return 1 // DYNA (dynamic name counter)
|
return 1 // DYNA (dynamic name counter)
|
||||||
+mStoreImp->mPotions.getDynamicSize()
|
+ get<ESM::Potion>().getDynamicSize()
|
||||||
+mStoreImp->mArmors.getDynamicSize()
|
+ get<ESM::Armor>().getDynamicSize()
|
||||||
+mStoreImp->mBooks.getDynamicSize()
|
+ get<ESM::Book>().getDynamicSize()
|
||||||
+mStoreImp->mClasses.getDynamicSize()
|
+ get<ESM::Class>().getDynamicSize()
|
||||||
+mStoreImp->mClothes.getDynamicSize()
|
+ get<ESM::Clothing>().getDynamicSize()
|
||||||
+mStoreImp->mEnchants.getDynamicSize()
|
+ get<ESM::Enchantment>().getDynamicSize()
|
||||||
+mStoreImp->mNpcs.getDynamicSize()
|
+ get<ESM::NPC>().getDynamicSize()
|
||||||
+mStoreImp->mSpells.getDynamicSize()
|
+ get<ESM::Spell>().getDynamicSize()
|
||||||
+mStoreImp->mWeapons.getDynamicSize()
|
+ get<ESM::Weapon>().getDynamicSize()
|
||||||
+mStoreImp->mCreatureLists.getDynamicSize()
|
+ get<ESM::CreatureLevList>().getDynamicSize()
|
||||||
+mStoreImp->mItemLists.getDynamicSize()
|
+ get<ESM::ItemLevList>().getDynamicSize()
|
||||||
+mStoreImp->mCreatures.getDynamicSize()
|
+ get<ESM::Creature>().getDynamicSize()
|
||||||
+mStoreImp->mContainers.getDynamicSize();
|
+ get<ESM::Container>().getDynamicSize();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESMStore::write (ESM::ESMWriter& writer, Loading::Listener& progress) const
|
void ESMStore::write (ESM::ESMWriter& writer, Loading::Listener& progress) const
|
||||||
|
@ -686,19 +756,19 @@ void ESMStore::removeMissingObjects(Store<T>& store)
|
||||||
writer.endRecord("COUN");
|
writer.endRecord("COUN");
|
||||||
writer.endRecord(ESM::REC_DYNA);
|
writer.endRecord(ESM::REC_DYNA);
|
||||||
|
|
||||||
mStoreImp->mPotions.write (writer, progress);
|
get<ESM::Potion>().write (writer, progress);
|
||||||
mStoreImp->mArmors.write (writer, progress);
|
get<ESM::Armor>().write (writer, progress);
|
||||||
mStoreImp->mBooks.write (writer, progress);
|
get<ESM::Book>().write (writer, progress);
|
||||||
mStoreImp->mClasses.write (writer, progress);
|
get<ESM::Class>().write (writer, progress);
|
||||||
mStoreImp->mClothes.write (writer, progress);
|
get<ESM::Clothing>().write (writer, progress);
|
||||||
mStoreImp->mEnchants.write (writer, progress);
|
get<ESM::Enchantment>().write (writer, progress);
|
||||||
mStoreImp->mSpells.write (writer, progress);
|
get<ESM::NPC>().write (writer, progress);
|
||||||
mStoreImp->mWeapons.write (writer, progress);
|
get<ESM::Spell>().write (writer, progress);
|
||||||
mStoreImp->mNpcs.write (writer, progress);
|
get<ESM::Weapon>().write (writer, progress);
|
||||||
mStoreImp->mItemLists.write (writer, progress);
|
get<ESM::CreatureLevList>().write (writer, progress);
|
||||||
mStoreImp->mCreatureLists.write (writer, progress);
|
get<ESM::ItemLevList>().write (writer, progress);
|
||||||
mStoreImp->mCreatures.write (writer, progress);
|
get<ESM::Creature>().write (writer, progress);
|
||||||
mStoreImp->mContainers.write (writer, progress);
|
get<ESM::Container>().write (writer, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ESMStore::readRecord (ESM::ESMReader& reader, uint32_t type)
|
bool ESMStore::readRecord (ESM::ESMReader& reader, uint32_t type)
|
||||||
|
@ -715,12 +785,12 @@ void ESMStore::removeMissingObjects(Store<T>& store)
|
||||||
case ESM::REC_WEAP:
|
case ESM::REC_WEAP:
|
||||||
case ESM::REC_LEVI:
|
case ESM::REC_LEVI:
|
||||||
case ESM::REC_LEVC:
|
case ESM::REC_LEVC:
|
||||||
mStores[type]->read (reader);
|
mStores[mStoreImp->mESM3RecordToRecordId[type] ]->read (reader);
|
||||||
return true;
|
return true;
|
||||||
case ESM::REC_NPC_:
|
case ESM::REC_NPC_:
|
||||||
case ESM::REC_CREA:
|
case ESM::REC_CREA:
|
||||||
case ESM::REC_CONT:
|
case ESM::REC_CONT:
|
||||||
mStores[type]->read (reader, true);
|
mStores[mStoreImp->mESM3RecordToRecordId[type]]->read (reader, true);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case ESM::REC_DYNA:
|
case ESM::REC_DYNA:
|
||||||
|
@ -738,10 +808,10 @@ void ESMStore::removeMissingObjects(Store<T>& store)
|
||||||
{
|
{
|
||||||
setUp();
|
setUp();
|
||||||
|
|
||||||
const ESM::NPC *player = mStoreImp->mNpcs.find ("player");
|
const ESM::NPC *player = get<ESM::NPC>().find ("player");
|
||||||
|
|
||||||
if (!mStoreImp->mRaces.find (player->mRace) ||
|
if (!get<ESM::Race>().find (player->mRace) ||
|
||||||
!mStoreImp->mClasses.find (player->mClass))
|
!get<ESM::Class>().find (player->mClass))
|
||||||
throw std::runtime_error ("Invalid player record (race or class unavailable");
|
throw std::runtime_error ("Invalid player record (race or class unavailable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,19 +836,19 @@ void ESMStore::removeMissingObjects(Store<T>& store)
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
const ESM::Cell *ESMStore::insert<ESM::Cell>(const ESM::Cell &cell) {
|
const ESM::Cell *ESMStore::insert<ESM::Cell>(const ESM::Cell &cell) {
|
||||||
return mStoreImp->mCells.insert(cell);
|
return getWritable<ESM::Cell>().insert(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
const ESM::NPC *ESMStore::insert<ESM::NPC>(const ESM::NPC &npc)
|
const ESM::NPC *ESMStore::insert<ESM::NPC>(const ESM::NPC &npc)
|
||||||
{
|
{
|
||||||
const std::string id = "$dynamic" + std::to_string(mDynamicCount++);
|
const std::string id = "$dynamic" + std::to_string(mDynamicCount++);
|
||||||
|
auto& NPCs = getWritable<ESM::NPC>();
|
||||||
if (Misc::StringUtils::ciEqual(npc.mId, "player"))
|
if (Misc::StringUtils::ciEqual(npc.mId, "player"))
|
||||||
{
|
{
|
||||||
return mStoreImp->mNpcs.insert(npc);
|
return NPCs.insert(npc);
|
||||||
}
|
}
|
||||||
else if (mStoreImp->mNpcs.search(id) != nullptr)
|
else if (NPCs.search(id) != nullptr)
|
||||||
{
|
{
|
||||||
const std::string msg = "Try to override existing record '" + id + "'";
|
const std::string msg = "Try to override existing record '" + id + "'";
|
||||||
throw std::runtime_error(msg);
|
throw std::runtime_error(msg);
|
||||||
|
@ -787,7 +857,7 @@ void ESMStore::removeMissingObjects(Store<T>& store)
|
||||||
|
|
||||||
record.mId = id;
|
record.mId = id;
|
||||||
|
|
||||||
ESM::NPC *ptr = mStoreImp->mNpcs.insert(record);
|
ESM::NPC *ptr = NPCs.insert(record);
|
||||||
mIds[ptr->mId] = ESM::REC_NPC_;
|
mIds[ptr->mId] = ESM::REC_NPC_;
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
@ -821,213 +891,5 @@ void ESMStore::removeMissingObjects(Store<T>& store)
|
||||||
ESM3overrideRecord(ESM::NPC);
|
ESM3overrideRecord(ESM::NPC);
|
||||||
#undef ESM3overrideRecord
|
#undef ESM3overrideRecord
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Activator> &ESMStore::get<ESM::Activator>() const {
|
|
||||||
return mStoreImp->mActivators;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Potion> &ESMStore::get<ESM::Potion>() const {
|
|
||||||
return mStoreImp->mPotions;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Apparatus> &ESMStore::get<ESM::Apparatus>() const {
|
|
||||||
return mStoreImp->mAppas;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Armor> &ESMStore::get<ESM::Armor>() const {
|
|
||||||
return mStoreImp->mArmors;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::BodyPart> &ESMStore::get<ESM::BodyPart>() const {
|
|
||||||
return mStoreImp->mBodyParts;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Book> &ESMStore::get<ESM::Book>() const {
|
|
||||||
return mStoreImp->mBooks;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::BirthSign> &ESMStore::get<ESM::BirthSign>() const {
|
|
||||||
return mStoreImp->mBirthSigns;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Class> &ESMStore::get<ESM::Class>() const {
|
|
||||||
return mStoreImp->mClasses;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Clothing> &ESMStore::get<ESM::Clothing>() const {
|
|
||||||
return mStoreImp->mClothes;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Container> &ESMStore::get<ESM::Container>() const {
|
|
||||||
return mStoreImp->mContainers;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Creature> &ESMStore::get<ESM::Creature>() const {
|
|
||||||
return mStoreImp->mCreatures;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Dialogue> &ESMStore::get<ESM::Dialogue>() const {
|
|
||||||
return mStoreImp->mDialogs;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Door> &ESMStore::get<ESM::Door>() const {
|
|
||||||
return mStoreImp->mDoors;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Enchantment> &ESMStore::get<ESM::Enchantment>() const {
|
|
||||||
return mStoreImp->mEnchants;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Faction> &ESMStore::get<ESM::Faction>() const {
|
|
||||||
return mStoreImp->mFactions;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Global> &ESMStore::get<ESM::Global>() const {
|
|
||||||
return mStoreImp->mGlobals;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Ingredient> &ESMStore::get<ESM::Ingredient>() const {
|
|
||||||
return mStoreImp->mIngreds;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::CreatureLevList> &ESMStore::get<ESM::CreatureLevList>() const {
|
|
||||||
return mStoreImp->mCreatureLists;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::ItemLevList> &ESMStore::get<ESM::ItemLevList>() const {
|
|
||||||
return mStoreImp->mItemLists;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Light> &ESMStore::get<ESM::Light>() const {
|
|
||||||
return mStoreImp->mLights;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Lockpick> &ESMStore::get<ESM::Lockpick>() const {
|
|
||||||
return mStoreImp->mLockpicks;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Miscellaneous> &ESMStore::get<ESM::Miscellaneous>() const {
|
|
||||||
return mStoreImp->mMiscItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::NPC> &ESMStore::get<ESM::NPC>() const {
|
|
||||||
return mStoreImp->mNpcs;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Probe> &ESMStore::get<ESM::Probe>() const {
|
|
||||||
return mStoreImp->mProbes;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Race> &ESMStore::get<ESM::Race>() const {
|
|
||||||
return mStoreImp->mRaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Region> &ESMStore::get<ESM::Region>() const {
|
|
||||||
return mStoreImp->mRegions;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Repair> &ESMStore::get<ESM::Repair>() const {
|
|
||||||
return mStoreImp->mRepairs;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::SoundGenerator> &ESMStore::get<ESM::SoundGenerator>() const {
|
|
||||||
return mStoreImp->mSoundGens;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Sound> &ESMStore::get<ESM::Sound>() const {
|
|
||||||
return mStoreImp->mSounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Spell> &ESMStore::get<ESM::Spell>() const {
|
|
||||||
return mStoreImp->mSpells;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::StartScript> &ESMStore::get<ESM::StartScript>() const {
|
|
||||||
return mStoreImp->mStartScripts;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Static> &ESMStore::get<ESM::Static>() const {
|
|
||||||
return mStoreImp->mStatics;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Weapon> &ESMStore::get<ESM::Weapon>() const {
|
|
||||||
return mStoreImp->mWeapons;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::GameSetting> &ESMStore::get<ESM::GameSetting>() const {
|
|
||||||
return mStoreImp->mGameSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Script> &ESMStore::get<ESM::Script>() const {
|
|
||||||
return mStoreImp->mScripts;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Cell> &ESMStore::get<ESM::Cell>() const {
|
|
||||||
return mStoreImp->mCells;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Land> &ESMStore::get<ESM::Land>() const {
|
|
||||||
return mStoreImp->mLands;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::LandTexture> &ESMStore::get<ESM::LandTexture>() const {
|
|
||||||
return mStoreImp->mLandTextures;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Pathgrid> &ESMStore::get<ESM::Pathgrid>() const {
|
|
||||||
return mStoreImp->mPathgrids;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::MagicEffect> &ESMStore::get<ESM::MagicEffect>() const {
|
|
||||||
return mStoreImp->mMagicEffects;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Skill> &ESMStore::get<ESM::Skill>() const {
|
|
||||||
return mStoreImp->mSkills;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
const Store<ESM::Attribute> &ESMStore::get<ESM::Attribute>() const {
|
|
||||||
return mStoreImp->mAttributes;
|
|
||||||
}
|
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
|
|
@ -43,12 +43,15 @@ namespace MWWorld
|
||||||
|
|
||||||
std::unordered_map<std::string, int> mRefCount;
|
std::unordered_map<std::string, int> mRefCount;
|
||||||
|
|
||||||
std::map<int, StoreBase *> mStores;
|
std::vector<std::unique_ptr< StoreBase >> mStores;
|
||||||
|
|
||||||
unsigned int mDynamicCount;
|
unsigned int mDynamicCount;
|
||||||
|
|
||||||
mutable std::unordered_map<std::string, std::weak_ptr<MWMechanics::SpellList>, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual> mSpellListCache;
|
mutable std::unordered_map<std::string, std::weak_ptr<MWMechanics::SpellList>, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual> mSpellListCache;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Store<T>& getWritable();
|
||||||
|
|
||||||
/// Validate entries in store after setup
|
/// Validate entries in store after setup
|
||||||
void validate();
|
void validate();
|
||||||
|
|
||||||
|
@ -67,7 +70,7 @@ namespace MWWorld
|
||||||
ESM::LuaScriptsCfg getLuaScriptsCfg() const;
|
ESM::LuaScriptsCfg getLuaScriptsCfg() const;
|
||||||
|
|
||||||
/// \todo replace with SharedIterator<StoreBase>
|
/// \todo replace with SharedIterator<StoreBase>
|
||||||
typedef std::map<int, StoreBase *>::const_iterator iterator;
|
typedef std::vector<std::unique_ptr< StoreBase>>::const_iterator iterator;
|
||||||
|
|
||||||
iterator begin() const {
|
iterator begin() const {
|
||||||
return mStores.begin();
|
return mStores.begin();
|
||||||
|
|
Loading…
Reference in a new issue