1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-20 21:09:40 +00:00

Merge branch 'ensure-unique-refnum' into 'master'

Ensure Unique Instance Refnum after clone, add, or move

Closes #4748

See merge request OpenMW/openmw!49
This commit is contained in:
Bret Curtis 2019-01-21 19:30:11 +00:00
commit 309855107b
4 changed files with 75 additions and 32 deletions

View file

@ -269,7 +269,7 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
bool interior = cellRecord.mId.substr (0, 1)!="#";
// count new references and adjust RefNumCount accordingsly
int newRefNum = cellRecord.mRefNumCounter;
unsigned int newRefNum = cellRecord.mRefNumCounter;
if (references!=mState.getSubRecords().end())
{
@ -279,11 +279,17 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
const CSMWorld::Record<CSMWorld::CellRef>& ref =
mDocument.getData().getReferences().getRecord (*iter);
if (ref.get().mNew ||
CSMWorld::CellRef refRecord = ref.get();
if (refRecord.mNew ||
(!interior && ref.mState==CSMWorld::RecordBase::State_ModifiedOnly &&
/// \todo consider worldspace
CSMWorld::CellCoordinates (ref.get().getCellIndex()).getId("")!=ref.get().mCell))
CSMWorld::CellCoordinates (refRecord.getCellIndex()).getId("") != refRecord.mCell))
++cellRecord.mRefNumCounter;
if (refRecord.mRefNum.mIndex >= newRefNum)
newRefNum = refRecord.mRefNum.mIndex + 1;
}
}
@ -328,7 +334,7 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
stream << "#" << index.first << " " << index.second;
}
if (refRecord.mNew ||
if (refRecord.mNew || refRecord.mRefNum.mIndex == 0 ||
(!interior && ref.mState==CSMWorld::RecordBase::State_ModifiedOnly &&
refRecord.mCell!=stream.str()))
{

View file

@ -17,6 +17,7 @@
#include "collectionbase.hpp"
#include "land.hpp"
#include "landtexture.hpp"
#include "ref.hpp"
namespace CSMWorld
{
@ -259,6 +260,11 @@ namespace CSMWorld
copy.mState = RecordBase::State_ModifiedOnly;
IdAccessorT().setId(copy.get(), destination);
if (type == UniversalId::Type_Reference) {
CSMWorld::CellRef* ptr = (CSMWorld::CellRef*) &copy.mModified;
ptr->mRefNum.mIndex = 0;
}
int index = getAppendIndex(destination, type);
insertRecord(copy, getAppendIndex(destination, type));

View file

@ -4,6 +4,7 @@
#include <memory>
#include <components/misc/stringops.hpp>
#include <components/misc/constants.hpp>
#include "../doc/document.hpp"
@ -140,29 +141,44 @@ void CSMWorld::CommandDispatcher::executeModify (QAbstractItemModel *model, cons
std::unique_ptr<CSMWorld::UpdateCellCommand> modifyCell;
std::unique_ptr<CSMWorld::ModifyCommand> modifyDataRefNum;
int columnId = model->data (index, ColumnBase::Role_ColumnId).toInt();
if (columnId==Columns::ColumnId_PositionXPos || columnId==Columns::ColumnId_PositionYPos)
{
IdTableProxyModel *proxy = dynamic_cast<IdTableProxyModel *> (model);
const float oldPosition = model->data (index).toFloat();
int row = proxy ? proxy->mapToSource (index).row() : index.row();
// This is not guaranteed to be the same as \a model, since a proxy could be used.
IdTable& model2 = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
int cellColumn = model2.searchColumnIndex (Columns::ColumnId_Cell);
if (cellColumn!=-1)
// Modulate by cell size, update cell id if reference has been moved to a new cell
if (std::abs(std::fmod(oldPosition, Constants::CellSizeInUnits))
- std::abs(std::fmod(new_.toFloat(), Constants::CellSizeInUnits)) >= 0.5f)
{
QModelIndex cellIndex = model2.index (row, cellColumn);
IdTableProxyModel *proxy = dynamic_cast<IdTableProxyModel *> (model);
std::string cellId = model2.data (cellIndex).toString().toUtf8().data();
int row = proxy ? proxy->mapToSource (index).row() : index.row();
if (cellId.find ('#')!=std::string::npos)
// This is not guaranteed to be the same as \a model, since a proxy could be used.
IdTable& model2 = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
int cellColumn = model2.searchColumnIndex (Columns::ColumnId_Cell);
if (cellColumn!=-1)
{
// Need to recalculate the cell
modifyCell.reset (new UpdateCellCommand (model2, row));
QModelIndex cellIndex = model2.index (row, cellColumn);
std::string cellId = model2.data (cellIndex).toString().toUtf8().data();
if (cellId.find ('#')!=std::string::npos)
{
// Need to recalculate the cell and (if necessary) clear the instance's refNum
modifyCell.reset (new UpdateCellCommand (model2, row));
// Not sure which model this should be applied to
int refNumColumn = model2.searchColumnIndex (Columns::ColumnId_RefNum);
if (refNumColumn!=-1)
modifyDataRefNum.reset (new ModifyCommand(*model, model->index(row, refNumColumn), 0));
}
}
}
}
@ -175,6 +191,8 @@ void CSMWorld::CommandDispatcher::executeModify (QAbstractItemModel *model, cons
CommandMacro macro (mDocument.getUndoStack());
macro.push (modifyData.release());
macro.push (modifyCell.release());
if (modifyDataRefNum.get())
macro.push (modifyDataRefNum.release());
}
else
mDocument.getUndoStack().push (modifyData.release());

View file

@ -670,6 +670,33 @@ void CSVRender::Object::apply (CSMWorld::CommandMacro& commands)
if (mOverrideFlags & Override_Position)
{
//Do cell check first so positions can be compared
const CSMWorld::CellRef& ref = collection.getRecord(recordIndex).get();
if (CSMWorld::CellCoordinates::isExteriorCell(ref.mCell))
{
// Find cell index at new position
std::pair<int, int> cellIndex = CSMWorld::CellCoordinates::coordinatesToCellIndex(
mPositionOverride.pos[0], mPositionOverride.pos[1]);
std::pair<int, int> originalIndex = ref.getCellIndex();
int cellColumn = collection.findColumnIndex (static_cast<CSMWorld::Columns::ColumnId> (
CSMWorld::Columns::ColumnId_Cell));
int refNumColumn = collection.findColumnIndex (static_cast<CSMWorld::Columns::ColumnId> (
CSMWorld::Columns::ColumnId_RefNum));
if (cellIndex != originalIndex)
{
/// \todo figure out worldspace (not important until multiple worldspaces are supported)
std::string cellId = CSMWorld::CellCoordinates (cellIndex).getId ("");
commands.push (new CSMWorld::ModifyCommand (*model,
model->index (recordIndex, cellColumn), QString::fromUtf8 (cellId.c_str())));
commands.push (new CSMWorld::ModifyCommand( *model,
model->index (recordIndex, refNumColumn), 0));
}
}
for (int i=0; i<3; ++i)
{
int column = collection.findColumnIndex (static_cast<CSMWorld::Columns::ColumnId> (
@ -678,20 +705,6 @@ void CSVRender::Object::apply (CSMWorld::CommandMacro& commands)
commands.push (new CSMWorld::ModifyCommand (*model,
model->index (recordIndex, column), mPositionOverride.pos[i]));
}
int column = collection.findColumnIndex (static_cast<CSMWorld::Columns::ColumnId> (
CSMWorld::Columns::ColumnId_Cell));
if (CSMWorld::CellCoordinates::isExteriorCell(collection.getRecord (recordIndex).get().mCell))
{
std::pair<int, int> cellIndex = collection.getRecord (recordIndex).get().getCellIndex();
/// \todo figure out worldspace (not important until multiple worldspaces are supported)
std::string cellId = CSMWorld::CellCoordinates (cellIndex).getId ("");
commands.push (new CSMWorld::ModifyCommand (*model,
model->index (recordIndex, column), QString::fromUtf8 (cellId.c_str())));
}
}
if (mOverrideFlags & Override_Rotation)