Finished all basic parsers. Added --quiet option to esmtool.

pull/7/head
Nicolay Korslund 15 years ago
parent 2302e1f712
commit db56985828

@ -6,7 +6,7 @@
namespace ESM {
/*
* Books
* Books, magic scrolls, notes and so on
*/
struct Book

@ -57,12 +57,11 @@ struct Cell
if(esm.isNextSub("DELE")) esm.skipHSub();
esm.getHNT(data, "DATA", 12);
region = esm.getHNOString("RGNN");
// Save position and move on
context = esm.getContext();
esm.skipRecord();
region = esm.getHNOString("RGNN");
}
};
}

@ -22,9 +22,9 @@ struct InventoryList
void load(ESMReader &esm)
{
ContItem ci;
while(esm.hasMoreSubs())
while(esm.isNextSub("NPCO"))
{
esm.getHNT(ci, "NPCO", 36);
esm.getHT(ci, 36);
list.push_back(ci);
}
}

@ -72,6 +72,7 @@ struct Creature
esm.getHNT(data, "NPDT", 96);
esm.getHNT(flags, "FLAG");
scale = 1.0;
esm.getHNOT(scale, "XSCL");
inventory.load(esm);

@ -0,0 +1,46 @@
#ifndef _ESM_DIAL_H
#define _ESM_DIAL_H
#include "esm_reader.hpp"
namespace ESM {
/*
* Dialogue topic and journal entries. The actual data is contained in
* the INFO records following the DIAL.
*/
struct Dialogue
{
enum Type
{
Topic = 0,
Voice = 1,
Greeting = 2,
Persuasion = 3,
Journal = 4,
Deleted = -1
};
char type;
void load(ESMReader &esm)
{
esm.getSubNameIs("DATA");
esm.getSubHeader();
int si = esm.getSubSize();
if(si == 1)
esm.getT(type);
else if(si == 4)
{
// These are just markers, their values are not used.
int i;
esm.getT(i);
esm.getHNT(i,"DELE");
type = Deleted;
}
else esm.fail("Unknown sub record size");
}
};
}
#endif

@ -203,6 +203,8 @@ struct GameSetting
void load(ESMReader &esm)
{
assert(id != "");
dirty = false;
// We are apparently allowed to be empty

@ -14,6 +14,7 @@
#include "loadcont.hpp"
#include "loadcrea.hpp"
#include "loadcrec.hpp"
#include "loaddial.hpp"
#include "loaddoor.hpp"
#include "loadench.hpp"
#include "loadfact.hpp"

@ -42,6 +42,8 @@ int main(int argc, char**argv)
return 0;
}
bool quiet = info.quiet_given;
esm.open(filename);
cout << "Author: " << esm.getAuthor() << endl;
@ -57,10 +59,11 @@ int main(int argc, char**argv)
while(esm.hasMoreRecs())
{
NAME n = esm.getRecName();
cout << "\nRecord: " << n.toString();
esm.getRecHeader();
string id = esm.getHNOString("NAME");
cout << " '" << id << "'\n";
if(!quiet)
cout << "\nRecord: " << n.toString()
<< " '" << id << "'\n";
switch(n.val)
{
@ -68,15 +71,33 @@ int main(int argc, char**argv)
{
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;
@ -90,23 +111,83 @@ int main(int argc, char**argv)
{
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);
if(quiet) break;
cout << " Name: " << b.name << endl;
cout << " Region: " << b.region << endl;
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);
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;
@ -114,10 +195,42 @@ int main(int argc, char**argv)
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;
@ -126,12 +239,14 @@ int main(int argc, char**argv)
{
Spell s;
s.load(esm);
if(quiet) break;
cout << " Name: " << s.name << endl;
break;
}
default:
cout << " Skipping\n";
esm.skipRecord();
if(quiet) break;
cout << " Skipping\n";
}
}

@ -4,5 +4,6 @@ purpose "Inspect and extract from Morrowind ES files (ESM, ESP, ESS)"
args "--unamed-opts=ES-FILE -F esmtool_cmd -G"
option "raw" r "Show an unformattet list of all records and subrecords" optional
option "quiet" q "Supress all record information. Useful for speed tests." optional
text "\nIf no option is given, the default action is to parse the entire archive and diplay diagnostic information."

@ -34,6 +34,7 @@ const char *gengetopt_args_info_help[] = {
" -h, --help Print help and exit",
" -V, --version Print version and exit",
" -r, --raw Show an unformattet list of all records and subrecords",
" -q, --quiet Supress all record information. Useful for speed tests.",
"\nIf no option is given, the default action is to parse the entire archive and \ndiplay diagnostic information.",
0
};
@ -60,6 +61,7 @@ void clear_given (struct gengetopt_args_info *args_info)
args_info->help_given = 0 ;
args_info->version_given = 0 ;
args_info->raw_given = 0 ;
args_info->quiet_given = 0 ;
}
static
@ -77,6 +79,7 @@ void init_args_info(struct gengetopt_args_info *args_info)
args_info->help_help = gengetopt_args_info_help[0] ;
args_info->version_help = gengetopt_args_info_help[1] ;
args_info->raw_help = gengetopt_args_info_help[2] ;
args_info->quiet_help = gengetopt_args_info_help[3] ;
}
@ -192,6 +195,8 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
write_into_file(outfile, "version", 0, 0 );
if (args_info->raw_given)
write_into_file(outfile, "raw", 0, 0 );
if (args_info->quiet_given)
write_into_file(outfile, "quiet", 0, 0 );
i = EXIT_SUCCESS;
@ -1019,6 +1024,7 @@ cmdline_parser_internal (
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'V' },
{ "raw", 0, NULL, 'r' },
{ "quiet", 0, NULL, 'q' },
{ 0, 0, 0, 0 }
};
@ -1027,7 +1033,7 @@ cmdline_parser_internal (
custom_opterr = opterr;
custom_optopt = optopt;
c = custom_getopt_long (argc, argv, "hVr", long_options, &option_index);
c = custom_getopt_long (argc, argv, "hVrq", long_options, &option_index);
optarg = custom_optarg;
optind = custom_optind;
@ -1060,6 +1066,18 @@ cmdline_parser_internal (
goto failure;
break;
case 'q': /* Supress all record information. Useful for speed tests.. */
if (update_arg( 0 ,
0 , &(args_info->quiet_given),
&(local_args_info.quiet_given), optarg, 0, 0, ARG_NO,
check_ambiguity, override, 0, 0,
"quiet", 'q',
additional_error))
goto failure;
break;
case 0: /* Long option with no short option */
case '?': /* Invalid option. */

@ -40,10 +40,12 @@ struct gengetopt_args_info
const char *help_help; /**< @brief Print help and exit help description. */
const char *version_help; /**< @brief Print version and exit help description. */
const char *raw_help; /**< @brief Show an unformattet list of all records and subrecords help description. */
const char *quiet_help; /**< @brief Supress all record information. Useful for speed tests. help description. */
unsigned int help_given ; /**< @brief Whether help was given. */
unsigned int version_given ; /**< @brief Whether version was given. */
unsigned int raw_given ; /**< @brief Whether raw was given. */
unsigned int quiet_given ; /**< @brief Whether quiet was given. */
char **inputs ; /**< @brief unamed options (options without names) */
unsigned inputs_num ; /**< @brief unamed options number */

@ -1,96 +0,0 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (loadspel.d) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
module esm.loadspel;
import esm.imports;
/*
* Spell
*/
struct SpellList
{
RegionBuffer!(Spell*) list;
void load()
{
list = esFile.getRegion().getBuffer!(Spell*)(0,1);
while(esFile.isNextSub("NPCS"))
list ~= esFile.getHPtr!(Spell)(spells);
}
}
struct Spell
{
char[] id;
LoadState state;
enum SpellType
{
Spell = 0, // Normal spell, must be cast and costs mana
Ability = 1, // Inert ability, always in effect
Blight = 2, // Blight disease
Disease = 3, // Common disease
Curse = 4, // Curse (?)
Power = 5 // Power, can use once a day
}
enum Flags
{
Autocalc = 1,
PCStart = 2,
Always = 4 // Casting always succeeds
}
align(1) struct SPDTstruct
{
SpellType type;
int cost;
Flags flags;
static assert(SPDTstruct.sizeof==12);
}
SPDTstruct data;
char[] name;
EffectList effects;
void load()
{with(esFile){
name = getHNOString("FNAM");
readHNExact(&data, data.sizeof, "SPDT");
effects = getRegion().getBuffer!(ENAMstruct)(0,1);
while(isNextSub("ENAM"))
{
effects.length = effects.length + 1;
readHExact(&effects.array[$-1], effects.array[$-1].sizeof);
}
}}
}
ListID!(Spell) spells;
Loading…
Cancel
Save