forked from teamnwah/openmw-tes3coop
Merge remote-tracking branch 'scrawl/respawn'
This commit is contained in:
commit
ebaeabc962
14 changed files with 140 additions and 55 deletions
|
@ -231,15 +231,16 @@ namespace MWBase
|
||||||
|
|
||||||
virtual float getTimeScaleFactor() const = 0;
|
virtual float getTimeScaleFactor() const = 0;
|
||||||
|
|
||||||
virtual void changeToInteriorCell (const std::string& cellName,
|
virtual void changeToInteriorCell (const std::string& cellName, const ESM::Position& position, bool changeEvent=true) = 0;
|
||||||
const ESM::Position& position) = 0;
|
|
||||||
///< Move to interior cell.
|
///< Move to interior cell.
|
||||||
|
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
|
||||||
|
|
||||||
virtual void changeToExteriorCell (const ESM::Position& position) = 0;
|
virtual void changeToExteriorCell (const ESM::Position& position, bool changeEvent=true) = 0;
|
||||||
///< Move to exterior cell.
|
///< Move to exterior cell.
|
||||||
|
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
|
||||||
|
|
||||||
virtual void changeToCell (const ESM::CellId& cellId, const ESM::Position& position, bool detectWorldSpaceChange=true) = 0;
|
virtual void changeToCell (const ESM::CellId& cellId, const ESM::Position& position, bool changeEvent=true) = 0;
|
||||||
///< @param detectWorldSpaceChange if true, clean up worldspace-specific data when the world space changes
|
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
|
||||||
|
|
||||||
virtual const ESM::Cell *getExterior (const std::string& cellName) const = 0;
|
virtual const ESM::Cell *getExterior (const std::string& cellName) const = 0;
|
||||||
///< Return a cell matching the given name or a 0-pointer, if there is no such cell.
|
///< Return a cell matching the given name or a 0-pointer, if there is no such cell.
|
||||||
|
|
|
@ -759,7 +759,18 @@ namespace MWClass
|
||||||
|
|
||||||
void Creature::respawn(const MWWorld::Ptr &ptr) const
|
void Creature::respawn(const MWWorld::Ptr &ptr) const
|
||||||
{
|
{
|
||||||
if (isFlagBitSet(ptr, ESM::Creature::Respawn))
|
const MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr);
|
||||||
|
if (ptr.getRefData().getCount() > 0 && !creatureStats.isDead())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->getFloat();
|
||||||
|
static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->getFloat();
|
||||||
|
|
||||||
|
float delay = ptr.getRefData().getCount() == 0 ? fCorpseClearDelay : std::min(fCorpseRespawnDelay, fCorpseClearDelay);
|
||||||
|
|
||||||
|
if (isFlagBitSet(ptr, ESM::Creature::Respawn)
|
||||||
|
&& creatureStats.getTimeOfDeath() + delay <= MWBase::Environment::get().getWorld()->getTimeStamp())
|
||||||
{
|
{
|
||||||
if (ptr.getCellRef().hasContentFile())
|
if (ptr.getCellRef().hasContentFile())
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,6 +44,27 @@ namespace MWClass
|
||||||
ensureCustomData(ptr);
|
ensureCustomData(ptr);
|
||||||
|
|
||||||
CreatureLevListCustomData& customData = ptr.getRefData().getCustomData()->asCreatureLevListCustomData();
|
CreatureLevListCustomData& customData = ptr.getRefData().getCustomData()->asCreatureLevListCustomData();
|
||||||
|
if (customData.mSpawn)
|
||||||
|
return;
|
||||||
|
|
||||||
|
MWWorld::Ptr creature = (customData.mSpawnActorId == -1) ? MWWorld::Ptr() : MWBase::Environment::get().getWorld()->searchPtrViaActorId(customData.mSpawnActorId);
|
||||||
|
if (!creature.isEmpty())
|
||||||
|
{
|
||||||
|
const MWMechanics::CreatureStats& creatureStats = creature.getClass().getCreatureStats(creature);
|
||||||
|
if (creature.getRefData().getCount() == 0)
|
||||||
|
customData.mSpawn = true;
|
||||||
|
else if (creatureStats.isDead())
|
||||||
|
{
|
||||||
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->getFloat();
|
||||||
|
static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->getFloat();
|
||||||
|
|
||||||
|
float delay = std::min(fCorpseRespawnDelay, fCorpseClearDelay);
|
||||||
|
if (creatureStats.getTimeOfDeath() + delay <= MWBase::Environment::get().getWorld()->getTimeStamp())
|
||||||
|
customData.mSpawn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
customData.mSpawn = true;
|
customData.mSpawn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1292,7 +1292,18 @@ namespace MWClass
|
||||||
|
|
||||||
void Npc::respawn(const MWWorld::Ptr &ptr) const
|
void Npc::respawn(const MWWorld::Ptr &ptr) const
|
||||||
{
|
{
|
||||||
if (ptr.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Respawn)
|
const MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr);
|
||||||
|
if (ptr.getRefData().getCount() > 0 && !creatureStats.isDead())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->getFloat();
|
||||||
|
static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->getFloat();
|
||||||
|
|
||||||
|
float delay = ptr.getRefData().getCount() == 0 ? fCorpseClearDelay : std::min(fCorpseRespawnDelay, fCorpseClearDelay);
|
||||||
|
|
||||||
|
if (ptr.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Respawn
|
||||||
|
&& creatureStats.getTimeOfDeath() + delay <= MWBase::Environment::get().getWorld()->getTimeStamp())
|
||||||
{
|
{
|
||||||
if (ptr.getCellRef().hasContentFile())
|
if (ptr.getCellRef().hasContentFile())
|
||||||
{
|
{
|
||||||
|
|
|
@ -187,6 +187,9 @@ namespace MWMechanics
|
||||||
|
|
||||||
if (index==0 && mDynamic[index].getCurrent()<1)
|
if (index==0 && mDynamic[index].getCurrent()<1)
|
||||||
{
|
{
|
||||||
|
if (!mDead)
|
||||||
|
mTimeOfDeath = MWBase::Environment::get().getWorld()->getTimeStamp();
|
||||||
|
|
||||||
mDead = true;
|
mDead = true;
|
||||||
|
|
||||||
mDynamic[index].setModifier(0);
|
mDynamic[index].setModifier(0);
|
||||||
|
@ -503,6 +506,7 @@ namespace MWMechanics
|
||||||
state.mLevel = mLevel;
|
state.mLevel = mLevel;
|
||||||
state.mActorId = mActorId;
|
state.mActorId = mActorId;
|
||||||
state.mDeathAnimation = mDeathAnimation;
|
state.mDeathAnimation = mDeathAnimation;
|
||||||
|
state.mTimeOfDeath = mTimeOfDeath.toEsm();
|
||||||
|
|
||||||
mSpells.writeState(state.mSpells);
|
mSpells.writeState(state.mSpells);
|
||||||
mActiveSpells.writeState(state.mActiveSpells);
|
mActiveSpells.writeState(state.mActiveSpells);
|
||||||
|
@ -549,6 +553,7 @@ namespace MWMechanics
|
||||||
mLevel = state.mLevel;
|
mLevel = state.mLevel;
|
||||||
mActorId = state.mActorId;
|
mActorId = state.mActorId;
|
||||||
mDeathAnimation = state.mDeathAnimation;
|
mDeathAnimation = state.mDeathAnimation;
|
||||||
|
mTimeOfDeath = MWWorld::TimeStamp(state.mTimeOfDeath);
|
||||||
|
|
||||||
mSpells.readState(state.mSpells);
|
mSpells.readState(state.mSpells);
|
||||||
mActiveSpells.readState(state.mActiveSpells);
|
mActiveSpells.readState(state.mActiveSpells);
|
||||||
|
@ -622,6 +627,11 @@ namespace MWMechanics
|
||||||
mDeathAnimation = index;
|
mDeathAnimation = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWWorld::TimeStamp CreatureStats::getTimeOfDeath() const
|
||||||
|
{
|
||||||
|
return mTimeOfDeath;
|
||||||
|
}
|
||||||
|
|
||||||
std::map<CreatureStats::SummonKey, int>& CreatureStats::getSummonedCreatureMap()
|
std::map<CreatureStats::SummonKey, int>& CreatureStats::getSummonedCreatureMap()
|
||||||
{
|
{
|
||||||
return mSummonedCreatures;
|
return mSummonedCreatures;
|
||||||
|
|
|
@ -65,6 +65,8 @@ namespace MWMechanics
|
||||||
// The index of the death animation that was played
|
// The index of the death animation that was played
|
||||||
unsigned char mDeathAnimation;
|
unsigned char mDeathAnimation;
|
||||||
|
|
||||||
|
MWWorld::TimeStamp mTimeOfDeath;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef std::pair<int, std::string> SummonKey; // <ESM::MagicEffect index, spell ID>
|
typedef std::pair<int, std::string> SummonKey; // <ESM::MagicEffect index, spell ID>
|
||||||
private:
|
private:
|
||||||
|
@ -259,6 +261,8 @@ namespace MWMechanics
|
||||||
unsigned char getDeathAnimation() const;
|
unsigned char getDeathAnimation() const;
|
||||||
void setDeathAnimation(unsigned char index);
|
void setDeathAnimation(unsigned char index);
|
||||||
|
|
||||||
|
MWWorld::TimeStamp getTimeOfDeath() const;
|
||||||
|
|
||||||
int getActorId();
|
int getActorId();
|
||||||
///< Will generate an actor ID, if the actor does not have one yet.
|
///< Will generate an actor ID, if the actor does not have one yet.
|
||||||
|
|
||||||
|
|
|
@ -493,7 +493,8 @@ void MWState::StateManager::loadGame (const Character *character, const std::str
|
||||||
// but some mods may be using it as a reload detector.
|
// but some mods may be using it as a reload detector.
|
||||||
MWBase::Environment::get().getScriptManager()->getGlobalScripts().addStartup();
|
MWBase::Environment::get().getScriptManager()->getGlobalScripts().addStartup();
|
||||||
|
|
||||||
// Do not trigger erroneous cellChanged events
|
// Since we passed "changeEvent=false" to changeCell, we shouldn't have triggered the cell change flag.
|
||||||
|
// But make sure the flag is cleared anyway in case it was set from an earlier game.
|
||||||
MWBase::Environment::get().getWorld()->markCellAsUnchanged();
|
MWBase::Environment::get().getWorld()->markCellAsUnchanged();
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
|
|
|
@ -889,11 +889,19 @@ namespace MWWorld
|
||||||
return mFogState.get();
|
return mFogState.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clearCorpse(const MWWorld::Ptr& ptr)
|
||||||
|
{
|
||||||
|
const MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr);
|
||||||
|
static const float fCorpseClearDelay = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fCorpseClearDelay")->getFloat();
|
||||||
|
if (!ptr.getClass().isPersistent(ptr) && creatureStats.getTimeOfDeath() + fCorpseClearDelay <= MWBase::Environment::get().getWorld()->getTimeStamp())
|
||||||
|
MWBase::Environment::get().getWorld()->deleteObject(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
void CellStore::respawn()
|
void CellStore::respawn()
|
||||||
{
|
{
|
||||||
if (mState == State_Loaded)
|
if (mState == State_Loaded)
|
||||||
{
|
{
|
||||||
static int iMonthsToRespawn = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("iMonthsToRespawn")->getInt();
|
static const int iMonthsToRespawn = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("iMonthsToRespawn")->getInt();
|
||||||
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();
|
||||||
|
@ -902,22 +910,26 @@ namespace MWWorld
|
||||||
Ptr ptr (&*it, this);
|
Ptr ptr (&*it, this);
|
||||||
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 (mCreatures.mList.begin()); it!=mCreatures.mList.end(); ++it)
|
||||||
{
|
{
|
||||||
Ptr ptr (&*it, this);
|
Ptr ptr (&*it, this);
|
||||||
|
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 (mNpcs.mList.begin()); it!=mNpcs.mList.end(); ++it)
|
||||||
{
|
{
|
||||||
Ptr ptr (&*it, this);
|
Ptr ptr (&*it, this);
|
||||||
|
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 (mCreatureLists.mList.begin()); it!=mCreatureLists.mList.end(); ++it)
|
||||||
{
|
{
|
||||||
Ptr ptr (&*it, this);
|
Ptr ptr (&*it, this);
|
||||||
|
// no need to clearCorpse, handled as part of mCreatures
|
||||||
ptr.getClass().respawn(ptr);
|
ptr.getClass().respawn(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -240,7 +240,7 @@ namespace MWWorld
|
||||||
mActiveCells.erase(*iter);
|
mActiveCells.erase(*iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::loadCell (CellStore *cell, Loading::Listener* loadingListener)
|
void Scene::loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn)
|
||||||
{
|
{
|
||||||
std::pair<CellStoreCollection::iterator, bool> result = mActiveCells.insert(cell);
|
std::pair<CellStoreCollection::iterator, bool> result = mActiveCells.insert(cell);
|
||||||
|
|
||||||
|
@ -270,12 +270,13 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cell->respawn();
|
|
||||||
|
|
||||||
// register local scripts
|
// register local scripts
|
||||||
// do this before insertCell, to make sure we don't add scripts from levelled creature spawning twice
|
// do this before insertCell, to make sure we don't add scripts from levelled creature spawning twice
|
||||||
MWBase::Environment::get().getWorld()->getLocalScripts().addCell (cell);
|
MWBase::Environment::get().getWorld()->getLocalScripts().addCell (cell);
|
||||||
|
|
||||||
|
if (respawn)
|
||||||
|
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);
|
||||||
|
@ -329,7 +330,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::changeCellGrid (int X, int Y)
|
void Scene::changeCellGrid (int X, int Y, bool changeEvent)
|
||||||
{
|
{
|
||||||
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
|
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
|
||||||
Loading::ScopedLoad load(loadingListener);
|
Loading::ScopedLoad load(loadingListener);
|
||||||
|
@ -403,7 +404,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(x, y);
|
CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(x, y);
|
||||||
|
|
||||||
loadCell (cell, loadingListener);
|
loadCell (cell, loadingListener, changeEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -411,6 +412,7 @@ namespace MWWorld
|
||||||
CellStore* current = MWBase::Environment::get().getWorld()->getExterior(X,Y);
|
CellStore* current = MWBase::Environment::get().getWorld()->getExterior(X,Y);
|
||||||
MWBase::Environment::get().getWindowManager()->changeCell(current);
|
MWBase::Environment::get().getWindowManager()->changeCell(current);
|
||||||
|
|
||||||
|
if (changeEvent)
|
||||||
mCellChanged = true;
|
mCellChanged = true;
|
||||||
|
|
||||||
mPreloader->updateCache(mRendering.getReferenceTime());
|
mPreloader->updateCache(mRendering.getReferenceTime());
|
||||||
|
@ -484,7 +486,7 @@ namespace MWWorld
|
||||||
return mActiveCells;
|
return mActiveCells;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
|
void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position, bool changeEvent)
|
||||||
{
|
{
|
||||||
CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(cellName);
|
CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(cellName);
|
||||||
bool loadcell = (mCurrentCell == NULL);
|
bool loadcell = (mCurrentCell == NULL);
|
||||||
|
@ -530,7 +532,7 @@ namespace MWWorld
|
||||||
loadingListener->setProgressRange(refsToLoad);
|
loadingListener->setProgressRange(refsToLoad);
|
||||||
|
|
||||||
// Load cell.
|
// Load cell.
|
||||||
loadCell (cell, loadingListener);
|
loadCell (cell, loadingListener, changeEvent);
|
||||||
|
|
||||||
changePlayerCell(cell, position, true);
|
changePlayerCell(cell, position, true);
|
||||||
|
|
||||||
|
@ -540,21 +542,24 @@ namespace MWWorld
|
||||||
// Sky system
|
// Sky system
|
||||||
MWBase::Environment::get().getWorld()->adjustSky();
|
MWBase::Environment::get().getWorld()->adjustSky();
|
||||||
|
|
||||||
mCellChanged = true; MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.5);
|
if (changeEvent)
|
||||||
|
mCellChanged = true;
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.5);
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
|
MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
|
||||||
|
|
||||||
mPreloader->updateCache(mRendering.getReferenceTime());
|
mPreloader->updateCache(mRendering.getReferenceTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos)
|
void Scene::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
|
||||||
{
|
{
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
|
|
||||||
MWBase::Environment::get().getWorld()->positionToIndex (position.pos[0], position.pos[1], x, y);
|
MWBase::Environment::get().getWorld()->positionToIndex (position.pos[0], position.pos[1], x, y);
|
||||||
|
|
||||||
changeCellGrid(x, y);
|
changeCellGrid(x, y, changeEvent);
|
||||||
|
|
||||||
CellStore* current = MWBase::Environment::get().getWorld()->getExterior(x, y);
|
CellStore* current = MWBase::Environment::get().getWorld()->getExterior(x, y);
|
||||||
changePlayerCell(current, position, adjustPlayerPos);
|
changePlayerCell(current, position, adjustPlayerPos);
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace MWWorld
|
||||||
void insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener);
|
void insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener);
|
||||||
|
|
||||||
// Load and unload cells as necessary to create a cell grid with "X" and "Y" in the center
|
// Load and unload cells as necessary to create a cell grid with "X" and "Y" in the center
|
||||||
void changeCellGrid (int X, int Y);
|
void changeCellGrid (int X, int Y, bool changeEvent = true);
|
||||||
|
|
||||||
void getGridCenter(int& cellX, int& cellY);
|
void getGridCenter(int& cellX, int& cellY);
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ namespace MWWorld
|
||||||
|
|
||||||
void unloadCell (CellStoreCollection::iterator iter);
|
void unloadCell (CellStoreCollection::iterator iter);
|
||||||
|
|
||||||
void loadCell (CellStore *cell, Loading::Listener* loadingListener);
|
void loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn);
|
||||||
|
|
||||||
void playerMoved (const osg::Vec3f& pos);
|
void playerMoved (const osg::Vec3f& pos);
|
||||||
|
|
||||||
|
@ -103,11 +103,13 @@ namespace MWWorld
|
||||||
bool hasCellChanged() const;
|
bool hasCellChanged() const;
|
||||||
///< Has the set of active cells changed, since the last frame?
|
///< Has the set of active cells changed, since the last frame?
|
||||||
|
|
||||||
void changeToInteriorCell (const std::string& cellName, const ESM::Position& position);
|
void changeToInteriorCell (const std::string& cellName, const ESM::Position& position, bool changeEvent=true);
|
||||||
///< Move to interior cell.
|
///< Move to interior cell.
|
||||||
|
/// @param changeEvent Set cellChanged flag?
|
||||||
|
|
||||||
void changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos);
|
void changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos, bool changeEvent=true);
|
||||||
///< Move to exterior cell.
|
///< Move to exterior cell.
|
||||||
|
/// @param changeEvent Set cellChanged flag?
|
||||||
|
|
||||||
void changeToVoid();
|
void changeToVoid();
|
||||||
///< Change into a void
|
///< Change into a void
|
||||||
|
|
|
@ -962,11 +962,11 @@ namespace MWWorld
|
||||||
return mTimeScale->getFloat();
|
return mTimeScale->getFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
|
void World::changeToInteriorCell (const std::string& cellName, const ESM::Position& position, bool changeEvent)
|
||||||
{
|
{
|
||||||
mPhysics->clearQueuedMovement();
|
mPhysics->clearQueuedMovement();
|
||||||
|
|
||||||
if (mCurrentWorldSpace != cellName)
|
if (changeEvent && mCurrentWorldSpace != cellName)
|
||||||
{
|
{
|
||||||
// changed worldspace
|
// changed worldspace
|
||||||
mProjectileManager->clear();
|
mProjectileManager->clear();
|
||||||
|
@ -976,34 +976,34 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
removeContainerScripts(getPlayerPtr());
|
removeContainerScripts(getPlayerPtr());
|
||||||
mWorldScene->changeToInteriorCell(cellName, position);
|
mWorldScene->changeToInteriorCell(cellName, position, changeEvent);
|
||||||
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
|
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::changeToExteriorCell (const ESM::Position& position)
|
void World::changeToExteriorCell (const ESM::Position& position, bool changeEvent)
|
||||||
{
|
{
|
||||||
mPhysics->clearQueuedMovement();
|
mPhysics->clearQueuedMovement();
|
||||||
|
|
||||||
if (mCurrentWorldSpace != "sys::default") // FIXME
|
if (changeEvent && mCurrentWorldSpace != "sys::default") // FIXME
|
||||||
{
|
{
|
||||||
// changed worldspace
|
// changed worldspace
|
||||||
mProjectileManager->clear();
|
mProjectileManager->clear();
|
||||||
mRendering->notifyWorldSpaceChanged();
|
mRendering->notifyWorldSpaceChanged();
|
||||||
}
|
}
|
||||||
removeContainerScripts(getPlayerPtr());
|
removeContainerScripts(getPlayerPtr());
|
||||||
mWorldScene->changeToExteriorCell(position, true);
|
mWorldScene->changeToExteriorCell(position, true, changeEvent);
|
||||||
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
|
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::changeToCell (const ESM::CellId& cellId, const ESM::Position& position, bool detectWorldSpaceChange)
|
void World::changeToCell (const ESM::CellId& cellId, const ESM::Position& position, bool changeEvent)
|
||||||
{
|
{
|
||||||
if (!detectWorldSpaceChange)
|
if (!changeEvent)
|
||||||
mCurrentWorldSpace = cellId.mWorldspace;
|
mCurrentWorldSpace = cellId.mWorldspace;
|
||||||
|
|
||||||
if (cellId.mPaged)
|
if (cellId.mPaged)
|
||||||
changeToExteriorCell (position);
|
changeToExteriorCell (position, changeEvent);
|
||||||
else
|
else
|
||||||
changeToInteriorCell (cellId.mWorldspace, position);
|
changeToInteriorCell (cellId.mWorldspace, position, changeEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::markCellAsUnchanged()
|
void World::markCellAsUnchanged()
|
||||||
|
|
|
@ -324,15 +324,16 @@ namespace MWWorld
|
||||||
|
|
||||||
virtual float getTimeScaleFactor() const;
|
virtual float getTimeScaleFactor() const;
|
||||||
|
|
||||||
virtual void changeToInteriorCell (const std::string& cellName,
|
virtual void changeToInteriorCell (const std::string& cellName, const ESM::Position& position, bool changeEvent = true);
|
||||||
const ESM::Position& position);
|
|
||||||
///< Move to interior cell.
|
///< Move to interior cell.
|
||||||
|
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
|
||||||
|
|
||||||
virtual void changeToExteriorCell (const ESM::Position& position);
|
virtual void changeToExteriorCell (const ESM::Position& position, bool changeEvent = true);
|
||||||
///< Move to exterior cell.
|
///< Move to exterior cell.
|
||||||
|
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
|
||||||
|
|
||||||
virtual void changeToCell (const ESM::CellId& cellId, const ESM::Position& position, bool detectWorldSpaceChange=true);
|
virtual void changeToCell (const ESM::CellId& cellId, const ESM::Position& position, bool changeEvent=true);
|
||||||
///< @param detectWorldSpaceChange if true, clean up worldspace-specific data when the world space changes
|
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
|
||||||
|
|
||||||
virtual const ESM::Cell *getExterior (const std::string& cellName) const;
|
virtual const ESM::Cell *getExterior (const std::string& cellName) const;
|
||||||
///< Return a cell matching the given name or a 0-pointer, if there is no such cell.
|
///< Return a cell matching the given name or a 0-pointer, if there is no such cell.
|
||||||
|
|
|
@ -87,6 +87,8 @@ void ESM::CreatureStats::load (ESMReader &esm)
|
||||||
mDeathAnimation = 0;
|
mDeathAnimation = 0;
|
||||||
esm.getHNOT (mDeathAnimation, "DANM");
|
esm.getHNOT (mDeathAnimation, "DANM");
|
||||||
|
|
||||||
|
esm.getHNOT (mTimeOfDeath, "DTIM");
|
||||||
|
|
||||||
mSpells.load(esm);
|
mSpells.load(esm);
|
||||||
mActiveSpells.load(esm);
|
mActiveSpells.load(esm);
|
||||||
mAiSequence.load(esm);
|
mAiSequence.load(esm);
|
||||||
|
@ -193,6 +195,9 @@ void ESM::CreatureStats::save (ESMWriter &esm) const
|
||||||
if (mDeathAnimation)
|
if (mDeathAnimation)
|
||||||
esm.writeHNT ("DANM", mDeathAnimation);
|
esm.writeHNT ("DANM", mDeathAnimation);
|
||||||
|
|
||||||
|
if (mTimeOfDeath.mHour != 0 && mTimeOfDeath.mDay != 0)
|
||||||
|
esm.writeHNT ("DTIM", mTimeOfDeath);
|
||||||
|
|
||||||
mSpells.save(esm);
|
mSpells.save(esm);
|
||||||
mActiveSpells.save(esm);
|
mActiveSpells.save(esm);
|
||||||
mAiSequence.save(esm);
|
mAiSequence.save(esm);
|
||||||
|
|
|
@ -57,6 +57,7 @@ namespace ESM
|
||||||
bool mRecalcDynamicStats;
|
bool mRecalcDynamicStats;
|
||||||
int mDrawState;
|
int mDrawState;
|
||||||
unsigned char mDeathAnimation;
|
unsigned char mDeathAnimation;
|
||||||
|
ESM::TimeStamp mTimeOfDeath;
|
||||||
|
|
||||||
int mLevel;
|
int mLevel;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue