mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 06:53:52 +00:00
removing 255 content file limitation
This commit is contained in:
parent
09fadd446b
commit
c22e38f825
9 changed files with 74 additions and 68 deletions
|
@ -244,7 +244,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";
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace MWWorld
|
||||||
void CellRefList<X>::load(ESM::CellRef &ref, const MWWorld::ESMStore &esmStore)
|
void CellRefList<X>::load(ESM::CellRef &ref, const MWWorld::ESMStore &esmStore)
|
||||||
{
|
{
|
||||||
// Get existing reference, in case we need to overwrite it.
|
// Get existing reference, in case we need to overwrite it.
|
||||||
typename std::list<LiveRef>::iterator iter = std::find(mList.begin(), mList.end(), ref.mRefnum);
|
typename std::list<LiveRef>::iterator iter = std::find(mList.begin(), mList.end(), ref.mRefNum);
|
||||||
|
|
||||||
// Skip this when reference was deleted.
|
// Skip this when reference was deleted.
|
||||||
// TODO: Support respawning references, in this case, we need to track it somehow.
|
// TODO: Support respawning references, in this case, we need to track it somehow.
|
||||||
|
@ -148,13 +148,14 @@ 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
|
||||||
while(mCell->getNextRef(esm[index], ref))
|
while(mCell->getNextRef(esm[index], ref))
|
||||||
{
|
{
|
||||||
// Don't load reference if it was moved to a different cell.
|
// Don't load reference if it was moved to a different cell.
|
||||||
std::string lowerCase = Misc::StringUtils::lowerCase(ref.mRefID);
|
std::string lowerCase = Misc::StringUtils::lowerCase(ref.mRefID);
|
||||||
ESM::MovedCellRefTracker::const_iterator iter = std::find(mCell->mMovedRefs.begin(), mCell->mMovedRefs.end(), ref.mRefnum);
|
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 = name;
|
cellRef.mRefID = 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;
|
||||||
|
|
|
@ -40,7 +40,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
|
||||||
|
@ -76,11 +76,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,7 +19,13 @@ namespace ESM
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
int mRefnum; // Reference number
|
struct RefNum
|
||||||
|
{
|
||||||
|
int mIndex;
|
||||||
|
int mContentFile; // -1 no content file
|
||||||
|
};
|
||||||
|
|
||||||
|
RefNum mRefNum; // Reference number
|
||||||
std::string mRefID; // ID of object being referenced
|
std::string mRefID; // ID of object being referenced
|
||||||
|
|
||||||
float mScale; // Scale applied to mesh
|
float mScale; // Scale applied to mesh
|
||||||
|
@ -87,6 +93,8 @@ namespace ESM
|
||||||
|
|
||||||
void blank();
|
void blank();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool operator== (const CellRef::RefNum& left, const CellRef::RefNum& right);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -9,20 +9,42 @@
|
||||||
#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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Cell::load(ESMReader &esm, bool saveContext)
|
void Cell::load(ESMReader &esm, bool saveContext)
|
||||||
|
@ -163,49 +185,17 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
|
||||||
//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");
|
||||||
|
@ -271,16 +261,10 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
|
||||||
|
|
||||||
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…
Reference in a new issue