|
|
|
@ -3,14 +3,15 @@
|
|
|
|
|
#include "esmreader.hpp"
|
|
|
|
|
#include "esmwriter.hpp"
|
|
|
|
|
#include "defs.hpp"
|
|
|
|
|
#include "util.hpp"
|
|
|
|
|
|
|
|
|
|
namespace ESM
|
|
|
|
|
{
|
|
|
|
|
unsigned int DialInfo::sRecordId = REC_INFO;
|
|
|
|
|
|
|
|
|
|
DialInfo::DialInfo()
|
|
|
|
|
: mIsDeleted(false)
|
|
|
|
|
: mFactionLess(false),
|
|
|
|
|
mQuestStatus(QS_None),
|
|
|
|
|
mIsDeleted(false)
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
void DialInfo::load(ESMReader &esm)
|
|
|
|
@ -29,6 +30,7 @@ namespace ESM
|
|
|
|
|
{
|
|
|
|
|
mQuestStatus = QS_None;
|
|
|
|
|
mFactionLess = false;
|
|
|
|
|
mIsDeleted = false;
|
|
|
|
|
|
|
|
|
|
mPrev = esm.getHNString("PNAM");
|
|
|
|
|
mNext = esm.getHNString("NNAM");
|
|
|
|
@ -36,118 +38,77 @@ namespace ESM
|
|
|
|
|
// Since there's no way to mark selects as "deleted", we have to clear the SelectStructs from all previous loadings
|
|
|
|
|
mSelects.clear();
|
|
|
|
|
|
|
|
|
|
// If the info is deleted, NAME and DELE sub-records are followed after NNAM
|
|
|
|
|
if (esm.isNextSub("NAME"))
|
|
|
|
|
{
|
|
|
|
|
mResponse = esm.getHString();
|
|
|
|
|
mIsDeleted = readDeleSubRecord(esm);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
esm.getSubNameIs("DATA");
|
|
|
|
|
esm.getHT(mData, 12);
|
|
|
|
|
|
|
|
|
|
if (!esm.hasMoreSubs())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// What follows is somewhat spaghetti-ish, but it's worth if for
|
|
|
|
|
// an extra speedup. INFO is by far the most common record type.
|
|
|
|
|
|
|
|
|
|
// subName is a reference to the original, so it changes whenever
|
|
|
|
|
// a new sub name is read. esm.isEmptyOrGetName() will get the
|
|
|
|
|
// next name for us, or return true if there are no more records.
|
|
|
|
|
esm.getSubName();
|
|
|
|
|
const NAME &subName = esm.retSubName();
|
|
|
|
|
|
|
|
|
|
if (subName.val == REC_ONAM)
|
|
|
|
|
{
|
|
|
|
|
mActor = esm.getHString();
|
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (subName.val == REC_RNAM)
|
|
|
|
|
{
|
|
|
|
|
mRace = esm.getHString();
|
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (subName.val == REC_CNAM)
|
|
|
|
|
{
|
|
|
|
|
mClass = esm.getHString();
|
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (subName.val == REC_FNAM)
|
|
|
|
|
{
|
|
|
|
|
mFaction = esm.getHString();
|
|
|
|
|
if (mFaction == "FFFF")
|
|
|
|
|
mFactionLess = true;
|
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (subName.val == REC_ANAM)
|
|
|
|
|
{
|
|
|
|
|
mCell = esm.getHString();
|
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (subName.val == REC_DNAM)
|
|
|
|
|
{
|
|
|
|
|
mPcFaction = esm.getHString();
|
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (subName.val == REC_SNAM)
|
|
|
|
|
{
|
|
|
|
|
mSound = esm.getHString();
|
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (subName.val == REC_NAME)
|
|
|
|
|
{
|
|
|
|
|
mResponse = esm.getHString();
|
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (subName.val == REC_SCVR)
|
|
|
|
|
while (esm.hasMoreSubs())
|
|
|
|
|
{
|
|
|
|
|
SelectStruct ss;
|
|
|
|
|
|
|
|
|
|
ss.mSelectRule = esm.getHString();
|
|
|
|
|
|
|
|
|
|
ss.mValue.read (esm, Variant::Format_Info);
|
|
|
|
|
|
|
|
|
|
mSelects.push_back(ss);
|
|
|
|
|
|
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
|
return;
|
|
|
|
|
esm.getSubName();
|
|
|
|
|
uint32_t name = esm.retSubName().val;
|
|
|
|
|
switch (name)
|
|
|
|
|
{
|
|
|
|
|
case ESM::FourCC<'D','E','L','E'>::value:
|
|
|
|
|
esm.skipHSub();
|
|
|
|
|
mIsDeleted = true;
|
|
|
|
|
break;
|
|
|
|
|
case ESM::FourCC<'D','A','T','A'>::value:
|
|
|
|
|
esm.getHT(mData, 12);
|
|
|
|
|
break;
|
|
|
|
|
case ESM::FourCC<'O','N','A','M'>::value:
|
|
|
|
|
mActor = esm.getHString();
|
|
|
|
|
break;
|
|
|
|
|
case ESM::FourCC<'R','N','A','M'>::value:
|
|
|
|
|
mRace = esm.getHString();
|
|
|
|
|
break;
|
|
|
|
|
case ESM::FourCC<'C','N','A','M'>::value:
|
|
|
|
|
mClass = esm.getHString();
|
|
|
|
|
break;
|
|
|
|
|
case ESM::FourCC<'F','N','A','M'>::value:
|
|
|
|
|
{
|
|
|
|
|
mFaction = esm.getHString();
|
|
|
|
|
if (mFaction == "FFFF")
|
|
|
|
|
{
|
|
|
|
|
mFactionLess = true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ESM::FourCC<'A','N','A','M'>::value:
|
|
|
|
|
mCell = esm.getHString();
|
|
|
|
|
break;
|
|
|
|
|
case ESM::FourCC<'D','N','A','M'>::value:
|
|
|
|
|
mPcFaction = esm.getHString();
|
|
|
|
|
break;
|
|
|
|
|
case ESM::FourCC<'S','N','A','M'>::value:
|
|
|
|
|
mSound = esm.getHString();
|
|
|
|
|
break;
|
|
|
|
|
case ESM::FourCC<'N','A','M','E'>::value:
|
|
|
|
|
mResponse = esm.getHString();
|
|
|
|
|
break;
|
|
|
|
|
case ESM::FourCC<'S','C','V','R'>::value:
|
|
|
|
|
{
|
|
|
|
|
SelectStruct ss;
|
|
|
|
|
ss.mSelectRule = esm.getHString();
|
|
|
|
|
ss.mValue.read(esm, Variant::Format_Info);
|
|
|
|
|
mSelects.push_back(ss);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ESM::FourCC<'B','N','A','M'>::value:
|
|
|
|
|
mResultScript = esm.getHString();
|
|
|
|
|
break;
|
|
|
|
|
case ESM::FourCC<'Q','S','T','N'>::value:
|
|
|
|
|
mQuestStatus = QS_Name;
|
|
|
|
|
esm.skipRecord();
|
|
|
|
|
break;
|
|
|
|
|
case ESM::FourCC<'Q','S','T','F'>::value:
|
|
|
|
|
mQuestStatus = QS_Finished;
|
|
|
|
|
esm.skipRecord();
|
|
|
|
|
break;
|
|
|
|
|
case ESM::FourCC<'Q','S','T','R'>::value:
|
|
|
|
|
mQuestStatus = QS_Restart;
|
|
|
|
|
esm.skipRecord();
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
esm.fail("Unknown subrecord");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (subName.val == REC_BNAM)
|
|
|
|
|
{
|
|
|
|
|
mResultScript = esm.getHString();
|
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (subName.val == REC_QSTN)
|
|
|
|
|
mQuestStatus = QS_Name;
|
|
|
|
|
else if (subName.val == REC_QSTF)
|
|
|
|
|
mQuestStatus = QS_Finished;
|
|
|
|
|
else if (subName.val == REC_QSTR)
|
|
|
|
|
mQuestStatus = QS_Restart;
|
|
|
|
|
else if (subName.val == REC_DELE)
|
|
|
|
|
mQuestStatus = QS_Deleted;
|
|
|
|
|
else
|
|
|
|
|
esm.fail(
|
|
|
|
|
"Don't know what to do with " + subName.toString()
|
|
|
|
|
+ " in INFO " + mId);
|
|
|
|
|
|
|
|
|
|
if (mQuestStatus != QS_None)
|
|
|
|
|
// Skip rest of record
|
|
|
|
|
esm.skipRecord();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DialInfo::save(ESMWriter &esm) const
|
|
|
|
@ -158,8 +119,7 @@ namespace ESM
|
|
|
|
|
|
|
|
|
|
if (mIsDeleted)
|
|
|
|
|
{
|
|
|
|
|
esm.writeHNCString("NAME", mResponse);
|
|
|
|
|
writeDeleSubRecord(esm);
|
|
|
|
|
esm.writeHNCString("DELE", "");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -186,7 +146,6 @@ namespace ESM
|
|
|
|
|
case QS_Name: esm.writeHNT("QSTN",'\1'); break;
|
|
|
|
|
case QS_Finished: esm.writeHNT("QSTF", '\1'); break;
|
|
|
|
|
case QS_Restart: esm.writeHNT("QSTR", '\1'); break;
|
|
|
|
|
case QS_Deleted: esm.writeHNT("DELE", '\1'); break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|