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; 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 << " ID: '" << ref.mRefID << "'\n";
std::cout << " Owner: '" << ref.mOwner << "'\n"; std::cout << " Owner: '" << ref.mOwner << "'\n";
std::cout << " Enchantment charge: '" << ref.mEnchantmentCharge << "'\n"; std::cout << " Enchantment charge: '" << ref.mEnchantmentCharge << "'\n";

@ -42,7 +42,7 @@ namespace MWWorld
if (const X *ptr = store.search (ref.mRefID)) if (const X *ptr = store.search (ref.mRefID))
{ {
typename std::list<LiveRef>::iterator iter = 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); LiveRef liveCellRef (ref, ptr);
@ -143,13 +143,16 @@ namespace MWWorld
mCell->restore (esm[index], i); mCell->restore (esm[index], i);
ESM::CellRef ref; ESM::CellRef ref;
ref.mRefNum.mContentFile = -1;
// Get each reference in turn // Get each reference in turn
bool deleted = false; bool deleted = false;
while(mCell->getNextRef(esm[index], ref, deleted)) while(mCell->getNextRef(esm[index], ref, deleted))
{ {
// Don't load reference if it was moved to a different cell. // 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()) { if (iter != mCell->mMovedRefs.end()) {
continue; continue;
} }

@ -31,6 +31,11 @@ namespace MWWorld
virtual ~LiveCellRefBase() { } 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. /// A reference to one object (of any type) in a cell.
/// ///
/// Constructing this with a CellRef instance in the constructor means that /// 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. // The object that this instance is based on.
const X* mBase; const X* mBase;
}; };
// template<typename X> bool operator==(const LiveCellRef<X>& ref, int pRefnum);
} }
#endif #endif

@ -25,6 +25,8 @@ namespace MWWorld
{ {
LiveCellRef<T> ref; LiveCellRef<T> ref;
ref.mBase = instance; ref.mBase = instance;
ref.mRef.mRefNum.mIndex = 0;
ref.mRef.mRefNum.mContentFile = -1;
mRef = ref; mRef = ref;
mPtr = Ptr (&boost::any_cast<LiveCellRef<T>&> (mRef), 0); mPtr = Ptr (&boost::any_cast<LiveCellRef<T>&> (mRef), 0);
@ -65,7 +67,8 @@ namespace MWWorld
// initialise // initialise
ESM::CellRef& cellRef = mPtr.getCellRef(); ESM::CellRef& cellRef = mPtr.getCellRef();
cellRef.mRefID = Misc::StringUtils::lowerCase (name); cellRef.mRefID = Misc::StringUtils::lowerCase (name);
cellRef.mRefnum = -1; cellRef.mRefNum.mIndex = 0;
cellRef.mRefNum.mContentFile = -1;
cellRef.mScale = 1; cellRef.mScale = 1;
cellRef.mFactIndex = 0; cellRef.mFactIndex = 0;
cellRef.mCharge = -1; 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. // We should not need to test for duplicates, as this part of the code is pre-cell merge.
cell->mMovedRefs.push_back(cMRef); cell->mMovedRefs.push_back(cMRef);
// But there may be duplicates here! // 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()) if (iter == cellAlt->mLeasedRefs.end())
cellAlt->mLeasedRefs.push_back(ref); cellAlt->mLeasedRefs.push_back(ref);
else 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 // 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) { 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 // 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()) { if (itold != oldcell->mMovedRefs.end()) {
ESM::MovedCellRef target0 = *itold; ESM::MovedCellRef target0 = *itold;
ESM::Cell *wipecell = const_cast<ESM::Cell*>(search(target0.mTarget[0], target0.mTarget[1])); 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); wipecell->mLeasedRefs.erase(it_lease);
*itold = *it; *itold = *it;
} }

@ -5,7 +5,8 @@
void ESM::CellRef::save(ESMWriter &esm) const 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); esm.writeHNCString("NAME", mRefID);
if (mScale != 1.0) { if (mScale != 1.0) {
@ -58,7 +59,8 @@ void ESM::CellRef::save(ESMWriter &esm) const
void ESM::CellRef::blank() void ESM::CellRef::blank()
{ {
mRefnum = 0; mRefNum.mIndex = 0;
mRefNum.mContentFile = -1;
mRefID.clear(); mRefID.clear();
mScale = 1; mScale = 1;
mOwner.clear(); mOwner.clear();
@ -85,3 +87,8 @@ void ESM::CellRef::blank()
mPos.rot[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: public:
int mRefnum; // Reference number struct RefNum
std::string mRefID; // ID of object being referenced (must be lowercase) {
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 float mScale; // Scale applied to mesh
@ -84,6 +90,8 @@ namespace ESM
void blank(); void blank();
}; };
bool operator== (const CellRef::RefNum& left, const CellRef::RefNum& right);
} }
#endif #endif

@ -9,19 +9,41 @@
#include "esmwriter.hpp" #include "esmwriter.hpp"
#include "defs.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 namespace ESM
{ {
unsigned int Cell::sRecordId = REC_CELL; unsigned int Cell::sRecordId = REC_CELL;
/// Some overloaded compare operators. // Some overloaded compare operators.
bool operator==(const MovedCellRef& ref, int pRefnum) bool operator== (const MovedCellRef& ref, const CellRef::RefNum& refNum)
{ {
return (ref.mRefnum == pRefnum); return ref.mRefNum == refNum;
} }
bool operator==(const CellRef& ref, int pRefnum) bool operator== (const CellRef& ref, const CellRef::RefNum& refNum)
{ {
return (ref.mRefnum == pRefnum); return ref.mRefNum == refNum;
} }
@ -163,49 +185,17 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted)
//esm.getHNOT(NAM0, "NAM0"); //esm.getHNOT(NAM0, "NAM0");
} }
esm.getHNT(ref.mRefnum, "FRMR"); esm.getHNT (ref.mRefNum.mIndex, "FRMR");
ref.mRefID = esm.getHNString("NAME"); ref.mRefID = esm.getHNString("NAME");
// Identify references belonging to a parent file and adapt the ID accordingly. // Identify references belonging to a parent file and adapt the ID accordingly.
int local = (ref.mRefnum & 0xff000000) >> 24; adjustRefNum (ref.mRefNum, esm);
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
}
// getHNOT will not change the existing value if the subrecord is // getHNOT will not change the existing value if the subrecord is
// missing // missing
ref.mScale = 1.0; ref.mScale = 1.0;
esm.getHNOT(ref.mScale, "XSCL"); 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.mOwner = esm.getHNOString("ANAM");
ref.mGlob = esm.getHNOString("BNAM"); ref.mGlob = esm.getHNOString("BNAM");
ref.mSoul = esm.getHNOString("XSOL"); 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) bool Cell::getNextMVRF(ESMReader &esm, MovedCellRef &mref)
{ {
esm.getHT(mref.mRefnum); esm.getHT(mref.mRefNum.mIndex);
esm.getHNOT(mref.mTarget, "CNDT"); esm.getHNOT(mref.mTarget, "CNDT");
// Identify references belonging to a parent file and adapt the ID accordingly. adjustRefNum (mref.mRefNum, esm);
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
return true; return true;
} }

@ -27,7 +27,7 @@ class ESMWriter;
class MovedCellRef class MovedCellRef
{ {
public: public:
int mRefnum; CellRef::RefNum mRefNum;
// Target cell (if exterior) // Target cell (if exterior)
int mTarget[2]; int mTarget[2];
@ -37,9 +37,9 @@ public:
// introduces a henchman (which no one uses), so we may need this as well. // 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. /// Overloaded compare operator used to search inside a list of cell refs.
bool operator==(const MovedCellRef& ref, int pRefnum); bool operator==(const MovedCellRef& ref, const CellRef::RefNum& refNum);
bool operator==(const CellRef& ref, int pRefnum); bool operator==(const CellRef& ref, const CellRef::RefNum& refNum);
typedef std::list<MovedCellRef> MovedCellRefTracker; typedef std::list<MovedCellRef> MovedCellRefTracker;
typedef std::list<CellRef> CellRefTracker; typedef std::list<CellRef> CellRefTracker;

Loading…
Cancel
Save