items: less xpath, more child iteration.

This commit is contained in:
Enno Rehling 2018-05-01 11:18:18 +02:00
parent dddbf5287a
commit 0b097371a1
2 changed files with 53 additions and 67 deletions

View file

@ -222,6 +222,9 @@ void score(void)
int default_score(const item_type *itype) { int default_score(const item_type *itype) {
int result = 0; int result = 0;
if (itype->rtype->wtype || itype->rtype->atype) {
result += 10;
}
if (itype->construction) { if (itype->construction) {
requirement *req = itype->construction->materials; requirement *req = itype->construction->materials;
while (req->number) { while (req->number) {

View file

@ -259,13 +259,14 @@ xml_readconstruction(xmlXPathContextPtr xpath, xmlNodePtr node, bool is_building
} }
static void static void
xml_readconstructions(xmlXPathContextPtr xpath, xmlNodeSetPtr nodeSet, xml_readconstructions(xmlXPathContextPtr xpath, xmlNodeSetPtr nodeSet, building_type *btype)
construction **consPtr, bool is_building)
{ {
construction **consPtr = &btype->construction;
int k; int k;
for (k = 0; k != nodeSet->nodeNr; ++k) { for (k = 0; k != nodeSet->nodeNr; ++k) {
xmlNodePtr node = nodeSet->nodeTab[k]; xmlNodePtr node = nodeSet->nodeTab[k];
construction *con = xml_readconstruction(xpath, node, is_building); construction *con = xml_readconstruction(xpath, node, true);
if (con) { if (con) {
*consPtr = con; *consPtr = con;
@ -349,7 +350,7 @@ static int parse_buildings(xmlDocPtr doc)
/* reading eressea/buildings/building/construction */ /* reading eressea/buildings/building/construction */
xpath->node = node; xpath->node = node;
result = xmlXPathEvalExpression(BAD_CAST "construction", xpath); result = xmlXPathEvalExpression(BAD_CAST "construction", xpath);
xml_readconstructions(xpath, result->nodesetval, &btype->construction, true); xml_readconstructions(xpath, result->nodesetval, btype);
xmlXPathFreeObject(result); xmlXPathFreeObject(result);
/* reading eressea/buildings/building/function */ /* 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->range_max = xml_ivalue(node, "maxrange", st->range_max);
st->storm = xml_fvalue(node, "storm", st->storm); 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) { for (child = node->children; child; child = child->next) {
if (strcmp((const char *)child->name, "modifier") == 0) { if (strcmp((const char *)child->name, "modifier") == 0) {
double value = xml_fvalue(child, "value", 0.0); double value = xml_fvalue(child, "value", 0.0);
@ -464,6 +459,10 @@ static int parse_ships(xmlDocPtr doc)
st->df_bonus = (int)value; st->df_bonus = (int)value;
xmlFree(propValue); 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 */ /* reading eressea/ships/ship/coast */
xpath->node = node; xpath->node = node;
@ -498,22 +497,25 @@ static int parse_ships(xmlDocPtr doc)
return result; 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); 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); 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; armor_type *atype = NULL;
unsigned int flags = ATF_NONE; unsigned int flags = ATF_NONE;
int ac = xml_ivalue(node, "ac", 0); 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) static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype)
{ {
xmlNodePtr node = xpath->node; xmlNodePtr child, node = xpath->node;
item_type *itype = NULL; item_type *itype = NULL;
unsigned int flags = ITF_NONE; unsigned int flags = ITF_NONE;
xmlXPathObjectPtr result;
if (xml_bvalue(node, "cursed", false)) if (xml_bvalue(node, "cursed", false))
flags |= ITF_CURSED; 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 = rtype->itype ? rtype->itype : it_get_or_create(rtype);
itype->weight = xml_ivalue(node, "weight", 0); itype->weight = xml_ivalue(node, "weight", 0);
itype->capacity = xml_ivalue(node, "capacity", 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, "allow", &itype->mask_allow);
mask_races(node, "deny", &itype->mask_deny); mask_races(node, "deny", &itype->mask_deny);
itype->flags |= flags; itype->flags |= flags;
/* reading item/construction */ for (child = node->children; child; child = child->next) {
xpath->node = node; if (strcmp((const char *)child->name, "construction") == 0) {
result = xmlXPathEvalExpression(BAD_CAST "construction", xpath); /* reading item/construction */
xml_readconstructions(xpath, result->nodesetval, &itype->construction, false); assert(!itype->construction);
xmlXPathFreeObject(result); xpath->node = child;
itype->construction = xml_readconstruction(xpath, child, false);
/* reading item/weapon */ }
xpath->node = node; else if (strcmp((const char *)child->name, "weapon") == 0) {
result = xmlXPathEvalExpression(BAD_CAST "weapon", xpath); /* reading item/weapon */
assert(result->nodesetval->nodeNr <= 1); assert(!rtype->wtype);
if (result->nodesetval->nodeNr != 0) { xpath->node = child;
xpath->node = result->nodesetval->nodeTab[0]; rtype->wtype = xml_readweapon(xpath, itype);
rtype->wtype = xml_readweapon(xpath, itype); }
} else if (strcmp((const char *)child->name, "armor") == 0) {
xmlXPathFreeObject(result); /* reading item/weapon */
assert(!rtype->atype);
/* reading item/potion */ rtype->atype = xml_readarmor(child, itype);
xpath->node = node; }
result = xmlXPathEvalExpression(BAD_CAST "potion", xpath); else if (strcmp((const char *)child->name, "luxury") == 0) {
assert(result->nodesetval->nodeNr <= 1); /* reading item/luxury */
if (result->nodesetval->nodeNr != 0) { assert(!rtype->ltype);
if ((itype->flags & ITF_CANUSE) == 0) { rtype->ltype = xml_readluxury(child, itype);
log_error("potion %s has no use attribute", rtype->_name); }
itype->flags |= ITF_CANUSE; 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 */ if (!itype->score) {
xpath->node = node; /* do this last, because score depends on itype data */
result = xmlXPathEvalExpression(BAD_CAST "luxury", xpath); itype->score = default_score(itype);
assert(result->nodesetval->nodeNr <= 1);
if (result->nodesetval->nodeNr != 0) {
xpath->node = result->nodesetval->nodeTab[0];
rtype->ltype = xml_readluxury(xpath, 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; return itype;
} }