Merge branch 'refnum' into savedgame

Conflicts:
	apps/openmw/mwworld/cellstore.cpp
	apps/openmw/mwworld/manualref.hpp
	components/esm/cellref.hpp
actorid
Marc Zinnschlag 11 years ago
commit 9025210965

@ -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 ESM
namespace
{
unsigned int Cell::sRecordId = REC_CELL;
///< 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;
/// Some overloaded compare operators.
bool operator==(const MovedCellRef& ref, int pRefnum)
{
return (ref.mRefnum == pRefnum);
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();
}
}
}
bool operator==(const CellRef& ref, int pRefnum)
namespace ESM
{
return (ref.mRefnum == pRefnum);
}
unsigned int Cell::sRecordId = REC_CELL;
// Some overloaded compare operators.
bool operator== (const MovedCellRef& ref, const CellRef::RefNum& refNum)
{
return ref.mRefNum == refNum;
}
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…
Cancel
Save