forked from github/server
parsing ships, done!
This commit is contained in:
parent
6d9ecd1879
commit
cb27895b81
1 changed files with 163 additions and 6 deletions
169
src/exparse.c
169
src/exparse.c
|
@ -10,6 +10,8 @@
|
||||||
#include "kernel/item.h"
|
#include "kernel/item.h"
|
||||||
#include "kernel/race.h"
|
#include "kernel/race.h"
|
||||||
#include "kernel/resources.h"
|
#include "kernel/resources.h"
|
||||||
|
#include "kernel/ship.h"
|
||||||
|
#include "kernel/terrain.h"
|
||||||
|
|
||||||
#include "util/functions.h"
|
#include "util/functions.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
|
@ -42,6 +44,7 @@ enum {
|
||||||
EXP_WEAPON,
|
EXP_WEAPON,
|
||||||
EXP_BUILDINGS,
|
EXP_BUILDINGS,
|
||||||
EXP_SHIPS,
|
EXP_SHIPS,
|
||||||
|
EXP_RACES,
|
||||||
EXP_MESSAGES,
|
EXP_MESSAGES,
|
||||||
EXP_STRINGS,
|
EXP_STRINGS,
|
||||||
};
|
};
|
||||||
|
@ -81,6 +84,16 @@ static variant xml_fraction(const XML_Char *val) {
|
||||||
return frac_make(num, den);
|
return frac_make(num, den);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 building_stage *stage;
|
static building_stage *stage;
|
||||||
|
|
||||||
#define UPKEEP_MAX 4
|
#define UPKEEP_MAX 4
|
||||||
|
@ -393,6 +406,20 @@ static void handle_maintenance(parseinfo *pi, const XML_Char *el, const XML_Char
|
||||||
++nupkeep;
|
++nupkeep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define COASTS_MAX 16
|
||||||
|
static int ncoasts;
|
||||||
|
static struct terrain_type *coasts[COASTS_MAX];
|
||||||
|
|
||||||
|
static void handle_coast(parseinfo *pi, const XML_Char *el, const XML_Char **attr) {
|
||||||
|
const XML_Char *tname = attr_get(attr, "terrain");
|
||||||
|
|
||||||
|
if (tname) {
|
||||||
|
terrain_type *coast = get_or_create_terrain(tname);
|
||||||
|
assert(ncoasts < COASTS_MAX);
|
||||||
|
coasts[ncoasts++] = coast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
skill_t sk = NOSKILL;
|
skill_t sk = NOSKILL;
|
||||||
|
@ -589,14 +616,109 @@ static void start_resources(parseinfo *pi, const XML_Char *el, const XML_Char **
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const XML_Char *attr_get(const XML_Char **attr, const char *key) {
|
static void XMLCALL start_ships(parseinfo *pi, const XML_Char *el, const XML_Char **attr) {
|
||||||
int i;
|
const char *flag_names[] = { "opensea", "fly", "nocoast", "speedy", NULL };
|
||||||
for (i = 0; attr[i]; i += 2) {
|
if (xml_strcmp(el, "ship") == 0) {
|
||||||
if (xml_strcmp(attr[i], key) == 0) {
|
const XML_Char *name;
|
||||||
return attr[i + 1];
|
|
||||||
|
name = attr_get(attr, "name");
|
||||||
|
if (name) {
|
||||||
|
ship_type *stype = st_get_or_create(name);
|
||||||
|
int i, flags = SFL_DEFAULT;
|
||||||
|
|
||||||
|
for (i = 0; attr[i]; i += 2) {
|
||||||
|
if (xml_strcmp(attr[i], "range") == 0) {
|
||||||
|
stype->range = xml_int(attr[i + 1]);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "maxrange") == 0) {
|
||||||
|
stype->range_max = xml_int(attr[i + 1]);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "cabins") == 0) {
|
||||||
|
stype->cabins = PERSON_WEIGHT * xml_int(attr[i + 1]);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "cargo") == 0) {
|
||||||
|
stype->cargo = xml_int(attr[i + 1]);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "combat") == 0) {
|
||||||
|
stype->combat = xml_int(attr[i + 1]);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "fishing") == 0) {
|
||||||
|
stype->fishing = xml_int(attr[i + 1]);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "cptskill") == 0) {
|
||||||
|
stype->cptskill = xml_int(attr[i + 1]);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "minskill") == 0) {
|
||||||
|
stype->minskill = xml_int(attr[i + 1]);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "sumskill") == 0) {
|
||||||
|
stype->sumskill = xml_int(attr[i + 1]);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "damage") == 0) {
|
||||||
|
stype->damage = xml_float(attr[i + 1]);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "storm") == 0) {
|
||||||
|
stype->storm = xml_float(attr[i + 1]);
|
||||||
|
}
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stype->flags = flags;
|
||||||
|
pi->object = stype;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ship_type *stype = (ship_type *)pi->object;
|
||||||
|
assert(stype);
|
||||||
|
if (xml_strcmp(el, "modifier") == 0) {
|
||||||
|
/* these modifiers are not like buildings */
|
||||||
|
int i;
|
||||||
|
const XML_Char *type = NULL, *value = NULL;
|
||||||
|
for (i = 0; attr[i]; i += 2) {
|
||||||
|
if (xml_strcmp(attr[i], "type") == 0) {
|
||||||
|
type = attr[i + 1];
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "value") == 0) {
|
||||||
|
value = attr[i + 1];
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "factor") == 0) {
|
||||||
|
value = attr[i + 1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
handle_bad_input(pi, el, attr[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type) {
|
||||||
|
if (xml_strcmp(type, "tactics") == 0) {
|
||||||
|
stype->tac_bonus = xml_float(value);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(type, "attack") == 0) {
|
||||||
|
stype->at_bonus = xml_int(value);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(type, "defense") == 0) {
|
||||||
|
stype->df_bonus = xml_int(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "requirement") == 0) {
|
||||||
|
assert(stype->construction);
|
||||||
|
handle_requirement(pi, el, attr);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "construction") == 0) {
|
||||||
|
assert(!stype->construction);
|
||||||
|
stype->construction = parse_construction(pi, el, attr);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "coast") == 0) {
|
||||||
|
handle_coast(pi, el, attr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
handle_bad_input(pi, el, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void XMLCALL start_buildings(parseinfo *pi, const XML_Char *el, const XML_Char **attr) {
|
static void XMLCALL start_buildings(parseinfo *pi, const XML_Char *el, const XML_Char **attr) {
|
||||||
|
@ -697,6 +819,9 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char
|
||||||
else if (xml_strcmp(el, "strings") == 0) {
|
else if (xml_strcmp(el, "strings") == 0) {
|
||||||
pi->type = EXP_STRINGS;
|
pi->type = EXP_STRINGS;
|
||||||
}
|
}
|
||||||
|
else if (xml_strcmp(el, "races") == 0) {
|
||||||
|
pi->type = EXP_RACES;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
handle_bad_input(pi, el, NULL);
|
handle_bad_input(pi, el, NULL);
|
||||||
}
|
}
|
||||||
|
@ -706,6 +831,9 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char
|
||||||
case EXP_BUILDINGS:
|
case EXP_BUILDINGS:
|
||||||
start_buildings(pi, el, attr);
|
start_buildings(pi, el, attr);
|
||||||
break;
|
break;
|
||||||
|
case EXP_SHIPS:
|
||||||
|
start_ships(pi, el, attr);
|
||||||
|
break;
|
||||||
case EXP_RESOURCES:
|
case EXP_RESOURCES:
|
||||||
start_resources(pi, el, attr);
|
start_resources(pi, el, attr);
|
||||||
break;
|
break;
|
||||||
|
@ -762,6 +890,30 @@ static void end_resources(parseinfo *pi, const XML_Char *el) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void end_ships(parseinfo *pi, const XML_Char *el) {
|
||||||
|
ship_type *stype = (ship_type *)pi->object;
|
||||||
|
if (xml_strcmp(el, "construction") == 0) {
|
||||||
|
assert(stype);
|
||||||
|
assert(stype->construction);
|
||||||
|
if (nreqs > 0) {
|
||||||
|
construction *con = stype->construction;
|
||||||
|
con->materials = calloc(sizeof(requirement), nreqs + 1);
|
||||||
|
memcpy(con->materials, reqs, sizeof(requirement) * nreqs);
|
||||||
|
nreqs = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "ship") == 0) {
|
||||||
|
if (ncoasts > 0) {
|
||||||
|
stype->coasts = calloc(sizeof(const terrain_type *), ncoasts + 1);
|
||||||
|
memcpy(stype->coasts, coasts, sizeof(const terrain_type *) * ncoasts);
|
||||||
|
ncoasts = 0;
|
||||||
|
}
|
||||||
|
pi->object = NULL;
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "ships") == 0) {
|
||||||
|
pi->type = EXP_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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: */
|
/* stores the end of the building's stage list: */
|
||||||
|
@ -769,6 +921,7 @@ static void end_buildings(parseinfo *pi, const XML_Char *el) {
|
||||||
|
|
||||||
building_type *btype = (building_type *)pi->object;
|
building_type *btype = (building_type *)pi->object;
|
||||||
if (xml_strcmp(el, "construction") == 0) {
|
if (xml_strcmp(el, "construction") == 0) {
|
||||||
|
assert(btype);
|
||||||
if (stage) {
|
if (stage) {
|
||||||
if (nreqs > 0) {
|
if (nreqs > 0) {
|
||||||
construction *con = stage->construction;
|
construction *con = stage->construction;
|
||||||
|
@ -798,6 +951,7 @@ static void end_buildings(parseinfo *pi, const XML_Char *el) {
|
||||||
memcpy(btype->modifiers, rmods, sizeof(resource_mod) * nrmods);
|
memcpy(btype->modifiers, rmods, sizeof(resource_mod) * nrmods);
|
||||||
nrmods = 0;
|
nrmods = 0;
|
||||||
}
|
}
|
||||||
|
pi->object = NULL;
|
||||||
}
|
}
|
||||||
else if (xml_strcmp(el, "buildings") == 0) {
|
else if (xml_strcmp(el, "buildings") == 0) {
|
||||||
pi->type = EXP_UNKNOWN;
|
pi->type = EXP_UNKNOWN;
|
||||||
|
@ -808,6 +962,9 @@ static void XMLCALL handle_end(void *data, const XML_Char *el) {
|
||||||
parseinfo *pi = (parseinfo *)data;
|
parseinfo *pi = (parseinfo *)data;
|
||||||
|
|
||||||
switch (pi->type) {
|
switch (pi->type) {
|
||||||
|
case EXP_SHIPS:
|
||||||
|
end_ships(pi, el);
|
||||||
|
break;
|
||||||
case EXP_BUILDINGS:
|
case EXP_BUILDINGS:
|
||||||
end_buildings(pi, el);
|
end_buildings(pi, el);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue