From 1e92cab3e76b9b258ae813eb43f020ecba2da754 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 21 Jan 2015 23:35:09 +0100 Subject: [PATCH] ESSImport: read dialogue/journal records, not converted yet --- apps/essimporter/CMakeLists.txt | 5 ++ apps/essimporter/converter.hpp | 81 +++++++++++++++++++++++++++++++-- apps/essimporter/importdial.cpp | 13 ++++++ apps/essimporter/importdial.hpp | 20 ++++++++ apps/essimporter/importer.cpp | 10 +++- apps/essimporter/importgame.cpp | 13 ++++++ apps/essimporter/importgame.hpp | 33 ++++++++++++++ apps/essimporter/importinfo.cpp | 14 ++++++ apps/essimporter/importinfo.hpp | 24 ++++++++++ apps/essimporter/importjour.cpp | 13 ++++++ apps/essimporter/importjour.hpp | 25 ++++++++++ apps/essimporter/importques.cpp | 14 ++++++ apps/essimporter/importques.hpp | 28 ++++++++++++ components/esm/defs.hpp | 2 +- components/esm/loadnpcc.hpp | 17 ------- 15 files changed, 290 insertions(+), 22 deletions(-) create mode 100644 apps/essimporter/importdial.cpp create mode 100644 apps/essimporter/importdial.hpp create mode 100644 apps/essimporter/importgame.cpp create mode 100644 apps/essimporter/importgame.hpp create mode 100644 apps/essimporter/importinfo.cpp create mode 100644 apps/essimporter/importinfo.hpp create mode 100644 apps/essimporter/importjour.cpp create mode 100644 apps/essimporter/importjour.hpp create mode 100644 apps/essimporter/importques.cpp create mode 100644 apps/essimporter/importques.hpp diff --git a/apps/essimporter/CMakeLists.txt b/apps/essimporter/CMakeLists.txt index 8d1af714d7..70eaefe2c6 100644 --- a/apps/essimporter/CMakeLists.txt +++ b/apps/essimporter/CMakeLists.txt @@ -9,6 +9,11 @@ set(ESSIMPORTER_FILES importinventory.cpp importklst.cpp importcntc.cpp + importgame.cpp + importinfo.cpp + importdial.cpp + importques.cpp + importjour.cpp importercontext.cpp converter.cpp convertacdt.cpp diff --git a/apps/essimporter/converter.hpp b/apps/essimporter/converter.hpp index 9f6ad49dfe..4ca0e83864 100644 --- a/apps/essimporter/converter.hpp +++ b/apps/essimporter/converter.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "importcrec.hpp" #include "importcntc.hpp" @@ -19,6 +20,11 @@ #include "importercontext.hpp" #include "importcellref.hpp" #include "importklst.hpp" +#include "importgame.hpp" +#include "importinfo.hpp" +#include "importdial.hpp" +#include "importques.hpp" +#include "importjour.hpp" #include "convertacdt.hpp" #include "convertnpcc.hpp" @@ -86,16 +92,15 @@ class ConvertNPC : public Converter public: virtual void read(ESM::ESMReader &esm) { - // this is always the player ESM::NPC npc; std::string id = esm.getHNString("NAME"); npc.load(esm); if (id != "player") { - // this handles changes to the NPC struct, but since there is no index here + // TODO: + // this should handle changes to the NPC struct, but since there is no index here // it will apply to ALL instances of the class. seems to be the reason for the // "feature" in MW where changing AI settings of one guard will change it for all guards of that refID. - std::cerr << "non-player NPC record: " << id << std::endl; } else { @@ -110,6 +115,18 @@ public: } }; +class ConvertCREA : public Converter +{ +public: + virtual void read(ESM::ESMReader &esm) + { + // See comment in ConvertNPC + ESM::Creature creature; + std::string id = esm.getHNString("NAME"); + creature.load(esm); + } +}; + class ConvertGlobal : public DefaultConverter { public: @@ -350,6 +367,64 @@ private: std::multimap mFactionStolenItems; }; +/// Seen responses for a dialogue topic? +/// Each DIAL record is followed by a number of INFO records, I believe, just like in ESMs +/// Dialogue conversion problems (probably have to adjust OpenMW format) - +/// - Journal is stored in one continuous HTML markup rather than each entry separately with associated info ID. +/// - Seen dialogue responses only store the INFO id, rather than the fulltext. +/// - Quest stages only store the INFO id, rather than the journal entry fulltext. +class ConvertINFO : public Converter +{ +public: + virtual void read(ESM::ESMReader& esm) + { + INFO info; + info.load(esm); + } +}; + +class ConvertDIAL : public Converter +{ +public: + virtual void read(ESM::ESMReader& esm) + { + std::string id = esm.getHNString("NAME"); + DIAL dial; + dial.load(esm); + } +}; + +class ConvertQUES : public Converter +{ +public: + virtual void read(ESM::ESMReader& esm) + { + std::string id = esm.getHNString("NAME"); + QUES quest; + quest.load(esm); + } +}; + +class ConvertJOUR : public Converter +{ +public: + virtual void read(ESM::ESMReader& esm) + { + JOUR journal; + journal.load(esm); + } +}; + +class ConvertGAME : public Converter +{ +public: + virtual void read(ESM::ESMReader &esm) + { + GAME game; + game.load(esm); + } +}; + } #endif diff --git a/apps/essimporter/importdial.cpp b/apps/essimporter/importdial.cpp new file mode 100644 index 0000000000..228d00a5ae --- /dev/null +++ b/apps/essimporter/importdial.cpp @@ -0,0 +1,13 @@ +#include "importdial.hpp" + +#include + +namespace ESSImport +{ + + void DIAL::load(ESM::ESMReader &esm) + { + esm.getHNT(mIndex, "XIDX"); + } + +} diff --git a/apps/essimporter/importdial.hpp b/apps/essimporter/importdial.hpp new file mode 100644 index 0000000000..fe4b0c5b4c --- /dev/null +++ b/apps/essimporter/importdial.hpp @@ -0,0 +1,20 @@ +#ifndef OPENMW_ESSIMPORT_IMPORTDIAL_H +#define OPENMW_ESSIMPORT_IMPORTDIAL_H +namespace ESM +{ + struct ESMReader; +} + +namespace ESSImport +{ + + struct DIAL + { + int mIndex; // Journal index + + void load(ESM::ESMReader& esm); + }; + +} + +#endif diff --git a/apps/essimporter/importer.cpp b/apps/essimporter/importer.cpp index c2092ea4df..8603200da8 100644 --- a/apps/essimporter/importer.cpp +++ b/apps/essimporter/importer.cpp @@ -201,11 +201,14 @@ namespace ESSImport const unsigned int recFMAP = ESM::FourCC<'F','M','A','P'>::value; const unsigned int recKLST = ESM::FourCC<'K','L','S','T'>::value; const unsigned int recSTLN = ESM::FourCC<'S','T','L','N'>::value; + const unsigned int recGAME = ESM::FourCC<'G','A','M','E'>::value; + const unsigned int recJOUR = ESM::FourCC<'J','O','U','R'>::value; std::map > converters; converters[ESM::REC_GLOB] = boost::shared_ptr(new ConvertGlobal()); converters[ESM::REC_BOOK] = boost::shared_ptr(new ConvertBook()); converters[ESM::REC_NPC_] = boost::shared_ptr(new ConvertNPC()); + converters[ESM::REC_CREA] = boost::shared_ptr(new ConvertCREA()); converters[ESM::REC_NPCC] = boost::shared_ptr(new ConvertNPCC()); converters[ESM::REC_CREC] = boost::shared_ptr(new ConvertCREC()); converters[recREFR ] = boost::shared_ptr(new ConvertREFR()); @@ -213,6 +216,7 @@ namespace ESSImport converters[recFMAP ] = boost::shared_ptr(new ConvertFMAP()); converters[recKLST ] = boost::shared_ptr(new ConvertKLST()); converters[recSTLN ] = boost::shared_ptr(new ConvertSTLN()); + converters[recGAME ] = boost::shared_ptr(new ConvertGAME()); converters[ESM::REC_CELL] = boost::shared_ptr(new ConvertCell()); converters[ESM::REC_ALCH] = boost::shared_ptr(new DefaultConverter()); converters[ESM::REC_CLAS] = boost::shared_ptr(new ConvertClass()); @@ -226,6 +230,10 @@ namespace ESSImport converters[ESM::REC_LEVI] = boost::shared_ptr(new DefaultConverter()); converters[ESM::REC_CNTC] = boost::shared_ptr(new ConvertCNTC()); converters[ESM::REC_FACT] = boost::shared_ptr(new ConvertFACT()); + converters[ESM::REC_INFO] = boost::shared_ptr(new ConvertINFO()); + converters[ESM::REC_DIAL] = boost::shared_ptr(new ConvertDIAL()); + converters[ESM::REC_QUES] = boost::shared_ptr(new ConvertQUES()); + converters[recJOUR ] = boost::shared_ptr(new ConvertJOUR()); std::set unknownRecords; @@ -248,7 +256,7 @@ namespace ESSImport else { if (unknownRecords.insert(n.val).second) - std::cerr << "unknown record " << n.toString() << std::endl; + std::cerr << "unknown record " << n.toString() << " (0x" << std::hex << esm.getFileOffset() << ")" << std::endl; esm.skipRecord(); } diff --git a/apps/essimporter/importgame.cpp b/apps/essimporter/importgame.cpp new file mode 100644 index 0000000000..0b3a4f1a7f --- /dev/null +++ b/apps/essimporter/importgame.cpp @@ -0,0 +1,13 @@ +#include "importgame.hpp" + +#include + +namespace ESSImport +{ + +void GAME::load(ESM::ESMReader &esm) +{ + esm.getHNT(mGMDT, "GMDT"); +} + +} diff --git a/apps/essimporter/importgame.hpp b/apps/essimporter/importgame.hpp new file mode 100644 index 0000000000..7bb8143207 --- /dev/null +++ b/apps/essimporter/importgame.hpp @@ -0,0 +1,33 @@ +#ifndef OPENMW_ESSIMPORT_GAME_H +#define OPENMW_ESSIMPORT_GAME_H + +namespace ESM +{ + class ESMReader; +} + +namespace ESSImport +{ + + /// Weather data + struct GAME + { + struct GMDT + { + char mCellName[64]; + int mFogColour; + float mFogDensity; + int mCurrentWeather, mNextWeather; + int mWeatherTransition; // 0-100 transition between weathers, top 3 bytes may be garbage + float mTimeOfNextTransition; // weather changes when gamehour == timeOfNextTransition + int masserPhase, secundaPhase; // top 3 bytes may be garbage + }; + + GMDT mGMDT; + + void load(ESM::ESMReader& esm); + }; + +} + +#endif diff --git a/apps/essimporter/importinfo.cpp b/apps/essimporter/importinfo.cpp new file mode 100644 index 0000000000..1131553709 --- /dev/null +++ b/apps/essimporter/importinfo.cpp @@ -0,0 +1,14 @@ +#include "importinfo.hpp" + +#include + +namespace ESSImport +{ + + void INFO::load(ESM::ESMReader &esm) + { + mInfo = esm.getHNString("INAM"); + mActorRefId = esm.getHNString("ACDT"); + } + +} diff --git a/apps/essimporter/importinfo.hpp b/apps/essimporter/importinfo.hpp new file mode 100644 index 0000000000..08f588f8d8 --- /dev/null +++ b/apps/essimporter/importinfo.hpp @@ -0,0 +1,24 @@ +#ifndef OPENMW_ESSIMPORT_IMPORTINFO_H +#define OPENMW_ESSIMPORT_IMPORTINFO_H + +#include + +namespace ESM +{ + struct ESMReader; +} + +namespace ESSImport +{ + + struct INFO + { + std::string mInfo; + std::string mActorRefId; + + void load(ESM::ESMReader& esm); + }; + +} + +#endif diff --git a/apps/essimporter/importjour.cpp b/apps/essimporter/importjour.cpp new file mode 100644 index 0000000000..e5d24e113c --- /dev/null +++ b/apps/essimporter/importjour.cpp @@ -0,0 +1,13 @@ +#include "importjour.hpp" + +#include + +namespace ESSImport +{ + + void JOUR::load(ESM::ESMReader &esm) + { + mText = esm.getHNString("NAME"); + } + +} diff --git a/apps/essimporter/importjour.hpp b/apps/essimporter/importjour.hpp new file mode 100644 index 0000000000..fe8775a93b --- /dev/null +++ b/apps/essimporter/importjour.hpp @@ -0,0 +1,25 @@ +#ifndef OPENMW_ESSIMPORT_IMPORTJOUR_H +#define OPENMW_ESSIMPORT_IMPORTJOUR_H + +#include + +namespace ESM +{ + struct ESMReader; +} + +namespace ESSImport +{ + + /// Journal + struct JOUR + { + // The entire journal, in HTML + std::string mText; + + void load(ESM::ESMReader& esm); + }; + +} + +#endif diff --git a/apps/essimporter/importques.cpp b/apps/essimporter/importques.cpp new file mode 100644 index 0000000000..78b779e439 --- /dev/null +++ b/apps/essimporter/importques.cpp @@ -0,0 +1,14 @@ +#include "importques.hpp" + +#include + +namespace ESSImport +{ + + void QUES::load(ESM::ESMReader &esm) + { + while (esm.isNextSub("DATA")) + mInfo.push_back(esm.getHString()); + } + +} diff --git a/apps/essimporter/importques.hpp b/apps/essimporter/importques.hpp new file mode 100644 index 0000000000..d7e718b928 --- /dev/null +++ b/apps/essimporter/importques.hpp @@ -0,0 +1,28 @@ +#ifndef OPENMW_ESSIMPORT_IMPORTQUES_H +#define OPENMW_ESSIMPORT_IMPORTQUES_H + +#include +#include + +namespace ESM +{ + struct ESMReader; +} + +namespace ESSImport +{ + + /// State for a quest + /// Presumably this record only exists when Tribunal is installed, + /// since pre-Tribunal there weren't any quest names in the data files. + struct QUES + { + std::string mName; // NAME, should be assigned from outside as usual + std::vector mInfo; // list of journal entries for the quest + + void load(ESM::ESMReader& esm); + }; + +} + +#endif diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index fe45d69149..effe9a3f18 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -97,7 +97,7 @@ enum RecNameInts // format 0 - saved games REC_SAVE = 0x45564153, - REC_JOUR = 0x524f55a4, + REC_JOUR = 0x524f55a4, // TODO: this is actually "\nOUR" rather than "JOUR", fix REC_QUES = 0x53455551, REC_GSCR = 0x52435347, REC_PLAY = 0x59414c50, diff --git a/components/esm/loadnpcc.hpp b/components/esm/loadnpcc.hpp index 6c087fd017..6b3cd533f4 100644 --- a/components/esm/loadnpcc.hpp +++ b/components/esm/loadnpcc.hpp @@ -20,24 +20,7 @@ class ESMWriter; * SCPT records do not define new scripts, but assign values to the * variables of existing ones. * - * STLN - stolen items, ONAM is the owner - * - * GAME - weather data - * struct GMDT - { - char mCellName[64]; - int mFogColour; - float mFogDensity; - int mCurrentWeather, mNextWeather; - int mWeatherTransition; // 0-100 transition between weathers, top 3 bytes may be garbage - float mTimeOfNextTransition; // weather changes when gamehour == timeOfNextTransition - int masserPhase, secundaPhase; // top 3 bytes may be garbage - }; - * * VFXM, SPLM - no clue - * KLST - kill counter - * - * PCDT - seems to contain a lot of DNAMs, strings? * * FMAP - MAPH and MAPD, global map image. *