|
|
|
@ -9,169 +9,173 @@ namespace ESM
|
|
|
|
|
{
|
|
|
|
|
unsigned int DialInfo::sRecordId = REC_INFO;
|
|
|
|
|
|
|
|
|
|
void DialInfo::load(ESMReader &esm)
|
|
|
|
|
{
|
|
|
|
|
mQuestStatus = QS_None;
|
|
|
|
|
mFactionLess = false;
|
|
|
|
|
|
|
|
|
|
mPrev = esm.getHNString("PNAM");
|
|
|
|
|
mNext = esm.getHNString("NNAM");
|
|
|
|
|
DialInfo::DialInfo()
|
|
|
|
|
: mIsDeleted(false)
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
// 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"))
|
|
|
|
|
void DialInfo::load(ESMReader &esm)
|
|
|
|
|
{
|
|
|
|
|
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.
|
|
|
|
|
mQuestStatus = QS_None;
|
|
|
|
|
mFactionLess = false;
|
|
|
|
|
|
|
|
|
|
// 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();
|
|
|
|
|
mPrev = esm.getHNString("PNAM");
|
|
|
|
|
mNext = esm.getHNString("NNAM");
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
// Since there's no way to mark selects as "deleted", we have to clear the SelectStructs from all previous loadings
|
|
|
|
|
mSelects.clear();
|
|
|
|
|
|
|
|
|
|
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())
|
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
SelectStruct ss;
|
|
|
|
|
|
|
|
|
|
ss.mSelectRule = esm.getHString();
|
|
|
|
|
|
|
|
|
|
ss.mValue.read (esm, Variant::Format_Info);
|
|
|
|
|
|
|
|
|
|
mSelects.push_back(ss);
|
|
|
|
|
|
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
esm.getSubNameIs("DATA");
|
|
|
|
|
esm.getHT(mData, 12);
|
|
|
|
|
|
|
|
|
|
if (subName.val == REC_BNAM)
|
|
|
|
|
{
|
|
|
|
|
mResultScript = esm.getHString();
|
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
|
if (!esm.hasMoreSubs())
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
esm.writeHNCString("PNAM", mPrev);
|
|
|
|
|
esm.writeHNCString("NNAM", mNext);
|
|
|
|
|
if (mIsDeleted)
|
|
|
|
|
{
|
|
|
|
|
esm.writeHNCString("NAME", mResponse);
|
|
|
|
|
writeDeleSubRecord(esm);
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
SelectStruct ss;
|
|
|
|
|
|
|
|
|
|
ss.mSelectRule = esm.getHString();
|
|
|
|
|
|
|
|
|
|
ss.mValue.read (esm, Variant::Format_Info);
|
|
|
|
|
|
|
|
|
|
mSelects.push_back(ss);
|
|
|
|
|
|
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
esm.writeHNT("DATA", mData, 12);
|
|
|
|
|
esm.writeHNOCString("ONAM", mActor);
|
|
|
|
|
esm.writeHNOCString("RNAM", mRace);
|
|
|
|
|
esm.writeHNOCString("CNAM", mClass);
|
|
|
|
|
esm.writeHNOCString("FNAM", mFaction);
|
|
|
|
|
esm.writeHNOCString("ANAM", mCell);
|
|
|
|
|
esm.writeHNOCString("DNAM", mPcFaction);
|
|
|
|
|
esm.writeHNOCString("SNAM", mSound);
|
|
|
|
|
esm.writeHNOString("NAME", mResponse);
|
|
|
|
|
|
|
|
|
|
for (std::vector<SelectStruct>::const_iterator it = mSelects.begin(); it != mSelects.end(); ++it)
|
|
|
|
|
void DialInfo::save(ESMWriter &esm) const
|
|
|
|
|
{
|
|
|
|
|
esm.writeHNString("SCVR", it->mSelectRule);
|
|
|
|
|
it->mValue.write (esm, Variant::Format_Info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
esm.writeHNOString("BNAM", mResultScript);
|
|
|
|
|
|
|
|
|
|
switch(mQuestStatus)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
esm.writeHNCString("PNAM", mPrev);
|
|
|
|
|
esm.writeHNCString("NNAM", mNext);
|
|
|
|
|
if (mIsDeleted)
|
|
|
|
|
{
|
|
|
|
|
esm.writeHNCString("NAME", mResponse);
|
|
|
|
|
writeDeleSubRecord(esm);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
esm.writeHNT("DATA", mData, 12);
|
|
|
|
|
esm.writeHNOCString("ONAM", mActor);
|
|
|
|
|
esm.writeHNOCString("RNAM", mRace);
|
|
|
|
|
esm.writeHNOCString("CNAM", mClass);
|
|
|
|
|
esm.writeHNOCString("FNAM", mFaction);
|
|
|
|
|
esm.writeHNOCString("ANAM", mCell);
|
|
|
|
|
esm.writeHNOCString("DNAM", mPcFaction);
|
|
|
|
|
esm.writeHNOCString("SNAM", mSound);
|
|
|
|
|
esm.writeHNOString("NAME", mResponse);
|
|
|
|
|
|
|
|
|
|
for (std::vector<SelectStruct>::const_iterator it = mSelects.begin(); it != mSelects.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
esm.writeHNString("SCVR", it->mSelectRule);
|
|
|
|
|
it->mValue.write (esm, Variant::Format_Info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
esm.writeHNOString("BNAM", mResultScript);
|
|
|
|
|
|
|
|
|
|
switch(mQuestStatus)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DialInfo::blank()
|
|
|
|
|
{
|
|
|
|
|