mirror of
https://github.com/OpenMW/openmw.git
synced 2025-10-17 15:46:43 +00:00
Merge branch 'dont-take-away-my-individuality' into 'master'
FIX: Track the highest local refNum during plugin loading and increment it for each cloned/created reference Closes #8620 See merge request OpenMW/openmw!4781
This commit is contained in:
commit
5ad9010e07
6 changed files with 22 additions and 31 deletions
|
@ -291,8 +291,7 @@ int CSMDoc::WriteCellCollectionStage::setup()
|
|||
return mDocument.getData().getCells().getSize();
|
||||
}
|
||||
|
||||
void CSMDoc::WriteCellCollectionStage::writeReferences(
|
||||
const std::deque<int>& references, bool interior, unsigned int& newRefNum)
|
||||
void CSMDoc::WriteCellCollectionStage::writeReferences(const std::deque<int>& references, bool interior)
|
||||
{
|
||||
ESM::ESMWriter& writer = mState.getWriter();
|
||||
|
||||
|
@ -304,6 +303,8 @@ void CSMDoc::WriteCellCollectionStage::writeReferences(
|
|||
{
|
||||
CSMWorld::CellRef refRecord = ref.get();
|
||||
|
||||
const bool isLocal = refRecord.mRefNum.mContentFile == -1;
|
||||
|
||||
// -1 is the current file, saved indices are 1-based
|
||||
refRecord.mRefNum.mContentFile++;
|
||||
|
||||
|
@ -316,12 +317,7 @@ void CSMDoc::WriteCellCollectionStage::writeReferences(
|
|||
}
|
||||
|
||||
ESM::RefId streamId = ESM::RefId::stringRefId(stream.str());
|
||||
if (refRecord.mNew || refRecord.mRefNum.mIndex == 0
|
||||
|| (!interior && ref.mState == CSMWorld::RecordBase::State_ModifiedOnly && refRecord.mCell != streamId))
|
||||
{
|
||||
refRecord.mRefNum.mIndex = newRefNum++;
|
||||
}
|
||||
else if ((refRecord.mOriginalCell.empty() ? refRecord.mCell : refRecord.mOriginalCell) != streamId
|
||||
if (!isLocal && (refRecord.mOriginalCell.empty() ? refRecord.mCell : refRecord.mOriginalCell) != streamId
|
||||
&& !interior)
|
||||
{
|
||||
// An empty mOriginalCell is meant to indicate that it is the same as
|
||||
|
@ -362,9 +358,6 @@ void CSMDoc::WriteCellCollectionStage::perform(int stage, Messages& messages)
|
|||
CSMWorld::Cell cellRecord = cell.get();
|
||||
const bool interior = !cellRecord.mId.startsWith("#");
|
||||
|
||||
// count new references and adjust RefNumCount accordingsly
|
||||
unsigned int newRefNum = cellRecord.mRefNumCounter;
|
||||
|
||||
if (references != nullptr)
|
||||
{
|
||||
for (std::deque<int>::const_iterator iter(references->begin()); iter != references->end(); ++iter)
|
||||
|
@ -390,9 +383,6 @@ void CSMDoc::WriteCellCollectionStage::perform(int stage, Messages& messages)
|
|||
ESM::RefId::stringRefId(CSMWorld::CellCoordinates(refRecord.getCellIndex()).getId(""))
|
||||
!= refRecord.mCell))
|
||||
++cellRecord.mRefNumCounter;
|
||||
|
||||
if (refRecord.mRefNum.mIndex >= newRefNum)
|
||||
newRefNum = refRecord.mRefNum.mIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -415,9 +405,9 @@ void CSMDoc::WriteCellCollectionStage::perform(int stage, Messages& messages)
|
|||
// write references
|
||||
if (references != nullptr)
|
||||
{
|
||||
writeReferences(persistentRefs, interior, newRefNum);
|
||||
writeReferences(persistentRefs, interior);
|
||||
cellRecord.saveTempMarker(writer, static_cast<int>(references->size()) - persistentRefs.size());
|
||||
writeReferences(tempRefs, interior, newRefNum);
|
||||
writeReferences(tempRefs, interior);
|
||||
}
|
||||
|
||||
writer.endRecord(cellRecord.sRecordId);
|
||||
|
|
|
@ -167,7 +167,7 @@ namespace CSMDoc
|
|||
Document& mDocument;
|
||||
SavingState& mState;
|
||||
|
||||
void writeReferences(const std::deque<int>& references, bool interior, unsigned int& newRefNum);
|
||||
void writeReferences(const std::deque<int>& references, bool interior);
|
||||
|
||||
public:
|
||||
WriteCellCollectionStage(Document& document, SavingState& state);
|
||||
|
|
|
@ -273,15 +273,6 @@ namespace CSMWorld
|
|||
copy->mState = RecordBase::State_ModifiedOnly;
|
||||
setRecordId(destination, copy->get());
|
||||
|
||||
if constexpr (std::is_same_v<ESXRecordT, CSMWorld::CellRef>)
|
||||
{
|
||||
if (type == UniversalId::Type_Reference)
|
||||
{
|
||||
CSMWorld::CellRef* ptr = (CSMWorld::CellRef*)©->mModified;
|
||||
ptr->mRefNum.mIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr (std::is_same_v<ESXRecordT, ESM::Dialogue>)
|
||||
{
|
||||
copy->mModified.mStringId = copy->mModified.mId.getRefIdString();
|
||||
|
|
|
@ -175,6 +175,9 @@ void CSMWorld::RefCollection::load(ESM::ESMReader& reader, int cellIndex, bool b
|
|||
ref.mIdNum = mNextId; // FIXME: fragile
|
||||
ref.mId = ESM::RefId::stringRefId(getNewId());
|
||||
|
||||
if (!base && ref.mRefNum.mIndex > mHighestUsedRefNum)
|
||||
mHighestUsedRefNum = ref.mRefNum.mIndex;
|
||||
|
||||
cache.emplace(ref.mRefNum, ref.mIdNum);
|
||||
|
||||
auto record = std::make_unique<Record<CellRef>>();
|
||||
|
@ -222,6 +225,11 @@ std::string CSMWorld::RefCollection::getNewId()
|
|||
return "ref#" + std::to_string(mNextId++);
|
||||
}
|
||||
|
||||
uint32_t CSMWorld::RefCollection::getNextRefNum()
|
||||
{
|
||||
return ++mHighestUsedRefNum;
|
||||
}
|
||||
|
||||
unsigned int CSMWorld::RefCollection::extractIdNum(std::string_view id) const
|
||||
{
|
||||
std::string::size_type separator = id.find_last_of('#');
|
||||
|
@ -283,6 +291,7 @@ void CSMWorld::RefCollection::appendBlankRecord(const ESM::RefId& id, UniversalI
|
|||
|
||||
record->get().mId = id;
|
||||
record->get().mIdNum = extractIdNum(id.getRefIdString());
|
||||
record->get().mRefNum.mIndex = getNextRefNum();
|
||||
|
||||
Collection<CellRef>::appendRecord(std::move(record));
|
||||
}
|
||||
|
@ -298,15 +307,13 @@ void CSMWorld::RefCollection::cloneRecord(
|
|||
|
||||
copy->get().mId = destination;
|
||||
copy->get().mIdNum = extractIdNum(destination.getRefIdString());
|
||||
copy->get().mRefNum.mIndex = getNextRefNum();
|
||||
|
||||
if (copy->get().mRefNum.hasContentFile())
|
||||
{
|
||||
mRefIndex.insert(std::make_pair(static_cast<Record<CellRef>*>(copy.get())->get().mIdNum, index));
|
||||
copy->get().mRefNum.mContentFile = -1;
|
||||
copy->get().mRefNum.mIndex = index;
|
||||
}
|
||||
else
|
||||
copy->get().mRefNum.mIndex = copy->get().mIdNum;
|
||||
|
||||
insertRecord(std::move(copy), getAppendIndex(destination, type)); // call RefCollection::insertRecord()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CSM_WOLRD_REFCOLLECTION_H
|
||||
#define CSM_WOLRD_REFCOLLECTION_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
@ -40,9 +41,12 @@ namespace CSMWorld
|
|||
std::map<unsigned int, int> mRefIndex; // CellRef index keyed by CSMWorld::CellRef::mIdNum
|
||||
|
||||
int mNextId;
|
||||
uint32_t mHighestUsedRefNum = 0;
|
||||
|
||||
unsigned int extractIdNum(std::string_view id) const;
|
||||
|
||||
uint32_t getNextRefNum();
|
||||
|
||||
int getIntIndex(unsigned int id) const;
|
||||
|
||||
int searchId(unsigned int id) const;
|
||||
|
|
|
@ -1277,9 +1277,8 @@ void CSVRender::InstanceMode::cloneSelectedInstances()
|
|||
if (CSVRender::ObjectTag* objectTag = dynamic_cast<CSVRender::ObjectTag*>(tag.get()))
|
||||
{
|
||||
macro.push(new CSMWorld::CloneCommand(referencesTable, objectTag->mObject->getReferenceId(),
|
||||
"ref#" + std::to_string(referencesTable.rowCount()), CSMWorld::UniversalId::Type_Reference));
|
||||
document.getData().getReferences().getNewId(), CSMWorld::UniversalId::Type_Reference));
|
||||
}
|
||||
// getWorldspaceWidget().clearSelection(Mask_Reference);
|
||||
}
|
||||
|
||||
void CSVRender::InstanceMode::dropInstance(CSVRender::Object* object, float dropHeight)
|
||||
|
|
Loading…
Reference in a new issue