forked from mirror/openmw-tes3mp
Feature #32: Implement respawn for containers, creatures and NPCs
This commit is contained in:
parent
92c5bb56e0
commit
ae66d28c87
16 changed files with 146 additions and 5 deletions
|
@ -60,6 +60,16 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Container::respawn(const MWWorld::Ptr &ptr) const
|
||||||
|
{
|
||||||
|
MWWorld::LiveCellRef<ESM::Container> *ref =
|
||||||
|
ptr.get<ESM::Container>();
|
||||||
|
if (ref->mBase->mFlags & ESM::Container::Respawn)
|
||||||
|
{
|
||||||
|
ptr.getRefData().setCustomData(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Container::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Container::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
|
|
@ -64,6 +64,8 @@ namespace MWClass
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
|
virtual void respawn (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -822,6 +822,26 @@ namespace MWClass
|
||||||
return ptr.get<ESM::Creature>()->mBase->mData.mGold;
|
return ptr.get<ESM::Creature>()->mBase->mData.mGold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Creature::respawn(const MWWorld::Ptr &ptr) const
|
||||||
|
{
|
||||||
|
if (ptr.get<ESM::Creature>()->mBase->mFlags & ESM::Creature::Respawn)
|
||||||
|
{
|
||||||
|
// Note we do not respawn moved references in the cell they were moved to. Instead they are respawned in the original cell.
|
||||||
|
// This also means we cannot respawn dynamically placed references with no content file connection.
|
||||||
|
if (ptr.getCellRef().mRefNum.mContentFile != -1)
|
||||||
|
{
|
||||||
|
if (ptr.getRefData().getCount() == 0)
|
||||||
|
ptr.getRefData().setCount(1);
|
||||||
|
|
||||||
|
// Reset to original position
|
||||||
|
ESM::Position& pos = ptr.getRefData().getPosition();
|
||||||
|
pos = ptr.getCellRef().mPos;
|
||||||
|
|
||||||
|
ptr.getRefData().setCustomData(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const ESM::GameSetting* Creature::fMinWalkSpeedCreature;
|
const ESM::GameSetting* Creature::fMinWalkSpeedCreature;
|
||||||
const ESM::GameSetting* Creature::fMaxWalkSpeedCreature;
|
const ESM::GameSetting* Creature::fMaxWalkSpeedCreature;
|
||||||
const ESM::GameSetting *Creature::fEncumberedMoveEffect;
|
const ESM::GameSetting *Creature::fEncumberedMoveEffect;
|
||||||
|
|
|
@ -143,6 +143,8 @@ namespace MWClass
|
||||||
///< Write additional state from \a ptr into \a state.
|
///< Write additional state from \a ptr into \a state.
|
||||||
|
|
||||||
virtual int getBaseGold(const MWWorld::Ptr& ptr) const;
|
virtual int getBaseGold(const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
|
virtual void respawn (const MWWorld::Ptr& ptr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace
|
||||||
{
|
{
|
||||||
// actorId of the creature we spawned
|
// actorId of the creature we spawned
|
||||||
int mSpawnActorId;
|
int mSpawnActorId;
|
||||||
|
bool mSpawn; // Should a new creature be spawned?
|
||||||
|
|
||||||
virtual MWWorld::CustomData *clone() const;
|
virtual MWWorld::CustomData *clone() const;
|
||||||
};
|
};
|
||||||
|
@ -31,6 +32,14 @@ namespace MWClass
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CreatureLevList::respawn(const MWWorld::Ptr &ptr) const
|
||||||
|
{
|
||||||
|
ensureCustomData(ptr);
|
||||||
|
|
||||||
|
CreatureLevListCustomData& customData = dynamic_cast<CreatureLevListCustomData&> (*ptr.getRefData().getCustomData());
|
||||||
|
customData.mSpawn = true;
|
||||||
|
}
|
||||||
|
|
||||||
void CreatureLevList::registerSelf()
|
void CreatureLevList::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new CreatureLevList);
|
boost::shared_ptr<Class> instance (new CreatureLevList);
|
||||||
|
@ -43,9 +52,8 @@ namespace MWClass
|
||||||
ensureCustomData(ptr);
|
ensureCustomData(ptr);
|
||||||
|
|
||||||
CreatureLevListCustomData& customData = dynamic_cast<CreatureLevListCustomData&> (*ptr.getRefData().getCustomData());
|
CreatureLevListCustomData& customData = dynamic_cast<CreatureLevListCustomData&> (*ptr.getRefData().getCustomData());
|
||||||
if (customData.mSpawnActorId != -1)
|
if (!customData.mSpawn)
|
||||||
return; // TODO: handle respawning
|
return;
|
||||||
|
|
||||||
|
|
||||||
MWWorld::LiveCellRef<ESM::CreatureLevList> *ref =
|
MWWorld::LiveCellRef<ESM::CreatureLevList> *ref =
|
||||||
ptr.get<ESM::CreatureLevList>();
|
ptr.get<ESM::CreatureLevList>();
|
||||||
|
@ -54,11 +62,21 @@ namespace MWClass
|
||||||
|
|
||||||
if (!id.empty())
|
if (!id.empty())
|
||||||
{
|
{
|
||||||
|
// Delete the previous creature
|
||||||
|
if (customData.mSpawnActorId != -1)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr creature = MWBase::Environment::get().getWorld()->searchPtrViaActorId(customData.mSpawnActorId);
|
||||||
|
if (!creature.isEmpty())
|
||||||
|
MWBase::Environment::get().getWorld()->deleteObject(creature);
|
||||||
|
customData.mSpawnActorId = -1;
|
||||||
|
}
|
||||||
|
|
||||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
MWWorld::ManualRef ref(store, id);
|
MWWorld::ManualRef ref(store, id);
|
||||||
ref.getPtr().getCellRef().mPos = ptr.getCellRef().mPos;
|
ref.getPtr().getCellRef().mPos = ptr.getCellRef().mPos;
|
||||||
MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(), ptr.getCell() , ptr.getCellRef().mPos);
|
MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(), ptr.getCell() , ptr.getCellRef().mPos);
|
||||||
customData.mSpawnActorId = placed.getClass().getCreatureStats(placed).getActorId();
|
customData.mSpawnActorId = placed.getClass().getCreatureStats(placed).getActorId();
|
||||||
|
customData.mSpawn = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +86,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
std::auto_ptr<CreatureLevListCustomData> data (new CreatureLevListCustomData);
|
std::auto_ptr<CreatureLevListCustomData> data (new CreatureLevListCustomData);
|
||||||
data->mSpawnActorId = -1;
|
data->mSpawnActorId = -1;
|
||||||
|
data->mSpawn = true;
|
||||||
|
|
||||||
ptr.getRefData().setCustomData(data.release());
|
ptr.getRefData().setCustomData(data.release());
|
||||||
}
|
}
|
||||||
|
@ -81,6 +100,7 @@ namespace MWClass
|
||||||
ensureCustomData(ptr);
|
ensureCustomData(ptr);
|
||||||
CreatureLevListCustomData& customData = dynamic_cast<CreatureLevListCustomData&> (*ptr.getRefData().getCustomData());
|
CreatureLevListCustomData& customData = dynamic_cast<CreatureLevListCustomData&> (*ptr.getRefData().getCustomData());
|
||||||
customData.mSpawnActorId = state2.mSpawnActorId;
|
customData.mSpawnActorId = state2.mSpawnActorId;
|
||||||
|
customData.mSpawn = state2.mSpawn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureLevList::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state)
|
void CreatureLevList::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state)
|
||||||
|
@ -91,5 +111,6 @@ namespace MWClass
|
||||||
ensureCustomData(ptr);
|
ensureCustomData(ptr);
|
||||||
CreatureLevListCustomData& customData = dynamic_cast<CreatureLevListCustomData&> (*ptr.getRefData().getCustomData());
|
CreatureLevListCustomData& customData = dynamic_cast<CreatureLevListCustomData&> (*ptr.getRefData().getCustomData());
|
||||||
state2.mSpawnActorId = customData.mSpawnActorId;
|
state2.mSpawnActorId = customData.mSpawnActorId;
|
||||||
|
state2.mSpawn = customData.mSpawn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@ namespace MWClass
|
||||||
virtual void writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state)
|
virtual void writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state)
|
||||||
const;
|
const;
|
||||||
///< Write additional state from \a ptr into \a state.
|
///< Write additional state from \a ptr into \a state.
|
||||||
|
|
||||||
|
virtual void respawn (const MWWorld::Ptr& ptr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1310,6 +1310,26 @@ namespace MWClass
|
||||||
return Misc::StringUtils::ciEqual(ptr.get<ESM::NPC>()->mBase->mClass, className);
|
return Misc::StringUtils::ciEqual(ptr.get<ESM::NPC>()->mBase->mClass, className);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Npc::respawn(const MWWorld::Ptr &ptr) const
|
||||||
|
{
|
||||||
|
if (ptr.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Respawn)
|
||||||
|
{
|
||||||
|
// Note we do not respawn moved references in the cell they were moved to. Instead they are respawned in the original cell.
|
||||||
|
// This also means we cannot respawn dynamically placed references with no content file connection.
|
||||||
|
if (ptr.getCellRef().mRefNum.mContentFile != -1)
|
||||||
|
{
|
||||||
|
if (ptr.getRefData().getCount() == 0)
|
||||||
|
ptr.getRefData().setCount(1);
|
||||||
|
|
||||||
|
// Reset to original position
|
||||||
|
ESM::Position& pos = ptr.getRefData().getPosition();
|
||||||
|
pos = ptr.getCellRef().mPos;
|
||||||
|
|
||||||
|
ptr.getRefData().setCustomData(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const ESM::GameSetting *Npc::fMinWalkSpeed;
|
const ESM::GameSetting *Npc::fMinWalkSpeed;
|
||||||
const ESM::GameSetting *Npc::fMaxWalkSpeed;
|
const ESM::GameSetting *Npc::fMaxWalkSpeed;
|
||||||
const ESM::GameSetting *Npc::fEncumberedMoveEffect;
|
const ESM::GameSetting *Npc::fEncumberedMoveEffect;
|
||||||
|
|
|
@ -178,6 +178,8 @@ namespace MWClass
|
||||||
virtual bool canWalk (const MWWorld::Ptr &ptr) const {
|
virtual bool canWalk (const MWWorld::Ptr &ptr) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void respawn (const MWWorld::Ptr& ptr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
CellStore::CellStore (const ESM::Cell *cell)
|
CellStore::CellStore (const ESM::Cell *cell)
|
||||||
: mCell (cell), mState (State_Unloaded), mHasState (false)
|
: mCell (cell), mState (State_Unloaded), mHasState (false), mLastRespawn(0,0)
|
||||||
{
|
{
|
||||||
mWaterLevel = cell->mWater;
|
mWaterLevel = cell->mWater;
|
||||||
}
|
}
|
||||||
|
@ -555,6 +555,7 @@ namespace MWWorld
|
||||||
mWaterLevel = state.mWaterLevel;
|
mWaterLevel = state.mWaterLevel;
|
||||||
|
|
||||||
mWaterLevel = state.mWaterLevel;
|
mWaterLevel = state.mWaterLevel;
|
||||||
|
mLastRespawn = MWWorld::TimeStamp(state.mLastRespawn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CellStore::saveState (ESM::CellState& state) const
|
void CellStore::saveState (ESM::CellState& state) const
|
||||||
|
@ -566,6 +567,7 @@ namespace MWWorld
|
||||||
|
|
||||||
state.mWaterLevel = mWaterLevel;
|
state.mWaterLevel = mWaterLevel;
|
||||||
state.mHasFogOfWar = (mFogState.get() ? 1 : 0);
|
state.mHasFogOfWar = (mFogState.get() ? 1 : 0);
|
||||||
|
state.mLastRespawn = mLastRespawn.toEsm();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CellStore::writeFog(ESM::ESMWriter &writer) const
|
void CellStore::writeFog(ESM::ESMWriter &writer) const
|
||||||
|
@ -754,4 +756,36 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
return mFogState.get();
|
return mFogState.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CellStore::respawn()
|
||||||
|
{
|
||||||
|
if (mState == State_Loaded)
|
||||||
|
{
|
||||||
|
static int iMonthsToRespawn = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("iMonthsToRespawn")->getInt();
|
||||||
|
if (MWBase::Environment::get().getWorld()->getTimeStamp() - mLastRespawn > 24*30*iMonthsToRespawn)
|
||||||
|
{
|
||||||
|
mLastRespawn = MWBase::Environment::get().getWorld()->getTimeStamp();
|
||||||
|
for (CellRefList<ESM::Container>::List::iterator it (mContainers.mList.begin()); it!=mContainers.mList.end(); ++it)
|
||||||
|
{
|
||||||
|
Ptr ptr (&*it, this);
|
||||||
|
ptr.getClass().respawn(ptr);
|
||||||
|
}
|
||||||
|
for (CellRefList<ESM::Creature>::List::iterator it (mCreatures.mList.begin()); it!=mCreatures.mList.end(); ++it)
|
||||||
|
{
|
||||||
|
Ptr ptr (&*it, this);
|
||||||
|
ptr.getClass().respawn(ptr);
|
||||||
|
}
|
||||||
|
for (CellRefList<ESM::NPC>::List::iterator it (mNpcs.mList.begin()); it!=mNpcs.mList.end(); ++it)
|
||||||
|
{
|
||||||
|
Ptr ptr (&*it, this);
|
||||||
|
ptr.getClass().respawn(ptr);
|
||||||
|
}
|
||||||
|
for (CellRefList<ESM::CreatureLevList>::List::iterator it (mCreatureLists.mList.begin()); it!=mCreatureLists.mList.end(); ++it)
|
||||||
|
{
|
||||||
|
Ptr ptr (&*it, this);
|
||||||
|
ptr.getClass().respawn(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
#include "../mwmechanics/pathgrid.hpp" // TODO: maybe belongs in mwworld
|
#include "../mwmechanics/pathgrid.hpp" // TODO: maybe belongs in mwworld
|
||||||
|
|
||||||
|
#include "timestamp.hpp"
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
struct CellState;
|
struct CellState;
|
||||||
|
@ -48,6 +50,8 @@ namespace MWWorld
|
||||||
std::vector<std::string> mIds;
|
std::vector<std::string> mIds;
|
||||||
float mWaterLevel;
|
float mWaterLevel;
|
||||||
|
|
||||||
|
MWWorld::TimeStamp mLastRespawn;
|
||||||
|
|
||||||
CellRefList<ESM::Activator> mActivators;
|
CellRefList<ESM::Activator> mActivators;
|
||||||
CellRefList<ESM::Potion> mPotions;
|
CellRefList<ESM::Potion> mPotions;
|
||||||
CellRefList<ESM::Apparatus> mAppas;
|
CellRefList<ESM::Apparatus> mAppas;
|
||||||
|
@ -161,6 +165,9 @@ namespace MWWorld
|
||||||
|
|
||||||
void readReferences (ESM::ESMReader& reader, const std::map<int, int>& contentFileMap);
|
void readReferences (ESM::ESMReader& reader, const std::map<int, int>& contentFileMap);
|
||||||
|
|
||||||
|
void respawn ();
|
||||||
|
///< Check mLastRespawn and respawn references if necessary. This is a no-op if the cell is not loaded.
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
CellRefList<T>& get() {
|
CellRefList<T>& get() {
|
||||||
throw std::runtime_error ("Storage for this type not exist in cells");
|
throw std::runtime_error ("Storage for this type not exist in cells");
|
||||||
|
|
|
@ -341,6 +341,8 @@ namespace MWWorld
|
||||||
virtual int getDoorState (const MWWorld::Ptr &ptr) const;
|
virtual int getDoorState (const MWWorld::Ptr &ptr) const;
|
||||||
/// This does not actually cause the door to move. Use World::activateDoor instead.
|
/// This does not actually cause the door to move. Use World::activateDoor instead.
|
||||||
virtual void setDoorState (const MWWorld::Ptr &ptr, int state) const;
|
virtual void setDoorState (const MWWorld::Ptr &ptr, int state) const;
|
||||||
|
|
||||||
|
virtual void respawn (const MWWorld::Ptr& ptr) const {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,6 +165,8 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cell->respawn();
|
||||||
|
|
||||||
// ... then references. This is important for adjustPosition to work correctly.
|
// ... then references. This is important for adjustPosition to work correctly.
|
||||||
/// \todo rescale depending on the state of a new GMST
|
/// \todo rescale depending on the state of a new GMST
|
||||||
insertCell (*cell, true, loadingListener);
|
insertCell (*cell, true, loadingListener);
|
||||||
|
|
|
@ -11,6 +11,10 @@ void ESM::CellState::load (ESMReader &esm)
|
||||||
|
|
||||||
mHasFogOfWar = false;
|
mHasFogOfWar = false;
|
||||||
esm.getHNOT (mHasFogOfWar, "HFOW");
|
esm.getHNOT (mHasFogOfWar, "HFOW");
|
||||||
|
|
||||||
|
mLastRespawn.mDay = 0;
|
||||||
|
mLastRespawn.mHour = 0;
|
||||||
|
esm.getHNOT (mLastRespawn, "RESP");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::CellState::save (ESMWriter &esm) const
|
void ESM::CellState::save (ESMWriter &esm) const
|
||||||
|
@ -18,5 +22,7 @@ void ESM::CellState::save (ESMWriter &esm) const
|
||||||
if (!mId.mPaged)
|
if (!mId.mPaged)
|
||||||
esm.writeHNT ("WLVL", mWaterLevel);
|
esm.writeHNT ("WLVL", mWaterLevel);
|
||||||
|
|
||||||
esm.writeHNT("HFOW", mHasFogOfWar);
|
esm.writeHNT ("HFOW", mHasFogOfWar);
|
||||||
|
|
||||||
|
esm.writeHNT ("RESP", mLastRespawn);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include "cellid.hpp"
|
#include "cellid.hpp"
|
||||||
|
|
||||||
|
#include "defs.hpp"
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
class ESMReader;
|
class ESMReader;
|
||||||
|
@ -19,6 +21,8 @@ namespace ESM
|
||||||
|
|
||||||
int mHasFogOfWar; // Do we have fog of war state (0 or 1)? (see fogstate.hpp)
|
int mHasFogOfWar; // Do we have fog of war state (0 or 1)? (see fogstate.hpp)
|
||||||
|
|
||||||
|
ESM::TimeStamp mLastRespawn;
|
||||||
|
|
||||||
void load (ESMReader &esm);
|
void load (ESMReader &esm);
|
||||||
void save (ESMWriter &esm) const;
|
void save (ESMWriter &esm) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,6 +12,9 @@ namespace ESM
|
||||||
|
|
||||||
mSpawnActorId = -1;
|
mSpawnActorId = -1;
|
||||||
esm.getHNOT (mSpawnActorId, "SPAW");
|
esm.getHNOT (mSpawnActorId, "SPAW");
|
||||||
|
|
||||||
|
mSpawn = false;
|
||||||
|
esm.getHNOT (mSpawn, "RESP");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureLevListState::save(ESMWriter &esm, bool inInventory) const
|
void CreatureLevListState::save(ESMWriter &esm, bool inInventory) const
|
||||||
|
@ -20,6 +23,9 @@ namespace ESM
|
||||||
|
|
||||||
if (mSpawnActorId != -1)
|
if (mSpawnActorId != -1)
|
||||||
esm.writeHNT ("SPAW", mSpawnActorId);
|
esm.writeHNT ("SPAW", mSpawnActorId);
|
||||||
|
|
||||||
|
if (mSpawn)
|
||||||
|
esm.writeHNT ("RESP", mSpawn);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace ESM
|
||||||
struct CreatureLevListState : public ObjectState
|
struct CreatureLevListState : public ObjectState
|
||||||
{
|
{
|
||||||
int mSpawnActorId;
|
int mSpawnActorId;
|
||||||
|
bool mSpawn;
|
||||||
|
|
||||||
virtual void load (ESMReader &esm);
|
virtual void load (ESMReader &esm);
|
||||||
virtual void save (ESMWriter &esm, bool inInventory = false) const;
|
virtual void save (ESMWriter &esm, bool inInventory = false) const;
|
||||||
|
|
Loading…
Reference in a new issue