mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-21 10:53:51 +00:00
Working on making output identical to input.
This commit is contained in:
parent
290d09de64
commit
f16a9ce5ed
7 changed files with 150 additions and 70 deletions
|
@ -19,13 +19,13 @@ namespace bpo = boost::program_options;
|
||||||
struct ESMData
|
struct ESMData
|
||||||
{
|
{
|
||||||
std::string author;
|
std::string author;
|
||||||
std::string description;
|
string description;
|
||||||
int version;
|
int version;
|
||||||
int type;
|
int type;
|
||||||
ESMReader::MasterList masters;
|
ESMReader::MasterList masters;
|
||||||
|
|
||||||
std::list<Record*> records;
|
list<Record*> records;
|
||||||
std::map<Record*, std::list<CellRef> > cellRefs;
|
map<Record*, list<CellRef> > cellRefs;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Based on the legacy struct
|
// Based on the legacy struct
|
||||||
|
@ -35,17 +35,17 @@ struct Arguments
|
||||||
unsigned int quiet_given;
|
unsigned int quiet_given;
|
||||||
unsigned int loadcells_given;
|
unsigned int loadcells_given;
|
||||||
|
|
||||||
std::string mode;
|
string mode;
|
||||||
std::string encoding;
|
string encoding;
|
||||||
std::string filename;
|
string filename;
|
||||||
std::string outname;
|
string outname;
|
||||||
|
|
||||||
ESMData data;
|
ESMData data;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool parseOptions (int argc, char** argv, Arguments &info)
|
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] mode infile [outfile]\nAllowed modes:\n dump\t Dumps all readable data from the input file\n clone\t Clones the input file to the output file.\n\nAllowed options");
|
bpo::options_description desc("Inspect and extract from Morrowind ES files (ESM, ESP, ESS)\nSyntax: esmtool [options] mode infile [outfile]\nAllowed modes:\n dump\t Dumps all readable data from the input file.\n clone\t Clones the input file to the output file.\n comp\t Compares the given files.\n\nAllowed options");
|
||||||
|
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "print help message.")
|
("help,h", "print help message.")
|
||||||
|
@ -54,7 +54,7 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
||||||
("quiet,q", "Supress all record information. Useful for speed tests.")
|
("quiet,q", "Supress all record information. Useful for speed tests.")
|
||||||
("loadcells,C", "Browse through contents of all cells.")
|
("loadcells,C", "Browse through contents of all cells.")
|
||||||
|
|
||||||
( "encoding,e", bpo::value<std::string>(&(info.encoding))->
|
( "encoding,e", bpo::value<string>(&(info.encoding))->
|
||||||
default_value("win1252"),
|
default_value("win1252"),
|
||||||
"Character encoding used in ESMTool:\n"
|
"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\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n"
|
||||||
|
@ -62,14 +62,14 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
||||||
"\n\twin1252 - Western European (Latin) alphabet, used by default")
|
"\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.";
|
string finalText = "\nIf no option is given, the default action is to parse all records in the archive\nand display diagnostic information.";
|
||||||
|
|
||||||
// input-file is hidden and used as a positional argument
|
// input-file is hidden and used as a positional argument
|
||||||
bpo::options_description hidden("Hidden Options");
|
bpo::options_description hidden("Hidden Options");
|
||||||
|
|
||||||
hidden.add_options()
|
hidden.add_options()
|
||||||
( "mode,m", bpo::value<std::string>(), "esmtool mode")
|
( "mode,m", bpo::value<string>(), "esmtool mode")
|
||||||
( "input-file,i", bpo::value< vector<std::string> >(), "input file")
|
( "input-file,i", bpo::value< vector<string> >(), "input file")
|
||||||
;
|
;
|
||||||
|
|
||||||
bpo::positional_options_description p;
|
bpo::positional_options_description p;
|
||||||
|
@ -87,70 +87,70 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
||||||
|
|
||||||
if (variables.count ("help"))
|
if (variables.count ("help"))
|
||||||
{
|
{
|
||||||
std::cout << desc << finalText << std::endl;
|
cout << desc << finalText << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (variables.count ("version"))
|
if (variables.count ("version"))
|
||||||
{
|
{
|
||||||
std::cout << "ESMTool version " << ESMTOOL_VERSION << std::endl;
|
cout << "ESMTool version " << ESMTOOL_VERSION << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!variables.count("mode"))
|
if (!variables.count("mode"))
|
||||||
{
|
{
|
||||||
std::cout << "No mode specified!" << std::endl << std::endl
|
cout << "No mode specified!" << endl << endl
|
||||||
<< desc << finalText << std::endl;
|
<< desc << finalText << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
info.mode = variables["mode"].as<std::string>();
|
info.mode = variables["mode"].as<string>();
|
||||||
if (!(info.mode == "dump" || info.mode == "clone"))
|
if (!(info.mode == "dump" || info.mode == "clone" || info.mode == "comp"))
|
||||||
{
|
{
|
||||||
std::cout << std::endl << "ERROR: invalid mode \"" << info.mode << "\"" << std::endl << std::endl
|
cout << endl << "ERROR: invalid mode \"" << info.mode << "\"" << endl << endl
|
||||||
<< desc << finalText << std::endl;
|
<< desc << finalText << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !variables.count("input-file") )
|
if ( !variables.count("input-file") )
|
||||||
{
|
{
|
||||||
std::cout << "\nERROR: missing ES file\n\n";
|
cout << "\nERROR: missing ES file\n\n";
|
||||||
std::cout << desc << finalText << std::endl;
|
cout << desc << finalText << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handling gracefully the user adding multiple files
|
// handling gracefully the user adding multiple files
|
||||||
/* if (variables["input-file"].as< vector<std::string> >().size() > 1)
|
/* if (variables["input-file"].as< vector<string> >().size() > 1)
|
||||||
{
|
{
|
||||||
std::cout << "\nERROR: more than one ES file specified\n\n";
|
cout << "\nERROR: more than one ES file specified\n\n";
|
||||||
std::cout << desc << finalText << std::endl;
|
cout << desc << finalText << endl;
|
||||||
return false;
|
return false;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
info.filename = variables["input-file"].as< vector<std::string> >()[0];
|
info.filename = variables["input-file"].as< vector<string> >()[0];
|
||||||
if (variables["input-file"].as< vector<std::string> >().size() > 1)
|
if (variables["input-file"].as< vector<string> >().size() > 1)
|
||||||
info.outname = variables["input-file"].as< vector<std::string> >()[1];
|
info.outname = variables["input-file"].as< vector<string> >()[1];
|
||||||
|
|
||||||
info.raw_given = variables.count ("raw");
|
info.raw_given = variables.count ("raw");
|
||||||
info.quiet_given = variables.count ("quiet");
|
info.quiet_given = variables.count ("quiet");
|
||||||
info.loadcells_given = variables.count ("loadcells");
|
info.loadcells_given = variables.count ("loadcells");
|
||||||
|
|
||||||
// Font encoding settings
|
// Font encoding settings
|
||||||
info.encoding = variables["encoding"].as<std::string>();
|
info.encoding = variables["encoding"].as<string>();
|
||||||
if (info.encoding == "win1250")
|
if (info.encoding == "win1250")
|
||||||
{
|
{
|
||||||
std::cout << "Using Central and Eastern European font encoding." << std::endl;
|
cout << "Using Central and Eastern European font encoding." << endl;
|
||||||
}
|
}
|
||||||
else if (info.encoding == "win1251")
|
else if (info.encoding == "win1251")
|
||||||
{
|
{
|
||||||
std::cout << "Using Cyrillic font encoding." << std::endl;
|
cout << "Using Cyrillic font encoding." << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(info.encoding != "win1252")
|
if(info.encoding != "win1252")
|
||||||
{
|
{
|
||||||
std::cout << info.encoding << " is not a valid encoding option." << std::endl;
|
cout << info.encoding << " is not a valid encoding option." << endl;
|
||||||
info.encoding = "win1252";
|
info.encoding = "win1252";
|
||||||
}
|
}
|
||||||
std::cout << "Using default (English) font encoding." << std::endl;
|
cout << "Using default (English) font encoding." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -161,6 +161,7 @@ void loadCell(Cell &cell, ESMReader &esm, Arguments& info);
|
||||||
|
|
||||||
int load(Arguments& info);
|
int load(Arguments& info);
|
||||||
int clone(Arguments& info);
|
int clone(Arguments& info);
|
||||||
|
int comp(Arguments& info);
|
||||||
|
|
||||||
int main(int argc, char**argv)
|
int main(int argc, char**argv)
|
||||||
{
|
{
|
||||||
|
@ -172,6 +173,8 @@ int main(int argc, char**argv)
|
||||||
return load(info);
|
return load(info);
|
||||||
else if (info.mode == "clone")
|
else if (info.mode == "clone")
|
||||||
return clone(info);
|
return clone(info);
|
||||||
|
else if (info.mode == "comp")
|
||||||
|
return comp(info);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "Invalid or no mode specified, dying horribly. Have a nice day." << endl;
|
cout << "Invalid or no mode specified, dying horribly. Have a nice day." << endl;
|
||||||
|
@ -231,9 +234,9 @@ int load(Arguments& info)
|
||||||
esm.setEncoding(info.encoding);
|
esm.setEncoding(info.encoding);
|
||||||
|
|
||||||
string filename = info.filename;
|
string filename = info.filename;
|
||||||
cout << "\nFile: " << filename << endl;
|
cout << "Loading file: " << filename << endl;
|
||||||
|
|
||||||
std::list<int> skipped;
|
list<int> skipped;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
@ -734,7 +737,7 @@ int load(Arguments& info)
|
||||||
{
|
{
|
||||||
cout << "\nERROR:\n\n " << e.what() << endl;
|
cout << "\nERROR:\n\n " << e.what() << endl;
|
||||||
|
|
||||||
for (std::list<Record*>::iterator it = info.data.records.begin(); it != info.data.records.end();)
|
for (list<Record*>::iterator it = info.data.records.begin(); it != info.data.records.end();)
|
||||||
{
|
{
|
||||||
delete *it;
|
delete *it;
|
||||||
info.data.records.erase(it++);
|
info.data.records.erase(it++);
|
||||||
|
@ -773,9 +776,9 @@ int clone(Arguments& info)
|
||||||
|
|
||||||
cout << "Loaded " << recordCount << " records:" << endl << endl;
|
cout << "Loaded " << recordCount << " records:" << endl << endl;
|
||||||
|
|
||||||
std::map<std::string, int> records;
|
map<string, int> records;
|
||||||
|
|
||||||
for (std::list<Record*>::iterator it = info.data.records.begin(); it != info.data.records.end(); ++it)
|
for (list<Record*>::iterator it = info.data.records.begin(); it != info.data.records.end(); ++it)
|
||||||
{
|
{
|
||||||
Record* rec = *it;
|
Record* rec = *it;
|
||||||
NAME n;
|
NAME n;
|
||||||
|
@ -784,9 +787,9 @@ int clone(Arguments& info)
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (std::map<std::string,int>::iterator it = records.begin(); it != records.end(); ++it)
|
for (map<string,int>::iterator it = records.begin(); it != records.end(); ++it)
|
||||||
{
|
{
|
||||||
std::string n = it->first;
|
string n = it->first;
|
||||||
float amount = it->second;
|
float amount = it->second;
|
||||||
cout << setw(digitCount) << amount << " " << n << " ";
|
cout << setw(digitCount) << amount << " " << n << " ";
|
||||||
|
|
||||||
|
@ -808,11 +811,11 @@ int clone(Arguments& info)
|
||||||
for (ESMReader::MasterList::iterator it = info.data.masters.begin(); it != info.data.masters.end(); ++it)
|
for (ESMReader::MasterList::iterator it = info.data.masters.begin(); it != info.data.masters.end(); ++it)
|
||||||
esm.addMaster(it->name, it->size);
|
esm.addMaster(it->name, it->size);
|
||||||
|
|
||||||
std::fstream save(info.outname.c_str(), std::fstream::out | std::fstream::binary);
|
fstream save(info.outname.c_str(), fstream::out | fstream::binary);
|
||||||
esm.save(save);
|
esm.save(save);
|
||||||
|
|
||||||
int saved = 0;
|
int saved = 0;
|
||||||
for (std::list<Record*>::iterator it = info.data.records.begin(); it != info.data.records.end() && i > 0; ++it)
|
for (list<Record*>::iterator it = info.data.records.begin(); it != info.data.records.end() && i > 0; ++it)
|
||||||
{
|
{
|
||||||
Record* rec = *it;
|
Record* rec = *it;
|
||||||
|
|
||||||
|
@ -820,14 +823,18 @@ int clone(Arguments& info)
|
||||||
n.val = rec->getName();
|
n.val = rec->getName();
|
||||||
|
|
||||||
esm.startRecord(n.toString(), 0);
|
esm.startRecord(n.toString(), 0);
|
||||||
std::string id = rec->getId();
|
string id = rec->getId();
|
||||||
esm.writeHNOString("NAME", id);
|
|
||||||
|
if (n.val == REC_GLOB || n.val == REC_CLAS || n.val == REC_FACT || n.val == REC_RACE)
|
||||||
|
esm.writeHNCString("NAME", id);
|
||||||
|
else
|
||||||
|
esm.writeHNOString("NAME", id);
|
||||||
rec->save(esm);
|
rec->save(esm);
|
||||||
|
|
||||||
if (n.val == REC_CELL && !info.data.cellRefs[rec].empty())
|
if (n.val == REC_CELL && !info.data.cellRefs[rec].empty())
|
||||||
{
|
{
|
||||||
std::list<CellRef>& refs = info.data.cellRefs[rec];
|
list<CellRef>& refs = info.data.cellRefs[rec];
|
||||||
for (std::list<CellRef>::iterator it = refs.begin(); it != refs.end(); ++it)
|
for (list<CellRef>::iterator it = refs.begin(); it != refs.end(); ++it)
|
||||||
{
|
{
|
||||||
it->save(esm);
|
it->save(esm);
|
||||||
}
|
}
|
||||||
|
@ -848,5 +855,52 @@ int clone(Arguments& info)
|
||||||
esm.close();
|
esm.close();
|
||||||
save.close();
|
save.close();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int comp(Arguments& info)
|
||||||
|
{
|
||||||
|
if (info.filename.empty() || info.outname.empty())
|
||||||
|
{
|
||||||
|
cout << "You need to specify two input files" << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arguments fileOne;
|
||||||
|
Arguments fileTwo;
|
||||||
|
|
||||||
|
fileOne.raw_given = 0;
|
||||||
|
fileTwo.raw_given = 0;
|
||||||
|
|
||||||
|
fileOne.mode = "clone";
|
||||||
|
fileTwo.mode = "clone";
|
||||||
|
|
||||||
|
fileOne.encoding = info.encoding;
|
||||||
|
fileTwo.encoding = info.encoding;
|
||||||
|
|
||||||
|
fileOne.filename = info.filename;
|
||||||
|
fileTwo.filename = info.outname;
|
||||||
|
|
||||||
|
if (load(fileOne) != 0)
|
||||||
|
{
|
||||||
|
cout << "Failed to load " << info.filename << ", aborting comparison." << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (load(fileTwo) != 0)
|
||||||
|
{
|
||||||
|
cout << "Failed to load " << info.outname << ", aborting comparison." << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileOne.data.records.size() != fileTwo.data.records.size())
|
||||||
|
{
|
||||||
|
cout << "Not equal, different amount of records." << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,12 +53,14 @@ void ESMWriter::save(const std::string& file)
|
||||||
|
|
||||||
void ESMWriter::save(std::ostream& file)
|
void ESMWriter::save(std::ostream& file)
|
||||||
{
|
{
|
||||||
|
m_recordCount = 0;
|
||||||
m_stream = &file;
|
m_stream = &file;
|
||||||
|
|
||||||
startRecord("TES3", 0);
|
startRecord("TES3", 0);
|
||||||
|
|
||||||
m_header.records = 0;
|
m_header.records = 0;
|
||||||
writeHNT("HEDR", m_header, 300);
|
writeHNT("HEDR", m_header, 300);
|
||||||
|
m_headerPos = m_stream->tellp() - (std::streampos)4;
|
||||||
|
|
||||||
for (std::list<MasterData>::iterator it = m_masters.begin(); it != m_masters.end(); ++it)
|
for (std::list<MasterData>::iterator it = m_masters.begin(); it != m_masters.end(); ++it)
|
||||||
{
|
{
|
||||||
|
@ -71,6 +73,10 @@ void ESMWriter::save(std::ostream& file)
|
||||||
|
|
||||||
void ESMWriter::close()
|
void ESMWriter::close()
|
||||||
{
|
{
|
||||||
|
std::cout << "Writing amount of saved records (" << m_recordCount - 1 << ")" << std::endl;
|
||||||
|
m_stream->seekp(m_headerPos);
|
||||||
|
writeT<int>(m_recordCount-1);
|
||||||
|
m_stream->seekp(0, std::ios::end);
|
||||||
m_stream->flush();
|
m_stream->flush();
|
||||||
|
|
||||||
if (!m_records.empty())
|
if (!m_records.empty())
|
||||||
|
@ -79,6 +85,8 @@ void ESMWriter::close()
|
||||||
|
|
||||||
void ESMWriter::startRecord(const std::string& name, uint32_t flags)
|
void ESMWriter::startRecord(const std::string& name, uint32_t flags)
|
||||||
{
|
{
|
||||||
|
m_recordCount++;
|
||||||
|
|
||||||
writeName(name);
|
writeName(name);
|
||||||
RecordData rec;
|
RecordData rec;
|
||||||
rec.name = name;
|
rec.name = name;
|
||||||
|
@ -128,6 +136,21 @@ void ESMWriter::writeHNString(const std::string& name, const std::string& data)
|
||||||
endRecord(name);
|
endRecord(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ESMWriter::writeHNString(const std::string& name, const std::string& data, int size)
|
||||||
|
{
|
||||||
|
assert(data.size() <= size);
|
||||||
|
startSubRecord(name);
|
||||||
|
writeHString(data);
|
||||||
|
|
||||||
|
if (data.size() < size)
|
||||||
|
{
|
||||||
|
for (int i = data.size(); i < size; ++i)
|
||||||
|
write("\0",1);
|
||||||
|
}
|
||||||
|
|
||||||
|
endRecord(name);
|
||||||
|
}
|
||||||
|
|
||||||
void ESMWriter::writeHString(const std::string& data)
|
void ESMWriter::writeHString(const std::string& data)
|
||||||
{
|
{
|
||||||
if (data.size() == 0)
|
if (data.size() == 0)
|
||||||
|
|
|
@ -34,6 +34,15 @@ public:
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
void writeHNString(const std::string& name, const std::string& data);
|
void writeHNString(const std::string& name, const std::string& data);
|
||||||
|
void writeHNString(const std::string& name, const std::string& data, int size);
|
||||||
|
void writeHNCString(const std::string& name, const std::string& data)
|
||||||
|
{
|
||||||
|
startSubRecord(name);
|
||||||
|
writeHString(data);
|
||||||
|
if (data.size() > 0 && data[data.size()-1] != '\0')
|
||||||
|
write("\0", 1);
|
||||||
|
endRecord(name);
|
||||||
|
}
|
||||||
void writeHNOString(const std::string& name, const std::string& data)
|
void writeHNOString(const std::string& name, const std::string& data)
|
||||||
{
|
{
|
||||||
if (!data.empty())
|
if (!data.empty())
|
||||||
|
@ -56,20 +65,6 @@ public:
|
||||||
endRecord(name);
|
endRecord(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*template<typename T>
|
|
||||||
void writeHT(const T& data)
|
|
||||||
{
|
|
||||||
writeT((unsigned int)sizeof(T));
|
|
||||||
writeT(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void writeHT(const T& data, int size)
|
|
||||||
{
|
|
||||||
assert(sizeof(T) == size);
|
|
||||||
writeHT(data);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void writeT(const T& data)
|
void writeT(const T& data)
|
||||||
{
|
{
|
||||||
|
@ -93,6 +88,8 @@ private:
|
||||||
std::list<MasterData> m_masters;
|
std::list<MasterData> m_masters;
|
||||||
std::list<RecordData> m_records;
|
std::list<RecordData> m_records;
|
||||||
std::ostream* m_stream;
|
std::ostream* m_stream;
|
||||||
|
std::streampos m_headerPos;
|
||||||
|
int m_recordCount;
|
||||||
|
|
||||||
HEDRstruct m_header;
|
HEDRstruct m_header;
|
||||||
SaveData m_saveData;
|
SaveData m_saveData;
|
||||||
|
|
|
@ -27,7 +27,7 @@ void Class::load(ESMReader &esm)
|
||||||
}
|
}
|
||||||
void Class::save(ESMWriter &esm)
|
void Class::save(ESMWriter &esm)
|
||||||
{
|
{
|
||||||
esm.writeHNString("FNAM", name);
|
esm.writeHNCString("FNAM", name);
|
||||||
esm.writeHNT("CLDT", data, 60);
|
esm.writeHNT("CLDT", data, 60);
|
||||||
esm.writeHNOString("DESC", description);
|
esm.writeHNOString("DESC", description);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,14 @@ void Faction::load(ESMReader &esm)
|
||||||
}
|
}
|
||||||
void Faction::save(ESMWriter &esm)
|
void Faction::save(ESMWriter &esm)
|
||||||
{
|
{
|
||||||
esm.writeHNString("FNAM", name);
|
esm.writeHNCString("FNAM", name);
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
esm.writeHNString("RNAM", ranks[i]);
|
if (ranks[i].empty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
esm.writeHNString("RNAM", ranks[i], 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
esm.writeHNT("FADT", data, 240);
|
esm.writeHNT("FADT", data, 240);
|
||||||
|
|
|
@ -12,7 +12,7 @@ void Race::load(ESMReader &esm)
|
||||||
}
|
}
|
||||||
void Race::save(ESMWriter &esm)
|
void Race::save(ESMWriter &esm)
|
||||||
{
|
{
|
||||||
esm.writeHNString("FNAM", name);
|
esm.writeHNCString("FNAM", name);
|
||||||
esm.writeHNT("RADT", data, 140);
|
esm.writeHNT("RADT", data, 140);
|
||||||
powers.save(esm);
|
powers.save(esm);
|
||||||
esm.writeHNOString("DESC", description);
|
esm.writeHNOString("DESC", description);
|
||||||
|
|
|
@ -40,19 +40,22 @@ void Script::load(ESMReader &esm)
|
||||||
}
|
}
|
||||||
void Script::save(ESMWriter &esm)
|
void Script::save(ESMWriter &esm)
|
||||||
{
|
{
|
||||||
esm.writeHNT("SCHD", data, 52);
|
std::string varNameString;
|
||||||
|
|
||||||
if (!varNames.empty())
|
if (!varNames.empty())
|
||||||
{
|
{
|
||||||
esm.startSubRecord("SCVR");
|
|
||||||
for (std::vector<std::string>::iterator it = varNames.begin(); it != varNames.end(); ++it)
|
for (std::vector<std::string>::iterator it = varNames.begin(); it != varNames.end(); ++it)
|
||||||
{
|
{
|
||||||
esm.writeT(it->c_str(), it->size());
|
varNameString.append(*it);
|
||||||
esm.writeT('\0');
|
//varNameString.append("\0");
|
||||||
}
|
}
|
||||||
esm.endRecord("SCVR");
|
|
||||||
|
data.stringTableSize = varNameString.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esm.writeHNT("SCHD", data, 52);
|
||||||
|
|
||||||
|
esm.writeHNOString("SCVR", varNameString);
|
||||||
|
|
||||||
esm.writeHNString("SCDT", std::string(&scriptData[0], scriptData.size()));
|
esm.writeHNString("SCDT", std::string(&scriptData[0], scriptData.size()));
|
||||||
esm.writeHNOString("SCTX", scriptText);
|
esm.writeHNOString("SCTX", scriptText);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue