mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-19 20:23:54 +00:00
Finished all basic parsers. Added --quiet option to esmtool.
This commit is contained in:
parent
2302e1f712
commit
db56985828
12 changed files with 194 additions and 105 deletions
|
@ -6,7 +6,7 @@
|
||||||
namespace ESM {
|
namespace ESM {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Books
|
* Books, magic scrolls, notes and so on
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct Book
|
struct Book
|
||||||
|
|
|
@ -57,12 +57,11 @@ struct Cell
|
||||||
if(esm.isNextSub("DELE")) esm.skipHSub();
|
if(esm.isNextSub("DELE")) esm.skipHSub();
|
||||||
|
|
||||||
esm.getHNT(data, "DATA", 12);
|
esm.getHNT(data, "DATA", 12);
|
||||||
|
region = esm.getHNOString("RGNN");
|
||||||
|
|
||||||
// Save position and move on
|
// Save position and move on
|
||||||
context = esm.getContext();
|
context = esm.getContext();
|
||||||
esm.skipRecord();
|
esm.skipRecord();
|
||||||
|
|
||||||
region = esm.getHNOString("RGNN");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,9 @@ struct InventoryList
|
||||||
void load(ESMReader &esm)
|
void load(ESMReader &esm)
|
||||||
{
|
{
|
||||||
ContItem ci;
|
ContItem ci;
|
||||||
while(esm.hasMoreSubs())
|
while(esm.isNextSub("NPCO"))
|
||||||
{
|
{
|
||||||
esm.getHNT(ci, "NPCO", 36);
|
esm.getHT(ci, 36);
|
||||||
list.push_back(ci);
|
list.push_back(ci);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ struct Creature
|
||||||
esm.getHNT(data, "NPDT", 96);
|
esm.getHNT(data, "NPDT", 96);
|
||||||
|
|
||||||
esm.getHNT(flags, "FLAG");
|
esm.getHNT(flags, "FLAG");
|
||||||
|
scale = 1.0;
|
||||||
esm.getHNOT(scale, "XSCL");
|
esm.getHNOT(scale, "XSCL");
|
||||||
|
|
||||||
inventory.load(esm);
|
inventory.load(esm);
|
||||||
|
|
46
esm/loaddial.hpp
Normal file
46
esm/loaddial.hpp
Normal file
|
@ -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)
|
void load(ESMReader &esm)
|
||||||
{
|
{
|
||||||
|
assert(id != "");
|
||||||
|
|
||||||
dirty = false;
|
dirty = false;
|
||||||
|
|
||||||
// We are apparently allowed to be empty
|
// We are apparently allowed to be empty
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "loadcont.hpp"
|
#include "loadcont.hpp"
|
||||||
#include "loadcrea.hpp"
|
#include "loadcrea.hpp"
|
||||||
#include "loadcrec.hpp"
|
#include "loadcrec.hpp"
|
||||||
|
#include "loaddial.hpp"
|
||||||
#include "loaddoor.hpp"
|
#include "loaddoor.hpp"
|
||||||
#include "loadench.hpp"
|
#include "loadench.hpp"
|
||||||
#include "loadfact.hpp"
|
#include "loadfact.hpp"
|
||||||
|
|
|
@ -42,6 +42,8 @@ int main(int argc, char**argv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool quiet = info.quiet_given;
|
||||||
|
|
||||||
esm.open(filename);
|
esm.open(filename);
|
||||||
|
|
||||||
cout << "Author: " << esm.getAuthor() << endl;
|
cout << "Author: " << esm.getAuthor() << endl;
|
||||||
|
@ -57,10 +59,11 @@ int main(int argc, char**argv)
|
||||||
while(esm.hasMoreRecs())
|
while(esm.hasMoreRecs())
|
||||||
{
|
{
|
||||||
NAME n = esm.getRecName();
|
NAME n = esm.getRecName();
|
||||||
cout << "\nRecord: " << n.toString();
|
|
||||||
esm.getRecHeader();
|
esm.getRecHeader();
|
||||||
string id = esm.getHNOString("NAME");
|
string id = esm.getHNOString("NAME");
|
||||||
cout << " '" << id << "'\n";
|
if(!quiet)
|
||||||
|
cout << "\nRecord: " << n.toString()
|
||||||
|
<< " '" << id << "'\n";
|
||||||
|
|
||||||
switch(n.val)
|
switch(n.val)
|
||||||
{
|
{
|
||||||
|
@ -68,15 +71,33 @@ int main(int argc, char**argv)
|
||||||
{
|
{
|
||||||
Activator ac;
|
Activator ac;
|
||||||
ac.load(esm);
|
ac.load(esm);
|
||||||
|
if(quiet) break;
|
||||||
cout << " Name: " << ac.name << endl;
|
cout << " Name: " << ac.name << endl;
|
||||||
cout << " Mesh: " << ac.model << endl;
|
cout << " Mesh: " << ac.model << endl;
|
||||||
cout << " Script: " << ac.script << endl;
|
cout << " Script: " << ac.script << endl;
|
||||||
break;
|
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:
|
case REC_ARMO:
|
||||||
{
|
{
|
||||||
Armor am;
|
Armor am;
|
||||||
am.load(esm);
|
am.load(esm);
|
||||||
|
if(quiet) break;
|
||||||
cout << " Name: " << am.name << endl;
|
cout << " Name: " << am.name << endl;
|
||||||
cout << " Mesh: " << am.model << endl;
|
cout << " Mesh: " << am.model << endl;
|
||||||
cout << " Icon: " << am.icon << endl;
|
cout << " Icon: " << am.icon << endl;
|
||||||
|
@ -90,23 +111,83 @@ int main(int argc, char**argv)
|
||||||
{
|
{
|
||||||
BodyPart bp;
|
BodyPart bp;
|
||||||
bp.load(esm);
|
bp.load(esm);
|
||||||
|
if(quiet) break;
|
||||||
cout << " Name: " << bp.name << endl;
|
cout << " Name: " << bp.name << endl;
|
||||||
cout << " Mesh: " << bp.model << endl;
|
cout << " Mesh: " << bp.model << endl;
|
||||||
break;
|
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:
|
case REC_BSGN:
|
||||||
{
|
{
|
||||||
BirthSign bs;
|
BirthSign bs;
|
||||||
bs.load(esm);
|
bs.load(esm);
|
||||||
|
if(quiet) break;
|
||||||
cout << " Name: " << bs.name << endl;
|
cout << " Name: " << bs.name << endl;
|
||||||
cout << " Texture: " << bs.texture << endl;
|
cout << " Texture: " << bs.texture << endl;
|
||||||
cout << " Description: " << bs.description << endl;
|
cout << " Description: " << bs.description << endl;
|
||||||
break;
|
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:
|
case REC_DOOR:
|
||||||
{
|
{
|
||||||
Door d;
|
Door d;
|
||||||
d.load(esm);
|
d.load(esm);
|
||||||
|
if(quiet) break;
|
||||||
cout << " Name: " << d.name << endl;
|
cout << " Name: " << d.name << endl;
|
||||||
cout << " Mesh: " << d.model << endl;
|
cout << " Mesh: " << d.model << endl;
|
||||||
cout << " Script: " << d.script << endl;
|
cout << " Script: " << d.script << endl;
|
||||||
|
@ -114,10 +195,42 @@ int main(int argc, char**argv)
|
||||||
cout << " CloseSound: " << d.closeSound << endl;
|
cout << " CloseSound: " << d.closeSound << endl;
|
||||||
break;
|
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:
|
case REC_SOUN:
|
||||||
{
|
{
|
||||||
Sound d;
|
Sound d;
|
||||||
d.load(esm);
|
d.load(esm);
|
||||||
|
if(quiet) break;
|
||||||
cout << " Sound: " << d.sound << endl;
|
cout << " Sound: " << d.sound << endl;
|
||||||
cout << " Volume: " << (int)d.data.volume << endl;
|
cout << " Volume: " << (int)d.data.volume << endl;
|
||||||
break;
|
break;
|
||||||
|
@ -126,12 +239,14 @@ int main(int argc, char**argv)
|
||||||
{
|
{
|
||||||
Spell s;
|
Spell s;
|
||||||
s.load(esm);
|
s.load(esm);
|
||||||
|
if(quiet) break;
|
||||||
cout << " Name: " << s.name << endl;
|
cout << " Name: " << s.name << endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
cout << " Skipping\n";
|
|
||||||
esm.skipRecord();
|
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"
|
args "--unamed-opts=ES-FILE -F esmtool_cmd -G"
|
||||||
|
|
||||||
option "raw" r "Show an unformattet list of all records and subrecords" optional
|
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."
|
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",
|
" -h, --help Print help and exit",
|
||||||
" -V, --version Print version and exit",
|
" -V, --version Print version and exit",
|
||||||
" -r, --raw Show an unformattet list of all records and subrecords",
|
" -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.",
|
"\nIf no option is given, the default action is to parse the entire archive and \ndiplay diagnostic information.",
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
@ -60,6 +61,7 @@ void clear_given (struct gengetopt_args_info *args_info)
|
||||||
args_info->help_given = 0 ;
|
args_info->help_given = 0 ;
|
||||||
args_info->version_given = 0 ;
|
args_info->version_given = 0 ;
|
||||||
args_info->raw_given = 0 ;
|
args_info->raw_given = 0 ;
|
||||||
|
args_info->quiet_given = 0 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
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->help_help = gengetopt_args_info_help[0] ;
|
||||||
args_info->version_help = gengetopt_args_info_help[1] ;
|
args_info->version_help = gengetopt_args_info_help[1] ;
|
||||||
args_info->raw_help = gengetopt_args_info_help[2] ;
|
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 );
|
write_into_file(outfile, "version", 0, 0 );
|
||||||
if (args_info->raw_given)
|
if (args_info->raw_given)
|
||||||
write_into_file(outfile, "raw", 0, 0 );
|
write_into_file(outfile, "raw", 0, 0 );
|
||||||
|
if (args_info->quiet_given)
|
||||||
|
write_into_file(outfile, "quiet", 0, 0 );
|
||||||
|
|
||||||
|
|
||||||
i = EXIT_SUCCESS;
|
i = EXIT_SUCCESS;
|
||||||
|
@ -1019,6 +1024,7 @@ cmdline_parser_internal (
|
||||||
{ "help", 0, NULL, 'h' },
|
{ "help", 0, NULL, 'h' },
|
||||||
{ "version", 0, NULL, 'V' },
|
{ "version", 0, NULL, 'V' },
|
||||||
{ "raw", 0, NULL, 'r' },
|
{ "raw", 0, NULL, 'r' },
|
||||||
|
{ "quiet", 0, NULL, 'q' },
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1027,7 +1033,7 @@ cmdline_parser_internal (
|
||||||
custom_opterr = opterr;
|
custom_opterr = opterr;
|
||||||
custom_optopt = optopt;
|
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;
|
optarg = custom_optarg;
|
||||||
optind = custom_optind;
|
optind = custom_optind;
|
||||||
|
@ -1060,6 +1066,18 @@ cmdline_parser_internal (
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
break;
|
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 0: /* Long option with no short option */
|
||||||
case '?': /* Invalid 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 *help_help; /**< @brief Print help and exit help description. */
|
||||||
const char *version_help; /**< @brief Print version 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 *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 help_given ; /**< @brief Whether help was given. */
|
||||||
unsigned int version_given ; /**< @brief Whether version was given. */
|
unsigned int version_given ; /**< @brief Whether version was given. */
|
||||||
unsigned int raw_given ; /**< @brief Whether raw 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) */
|
char **inputs ; /**< @brief unamed options (options without names) */
|
||||||
unsigned inputs_num ; /**< @brief unamed options number */
|
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…
Reference in a new issue