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);
if (deleted)
liveCellRef.mData.setCount (0);
liveCellRef.mData.setDeleted(true);
if (iter != mList.end())
*iter = liveCellRef;

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

@ -17,7 +17,7 @@ namespace
cellRefList.mList.begin());
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));
}

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

@ -37,6 +37,8 @@ namespace MWWorld
bool mEnabled;
int mCount; // 0: deleted
bool mDeleted; // separate delete flag used for deletion by a content file
ESM::Position mPosition;
LocalRotation mLocalRotation;
@ -86,12 +88,19 @@ namespace MWWorld
void setLocals (const ESM::Script& script);
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
/// container or an actor's inventory. Call ContainerStore::add() or
/// 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();
bool isEnabled() const;

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

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

Loading…
Cancel
Save