parse building stages, too.

This commit is contained in:
Enno Rehling 2018-05-01 20:58:30 +02:00
parent 7128e1fb5c
commit 59f74d0a98

View file

@ -81,6 +81,20 @@ static variant xml_fraction(const XML_Char *val) {
return frac_make(num, den); return frac_make(num, den);
} }
static building_stage *stage;
#define MAX_REQUIREMENTS 8
static requirement reqs[MAX_REQUIREMENTS];
static int nreqs;
#define RMOD_MAX 8
static resource_mod rmods[RMOD_MAX];
static int nrmods;
#define WMOD_MAX 8
static weapon_mod wmods[WMOD_MAX];
static int nwmods;
static void handle_bad_input(parseinfo *pi, const XML_Char *el, const XML_Char *attr) { static void handle_bad_input(parseinfo *pi, const XML_Char *el, const XML_Char *attr) {
if (attr) { if (attr) {
log_error("unknown attribute in <%s>: %s", el, attr); log_error("unknown attribute in <%s>: %s", el, attr);
@ -239,11 +253,6 @@ static void handle_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **at
wtype->flags = flags; wtype->flags = flags;
} }
#define WMOD_MAX 8
static weapon_mod wmods[WMOD_MAX];
static int nwmods;
static void XMLCALL start_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { static void XMLCALL start_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **attr) {
resource_type *rtype = (resource_type *)pi->object; resource_type *rtype = (resource_type *)pi->object;
@ -334,13 +343,25 @@ static void XMLCALL start_weapon(parseinfo *pi, const XML_Char *el, const XML_Ch
} }
} }
#define MAX_REQUIREMENTS 8 static void handle_requirement(parseinfo *pi, const XML_Char *el, const XML_Char **attr) {
static requirement reqs[MAX_REQUIREMENTS]; requirement *req;
static int nreqs; int i;
#define RMOD_MAX 8 assert(nreqs < MAX_REQUIREMENTS);
static resource_mod rmods[RMOD_MAX]; req = reqs + nreqs;
static int nrmods; for (i = 0; attr[i]; i += 2) {
if (xml_strcmp(attr[i], "type") == 0) {
req->rtype = rt_get_or_create(attr[i + 1]);
}
else if (xml_strcmp(attr[i], "quantity") == 0) {
req->number = xml_int(attr[i + 1]);
}
else {
handle_bad_input(pi, el, attr[i]);
}
}
++nreqs;
}
static void handle_modifier(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { static void handle_modifier(parseinfo *pi, const XML_Char *el, const XML_Char **attr) {
int i; int i;
@ -396,6 +417,37 @@ static void handle_modifier(parseinfo *pi, const XML_Char *el, const XML_Char **
} }
} }
static construction *parse_construction(parseinfo *pi, const XML_Char *el, const XML_Char **attr) {
construction *con = calloc(sizeof(construction), 1);
int i;
con->maxsize = -1;
con->minskill = -1;
con->reqsize = 1;
for (i = 0; attr[i]; i += 2) {
if (xml_strcmp(attr[i], "skill") == 0) {
con->skill = findskill(attr[i + 1]);
}
else if (xml_strcmp(attr[i], "maxsize") == 0) {
con->maxsize = xml_int(attr[i + 1]);
}
else if (xml_strcmp(attr[i], "reqsize") == 0) {
con->reqsize = xml_int(attr[i + 1]);
}
else if (xml_strcmp(attr[i], "minskill") == 0) {
con->minskill = xml_int(attr[i + 1]);
}
else if (stage != NULL && xml_strcmp(attr[i], "name") == 0) {
/* only building stages have names */
stage->name = str_strdup(attr[i + 1]);
}
else {
handle_bad_input(pi, el, attr[i]);
}
}
nreqs = 0;
return con;
}
static void start_resources(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { static void start_resources(parseinfo *pi, const XML_Char *el, const XML_Char **attr) {
resource_type *rtype = (resource_type *)pi->object; resource_type *rtype = (resource_type *)pi->object;
if (xml_strcmp(el, "resource") == 0) { if (xml_strcmp(el, "resource") == 0) {
@ -440,52 +492,14 @@ static void start_resources(parseinfo *pi, const XML_Char *el, const XML_Char **
else if (rtype->itype) { else if (rtype->itype) {
item_type *itype = rtype->itype; item_type *itype = rtype->itype;
if (xml_strcmp(el, "construction") == 0) { if (xml_strcmp(el, "construction") == 0) {
construction *con = calloc(sizeof(construction), 1); itype->construction = parse_construction(pi, el, attr);
int i;
con->maxsize = -1;
con->minskill = -1;
con->reqsize = 1;
for (i = 0; attr[i]; i += 2) {
if (xml_strcmp(attr[i], "skill") == 0) {
con->skill = findskill(attr[i + 1]);
}
else if (xml_strcmp(attr[i], "maxsize") == 0) {
con->maxsize = xml_int(attr[i + 1]);
}
else if (xml_strcmp(attr[i], "reqsize") == 0) {
con->reqsize = xml_int(attr[i + 1]);
}
else if (xml_strcmp(attr[i], "minskill") == 0) {
con->minskill = xml_int(attr[i + 1]);
}
else {
handle_bad_input(pi, el, attr[i]);
}
}
itype->construction = con;
nreqs = 0;
} }
else if (xml_strcmp(el, "modifier") == 0) { else if (xml_strcmp(el, "modifier") == 0) {
handle_modifier(pi, el, attr); handle_modifier(pi, el, attr);
} }
else if (xml_strcmp(el, "requirement") == 0) { else if (xml_strcmp(el, "requirement") == 0) {
requirement *req;
int i;
assert(itype->construction); assert(itype->construction);
assert(nreqs < MAX_REQUIREMENTS); handle_requirement(pi, el, attr);
req = reqs + nreqs;
for (i = 0; attr[i]; i += 2) {
if (xml_strcmp(attr[i], "type") == 0) {
req->rtype = rt_get_or_create(attr[i + 1]);
}
else if (xml_strcmp(attr[i], "quantity") == 0) {
req->number = xml_int(attr[i + 1]);
}
else {
handle_bad_input(pi, el, attr[i]);
}
}
++nreqs;
} }
else if (xml_strcmp(el, "luxury") == 0) { else if (xml_strcmp(el, "luxury") == 0) {
rtype->ltype = new_luxurytype(itype, 0); rtype->ltype = new_luxurytype(itype, 0);
@ -560,6 +574,7 @@ static void XMLCALL start_buildings(parseinfo *pi, const XML_Char *el, const XML
if (xml_strcmp(el, "building") == 0) { if (xml_strcmp(el, "building") == 0) {
const XML_Char *name; const XML_Char *name;
assert(stage == NULL);
name = attr_get(attr, "name"); name = attr_get(attr, "name");
if (name) { if (name) {
building_type *btype = bt_get_or_create(name); building_type *btype = bt_get_or_create(name);
@ -602,13 +617,25 @@ static void XMLCALL start_buildings(parseinfo *pi, const XML_Char *el, const XML
pi->object = btype; pi->object = btype;
} }
} }
else if (xml_strcmp(el, "modifier") == 0) {
handle_modifier(pi, el, attr);
}
else { else {
building_type *btype = (building_type *)pi->object; building_type *btype = (building_type *)pi->object;
assert(btype); assert(btype);
handle_bad_input(pi, el, NULL); if (xml_strcmp(el, "modifier") == 0) {
handle_modifier(pi, el, attr);
}
else if (xml_strcmp(el, "requirement") == 0) {
assert(stage);
assert(stage->construction);
handle_requirement(pi, el, attr);
}
else if (xml_strcmp(el, "construction") == 0) {
assert(stage == NULL);
stage = calloc(1, sizeof(building_stage));
stage->construction = parse_construction(pi, el, attr);
}
else {
handle_bad_input(pi, el, NULL);
}
} }
} }
@ -701,9 +728,32 @@ static void end_resources(parseinfo *pi, const XML_Char *el) {
} }
} }
static void end_buildings(parseinfo *pi, const XML_Char *el) { static void end_buildings(parseinfo *pi, const XML_Char *el) {
/* stores the end of the building's stage list: */
static building_stage **stage_ptr;
building_type *btype = (building_type *)pi->object; building_type *btype = (building_type *)pi->object;
if (xml_strcmp(el, "building") == 0) { if (xml_strcmp(el, "construction") == 0) {
if (stage) {
if (nreqs > 0) {
construction *con = stage->construction;
con->materials = calloc(sizeof(requirement), nreqs + 1);
memcpy(con->materials, reqs, sizeof(requirement) * nreqs);
nreqs = 0;
}
if (stage_ptr == NULL) {
/* at the first build stage, initialize stage_ptr: */
assert(btype->stages == NULL);
stage_ptr = &btype->stages;
}
*stage_ptr = stage;
stage_ptr = &stage->next;
stage = NULL;
}
}
else if (xml_strcmp(el, "building") == 0) {
stage_ptr = NULL;
if (nrmods > 0) { if (nrmods > 0) {
btype->modifiers = calloc(sizeof(resource_mod), nrmods + 1); btype->modifiers = calloc(sizeof(resource_mod), nrmods + 1);
memcpy(btype->modifiers, rmods, sizeof(resource_mod) * nrmods); memcpy(btype->modifiers, rmods, sizeof(resource_mod) * nrmods);