diff --git a/src/exparse.c b/src/exparse.c index c98d28d6e..590cb446b 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -541,6 +541,70 @@ static void XMLCALL start_resources(parseinfo *pi, const XML_Char *el, const XML } } +const XML_Char *attr_get(const XML_Char **attr, const char *key) { + int i; + for (i = 0; attr[i]; i += 2) { + if (xml_strcmp(attr[i], key) == 0) { + return attr[i + 1]; + } + } + return NULL; +} + +static void XMLCALL start_buildings(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { + const char *flag_names[] = { "nodestroy", "nobuild", "unique", "decay", "magic", "namechange", "fort", "oneperturn", NULL }; + if (xml_strcmp(el, "building") == 0) { + const XML_Char *name; + + name = attr_get(attr, "name"); + if (name) { + building_type *btype = bt_get_or_create(name); + int i, flags = BTF_DEFAULT; + + for (i = 0; attr[i]; i += 2) { + if (xml_strcmp(attr[i], "maxsize") == 0) { + btype->maxsize = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "capacity") == 0) { + btype->capacity = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "maxcapacity") == 0) { + btype->maxcapacity = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "magresbonus") == 0) { + btype->magresbonus = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "fumblebonus") == 0) { + btype->fumblebonus = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "taxes") == 0) { + btype->taxes = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "auraregen") == 0) { + btype->auraregen = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "magres") == 0) { + /* magres is specified in percent! */ + btype->magres = frac_make(xml_int(attr[i + 1]), 100); + } + else if (!handle_flag(&flags, attr + i, flag_names)) { + /* we already handled the name earlier */ + if (xml_strcmp(attr[i], "name") != 0) { + handle_bad_input(pi, el, attr[i]); + } + } + } + btype->flags = flags; + pi->object = btype; + } + } + else { + building_type *btype = (building_type *)pi->object; + assert(btype); + handle_bad_input(pi, el, NULL); + } +} + static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char **attr) { parseinfo *pi = (parseinfo *)data; if (pi->depth == 0) { @@ -571,6 +635,9 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char } else { switch (pi->type) { + case EXP_BUILDINGS: + start_buildings(pi, el, attr); + break; case EXP_RESOURCES: start_resources(pi, el, attr); break; @@ -639,6 +706,7 @@ static void XMLCALL handle_end(void *data, const XML_Char *el) { break; default: if (pi->depth == 1) { + pi->object = NULL; pi->type = EXP_UNKNOWN; } if (pi->cdata) { diff --git a/src/kernel/building.c b/src/kernel/building.c index c71cbc552..f3f01905f 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -144,6 +144,7 @@ building_type *bt_get_or_create(const char *name) if (btype == NULL) { btype = calloc(sizeof(building_type), 1); btype->_name = str_strdup(name); + btype->flags = BTF_DEFAULT; btype->auraregen = 1.0; btype->maxsize = -1; btype->capacity = 1; diff --git a/src/kernel/building.h b/src/kernel/building.h index 915a756b7..eacf42942 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -48,11 +48,13 @@ extern "C" { #define BTF_NOBUILD 0x02 /* special, can't be built */ #define BTF_UNIQUE 0x04 /* only one per struct region (harbour) */ #define BTF_DECAY 0x08 /* decays when not occupied */ -#define BTF_DYNAMIC 0x10 /* dynamic type, needs bt_write */ -#define BTF_MAGIC 0x40 /* magical effect */ +#define BTF_MAGIC 0x10 /* magical effect */ +#define BTF_NAMECHANGE 0x20 /* name and description can be changed more than once */ +#define BTF_FORTIFICATION 0x40 /* building_protection, safe from monsters */ #define BTF_ONEPERTURN 0x80 /* one one sizepoint can be added per turn */ -#define BTF_NAMECHANGE 0x100 /* name and description can be changed more than once */ -#define BTF_FORTIFICATION 0x200 /* building_protection, safe from monsters */ +#define BTF_DYNAMIC 0x100 /* dynamic type, needs bt_write */ + +#define BTF_DEFAULT (BTF_NAMECHANGE) typedef struct building_stage { /* construction of this building stage: */ diff --git a/src/tests.c b/src/tests.c index e3799c1b5..696baf447 100644 --- a/src/tests.c +++ b/src/tests.c @@ -338,7 +338,6 @@ building_type * test_create_buildingtype(const char * name) { construction *con; building_type *btype = bt_get_or_create(name); - btype->flags = BTF_NAMECHANGE; if (btype->stages) { con = btype->stages->construction; } else { diff --git a/src/xmlreader.c b/src/xmlreader.c index 45003e021..eea73e234 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -325,20 +325,20 @@ static int parse_buildings(xmlDocPtr doc) if (xml_bvalue(node, "nodestroy", false)) btype->flags |= BTF_INDESTRUCTIBLE; - if (xml_bvalue(node, "oneperturn", false)) - btype->flags |= BTF_ONEPERTURN; if (xml_bvalue(node, "nobuild", false)) btype->flags |= BTF_NOBUILD; - if (xml_bvalue(node, "namechange", true)) - btype->flags |= BTF_NAMECHANGE; if (xml_bvalue(node, "unique", false)) btype->flags |= BTF_UNIQUE; if (xml_bvalue(node, "decay", false)) btype->flags |= BTF_DECAY; if (xml_bvalue(node, "magic", false)) btype->flags |= BTF_MAGIC; + if (xml_bvalue(node, "namechange", true)) + btype->flags |= BTF_NAMECHANGE; if (xml_bvalue(node, "fort", false)) btype->flags |= BTF_FORTIFICATION; + if (xml_bvalue(node, "oneperturn", false)) + btype->flags |= BTF_ONEPERTURN; /* reading eressea/buildings/building/modifier */ xpath->node = node; @@ -1172,18 +1172,6 @@ static int parse_spells(xmlDocPtr doc) sp->syntax = str_strdup((const char *)propValue); xmlFree(propValue); } -#ifdef TODO /* no longer need it, spellbooks! */ - /* magic type */ - propValue = xmlGetProp(node, BAD_CAST "type"); - assert(propValue != NULL); - for (sp->magietyp = 0; sp->magietyp != MAXMAGIETYP; ++sp->magietyp) { - if (strcmp(magic_school[sp->magietyp], (const char *)propValue) == 0) - break; - } - assert(sp->magietyp != MAXMAGIETYP); - xmlFree(propValue); - /* level, rank and flags */ -#endif sp->rank = (char)xml_ivalue(node, "rank", -1); if (xml_bvalue(node, "los", false)) sp->sptyp |= TESTCANSEE; /* must see or have contact */