1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-16 17:19:56 +00:00
openmw-tes3mp/apps/openmw/mwworld/esmstore.hpp

464 lines
14 KiB
C++
Raw Normal View History

2012-11-05 14:09:14 +00:00
#ifndef OPENMW_MWWORLD_ESMSTORE_H
#define OPENMW_MWWORLD_ESMSTORE_H
2012-10-01 15:17:04 +00:00
2012-11-05 14:09:14 +00:00
#include <stdexcept>
2012-10-01 15:17:04 +00:00
#include <components/esm/records.hpp>
2012-11-05 14:09:14 +00:00
#include "store.hpp"
2012-10-01 15:17:04 +00:00
namespace Loading
{
class Listener;
}
2012-12-23 19:23:24 +00:00
namespace MWWorld
2012-10-01 15:17:04 +00:00
{
2012-11-05 14:09:14 +00:00
class ESMStore
2012-10-01 15:17:04 +00:00
{
2012-11-05 14:09:14 +00:00
Store<ESM::Activator> mActivators;
Store<ESM::Potion> mPotions;
Store<ESM::Apparatus> mAppas;
Store<ESM::Armor> mArmors;
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;
2013-03-22 04:50:54 +00:00
Store<ESM::Lockpick> mLockpicks;
2012-11-05 14:09:14 +00:00
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;
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;
// Lookup of all IDs. Makes looking up references faster. Just
// maps the id name to the record type.
std::map<std::string, int> mIds;
std::map<int, StoreBase *> mStores;
2013-05-15 20:38:53 +00:00
ESM::NPC mPlayerTemplate;
2012-11-06 13:51:38 +00:00
unsigned int mDynamicCount;
2012-11-05 14:09:14 +00:00
public:
/// \todo replace with SharedIterator<StoreBase>
typedef std::map<int, StoreBase *>::const_iterator iterator;
iterator begin() const {
return mStores.begin();
}
iterator end() const {
return mStores.end();
}
2014-05-22 13:29:36 +00:00
/// Look up the given ID in 'all'. Returns 0 if not found.
/// \note id must be in lower case.
2012-11-05 14:09:14 +00:00
int find(const std::string &id) const
{
std::map<std::string, int>::const_iterator it = mIds.find(id);
if (it == mIds.end()) {
return 0;
}
return it->second;
}
ESMStore()
2012-11-06 13:51:38 +00:00
: mDynamicCount(0)
2012-11-05 14:09:14 +00:00
{
// Cell store needs access to this for tracking moved references
mCells.mEsmStore = this;
2013-12-06 10:17:14 +00:00
2012-11-05 14:09:14 +00:00
mStores[ESM::REC_ACTI] = &mActivators;
mStores[ESM::REC_ALCH] = &mPotions;
mStores[ESM::REC_APPA] = &mAppas;
mStores[ESM::REC_ARMO] = &mArmors;
mStores[ESM::REC_BODY] = &mBodyParts;
mStores[ESM::REC_BOOK] = &mBooks;
mStores[ESM::REC_BSGN] = &mBirthSigns;
mStores[ESM::REC_CELL] = &mCells;
mStores[ESM::REC_CLAS] = &mClasses;
mStores[ESM::REC_CLOT] = &mClothes;
mStores[ESM::REC_CONT] = &mContainers;
mStores[ESM::REC_CREA] = &mCreatures;
mStores[ESM::REC_DIAL] = &mDialogs;
mStores[ESM::REC_DOOR] = &mDoors;
mStores[ESM::REC_ENCH] = &mEnchants;
mStores[ESM::REC_FACT] = &mFactions;
mStores[ESM::REC_GLOB] = &mGlobals;
mStores[ESM::REC_GMST] = &mGameSettings;
mStores[ESM::REC_INGR] = &mIngreds;
mStores[ESM::REC_LAND] = &mLands;
mStores[ESM::REC_LEVC] = &mCreatureLists;
mStores[ESM::REC_LEVI] = &mItemLists;
mStores[ESM::REC_LIGH] = &mLights;
mStores[ESM::REC_LOCK] = &mLockpicks;
mStores[ESM::REC_LTEX] = &mLandTextures;
mStores[ESM::REC_MISC] = &mMiscItems;
mStores[ESM::REC_NPC_] = &mNpcs;
mStores[ESM::REC_PGRD] = &mPathgrids;
mStores[ESM::REC_PROB] = &mProbes;
mStores[ESM::REC_RACE] = &mRaces;
mStores[ESM::REC_REGN] = &mRegions;
mStores[ESM::REC_REPA] = &mRepairs;
mStores[ESM::REC_SCPT] = &mScripts;
mStores[ESM::REC_SNDG] = &mSoundGens;
mStores[ESM::REC_SOUN] = &mSounds;
mStores[ESM::REC_SPEL] = &mSpells;
mStores[ESM::REC_SSCR] = &mStartScripts;
mStores[ESM::REC_STAT] = &mStatics;
mStores[ESM::REC_WEAP] = &mWeapons;
}
2013-05-15 15:54:18 +00:00
void clearDynamic ()
{
for (std::map<int, StoreBase *>::iterator it = mStores.begin(); it != mStores.end(); ++it)
it->second->clearDynamic();
2013-05-15 20:38:53 +00:00
mNpcs.insert(mPlayerTemplate);
2013-05-15 15:54:18 +00:00
}
void movePlayerRecord ()
{
2013-05-15 20:38:53 +00:00
mPlayerTemplate = *mNpcs.find("player");
mNpcs.eraseStatic(mPlayerTemplate.mId);
mNpcs.insert(mPlayerTemplate);
2013-05-15 15:54:18 +00:00
}
void load(ESM::ESMReader &esm, Loading::Listener* listener);
2012-11-05 14:09:14 +00:00
template <class T>
const Store<T> &get() const {
throw std::runtime_error("Storage for this type not exist");
}
2012-11-06 13:51:38 +00:00
template <class T>
2012-11-08 12:37:57 +00:00
const T *insert(const T &x) {
std::ostringstream id;
id << "$dynamic" << mDynamicCount++;
2012-11-06 13:51:38 +00:00
Store<T> &store = const_cast<Store<T> &>(get<T>());
if (store.search(id.str()) != 0) {
2012-11-08 12:37:57 +00:00
std::ostringstream msg;
msg << "Try to override existing record '" << id.str() << "'";
2012-11-08 12:37:57 +00:00
throw std::runtime_error(msg.str());
}
2012-11-06 13:51:38 +00:00
T record = x;
record.mId = id.str();
2012-12-23 19:23:24 +00:00
2012-11-06 13:51:38 +00:00
T *ptr = store.insert(record);
for (iterator it = mStores.begin(); it != mStores.end(); ++it) {
if (it->second == &store) {
mIds[ptr->mId] = it->first;
}
}
return ptr;
}
template <class T>
const T *insertStatic(const T &x) {
std::ostringstream id;
id << "$dynamic" << mDynamicCount++;
Store<T> &store = const_cast<Store<T> &>(get<T>());
if (store.search(id.str()) != 0) {
std::ostringstream msg;
msg << "Try to override existing record '" << id.str() << "'";
throw std::runtime_error(msg.str());
}
T record = x;
T *ptr = store.insertStatic(record);
for (iterator it = mStores.begin(); it != mStores.end(); ++it) {
if (it->second == &store) {
mIds[ptr->mId] = it->first;
}
}
return ptr;
}
// This method must be called once, after loading all master/plugin files. This can only be done
// from the outside, so it must be public.
void setUp();
2013-12-07 12:17:28 +00:00
int countSavedGameRecords() const;
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
2013-12-07 12:17:28 +00:00
bool readRecord (ESM::ESMReader& reader, int32_t type);
///< \return Known type?
2012-11-05 14:09:14 +00:00
};
2012-11-06 13:51:38 +00:00
template <>
2012-11-08 12:37:57 +00:00
inline const ESM::Cell *ESMStore::insert<ESM::Cell>(const ESM::Cell &cell) {
2012-11-06 13:51:38 +00:00
return mCells.insert(cell);
}
2012-11-08 12:37:57 +00:00
template <>
inline const ESM::NPC *ESMStore::insert<ESM::NPC>(const ESM::NPC &npc) {
std::ostringstream id;
id << "$dynamic" << mDynamicCount++;
2012-12-23 19:23:24 +00:00
if (Misc::StringUtils::ciEqual(npc.mId, "player")) {
2012-11-08 12:37:57 +00:00
return mNpcs.insert(npc);
} else if (mNpcs.search(id.str()) != 0) {
2012-11-08 12:37:57 +00:00
std::ostringstream msg;
msg << "Try to override existing record '" << id.str() << "'";
2012-11-08 12:37:57 +00:00
throw std::runtime_error(msg.str());
}
ESM::NPC record = npc;
record.mId = id.str();
2012-12-23 19:23:24 +00:00
2012-11-08 12:37:57 +00:00
ESM::NPC *ptr = mNpcs.insert(record);
mIds[ptr->mId] = ESM::REC_NPC_;
return ptr;
}
2012-11-05 14:09:14 +00:00
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Activator> &ESMStore::get<ESM::Activator>() const {
2012-11-05 14:09:14 +00:00
return mActivators;
2012-10-01 15:17:04 +00:00
}
2012-11-05 14:09:14 +00:00
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Potion> &ESMStore::get<ESM::Potion>() const {
2012-11-05 14:09:14 +00:00
return mPotions;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Apparatus> &ESMStore::get<ESM::Apparatus>() const {
2012-11-05 14:09:14 +00:00
return mAppas;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Armor> &ESMStore::get<ESM::Armor>() const {
2012-11-05 14:09:14 +00:00
return mArmors;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::BodyPart> &ESMStore::get<ESM::BodyPart>() const {
2012-11-05 14:09:14 +00:00
return mBodyParts;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Book> &ESMStore::get<ESM::Book>() const {
2012-11-05 14:09:14 +00:00
return mBooks;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::BirthSign> &ESMStore::get<ESM::BirthSign>() const {
2012-11-05 14:09:14 +00:00
return mBirthSigns;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Class> &ESMStore::get<ESM::Class>() const {
2012-11-05 14:09:14 +00:00
return mClasses;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Clothing> &ESMStore::get<ESM::Clothing>() const {
2012-11-05 14:09:14 +00:00
return mClothes;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Container> &ESMStore::get<ESM::Container>() const {
2012-11-05 14:09:14 +00:00
return mContainers;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Creature> &ESMStore::get<ESM::Creature>() const {
2012-11-05 14:09:14 +00:00
return mCreatures;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Dialogue> &ESMStore::get<ESM::Dialogue>() const {
2012-11-05 14:09:14 +00:00
return mDialogs;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Door> &ESMStore::get<ESM::Door>() const {
2012-11-05 14:09:14 +00:00
return mDoors;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Enchantment> &ESMStore::get<ESM::Enchantment>() const {
2012-11-05 14:09:14 +00:00
return mEnchants;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Faction> &ESMStore::get<ESM::Faction>() const {
2012-11-05 14:09:14 +00:00
return mFactions;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Global> &ESMStore::get<ESM::Global>() const {
2012-11-05 14:09:14 +00:00
return mGlobals;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Ingredient> &ESMStore::get<ESM::Ingredient>() const {
2012-11-05 14:09:14 +00:00
return mIngreds;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::CreatureLevList> &ESMStore::get<ESM::CreatureLevList>() const {
2012-11-05 14:09:14 +00:00
return mCreatureLists;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::ItemLevList> &ESMStore::get<ESM::ItemLevList>() const {
2012-11-05 14:09:14 +00:00
return mItemLists;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Light> &ESMStore::get<ESM::Light>() const {
2012-11-05 14:09:14 +00:00
return mLights;
}
template <>
2013-03-22 04:50:54 +00:00
inline const Store<ESM::Lockpick> &ESMStore::get<ESM::Lockpick>() const {
2012-11-05 14:09:14 +00:00
return mLockpicks;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Miscellaneous> &ESMStore::get<ESM::Miscellaneous>() const {
2012-11-05 14:09:14 +00:00
return mMiscItems;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::NPC> &ESMStore::get<ESM::NPC>() const {
2012-11-05 14:09:14 +00:00
return mNpcs;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Probe> &ESMStore::get<ESM::Probe>() const {
2012-11-05 14:09:14 +00:00
return mProbes;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Race> &ESMStore::get<ESM::Race>() const {
2012-11-05 14:09:14 +00:00
return mRaces;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Region> &ESMStore::get<ESM::Region>() const {
2012-11-05 14:09:14 +00:00
return mRegions;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Repair> &ESMStore::get<ESM::Repair>() const {
2012-11-05 14:09:14 +00:00
return mRepairs;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::SoundGenerator> &ESMStore::get<ESM::SoundGenerator>() const {
2012-11-05 14:09:14 +00:00
return mSoundGens;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Sound> &ESMStore::get<ESM::Sound>() const {
2012-11-05 14:09:14 +00:00
return mSounds;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Spell> &ESMStore::get<ESM::Spell>() const {
2012-11-05 14:09:14 +00:00
return mSpells;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::StartScript> &ESMStore::get<ESM::StartScript>() const {
2012-11-05 14:09:14 +00:00
return mStartScripts;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Static> &ESMStore::get<ESM::Static>() const {
2012-11-05 14:09:14 +00:00
return mStatics;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Weapon> &ESMStore::get<ESM::Weapon>() const {
2012-11-05 14:09:14 +00:00
return mWeapons;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::GameSetting> &ESMStore::get<ESM::GameSetting>() const {
2012-11-05 14:09:14 +00:00
return mGameSettings;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Script> &ESMStore::get<ESM::Script>() const {
2012-11-05 14:09:14 +00:00
return mScripts;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Cell> &ESMStore::get<ESM::Cell>() const {
2012-11-05 14:09:14 +00:00
return mCells;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Land> &ESMStore::get<ESM::Land>() const {
2012-11-05 14:09:14 +00:00
return mLands;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::LandTexture> &ESMStore::get<ESM::LandTexture>() const {
2012-11-05 14:09:14 +00:00
return mLandTextures;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Pathgrid> &ESMStore::get<ESM::Pathgrid>() const {
2012-11-05 14:09:14 +00:00
return mPathgrids;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::MagicEffect> &ESMStore::get<ESM::MagicEffect>() const {
2012-11-05 14:09:14 +00:00
return mMagicEffects;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Skill> &ESMStore::get<ESM::Skill>() const {
2012-11-05 14:09:14 +00:00
return mSkills;
}
template <>
2012-11-06 11:10:57 +00:00
inline const Store<ESM::Attribute> &ESMStore::get<ESM::Attribute>() const {
2012-11-05 14:09:14 +00:00
return mAttributes;
}
2012-10-01 15:17:04 +00:00
}
#endif