ESSImport: read dialogue/journal records, not converted yet

openmw-35
scrawl 9 years ago
parent acf8461841
commit 1e92cab3e7

@ -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

@ -12,6 +12,7 @@
#include <components/esm/loadfact.hpp>
#include <components/esm/dialoguestate.hpp>
#include <components/esm/custommarkerstate.hpp>
#include <components/esm/loadcrea.hpp>
#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<ESM::Global>
{
public:
@ -350,6 +367,64 @@ private:
std::multimap<std::string, std::string> 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

@ -0,0 +1,13 @@
#include "importdial.hpp"
#include <components/esm/esmreader.hpp>
namespace ESSImport
{
void DIAL::load(ESM::ESMReader &esm)
{
esm.getHNT(mIndex, "XIDX");
}
}

@ -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

@ -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<unsigned int, boost::shared_ptr<Converter> > converters;
converters[ESM::REC_GLOB] = boost::shared_ptr<Converter>(new ConvertGlobal());
converters[ESM::REC_BOOK] = boost::shared_ptr<Converter>(new ConvertBook());
converters[ESM::REC_NPC_] = boost::shared_ptr<Converter>(new ConvertNPC());
converters[ESM::REC_CREA] = boost::shared_ptr<Converter>(new ConvertCREA());
converters[ESM::REC_NPCC] = boost::shared_ptr<Converter>(new ConvertNPCC());
converters[ESM::REC_CREC] = boost::shared_ptr<Converter>(new ConvertCREC());
converters[recREFR ] = boost::shared_ptr<Converter>(new ConvertREFR());
@ -213,6 +216,7 @@ namespace ESSImport
converters[recFMAP ] = boost::shared_ptr<Converter>(new ConvertFMAP());
converters[recKLST ] = boost::shared_ptr<Converter>(new ConvertKLST());
converters[recSTLN ] = boost::shared_ptr<Converter>(new ConvertSTLN());
converters[recGAME ] = boost::shared_ptr<Converter>(new ConvertGAME());
converters[ESM::REC_CELL] = boost::shared_ptr<Converter>(new ConvertCell());
converters[ESM::REC_ALCH] = boost::shared_ptr<Converter>(new DefaultConverter<ESM::Potion>());
converters[ESM::REC_CLAS] = boost::shared_ptr<Converter>(new ConvertClass());
@ -226,6 +230,10 @@ namespace ESSImport
converters[ESM::REC_LEVI] = boost::shared_ptr<Converter>(new DefaultConverter<ESM::ItemLevList>());
converters[ESM::REC_CNTC] = boost::shared_ptr<Converter>(new ConvertCNTC());
converters[ESM::REC_FACT] = boost::shared_ptr<Converter>(new ConvertFACT());
converters[ESM::REC_INFO] = boost::shared_ptr<Converter>(new ConvertINFO());
converters[ESM::REC_DIAL] = boost::shared_ptr<Converter>(new ConvertDIAL());
converters[ESM::REC_QUES] = boost::shared_ptr<Converter>(new ConvertQUES());
converters[recJOUR ] = boost::shared_ptr<Converter>(new ConvertJOUR());
std::set<unsigned int> 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();
}

@ -0,0 +1,13 @@
#include "importgame.hpp"
#include <components/esm/esmreader.hpp>
namespace ESSImport
{
void GAME::load(ESM::ESMReader &esm)
{
esm.getHNT(mGMDT, "GMDT");
}
}

@ -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

@ -0,0 +1,14 @@
#include "importinfo.hpp"
#include <components/esm/esmreader.hpp>
namespace ESSImport
{
void INFO::load(ESM::ESMReader &esm)
{
mInfo = esm.getHNString("INAM");
mActorRefId = esm.getHNString("ACDT");
}
}

@ -0,0 +1,24 @@
#ifndef OPENMW_ESSIMPORT_IMPORTINFO_H
#define OPENMW_ESSIMPORT_IMPORTINFO_H
#include <string>
namespace ESM
{
struct ESMReader;
}
namespace ESSImport
{
struct INFO
{
std::string mInfo;
std::string mActorRefId;
void load(ESM::ESMReader& esm);
};
}
#endif

@ -0,0 +1,13 @@
#include "importjour.hpp"
#include <components/esm/esmreader.hpp>
namespace ESSImport
{
void JOUR::load(ESM::ESMReader &esm)
{
mText = esm.getHNString("NAME");
}
}

@ -0,0 +1,25 @@
#ifndef OPENMW_ESSIMPORT_IMPORTJOUR_H
#define OPENMW_ESSIMPORT_IMPORTJOUR_H
#include <string>
namespace ESM
{
struct ESMReader;
}
namespace ESSImport
{
/// Journal
struct JOUR
{
// The entire journal, in HTML
std::string mText;
void load(ESM::ESMReader& esm);
};
}
#endif

@ -0,0 +1,14 @@
#include "importques.hpp"
#include <components/esm/esmreader.hpp>
namespace ESSImport
{
void QUES::load(ESM::ESMReader &esm)
{
while (esm.isNextSub("DATA"))
mInfo.push_back(esm.getHString());
}
}

@ -0,0 +1,28 @@
#ifndef OPENMW_ESSIMPORT_IMPORTQUES_H
#define OPENMW_ESSIMPORT_IMPORTQUES_H
#include <string>
#include <vector>
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<std::string> mInfo; // list of journal entries for the quest
void load(ESM::ESMReader& esm);
};
}
#endif

@ -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,

@ -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.
*

Loading…
Cancel
Save