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 result = 0;
if (itype->rtype->wtype || itype->rtype->atype) {
result += 10;
}
if (itype->construction) {
requirement *req = itype->construction->materials;
while (req->number) {

View file

@ -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;
}