Add support for undeleting references (Fixes #2193)

Deleted references should be accessible via an explicit reference, and can be undeleted using "setdelete 0". Also the Resurrect function implicitely undeletes the given reference.
moveref
scrawl 10 years ago
parent 2952a0e2aa
commit f49fde3d5d

@ -279,6 +279,7 @@ namespace MWBase
///< Attempt to fix position so that the Ptr is no longer inside collision geometry. ///< Attempt to fix position so that the Ptr is no longer inside collision geometry.
virtual void deleteObject (const MWWorld::Ptr& ptr) = 0; virtual void deleteObject (const MWWorld::Ptr& ptr) = 0;
virtual void undeleteObject (const MWWorld::Ptr& ptr) = 0;
virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0; virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;

@ -571,6 +571,10 @@ namespace MWScript
if (parameter == 1) if (parameter == 1)
MWBase::Environment::get().getWorld()->deleteObject(ptr); MWBase::Environment::get().getWorld()->deleteObject(ptr);
else if (parameter == 0)
MWBase::Environment::get().getWorld()->undeleteObject(ptr);
else
throw std::runtime_error("SetDelete: unexpected parameter");
} }
}; };

@ -1184,6 +1184,7 @@ namespace MWScript
ptr.getClass().getCreatureStats(ptr).resurrect(); ptr.getClass().getCreatureStats(ptr).resurrect();
else if (ptr.getClass().getCreatureStats(ptr).isDead()) else if (ptr.getClass().getCreatureStats(ptr).isDead())
{ {
MWBase::Environment::get().getWorld()->undeleteObject(ptr);
// resets runtime state such as inventory, stats and AI. does not reset position in the world // resets runtime state such as inventory, stats and AI. does not reset position in the world
ptr.getRefData().setCustomData(NULL); ptr.getRefData().setCustomData(NULL);
} }

@ -27,7 +27,7 @@ namespace MWWorld
LiveRef *find (const std::string& name) LiveRef *find (const std::string& name)
{ {
for (typename List::iterator iter (mList.begin()); iter!=mList.end(); ++iter) for (typename List::iterator iter (mList.begin()); iter!=mList.end(); ++iter)
if (iter->mData.getCount() > 0 && iter->mRef.getRefId() == name) if (iter->mRef.getRefId() == name)
return &*iter; return &*iter;
return 0; return 0;
@ -42,7 +42,7 @@ namespace MWWorld
LiveCellRef<X> *searchViaHandle (const std::string& handle) LiveCellRef<X> *searchViaHandle (const std::string& handle)
{ {
for (typename List::iterator iter (mList.begin()); iter!=mList.end(); ++iter) for (typename List::iterator iter (mList.begin()); iter!=mList.end(); ++iter)
if (iter->mData.getCount()>0 && iter->mData.getBaseNode() && if (iter->mData.getBaseNode() &&
iter->mData.getHandle()==handle) iter->mData.getHandle()==handle)
return &*iter; return &*iter;

@ -196,7 +196,7 @@ namespace MWWorld
for (typename List::List::iterator iter (list.mList.begin()); iter!=list.mList.end(); for (typename List::List::iterator iter (list.mList.begin()); iter!=list.mList.end();
++iter) ++iter)
{ {
if (iter->mData.isDeleted()) if (iter->mData.isDeletedByContentFile())
continue; continue;
if (!functor (MWWorld::Ptr(&*iter, this))) if (!functor (MWWorld::Ptr(&*iter, this)))
return false; return false;

@ -180,6 +180,11 @@ namespace MWWorld
return mDeleted || mCount == 0; return mDeleted || mCount == 0;
} }
bool RefData::isDeletedByContentFile() const
{
return mDeleted;
}
MWScript::Locals& RefData::getLocals() MWScript::Locals& RefData::getLocals()
{ {
return mLocals; return mLocals;

@ -100,6 +100,8 @@ namespace MWWorld
/// Returns true if the object was either deleted by the content file or by gameplay. /// Returns true if the object was either deleted by the content file or by gameplay.
bool isDeleted() const; bool isDeleted() const;
/// Returns true if the object was deleted by a content file.
bool isDeletedByContentFile() const;
MWScript::Locals& getLocals(); MWScript::Locals& getLocals();

@ -1072,6 +1072,25 @@ namespace MWWorld
} }
} }
void World::undeleteObject(const Ptr& ptr)
{
if (ptr.getCellRef().getRefNum().mContentFile == -1)
return;
if (ptr.getRefData().isDeleted())
{
ptr.getRefData().setCount(1);
if (mWorldScene->getActiveCells().find(ptr.getCell()) != mWorldScene->getActiveCells().end()
&& ptr.getRefData().isEnabled())
{
mWorldScene->addObjectToScene(ptr);
std::string script = ptr.getClass().getScript(ptr);
if (!script.empty())
mLocalScripts.add(script, ptr);
addContainerScripts(ptr, ptr.getCell());
}
}
}
void World::moveObject(const Ptr &ptr, CellStore* newCell, float x, float y, float z) void World::moveObject(const Ptr &ptr, CellStore* newCell, float x, float y, float z)
{ {
ESM::Position pos = ptr.getRefData().getPosition(); ESM::Position pos = ptr.getRefData().getPosition();

@ -338,6 +338,7 @@ namespace MWWorld
virtual std::pair<MWWorld::Ptr,Ogre::Vector3> getHitContact(const MWWorld::Ptr &ptr, float distance); virtual std::pair<MWWorld::Ptr,Ogre::Vector3> getHitContact(const MWWorld::Ptr &ptr, float distance);
virtual void deleteObject (const Ptr& ptr); virtual void deleteObject (const Ptr& ptr);
virtual void undeleteObject (const Ptr& ptr);
virtual void moveObject (const Ptr& ptr, float x, float y, float z); virtual void moveObject (const Ptr& ptr, float x, float y, float z);
virtual void moveObject (const Ptr& ptr, CellStore* newCell, float x, float y, float z); virtual void moveObject (const Ptr& ptr, CellStore* newCell, float x, float y, float z);

Loading…
Cancel
Save