mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 15:29:55 +00:00
Merge branch 'refnum' into savedgame
Conflicts: apps/openmw/mwworld/cellstore.cpp apps/openmw/mwworld/manualref.hpp components/esm/cellref.hpp
This commit is contained in:
commit
9025210965
9 changed files with 77 additions and 69 deletions
|
@ -246,7 +246,7 @@ void loadCell(ESM::Cell &cell, ESM::ESMReader &esm, Arguments& info)
|
|||
|
||||
if(quiet) continue;
|
||||
|
||||
std::cout << " Refnum: " << ref.mRefnum << std::endl;
|
||||
std::cout << " Refnum: " << ref.mRefNum.mIndex << std::endl;
|
||||
std::cout << " ID: '" << ref.mRefID << "'\n";
|
||||
std::cout << " Owner: '" << ref.mOwner << "'\n";
|
||||
std::cout << " Enchantment charge: '" << ref.mEnchantmentCharge << "'\n";
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace MWWorld
|
|||
if (const X *ptr = store.search (ref.mRefID))
|
||||
{
|
||||
typename std::list<LiveRef>::iterator iter =
|
||||
std::find(mList.begin(), mList.end(), ref.mRefnum);
|
||||
std::find(mList.begin(), mList.end(), ref.mRefNum);
|
||||
|
||||
LiveRef liveCellRef (ref, ptr);
|
||||
|
||||
|
@ -143,13 +143,16 @@ namespace MWWorld
|
|||
mCell->restore (esm[index], i);
|
||||
|
||||
ESM::CellRef ref;
|
||||
ref.mRefNum.mContentFile = -1;
|
||||
|
||||
// Get each reference in turn
|
||||
bool deleted = false;
|
||||
while(mCell->getNextRef(esm[index], ref, deleted))
|
||||
{
|
||||
// Don't load reference if it was moved to a different cell.
|
||||
ESM::MovedCellRefTracker::const_iterator iter = std::find(mCell->mMovedRefs.begin(), mCell->mMovedRefs.end(), ref.mRefnum);
|
||||
std::string lowerCase = Misc::StringUtils::lowerCase(ref.mRefID);
|
||||
ESM::MovedCellRefTracker::const_iterator iter =
|
||||
std::find(mCell->mMovedRefs.begin(), mCell->mMovedRefs.end(), ref.mRefNum);
|
||||
if (iter != mCell->mMovedRefs.end()) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,11 @@ namespace MWWorld
|
|||
virtual ~LiveCellRefBase() { }
|
||||
};
|
||||
|
||||
inline bool operator== (const LiveCellRefBase& cellRef, const ESM::CellRef::RefNum refNum)
|
||||
{
|
||||
return cellRef.mRef.mRefNum==refNum;
|
||||
}
|
||||
|
||||
/// A reference to one object (of any type) in a cell.
|
||||
///
|
||||
/// Constructing this with a CellRef instance in the constructor means that
|
||||
|
@ -51,8 +56,6 @@ namespace MWWorld
|
|||
// The object that this instance is based on.
|
||||
const X* mBase;
|
||||
};
|
||||
|
||||
// template<typename X> bool operator==(const LiveCellRef<X>& ref, int pRefnum);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,8 @@ namespace MWWorld
|
|||
{
|
||||
LiveCellRef<T> ref;
|
||||
ref.mBase = instance;
|
||||
ref.mRef.mRefNum.mIndex = 0;
|
||||
ref.mRef.mRefNum.mContentFile = -1;
|
||||
|
||||
mRef = ref;
|
||||
mPtr = Ptr (&boost::any_cast<LiveCellRef<T>&> (mRef), 0);
|
||||
|
@ -64,8 +66,9 @@ namespace MWWorld
|
|||
|
||||
// initialise
|
||||
ESM::CellRef& cellRef = mPtr.getCellRef();
|
||||
cellRef.mRefID = Misc::StringUtils::lowerCase(name);
|
||||
cellRef.mRefnum = -1;
|
||||
cellRef.mRefID = Misc::StringUtils::lowerCase (name);
|
||||
cellRef.mRefNum.mIndex = 0;
|
||||
cellRef.mRefNum.mContentFile = -1;
|
||||
cellRef.mScale = 1;
|
||||
cellRef.mFactIndex = 0;
|
||||
cellRef.mCharge = -1;
|
||||
|
|
|
@ -39,7 +39,7 @@ void Store<ESM::Cell>::load(ESM::ESMReader &esm, const std::string &id)
|
|||
// We should not need to test for duplicates, as this part of the code is pre-cell merge.
|
||||
cell->mMovedRefs.push_back(cMRef);
|
||||
// But there may be duplicates here!
|
||||
ESM::CellRefTracker::iterator iter = std::find(cellAlt->mLeasedRefs.begin(), cellAlt->mLeasedRefs.end(), ref.mRefnum);
|
||||
ESM::CellRefTracker::iterator iter = std::find(cellAlt->mLeasedRefs.begin(), cellAlt->mLeasedRefs.end(), ref.mRefNum);
|
||||
if (iter == cellAlt->mLeasedRefs.end())
|
||||
cellAlt->mLeasedRefs.push_back(ref);
|
||||
else
|
||||
|
@ -75,11 +75,11 @@ void Store<ESM::Cell>::load(ESM::ESMReader &esm, const std::string &id)
|
|||
// merge lists of leased references, use newer data in case of conflict
|
||||
for (ESM::MovedCellRefTracker::const_iterator it = cell->mMovedRefs.begin(); it != cell->mMovedRefs.end(); ++it) {
|
||||
// remove reference from current leased ref tracker and add it to new cell
|
||||
ESM::MovedCellRefTracker::iterator itold = std::find(oldcell->mMovedRefs.begin(), oldcell->mMovedRefs.end(), it->mRefnum);
|
||||
ESM::MovedCellRefTracker::iterator itold = std::find(oldcell->mMovedRefs.begin(), oldcell->mMovedRefs.end(), it->mRefNum);
|
||||
if (itold != oldcell->mMovedRefs.end()) {
|
||||
ESM::MovedCellRef target0 = *itold;
|
||||
ESM::Cell *wipecell = const_cast<ESM::Cell*>(search(target0.mTarget[0], target0.mTarget[1]));
|
||||
ESM::CellRefTracker::iterator it_lease = std::find(wipecell->mLeasedRefs.begin(), wipecell->mLeasedRefs.end(), it->mRefnum);
|
||||
ESM::CellRefTracker::iterator it_lease = std::find(wipecell->mLeasedRefs.begin(), wipecell->mLeasedRefs.end(), it->mRefNum);
|
||||
wipecell->mLeasedRefs.erase(it_lease);
|
||||
*itold = *it;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
void ESM::CellRef::save(ESMWriter &esm) const
|
||||
{
|
||||
esm.writeHNT("FRMR", mRefnum);
|
||||
esm.writeHNT("FRMR", mRefNum.mIndex);
|
||||
/// \todo read content file index (if present)
|
||||
esm.writeHNCString("NAME", mRefID);
|
||||
|
||||
if (mScale != 1.0) {
|
||||
|
@ -58,7 +59,8 @@ void ESM::CellRef::save(ESMWriter &esm) const
|
|||
|
||||
void ESM::CellRef::blank()
|
||||
{
|
||||
mRefnum = 0;
|
||||
mRefNum.mIndex = 0;
|
||||
mRefNum.mContentFile = -1;
|
||||
mRefID.clear();
|
||||
mScale = 1;
|
||||
mOwner.clear();
|
||||
|
@ -84,4 +86,9 @@ void ESM::CellRef::blank()
|
|||
mPos.pos[i] = 0;
|
||||
mPos.rot[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ESM::operator== (const CellRef::RefNum& left, const CellRef::RefNum& right)
|
||||
{
|
||||
return left.mIndex==right.mIndex && left.mContentFile==right.mContentFile;
|
||||
}
|
|
@ -19,8 +19,14 @@ namespace ESM
|
|||
{
|
||||
public:
|
||||
|
||||
int mRefnum; // Reference number
|
||||
std::string mRefID; // ID of object being referenced (must be lowercase)
|
||||
struct RefNum
|
||||
{
|
||||
int mIndex;
|
||||
int mContentFile; // -1 no content file
|
||||
};
|
||||
|
||||
RefNum mRefNum; // Reference number
|
||||
std::string mRefID; // ID of object being referenced
|
||||
|
||||
float mScale; // Scale applied to mesh
|
||||
|
||||
|
@ -84,6 +90,8 @@ namespace ESM
|
|||
|
||||
void blank();
|
||||
};
|
||||
|
||||
bool operator== (const CellRef::RefNum& left, const CellRef::RefNum& right);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,20 +9,42 @@
|
|||
#include "esmwriter.hpp"
|
||||
#include "defs.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
///< Translate 8bit/24bit code (stored in refNum.mIndex) into a proper refNum
|
||||
void adjustRefNum (ESM::CellRef::RefNum& refNum, ESM::ESMReader& reader)
|
||||
{
|
||||
int local = (refNum.mIndex & 0xff000000) >> 24;
|
||||
|
||||
if (local)
|
||||
{
|
||||
// If the most significant 8 bits are used, then this reference already exists.
|
||||
// In this case, do not spawn a new reference, but overwrite the old one.
|
||||
refNum.mIndex &= 0x00ffffff; // delete old plugin ID
|
||||
refNum.mContentFile = reader.getGameFiles()[local-1].index;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is an addition by the present plugin. Set the corresponding plugin index.
|
||||
refNum.mContentFile = reader.getIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
unsigned int Cell::sRecordId = REC_CELL;
|
||||
|
||||
/// Some overloaded compare operators.
|
||||
bool operator==(const MovedCellRef& ref, int pRefnum)
|
||||
{
|
||||
return (ref.mRefnum == pRefnum);
|
||||
}
|
||||
// Some overloaded compare operators.
|
||||
bool operator== (const MovedCellRef& ref, const CellRef::RefNum& refNum)
|
||||
{
|
||||
return ref.mRefNum == refNum;
|
||||
}
|
||||
|
||||
bool operator==(const CellRef& ref, int pRefnum)
|
||||
{
|
||||
return (ref.mRefnum == pRefnum);
|
||||
}
|
||||
bool operator== (const CellRef& ref, const CellRef::RefNum& refNum)
|
||||
{
|
||||
return ref.mRefNum == refNum;
|
||||
}
|
||||
|
||||
|
||||
void Cell::load(ESMReader &esm, bool saveContext)
|
||||
|
@ -163,49 +185,17 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted)
|
|||
//esm.getHNOT(NAM0, "NAM0");
|
||||
}
|
||||
|
||||
esm.getHNT(ref.mRefnum, "FRMR");
|
||||
esm.getHNT (ref.mRefNum.mIndex, "FRMR");
|
||||
ref.mRefID = esm.getHNString("NAME");
|
||||
|
||||
// Identify references belonging to a parent file and adapt the ID accordingly.
|
||||
int local = (ref.mRefnum & 0xff000000) >> 24;
|
||||
size_t global = esm.getIndex() + 1;
|
||||
if (local)
|
||||
{
|
||||
// If the most significant 8 bits are used, then this reference already exists.
|
||||
// In this case, do not spawn a new reference, but overwrite the old one.
|
||||
ref.mRefnum &= 0x00ffffff; // delete old plugin ID
|
||||
const std::vector<Header::MasterData> &masters = esm.getGameFiles();
|
||||
global = masters[local-1].index + 1;
|
||||
ref.mRefnum |= global << 24; // insert global plugin ID
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is an addition by the present plugin. Set the corresponding plugin index.
|
||||
ref.mRefnum |= global << 24; // insert global plugin ID
|
||||
}
|
||||
adjustRefNum (ref.mRefNum, esm);
|
||||
|
||||
// getHNOT will not change the existing value if the subrecord is
|
||||
// missing
|
||||
ref.mScale = 1.0;
|
||||
esm.getHNOT(ref.mScale, "XSCL");
|
||||
|
||||
// TODO: support loading references from saves, there are tons of keys not recognized yet.
|
||||
// The following is just an incomplete list.
|
||||
if (esm.isNextSub("ACTN"))
|
||||
esm.skipHSub();
|
||||
if (esm.isNextSub("STPR"))
|
||||
esm.skipHSub();
|
||||
if (esm.isNextSub("ACDT"))
|
||||
esm.skipHSub();
|
||||
if (esm.isNextSub("ACSC"))
|
||||
esm.skipHSub();
|
||||
if (esm.isNextSub("ACSL"))
|
||||
esm.skipHSub();
|
||||
if (esm.isNextSub("CHRD"))
|
||||
esm.skipHSub();
|
||||
else if (esm.isNextSub("CRED")) // ???
|
||||
esm.skipHSub();
|
||||
|
||||
ref.mOwner = esm.getHNOString("ANAM");
|
||||
ref.mGlob = esm.getHNOString("BNAM");
|
||||
ref.mSoul = esm.getHNOString("XSOL");
|
||||
|
@ -272,16 +262,10 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted)
|
|||
|
||||
bool Cell::getNextMVRF(ESMReader &esm, MovedCellRef &mref)
|
||||
{
|
||||
esm.getHT(mref.mRefnum);
|
||||
esm.getHT(mref.mRefNum.mIndex);
|
||||
esm.getHNOT(mref.mTarget, "CNDT");
|
||||
|
||||
// Identify references belonging to a parent file and adapt the ID accordingly.
|
||||
int local = (mref.mRefnum & 0xff000000) >> 24;
|
||||
size_t global = esm.getIndex() + 1;
|
||||
mref.mRefnum &= 0x00ffffff; // delete old plugin ID
|
||||
const std::vector<Header::MasterData> &masters = esm.getGameFiles();
|
||||
global = masters[local-1].index + 1;
|
||||
mref.mRefnum |= global << 24; // insert global plugin ID
|
||||
adjustRefNum (mref.mRefNum, esm);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ class ESMWriter;
|
|||
class MovedCellRef
|
||||
{
|
||||
public:
|
||||
int mRefnum;
|
||||
CellRef::RefNum mRefNum;
|
||||
|
||||
// Target cell (if exterior)
|
||||
int mTarget[2];
|
||||
|
@ -37,9 +37,9 @@ public:
|
|||
// introduces a henchman (which no one uses), so we may need this as well.
|
||||
};
|
||||
|
||||
/// Overloaded copare operator used to search inside a list of cell refs.
|
||||
bool operator==(const MovedCellRef& ref, int pRefnum);
|
||||
bool operator==(const CellRef& ref, int pRefnum);
|
||||
/// Overloaded compare operator used to search inside a list of cell refs.
|
||||
bool operator==(const MovedCellRef& ref, const CellRef::RefNum& refNum);
|
||||
bool operator==(const CellRef& ref, const CellRef::RefNum& refNum);
|
||||
|
||||
typedef std::list<MovedCellRef> MovedCellRefTracker;
|
||||
typedef std::list<CellRef> CellRefTracker;
|
||||
|
|
Loading…
Reference in a new issue