diff --git a/src/exparse.c b/src/exparse.c index bbb1155cc..702c80557 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -273,6 +273,51 @@ static void handle_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **at wtype->flags = flags; } +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 }; + if (xml_strcmp(el, "spell") == 0) { + spell *sp; + const XML_Char *name = NULL, *syntax = NULL, *parameter = NULL; + int i, rank = 0, flags = 0; + for (i = 0; attr[i]; i += 2) { + const XML_Char *key = attr[i], *val = attr[i + 1]; + if (xml_strcmp(key, "name") == 0) { + name = val; + } + else if (xml_strcmp(key, "syntax") == 0) { + syntax = val; + } + else if (xml_strcmp(key, "parameters") == 0) { + parameter = val; + } + else if (xml_strcmp(key, "rank") == 0) { + rank = xml_int(val); + } + else if (xml_strcmp(key, "combat") == 0) { + int mode = PRECOMBATSPELL; + int k = xml_int(val); + if (k > 1 && k <= 3) { + mode = mode << (k - 1); + } + flags |= mode; + } + else if (!handle_flag(&flags, attr + i, flag_names)) { + handle_bad_input(pi, el, attr[i]); + } + } + pi->object = sp = create_spell(name); + sp->rank = rank; + sp->syntax = str_strdup(syntax); + sp->parameter = str_strdup(parameter); + sp->sptyp = flags; + } + else { + handle_bad_input(pi, el, NULL); + } +} + static void XMLCALL start_spellbooks(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { spellbook * sb = (spellbook *)pi->object; if (xml_strcmp(el, "spellbook") == 0) { @@ -908,6 +953,9 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char case EXP_SPELLBOOKS: start_spellbooks(pi, el, attr); break; + case EXP_SPELLS: + start_spells(pi, el, attr); + break; default: /* not implemented */ handle_bad_input(pi, el, NULL); diff --git a/src/magic.h b/src/magic.h index 4a00a7b13..fd87428ae 100644 --- a/src/magic.h +++ b/src/magic.h @@ -154,28 +154,28 @@ extern "C" { #define FARCASTING (1<<0) /* ZAUBER [struct region x y] */ #define SPELLLEVEL (1<<1) /* ZAUBER [STUFE x] */ - /* ID's können zu drei unterschiedlichen Entitäten gehören: Einheiten, - * Gebäuden und Schiffen. */ -#define UNITSPELL (1<<2) /* ZAUBER .. [ ..] */ -#define SHIPSPELL (1<<3) /* ZAUBER .. [ ..] */ -#define BUILDINGSPELL (1<<4) /* ZAUBER .. [ ..] */ -#define REGIONSPELL (1<<5) /* wirkt auf struct region */ +#define OCEANCASTABLE (1<<2) /* Können auch nicht-Meermenschen auf + hoher See zaubern */ +#define ONSHIPCAST (1<<3) /* kann auch auf von Land ablegenden + Schiffen stehend gezaubert werden */ +#define TESTCANSEE (1<<4) /* alle Zielunits auf cansee prüfen */ -#define PRECOMBATSPELL (1<<7) /* PRÄKAMPFZAUBER .. */ -#define COMBATSPELL (1<<8) /* KAMPFZAUBER .. */ -#define POSTCOMBATSPELL (1<<9) /* POSTKAMPFZAUBER .. */ + /* ID's können zu drei unterschiedlichen Entitäten gehören: Einheiten, + * Gebäuden und Schiffen. */ +#define UNITSPELL (1<<5) /* ZAUBER .. [ ..] */ +#define SHIPSPELL (1<<6) /* ZAUBER .. [ ..] */ +#define BUILDINGSPELL (1<<7) /* ZAUBER .. [ ..] */ +#define REGIONSPELL (1<<8) /* wirkt auf struct region */ + +#define PRECOMBATSPELL (1<<9) /* PRÄKAMPFZAUBER .. */ +#define COMBATSPELL (1<<10) /* KAMPFZAUBER .. */ +#define POSTCOMBATSPELL (1<<11) /* POSTKAMPFZAUBER .. */ #define ISCOMBATSPELL (PRECOMBATSPELL|COMBATSPELL|POSTCOMBATSPELL) -#define OCEANCASTABLE (1<<10) /* Können auch nicht-Meermenschen auf - hoher See zaubern */ -#define ONSHIPCAST (1<<11) /* kann auch auf von Land ablegenden - Schiffen stehend gezaubert werden */ - /* */ -#define NOTFAMILIARCAST (1<<12) -#define TESTRESISTANCE (1<<13) /* alle Zielobjekte (u, s, b, r) auf +#define TESTRESISTANCE (1<<12) /* alle Zielobjekte (u, s, b, r) auf Magieresistenz prüfen */ -#define SEARCHLOCAL (1<<14) /* Ziel muss in der target_region sein */ -#define TESTCANSEE (1<<15) /* alle Zielunits auf cansee prüfen */ +#define SEARCHLOCAL (1<<13) /* Ziel muss in der target_region sein */ +#define NOTFAMILIARCAST (1<<14) /* not used by XML? */ #define ANYTARGET (UNITSPELL|REGIONSPELL|BUILDINGSPELL|SHIPSPELL) /* wirkt auf alle objekttypen (unit, ship, building, region) */ /* Flag Spruchkostenberechnung: */ diff --git a/src/xmlreader.c b/src/xmlreader.c index 006c37a8a..9d910f6fe 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -1174,7 +1174,7 @@ static int parse_spells(xmlDocPtr doc) sp->syntax = str_strdup((const char *)propValue); xmlFree(propValue); } - sp->rank = (char)xml_ivalue(node, "rank", 0); + sp->rank = (char)xml_ivalue(node, "rank", sp->rank); if (xml_bvalue(node, "los", false)) sp->sptyp |= TESTCANSEE; /* must see or have contact */ if (!xml_bvalue(node, "target_global", false)) @@ -1705,12 +1705,12 @@ void register_xmlreader(void) xml_register_callback(parse_resources); xml_register_callback(parse_buildings); xml_register_callback(parse_ships); + xml_register_callback(parse_spellbooks); #endif xml_register_callback(parse_races); xml_register_callback(parse_equipment); xml_register_callback(parse_spells); - xml_register_callback(parse_spellbooks); xml_register_callback(parse_strings); xml_register_callback(parse_messages);