mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-19 21:41:33 +00:00
Merge branch 'cellstore_refactor' into 'master'
CellStore refactor, same idea as ESMStore refactor See merge request OpenMW/openmw!2389
This commit is contained in:
commit
db619c684f
32 changed files with 307 additions and 448 deletions
|
@ -7,6 +7,8 @@
|
||||||
#include <components/sceneutil/positionattitudetransform.hpp>
|
#include <components/sceneutil/positionattitudetransform.hpp>
|
||||||
#include <components/esm3/loadsoun.hpp>
|
#include <components/esm3/loadsoun.hpp>
|
||||||
#include <components/esm3/loadsndg.hpp>
|
#include <components/esm3/loadsndg.hpp>
|
||||||
|
#include <components/esm3/loadacti.hpp>
|
||||||
|
#include <components/esm3/loadcrea.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <MyGUI_TextIterator.h>
|
#include <MyGUI_TextIterator.h>
|
||||||
|
|
||||||
#include <components/esm3/loadappa.hpp>
|
#include <components/esm3/loadappa.hpp>
|
||||||
|
#include <components/esm3/loadnpc.hpp>
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <components/esm3/loadskil.hpp>
|
#include <components/esm3/loadskil.hpp>
|
||||||
#include <components/esm3/loadgmst.hpp>
|
#include <components/esm3/loadgmst.hpp>
|
||||||
#include <components/esm3/loadrace.hpp>
|
#include <components/esm3/loadrace.hpp>
|
||||||
|
#include <components/esm3/loadnpc.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "bodypart.hpp"
|
#include "bodypart.hpp"
|
||||||
|
|
||||||
|
#include <components/esm3/loadbody.hpp>
|
||||||
|
|
||||||
#include "../mwrender/renderinginterface.hpp"
|
#include "../mwrender/renderinginterface.hpp"
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/objects.hpp"
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <components/esm3/loadclot.hpp>
|
#include <components/esm3/loadclot.hpp>
|
||||||
#include <components/esm3/loadrace.hpp>
|
#include <components/esm3/loadrace.hpp>
|
||||||
|
#include <components/esm3/loadnpc.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <MyGUI_TextIterator.h>
|
#include <MyGUI_TextIterator.h>
|
||||||
|
|
||||||
#include <components/esm3/loadingr.hpp>
|
#include <components/esm3/loadingr.hpp>
|
||||||
|
#include <components/esm3/loadnpc.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <MyGUI_TextIterator.h>
|
#include <MyGUI_TextIterator.h>
|
||||||
|
|
||||||
#include <components/esm3/loadligh.hpp>
|
#include <components/esm3/loadligh.hpp>
|
||||||
|
#include <components/esm3/loadnpc.hpp>
|
||||||
#include <components/esm3/objectstate.hpp>
|
#include <components/esm3/objectstate.hpp>
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <MyGUI_TextIterator.h>
|
#include <MyGUI_TextIterator.h>
|
||||||
|
|
||||||
#include <components/esm3/loadlock.hpp>
|
#include <components/esm3/loadlock.hpp>
|
||||||
|
#include <components/esm3/loadnpc.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
#include <MyGUI_TextIterator.h>
|
#include <MyGUI_TextIterator.h>
|
||||||
|
|
||||||
#include <components/esm3/loadmisc.hpp>
|
#include <components/esm3/loadmisc.hpp>
|
||||||
|
#include <components/esm3/loadnpc.hpp>
|
||||||
|
#include <components/esm3/loadcrea.hpp>
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <components/esm3/loadclas.hpp>
|
#include <components/esm3/loadclas.hpp>
|
||||||
#include <components/esm3/loadnpc.hpp>
|
#include <components/esm3/loadnpc.hpp>
|
||||||
#include <components/esm3/loadsoun.hpp>
|
#include <components/esm3/loadsoun.hpp>
|
||||||
|
#include <components/esm3/loadbody.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <MyGUI_TextIterator.h>
|
#include <MyGUI_TextIterator.h>
|
||||||
|
|
||||||
#include <components/esm3/loadalch.hpp>
|
#include <components/esm3/loadalch.hpp>
|
||||||
|
#include <components/esm3/loadnpc.hpp>
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <MyGUI_TextIterator.h>
|
#include <MyGUI_TextIterator.h>
|
||||||
|
|
||||||
#include <components/esm3/loadprob.hpp>
|
#include <components/esm3/loadprob.hpp>
|
||||||
|
#include <components/esm3/loadnpc.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <MyGUI_TextIterator.h>
|
#include <MyGUI_TextIterator.h>
|
||||||
|
|
||||||
#include <components/esm3/loadrepa.hpp>
|
#include <components/esm3/loadrepa.hpp>
|
||||||
|
#include <components/esm3/loadnpc.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <MyGUI_TextIterator.h>
|
#include <MyGUI_TextIterator.h>
|
||||||
|
|
||||||
#include <components/esm3/loadweap.hpp>
|
#include <components/esm3/loadweap.hpp>
|
||||||
|
#include <components/esm3/loadnpc.hpp>
|
||||||
#include <components/misc/constants.hpp>
|
#include <components/misc/constants.hpp>
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <components/compiler/locals.hpp>
|
#include <components/compiler/locals.hpp>
|
||||||
#include <components/esm3/loadmgef.hpp>
|
#include <components/esm3/loadmgef.hpp>
|
||||||
#include <components/esm3/loadfact.hpp>
|
#include <components/esm3/loadfact.hpp>
|
||||||
|
#include <components/esm3/loadcrea.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
#include <components/esm3/loadgmst.hpp>
|
#include <components/esm3/loadgmst.hpp>
|
||||||
|
#include <components/esm3/loadcrea.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "luabindings.hpp"
|
#include "luabindings.hpp"
|
||||||
|
|
||||||
#include <components/esm3/loadcell.hpp>
|
#include <components/esm/records.hpp>
|
||||||
|
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include <components/esm3/loadmgef.hpp>
|
#include <components/esm3/loadmgef.hpp>
|
||||||
#include <components/esm3/loadgmst.hpp>
|
#include <components/esm3/loadgmst.hpp>
|
||||||
|
#include <components/esm3/loadcrea.hpp>
|
||||||
|
#include <components/esm3/loadstat.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include <components/sceneutil/positionattitudetransform.hpp>
|
#include <components/sceneutil/positionattitudetransform.hpp>
|
||||||
#include <components/detournavigator/agentbounds.hpp>
|
#include <components/detournavigator/agentbounds.hpp>
|
||||||
|
#include <components/esm3/loadbody.hpp>
|
||||||
|
#include <components/esm3/loaddoor.hpp>
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <components/misc/strings/format.hpp>
|
#include <components/misc/strings/format.hpp>
|
||||||
#include <components/esm3/loadmgef.hpp>
|
#include <components/esm3/loadmgef.hpp>
|
||||||
#include <components/esm3/loadench.hpp>
|
#include <components/esm3/loadench.hpp>
|
||||||
|
#include <components/esm3/loadstat.hpp>
|
||||||
|
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
#include <components/esm3/loadench.hpp>
|
#include <components/esm3/loadench.hpp>
|
||||||
|
#include <components/esm3/loadstat.hpp>
|
||||||
|
#include <components/esm3/loadcrea.hpp>
|
||||||
|
#include <components/esm3/loadbody.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <components/esm3/loadligh.hpp>
|
#include <components/esm3/loadligh.hpp>
|
||||||
#include <components/esm3/loadcell.hpp>
|
#include <components/esm3/loadcell.hpp>
|
||||||
|
#include <components/esm3/loadbody.hpp>
|
||||||
|
|
||||||
#include <components/resource/resourcesystem.hpp>
|
#include <components/resource/resourcesystem.hpp>
|
||||||
#include <components/resource/scenemanager.hpp>
|
#include <components/resource/scenemanager.hpp>
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
#include <components/esm3/loadmgef.hpp>
|
#include <components/esm3/loadmgef.hpp>
|
||||||
#include <components/esm3/loadrace.hpp>
|
#include <components/esm3/loadrace.hpp>
|
||||||
|
#include <components/esm3/loadnpc.hpp>
|
||||||
|
#include <components/esm3/loadcont.hpp>
|
||||||
|
#include <components/esm3/loadcrea.hpp>
|
||||||
|
|
||||||
#include <components/sceneutil/keyframe.hpp>
|
#include <components/sceneutil/keyframe.hpp>
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
#include <components/esm3/loadmgef.hpp>
|
#include <components/esm3/loadmgef.hpp>
|
||||||
#include <components/esm3/loadcrea.hpp>
|
#include <components/esm3/loadcrea.hpp>
|
||||||
|
#include <components/esm3/loadlevlist.hpp>
|
||||||
|
#include <components/esm3/loaddoor.hpp>
|
||||||
|
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
#include <components/files/conversion.hpp>
|
#include <components/files/conversion.hpp>
|
||||||
|
|
|
@ -7,9 +7,11 @@
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
struct CellRefListBase {};
|
||||||
|
|
||||||
/// \brief Collection of references of one type
|
/// \brief Collection of references of one type
|
||||||
template <typename X>
|
template <typename X>
|
||||||
struct CellRefList
|
struct CellRefList : public CellRefListBase
|
||||||
{
|
{
|
||||||
typedef LiveCellRef<X> LiveRef;
|
typedef LiveCellRef<X> LiveRef;
|
||||||
typedef std::list<LiveRef> List;
|
typedef std::list<LiveRef> List;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
|
|
||||||
|
#include <components/misc/tuplehelpers.hpp>
|
||||||
#include <components/esm3/cellstate.hpp>
|
#include <components/esm3/cellstate.hpp>
|
||||||
#include <components/esm3/cellid.hpp>
|
#include <components/esm3/cellid.hpp>
|
||||||
#include <components/esm3/cellref.hpp>
|
#include <components/esm3/cellref.hpp>
|
||||||
|
@ -18,6 +19,26 @@
|
||||||
#include <components/esm3/creaturelevliststate.hpp>
|
#include <components/esm3/creaturelevliststate.hpp>
|
||||||
#include <components/esm3/doorstate.hpp>
|
#include <components/esm3/doorstate.hpp>
|
||||||
#include <components/esm3/readerscache.hpp>
|
#include <components/esm3/readerscache.hpp>
|
||||||
|
#include <components/esm3/loadacti.hpp>
|
||||||
|
#include <components/esm3/loadalch.hpp>
|
||||||
|
#include <components/esm3/loadappa.hpp>
|
||||||
|
#include <components/esm3/loadarmo.hpp>
|
||||||
|
#include <components/esm3/loadbook.hpp>
|
||||||
|
#include <components/esm3/loadclot.hpp>
|
||||||
|
#include <components/esm3/loadcont.hpp>
|
||||||
|
#include <components/esm3/loadcrea.hpp>
|
||||||
|
#include <components/esm3/loaddoor.hpp>
|
||||||
|
#include <components/esm3/loadingr.hpp>
|
||||||
|
#include <components/esm3/loadlevlist.hpp>
|
||||||
|
#include <components/esm3/loadligh.hpp>
|
||||||
|
#include <components/esm3/loadlock.hpp>
|
||||||
|
#include <components/esm3/loadprob.hpp>
|
||||||
|
#include <components/esm3/loadrepa.hpp>
|
||||||
|
#include <components/esm3/loadstat.hpp>
|
||||||
|
#include <components/esm3/loadweap.hpp>
|
||||||
|
#include <components/esm3/loadnpc.hpp>
|
||||||
|
#include <components/esm3/loadmisc.hpp>
|
||||||
|
#include <components/esm3/loadbody.hpp>
|
||||||
#include <components/esm3/loadench.hpp>
|
#include <components/esm3/loadench.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
@ -36,6 +57,39 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template <typename Record>
|
||||||
|
struct RecordToState
|
||||||
|
{
|
||||||
|
using StateType = ESM::ObjectState;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct RecordToState<ESM::NPC>
|
||||||
|
{
|
||||||
|
using StateType = ESM::NpcState;
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct RecordToState<ESM::Creature>
|
||||||
|
{
|
||||||
|
using StateType = ESM::CreatureState;
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct RecordToState<ESM::Door>
|
||||||
|
{
|
||||||
|
using StateType = ESM::DoorState;
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct RecordToState<ESM::Container>
|
||||||
|
{
|
||||||
|
using StateType = ESM::ContainerState;
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct RecordToState<ESM::CreatureLevList>
|
||||||
|
{
|
||||||
|
using StateType = ESM::CreatureLevListState;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
MWWorld::Ptr searchInContainerList(MWWorld::CellRefList<T>& containerList, std::string_view id)
|
MWWorld::Ptr searchInContainerList(MWWorld::CellRefList<T>& containerList, std::string_view id)
|
||||||
{
|
{
|
||||||
|
@ -76,7 +130,7 @@ namespace
|
||||||
return MWWorld::Ptr();
|
return MWWorld::Ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RecordType, typename T>
|
template<typename T>
|
||||||
void writeReferenceCollection (ESM::ESMWriter& writer,
|
void writeReferenceCollection (ESM::ESMWriter& writer,
|
||||||
const MWWorld::CellRefList<T>& collection)
|
const MWWorld::CellRefList<T>& collection)
|
||||||
{
|
{
|
||||||
|
@ -97,8 +151,8 @@ namespace
|
||||||
// Deleted reference that did not come from a content file -> ignore
|
// Deleted reference that did not come from a content file -> ignore
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
using StateType = typename RecordToState<T>::StateType;
|
||||||
RecordType state;
|
StateType state;
|
||||||
iter->save (state);
|
iter->save (state);
|
||||||
|
|
||||||
// recordId currently unused
|
// recordId currently unused
|
||||||
|
@ -148,13 +202,14 @@ namespace
|
||||||
fixRestockingImpl(base, state);
|
fixRestockingImpl(base, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RecordType, typename T>
|
template<typename T>
|
||||||
void readReferenceCollection (ESM::ESMReader& reader,
|
void readReferenceCollection (ESM::ESMReader& reader,
|
||||||
MWWorld::CellRefList<T>& collection, const ESM::CellRef& cref, const std::map<int, int>& contentFileMap, MWWorld::CellStore* cellstore)
|
MWWorld::CellRefList<T>& collection, const ESM::CellRef& cref, const std::map<int, int>& contentFileMap, MWWorld::CellStore* cellstore)
|
||||||
{
|
{
|
||||||
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
RecordType state;
|
using StateType = typename RecordToState<T>::StateType;
|
||||||
|
StateType state;
|
||||||
state.mRef = cref;
|
state.mRef = cref;
|
||||||
state.load(reader);
|
state.load(reader);
|
||||||
|
|
||||||
|
@ -229,10 +284,63 @@ namespace
|
||||||
MWWorld::LiveCellRefBase* base = &collection.mList.back();
|
MWWorld::LiveCellRefBase* base = &collection.mList.back();
|
||||||
MWBase::Environment::get().getLuaManager()->registerObject(MWWorld::Ptr(base, cellstore));
|
MWBase::Environment::get().getLuaManager()->registerObject(MWWorld::Ptr(base, cellstore));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//this function allows us to link a CellRefList<T> to the associated recNameInt, and apply a function
|
||||||
|
template<typename RecordType, typename Callable>
|
||||||
|
static void recNameSwitcher(MWWorld::CellRefList<RecordType>& store, ESM::RecNameInts recnNameInt, Callable&& f)
|
||||||
|
{
|
||||||
|
if (RecordType::sRecordId == recnNameInt)
|
||||||
|
{
|
||||||
|
f(store);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function for forEachInternal
|
||||||
|
template<class Visitor, class List>
|
||||||
|
bool forEachImp (Visitor& visitor, List& list, MWWorld::CellStore* cellStore)
|
||||||
|
{
|
||||||
|
for (typename List::List::iterator iter (list.mList.begin()); iter!=list.mList.end();
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
if (!MWWorld::CellStore::isAccessible(iter->mData, iter->mRef))
|
||||||
|
continue;
|
||||||
|
if (!visitor (MWWorld::Ptr(&*iter, cellStore)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
struct CellStoreImp
|
||||||
|
{
|
||||||
|
CellStoreTuple mRefLists;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static void assignStoreToIndex(CellStore& stores, CellRefList<T>& refList)
|
||||||
|
{
|
||||||
|
const std::size_t storeIndex = CellStore::getTypeIndex<T>();
|
||||||
|
if (stores.mCellRefLists.size() <= storeIndex)
|
||||||
|
stores.mCellRefLists.resize(storeIndex + 1);
|
||||||
|
|
||||||
|
assert(&refList == &std::get<CellRefList<T>>(stores.mCellStoreImp->mRefLists));
|
||||||
|
|
||||||
|
stores.mCellRefLists[storeIndex] = &refList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// listing only objects owned by this cell. Internal use only, you probably want to use forEach() so that moved objects are accounted for.
|
||||||
|
template<class Visitor>
|
||||||
|
static bool forEachInternal (Visitor& visitor, MWWorld::CellStore& cellStore)
|
||||||
|
{
|
||||||
|
bool returnValue = true;
|
||||||
|
|
||||||
|
Misc::tupleForEach(cellStore.mCellStoreImp->mRefLists, [&visitor, &returnValue, &cellStore](auto& store) { returnValue = returnValue && forEachImp(visitor, store, &cellStore); });
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename X>
|
template <typename X>
|
||||||
void CellRefList<X>::load(ESM::CellRef &ref, bool deleted, const MWWorld::ESMStore &esmStore)
|
void CellRefList<X>::load(ESM::CellRef &ref, bool deleted, const MWWorld::ESMStore &esmStore)
|
||||||
|
@ -374,7 +482,7 @@ namespace MWWorld
|
||||||
mMergedRefs.clear();
|
mMergedRefs.clear();
|
||||||
mRechargingItemsUpToDate = false;
|
mRechargingItemsUpToDate = false;
|
||||||
MergeVisitor visitor(mMergedRefs, mMovedHere, mMovedToAnotherCell);
|
MergeVisitor visitor(mMergedRefs, mMovedHere, mMovedToAnotherCell);
|
||||||
forEachInternal(visitor);
|
CellStoreImp::forEachInternal(visitor, *this);
|
||||||
visitor.merge();
|
visitor.merge();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,11 +504,16 @@ namespace MWWorld
|
||||||
, mState(State_Unloaded)
|
, mState(State_Unloaded)
|
||||||
, mHasState(false)
|
, mHasState(false)
|
||||||
, mLastRespawn(0, 0)
|
, mLastRespawn(0, 0)
|
||||||
|
, mCellStoreImp(std::make_unique<CellStoreImp>())
|
||||||
, mRechargingItemsUpToDate(false)
|
, mRechargingItemsUpToDate(false)
|
||||||
{
|
{
|
||||||
|
std::apply([this](auto& ...x) {(CellStoreImp::assignStoreToIndex(*this, x), ...); }, mCellStoreImp->mRefLists);
|
||||||
mWaterLevel = cell->mWater;
|
mWaterLevel = cell->mWater;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CellStore::~CellStore() = default;
|
||||||
|
CellStore::CellStore(CellStore&&) = default;
|
||||||
|
|
||||||
const ESM::Cell *CellStore::getCell() const
|
const ESM::Cell *CellStore::getCell() const
|
||||||
{
|
{
|
||||||
return mCell;
|
return mCell;
|
||||||
|
@ -466,10 +579,10 @@ namespace MWWorld
|
||||||
|
|
||||||
Ptr CellStore::searchViaActorId (int id)
|
Ptr CellStore::searchViaActorId (int id)
|
||||||
{
|
{
|
||||||
if (Ptr ptr = ::searchViaActorId (mNpcs, id, this, mMovedToAnotherCell))
|
if (Ptr ptr = ::searchViaActorId (get<ESM::NPC>(), id, this, mMovedToAnotherCell))
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
if (Ptr ptr = ::searchViaActorId (mCreatures, id, this, mMovedToAnotherCell))
|
if (Ptr ptr = ::searchViaActorId (get<ESM::Creature>(), id, this, mMovedToAnotherCell))
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
for (const auto& [base, _] : mMovedHere)
|
for (const auto& [base, _] : mMovedHere)
|
||||||
|
@ -683,13 +796,13 @@ namespace MWWorld
|
||||||
|
|
||||||
mHasState = true;
|
mHasState = true;
|
||||||
|
|
||||||
if (Ptr ptr = searchInContainerList (mContainers, id))
|
if (Ptr ptr = searchInContainerList (get<ESM::Container>(), id))
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
if (Ptr ptr = searchInContainerList (mCreatures, id))
|
if (Ptr ptr = searchInContainerList (get<ESM::Creature>(), id))
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
if (Ptr ptr = searchInContainerList (mNpcs, id))
|
if (Ptr ptr = searchInContainerList (get<ESM::NPC>(), id))
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
mHasState = oldState;
|
mHasState = oldState;
|
||||||
|
@ -709,62 +822,33 @@ namespace MWWorld
|
||||||
if (it->second != ref.mRefID)
|
if (it->second != ref.mRefID)
|
||||||
{
|
{
|
||||||
// refID was modified, make sure we don't end up with duplicated refs
|
// refID was modified, make sure we don't end up with duplicated refs
|
||||||
switch (store.find(it->second))
|
ESM::RecNameInts foundType = static_cast<ESM::RecNameInts>(store.find(it->second));
|
||||||
|
if (foundType != 0)
|
||||||
{
|
{
|
||||||
case ESM::REC_ACTI: mActivators.remove(ref.mRefNum); break;
|
Misc::tupleForEach(this->mCellStoreImp->mRefLists,
|
||||||
case ESM::REC_ALCH: mPotions.remove(ref.mRefNum); break;
|
[&ref, foundType](auto& x) { recNameSwitcher(x, foundType, [&ref](auto& storeIn) { storeIn.remove(ref.mRefNum); }); });
|
||||||
case ESM::REC_APPA: mAppas.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_ARMO: mArmors.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_BOOK: mBooks.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_CLOT: mClothes.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_CONT: mContainers.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_CREA: mCreatures.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_DOOR: mDoors.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_INGR: mIngreds.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_LEVC: mCreatureLists.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_LEVI: mItemLists.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_LIGH: mLights.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_LOCK: mLockpicks.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_MISC: mMiscItems.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_NPC_: mNpcs.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_PROB: mProbes.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_REPA: mRepairs.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_STAT: mStatics.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_WEAP: mWeapons.remove(ref.mRefNum); break;
|
|
||||||
case ESM::REC_BODY: mBodyParts.remove(ref.mRefNum); break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (store.find (ref.mRefID))
|
ESM::RecNameInts foundType = static_cast<ESM::RecNameInts>(store.find(ref.mRefID));
|
||||||
|
bool handledType = false;
|
||||||
|
if (foundType != 0)
|
||||||
{
|
{
|
||||||
case ESM::REC_ACTI: mActivators.load(ref, deleted, store); break;
|
Misc::tupleForEach(this->mCellStoreImp->mRefLists, [&ref, &deleted, &store, foundType, &handledType](auto& x) {
|
||||||
case ESM::REC_ALCH: mPotions.load(ref, deleted,store); break;
|
recNameSwitcher(x, foundType, [&ref, &deleted, &store, &handledType](auto& storeIn) {
|
||||||
case ESM::REC_APPA: mAppas.load(ref, deleted, store); break;
|
handledType = true;
|
||||||
case ESM::REC_ARMO: mArmors.load(ref, deleted, store); break;
|
storeIn.load(ref, deleted, store);
|
||||||
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;
|
else
|
||||||
case ESM::REC_DOOR: mDoors.load(ref, deleted, store); break;
|
{
|
||||||
case ESM::REC_INGR: mIngreds.load(ref, deleted, store); break;
|
Log(Debug::Error) << "Cell reference '" + ref.mRefID + "' not found!"; return;
|
||||||
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 ESM::REC_BODY: mBodyParts.load(ref, deleted, store); break;
|
|
||||||
|
|
||||||
case 0: Log(Debug::Error) << "Cell reference '" + ref.mRefID + "' not found!"; return;
|
if (!handledType)
|
||||||
|
{
|
||||||
default:
|
|
||||||
Log(Debug::Error) << "Error: Ignoring reference '" << ref.mRefID << "' of unhandled type";
|
Log(Debug::Error) << "Error: Ignoring reference '" << ref.mRefID << "' of unhandled type";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -809,27 +893,7 @@ namespace MWWorld
|
||||||
|
|
||||||
void CellStore::writeReferences (ESM::ESMWriter& writer) const
|
void CellStore::writeReferences (ESM::ESMWriter& writer) const
|
||||||
{
|
{
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mActivators);
|
Misc::tupleForEach(this->mCellStoreImp->mRefLists, [&writer](auto& cellRefList) { writeReferenceCollection(writer, cellRefList); });
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mPotions);
|
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mAppas);
|
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mArmors);
|
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mBooks);
|
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mClothes);
|
|
||||||
writeReferenceCollection<ESM::ContainerState> (writer, mContainers);
|
|
||||||
writeReferenceCollection<ESM::CreatureState> (writer, mCreatures);
|
|
||||||
writeReferenceCollection<ESM::DoorState> (writer, mDoors);
|
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mIngreds);
|
|
||||||
writeReferenceCollection<ESM::CreatureLevListState> (writer, mCreatureLists);
|
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mItemLists);
|
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mLights);
|
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mLockpicks);
|
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mMiscItems);
|
|
||||||
writeReferenceCollection<ESM::NpcState> (writer, mNpcs);
|
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mProbes);
|
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mRepairs);
|
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mStatics);
|
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mWeapons);
|
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mBodyParts);
|
|
||||||
|
|
||||||
for (const auto& [base, store] : mMovedToAnotherCell)
|
for (const auto& [base, store] : mMovedToAnotherCell)
|
||||||
{
|
{
|
||||||
|
@ -867,116 +931,18 @@ namespace MWWorld
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type)
|
if (type != 0)
|
||||||
{
|
{
|
||||||
case ESM::REC_ACTI:
|
bool foundCorrespondingStore = false;
|
||||||
|
Misc::tupleForEach(this->mCellStoreImp->mRefLists, [&reader, this, &cref, &contentFileMap, &foundCorrespondingStore, type](auto&& x) {
|
||||||
|
recNameSwitcher(x, static_cast<ESM::RecNameInts>(type), [&reader, this, &cref, &contentFileMap, &foundCorrespondingStore](auto& store) {
|
||||||
|
foundCorrespondingStore = true;
|
||||||
|
readReferenceCollection(reader, store, cref, contentFileMap, this);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mActivators, cref, contentFileMap, this);
|
if (!foundCorrespondingStore)
|
||||||
break;
|
throw std::runtime_error("unknown type in cell reference section");
|
||||||
|
|
||||||
case ESM::REC_ALCH:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mPotions, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_APPA:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mAppas, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_ARMO:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mArmors, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_BOOK:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mBooks, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_CLOT:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mClothes, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_CONT:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ContainerState> (reader, mContainers, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_CREA:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::CreatureState> (reader, mCreatures, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_DOOR:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::DoorState> (reader, mDoors, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_INGR:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mIngreds, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_LEVC:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::CreatureLevListState> (reader, mCreatureLists, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_LEVI:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mItemLists, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_LIGH:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mLights, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_LOCK:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mLockpicks, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_MISC:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mMiscItems, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_NPC_:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::NpcState> (reader, mNpcs, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_PROB:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mProbes, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_REPA:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mRepairs, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_STAT:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mStatics, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_WEAP:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mWeapons, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESM::REC_BODY:
|
|
||||||
|
|
||||||
readReferenceCollection<ESM::ObjectState> (reader, mBodyParts, cref, contentFileMap, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
throw std::runtime_error ("unknown type in cell reference section");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1067,7 +1033,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
if (mState == State_Loaded)
|
if (mState == State_Loaded)
|
||||||
{
|
{
|
||||||
for (CellRefList<ESM::Creature>::List::iterator it (mCreatures.mList.begin()); it!=mCreatures.mList.end(); ++it)
|
for (CellRefList<ESM::Creature>::List::iterator it (get<ESM::Creature>().mList.begin()); it!=get<ESM::Creature>().mList.end(); ++it)
|
||||||
{
|
{
|
||||||
Ptr ptr = getCurrentPtr(&*it);
|
Ptr ptr = getCurrentPtr(&*it);
|
||||||
if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0)
|
if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0)
|
||||||
|
@ -1075,7 +1041,7 @@ namespace MWWorld
|
||||||
MWBase::Environment::get().getMechanicsManager()->restoreDynamicStats(ptr, hours, true);
|
MWBase::Environment::get().getMechanicsManager()->restoreDynamicStats(ptr, hours, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (CellRefList<ESM::NPC>::List::iterator it (mNpcs.mList.begin()); it!=mNpcs.mList.end(); ++it)
|
for (CellRefList<ESM::NPC>::List::iterator it (get<ESM::NPC>().mList.begin()); it!=get<ESM::NPC>().mList.end(); ++it)
|
||||||
{
|
{
|
||||||
Ptr ptr = getCurrentPtr(&*it);
|
Ptr ptr = getCurrentPtr(&*it);
|
||||||
if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0)
|
if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0)
|
||||||
|
@ -1093,7 +1059,7 @@ namespace MWWorld
|
||||||
|
|
||||||
if (mState == State_Loaded)
|
if (mState == State_Loaded)
|
||||||
{
|
{
|
||||||
for (CellRefList<ESM::Creature>::List::iterator it (mCreatures.mList.begin()); it!=mCreatures.mList.end(); ++it)
|
for (CellRefList<ESM::Creature>::List::iterator it (get<ESM::Creature>().mList.begin()); it!=get<ESM::Creature>().mList.end(); ++it)
|
||||||
{
|
{
|
||||||
Ptr ptr = getCurrentPtr(&*it);
|
Ptr ptr = getCurrentPtr(&*it);
|
||||||
if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0)
|
if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0)
|
||||||
|
@ -1101,7 +1067,7 @@ namespace MWWorld
|
||||||
ptr.getClass().getContainerStore(ptr).rechargeItems(duration);
|
ptr.getClass().getContainerStore(ptr).rechargeItems(duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (CellRefList<ESM::NPC>::List::iterator it (mNpcs.mList.begin()); it!=mNpcs.mList.end(); ++it)
|
for (CellRefList<ESM::NPC>::List::iterator it (get<ESM::NPC>().mList.begin()); it!=get<ESM::NPC>().mList.end(); ++it)
|
||||||
{
|
{
|
||||||
Ptr ptr = getCurrentPtr(&*it);
|
Ptr ptr = getCurrentPtr(&*it);
|
||||||
if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0)
|
if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0)
|
||||||
|
@ -1109,7 +1075,7 @@ namespace MWWorld
|
||||||
ptr.getClass().getContainerStore(ptr).rechargeItems(duration);
|
ptr.getClass().getContainerStore(ptr).rechargeItems(duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (CellRefList<ESM::Container>::List::iterator it (mContainers.mList.begin()); it!=mContainers.mList.end(); ++it)
|
for (CellRefList<ESM::Container>::List::iterator it (get<ESM::Container>().mList.begin()); it!=get<ESM::Container>().mList.end(); ++it)
|
||||||
{
|
{
|
||||||
Ptr ptr = getCurrentPtr(&*it);
|
Ptr ptr = getCurrentPtr(&*it);
|
||||||
if (!ptr.isEmpty() && ptr.getRefData().getCustomData() != nullptr && ptr.getRefData().getCount() > 0
|
if (!ptr.isEmpty() && ptr.getRefData().getCustomData() != nullptr && ptr.getRefData().getCount() > 0
|
||||||
|
@ -1131,29 +1097,29 @@ namespace MWWorld
|
||||||
if (MWBase::Environment::get().getWorld()->getTimeStamp() - mLastRespawn > 24*30*iMonthsToRespawn)
|
if (MWBase::Environment::get().getWorld()->getTimeStamp() - mLastRespawn > 24*30*iMonthsToRespawn)
|
||||||
{
|
{
|
||||||
mLastRespawn = MWBase::Environment::get().getWorld()->getTimeStamp();
|
mLastRespawn = MWBase::Environment::get().getWorld()->getTimeStamp();
|
||||||
for (CellRefList<ESM::Container>::List::iterator it (mContainers.mList.begin()); it!=mContainers.mList.end(); ++it)
|
for (CellRefList<ESM::Container>::List::iterator it (get<ESM::Container>().mList.begin()); it!=get<ESM::Container>().mList.end(); ++it)
|
||||||
{
|
{
|
||||||
Ptr ptr = getCurrentPtr(&*it);
|
Ptr ptr = getCurrentPtr(&*it);
|
||||||
ptr.getClass().respawn(ptr);
|
ptr.getClass().respawn(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (CellRefList<ESM::Creature>::List::iterator it (mCreatures.mList.begin()); it!=mCreatures.mList.end(); ++it)
|
for (CellRefList<ESM::Creature>::List::iterator it (get<ESM::Creature>().mList.begin()); it!=get<ESM::Creature>().mList.end(); ++it)
|
||||||
{
|
{
|
||||||
Ptr ptr = getCurrentPtr(&*it);
|
Ptr ptr = getCurrentPtr(&*it);
|
||||||
clearCorpse(ptr);
|
clearCorpse(ptr);
|
||||||
ptr.getClass().respawn(ptr);
|
ptr.getClass().respawn(ptr);
|
||||||
}
|
}
|
||||||
for (CellRefList<ESM::NPC>::List::iterator it (mNpcs.mList.begin()); it!=mNpcs.mList.end(); ++it)
|
for (CellRefList<ESM::NPC>::List::iterator it (get<ESM::NPC>().mList.begin()); it!=get<ESM::NPC>().mList.end(); ++it)
|
||||||
{
|
{
|
||||||
Ptr ptr = getCurrentPtr(&*it);
|
Ptr ptr = getCurrentPtr(&*it);
|
||||||
clearCorpse(ptr);
|
clearCorpse(ptr);
|
||||||
ptr.getClass().respawn(ptr);
|
ptr.getClass().respawn(ptr);
|
||||||
}
|
}
|
||||||
for (CellRefList<ESM::CreatureLevList>::List::iterator it (mCreatureLists.mList.begin()); it!=mCreatureLists.mList.end(); ++it)
|
for (CellRefList<ESM::CreatureLevList>::List::iterator it (get<ESM::CreatureLevList>().mList.begin()); it!=get<ESM::CreatureLevList>().mList.end(); ++it)
|
||||||
{
|
{
|
||||||
Ptr ptr = getCurrentPtr(&*it);
|
Ptr ptr = getCurrentPtr(&*it);
|
||||||
// no need to clearCorpse, handled as part of mCreatures
|
// no need to clearCorpse, handled as part of get<ESM::Creature>()
|
||||||
ptr.getClass().respawn(ptr);
|
ptr.getClass().respawn(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1188,10 +1154,10 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
update(mWeapons.mList);
|
update(get<ESM::Weapon>().mList);
|
||||||
update(mArmors.mList);
|
update(get<ESM::Armor>().mList);
|
||||||
update(mClothes.mList);
|
update(get<ESM::Clothing>().mList);
|
||||||
update(mBooks.mList);
|
update(get<ESM::Book>().mList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWWorld::CellStore::checkItem(const Ptr& ptr)
|
void MWWorld::CellStore::checkItem(const Ptr& ptr)
|
||||||
|
|
|
@ -2,36 +2,19 @@
|
||||||
#define GAME_MWWORLD_CELLSTORE_H
|
#define GAME_MWWORLD_CELLSTORE_H
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <tuple>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "livecellref.hpp"
|
#include "livecellref.hpp"
|
||||||
#include "cellreflist.hpp"
|
#include "cellreflist.hpp"
|
||||||
|
|
||||||
#include <components/esm3/loadacti.hpp>
|
#include <components/misc/tuplemeta.hpp>
|
||||||
#include <components/esm3/loadalch.hpp>
|
|
||||||
#include <components/esm3/loadappa.hpp>
|
|
||||||
#include <components/esm3/loadarmo.hpp>
|
|
||||||
#include <components/esm3/loadbook.hpp>
|
|
||||||
#include <components/esm3/loadclot.hpp>
|
|
||||||
#include <components/esm3/loadcont.hpp>
|
|
||||||
#include <components/esm3/loadcrea.hpp>
|
|
||||||
#include <components/esm3/loaddoor.hpp>
|
|
||||||
#include <components/esm3/loadingr.hpp>
|
|
||||||
#include <components/esm3/loadlevlist.hpp>
|
|
||||||
#include <components/esm3/loadligh.hpp>
|
|
||||||
#include <components/esm3/loadlock.hpp>
|
|
||||||
#include <components/esm3/loadprob.hpp>
|
|
||||||
#include <components/esm3/loadrepa.hpp>
|
|
||||||
#include <components/esm3/loadstat.hpp>
|
|
||||||
#include <components/esm3/loadweap.hpp>
|
|
||||||
#include <components/esm3/loadnpc.hpp>
|
|
||||||
#include <components/esm3/loadmisc.hpp>
|
|
||||||
#include <components/esm3/loadbody.hpp>
|
|
||||||
#include <components/esm3/fogstate.hpp>
|
#include <components/esm3/fogstate.hpp>
|
||||||
|
|
||||||
#include "timestamp.hpp"
|
#include "timestamp.hpp"
|
||||||
|
@ -44,15 +27,61 @@ namespace ESM
|
||||||
struct CellState;
|
struct CellState;
|
||||||
struct CellId;
|
struct CellId;
|
||||||
struct RefNum;
|
struct RefNum;
|
||||||
|
struct Activator;
|
||||||
|
struct Potion;
|
||||||
|
struct Apparatus;
|
||||||
|
struct Armor;
|
||||||
|
struct Book;
|
||||||
|
struct Clothing;
|
||||||
|
struct Container;
|
||||||
|
struct Creature;
|
||||||
|
struct Door;
|
||||||
|
struct Ingredient;
|
||||||
|
struct CreatureLevList;
|
||||||
|
struct ItemLevList;
|
||||||
|
struct Light;
|
||||||
|
struct Lockpick;
|
||||||
|
struct Miscellaneous;
|
||||||
|
struct NPC;
|
||||||
|
struct Probe;
|
||||||
|
struct Repair;
|
||||||
|
struct Static;
|
||||||
|
struct Weapon;
|
||||||
|
struct BodyPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
class ESMStore;
|
class ESMStore;
|
||||||
|
struct CellStoreImp;
|
||||||
|
|
||||||
|
using CellStoreTuple = std::tuple <
|
||||||
|
CellRefList<ESM::Activator>,
|
||||||
|
CellRefList<ESM::Potion>,
|
||||||
|
CellRefList<ESM::Apparatus>,
|
||||||
|
CellRefList<ESM::Armor>,
|
||||||
|
CellRefList<ESM::Book>,
|
||||||
|
CellRefList<ESM::Clothing>,
|
||||||
|
CellRefList<ESM::Container>,
|
||||||
|
CellRefList<ESM::Creature>,
|
||||||
|
CellRefList<ESM::Door>,
|
||||||
|
CellRefList<ESM::Ingredient>,
|
||||||
|
CellRefList<ESM::CreatureLevList>,
|
||||||
|
CellRefList<ESM::ItemLevList>,
|
||||||
|
CellRefList<ESM::Light>,
|
||||||
|
CellRefList<ESM::Lockpick>,
|
||||||
|
CellRefList<ESM::Miscellaneous>,
|
||||||
|
CellRefList<ESM::NPC>,
|
||||||
|
CellRefList<ESM::Probe>,
|
||||||
|
CellRefList<ESM::Repair>,
|
||||||
|
CellRefList<ESM::Static>,
|
||||||
|
CellRefList<ESM::Weapon>,
|
||||||
|
CellRefList<ESM::BodyPart>>;
|
||||||
|
|
||||||
/// \brief Mutable state of a cell
|
/// \brief Mutable state of a cell
|
||||||
class CellStore
|
class CellStore
|
||||||
{
|
{
|
||||||
|
friend struct CellStoreImp;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum State
|
enum State
|
||||||
|
@ -78,28 +107,29 @@ namespace MWWorld
|
||||||
|
|
||||||
MWWorld::TimeStamp mLastRespawn;
|
MWWorld::TimeStamp mLastRespawn;
|
||||||
|
|
||||||
// List of refs owned by this cell
|
template<typename T>
|
||||||
CellRefList<ESM::Activator> mActivators;
|
static constexpr std::size_t getTypeIndex()
|
||||||
CellRefList<ESM::Potion> mPotions;
|
{
|
||||||
CellRefList<ESM::Apparatus> mAppas;
|
static_assert(Misc::TupleHasType<CellRefList<T>, CellStoreTuple>::value);
|
||||||
CellRefList<ESM::Armor> mArmors;
|
return Misc::TupleTypeIndex<CellRefList<T>, CellStoreTuple>::value;
|
||||||
CellRefList<ESM::Book> mBooks;
|
}
|
||||||
CellRefList<ESM::Clothing> mClothes;
|
|
||||||
CellRefList<ESM::Container> mContainers;
|
std::unique_ptr<CellStoreImp> mCellStoreImp;
|
||||||
CellRefList<ESM::Creature> mCreatures;
|
std::vector<CellRefListBase*> mCellRefLists;
|
||||||
CellRefList<ESM::Door> mDoors;
|
|
||||||
CellRefList<ESM::Ingredient> mIngreds;
|
|
||||||
CellRefList<ESM::CreatureLevList> mCreatureLists;
|
template <class T>
|
||||||
CellRefList<ESM::ItemLevList> mItemLists;
|
CellRefList<T>& get()
|
||||||
CellRefList<ESM::Light> mLights;
|
{
|
||||||
CellRefList<ESM::Lockpick> mLockpicks;
|
mHasState = true;
|
||||||
CellRefList<ESM::Miscellaneous> mMiscItems;
|
return static_cast<CellRefList<T>&>(*mCellRefLists[getTypeIndex<T>()]);
|
||||||
CellRefList<ESM::NPC> mNpcs;
|
}
|
||||||
CellRefList<ESM::Probe> mProbes;
|
|
||||||
CellRefList<ESM::Repair> mRepairs;
|
template <class T>
|
||||||
CellRefList<ESM::Static> mStatics;
|
const CellRefList<T>& get() const
|
||||||
CellRefList<ESM::Weapon> mWeapons;
|
{
|
||||||
CellRefList<ESM::BodyPart> mBodyParts;
|
return static_cast<const CellRefList<T>&>(*mCellRefLists[getTypeIndex<T>()]);
|
||||||
|
}
|
||||||
|
|
||||||
typedef std::map<LiveCellRefBase*, MWWorld::CellStore*> MovedRefTracker;
|
typedef std::map<LiveCellRefBase*, MWWorld::CellStore*> MovedRefTracker;
|
||||||
// References owned by a different cell that have been moved here.
|
// References owned by a different cell that have been moved here.
|
||||||
|
@ -131,53 +161,6 @@ namespace MWWorld
|
||||||
void rechargeItems(float duration);
|
void rechargeItems(float duration);
|
||||||
void checkItem(const Ptr& ptr);
|
void checkItem(const Ptr& ptr);
|
||||||
|
|
||||||
// helper function for forEachInternal
|
|
||||||
template<class Visitor, class List>
|
|
||||||
bool forEachImp (Visitor& visitor, List& list)
|
|
||||||
{
|
|
||||||
for (typename List::List::iterator iter (list.mList.begin()); iter!=list.mList.end();
|
|
||||||
++iter)
|
|
||||||
{
|
|
||||||
if (!isAccessible(iter->mData, iter->mRef))
|
|
||||||
continue;
|
|
||||||
if (!visitor (MWWorld::Ptr(&*iter, this)))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// listing only objects owned by this cell. Internal use only, you probably want to use forEach() so that moved objects are accounted for.
|
|
||||||
template<class Visitor>
|
|
||||||
bool forEachInternal (Visitor& visitor)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
forEachImp (visitor, mActivators) &&
|
|
||||||
forEachImp (visitor, mPotions) &&
|
|
||||||
forEachImp (visitor, mAppas) &&
|
|
||||||
forEachImp (visitor, mArmors) &&
|
|
||||||
forEachImp (visitor, mBooks) &&
|
|
||||||
forEachImp (visitor, mClothes) &&
|
|
||||||
forEachImp (visitor, mContainers) &&
|
|
||||||
forEachImp (visitor, mDoors) &&
|
|
||||||
forEachImp (visitor, mIngreds) &&
|
|
||||||
forEachImp (visitor, mItemLists) &&
|
|
||||||
forEachImp (visitor, mLights) &&
|
|
||||||
forEachImp (visitor, mLockpicks) &&
|
|
||||||
forEachImp (visitor, mMiscItems) &&
|
|
||||||
forEachImp (visitor, mProbes) &&
|
|
||||||
forEachImp (visitor, mRepairs) &&
|
|
||||||
forEachImp (visitor, mStatics) &&
|
|
||||||
forEachImp (visitor, mWeapons) &&
|
|
||||||
forEachImp (visitor, mBodyParts) &&
|
|
||||||
forEachImp (visitor, mCreatures) &&
|
|
||||||
forEachImp (visitor, mNpcs) &&
|
|
||||||
forEachImp (visitor, mCreatureLists);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @note If you get a linker error here, this means the given type can not be stored in a cell. The supported types are
|
|
||||||
/// defined at the bottom of this file.
|
|
||||||
template <class T>
|
|
||||||
CellRefList<T>& get();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -214,6 +197,8 @@ namespace MWWorld
|
||||||
|
|
||||||
/// @param readerList The readers to use for loading of the cell on-demand.
|
/// @param readerList The readers to use for loading of the cell on-demand.
|
||||||
CellStore(const ESM::Cell* cell, const MWWorld::ESMStore& store, ESM::ReadersCache& readers);
|
CellStore(const ESM::Cell* cell, const MWWorld::ESMStore& store, ESM::ReadersCache& readers);
|
||||||
|
CellStore(CellStore&&);
|
||||||
|
~CellStore();
|
||||||
|
|
||||||
const ESM::Cell *getCell() const;
|
const ESM::Cell *getCell() const;
|
||||||
|
|
||||||
|
@ -362,11 +347,11 @@ namespace MWWorld
|
||||||
// Should be phased out when we have const version of forEach
|
// Should be phased out when we have const version of forEach
|
||||||
inline const CellRefList<ESM::Door>& getReadOnlyDoors() const
|
inline const CellRefList<ESM::Door>& getReadOnlyDoors() const
|
||||||
{
|
{
|
||||||
return mDoors;
|
return get<ESM::Door>();
|
||||||
}
|
}
|
||||||
inline const CellRefList<ESM::Static>& getReadOnlyStatics() const
|
inline const CellRefList<ESM::Static>& getReadOnlyStatics() const
|
||||||
{
|
{
|
||||||
return mStatics;
|
return get<ESM::Static>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isExterior() const;
|
bool isExterior() const;
|
||||||
|
@ -414,153 +399,6 @@ namespace MWWorld
|
||||||
/// Invalid \a ref objects are silently dropped.
|
/// Invalid \a ref objects are silently dropped.
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Activator>& CellStore::get<ESM::Activator>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mActivators;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Potion>& CellStore::get<ESM::Potion>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mPotions;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Apparatus>& CellStore::get<ESM::Apparatus>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mAppas;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Armor>& CellStore::get<ESM::Armor>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mArmors;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Book>& CellStore::get<ESM::Book>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mBooks;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Clothing>& CellStore::get<ESM::Clothing>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mClothes;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Container>& CellStore::get<ESM::Container>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mContainers;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Creature>& CellStore::get<ESM::Creature>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mCreatures;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Door>& CellStore::get<ESM::Door>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mDoors;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Ingredient>& CellStore::get<ESM::Ingredient>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mIngreds;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::CreatureLevList>& CellStore::get<ESM::CreatureLevList>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mCreatureLists;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::ItemLevList>& CellStore::get<ESM::ItemLevList>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mItemLists;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Light>& CellStore::get<ESM::Light>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mLights;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Lockpick>& CellStore::get<ESM::Lockpick>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mLockpicks;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Miscellaneous>& CellStore::get<ESM::Miscellaneous>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mMiscItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::NPC>& CellStore::get<ESM::NPC>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mNpcs;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Probe>& CellStore::get<ESM::Probe>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mProbes;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Repair>& CellStore::get<ESM::Repair>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mRepairs;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Static>& CellStore::get<ESM::Static>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mStatics;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::Weapon>& CellStore::get<ESM::Weapon>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mWeapons;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline CellRefList<ESM::BodyPart>& CellStore::get<ESM::BodyPart>()
|
|
||||||
{
|
|
||||||
mHasState = true;
|
|
||||||
return mBodyParts;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator== (const CellStore& left, const CellStore& right);
|
bool operator== (const CellStore& left, const CellStore& right);
|
||||||
bool operator!= (const CellStore& left, const CellStore& right);
|
bool operator!= (const CellStore& left, const CellStore& right);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
#include <components/esm3/loadscpt.hpp>
|
#include <components/esm3/loadscpt.hpp>
|
||||||
|
#include <components/esm3/loadcont.hpp>
|
||||||
|
#include <components/esm3/loadcrea.hpp>
|
||||||
|
#include <components/esm3/loadnpc.hpp>
|
||||||
|
|
||||||
#include "esmstore.hpp"
|
#include "esmstore.hpp"
|
||||||
#include "cellstore.hpp"
|
#include "cellstore.hpp"
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <components/misc/convert.hpp>
|
#include <components/misc/convert.hpp>
|
||||||
#include <components/detournavigator/heightfieldshape.hpp>
|
#include <components/detournavigator/heightfieldshape.hpp>
|
||||||
#include <components/detournavigator/navigatorimpl.hpp>
|
#include <components/detournavigator/navigatorimpl.hpp>
|
||||||
|
#include <components/esm/records.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include <components/esm3/loadench.hpp>
|
#include <components/esm3/loadench.hpp>
|
||||||
#include <components/esm3/loadmgef.hpp>
|
#include <components/esm3/loadmgef.hpp>
|
||||||
#include <components/esm3/loadclas.hpp>
|
#include <components/esm3/loadclas.hpp>
|
||||||
|
#include <components/esm3/loadcrea.hpp>
|
||||||
|
#include <components/esm3/loadstat.hpp>
|
||||||
|
|
||||||
#include <components/misc/constants.hpp>
|
#include <components/misc/constants.hpp>
|
||||||
#include <components/misc/mathutil.hpp>
|
#include <components/misc/mathutil.hpp>
|
||||||
|
|
|
@ -197,7 +197,7 @@ add_component_dir (esm4
|
||||||
|
|
||||||
add_component_dir (misc
|
add_component_dir (misc
|
||||||
constants utf8stream resourcehelpers rng messageformatparser weakcache thread
|
constants utf8stream resourcehelpers rng messageformatparser weakcache thread
|
||||||
compression osguservalues errorMarker color
|
compression osguservalues errorMarker color tuplemeta tuplehelpers
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (stereo
|
add_component_dir (stereo
|
||||||
|
|
15
components/misc/tuplehelpers.hpp
Normal file
15
components/misc/tuplehelpers.hpp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef OPENMW_COMPONENTS_MISC_TUPLEHELPERS_H
|
||||||
|
#define OPENMW_COMPONENTS_MISC_TUPLEHELPERS_H
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace Misc
|
||||||
|
{
|
||||||
|
template <typename TupleType, typename Callable>
|
||||||
|
void tupleForEach(TupleType& tuple, Callable&& f)
|
||||||
|
{
|
||||||
|
std::apply([&f](auto&... x) { (f(x), ...); }, tuple);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue