Use a separate flag for references deleted by a content file (Fixes #2018)

The flag must be separate so as to not contaminate the user's savegame.

Fixes the following use cases that were broken before:

 - Content file edits a reference that was already deleted by a previously loaded content file -> reference must stay deleted
 - Changed or new content file deletes a reference that is already present in the user's savegame -> reference must be deleted
 - Said content file is disabled again - reference must be undeleted
report
scrawl 10 years ago
parent 4c1906b999
commit 48d5789aeb

@ -156,7 +156,7 @@ namespace MWWorld
LiveRef liveCellRef (ref, ptr); LiveRef liveCellRef (ref, ptr);
if (deleted) if (deleted)
liveCellRef.mData.setCount (0); liveCellRef.mData.setDeleted(true);
if (iter != mList.end()) if (iter != mList.end())
*iter = liveCellRef; *iter = liveCellRef;

@ -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.getCount()) if (iter->mData.isDeleted())
continue; continue;
if (!functor (MWWorld::Ptr(&*iter, this))) if (!functor (MWWorld::Ptr(&*iter, this)))
return false; return false;

@ -17,7 +17,7 @@ namespace
cellRefList.mList.begin()); cellRefList.mList.begin());
iter!=cellRefList.mList.end(); ++iter) iter!=cellRefList.mList.end(); ++iter)
{ {
if (!iter->mBase->mScript.empty() && iter->mData.getCount()) if (!iter->mBase->mScript.empty() && !iter->mData.isDeleted())
{ {
localScripts.add (iter->mBase->mScript, MWWorld::Ptr (&*iter, cell)); localScripts.add (iter->mBase->mScript, MWWorld::Ptr (&*iter, cell));
} }

@ -23,6 +23,7 @@ namespace MWWorld
mPosition = refData.mPosition; mPosition = refData.mPosition;
mLocalRotation = refData.mLocalRotation; mLocalRotation = refData.mLocalRotation;
mChanged = refData.mChanged; mChanged = refData.mChanged;
mDeleted = refData.mDeleted;
mCustomData = refData.mCustomData ? refData.mCustomData->clone() : 0; mCustomData = refData.mCustomData ? refData.mCustomData->clone() : 0;
} }
@ -36,7 +37,7 @@ namespace MWWorld
} }
RefData::RefData() RefData::RefData()
: mBaseNode(0), mHasLocals (false), mEnabled (true), mCount (1), mCustomData (0), mChanged(false) : mBaseNode(0), mHasLocals (false), mEnabled (true), mCount (1), mCustomData (0), mChanged(false), mDeleted(false)
{ {
for (int i=0; i<3; ++i) for (int i=0; i<3; ++i)
{ {
@ -49,7 +50,8 @@ namespace MWWorld
RefData::RefData (const ESM::CellRef& cellRef) RefData::RefData (const ESM::CellRef& cellRef)
: mBaseNode(0), mHasLocals (false), mEnabled (true), mCount (1), mPosition (cellRef.mPos), : mBaseNode(0), mHasLocals (false), mEnabled (true), mCount (1), mPosition (cellRef.mPos),
mCustomData (0), mCustomData (0),
mChanged(false) // Loading from ESM/ESP files -> assume unchanged mChanged(false), // Loading from ESM/ESP files -> assume unchanged
mDeleted(false)
{ {
mLocalRotation.rot[0]=0; mLocalRotation.rot[0]=0;
mLocalRotation.rot[1]=0; mLocalRotation.rot[1]=0;
@ -59,7 +61,8 @@ namespace MWWorld
RefData::RefData (const ESM::ObjectState& objectState) RefData::RefData (const ESM::ObjectState& objectState)
: mBaseNode (0), mHasLocals (false), mEnabled (objectState.mEnabled), : mBaseNode (0), mHasLocals (false), mEnabled (objectState.mEnabled),
mCount (objectState.mCount), mPosition (objectState.mPosition), mCustomData (0), mCount (objectState.mCount), mPosition (objectState.mPosition), mCustomData (0),
mChanged(true) // Loading from a savegame -> assume changed mChanged(true), // Loading from a savegame -> assume changed
mDeleted(false)
{ {
for (int i=0; i<3; ++i) for (int i=0; i<3; ++i)
mLocalRotation.rot[i] = objectState.mLocalRotation[i]; mLocalRotation.rot[i] = objectState.mLocalRotation[i];
@ -167,6 +170,16 @@ namespace MWWorld
mCount = count; mCount = count;
} }
void RefData::setDeleted(bool deleted)
{
mDeleted = deleted;
}
bool RefData::isDeleted() const
{
return mDeleted || mCount == 0;
}
MWScript::Locals& RefData::getLocals() MWScript::Locals& RefData::getLocals()
{ {
return mLocals; return mLocals;

@ -37,6 +37,8 @@ namespace MWWorld
bool mEnabled; bool mEnabled;
int mCount; // 0: deleted int mCount; // 0: deleted
bool mDeleted; // separate delete flag used for deletion by a content file
ESM::Position mPosition; ESM::Position mPosition;
LocalRotation mLocalRotation; LocalRotation mLocalRotation;
@ -86,12 +88,19 @@ namespace MWWorld
void setLocals (const ESM::Script& script); void setLocals (const ESM::Script& script);
void setCount (int count); void setCount (int count);
/// Set object count (an object pile is a simple object with a count >1). ///< Set object count (an object pile is a simple object with a count >1).
/// ///
/// \warning Do not call setCount() to add or remove objects from a /// \warning Do not call setCount() to add or remove objects from a
/// container or an actor's inventory. Call ContainerStore::add() or /// container or an actor's inventory. Call ContainerStore::add() or
/// ContainerStore::remove() instead. /// ContainerStore::remove() instead.
/// This flag is only used for content stack loading and will not be stored in the savegame.
/// If the object was deleted by gameplay, then use setCount(0) instead.
void setDeleted(bool deleted);
/// Returns true if the object was either deleted by the content file or by gameplay.
bool isDeleted() const;
MWScript::Locals& getLocals(); MWScript::Locals& getLocals();
bool isEnabled() const; bool isEnabled() const;

@ -75,7 +75,7 @@ namespace
ptr.getCellRef().setScale(2); ptr.getCellRef().setScale(2);
} }
if (ptr.getRefData().getCount() && ptr.getRefData().isEnabled()) if (!ptr.getRefData().isDeleted() && ptr.getRefData().isEnabled())
{ {
try try
{ {

@ -1057,7 +1057,7 @@ namespace MWWorld
void World::deleteObject (const Ptr& ptr) void World::deleteObject (const Ptr& ptr)
{ {
if (ptr.getRefData().getCount() > 0) if (!ptr.getRefData().isDeleted())
{ {
ptr.getRefData().setCount(0); ptr.getRefData().setCount(0);

Loading…
Cancel
Save