mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 18:35:20 +00:00
Fix cell overrides and remove unused, incomplete erase method
This commit is contained in:
parent
cdc753df70
commit
2a48642fe3
@ -646,96 +646,71 @@ namespace MWWorld
|
||||
// All cells have a name record, even nameless exterior cells.
|
||||
ESM::Cell* emplacedCell = nullptr;
|
||||
bool isDeleted = false;
|
||||
bool newCell = false;
|
||||
|
||||
{
|
||||
ESM::Cell cellToLoad;
|
||||
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;
|
||||
// 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
|
||||
if (cell.mData.mFlags & ESM::Cell::Interior)
|
||||
{
|
||||
// Store interior cell by name, try to merge with existing parent data.
|
||||
ESM::Cell* oldcell = const_cast<ESM::Cell*>(search(cell.mName));
|
||||
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);
|
||||
|
||||
cell.loadCell(esm, true);
|
||||
if (newCell)
|
||||
mInt[cell.mName] = &cell;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Store exterior cells by grid position, try to merge with existing parent data.
|
||||
ESM::Cell* oldcell = const_cast<ESM::Cell*>(search(cell.getGridX(), cell.getGridY()));
|
||||
if (oldcell)
|
||||
cell.loadCell(esm, false);
|
||||
// handle moved ref (MVRF) subrecords
|
||||
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
|
||||
for (ESM::MovedCellRefTracker::const_iterator it = cell.mMovedRefs.begin(); it != cell.mMovedRefs.end();
|
||||
++it)
|
||||
for (const auto& movedRef : newMovedRefs)
|
||||
{
|
||||
// remove reference from current leased ref tracker and add it to new cell
|
||||
ESM::MovedCellRefTracker::iterator itold
|
||||
= std::find(oldcell->mMovedRefs.begin(), oldcell->mMovedRefs.end(), it->mRefNum);
|
||||
if (itold != oldcell->mMovedRefs.end())
|
||||
auto itold = std::find(cell.mMovedRefs.begin(), cell.mMovedRefs.end(), movedRef.mRefNum);
|
||||
if (itold != cell.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::CellRefTracker::iterator it_lease = std::find_if(wipecell->mLeasedRefs.begin(),
|
||||
wipecell->mLeasedRefs.end(), ESM::CellRefTrackerPredicate(it->mRefNum));
|
||||
auto it_lease = std::find_if(wipecell->mLeasedRefs.begin(), wipecell->mLeasedRefs.end(),
|
||||
ESM::CellRefTrackerPredicate(movedRef.mRefNum));
|
||||
if (it_lease != wipecell->mLeasedRefs.end())
|
||||
wipecell->mLeasedRefs.erase(it_lease);
|
||||
else
|
||||
Log(Debug::Error) << "Error: can't find " << it->mRefNum.mIndex << " "
|
||||
<< it->mRefNum.mContentFile << " in leasedRefs";
|
||||
Log(Debug::Error) << "Error: can't find " << movedRef.mRefNum.mIndex << " "
|
||||
<< movedRef.mRefNum.mContentFile << " in leasedRefs";
|
||||
}
|
||||
*itold = *it;
|
||||
*itold = movedRef;
|
||||
}
|
||||
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
|
||||
// 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.
|
||||
}
|
||||
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);
|
||||
@ -834,51 +809,6 @@ namespace MWWorld
|
||||
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
|
||||
//=========================================================================
|
||||
|
@ -408,11 +408,6 @@ namespace MWWorld
|
||||
void listIdentifier(std::vector<ESM::RefId>& list) const override;
|
||||
|
||||
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 <>
|
||||
|
Loading…
x
Reference in New Issue
Block a user