diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index e4de63dd47..38fddd6b92 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -112,14 +112,11 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss) case '5': oper_str = ">="; break; } - std::string value_str = "??"; - if (ss.mType == ESM::VT_Int) - value_str = str(boost::format("%d") % ss.mI); - else if (ss.mType == ESM::VT_Float) - value_str = str(boost::format("%f") % ss.mF); + std::ostringstream stream; + stream << ss.mValue; std::string result = str(boost::format("%-12s %-32s %2s %s") - % type_str % func_str % oper_str % value_str); + % type_str % func_str % oper_str % stream.str()); return result; } diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 9cc528a118..9d705f6bec 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -31,14 +31,13 @@ namespace template bool selectCompareImp (const ESM::DialInfo::SelectStruct& select, T value1) { - if (select.mType==ESM::VT_Short || select.mType==ESM::VT_Int || - select.mType==ESM::VT_Long) + if (select.mValue.getType()==ESM::VT_Int) { - return selectCompareImp (select.mSelectRule[4], value1, select.mI); + return selectCompareImp (select.mSelectRule[4], value1, select.mValue.getInteger()); } - else if (select.mType==ESM::VT_Float) + else if (select.mValue.getType()==ESM::VT_Float) { - return selectCompareImp (select.mSelectRule[4], value1, select.mF); + return selectCompareImp (select.mSelectRule[4], value1, select.mValue.getFloat()); } else throw std::runtime_error ( diff --git a/components/esm/loadinfo.cpp b/components/esm/loadinfo.cpp index f237cf7808..90f8fcf35b 100644 --- a/components/esm/loadinfo.cpp +++ b/components/esm/loadinfo.cpp @@ -84,22 +84,8 @@ void DialInfo::load(ESMReader &esm) 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()); + + ss.mValue.read (esm, Variant::Format_Info); mSelects.push_back(ss); @@ -152,16 +138,11 @@ void DialInfo::save(ESMWriter &esm) for (std::vector::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; - } + it->mValue.write (esm, Variant::Format_Info); } esm.writeHNOString("BNAM", mResultScript); - + switch(mQuestStatus) { case QS_Name: esm.writeHNT("QSTN",'\1'); break; diff --git a/components/esm/loadinfo.hpp b/components/esm/loadinfo.hpp index ca08c3b55b..2361ed9eb5 100644 --- a/components/esm/loadinfo.hpp +++ b/components/esm/loadinfo.hpp @@ -13,8 +13,6 @@ namespace ESM class ESMReader; class ESMWriter; -// NOT DONE - /* * Dialogue information. A series of these follow after DIAL records, * and form a linked list of dialogue items. @@ -44,9 +42,7 @@ struct DialInfo struct SelectStruct { std::string mSelectRule; // This has a complicated format - float mF; // Only one of 'f' or 'i' is used - int mI; - VarType mType; + Variant mValue; }; // Journal quest indices (introduced with the quest system in Tribunal) @@ -94,8 +90,7 @@ struct DialInfo REC_SNAM = 0x4d414e53, REC_NAME = 0x454d414e, REC_SCVR = 0x52564353, - REC_INTV = 0x56544e49, - REC_FLTV = 0x56544c46, + REC_BNAM = 0x4d414e42, REC_QSTN = 0x4e545351, REC_QSTF = 0x46545351, @@ -107,42 +102,5 @@ struct DialInfo void save(ESMWriter &esm); }; -/* - Some old and unused D code and comments, that might be useful later: - -------- - - // We only need to put each item in ONE list. For if your NPC - // matches this response, then it must match ALL criteria, thus it - // will have to look up itself in all the lists. I think the order - // is well optimized in making the lists as small as possible. - if(this.actor.index != -1) actorDial[this.actor][parent]++; - else if(cell != "") cellDial[cell][parent]++; - else if(this.Class != -1) classDial[this.Class][parent]++; - else if(this.npcFaction != -1) - factionDial[this.npcFaction][parent]++; - else if(this.race != -1) raceDial[this.race][parent]++; - else allDial[parent]++; // Lists dialogues that might - // apply to all npcs. - */ - -// List of dialogue topics (and greetings, voices, etc.) that -// reference other objects. Eg. raceDial is indexed by the indices of -// all races referenced. The value of raceDial is a new AA, which is -// basically used as a map (the int value is just a count and isn't -// used for anything important.) The indices (or elements of the map) -// are the dialogues that reference the given race. I use an AA -// instead of a list or array, since each dialogue can be added lots -// of times. - -/* -int allDial[Dialogue*]; -int classDial[int][Dialogue*]; -int factionDial[int][Dialogue*]; -int actorDial[Item][Dialogue*]; -// If I look up cells on cell load, I don't have to resolve these -// names into anything! -int cellDial[char[]][Dialogue*]; -int raceDial[int][Dialogue*]; -*/ } #endif diff --git a/components/esm/variant.cpp b/components/esm/variant.cpp index 98786c20e3..d25072e548 100644 --- a/components/esm/variant.cpp +++ b/components/esm/variant.cpp @@ -79,7 +79,7 @@ void ESM::Variant::read (ESMReader& esm, Format format) else esm.fail ("illegal global variable type " + typeId); } - else // GMST + else if (format==Format_Gmst) { if (!esm.hasMoreSubs()) { @@ -106,6 +106,22 @@ void ESM::Variant::read (ESMReader& esm, Format format) esm.fail ("invalid subrecord: " + name.toString()); } } + else // info + { + esm.getSubName(); + NAME name = esm.retSubName(); + + if (name=="INTV") + { + type = VT_Int; + } + else if (name=="FLTV") + { + type = VT_Float; + } + else + esm.fail ("invalid subrecord: " + name.toString()); + } setType (type); @@ -125,6 +141,9 @@ void ESM::Variant::write (ESMWriter& esm, Format format) const if (format==Format_Global) throw std::runtime_error ("can not serialise variant of type none to global format"); + if (format==Format_Info) + throw std::runtime_error ("can not serialise variant of type none to info format"); + // nothing to do here for GMST format } else diff --git a/components/esm/variant.hpp b/components/esm/variant.hpp index b78d647a82..8c5f3b3d47 100644 --- a/components/esm/variant.hpp +++ b/components/esm/variant.hpp @@ -32,7 +32,8 @@ namespace ESM enum Format { Format_Global, - Format_Gmst + Format_Gmst, + Format_Info }; Variant(); diff --git a/components/esm/variantimp.cpp b/components/esm/variantimp.cpp index 1b8cf4f875..160402aa4b 100644 --- a/components/esm/variantimp.cpp +++ b/components/esm/variantimp.cpp @@ -78,6 +78,9 @@ void ESM::VariantStringData::read (ESMReader& esm, Variant::Format format, VarTy if (format==Variant::Format_Global) esm.fail ("global variables of type string not supported"); + if (format==Variant::Format_Info) + esm.fail ("info variables of type string not supported"); + // GMST mValue = esm.getHString(); } @@ -90,6 +93,9 @@ void ESM::VariantStringData::write (ESMWriter& esm, Variant::Format format, VarT if (format==Variant::Format_Global) throw std::runtime_error ("global variables of type string not supported"); + if (format==Variant::Format_Info) + throw std::runtime_error ("info variables of type string not supported"); + // GMST esm.writeHNString ("STRV", mValue); } @@ -154,10 +160,16 @@ void ESM::VariantIntegerData::read (ESMReader& esm, Variant::Format format, VarT else esm.fail ("unsupported global variable integer type"); } - else // GMST + else if (format==Variant::Format_Gmst || format==Variant::Format_Info) { if (type!=VT_Int) - esm.fail ("unsupported gmst variable integer type"); + { + std::ostringstream stream; + stream + << "unsupported " <<(format==Variant::Format_Gmst ? "gmst" : "info") + << " variable integer type"; + esm.fail (stream.str()); + } esm.getHT (mValue); } @@ -179,10 +191,16 @@ void ESM::VariantIntegerData::write (ESMWriter& esm, Variant::Format format, Var else throw std::runtime_error ("unsupported global variable integer type"); } - else // GMST + else if (format==Variant::Format_Gmst || format==Variant::Format_Info) { if (type==VT_Int) - throw std::runtime_error ("unsupported global variable integer type"); + { + std::ostringstream stream; + stream + << "unsupported " <<(format==Variant::Format_Gmst ? "gmst" : "info") + << " variable integer type"; + throw std::runtime_error (stream.str()); + } esm.writeHNT ("INTV", mValue); } @@ -234,7 +252,7 @@ void ESM::VariantFloatData::read (ESMReader& esm, Variant::Format format, VarTyp { esm.getHNT (mValue, "FLTV"); } - else // GMST + else if (format==Variant::Format_Gmst || format==Variant::Format_Info) { esm.getHT (mValue); } @@ -250,9 +268,9 @@ void ESM::VariantFloatData::write (ESMWriter& esm, Variant::Format format, VarTy esm.writeHNString ("FNAM", "f"); esm.writeHNT ("FLTV", mValue); } - else // GMST + else if (format==Variant::Format_Gmst || format==Variant::Format_Info) { - esm.writeHNT ("INTV", mValue); + esm.writeHNT ("FLTV", mValue); } }