Extended the esmtool a bit and prepared all records for saving.

actorid
Alexander "Ace" Olofsson 13 years ago
parent 47013799ea
commit 0fd48c4229

@ -1,8 +1,10 @@
#include <iostream>
#include <list>
#include <boost/program_options.hpp>
#include <components/esm/esm_reader.hpp>
#include <components/esm/esm_writer.hpp>
#include <components/esm/records.hpp>
#define ESMTOOL_VERSION 1.1
@ -16,19 +18,33 @@ namespace bpo = boost::program_options;
void printRaw(ESMReader &esm);
void loadCell(Cell &cell, ESMReader &esm, bool quiet);
struct ESMData
{
std::string author;
std::string description;
ESMReader::MasterList masters;
std::list<Record*> records;
};
// Based on the legacy struct
struct Arguments
{
unsigned int raw_given;
unsigned int quiet_given;
unsigned int loadcells_given;
std::string mode;
std::string encoding;
std::string filename;
std::string outname;
ESMData data;
};
bool parseOptions (int argc, char** argv, Arguments &info)
{
bpo::options_description desc("Inspect and extract from Morrowind ES files (ESM, ESP, ESS)\nSyntax: esmtool [options] file \nAllowed options");
bpo::options_description desc("Inspect and extract from Morrowind ES files (ESM, ESP, ESS)\nSyntax: esmtool [options] mode infile [outfile]\nAllowed options");
desc.add_options()
("help,h", "print help message.")
@ -38,11 +54,11 @@ bool parseOptions (int argc, char** argv, Arguments &info)
("loadcells,C", "Browse through contents of all cells.")
( "encoding,e", bpo::value<std::string>(&(info.encoding))->
default_value("win1252"),
"Character encoding used in ESMTool:\n"
"\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n"
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
"\n\twin1252 - Western European (Latin) alphabet, used by default")
default_value("win1252"),
"Character encoding used in ESMTool:\n"
"\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n"
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
"\n\twin1252 - Western European (Latin) alphabet, used by default")
;
std::string finalText = "\nIf no option is given, the default action is to parse all records in the archive\nand display diagnostic information.";
@ -51,11 +67,12 @@ bool parseOptions (int argc, char** argv, Arguments &info)
bpo::options_description hidden("Hidden Options");
hidden.add_options()
( "mode,m", bpo::value<std::string>(), "esmtool mode")
( "input-file,i", bpo::value< vector<std::string> >(), "input file")
;
bpo::positional_options_description p;
p.add("input-file", -1);
p.add("mode", 1).add("input-file", 2);
// there might be a better way to do this
bpo::options_description all;
@ -77,6 +94,12 @@ bool parseOptions (int argc, char** argv, Arguments &info)
std::cout << "ESMTool version " << ESMTOOL_VERSION << std::endl;
return false;
}
if (!variables.count("mode"))
{
std::cout << "No mode specified!" << std::endl << std::endl
<< desc << finalText << std::endl;
return false;
}
if ( !variables.count("input-file") )
{
@ -86,14 +109,18 @@ bool parseOptions (int argc, char** argv, Arguments &info)
}
// handling gracefully the user adding multiple files
if (variables["input-file"].as< vector<std::string> >().size() > 1)
{
std::cout << "\nERROR: more than one ES file specified\n\n";
std::cout << desc << finalText << std::endl;
return false;
}
/* if (variables["input-file"].as< vector<std::string> >().size() > 1)
{
std::cout << "\nERROR: more than one ES file specified\n\n";
std::cout << desc << finalText << std::endl;
return false;
}*/
info.mode = variables["mode"].as<std::string>();
info.filename = variables["input-file"].as< vector<std::string> >()[0];
if (variables["input-file"].as< vector<std::string> >().size() > 1)
info.outname = variables["input-file"].as< vector<std::string> >()[1];
info.raw_given = variables.count ("raw");
info.quiet_given = variables.count ("quiet");
@ -122,288 +149,612 @@ bool parseOptions (int argc, char** argv, Arguments &info)
return true;
}
int load(Arguments& info);
int clone(Arguments& info);
int main(int argc, char**argv)
{
Arguments info;
if(!parseOptions (argc, argv, info))
return 1;
Arguments info;
if(!parseOptions (argc, argv, info))
return 1;
if (info.mode == "dump")
return load(info);
else if (info.mode == "clone")
return clone(info);
else
{
cout << "Invalid or no mode specified, dying horribly. Have a nice day." << endl;
return 1;
}
return 0;
}
ESMReader esm;
esm.setEncoding(info.encoding);
void loadCell(Cell &cell, ESMReader &esm, bool quiet)
{
// Skip back to the beginning of the reference list
cell.restore(esm);
string filename = info.filename;
cout << "\nFile: " << filename << endl;
// Loop through all the references
CellRef ref;
if(!quiet) cout << " References:\n";
while(cell.getNextRef(esm, ref))
{
if(quiet) continue;
try {
cout << " Refnum: " << ref.refnum << endl;
cout << " ID: '" << ref.refID << "'\n";
cout << " Owner: '" << ref.owner << "'\n";
cout << " INTV: " << ref.intv << " NAM9: " << ref.intv << endl;
}
}
if(info.raw_given)
void printRaw(ESMReader &esm)
{
while(esm.hasMoreRecs())
{
cout << "RAW file listing:\n";
NAME n = esm.getRecName();
cout << "Record: " << n.toString() << endl;
esm.getRecHeader();
while(esm.hasMoreSubs())
{
uint64_t offs = esm.getOffset();
esm.getSubName();
esm.skipHSub();
n = esm.retSubName();
cout << " " << n.toString() << " - " << esm.getSubSize()
<< " bytes @ 0x" << hex << offs << "\n";
}
}
}
esm.openRaw(filename);
int load(Arguments& info)
{
ESMReader esm;
esm.setEncoding(info.encoding);
printRaw(esm);
string filename = info.filename;
cout << "\nFile: " << filename << endl;
return 0;
}
std::list<int> skipped;
bool quiet = info.quiet_given;
bool loadCells = info.loadcells_given;
try {
esm.open(filename);
if(info.raw_given)
{
cout << "RAW file listing:\n";
cout << "Author: " << esm.getAuthor() << endl;
cout << "Description: " << esm.getDesc() << endl;
cout << "File format version: " << esm.getFVer() << endl;
cout << "Special flag: " << esm.getSpecial() << endl;
cout << "Masters:\n";
ESMReader::MasterList m = esm.getMasters();
for(unsigned int i=0;i<m.size();i++)
cout << " " << m[i].name << ", " << m[i].size << " bytes\n";
esm.openRaw(filename);
// Loop through all records
while(esm.hasMoreRecs())
{
NAME n = esm.getRecName();
esm.getRecHeader();
string id = esm.getHNOString("NAME");
if(!quiet)
cout << "\nRecord: " << n.toString()
<< " '" << id << "'\n";
switch(n.val)
printRaw(esm);
return 0;
}
bool quiet = (info.quiet_given || info.mode == "clone");
bool loadCells = (info.loadcells_given || info.mode == "clone");
bool save = (info.mode == "clone");
esm.open(filename);
info.data.author = esm.getAuthor();
info.data.description = esm.getDesc();
info.data.masters = esm.getMasters();
cout << "Author: " << esm.getAuthor() << endl;
cout << "Description: " << esm.getDesc() << endl;
cout << "File format version: " << esm.getFVer() << endl;
cout << "Special flag: " << esm.getSpecial() << endl;
cout << "Masters:\n";
ESMReader::MasterList m = esm.getMasters();
for(unsigned int i=0;i<m.size();i++)
cout << " " << m[i].name << ", " << m[i].size << " bytes\n";
// Loop through all records
while(esm.hasMoreRecs())
{
case REC_ACTI:
{
Activator ac;
ac.load(esm);
if(quiet) break;
cout << " Name: " << ac.name << endl;
cout << " Mesh: " << ac.model << endl;
cout << " Script: " << ac.script << endl;
break;
}
case REC_ALCH:
{
Potion p;
p.load(esm);
if(quiet) break;
cout << " Name: " << p.name << endl;
break;
}
case REC_APPA:
{
Apparatus p;
p.load(esm);
if(quiet) break;
cout << " Name: " << p.name << endl;
break;
}
case REC_ARMO:
{
Armor am;
am.load(esm);
if(quiet) break;
cout << " Name: " << am.name << endl;
cout << " Mesh: " << am.model << endl;
cout << " Icon: " << am.icon << endl;
cout << " Script: " << am.script << endl;
cout << " Enchantment: " << am.enchant << endl;
cout << " Type: " << am.data.type << endl;
cout << " Weight: " << am.data.weight << endl;
break;
}
case REC_BODY:
{
BodyPart bp;
bp.load(esm);
if(quiet) break;
cout << " Name: " << bp.name << endl;
cout << " Mesh: " << bp.model << endl;
break;
}
case REC_BOOK:
{
Book b;
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
cout << " Mesh: " << b.model << endl;
break;
}
case REC_BSGN:
{
BirthSign bs;
bs.load(esm);
if(quiet) break;
cout << " Name: " << bs.name << endl;
cout << " Texture: " << bs.texture << endl;
cout << " Description: " << bs.description << endl;
break;
}
case REC_CELL:
{
Cell b;
b.load(esm);
NAME n = esm.getRecName();
esm.getRecHeader();
string id = esm.getHNOString("NAME");
if(!quiet)
{
cout << "\nRecord: " << n.toString()
<< " '" << id << "'\n";
Record* rec = NULL;
switch(n.val)
{
case REC_ACTI:
{
rec = new Activator();
Activator& ac = *(Activator*)rec;
ac.load(esm);
if(quiet) break;
cout << " Name: " << ac.name << endl;
cout << " Mesh: " << ac.model << endl;
cout << " Script: " << ac.script << endl;
break;
}
case REC_ALCH:
{
rec = new Potion();
Potion& p = *(Potion*)rec;
p.load(esm);
if(quiet) break;
cout << " Name: " << p.name << endl;
break;
}
case REC_APPA:
{
rec = new Apparatus();
Apparatus& p = *(Apparatus*)rec;
p.load(esm);
if(quiet) break;
cout << " Name: " << p.name << endl;
break;
}
case REC_ARMO:
{
rec = new Armor();
Armor& am = *(Armor*)rec;
am.load(esm);
if(quiet) break;
cout << " Name: " << am.name << endl;
cout << " Mesh: " << am.model << endl;
cout << " Icon: " << am.icon << endl;
cout << " Script: " << am.script << endl;
cout << " Enchantment: " << am.enchant << endl;
cout << " Type: " << am.data.type << endl;
cout << " Weight: " << am.data.weight << endl;
break;
}
case REC_BODY:
{
rec = new BodyPart();
BodyPart& bp = *(BodyPart*)rec;
bp.load(esm);
if(quiet) break;
cout << " Name: " << bp.name << endl;
cout << " Mesh: " << bp.model << endl;
break;
}
case REC_BOOK:
{
rec = new Book();
Book& b = *(Book*)rec;
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
cout << " Mesh: " << b.model << endl;
break;
}
case REC_BSGN:
{
rec = new BirthSign();
BirthSign& bs = *(BirthSign*)rec;
bs.load(esm);
if(quiet) break;
cout << " Name: " << bs.name << endl;
cout << " Texture: " << bs.texture << endl;
cout << " Description: " << bs.description << endl;
break;
}
case REC_CELL:
{
rec = new Cell();
Cell& b = *(Cell*)rec;
b.load(esm);
if(!quiet)
{
cout << " Name: " << b.name << endl;
cout << " Region: " << b.region << endl;
}
if(loadCells)
loadCell(b, esm, quiet);
break;
}
case REC_CLAS:
{
rec = new Class();
Class& b = *(Class*)rec;
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
cout << " Description: " << b.description << endl;
break;
}
case REC_CLOT:
{
rec = new Clothing();
Clothing& b = *(Clothing*)rec;
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
break;
}
case REC_CONT:
{
rec = new Container();
Container& b = *(Container*)rec;
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
cout << " Region: " << b.region << endl;
}
if(loadCells)
loadCell(b, esm, quiet);
break;
}
case REC_CLAS:
{
Class b;
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
cout << " Description: " << b.description << endl;
break;
}
case REC_CLOT:
{
Clothing b;
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
break;
}
case REC_CONT:
{
Container b;
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
break;
}
case REC_CREA:
{
Creature b;
b.load(esm, id);
if(quiet) break;
cout << " Name: " << b.name << endl;
break;
}
case REC_DIAL:
{
Dialogue b;
b.load(esm);
break;
}
case REC_DOOR:
{
Door d;
d.load(esm);
if(quiet) break;
cout << " Name: " << d.name << endl;
cout << " Mesh: " << d.model << endl;
cout << " Script: " << d.script << endl;
cout << " OpenSound: " << d.openSound << endl;
cout << " CloseSound: " << d.closeSound << endl;
break;
}
case REC_ENCH:
{
Enchantment b;
b.load(esm);
break;
}
case REC_GMST:
{
GameSetting b;
b.id = id;
b.load(esm);
if(quiet) break;
cout << " Value: ";
if(b.type == VT_String)
cout << "'" << b.str << "' (string)";
else if(b.type == VT_Float)
cout << b.f << " (float)";
else if(b.type == VT_Int)
cout << b.i << " (int)";
cout << "\n Dirty: " << b.dirty << endl;
break;
}
case REC_INFO:
{
DialInfo p;
p.load(esm);
if(quiet) break;
cout << " Id: " << p.id << endl;
cout << " Text: " << p.response << endl;
break;
}
case REC_SOUN:
{
Sound d;
d.load(esm);
if(quiet) break;
cout << " Sound: " << d.sound << endl;
cout << " Volume: " << (int)d.data.volume << endl;
break;
}
case REC_SPEL:
{
Spell s;
s.load(esm);
if(quiet) break;
cout << " Name: " << s.name << endl;
break;
}
default:
esm.skipRecord();
if(quiet) break;
cout << " Skipping\n";
break;
}
case REC_CREA:
{
rec = new Creature();
Creature& b = *(Creature*)rec;
b.setID(id);
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
break;
}
case REC_DIAL:
{
rec = new Dialogue();
Dialogue& b = *(Dialogue*)rec;
b.load(esm);
break;
}
case REC_DOOR:
{
rec = new Door();
Door& d = *(Door*)rec;
d.load(esm);
if(quiet) break;
cout << " Name: " << d.name << endl;
cout << " Mesh: " << d.model << endl;
cout << " Script: " << d.script << endl;
cout << " OpenSound: " << d.openSound << endl;
cout << " CloseSound: " << d.closeSound << endl;
break;
}
case REC_ENCH:
{
rec = new Enchantment();
Enchantment& b = *(Enchantment*)rec;
b.load(esm);
break;
}
case REC_FACT:
{
rec = new Faction();
Faction& f = *(Faction*)rec;
f.load(esm);
if (quiet) break;
cout << " Name: " << f.name << endl
<< " Attr1: " << f.data.attribute1 << endl
<< " Attr2: " << f.data.attribute2 << endl
<< " Hidden: " << f.data.isHidden << endl;
break;
}
case REC_GLOB:
{
rec = new Global();
Global& g = *(Global*)rec;
g.load(esm);
break;
}
case REC_GMST:
{
rec = new GameSetting();
GameSetting& b = *(GameSetting*)rec;
b.id = id;
b.load(esm);
if(quiet) break;
cout << " Value: ";
if(b.type == VT_String)
cout << "'" << b.str << "' (string)";
else if(b.type == VT_Float)
cout << b.f << " (float)";
else if(b.type == VT_Int)
cout << b.i << " (int)";
cout << "\n Dirty: " << b.dirty << endl;
break;
}
case REC_INFO:
{
rec = new DialInfo();
DialInfo& p = *(DialInfo*)rec;
p.load(esm);
if(quiet) break;
cout << " Id: " << p.id << endl;
cout << " Text: " << p.response << endl;
break;
}
case REC_INGR:
{
rec = new Ingredient();
Ingredient& i = *(Ingredient*)rec;
i.load(esm);
if (quiet) break;
cout << " Name: " << i.name << endl
<< " Weight: " << i.data.weight << endl
<< " Value: " << i.data.value << endl;
break;
}
case REC_LAND:
{
rec = new Land();
Land& l = *(Land*)rec;
l.load(esm);
if (quiet) break;
cout << " Coords: [" << l.X << "," << l.Y << "]" << endl;
break;
}
case REC_LEVI:
{
rec = new ItemLevList();
ItemLevList& l = *(ItemLevList*)rec;
l.load(esm);
if (quiet) break;
cout << " Number of items: " << l.list.size() << endl;
break;
}
case REC_LEVC:
{
rec = new CreatureLevList();
CreatureLevList& l = *(CreatureLevList*)rec;
l.load(esm);
if (quiet) break;
cout << " Number of items: " << l.list.size() << endl;
break;
}
case REC_LIGH:
{
rec = new Light();
Light& l = *(Light*)rec;
l.load(esm);
if (quiet) break;
cout << " Name: " << l.name << endl
<< " Weight: " << l.data.weight << endl
<< " Value: " << l.data.value << endl;
}
case REC_LOCK:
{
rec = new Tool();
Tool& l = *(Tool*)rec;
l.load(esm);
if (quiet) break;
cout << " Name: " << l.name << endl
<< " Quality: " << l.data.quality << endl;
break;
}
case REC_LTEX:
{
rec = new LandTexture();
LandTexture& t = *(LandTexture*)rec;
t.load(esm);
if (quiet) break;
cout << " Id: " << t.id << endl
<< " Texture: " << t.texture << endl;
break;
}
case REC_MISC:
{
rec = new Miscellaneous();
Miscellaneous& m = *(Miscellaneous*)rec;
m.load(esm);
if (quiet) break;
cout << " Name: " << m.name << endl
<< " Value: " << m.data.value << endl;
break;
}
case REC_MGEF:
{
rec = new MagicEffect();
MagicEffect& m = *(MagicEffect*)rec;
m.load(esm);
if (quiet) break;
cout << " Index: " << m.index << endl
<< " " << (m.data.flags & MagicEffect::Negative ? "Negative" : "Positive") << endl;
break;
}
case REC_NPC_:
{
rec = new NPC();
NPC& n = *(NPC*)rec;
n.load(esm);
if (quiet) break;
cout << " Name: " << n.name << endl
<< " Race: " << n.race << endl;
break;
}
case REC_PGRD:
{
rec = new Pathgrid();
Pathgrid& p = *(Pathgrid*)rec;
p.load(esm);
if (quiet) break;
cout << " Cell: " << p.cell << endl
<< " Point count: " << p.points.size() << endl
<< " Edge count: " << p.edges.size() << endl;
break;
}
case REC_PROB:
{
rec = new Probe();
Probe& r = *(Probe*)rec;
r.load(esm);
if (quiet) break;
cout << " Name: " << r.name << endl
<< " Quality: " << r.data.quality << endl;
break;
}
case REC_RACE:
{
rec = new Race();
Race& r = *(Race*)rec;
r.load(esm);
if (quiet) break;
cout << " Name: " << r.name << endl
<< " Length: " << r.data.height.male << "m " << r.data.height.female << "f" << endl;
break;
}
case REC_REGN:
{
rec = new Region();
Region& r = *(Region*)rec;
r.load(esm);
if (quiet) break;
cout << " Name: " << r.name << endl;
break;
}
case REC_REPA:
{
rec = new Repair();
Repair& r = *(Repair*)rec;
r.load(esm);
if (quiet) break;
cout << " Name: " << r.name << endl
<< " Quality: " << r.data.quality << endl;
break;
}
case REC_SCPT:
{
rec = new Script();
Script& s = *(Script*)rec;
s.load(esm);
if (quiet) break;
cout << " Name: " << s.data.name.toString() << endl;
break;
}
case REC_SKIL:
{
rec = new Skill();
Skill& s = *(Skill*)rec;
s.load(esm);
if (quiet) break;
cout << " ID: " << s.index << endl
<< " Type: " << (s.data.specialization == 0 ? "Combat" : (s.data.specialization == 1 ? "Magic" : "Stealth")) << endl;
break;
}
case REC_SNDG:
{
rec = new SoundGenerator();
SoundGenerator& s = *(SoundGenerator*)rec;
s.load(esm);
if (quiet) break;
cout << " Creature: " << s.creature << endl
<< " Sound: " << s.sound << endl;
break;
}
case REC_SOUN:
{
rec = new Sound();
Sound& d = *(Sound*)rec;
d.load(esm);
if(quiet) break;
cout << " Sound: " << d.sound << endl;
cout << " Volume: " << (int)d.data.volume << endl;
break;
}
case REC_SPEL:
{
rec = new Spell();
Spell& s = *(Spell*)rec;
s.load(esm);
if(quiet) break;
cout << " Name: " << s.name << endl;
break;
}
case REC_STAT:
{
rec = new Static();
Static& s = *(Static*)rec;
s.load(esm);
if (quiet) break;
cout << " Model: " << s.model << endl;
break;
}
case REC_WEAP:
{
rec = new Weapon();
Weapon& w = *(Weapon*)rec;
w.load(esm);
if (quiet) break;
cout << " Name: " << w.name << endl
<< " Chop: " << w.data.chop[0] << "-" << w.data.chop[1] << endl
<< " Slash: " << w.data.slash[0] << "-" << w.data.slash[1] << endl
<< " Thrust: " << w.data.thrust[0] << "-" << w.data.thrust[1] << endl
<< " Value: " << w.data.value << endl;
break;
}
default:
if (find(skipped.begin(), skipped.end(), n.val) == skipped.end())
{
cout << "Skipping " << n.toString() << " records." << endl;
skipped.push_back(n.val);
}
esm.skipRecord();
if(quiet) break;
cout << " Skipping\n";
}
if (rec != NULL)
{
if (save)
info.data.records.push_back(rec);
else
delete rec;
}
}
}
} catch(exception &e)
} catch(exception &e)
{
cout << "\nERROR:\n\n " << e.what() << endl;
return 1;
cout << "\nERROR:\n\n " << e.what() << endl;
for (std::list<Record*>::iterator it = info.data.records.begin(); it != info.data.records.end();)
{
delete *it;
info.data.records.erase(it++);
}
return 1;
}
return 0;
return 0;
}
void loadCell(Cell &cell, ESMReader &esm, bool quiet)
#include <map>
int clone(Arguments& info)
{
// Skip back to the beginning of the reference list
cell.restore(esm);
if (info.outname.empty())
{
cout << "You need to specify an output name" << endl;
return 1;
}
if (load(info) != 0)
{
cout << "Failed to load, aborting." << endl;
return 1;
}
// Loop through all the references
CellRef ref;
if(!quiet) cout << " References:\n";
while(cell.getNextRef(esm, ref))
cout << "Loaded " << info.data.records.size() << " records:" << endl;
std::map<std::string, int> records;
for (std::list<Record*>::iterator it = info.data.records.begin(); it != info.data.records.end();)
{
if(quiet) continue;
Record* rec = *it;
NAME n;
n.val = rec->getName();
records[n.toString()]++;
cout << " Refnum: " << ref.refnum << endl;
cout << " ID: '" << ref.refID << "'\n";
cout << " Owner: '" << ref.owner << "'\n";
cout << " INTV: " << ref.intv << " NAM9: " << ref.intv << endl;
delete rec;
info.data.records.erase(it++);
}
}
void printRaw(ESMReader &esm)
{
while(esm.hasMoreRecs())
for (std::map<std::string,int>::iterator it = records.begin(); it != records.end(); ++it)
{
NAME n = esm.getRecName();
cout << "Record: " << n.toString() << endl;
esm.getRecHeader();
while(esm.hasMoreSubs())
{
uint64_t offs = esm.getOffset();
esm.getSubName();
esm.skipHSub();
n = esm.retSubName();
cout << " " << n.toString() << " - " << esm.getSubSize()
<< " bytes @ 0x" << hex << offs << "\n";
}
std::string n = it->first;
cout << n << ": " << it->second << " records." << endl;
}
return 0;
}

@ -1,4 +1,6 @@
#include "esm_writer.hpp"
#include <fstream>
#include <cstring>
namespace ESM
{
@ -15,22 +17,31 @@ void ESMWriter::setType(FileType type)
void ESMWriter::setAuthor(const std::string& auth)
{
strcpy(auth.c_str(), m_header.author, 32);
strncpy((char*)&m_header.author, auth.c_str(), 32);
}
void ESMWriter::setDescription(const std::string& desc)
{
strcpy(desc.c_str(), m_header.desc, 256);
strncpy((char*)&m_header.desc, desc.c_str(), 256);
}
void ESMWriter::save(const std::string& file)
{
std::ostream os(file, "wb");
save(os);
std::ofstream fs(file.c_str(), std::ios_base::out | std::ios_base::trunc);
save(fs);
fs.close();
}
void ESMWriter::save(std::ostream& file)
{
m_stream = &file;
startRecord("TES3");
writeT<int>(0);
writeT<int>(0);
endRecord();
// TODO: Saving
}
@ -39,6 +50,28 @@ void ESMWriter::close()
// TODO: Saving
}
void ESMWriter::startRecord(const std::string& name)
{
writeName(name);
RecordData rec;
rec.position = m_stream->tellp();
rec.size = 0;
m_records.push_back(rec);
writeT<int>(0);
}
void ESMWriter::endRecord()
{
std::streampos cur = m_stream->tellp();
RecordData rec = m_records.back();
m_records.pop_back();
m_stream->seekp(rec.position);
m_stream->write((char*)&rec.size, sizeof(int));
m_stream->seekp(cur);
}
void ESMWriter::writeHNString(const std::string& name, const std::string& data)
{
writeName(name);
@ -59,7 +92,10 @@ void ESMWriter::writeName(const std::string& name)
void ESMWriter::write(const char* data, int size)
{
m_stream.write(data, size);
if (!m_records.empty())
m_records.back().size += size;
m_stream->write(data, size);
}
}

@ -2,6 +2,7 @@
#define _ESM_WRITER_H
#include <iostream>
#include <vector>
#include <assert.h>
#include "esm_common.hpp"
@ -10,6 +11,12 @@ namespace ESM {
class ESMWriter
{
struct RecordData
{
std::streampos position;
int size;
};
public:
void setVersion(Version ver);
void setType(FileType type);
@ -68,13 +75,16 @@ public:
assert(sizeof(T) == size);
writeT(data);
}
void startRecord(const std::string& name);
void endRecord();
void writeHString(const std::string& data);
void writeName(const std::string& data);
void write(const char* data, int size);
private:
std::ostream m_stream;
std::vector<RecordData> m_records;
std::ostream* m_stream;
HEDRstruct m_header;
SaveData m_saveData;

@ -1,18 +1,21 @@
#ifndef _ESM_ACTI_H
#define _ESM_ACTI_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
namespace ESM
{
struct Activator
struct Activator : public Record
{
std::string name, script, model;
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_ACTI; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_ALCH_H
#define _ESM_ALCH_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
#include "defs.hpp"
@ -12,7 +13,7 @@ namespace ESM
* Alchemy item (potions)
*/
struct Potion
struct Potion : public Record
{
struct ALDTstruct
{
@ -27,6 +28,8 @@ struct Potion
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_ALCH; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_APPA_H
#define _ESM_APPA_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -11,7 +12,7 @@ namespace ESM
* Alchemist apparatus
*/
struct Apparatus
struct Apparatus : public Record
{
enum AppaType
{
@ -34,6 +35,8 @@ struct Apparatus
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_APPA; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_ARMO_H
#define _ESM_ARMO_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -54,7 +55,7 @@ struct PartReferenceList
void save(ESMWriter &esm);
};
struct Armor
struct Armor : public Record
{
enum Type
{
@ -85,6 +86,8 @@ struct Armor
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_ARMO; }
};
}
#endif

@ -1,13 +1,14 @@
#ifndef _ESM_BODY_H
#define _ESM_BODY_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
namespace ESM
{
struct BodyPart
struct BodyPart : public Record
{
enum MeshPart
{
@ -54,6 +55,8 @@ struct BodyPart
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_BODY; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_BOOK_H
#define _ESM_BOOK_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -11,7 +12,7 @@ namespace ESM
* Books, magic scrolls, notes and so on
*/
struct Book
struct Book : public Record
{
struct BKDTstruct
{
@ -24,6 +25,8 @@ struct Book
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_BOOK; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_BSGN_H
#define _ESM_BSGN_H
#include "record.hpp"
#include "defs.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -8,7 +9,7 @@
namespace ESM
{
struct BirthSign
struct BirthSign : public Record
{
std::string name, description, texture;
@ -17,6 +18,8 @@ struct BirthSign
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_BSGN; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_CELL_H
#define _ESM_CELL_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
#include "defs.hpp"
@ -84,7 +85,7 @@ public:
(using ESMReader::getContext()) and jumping back into place
whenever we need to load a given cell.
*/
struct Cell
struct Cell : public Record
{
enum Flags
{
@ -123,6 +124,8 @@ struct Cell
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_CELL; }
bool isExterior() const
{
return !(data.flags & Interior);

@ -1,6 +1,7 @@
#ifndef _ESM_CLAS_H
#define _ESM_CLAS_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -13,7 +14,7 @@ namespace ESM
// These flags tells us which items should be auto-calculated for this
// class
struct Class
struct Class : public Record
{
enum AutoCalc
{
@ -63,6 +64,8 @@ struct Class
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_CLAS; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_CLOT_H
#define _ESM_CLOT_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
#include "loadarmo.hpp"
@ -12,7 +13,7 @@ namespace ESM
* Clothing
*/
struct Clothing
struct Clothing : public Record
{
enum Type
{
@ -43,6 +44,8 @@ struct Clothing
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_CLOT; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_CONT_H
#define _ESM_CONT_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -25,7 +26,7 @@ struct InventoryList
void save(ESMWriter &esm);
};
struct Container
struct Container : public Record
{
enum Flags
{
@ -42,6 +43,8 @@ struct Container
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_CONT; }
};
}
#endif

@ -2,10 +2,13 @@
namespace ESM {
void Creature::load(ESMReader &esm, const std::string& id)
void Creature::setID(const std::string& id)
{
mId = id;
}
void Creature::load(ESMReader &esm)
{
model = esm.getHNString("MODL");
original = esm.getHNOString("CNAM");
name = esm.getHNOString("FNAM");

@ -1,6 +1,7 @@
#ifndef _ESM_CREA_H
#define _ESM_CREA_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
#include "loadcont.hpp"
@ -13,7 +14,7 @@ namespace ESM
*
*/
struct Creature
struct Creature : public Record
{
// Default is 0x48?
enum Flags
@ -64,8 +65,11 @@ struct Creature
std::string mId;
void load(ESMReader &esm, const std::string& id);
void setID(const std::string& id);
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_CREA; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_CREC_H
#define _ESM_CREC_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -10,29 +11,33 @@ namespace ESM {
*/
/// Changes a creature
struct LoadCREC
struct LoadCREC : public Record
{
void load(ESMReader &esm)
void load(ESMReader &esm)
{
esm.skipRecord();
}
void save(ESMWriter &esm)
void save(ESMWriter &esm)
{
}
int getName() { return REC_CREC; }
};
/// Changes an item list / container
struct LoadCNTC
struct LoadCNTC : public Record
{
void load(ESMReader &esm)
void load(ESMReader &esm)
{
esm.skipRecord();
}
void save(ESMWriter &esm)
void save(ESMWriter &esm)
{
}
int getName() { return REC_CNTC; }
};
}
#endif

@ -3,6 +3,7 @@
#include <vector>
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
#include "loadinfo.hpp"
@ -15,7 +16,7 @@ namespace ESM
* the INFO records following the DIAL.
*/
struct Dialogue
struct Dialogue : public Record
{
enum Type
{
@ -32,6 +33,8 @@ struct Dialogue
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_DIAL; }
};
}
#endif

@ -1,18 +1,21 @@
#ifndef _ESM_DOOR_H
#define _ESM_DOOR_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
namespace ESM
{
struct Door
struct Door : public Record
{
std::string name, model, script, openSound, closeSound;
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_DOOR; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_ENCH_H
#define _ESM_ENCH_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
#include "defs.hpp"
@ -12,7 +13,7 @@ namespace ESM
* Enchantments
*/
struct Enchantment
struct Enchantment : public Record
{
enum Type
{
@ -36,6 +37,8 @@ struct Enchantment
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_ENCH; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_FACT_H
#define _ESM_FACT_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -24,7 +25,7 @@ struct RankData
int factReaction; // Reaction from faction members
};
struct Faction
struct Faction : public Record
{
std::string id, name;
@ -55,6 +56,8 @@ struct Faction
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_FACT; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_GLOB_H
#define _ESM_GLOB_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
#include "defs.hpp"
@ -12,13 +13,15 @@ namespace ESM
* Global script variables
*/
struct Global
struct Global : public Record
{
unsigned value;
VarType type;
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_GLOB; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_GMST_H
#define _ESM_GMST_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
#include "defs.hpp"
@ -13,7 +14,7 @@ namespace ESM
*
*/
struct GameSetting
struct GameSetting : public Record
{
std::string id;
@ -85,6 +86,8 @@ struct GameSetting
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_GMST; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_INFO_H
#define _ESM_INFO_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
#include "defs.hpp"
@ -15,7 +16,7 @@ namespace ESM
* and form a linked list of dialogue items.
*/
struct DialInfo
struct DialInfo : public Record
{
enum Gender
{
@ -100,6 +101,8 @@ struct DialInfo
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_INFO; }
};
/*

@ -1,6 +1,7 @@
#ifndef _ESM_INGR_H
#define _ESM_INGR_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -11,7 +12,7 @@ namespace ESM
* Alchemy ingredient
*/
struct Ingredient
struct Ingredient : public Record
{
struct IRDTstruct
{
@ -27,6 +28,8 @@ struct Ingredient
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_INGR; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_LAND_H
#define _ESM_LAND_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -10,7 +11,7 @@ namespace ESM
* Landscape data.
*/
struct Land
struct Land : public Record
{
Land();
~Land();
@ -75,6 +76,8 @@ struct Land
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_LAND; }
/**
* Actually loads data
*/

@ -1,6 +1,7 @@
#ifndef _ESM_LEVLISTS_H
#define _ESM_LEVLISTS_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -15,7 +16,7 @@ namespace ESM
* several files.
*/
struct LeveledListBase
struct LeveledListBase : public Record
{
enum Flags
{
@ -45,6 +46,14 @@ struct LeveledListBase
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName()
{
if (recName[0] == 'C')
return REC_LEVC;
return REC_LEVI;
}
};
struct CreatureLevList: LeveledListBase

@ -1,6 +1,7 @@
#ifndef _ESM_LIGH_H
#define _ESM_LIGH_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -12,7 +13,7 @@ namespace ESM
* and torches.
*/
struct Light
struct Light : public Record
{
enum Flags
{
@ -43,6 +44,8 @@ struct Light
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_LIGH; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_LOCKS_H
#define _ESM_LOCKS_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -12,7 +13,7 @@ namespace ESM
* items (REPA). These have nearly identical data structures.
*/
struct Tool
struct Tool : public Record
{
enum Type
{
@ -38,16 +39,26 @@ struct Tool
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName()
{
if (type == Type_Probe)
return REC_PROB;
else if (type == Type_Repair)
return REC_REPA;
else
return REC_LOCK;
}
};
struct Probe: Tool
{
Probe() { type = Type_Probe; }
};
struct Repair: Tool
{
Repair() { type = Type_Repair; }
};
}

@ -1,6 +1,7 @@
#ifndef _ESM_LTEX_H
#define _ESM_LTEX_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -23,13 +24,15 @@ namespace ESM
* texture, and see if it affects the game.
*/
struct LandTexture
struct LandTexture : public Record
{
std::string id, texture;
int index;
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_LTEX; }
};
}
#endif

@ -1,13 +1,14 @@
#ifndef _ESM_MGEF_H
#define _ESM_MGEF_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
namespace ESM
{
struct MagicEffect
struct MagicEffect : public Record
{
enum Flags
{
@ -48,6 +49,8 @@ struct MagicEffect
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_MGEF; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_MISC_H
#define _ESM_MISC_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -12,7 +13,7 @@ namespace ESM
* carried, bought and sold. It also includes keys.
*/
struct Miscellaneous
struct Miscellaneous : public Record
{
struct MCDTstruct
{
@ -28,6 +29,8 @@ struct Miscellaneous
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_MISC; }
};
}
#endif

@ -3,10 +3,13 @@
namespace ESM
{
void NPC::load(ESMReader &esm, const std::string& id)
void NPC::setID(const std::string& id)
{
mId = id;
}
void NPC::load(ESMReader &esm)
{
npdt52.gold = -10;
model = esm.getHNOString("MODL");

@ -1,6 +1,7 @@
#ifndef _ESM_NPC_H
#define _ESM_NPC_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
#include "loadcont.hpp"
@ -12,7 +13,7 @@ namespace ESM {
* NPC definition
*/
struct NPC
struct NPC : public Record
{
// Services
enum Services
@ -102,8 +103,11 @@ struct NPC
std::string mId;
// Implementation moved to load_impl.cpp
void load(ESMReader &esm, const std::string& id);
void setID(const std::string& id);
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_NPC_; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_NPCC_H
#define _ESM_NPCC_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -71,7 +72,7 @@ namespace ESM {
* will be harder than reading it.
*/
struct LoadNPCC
struct LoadNPCC : public Record
{
void load(ESMReader &esm)
{
@ -80,6 +81,8 @@ struct LoadNPCC
void save(ESMWriter &esm)
{
}
int getName() { return REC_NPCC; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_PGRD_H
#define _ESM_PGRD_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -10,7 +11,7 @@ namespace ESM
/*
* Path grid.
*/
struct Pathgrid
struct Pathgrid : public Record
{
struct DATAstruct
{
@ -44,6 +45,8 @@ struct Pathgrid
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_PGRD; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_RACE_H
#define _ESM_RACE_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
#include "defs.hpp"
@ -12,7 +13,7 @@ namespace ESM
* Race definition
*/
struct Race
struct Race : public Record
{
struct SkillBonus
{
@ -60,6 +61,8 @@ struct Race
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_RACE; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_REGN_H
#define _ESM_REGN_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -11,7 +12,7 @@ namespace ESM
* Region data
*/
struct Region
struct Region : public Record
{
#pragma pack(push)
#pragma pack(1)
@ -43,6 +44,8 @@ struct Region
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_REGN; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_SCPT_H
#define _ESM_SCPT_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -11,7 +12,7 @@ namespace ESM
* Script definitions
*/
class Script
class Script : public Record
{
public:
struct SCHDstruct
@ -52,6 +53,8 @@ public:
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_SCPT; }
};
}
#endif

@ -3,6 +3,7 @@
#include <boost/array.hpp>
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
#include "defs.hpp"
@ -14,7 +15,7 @@ namespace ESM {
*
*/
struct Skill
struct Skill : public Record
{
struct SKDTstruct
{
@ -69,6 +70,8 @@ struct Skill
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_SKIL; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_SNDG_H
#define _ESM_SNDG_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -11,7 +12,7 @@ namespace ESM
* Sound generator. This describes the sounds a creature make.
*/
struct SoundGenerator
struct SoundGenerator : public Record
{
enum Type
{
@ -32,6 +33,8 @@ struct SoundGenerator
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_SNDG; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_SOUN_H
#define _ESM_SOUN_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -12,13 +13,15 @@ struct SOUNstruct
unsigned char volume, minRange, maxRange;
};
struct Sound
struct Sound : public Record
{
SOUNstruct data;
std::string sound;
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_SOUN; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_SPEL_H
#define _ESM_SPEL_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
#include "defs.hpp"
@ -8,7 +9,7 @@
namespace ESM
{
struct Spell
struct Spell : public Record
{
enum SpellType
{
@ -40,6 +41,8 @@ struct Spell
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_SPEL; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_SSCR_H
#define _ESM_SSCR_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -15,13 +16,15 @@ namespace ESM
reference.
*/
struct StartScript
struct StartScript : public Record
{
std::string script;
// Load a record and add it to the list
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_SSCR; }
};
}

@ -1,6 +1,7 @@
#ifndef _ESM_STAT_H
#define _ESM_STAT_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -18,12 +19,14 @@ namespace ESM {
* you decode the CELL blocks, if you want to test this hypothesis.
*/
struct Static
struct Static : public Record
{
std::string model;
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_STAT; }
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_WEAP_H
#define _ESM_WEAP_H
#include "record.hpp"
#include "esm_reader.hpp"
#include "esm_writer.hpp"
@ -11,7 +12,7 @@ namespace ESM
* Weapon definition
*/
struct Weapon
struct Weapon : public Record
{
enum Type
{
@ -58,6 +59,8 @@ struct Weapon
void load(ESMReader &esm);
void save(ESMWriter &esm);
int getName() { return REC_WEAP; }
};
}
#endif

@ -0,0 +1,70 @@
#ifndef _ESM_RECORD_H
#define _ESM_RECORD_H
namespace ESM
{
enum RecNameInts
{
REC_ACTI = 0x49544341,
REC_ALCH = 0x48434c41,
REC_APPA = 0x41505041,
REC_ARMO = 0x4f4d5241,
REC_BODY = 0x59444f42,
REC_BOOK = 0x4b4f4f42,
REC_BSGN = 0x4e475342,
REC_CELL = 0x4c4c4543,
REC_CLAS = 0x53414c43,
REC_CLOT = 0x544f4c43,
REC_CNTC = 0x43544e43,
REC_CONT = 0x544e4f43,
REC_CREA = 0x41455243,
REC_CREC = 0x43455243,
REC_DIAL = 0x4c414944,
REC_DOOR = 0x524f4f44,
REC_ENCH = 0x48434e45,
REC_FACT = 0x54434146,
REC_GLOB = 0x424f4c47,
REC_GMST = 0x54534d47,
REC_INFO = 0x4f464e49,
REC_INGR = 0x52474e49,
REC_LAND = 0x444e414c,
REC_LEVC = 0x4356454c,
REC_LEVI = 0x4956454c,
REC_LIGH = 0x4847494c,
REC_LOCK = 0x4b434f4c,
REC_LTEX = 0x5845544c,
REC_MGEF = 0x4645474d,
REC_MISC = 0x4353494d,
REC_NPC_ = 0x5f43504e,
REC_NPCC = 0x4343504e,
REC_PGRD = 0x44524750,
REC_PROB = 0x424f5250,
REC_RACE = 0x45434152,
REC_REGN = 0x4e474552,
REC_REPA = 0x41504552,
REC_SCPT = 0x54504353,
REC_SKIL = 0x4c494b53,
REC_SNDG = 0x47444e53,
REC_SOUN = 0x4e554f53,
REC_SPEL = 0x4c455053,
REC_SSCR = 0x52435353,
REC_STAT = 0x54415453,
REC_WEAP = 0x50414557
};
class ESMReader;
class ESMWriter;
class Record
{
public:
virtual void load(ESMReader& esm) = 0;
virtual void save(ESMWriter& esm) = 0;
virtual int getName() = 0;
};
}
#endif

@ -1,6 +1,7 @@
#ifndef _ESM_RECORDS_H
#define _ESM_RECORDS_H
#include "record.hpp"
#include "loadacti.hpp"
#include "loadalch.hpp"
#include "loadappa.hpp"
@ -45,57 +46,4 @@
// Special records which are not loaded from ESM
#include "attr.hpp"
namespace ESM {
// Integer versions of all the record names, used for faster lookup
enum RecNameInts
{
REC_ACTI = 0x49544341,
REC_ALCH = 0x48434c41,
REC_APPA = 0x41505041,
REC_ARMO = 0x4f4d5241,
REC_BODY = 0x59444f42,
REC_BOOK = 0x4b4f4f42,
REC_BSGN = 0x4e475342,
REC_CELL = 0x4c4c4543,
REC_CLAS = 0x53414c43,
REC_CLOT = 0x544f4c43,
REC_CNTC = 0x43544e43,
REC_CONT = 0x544e4f43,
REC_CREA = 0x41455243,
REC_CREC = 0x43455243,
REC_DIAL = 0x4c414944,
REC_DOOR = 0x524f4f44,
REC_ENCH = 0x48434e45,
REC_FACT = 0x54434146,
REC_GLOB = 0x424f4c47,
REC_GMST = 0x54534d47,
REC_INFO = 0x4f464e49,
REC_INGR = 0x52474e49,
REC_LAND = 0x444e414c,
REC_LEVC = 0x4356454c,
REC_LEVI = 0x4956454c,
REC_LIGH = 0x4847494c,
REC_LOCK = 0x4b434f4c,
REC_LTEX = 0x5845544c,
REC_MGEF = 0x4645474d,
REC_MISC = 0x4353494d,
REC_NPC_ = 0x5f43504e,
REC_NPCC = 0x4343504e,
REC_PGRD = 0x44524750,
REC_PROB = 0x424f5250,
REC_RACE = 0x45434152,
REC_REGN = 0x4e474552,
REC_REPA = 0x41504552,
REC_SCPT = 0x54504353,
REC_SKIL = 0x4c494b53,
REC_SNDG = 0x47444e53,
REC_SOUN = 0x4e554f53,
REC_SPEL = 0x4c455053,
REC_SSCR = 0x52435353,
REC_STAT = 0x54415453,
REC_WEAP = 0x50414557
};
}
#endif

@ -104,7 +104,8 @@ namespace ESMS
void load(ESMReader &esm, const std::string &id)
{
std::string id2 = toLower (id);
list[id2].load(esm, id2);
list[id2].setID(id2);
list[id2].load(esm);
}
// Find the given object ID, or return NULL if not found.

Loading…
Cancel
Save