More ESM records have DELE handling.

Changed records: Race, Land, Pathgrid, StartScript, DebugProfile, Filter

(cherry picked from commit e65ff723ce6e71da7d00e68820250682512418c1)

Conflicts:
	components/esm/loadland.cpp
	components/esm/loadland.hpp
This commit is contained in:
Stanislav Bas 2015-07-16 22:17:49 +03:00 committed by cc9cii
parent 8b7b3d2a4e
commit b5c958c62a
12 changed files with 501 additions and 369 deletions

View File

@ -6,17 +6,53 @@
unsigned int ESM::DebugProfile::sRecordId = REC_DBGP; unsigned int ESM::DebugProfile::sRecordId = REC_DBGP;
ESM::DebugProfile::DebugProfile()
: mIsDeleted(false)
{}
void ESM::DebugProfile::load (ESMReader& esm) void ESM::DebugProfile::load (ESMReader& esm)
{ {
mId = esm.getHNString ("NAME"); mIsDeleted = false;
mDescription = esm.getHNString ("DESC");
mScriptText = esm.getHNString ("SCRP"); while (esm.hasMoreSubs())
esm.getHNT (mFlags, "FLAG"); {
esm.getSubName();
uint32_t name = esm.retSubName().val;
switch (name)
{
case ESM::FourCC<'N','A','M','E'>::value:
mId = esm.getHString();
break;
case ESM::FourCC<'D','E','L','E'>::value:
esm.skipHSub();
mIsDeleted = true;
break;
case ESM::FourCC<'D','E','S','C'>::value:
mDescription = esm.getHString();
break;
case ESM::FourCC<'S','C','R','P'>::value:
mScriptText = esm.getHString();
break;
case ESM::FourCC<'F','L','A','G'>::value:
esm.getHT(mFlags);
break;
default:
esm.fail("Unknown subrecord");
break;
}
}
} }
void ESM::DebugProfile::save (ESMWriter& esm) const void ESM::DebugProfile::save (ESMWriter& esm) const
{ {
esm.writeHNCString ("NAME", mId); esm.writeHNCString ("NAME", mId);
if (mIsDeleted)
{
esm.writeHNCString("DELE", "");
return;
}
esm.writeHNCString ("DESC", mDescription); esm.writeHNCString ("DESC", mDescription);
esm.writeHNCString ("SCRP", mScriptText); esm.writeHNCString ("SCRP", mScriptText);
esm.writeHNT ("FLAG", mFlags); esm.writeHNT ("FLAG", mFlags);
@ -27,4 +63,5 @@ void ESM::DebugProfile::blank()
mDescription.clear(); mDescription.clear();
mScriptText.clear(); mScriptText.clear();
mFlags = 0; mFlags = 0;
mIsDeleted = false;
} }

View File

@ -27,6 +27,10 @@ namespace ESM
unsigned int mFlags; unsigned int mFlags;
bool mIsDeleted;
DebugProfile();
void load (ESMReader& esm); void load (ESMReader& esm);
void save (ESMWriter& esm) const; void save (ESMWriter& esm) const;

View File

@ -6,16 +6,50 @@
unsigned int ESM::Filter::sRecordId = REC_FILT; unsigned int ESM::Filter::sRecordId = REC_FILT;
ESM::Filter::Filter()
: mIsDeleted(false)
{}
void ESM::Filter::load (ESMReader& esm) void ESM::Filter::load (ESMReader& esm)
{ {
mId = esm.getHNString ("NAME"); mIsDeleted = false;
mFilter = esm.getHNString ("FILT");
mDescription = esm.getHNString ("DESC"); while (esm.hasMoreSubs())
{
esm.getSubName();
uint32_t name = esm.retSubName().val;
switch (name)
{
case ESM::FourCC<'N','A','M','E'>::value:
mId = esm.getHString();
break;
case ESM::FourCC<'D','E','L','E'>::value:
esm.skipHSub();
mIsDeleted = true;
break;
case ESM::FourCC<'F','I','L','T'>::value:
mFilter = esm.getHString();
break;
case ESM::FourCC<'D','E','S','C'>::value:
mDescription = esm.getHString();
break;
default:
esm.fail("Unknown subrecord");
break;
}
}
} }
void ESM::Filter::save (ESMWriter& esm) const void ESM::Filter::save (ESMWriter& esm) const
{ {
esm.writeHNCString ("NAME", mId); esm.writeHNCString ("NAME", mId);
if (mIsDeleted)
{
esm.writeHNCString("DELE", "");
return;
}
esm.writeHNCString ("FILT", mFilter); esm.writeHNCString ("FILT", mFilter);
esm.writeHNCString ("DESC", mDescription); esm.writeHNCString ("DESC", mDescription);
} }
@ -24,4 +58,5 @@ void ESM::Filter::blank()
{ {
mFilter.clear(); mFilter.clear();
mDescription.clear(); mDescription.clear();
mIsDeleted = false;
} }

View File

@ -18,6 +18,10 @@ namespace ESM
std::string mFilter; std::string mFilter;
bool mIsDeleted;
Filter();
void load (ESMReader& esm); void load (ESMReader& esm);
void save (ESMWriter& esm) const; void save (ESMWriter& esm) const;

View File

@ -10,8 +10,8 @@ namespace ESM
{ {
unsigned int Land::sRecordId = REC_LAND; unsigned int Land::sRecordId = REC_LAND;
void Land::LandData::save(ESMWriter &esm) const void Land::LandData::save(ESMWriter &esm) const
{ {
if (mDataTypes & Land::DATA_VNML) { if (mDataTypes & Land::DATA_VNML) {
esm.writeHNT("VNML", mNormals, sizeof(mNormals)); esm.writeHNT("VNML", mNormals, sizeof(mNormals));
} }
@ -53,19 +53,19 @@ void Land::LandData::save(ESMWriter &esm) const
transposeTextureData(mTextures, vtex); transposeTextureData(mTextures, vtex);
esm.writeHNT("VTEX", vtex, sizeof(vtex)); esm.writeHNT("VTEX", vtex, sizeof(vtex));
} }
} }
void Land::LandData::transposeTextureData(const uint16_t *in, uint16_t *out) void Land::LandData::transposeTextureData(const uint16_t *in, uint16_t *out)
{ {
int readPos = 0; //bit ugly, but it works int readPos = 0; //bit ugly, but it works
for ( int y1 = 0; y1 < 4; y1++ ) for ( int y1 = 0; y1 < 4; y1++ )
for ( int x1 = 0; x1 < 4; x1++ ) for ( int x1 = 0; x1 < 4; x1++ )
for ( int y2 = 0; y2 < 4; y2++) for ( int y2 = 0; y2 < 4; y2++)
for ( int x2 = 0; x2 < 4; x2++ ) for ( int x2 = 0; x2 < 4; x2++ )
out[(y1*4+y2)*16+(x1*4+x2)] = in[readPos++]; out[(y1*4+y2)*16+(x1*4+x2)] = in[readPos++];
} }
Land::Land() Land::Land()
: mFlags(0) : mFlags(0)
, mX(0) , mX(0)
, mY(0) , mY(0)
@ -74,18 +74,20 @@ Land::Land()
, mDataTypes(0) , mDataTypes(0)
, mDataLoaded(false) , mDataLoaded(false)
, mLandData(NULL) , mLandData(NULL)
{ , mIsDeleted(false)
} {
}
Land::~Land() Land::~Land()
{ {
delete mLandData; delete mLandData;
} }
void Land::load(ESMReader &esm) void Land::load(ESMReader &esm)
{ {
mEsm = &esm; mEsm = &esm;
mPlugin = mEsm->getIndex(); mPlugin = mEsm->getIndex();
mIsDeleted = false;
// Get the grid location // Get the grid location
esm.getSubNameIs("INTV"); esm.getSubNameIs("INTV");
@ -95,6 +97,12 @@ void Land::load(ESMReader &esm)
esm.getHNT(mFlags, "DATA"); esm.getHNT(mFlags, "DATA");
if (esm.isNextSub("DELE"))
{
esm.skipHSub();
mIsDeleted = true;
}
// Store the file position // Store the file position
mContext = esm.getContext(); mContext = esm.getContext();
@ -127,20 +135,35 @@ void Land::load(ESMReader &esm)
mDataLoaded = 0; mDataLoaded = 0;
mLandData = NULL; mLandData = NULL;
} }
void Land::save(ESMWriter &esm) const void Land::save(ESMWriter &esm) const
{ {
esm.startSubRecord("INTV"); esm.startSubRecord("INTV");
esm.writeT(mX); esm.writeT(mX);
esm.writeT(mY); esm.writeT(mY);
esm.endRecord("INTV"); esm.endRecord("INTV");
esm.writeHNT("DATA", mFlags); esm.writeHNT("DATA", mFlags);
}
void Land::loadData(int flags) const if (mIsDeleted)
{ {
esm.writeHNCString("DELE", "");
}
if (mLandData != NULL)
{
mLandData->save(esm);
}
}
void Land::blank()
{
mIsDeleted = false;
}
void Land::loadData(int flags) const
{
// Try to load only available data // Try to load only available data
flags = flags & mDataTypes; flags = flags & mDataTypes;
// Return if all required data is loaded // Return if all required data is loaded
@ -189,20 +212,20 @@ void Land::loadData(int flags) const
LandData::transposeTextureData(vtex, mLandData->mTextures); LandData::transposeTextureData(vtex, mLandData->mTextures);
} }
} }
} }
void Land::unloadData() void Land::unloadData()
{ {
if (mDataLoaded) if (mDataLoaded)
{ {
delete mLandData; delete mLandData;
mLandData = NULL; mLandData = NULL;
mDataLoaded = 0; mDataLoaded = 0;
} }
} }
bool Land::condLoad(int flags, int dataFlag, void *ptr, unsigned int size) const bool Land::condLoad(int flags, int dataFlag, void *ptr, unsigned int size) const
{ {
if ((mDataLoaded & dataFlag) == 0 && (flags & dataFlag) != 0) { if ((mDataLoaded & dataFlag) == 0 && (flags & dataFlag) != 0) {
mEsm->getHExact(ptr, size); mEsm->getHExact(ptr, size);
mDataLoaded |= dataFlag; mDataLoaded |= dataFlag;
@ -210,76 +233,11 @@ bool Land::condLoad(int flags, int dataFlag, void *ptr, unsigned int size) const
} }
mEsm->skipHSubSize(size); mEsm->skipHSubSize(size);
return false; return false;
} }
bool Land::isDataLoaded(int flags) const bool Land::isDataLoaded(int flags) const
{ {
return (mDataLoaded & flags) == (flags & mDataTypes); return (mDataLoaded & flags) == (flags & mDataTypes);
} }
Land::Land (const Land& land)
: mFlags (land.mFlags), mX (land.mX), mY (land.mY), mPlugin (land.mPlugin),
mEsm (land.mEsm), mContext (land.mContext), mDataTypes (land.mDataTypes),
mDataLoaded (land.mDataLoaded),
mLandData (land.mLandData ? new LandData (*land.mLandData) : 0)
{}
Land& Land::operator= (Land land)
{
swap (land);
return *this;
}
void Land::swap (Land& land)
{
std::swap (mFlags, land.mFlags);
std::swap (mX, land.mX);
std::swap (mY, land.mY);
std::swap (mPlugin, land.mPlugin);
std::swap (mEsm, land.mEsm);
std::swap (mContext, land.mContext);
std::swap (mDataTypes, land.mDataTypes);
std::swap (mDataLoaded, land.mDataLoaded);
std::swap (mLandData, land.mLandData);
}
const Land::LandData *Land::getLandData (int flags) const
{
if (!(flags & mDataTypes))
return 0;
loadData (flags);
return mLandData;
}
const Land::LandData *Land::getLandData() const
{
return mLandData;
}
Land::LandData *Land::getLandData()
{
return mLandData;
}
void Land::add (int flags)
{
if (!mLandData)
mLandData = new LandData;
mDataTypes |= flags;
mDataLoaded |= flags;
}
void Land::remove (int flags)
{
mDataTypes &= ~flags;
mDataLoaded &= ~flags;
if (!mDataLoaded)
{
delete mLandData;
mLandData = 0;
}
}
} }

View File

@ -106,10 +106,12 @@ struct Land
static void transposeTextureData(const uint16_t *in, uint16_t *out); static void transposeTextureData(const uint16_t *in, uint16_t *out);
}; };
bool mIsDeleted;
void load(ESMReader &esm); void load(ESMReader &esm);
void save(ESMWriter &esm) const; void save(ESMWriter &esm) const;
void blank() {} void blank();
/** /**
* Actually loads data * Actually loads data

View File

@ -32,18 +32,35 @@ namespace ESM
{ {
} }
void Pathgrid::load(ESMReader &esm) Pathgrid::Pathgrid()
{ : mIsDeleted(false)
esm.getHNT(mData, "DATA", 12); {}
mCell = esm.getHNString("NAME");
void Pathgrid::load(ESMReader &esm)
{
mPoints.clear(); mPoints.clear();
mEdges.clear(); mEdges.clear();
// keep track of total connections so we can reserve edge vector size // keep track of total connections so we can reserve edge vector size
int edgeCount = 0; int edgeCount = 0;
if (esm.isNextSub("PGRP")) bool hasData = false;
bool hasName = false;
while (esm.hasMoreSubs())
{
esm.getSubName();
uint32_t name = esm.retSubName().val;
switch (name)
{
case ESM::FourCC<'D','A','T','A'>::value:
esm.getHT(mData, 12);
hasData = true;
break;
case ESM::FourCC<'N','A','M','E'>::value:
mCell = esm.getHString();
hasName = true;
break;
case ESM::FourCC<'P','G','R','P'>::value:
{ {
esm.getSubHeader(); esm.getSubHeader();
int size = esm.getSubSize(); int size = esm.getSubSize();
@ -62,9 +79,9 @@ void Pathgrid::load(ESMReader &esm)
edgeCount += p.mConnectionNum; edgeCount += p.mConnectionNum;
} }
} }
break;
} }
case ESM::FourCC<'P','G','R','C'>::value:
if (esm.isNextSub("PGRC"))
{ {
esm.getSubHeader(); esm.getSubHeader();
int size = esm.getSubSize(); int size = esm.getSubSize();
@ -97,13 +114,35 @@ void Pathgrid::load(ESMReader &esm)
} }
} }
} }
break;
} }
} case ESM::FourCC<'D','E','L','E'>::value:
void Pathgrid::save(ESMWriter &esm) const esm.skipHSub();
{ mIsDeleted = true;
break;
default:
esm.fail("Unknown subrecord");
break;
}
}
if (!hasData)
esm.fail("Missing DATA subrecord");
if (!hasName)
esm.fail("Missing NAME subrecord");
}
void Pathgrid::save(ESMWriter &esm) const
{
esm.writeHNT("DATA", mData, 12); esm.writeHNT("DATA", mData, 12);
esm.writeHNCString("NAME", mCell); esm.writeHNCString("NAME", mCell);
if (mIsDeleted)
{
esm.writeHNCString("DELE", "");
return;
}
if (!mPoints.empty()) if (!mPoints.empty())
{ {
esm.startSubRecord("PGRP"); esm.startSubRecord("PGRP");
@ -123,7 +162,7 @@ void Pathgrid::save(ESMWriter &esm) const
} }
esm.endRecord("PGRC"); esm.endRecord("PGRC");
} }
} }
void Pathgrid::blank() void Pathgrid::blank()
{ {
@ -134,5 +173,6 @@ void Pathgrid::save(ESMWriter &esm) const
mData.mS2 = 0; mData.mS2 = 0;
mPoints.clear(); mPoints.clear();
mEdges.clear(); mEdges.clear();
mIsDeleted = false;
} }
} }

View File

@ -53,6 +53,10 @@ struct Pathgrid
typedef std::vector<Edge> EdgeList; typedef std::vector<Edge> EdgeList;
EdgeList mEdges; EdgeList mEdges;
bool mIsDeleted;
Pathgrid();
void load(ESMReader &esm); void load(ESMReader &esm);
void save(ESMWriter &esm) const; void save(ESMWriter &esm) const;

View File

@ -8,6 +8,10 @@ namespace ESM
{ {
unsigned int Race::sRecordId = REC_RACE; unsigned int Race::sRecordId = REC_RACE;
Race::Race()
: mIsDeleted(false)
{}
int Race::MaleFemale::getValue (bool male) const int Race::MaleFemale::getValue (bool male) const
{ {
return male ? mMale : mFemale; return male ? mMale : mFemale;
@ -18,12 +22,12 @@ namespace ESM
return static_cast<int>(male ? mMale : mFemale); return static_cast<int>(male ? mMale : mFemale);
} }
void Race::load(ESMReader &esm) void Race::load(ESMReader &esm)
{ {
mPowers.mList.clear(); mPowers.mList.clear();
mIsDeleted = false;
mId = esm.getHNString("NAME"); bool hasName = false;
bool hasData = false; bool hasData = false;
while (esm.hasMoreSubs()) while (esm.hasMoreSubs())
{ {
@ -31,6 +35,14 @@ void Race::load(ESMReader &esm)
uint32_t name = esm.retSubName().val; uint32_t name = esm.retSubName().val;
switch (name) switch (name)
{ {
case ESM::FourCC<'N','A','M','E'>::value:
mId = esm.getHString();
hasName = true;
break;
case ESM::FourCC<'D','E','L','E'>::value:
esm.skipHSub();
mIsDeleted = true;
break;
case ESM::FourCC<'F','N','A','M'>::value: case ESM::FourCC<'F','N','A','M'>::value:
mName = esm.getHString(); mName = esm.getHString();
break; break;
@ -48,17 +60,27 @@ void Race::load(ESMReader &esm)
esm.fail("Unknown subrecord"); esm.fail("Unknown subrecord");
} }
} }
if (!hasData)
if (!hasName)
esm.fail("Missing NAME subrecord");
if (!hasData && !mIsDeleted)
esm.fail("Missing RADT subrecord"); esm.fail("Missing RADT subrecord");
} }
void Race::save(ESMWriter &esm) const void Race::save(ESMWriter &esm) const
{ {
esm.writeHNCString("NAME", mId); esm.writeHNCString("NAME", mId);
if (mIsDeleted)
{
esm.writeHNCString("DELE", "");
return;
}
esm.writeHNOCString("FNAM", mName); esm.writeHNOCString("FNAM", mName);
esm.writeHNT("RADT", mData, 140); esm.writeHNT("RADT", mData, 140);
mPowers.save(esm); mPowers.save(esm);
esm.writeHNOString("DESC", mDescription); esm.writeHNOString("DESC", mDescription);
} }
void Race::blank() void Race::blank()
{ {

View File

@ -68,6 +68,10 @@ struct Race
std::string mId, mName, mDescription; std::string mId, mName, mDescription;
SpellList mPowers; SpellList mPowers;
bool mIsDeleted;
Race();
void load(ESMReader &esm); void load(ESMReader &esm);
void save(ESMWriter &esm) const; void save(ESMWriter &esm) const;

View File

@ -8,8 +8,14 @@ namespace ESM
{ {
unsigned int StartScript::sRecordId = REC_SSCR; unsigned int StartScript::sRecordId = REC_SSCR;
StartScript::StartScript()
: mIsDeleted(false)
{}
void StartScript::load(ESMReader &esm) void StartScript::load(ESMReader &esm)
{ {
mIsDeleted = false;
bool hasData = false; bool hasData = false;
bool hasName = false; bool hasName = false;
while (esm.hasMoreSubs()) while (esm.hasMoreSubs())
@ -26,10 +32,16 @@ namespace ESM
mId = esm.getHString(); mId = esm.getHString();
hasName = true; hasName = true;
break; break;
case ESM::FourCC<'D','E','L','E'>::value:
esm.skipHSub();
mIsDeleted = true;
break;
default: default:
esm.fail("Unknown subrecord"); esm.fail("Unknown subrecord");
break;
} }
} }
if (!hasData) if (!hasData)
esm.fail("Missing DATA"); esm.fail("Missing DATA");
if (!hasName) if (!hasName)
@ -39,10 +51,16 @@ namespace ESM
{ {
esm.writeHNString("DATA", mData); esm.writeHNString("DATA", mData);
esm.writeHNString("NAME", mId); esm.writeHNString("NAME", mId);
if (mIsDeleted)
{
esm.writeHNCString("DELE", "");
}
} }
void StartScript::blank() void StartScript::blank()
{ {
mData.clear(); mData.clear();
mIsDeleted = false;
} }
} }

View File

@ -26,6 +26,10 @@ struct StartScript
std::string mData; std::string mData;
std::string mId; std::string mId;
bool mIsDeleted;
StartScript();
// Load a record and add it to the list // Load a record and add it to the list
void load(ESMReader &esm); void load(ESMReader &esm);
void save(ESMWriter &esm) const; void save(ESMWriter &esm) const;