mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-21 19:09:41 +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)!="#";
|
bool interior = cellRecord.mId.substr (0, 1)!="#";
|
||||||
|
|
||||||
// count new references and adjust RefNumCount accordingsly
|
// count new references and adjust RefNumCount accordingsly
|
||||||
int newRefNum = cellRecord.mRefNumCounter;
|
unsigned int newRefNum = cellRecord.mRefNumCounter;
|
||||||
|
|
||||||
if (references!=mState.getSubRecords().end())
|
if (references!=mState.getSubRecords().end())
|
||||||
{
|
{
|
||||||
|
@ -279,11 +279,17 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
|
||||||
const CSMWorld::Record<CSMWorld::CellRef>& ref =
|
const CSMWorld::Record<CSMWorld::CellRef>& ref =
|
||||||
mDocument.getData().getReferences().getRecord (*iter);
|
mDocument.getData().getReferences().getRecord (*iter);
|
||||||
|
|
||||||
if (ref.get().mNew ||
|
CSMWorld::CellRef refRecord = ref.get();
|
||||||
|
|
||||||
|
if (refRecord.mNew ||
|
||||||
(!interior && ref.mState==CSMWorld::RecordBase::State_ModifiedOnly &&
|
(!interior && ref.mState==CSMWorld::RecordBase::State_ModifiedOnly &&
|
||||||
/// \todo consider worldspace
|
/// \todo consider worldspace
|
||||||
CSMWorld::CellCoordinates (ref.get().getCellIndex()).getId("")!=ref.get().mCell))
|
CSMWorld::CellCoordinates (refRecord.getCellIndex()).getId("") != refRecord.mCell))
|
||||||
++cellRecord.mRefNumCounter;
|
++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;
|
stream << "#" << index.first << " " << index.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (refRecord.mNew ||
|
if (refRecord.mNew || refRecord.mRefNum.mIndex == 0 ||
|
||||||
(!interior && ref.mState==CSMWorld::RecordBase::State_ModifiedOnly &&
|
(!interior && ref.mState==CSMWorld::RecordBase::State_ModifiedOnly &&
|
||||||
refRecord.mCell!=stream.str()))
|
refRecord.mCell!=stream.str()))
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "collectionbase.hpp"
|
#include "collectionbase.hpp"
|
||||||
#include "land.hpp"
|
#include "land.hpp"
|
||||||
#include "landtexture.hpp"
|
#include "landtexture.hpp"
|
||||||
|
#include "ref.hpp"
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
|
@ -259,6 +260,11 @@ namespace CSMWorld
|
||||||
copy.mState = RecordBase::State_ModifiedOnly;
|
copy.mState = RecordBase::State_ModifiedOnly;
|
||||||
IdAccessorT().setId(copy.get(), destination);
|
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);
|
int index = getAppendIndex(destination, type);
|
||||||
insertRecord(copy, getAppendIndex(destination, type));
|
insertRecord(copy, getAppendIndex(destination, type));
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
#include <components/misc/constants.hpp>
|
||||||
|
|
||||||
#include "../doc/document.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::UpdateCellCommand> modifyCell;
|
||||||
|
|
||||||
|
std::unique_ptr<CSMWorld::ModifyCommand> modifyDataRefNum;
|
||||||
|
|
||||||
int columnId = model->data (index, ColumnBase::Role_ColumnId).toInt();
|
int columnId = model->data (index, ColumnBase::Role_ColumnId).toInt();
|
||||||
|
|
||||||
if (columnId==Columns::ColumnId_PositionXPos || columnId==Columns::ColumnId_PositionYPos)
|
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();
|
// Modulate by cell size, update cell id if reference has been moved to a new cell
|
||||||
|
if (std::abs(std::fmod(oldPosition, Constants::CellSizeInUnits))
|
||||||
// This is not guaranteed to be the same as \a model, since a proxy could be used.
|
- std::abs(std::fmod(new_.toFloat(), Constants::CellSizeInUnits)) >= 0.5f)
|
||||||
IdTable& model2 = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
|
|
||||||
|
|
||||||
int cellColumn = model2.searchColumnIndex (Columns::ColumnId_Cell);
|
|
||||||
|
|
||||||
if (cellColumn!=-1)
|
|
||||||
{
|
{
|
||||||
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
|
QModelIndex cellIndex = model2.index (row, cellColumn);
|
||||||
modifyCell.reset (new UpdateCellCommand (model2, row));
|
|
||||||
|
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());
|
CommandMacro macro (mDocument.getUndoStack());
|
||||||
macro.push (modifyData.release());
|
macro.push (modifyData.release());
|
||||||
macro.push (modifyCell.release());
|
macro.push (modifyCell.release());
|
||||||
|
if (modifyDataRefNum.get())
|
||||||
|
macro.push (modifyDataRefNum.release());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mDocument.getUndoStack().push (modifyData.release());
|
mDocument.getUndoStack().push (modifyData.release());
|
||||||
|
|
|
@ -670,6 +670,33 @@ void CSVRender::Object::apply (CSMWorld::CommandMacro& commands)
|
||||||
|
|
||||||
if (mOverrideFlags & Override_Position)
|
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)
|
for (int i=0; i<3; ++i)
|
||||||
{
|
{
|
||||||
int column = collection.findColumnIndex (static_cast<CSMWorld::Columns::ColumnId> (
|
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,
|
commands.push (new CSMWorld::ModifyCommand (*model,
|
||||||
model->index (recordIndex, column), mPositionOverride.pos[i]));
|
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)
|
if (mOverrideFlags & Override_Rotation)
|
||||||
|
|
Loading…
Reference in a new issue