From 0b097371a19ce24f438c344add27869daa1babd3 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 1 May 2018 11:18:18 +0200 Subject: [PATCH] items: less xpath, more child iteration. --- src/modules/score.c | 3 ++ src/xmlreader.c | 117 +++++++++++++++++++------------------------- 2 files changed, 53 insertions(+), 67 deletions(-) diff --git a/src/modules/score.c b/src/modules/score.c index 7b6cb07bb..0ffb73301 100644 --- a/src/modules/score.c +++ b/src/modules/score.c @@ -222,6 +222,9 @@ void score(void) int default_score(const item_type *itype) { int result = 0; + if (itype->rtype->wtype || itype->rtype->atype) { + result += 10; + } if (itype->construction) { requirement *req = itype->construction->materials; while (req->number) { diff --git a/src/xmlreader.c b/src/xmlreader.c index d98ddaa2b..fb8f8c18a 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -259,13 +259,14 @@ xml_readconstruction(xmlXPathContextPtr xpath, xmlNodePtr node, bool is_building } static void -xml_readconstructions(xmlXPathContextPtr xpath, xmlNodeSetPtr nodeSet, - construction **consPtr, bool is_building) +xml_readconstructions(xmlXPathContextPtr xpath, xmlNodeSetPtr nodeSet, building_type *btype) { + construction **consPtr = &btype->construction; int k; + for (k = 0; k != nodeSet->nodeNr; ++k) { xmlNodePtr node = nodeSet->nodeTab[k]; - construction *con = xml_readconstruction(xpath, node, is_building); + construction *con = xml_readconstruction(xpath, node, true); if (con) { *consPtr = con; @@ -349,7 +350,7 @@ static int parse_buildings(xmlDocPtr doc) /* reading eressea/buildings/building/construction */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "construction", xpath); - xml_readconstructions(xpath, result->nodesetval, &btype->construction, true); + xml_readconstructions(xpath, result->nodesetval, btype); xmlXPathFreeObject(result); /* reading eressea/buildings/building/function */ @@ -446,12 +447,6 @@ static int parse_ships(xmlDocPtr doc) st->range_max = xml_ivalue(node, "maxrange", st->range_max); st->storm = xml_fvalue(node, "storm", st->storm); - /* reading eressea/ships/ship/construction */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "construction", xpath); - xml_readconstructions(xpath, result->nodesetval, &st->construction, false); - xmlXPathFreeObject(result); - for (child = node->children; child; child = child->next) { if (strcmp((const char *)child->name, "modifier") == 0) { double value = xml_fvalue(child, "value", 0.0); @@ -464,6 +459,10 @@ static int parse_ships(xmlDocPtr doc) st->df_bonus = (int)value; xmlFree(propValue); } + else if (strcmp((const char *)child->name, "construction") == 0) { + assert(!st->construction); + st->construction = xml_readconstruction(xpath, child, false); + } } /* reading eressea/ships/ship/coast */ xpath->node = node; @@ -498,22 +497,25 @@ static int parse_ships(xmlDocPtr doc) return result; } -static void xml_readpotion(xmlXPathContextPtr xpath, item_type * itype) +static void xml_readpotion(xmlNodePtr node, item_type * itype) { - int level = xml_ivalue(xpath->node, "level", 0); + int level = xml_ivalue(node, "level", 0); + if ((itype->flags & ITF_CANUSE) == 0) { + log_error("potion %s has no use attribute", itype->rtype->_name); + itype->flags |= ITF_CANUSE; + } new_potiontype(itype, level); } -static luxury_type *xml_readluxury(xmlXPathContextPtr xpath, item_type * itype) +static luxury_type *xml_readluxury(xmlNodePtr node, item_type * itype) { - int price = xml_ivalue(xpath->node, "price", 0); + int price = xml_ivalue(node, "price", 0); return new_luxurytype(itype, price); } -static armor_type *xml_readarmor(xmlXPathContextPtr xpath, item_type * itype) +static armor_type *xml_readarmor(xmlNodePtr node, item_type * itype) { - xmlNodePtr node = xpath->node; armor_type *atype = NULL; unsigned int flags = ATF_NONE; int ac = xml_ivalue(node, "ac", 0); @@ -666,10 +668,9 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) { - xmlNodePtr node = xpath->node; + xmlNodePtr child, node = xpath->node; item_type *itype = NULL; unsigned int flags = ITF_NONE; - xmlXPathObjectPtr result; if (xml_bvalue(node, "cursed", false)) flags |= ITF_CURSED; @@ -688,63 +689,45 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) itype = rtype->itype ? rtype->itype : it_get_or_create(rtype); itype->weight = xml_ivalue(node, "weight", 0); itype->capacity = xml_ivalue(node, "capacity", 0); + itype->score = xml_ivalue(node, "score", 0); + mask_races(node, "allow", &itype->mask_allow); mask_races(node, "deny", &itype->mask_deny); itype->flags |= flags; - /* reading item/construction */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "construction", xpath); - xml_readconstructions(xpath, result->nodesetval, &itype->construction, false); - xmlXPathFreeObject(result); - - /* reading item/weapon */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "weapon", xpath); - assert(result->nodesetval->nodeNr <= 1); - if (result->nodesetval->nodeNr != 0) { - xpath->node = result->nodesetval->nodeTab[0]; - rtype->wtype = xml_readweapon(xpath, itype); - } - xmlXPathFreeObject(result); - - /* reading item/potion */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "potion", xpath); - assert(result->nodesetval->nodeNr <= 1); - if (result->nodesetval->nodeNr != 0) { - if ((itype->flags & ITF_CANUSE) == 0) { - log_error("potion %s has no use attribute", rtype->_name); - itype->flags |= ITF_CANUSE; + for (child = node->children; child; child = child->next) { + if (strcmp((const char *)child->name, "construction") == 0) { + /* reading item/construction */ + assert(!itype->construction); + xpath->node = child; + itype->construction = xml_readconstruction(xpath, child, false); + } + else if (strcmp((const char *)child->name, "weapon") == 0) { + /* reading item/weapon */ + assert(!rtype->wtype); + xpath->node = child; + rtype->wtype = xml_readweapon(xpath, itype); + } + else if (strcmp((const char *)child->name, "armor") == 0) { + /* reading item/weapon */ + assert(!rtype->atype); + rtype->atype = xml_readarmor(child, itype); + } + else if (strcmp((const char *)child->name, "luxury") == 0) { + /* reading item/luxury */ + assert(!rtype->ltype); + rtype->ltype = xml_readluxury(child, itype); + } + else if (strcmp((const char *)child->name, "potion") == 0) { + /* reading item/potion */ + xml_readpotion(child, itype); } - xpath->node = result->nodesetval->nodeTab[0]; - xml_readpotion(xpath, itype); } - xmlXPathFreeObject(result); - /* reading item/luxury */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "luxury", xpath); - assert(result->nodesetval->nodeNr <= 1); - if (result->nodesetval->nodeNr != 0) { - xpath->node = result->nodesetval->nodeTab[0]; - rtype->ltype = xml_readluxury(xpath, itype); + if (!itype->score) { + /* do this last, because score depends on itype data */ + itype->score = default_score(itype); } - xmlXPathFreeObject(result); - - /* reading item/armor */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "armor", xpath); - assert(result->nodesetval->nodeNr <= 1); - if (result->nodesetval->nodeNr != 0) { - xpath->node = result->nodesetval->nodeTab[0]; - rtype->atype = xml_readarmor(xpath, itype); - } - xmlXPathFreeObject(result); - - itype->score = xml_ivalue(node, "score", 0); - if (!itype->score) itype->score = default_score(itype); - return itype; }