1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-04 12:39:55 +00:00
OpenMW/apps/openmw/mwworld/esmstore.hpp

245 lines
6.8 KiB
C++
Raw Normal View History

2012-11-05 18:09:14 +04:00
#ifndef OPENMW_MWWORLD_ESMSTORE_H
#define OPENMW_MWWORLD_ESMSTORE_H
2012-10-01 19:17:04 +04:00
#include <memory>
2012-11-05 18:09:14 +04:00
#include <stdexcept>
#include <unordered_map>
#include <tuple>
2012-10-01 19:17:04 +04:00
#include <components/esm/luascripts.hpp>
#include <components/esm3/loadgmst.hpp>
2012-11-05 18:09:14 +04:00
#include "store.hpp"
2012-10-01 19:17:04 +04:00
namespace Loading
{
class Listener;
}
namespace MWMechanics
{
class SpellList;
}
namespace ESM
{
class ReadersCache;
struct Activator;
struct Potion;
struct Apparatus;
struct Armor;
struct BodyPart;
struct Book;
struct BirthSign;
struct Class;
struct Clothing;
struct Container;
struct Creature;
struct Dialogue;
struct Door;
struct Enchantment;
struct Faction;
struct Global;
struct Ingredient;
struct CreatureLevList;
struct ItemLevList;
struct Light;
struct Lockpick;
struct Miscellaneous;
struct NPC;
struct Probe;
struct Race;
struct Region;
struct Repair;
struct SoundGenerator;
struct Sound;
struct Spell;
struct StartScript;
struct Static;
struct Weapon;
struct GameSetting;
class Script;
struct Cell;
struct Land;
struct LandTexture;
struct Pathgrid;
struct MagicEffect;
struct Skill;
struct Attribute;
}
2012-12-23 23:23:24 +04:00
namespace MWWorld
2012-10-01 19:17:04 +04:00
{
struct ESMStoreImp;
2012-11-05 18:09:14 +04:00
class ESMStore
2012-10-01 19:17:04 +04:00
{
friend struct ESMStoreImp; //This allows StoreImp to extend esmstore without beeing included everywhere
using StoreTuple = std::tuple <
Store<ESM::Activator>,
Store<ESM::Potion>,
Store<ESM::Apparatus>,
Store<ESM::Armor>,
Store<ESM::BodyPart>,
Store<ESM::Book>,
Store<ESM::BirthSign>,
Store<ESM::Class>,
Store<ESM::Clothing>,
Store<ESM::Container>,
Store<ESM::Creature>,
Store<ESM::Dialogue>,
Store<ESM::Door>,
Store<ESM::Enchantment>,
Store<ESM::Faction>,
Store<ESM::Global>,
Store<ESM::Ingredient>,
Store<ESM::CreatureLevList>,
Store<ESM::ItemLevList>,
Store<ESM::Light>,
Store<ESM::Lockpick>,
Store<ESM::Miscellaneous>,
Store<ESM::NPC>,
Store<ESM::Probe>,
Store<ESM::Race>,
Store<ESM::Region>,
Store<ESM::Repair>,
Store<ESM::SoundGenerator>,
Store<ESM::Sound>,
Store<ESM::Spell>,
Store<ESM::StartScript>,
Store<ESM::Static>,
Store<ESM::Weapon>,
Store<ESM::GameSetting>,
Store<ESM::Script>,
// Lists that need special rules
Store<ESM::Cell>,
Store<ESM::Land>,
Store<ESM::LandTexture>,
Store<ESM::Pathgrid>,
Store<ESM::MagicEffect>,
Store<ESM::Skill>,
// Special entry which is hardcoded and not loaded from an ESM
Store<ESM::Attribute >>;
template <class T, class Tuple>
struct HasMember;
template <class T, class ... Args>
struct HasMember<T, std::tuple<Store<Args> ...>> {
static constexpr bool value = (std::is_same_v<T, Args> || ...);
};
static std::size_t &getTypeIndexCounter();
template<typename T>
static std::size_t getTypeIndex()
{
static_assert(HasMember<T, StoreTuple>::value);
2022-09-03 19:25:15 +02:00
static std::size_t sIndex = getTypeIndexCounter()++;
return sIndex;
}
std::unique_ptr<ESMStoreImp> mStoreImp;
2012-11-05 18:09:14 +04:00
std::unordered_map<std::string, int> mRefCount;
std::vector<StoreBase*> mStores;
std::vector<DynamicStore*> mDynamicStores;
2012-11-05 18:09:14 +04:00
2012-11-06 17:51:38 +04:00
unsigned int mDynamicCount;
mutable std::unordered_map<std::string, std::weak_ptr<MWMechanics::SpellList>, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual> mSpellListCache;
template <class T>
Store<T>& getWritable() {return static_cast<Store<T>&>(*mStores[getTypeIndex<T>()]);}
/// Validate entries in store after setup
void validate();
void countAllCellRefs(ESM::ReadersCache& readers);
2021-07-12 20:51:13 +02:00
template<class T>
void removeMissingObjects(Store<T>& store);
using LuaContent = std::variant<
ESM::LuaScriptsCfg, // data from an omwaddon
std::string>; // path to an omwscripts file
std::vector<LuaContent> mLuaContent;
2012-11-05 18:09:14 +04:00
public:
void addOMWScripts(std::string filePath) { mLuaContent.push_back(std::move(filePath)); }
ESM::LuaScriptsCfg getLuaScriptsCfg() const;
/// \todo replace with SharedIterator<StoreBase>
typedef std::vector<DynamicStore*>::const_iterator iterator;
iterator begin() const {
return mDynamicStores.begin();
}
iterator end() const {
return mDynamicStores.end();
}
2014-05-22 15:29:36 +02:00
/// Look up the given ID in 'all'. Returns 0 if not found.
int find(const std::string_view& id) const;
int findStatic(const std::string& id) const;
2012-11-05 18:09:14 +04:00
ESMStore();
~ESMStore();
2012-11-05 18:09:14 +04:00
void clearDynamic();
2013-05-15 17:54:18 +02:00
void movePlayerRecord();
2013-05-15 17:54:18 +02:00
/// Validate entries in store after loading a save
void validateDynamic();
2022-04-16 16:28:39 +02:00
void load(ESM::ESMReader &esm, Loading::Listener* listener, ESM::Dialogue*& dialogue);
2012-11-05 18:09:14 +04:00
template <class T>
const Store<T>& get() const {return static_cast<const Store<T>&>(*mStores[getTypeIndex<T>()]);}
2012-11-06 17:51:38 +04:00
/// Insert a custom record (i.e. with a generated ID that will not clash will pre-existing records)
template <class T>
const T* insert(const T& x);
2012-11-06 17:51:38 +04:00
/// Insert a record with set ID, and allow it to override a pre-existing static record.
template <class T>
const T *overrideRecord(const T &x);
template <class T>
const T *insertStatic(const T &x);
// 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();
void validateRecords(ESM::ReadersCache& readers);
2013-12-07 13:17:28 +01:00
int countSavedGameRecords() const;
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
2013-12-07 13:17:28 +01:00
2015-01-22 19:04:59 +01:00
bool readRecord (ESM::ESMReader& reader, uint32_t type);
2013-12-07 13:17:28 +01:00
///< \return Known type?
// To be called when we are done with dynamic record loading
void checkPlayer();
/// @return The number of instances defined in the base files. Excludes changes from the save file.
int getRefCount(std::string_view id) const;
/// Actors with the same ID share spells, abilities, etc.
/// @return The shared spell list to use for this actor and whether or not it has already been initialized.
std::pair<std::shared_ptr<MWMechanics::SpellList>, bool> getSpellList(const std::string& id) const;
2012-11-05 18:09:14 +04:00
};
2012-10-01 19:17:04 +04:00
}
#endif