Properly handle moved references in respawning code (Fixes #3600)

coverity_scan^2
scrawl 8 years ago
parent 77bc807305
commit a7d4928593

@ -204,6 +204,14 @@ namespace MWWorld
return (ref.mRef.mRefnum == pRefnum); return (ref.mRef.mRefnum == pRefnum);
} }
Ptr CellStore::getCurrentPtr(LiveCellRefBase *ref)
{
MovedRefTracker::iterator found = mMovedToAnotherCell.find(ref);
if (found != mMovedToAnotherCell.end())
return Ptr(ref, found->second);
return Ptr(ref, this);
}
void CellStore::moveFrom(const Ptr &object, CellStore *from) void CellStore::moveFrom(const Ptr &object, CellStore *from)
{ {
if (mState != State_Loaded) if (mState != State_Loaded)
@ -964,26 +972,26 @@ namespace MWWorld
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 (mContainers.mList.begin()); it!=mContainers.mList.end(); ++it)
{ {
Ptr ptr (&*it, this); 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 (mCreatures.mList.begin()); it!=mCreatures.mList.end(); ++it)
{ {
Ptr ptr (&*it, this); 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 (mNpcs.mList.begin()); it!=mNpcs.mList.end(); ++it)
{ {
Ptr ptr (&*it, this); 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 (mCreatureLists.mList.begin()); it!=mCreatureLists.mList.end(); ++it)
{ {
Ptr ptr (&*it, this); Ptr ptr = getCurrentPtr(&*it);
// no need to clearCorpse, handled as part of mCreatures // no need to clearCorpse, handled as part of mCreatures
ptr.getClass().respawn(ptr); ptr.getClass().respawn(ptr);
} }

@ -111,6 +111,9 @@ namespace MWWorld
// Merged list of ref's currently in this cell - i.e. with added refs from mMovedHere, removed refs from mMovedToAnotherCell // Merged list of ref's currently in this cell - i.e. with added refs from mMovedHere, removed refs from mMovedToAnotherCell
std::vector<LiveCellRefBase*> mMergedRefs; std::vector<LiveCellRefBase*> mMergedRefs;
// Get the Ptr for the given ref which originated from this cell (possibly moved to another cell at this point).
Ptr getCurrentPtr(MWWorld::LiveCellRefBase* ref);
/// Moves object from the given cell to this cell. /// Moves object from the given cell to this cell.
void moveFrom(const MWWorld::Ptr& object, MWWorld::CellStore* from); void moveFrom(const MWWorld::Ptr& object, MWWorld::CellStore* from);

Loading…
Cancel
Save