@ -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) \n Syntax: esmtool [options] file \n Allowed options " ) ;
bpo : : options_description desc ( " Inspect and extract from Morrowind ES files (ESM, ESP, ESS) \n Syntax: esmtool [options] mode in file [outfile] \n Allowed 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 \t win1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages \n "
" \n \t win1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages \n "
" \n \t win1252 - Western European (Latin) alphabet, used by default " )
default_value ( " win1252 " ) ,
" Character encoding used in ESMTool: \n "
" \n \t win1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages \n "
" \n \t win1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages \n "
" \n \t win1252 - Western European (Latin) alphabet, used by default " )
;
std : : string finalText = " \n If no option is given, the default action is to parse all records in the archive \n and 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 < < " \n ERROR: 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 < < " \n ERROR: 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 < < " \n File: " < < 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 < < " \n File: " < < 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 < < " \n Record: " < < 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 < < " \n Record: " < < 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 < < " \n ERROR: \n \n " < < e . what ( ) < < endl ;
return 1 ;
cout < < " \n ERROR: \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 ;
}