1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-21 09:39:56 +00:00

Initial support of generated RefNums with negative mContentFile.

This commit is contained in:
Petr Mikheev 2021-01-22 15:48:37 +01:00
parent b53667d555
commit 6db2450c90
10 changed files with 38 additions and 10 deletions

View File

@ -225,7 +225,7 @@ namespace MWRender
esm.resize(index+1);
cell->restore(esm[index], i);
ESM::CellRef ref;
ref.mRefNum.mContentFile = ESM::RefNum::RefNum_NoContentFile;
ref.mRefNum.unset();
bool deleted = false;
while(cell->getNextRef(esm[index], ref, deleted))
{

View File

@ -422,7 +422,7 @@ namespace MWRender
esm.resize(index+1);
cell->restore(esm[index], i);
ESM::CellRef ref;
ref.mRefNum.mContentFile = ESM::RefNum::RefNum_NoContentFile;
ref.mRefNum.unset();
ESM::MovedCellRef cMRef;
cMRef.mRefNum.mIndex = 0;
bool deleted = false;

View File

@ -1,5 +1,8 @@
#include "cellref.hpp"
#include <assert.h>
#include <components/debug/debuglog.hpp>
#include <components/esm/objectstate.hpp>
namespace MWWorld
@ -10,6 +13,25 @@ namespace MWWorld
return mCellRef.mRefNum;
}
const ESM::RefNum& CellRef::getOrAssignRefNum(ESM::RefNum& lastAssignedRefNum)
{
if (!mCellRef.mRefNum.isSet())
{
// Generated RefNums have negative mContentFile
assert(lastAssignedRefNum.mContentFile < 0);
lastAssignedRefNum.mIndex++;
if (lastAssignedRefNum.mIndex == 0) // mIndex overflow, so mContentFile should be changed
{
lastAssignedRefNum.mContentFile--;
if (lastAssignedRefNum.mContentFile > 0)
Log(Debug::Error) << "RefNum counter overflow in CellRef::getOrAssignRefNum";
}
mCellRef.mRefNum = lastAssignedRefNum;
mChanged = true;
}
return mCellRef.mRefNum;
}
bool CellRef::hasContentFile() const
{
return mCellRef.mRefNum.hasContentFile();

View File

@ -25,6 +25,10 @@ namespace MWWorld
// Note: Currently unused for items in containers
const ESM::RefNum& getRefNum() const;
// Returns RefNum.
// If RefNum is not set, assigns a generated one and changes the "lastAssignedRefNum" counter.
const ESM::RefNum& getOrAssignRefNum(ESM::RefNum& lastAssignedRefNum);
// Set RefNum to its default state.
void unsetRefNum();

View File

@ -615,7 +615,7 @@ namespace MWWorld
mCell->restore (esm[index], i);
ESM::CellRef ref;
ref.mRefNum.mContentFile = ESM::RefNum::RefNum_NoContentFile;
ref.mRefNum.unset();
// Get each reference in turn
ESM::MovedCellRef cMRef;

View File

@ -34,7 +34,7 @@ namespace
readers.resize(index + 1);
cell.restore(readers[index], i);
ESM::CellRef ref;
ref.mRefNum.mContentFile = ESM::RefNum::RefNum_NoContentFile;
ref.mRefNum.unset();
bool deleted = false;
while(cell.getNextRef(readers[index], ref, deleted))
{

View File

@ -2020,7 +2020,7 @@ namespace MWWorld
rayToObject = mRendering->castCameraToViewportRay(0.5f, 0.5f, maxDistance, ignorePlayer);
facedObject = rayToObject.mHitObject;
if (facedObject.isEmpty() && rayToObject.mHitRefnum.hasContentFile())
if (facedObject.isEmpty() && rayToObject.mHitRefnum.isSet())
{
for (CellStore* cellstore : mWorldScene->getActiveCells())
{

View File

@ -24,8 +24,9 @@ void ESM::RefNum::save (ESMWriter &esm, bool wide, const std::string& tag) const
esm.writeHNT (tag, *this, 8);
else
{
if (isSet() && !hasContentFile())
Log(Debug::Error) << "Generated RefNum can not be saved in 32bit format";
int refNum = (mIndex & 0xffffff) | ((hasContentFile() ? mContentFile : 0xff)<<24);
esm.writeHNT (tag, refNum, 4);
}
}

View File

@ -23,9 +23,10 @@ namespace ESM
void save (ESMWriter &esm, bool wide = false, const std::string& tag = "FRMR") const;
enum { RefNum_NoContentFile = -1 };
inline bool hasContentFile() const { return mContentFile != RefNum_NoContentFile; }
inline void unset() { mIndex = 0; mContentFile = RefNum_NoContentFile; }
inline bool hasContentFile() const { return mContentFile >= 0; }
inline bool isSet() const { return mIndex != 0 || mContentFile != -1; }
inline void unset() { *this = {0, -1}; }
// Note: this method should not be used for objects with invalid RefNum
// (for example, for objects from disabled plugins in savegames).

View File

@ -30,7 +30,7 @@ void ESM::GlobalScript::save (ESMWriter &esm) const
if (!mTargetId.empty())
{
esm.writeHNOString ("TARG", mTargetId);
if (mTargetRef.hasContentFile())
if (mTargetRef.isSet())
mTargetRef.save (esm, true, "FRMR");
}
}