From bd6254b6dff5feb0196e08a5638d776577cb8d4e Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Thu, 17 Jul 2025 08:22:26 +0200 Subject: [PATCH] Ensure corpses of actors that have moved cells are cleaned up --- apps/openmw/mwworld/cellstore.cpp | 42 +++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index 61618c001e..75ee14f627 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -1263,26 +1263,48 @@ namespace MWWorld } } - for (CellRefList::List::iterator it(get().mList.begin()); - it != get().mList.end(); ++it) + // Actors need to respawn here even if they've been moved to another cell + for (LiveCellRefBase& base : get().mList) { - Ptr ptr = getCurrentPtr(&*it); + Ptr ptr = getCurrentPtr(&base); clearCorpse(ptr, mStore); ptr.getClass().respawn(ptr); } - for (CellRefList::List::iterator it(get().mList.begin()); - it != get().mList.end(); ++it) + for (LiveCellRefBase& base : get().mList) { - Ptr ptr = getCurrentPtr(&*it); + Ptr ptr = getCurrentPtr(&base); clearCorpse(ptr, mStore); ptr.getClass().respawn(ptr); } - forEachType([](Ptr ptr) { - // no need to clearCorpse, handled as part of get() + for (LiveCellRefBase& base : get().mList) + { + Ptr ptr = getCurrentPtr(&base); if (!ptr.mRef->isDeleted()) ptr.getClass().respawn(ptr); - return true; - }); + } + for (const auto& [base, _] : mMovedHere) + { + switch (base->getType()) + { + case ESM::Creature::sRecordId: + case ESM::NPC::sRecordId: + case ESM::CreatureLevList::sRecordId: + { + MWWorld::Ptr ptr(base, this); + if (ptr.mRef->isDeleted()) + continue; + // Remove actors that have been dead a while, but don't belong here and didn't get hit by the + // logic above + if (ptr.getClass().isActor()) + clearCorpse(ptr, mStore); + else // Respawn lists in their new position + ptr.getClass().respawn(ptr); + break; + } + default: + break; + } + } } }