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; 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) { static void XMLCALL start_spells(parseinfo *pi, const XML_Char *el, const XML_Char **attr) {
const char *flag_names[] = { const char *flag_names[] = {
"far", "variable", "ocean", "ship", "los", "far", "variable", "ocean", "ship", "los",
"unittarget", "shiptarget", "buildingtarget", "regiontarget", NULL }; "unittarget", "shiptarget", "buildingtarget", "regiontarget", "globaltarget", NULL };
if (xml_strcmp(el, "resource") == 0) { if (xml_strcmp(el, "resource") == 0) {
spell_component *spc = NULL; spell_component *spc;
(void)spc; int i;
handle_bad_input(pi, el, NULL);
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) { else if (xml_strcmp(el, "spell") == 0) {
spell *sp; spell *sp;
@ -962,14 +997,33 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char
case EXP_SPELLS: case EXP_SPELLS:
start_spells(pi, el, attr); start_spells(pi, el, attr);
break; break;
case EXP_UNKNOWN:
handle_bad_input(pi, el, NULL);
break;
default: default:
/* not implemented */ /* not implemented */
handle_bad_input(pi, el, NULL); handle_bad_input(pi, el, NULL);
return;
} }
} }
++pi->depth; ++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) { static void end_weapon(parseinfo *pi, const XML_Char *el) {
resource_type *rtype = (resource_type *)pi->object; resource_type *rtype = (resource_type *)pi->object;
assert(rtype && rtype->wtype); assert(rtype && rtype->wtype);
@ -1093,6 +1147,9 @@ static void XMLCALL handle_end(void *data, const XML_Char *el) {
case EXP_WEAPON: case EXP_WEAPON:
end_weapon(pi, el); end_weapon(pi, el);
break; break;
case EXP_SPELLS:
end_spells(pi, el);
break;
default: default:
if (pi->depth == 1) { if (pi->depth == 1) {
pi->object = NULL; pi->object = NULL;
@ -1160,7 +1217,9 @@ int exparse_readfile(const char * filename) {
break; break;
} }
} }
assert(pi.depth == 0); if (pi.depth != 0) {
err = -3;
}
XML_ParserFree(xp); XML_ParserFree(xp);
fclose(F); fclose(F);
if (err != 0) { if (err != 0) {

View file

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