|
|
|
#include "loadinfo.hpp"
|
|
|
|
|
|
|
|
#include "esm_reader.hpp"
|
|
|
|
#include "esm_writer.hpp"
|
|
|
|
|
|
|
|
namespace ESM
|
|
|
|
{
|
|
|
|
|
|
|
|
void DialInfo::load(ESMReader &esm)
|
|
|
|
{
|
|
|
|
mSelfId = esm.getHNString("INAM");
|
|
|
|
mPrev = esm.getHNString("PNAM");
|
|
|
|
mNext = esm.getHNString("NNAM");
|
|
|
|
|
|
|
|
// Not present if deleted
|
|
|
|
if (esm.isNextSub("DATA")) {
|
|
|
|
esm.getHT(mData, 12);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
mFactionLess = false;
|
|
|
|
if (subName.val == REC_FNAM)
|
|
|
|
{
|
|
|
|
mNpcFaction = esm.getHString();
|
|
|
|
if (mNpcFaction == "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();
|
|
|
|
esm.isEmptyOrGetName();
|
|
|
|
|
|
|
|
if (subName.val == REC_INTV)
|
|
|
|
{
|
|
|
|
ss.mType = VT_Int;
|
|
|
|
esm.getHT(ss.mI);
|
|
|
|
}
|
|
|
|
else if (subName.val == REC_FLTV)
|
|
|
|
{
|
|
|
|
ss.mType = VT_Float;
|
|
|
|
esm.getHT(ss.mF);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
esm.fail(
|
|
|
|
"INFO.SCVR must precede INTV or FLTV, not "
|
|
|
|
+ subName.toString());
|
|
|
|
|
|
|
|
mSelects.push_back(ss);
|
|
|
|
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (subName.val == REC_BNAM)
|
|
|
|
{
|
|
|
|
mResultScript = esm.getHString();
|
|
|
|
if (esm.isEmptyOrGetName())
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mQuestStatus = QS_None;
|
|
|
|
|
|
|
|
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 " + mSelfId);
|
|
|
|
|
|
|
|
if (mQuestStatus != QS_None)
|
|
|
|
// Skip rest of record
|
|
|
|
esm.skipRecord();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DialInfo::save(ESMWriter &esm)
|
|
|
|
{
|
|
|
|
esm.writeHNCString("INAM", mSelfId);
|
|
|
|
esm.writeHNCString("PNAM", mPrev);
|
|
|
|
esm.writeHNCString("NNAM", mNext);
|
|
|
|
esm.writeHNT("DATA", mData, 12);
|
|
|
|
esm.writeHNOCString("ONAM", mActor);
|
|
|
|
esm.writeHNOCString("RNAM", mRace);
|
|
|
|
esm.writeHNOCString("CNAM", mClass);
|
|
|
|
esm.writeHNOCString("FNAM", mNpcFaction);
|
|
|
|
esm.writeHNOCString("ANAM", mCell);
|
|
|
|
esm.writeHNOCString("DNAM", mPcFaction);
|
|
|
|
esm.writeHNOCString("SNAM", mSound);
|
|
|
|
esm.writeHNOString("NAME", mResponse);
|
|
|
|
|
|
|
|
for (std::vector<SelectStruct>::iterator it = mSelects.begin(); it != mSelects.end(); ++it)
|
|
|
|
{
|
|
|
|
esm.writeHNString("SCVR", it->mSelectRule);
|
|
|
|
switch(it->mType)
|
|
|
|
{
|
|
|
|
case VT_Int: esm.writeHNT("INTV", it->mI); break;
|
|
|
|
case VT_Float: esm.writeHNT("FLTV", it->mF); break;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|