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:
commit
309855107b
4 changed files with 75 additions and 32 deletions
|
@ -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()))
|
||||
{
|
||||
|
|
|
@ -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*) ©.mModified;
|
||||
ptr->mRefNum.mIndex = 0;
|
||||
}
|
||||
|
||||
int index = getAppendIndex(destination, type);
|
||||
insertRecord(copy, getAppendIndex(destination, type));
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue