parse spell components.

This commit is contained in:
Enno Rehling 2018-05-08 23:06:33 +02:00
parent 371335ab95
commit b197bb395d
2 changed files with 70 additions and 11 deletions

View file

@ -273,15 +273,50 @@ static void handle_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **at
wtype->flags = flags;
}
#define MAX_COMPONENTS 8
static spell_component components[MAX_COMPONENTS];
static int ncomponents;
static void XMLCALL start_spells(parseinfo *pi, const XML_Char *el, const XML_Char **attr) {
const char *flag_names[] = {
"far", "variable", "ocean", "ship", "los",
"unittarget", "shiptarget", "buildingtarget", "regiontarget", NULL };
"unittarget", "shiptarget", "buildingtarget", "regiontarget", "globaltarget", NULL };
if (xml_strcmp(el, "resource") == 0) {
spell_component *spc = NULL;
(void)spc;
handle_bad_input(pi, el, NULL);
spell_component *spc;
int i;
assert(ncomponents < MAX_COMPONENTS);
spc = components + ncomponents;
spc->cost = SPC_FIX;
++ncomponents;
memset(spc, 0, sizeof(spell_component));
for (i = 0; attr[i]; i += 2) {
const XML_Char *key = attr[i], *val = attr[i + 1];
if (xml_strcmp(key, "name") == 0) {
spc->type = rt_get_or_create(val);
}
else if (xml_strcmp(key, "amount") == 0) {
spc->amount = xml_int(val);
}
else if (xml_strcmp(key, "cost") == 0) {
if (xml_strcmp(val, "level") == 0) {
spc->cost = SPC_LEVEL;
}
else if (xml_strcmp(val, "linear") == 0) {
spc->cost = SPC_LINEAR;
}
else if (xml_strcmp(val, "fixed") == 0) {
spc->cost = SPC_FIX;
}
else {
handle_bad_input(pi, key, val);
}
}
else {
handle_bad_input(pi, el, key);
}
}
}
else if (xml_strcmp(el, "spell") == 0) {
spell *sp;
@ -962,14 +997,33 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char
case EXP_SPELLS:
start_spells(pi, el, attr);
break;
case EXP_UNKNOWN:
handle_bad_input(pi, el, NULL);
break;
default:
/* not implemented */
handle_bad_input(pi, el, NULL);
return;
}
}
++pi->depth;
}
static void end_spells(parseinfo *pi, const XML_Char *el) {
if (xml_strcmp(el, "spells") == 0) {
pi->type = EXP_UNKNOWN;
}
else if (xml_strcmp(el, "spell") == 0) {
spell *sp = (spell *)pi->object;
if (ncomponents > 0) {
sp->components = calloc(sizeof(spell_component), ncomponents + 1);
memcpy(sp->components, components, sizeof(spell_component) * ncomponents);
ncomponents = 0;
}
pi->object = NULL;
}
}
static void end_weapon(parseinfo *pi, const XML_Char *el) {
resource_type *rtype = (resource_type *)pi->object;
assert(rtype && rtype->wtype);
@ -1093,6 +1147,9 @@ static void XMLCALL handle_end(void *data, const XML_Char *el) {
case EXP_WEAPON:
end_weapon(pi, el);
break;
case EXP_SPELLS:
end_spells(pi, el);
break;
default:
if (pi->depth == 1) {
pi->object = NULL;
@ -1160,7 +1217,9 @@ int exparse_readfile(const char * filename) {
break;
}
}
assert(pi.depth == 0);
if (pi.depth != 0) {
err = -3;
}
XML_ParserFree(xp);
fclose(F);
if (err != 0) {

View file

@ -166,15 +166,15 @@ extern "C" {
#define SHIPSPELL (1<<6) /* ZAUBER .. <Schiff-Nr> [<Schiff-Nr> ..] */
#define BUILDINGSPELL (1<<7) /* ZAUBER .. <Gebaeude-Nr> [<Gebaeude-Nr> ..] */
#define REGIONSPELL (1<<8) /* wirkt auf struct region */
#define GLOBALTARGET (1<<9) /* Ziel kann ausserhalb der region sein */
#define PRECOMBATSPELL (1<<9) /* PRÄKAMPFZAUBER .. */
#define COMBATSPELL (1<<10) /* KAMPFZAUBER .. */
#define POSTCOMBATSPELL (1<<11) /* POSTKAMPFZAUBER .. */
#define PRECOMBATSPELL (1<<10) /* PRÄKAMPFZAUBER .. */
#define COMBATSPELL (1<<11) /* KAMPFZAUBER .. */
#define POSTCOMBATSPELL (1<<12) /* POSTKAMPFZAUBER .. */
#define ISCOMBATSPELL (PRECOMBATSPELL|COMBATSPELL|POSTCOMBATSPELL)
#define TESTRESISTANCE (1<<12) /* alle Zielobjekte (u, s, b, r) auf
Magieresistenz prüfen */
#define GLOBALTARGET (1<<13) /* Ziel muss in der target_region sein */
#define TESTRESISTANCE (1<<13) /* Zielobjekte auf Magieresistenz prüfen. not used in XML? */
#define NOTFAMILIARCAST (1<<14) /* not used by XML? */
#define ANYTARGET (UNITSPELL|REGIONSPELL|BUILDINGSPELL|SHIPSPELL) /* wirkt auf alle objekttypen (unit, ship, building, region) */