1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-28 14:53:58 +00:00

Fix cell overrides and remove unused, incomplete erase method

This commit is contained in:
Evil Eye 2023-05-05 16:39:24 +02:00
parent cdc753df70
commit 2a48642fe3
2 changed files with 32 additions and 107 deletions

View File

@ -646,96 +646,71 @@ namespace MWWorld
// All cells have a name record, even nameless exterior cells. // All cells have a name record, even nameless exterior cells.
ESM::Cell* emplacedCell = nullptr; ESM::Cell* emplacedCell = nullptr;
bool isDeleted = false; bool isDeleted = false;
bool newCell = false;
{ {
ESM::Cell cellToLoad; ESM::Cell cellToLoad;
cellToLoad.loadNameAndData(esm, isDeleted); cellToLoad.loadNameAndData(esm, isDeleted);
emplacedCell = &mCells.insert(std::make_pair(cellToLoad.mId, cellToLoad)).first->second; auto [it, inserted] = mCells.insert(std::make_pair(cellToLoad.mId, cellToLoad));
emplacedCell = &it->second;
if (!inserted)
{
emplacedCell->mData = cellToLoad.mData;
emplacedCell->mName = cellToLoad.mName;
}
newCell = inserted;
} }
ESM::Cell& cell = *emplacedCell; ESM::Cell& cell = *emplacedCell;
// Load the (x,y) coordinates of the cell, if it is an exterior cell, // Load the (x,y) coordinates of the cell, if it is an exterior cell,
// so we can find the cell we need to merge with // so we can find the cell we need to merge with
if (cell.mData.mFlags & ESM::Cell::Interior) if (cell.mData.mFlags & ESM::Cell::Interior)
{ {
// Store interior cell by name, try to merge with existing parent data. cell.loadCell(esm, true);
ESM::Cell* oldcell = const_cast<ESM::Cell*>(search(cell.mName)); if (newCell)
if (oldcell)
{
// merge new cell into old cell
// push the new references on the list of references to manage (saveContext = true)
oldcell->mData = cell.mData;
oldcell->mName
= cell.mName; // merge name just to be sure (ID will be the same, but case could have been changed)
oldcell->loadCell(esm, true);
}
else
{
// spawn a new cell
cell.loadCell(esm, true);
mInt[cell.mName] = &cell; mInt[cell.mName] = &cell;
}
} }
else else
{ {
// Store exterior cells by grid position, try to merge with existing parent data. cell.loadCell(esm, false);
ESM::Cell* oldcell = const_cast<ESM::Cell*>(search(cell.getGridX(), cell.getGridY())); // handle moved ref (MVRF) subrecords
if (oldcell) ESM::MovedCellRefTracker newMovedRefs;
std::swap(newMovedRefs, cell.mMovedRefs);
handleMovedCellRefs(esm, &cell);
std::swap(newMovedRefs, cell.mMovedRefs);
// push the new references on the list of references to manage
cell.postLoad(esm);
if (newCell)
mExt[std::make_pair(cell.mData.mX, cell.mData.mY)] = &cell;
else
{ {
// merge new cell into old cell
oldcell->mData = cell.mData;
oldcell->mName = cell.mName;
oldcell->loadCell(esm, false);
// handle moved ref (MVRF) subrecords
handleMovedCellRefs(esm, &cell);
// push the new references on the list of references to manage
oldcell->postLoad(esm);
// merge lists of leased references, use newer data in case of conflict // merge lists of leased references, use newer data in case of conflict
for (ESM::MovedCellRefTracker::const_iterator it = cell.mMovedRefs.begin(); it != cell.mMovedRefs.end(); for (const auto& movedRef : newMovedRefs)
++it)
{ {
// remove reference from current leased ref tracker and add it to new cell // remove reference from current leased ref tracker and add it to new cell
ESM::MovedCellRefTracker::iterator itold auto itold = std::find(cell.mMovedRefs.begin(), cell.mMovedRefs.end(), movedRef.mRefNum);
= std::find(oldcell->mMovedRefs.begin(), oldcell->mMovedRefs.end(), it->mRefNum); if (itold != cell.mMovedRefs.end())
if (itold != oldcell->mMovedRefs.end())
{ {
if (it->mTarget[0] != itold->mTarget[0] || it->mTarget[1] != itold->mTarget[1]) if (movedRef.mTarget[0] != itold->mTarget[0] || movedRef.mTarget[1] != itold->mTarget[1])
{ {
ESM::Cell* wipecell = const_cast<ESM::Cell*>(search(itold->mTarget[0], itold->mTarget[1])); ESM::Cell* wipecell = const_cast<ESM::Cell*>(search(itold->mTarget[0], itold->mTarget[1]));
ESM::CellRefTracker::iterator it_lease = std::find_if(wipecell->mLeasedRefs.begin(), auto it_lease = std::find_if(wipecell->mLeasedRefs.begin(), wipecell->mLeasedRefs.end(),
wipecell->mLeasedRefs.end(), ESM::CellRefTrackerPredicate(it->mRefNum)); ESM::CellRefTrackerPredicate(movedRef.mRefNum));
if (it_lease != wipecell->mLeasedRefs.end()) if (it_lease != wipecell->mLeasedRefs.end())
wipecell->mLeasedRefs.erase(it_lease); wipecell->mLeasedRefs.erase(it_lease);
else else
Log(Debug::Error) << "Error: can't find " << it->mRefNum.mIndex << " " Log(Debug::Error) << "Error: can't find " << movedRef.mRefNum.mIndex << " "
<< it->mRefNum.mContentFile << " in leasedRefs"; << movedRef.mRefNum.mContentFile << " in leasedRefs";
} }
*itold = *it; *itold = movedRef;
} }
else else
oldcell->mMovedRefs.push_back(*it); cell.mMovedRefs.push_back(movedRef);
} }
// We don't need to merge mLeasedRefs of cell / oldcell. This list is filled when another cell moves a // We don't need to merge mLeasedRefs of cell / oldcell. This list is filled when another cell moves a
// reference to this cell, so the list for the new cell should be empty. The list for oldcell, // reference to this cell, so the list for the new cell should be empty. The list for oldcell,
// however, could have leased refs in it and so should be kept. // however, could have leased refs in it and so should be kept.
} }
else
{
// spawn a new cell
emplacedCell->loadCell(esm, false);
// handle moved ref (MVRF) subrecords
handleMovedCellRefs(esm, emplacedCell);
// push the new references on the list of references to manage
emplacedCell->postLoad(esm);
mExt[std::make_pair(cell.mData.mX, cell.mData.mY)] = &cell;
}
} }
return RecordId(cell.mId, isDeleted); return RecordId(cell.mId, isDeleted);
@ -834,51 +809,6 @@ namespace MWWorld
return result->second; return result->second;
} }
} }
bool Store<ESM::Cell>::erase(const ESM::Cell& cell)
{
if (cell.isExterior())
{
return erase(cell.getGridX(), cell.getGridY());
}
return erase(cell.mName);
}
bool Store<ESM::Cell>::erase(std::string_view name)
{
auto it = mDynamicInt.find(name);
if (it == mDynamicInt.end())
{
return false;
}
mDynamicInt.erase(it);
mSharedInt.erase(mSharedInt.begin() + mSharedInt.size(), mSharedInt.end());
for (it = mDynamicInt.begin(); it != mDynamicInt.end(); ++it)
{
mSharedInt.push_back(it->second);
}
return true;
}
bool Store<ESM::Cell>::erase(int x, int y)
{
std::pair<int, int> key(x, y);
DynamicExt::iterator it = mDynamicExt.find(key);
if (it == mDynamicExt.end())
{
return false;
}
mDynamicExt.erase(it);
mSharedExt.erase(mSharedExt.begin() + mSharedExt.size(), mSharedExt.end());
for (it = mDynamicExt.begin(); it != mDynamicExt.end(); ++it)
{
mSharedExt.push_back(it->second);
}
return true;
}
// Pathgrid // Pathgrid
//========================================================================= //=========================================================================

View File

@ -408,11 +408,6 @@ namespace MWWorld
void listIdentifier(std::vector<ESM::RefId>& list) const override; void listIdentifier(std::vector<ESM::RefId>& list) const override;
ESM::Cell* insert(const ESM::Cell& cell); ESM::Cell* insert(const ESM::Cell& cell);
bool erase(const ESM::Cell& cell);
bool erase(std::string_view id);
bool erase(int x, int y);
}; };
template <> template <>