forked from github/server
exparse: parse (most of) the resource data.
This commit is contained in:
parent
08663b6eb5
commit
edadf2cbab
7 changed files with 374 additions and 35 deletions
317
src/exparse.c
317
src/exparse.c
|
@ -3,21 +3,330 @@
|
||||||
#endif
|
#endif
|
||||||
#include "exparse.h"
|
#include "exparse.h"
|
||||||
|
|
||||||
|
#include "kernel/build.h"
|
||||||
|
#include "kernel/item.h"
|
||||||
|
#include "kernel/resources.h"
|
||||||
|
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
|
|
||||||
#include <expat.h>
|
#include <expat.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef XML_LARGE_SIZE
|
||||||
|
# if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
|
||||||
|
# define XML_FMT_INT_MOD "I64"
|
||||||
|
# else
|
||||||
|
# define XML_FMT_INT_MOD "ll"
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define XML_FMT_INT_MOD "l"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef XML_UNICODE_WCHAR_T
|
||||||
|
# define XML_FMT_STR "ls"
|
||||||
|
#else
|
||||||
|
# define XML_FMT_STR "s"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum {
|
||||||
|
EXP_UNKNOWN,
|
||||||
|
|
||||||
|
EXP_RESOURCES,
|
||||||
|
EXP_BUILDINGS,
|
||||||
|
EXP_SHIPS,
|
||||||
|
EXP_MESSAGES,
|
||||||
|
EXP_STRINGS,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct userdata {
|
||||||
|
int type;
|
||||||
|
int depth;
|
||||||
|
int errors;
|
||||||
|
XML_Char *cdata;
|
||||||
|
size_t clength;
|
||||||
|
void *object;
|
||||||
|
} userdata;
|
||||||
|
|
||||||
|
static int xml_strcmp(const XML_Char *xs, const char *cs) {
|
||||||
|
return strcmp(xs, cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const 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 (const char *)attr[i + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool xml_bool(const XML_Char *val) {
|
||||||
|
if (xml_strcmp(val, "yes") == 0) return true;
|
||||||
|
if (xml_strcmp(val, "true") == 0) return true;
|
||||||
|
if (xml_strcmp(val, "1") == 0) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xml_int(const XML_Char *val) {
|
||||||
|
return atoi((const char *)val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool attr_bool(XML_Char **pair, const char *key) {
|
||||||
|
if (xml_strcmp(pair[0], key) == 0) {
|
||||||
|
return xml_bool(pair[1]);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_bad_input(userdata *ud, const XML_Char *el, const XML_Char *attr) {
|
||||||
|
if (attr) {
|
||||||
|
log_error("unknown attribute in <%s>: %s", (const char *)el, (const char *)attr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log_error("unexpected element <%s>", (const char *)el);
|
||||||
|
}
|
||||||
|
++ud->errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool handle_flag(int *flags, const XML_Char **pair, const char *names[]) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; names[i]; ++i) {
|
||||||
|
if (xml_strcmp(pair[0], names[i]) == 0) {
|
||||||
|
if (xml_bool(pair[1])) {
|
||||||
|
*flags |= (1 << i);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*flags &= ~(1 << i);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_resource(userdata *ud, const XML_Char *el, const XML_Char **attr) {
|
||||||
|
const char *flag_names[] = { "item", "limited", "pooled", NULL };
|
||||||
|
int i;
|
||||||
|
const char *name = NULL, *appear = NULL;
|
||||||
|
int flags = RTF_POOLED;
|
||||||
|
bool material = false;
|
||||||
|
(void)el;
|
||||||
|
for (i = 0; attr[i]; i += 2) {
|
||||||
|
if (xml_strcmp(attr[i], "name") == 0) {
|
||||||
|
name = (const char *)attr[i + 1];
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "appearance") == 0) {
|
||||||
|
/* TODO: appearance should be a property of item, not resource */
|
||||||
|
appear = (const char *)attr[i + 1];
|
||||||
|
flags |= RTF_ITEM;
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "material") == 0) {
|
||||||
|
/* TODO: appearance should be a property of item, not resource */
|
||||||
|
material = xml_bool(attr[i + 1]);
|
||||||
|
}
|
||||||
|
else if (!handle_flag(&flags, attr + i, flag_names)) {
|
||||||
|
handle_bad_input(ud, el, attr[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name) {
|
||||||
|
resource_type *rtype = rt_get_or_create(name);
|
||||||
|
rtype->flags = flags;
|
||||||
|
if (appear) {
|
||||||
|
/* TODO: appearance should be a property of item, not resource */
|
||||||
|
rtype->itype = it_get_or_create(rtype);
|
||||||
|
it_set_appearance(rtype->itype, appear);
|
||||||
|
}
|
||||||
|
if (material) {
|
||||||
|
rmt_create(rtype);
|
||||||
|
}
|
||||||
|
ud->object = rtype;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_item(userdata *ud, const XML_Char *el, const XML_Char **attr) {
|
||||||
|
const char *flag_names[] = { "herb", "cursed", "notlost", "big", "animal", "vehicle", "use", NULL };
|
||||||
|
int i, flags = ITF_NONE;
|
||||||
|
resource_type *rtype = (resource_type *)ud->object;
|
||||||
|
item_type * itype = rtype->itype;
|
||||||
|
assert(rtype);
|
||||||
|
if (!itype) {
|
||||||
|
itype = it_get_or_create(rtype);
|
||||||
|
}
|
||||||
|
for (i = 0; attr[i]; i += 2) {
|
||||||
|
if (xml_strcmp(attr[i], "weight") == 0) {
|
||||||
|
itype->weight = xml_int(attr[i + 1]);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "capacity") == 0) {
|
||||||
|
itype->capacity = xml_int(attr[i + 1]);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(attr[i], "score") == 0) {
|
||||||
|
itype->score = xml_int(attr[i + 1]);
|
||||||
|
}
|
||||||
|
else if (!handle_flag(&flags, attr + i, flag_names)) {
|
||||||
|
handle_bad_input(ud, el, attr[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
itype->flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void XMLCALL handle_resources(userdata *ud, const XML_Char *el, const XML_Char **attr) {
|
||||||
|
resource_type *rtype = (resource_type *)ud->object;
|
||||||
|
if (xml_strcmp(el, "resource") == 0) {
|
||||||
|
handle_resource(ud, el, attr);
|
||||||
|
}
|
||||||
|
else if (rtype) {
|
||||||
|
if (xml_strcmp(el, "item") == 0) {
|
||||||
|
assert(rtype);
|
||||||
|
handle_item(ud, el, attr);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "function") == 0) {
|
||||||
|
assert(rtype);
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
else if (rtype->itype) {
|
||||||
|
item_type *itype = rtype->itype;
|
||||||
|
if (xml_strcmp(el, "construction") == 0) {
|
||||||
|
construction *con = calloc(sizeof(construction), 1);
|
||||||
|
int i;
|
||||||
|
for (i = 0; attr[i]; i += 2) {
|
||||||
|
if (xml_strcmp(attr[i], "skill") == 0) {
|
||||||
|
con->skill = findskill((const char *)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(ud, el, attr[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
itype->construction = con;
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "requirement") == 0) {
|
||||||
|
assert(itype->construction);
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "luxury") == 0) {
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "potion") == 0) {
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "armor") == 0) {
|
||||||
|
/* TODO */
|
||||||
|
rtype->atype = new_armortype(itype, 0.0, frac_zero, 0, 0);
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "weapon") == 0) {
|
||||||
|
rtype->wtype = new_weapontype(itype, 0, frac_zero, NULL, 0, 0, 0, SK_MELEE);
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "damage") == 0) {
|
||||||
|
assert(rtype->wtype);
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
handle_bad_input(ud, el, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
handle_bad_input(ud, el, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
handle_bad_input(ud, el, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char **attr) {
|
||||||
|
userdata *ud = (userdata *)data;
|
||||||
|
if (ud->depth == 0) {
|
||||||
|
ud->type = EXP_UNKNOWN;
|
||||||
|
if (xml_strcmp(el, "eressea") != 0) {
|
||||||
|
handle_bad_input(ud, el, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ud->depth == 1) {
|
||||||
|
if (xml_strcmp(el, "resources") == 0) {
|
||||||
|
ud->type = EXP_RESOURCES;
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "buildings") == 0) {
|
||||||
|
ud->type = EXP_BUILDINGS;
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "ships") == 0) {
|
||||||
|
ud->type = EXP_SHIPS;
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "messages") == 0) {
|
||||||
|
ud->type = EXP_MESSAGES;
|
||||||
|
}
|
||||||
|
else if (xml_strcmp(el, "strings") == 0) {
|
||||||
|
ud->type = EXP_STRINGS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
handle_bad_input(ud, el, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (ud->type) {
|
||||||
|
case EXP_RESOURCES:
|
||||||
|
handle_resources(ud, el, attr);
|
||||||
|
default:
|
||||||
|
/* not implemented */
|
||||||
|
handle_bad_input(ud, el, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++ud->depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void XMLCALL handle_end(void *data, const XML_Char *el) {
|
||||||
|
userdata *ud = (userdata *)data;
|
||||||
|
--ud->depth;
|
||||||
|
if (ud->cdata) {
|
||||||
|
free(ud->cdata);
|
||||||
|
ud->cdata = NULL;
|
||||||
|
ud->clength = 0;
|
||||||
|
}
|
||||||
|
if (ud->depth == 0) {
|
||||||
|
ud->type = EXP_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void XMLCALL handle_data(void *data, const XML_Char *xs, int len) {
|
||||||
|
userdata *ud = (userdata *)data;
|
||||||
|
if (len > 0) {
|
||||||
|
if (ud->type == EXP_MESSAGES && ud->depth == 4) {
|
||||||
|
size_t bytes = (size_t)len;
|
||||||
|
ud->cdata = realloc(ud->cdata, ud->clength + bytes);
|
||||||
|
memcpy(ud->cdata + ud->clength, xs, bytes);
|
||||||
|
ud->clength = ud->clength + bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int exparse_readfile(const char * filename) {
|
int exparse_readfile(const char * filename) {
|
||||||
XML_Parser xp;
|
XML_Parser xp;
|
||||||
FILE *F;
|
FILE *F;
|
||||||
int err = 1;
|
int err = 1;
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
|
userdata ud;
|
||||||
|
|
||||||
F = fopen(filename, "r");
|
F = fopen(filename, "r");
|
||||||
if (!F) {
|
if (!F) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
xp = XML_ParserCreate("UTF-8");
|
xp = XML_ParserCreate("UTF-8");
|
||||||
|
XML_SetElementHandler(xp, handle_start, handle_end);
|
||||||
|
XML_SetCharacterDataHandler(xp, handle_data);
|
||||||
|
XML_SetUserData(xp, &ud);
|
||||||
|
memset(&ud, 0, sizeof(ud));
|
||||||
for (;;) {
|
for (;;) {
|
||||||
size_t len = (int) fread(buf, 1, sizeof(buf), F);
|
size_t len = (int) fread(buf, 1, sizeof(buf), F);
|
||||||
int done;
|
int done;
|
||||||
|
@ -29,7 +338,7 @@ int exparse_readfile(const char * filename) {
|
||||||
}
|
}
|
||||||
done = feof(F);
|
done = feof(F);
|
||||||
if (XML_Parse(xp, buf, len, done) == XML_STATUS_ERROR) {
|
if (XML_Parse(xp, buf, len, done) == XML_STATUS_ERROR) {
|
||||||
log_error("parse error at line %u of %s: %s",
|
log_error("parse error at line %" XML_FMT_INT_MOD " of %s: %" XML_FMT_STR,
|
||||||
XML_GetCurrentLineNumber(xp),
|
XML_GetCurrentLineNumber(xp),
|
||||||
filename,
|
filename,
|
||||||
XML_ErrorString(XML_GetErrorCode(xp)));
|
XML_ErrorString(XML_GetErrorCode(xp)));
|
||||||
|
@ -40,7 +349,11 @@ int exparse_readfile(const char * filename) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
assert(ud.depth == 0);
|
||||||
XML_ParserFree(xp);
|
XML_ParserFree(xp);
|
||||||
fclose(F);
|
fclose(F);
|
||||||
return err;
|
if (err != 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return ud.errors;
|
||||||
}
|
}
|
||||||
|
|
|
@ -916,7 +916,11 @@ static void free_itype(item_type *itype) {
|
||||||
free(itype);
|
free(itype);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_wtype(weapon_type *wtype) {
|
void free_atype(armor_type *atype) {
|
||||||
|
free(atype);
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_wtype(weapon_type *wtype) {
|
||||||
assert(wtype);
|
assert(wtype);
|
||||||
free(wtype->damage[0]);
|
free(wtype->damage[0]);
|
||||||
free(wtype->damage[1]);
|
free(wtype->damage[1]);
|
||||||
|
@ -931,7 +935,9 @@ void free_rtype(resource_type *rtype) {
|
||||||
if (rtype->itype) {
|
if (rtype->itype) {
|
||||||
free_itype(rtype->itype);
|
free_itype(rtype->itype);
|
||||||
}
|
}
|
||||||
free(rtype->atype);
|
if (rtype->atype) {
|
||||||
|
free_atype(rtype->atype);
|
||||||
|
}
|
||||||
free(rtype->modifiers);
|
free(rtype->modifiers);
|
||||||
free(rtype->raw);
|
free(rtype->raw);
|
||||||
free(rtype->_name);
|
free(rtype->_name);
|
||||||
|
|
|
@ -224,9 +224,10 @@ extern "C" {
|
||||||
weapon_type *new_weapontype(item_type * itype, int wflags,
|
weapon_type *new_weapontype(item_type * itype, int wflags,
|
||||||
variant magres, const char *damage[], int offmod, int defmod, int reload,
|
variant magres, const char *damage[], int offmod, int defmod, int reload,
|
||||||
skill_t sk);
|
skill_t sk);
|
||||||
|
void free_wtype(struct weapon_type *wtype);
|
||||||
armor_type *new_armortype(item_type * itype, double penalty,
|
armor_type *new_armortype(item_type * itype, double penalty,
|
||||||
variant magres, int prot, unsigned int flags);
|
variant magres, int prot, unsigned int flags);
|
||||||
|
void free_atype(struct armor_type *wtype);
|
||||||
/* these constants are used with get_resourcetype.
|
/* these constants are used with get_resourcetype.
|
||||||
* The order of the enum is not important for stored data.
|
* The order of the enum is not important for stored data.
|
||||||
* The resourcenames array must be updated to match.
|
* The resourcenames array must be updated to match.
|
||||||
|
|
|
@ -971,16 +971,16 @@ static char *makename(void)
|
||||||
size_t nk, ne, nv, ns;
|
size_t nk, ne, nv, ns;
|
||||||
static char name[16];
|
static char name[16];
|
||||||
const char *kons = "bcdfghklmnprstvwz",
|
const char *kons = "bcdfghklmnprstvwz",
|
||||||
*start = "bcdgtskpvfr",
|
*handle_start = "bcdgtskpvfr",
|
||||||
*end = "nlrdst",
|
*handle_end = "nlrdst",
|
||||||
*vowels = "aaaaaaaaaaaeeeeeeeeeeeeiiiiiiiiiiioooooooooooouuuuuuuuuuyy";
|
*vowels = "aaaaaaaaaaaeeeeeeeeeeeeiiiiiiiiiiioooooooooooouuuuuuuuuuyy";
|
||||||
|
|
||||||
/* const char * vowels_latin1 = "aaaaaaaaaàâeeeeeeeeeéèêiiiiiiiiiíîoooooooooóòôuuuuuuuuuúyy"; */
|
/* const char * vowels_latin1 = "aaaaaaaaaàâeeeeeeeeeéèêiiiiiiiiiíîoooooooooóòôuuuuuuuuuúyy"; */
|
||||||
|
|
||||||
nk = strlen(kons);
|
nk = strlen(kons);
|
||||||
ne = strlen(end);
|
ne = strlen(handle_end);
|
||||||
nv = strlen(vowels);
|
nv = strlen(vowels);
|
||||||
ns = strlen(start);
|
ns = strlen(handle_start);
|
||||||
|
|
||||||
for (s = rng_int() % 3 + 2; s > 0; s--) {
|
for (s = rng_int() % 3 + 2; s > 0; s--) {
|
||||||
int v;
|
int v;
|
||||||
|
@ -991,7 +991,7 @@ static char *makename(void)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
k = rng_int() % (int)ns;
|
k = rng_int() % (int)ns;
|
||||||
name[p] = start[k];
|
name[p] = handle_start[k];
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
v = rng_int() % (int)nv;
|
v = rng_int() % (int)nv;
|
||||||
|
@ -999,7 +999,7 @@ static char *makename(void)
|
||||||
p++;
|
p++;
|
||||||
if (rng_int() % 3 == 2 || s == 1) {
|
if (rng_int() % 3 == 2 || s == 1) {
|
||||||
e = rng_int() % (int)ne;
|
e = rng_int() % (int)ne;
|
||||||
name[p] = end[e];
|
name[p] = handle_end[e];
|
||||||
p++;
|
p++;
|
||||||
x = 1;
|
x = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,15 +180,15 @@ struct rawmaterial_type *rmt_create(struct resource_type *rtype)
|
||||||
{
|
{
|
||||||
rawmaterial_type *rmtype;
|
rawmaterial_type *rmtype;
|
||||||
|
|
||||||
assert(!rtype->raw);
|
if (!rtype->raw) {
|
||||||
assert(!rtype->itype || rtype->itype->construction);
|
rmtype = rtype->raw = malloc(sizeof(rawmaterial_type));
|
||||||
rmtype = rtype->raw = malloc(sizeof(rawmaterial_type));
|
rmtype->rtype = rtype;
|
||||||
rmtype->rtype = rtype;
|
rmtype->terraform = terraform_default;
|
||||||
rmtype->terraform = terraform_default;
|
rmtype->update = NULL;
|
||||||
rmtype->update = NULL;
|
rmtype->use = use_default;
|
||||||
rmtype->use = use_default;
|
rmtype->visible = visible_default;
|
||||||
rmtype->visible = visible_default;
|
}
|
||||||
return rmtype;
|
return rtype->raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
int limit_resource(const struct region *r, const resource_type *rtype)
|
int limit_resource(const struct region *r, const resource_type *rtype)
|
||||||
|
|
|
@ -232,7 +232,7 @@ static message *cinfo_sparkle(const void *obj, objtype_t typ, const curse * c,
|
||||||
"sparkle_18",
|
"sparkle_18",
|
||||||
NULL, /* end draig */
|
NULL, /* end draig */
|
||||||
};
|
};
|
||||||
int m, begin = 0, end = 0;
|
int m, begin = 0, handle_end = 0;
|
||||||
unit *u;
|
unit *u;
|
||||||
UNUSED_ARG(typ);
|
UNUSED_ARG(typ);
|
||||||
|
|
||||||
|
@ -243,18 +243,18 @@ static message *cinfo_sparkle(const void *obj, objtype_t typ, const curse * c,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (m = 0; m != c->magician->faction->magiegebiet; ++m) {
|
for (m = 0; m != c->magician->faction->magiegebiet; ++m) {
|
||||||
while (effects[end] != NULL)
|
while (effects[handle_end] != NULL)
|
||||||
++end;
|
++handle_end;
|
||||||
begin = end + 1;
|
begin = handle_end + 1;
|
||||||
end = begin;
|
handle_end = begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (effects[end] != NULL)
|
while (effects[handle_end] != NULL)
|
||||||
++end;
|
++handle_end;
|
||||||
if (end == begin)
|
if (handle_end == begin)
|
||||||
return NULL;
|
return NULL;
|
||||||
else {
|
else {
|
||||||
int index = begin + curse_geteffect_int(c) % (end - begin);
|
int index = begin + curse_geteffect_int(c) % (handle_end - begin);
|
||||||
return msg_message(mkname("curseinfo", effects[index]), "unit id", u,
|
return msg_message(mkname("curseinfo", effects[index]), "unit id", u,
|
||||||
c->no);
|
c->no);
|
||||||
}
|
}
|
||||||
|
|
|
@ -559,8 +559,7 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype)
|
||||||
assert(sk != NOSKILL);
|
assert(sk != NOSKILL);
|
||||||
xmlFree(propValue);
|
xmlFree(propValue);
|
||||||
|
|
||||||
wtype =
|
wtype = new_weapontype(itype, flags, magres, NULL, offmod, defmod, reload, sk);
|
||||||
new_weapontype(itype, flags, magres, NULL, offmod, defmod, reload, sk);
|
|
||||||
|
|
||||||
/* reading weapon/damage */
|
/* reading weapon/damage */
|
||||||
xpath->node = node;
|
xpath->node = node;
|
||||||
|
@ -712,7 +711,14 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype)
|
||||||
flags |= ITF_ANIMAL;
|
flags |= ITF_ANIMAL;
|
||||||
if (xml_bvalue(node, "vehicle", false))
|
if (xml_bvalue(node, "vehicle", false))
|
||||||
flags |= ITF_VEHICLE;
|
flags |= ITF_VEHICLE;
|
||||||
|
|
||||||
itype = rtype->itype ? rtype->itype : it_get_or_create(rtype);
|
itype = rtype->itype ? rtype->itype : it_get_or_create(rtype);
|
||||||
|
/* exparse: recreate child data. */
|
||||||
|
if (itype->construction) {
|
||||||
|
free_construction(itype->construction);
|
||||||
|
itype->construction = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
mask_races(node, "allow", &itype->mask_allow);
|
mask_races(node, "allow", &itype->mask_allow);
|
||||||
|
@ -823,7 +829,18 @@ static int parse_resources(xmlDocPtr doc)
|
||||||
log_error("invalid resource %d has no name", i);
|
log_error("invalid resource %d has no name", i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtype = rt_get_or_create((const char *)name);
|
rtype = rt_get_or_create((const char *)name);
|
||||||
|
/* exparse: recreate child data. */
|
||||||
|
if (rtype->atype) {
|
||||||
|
free_atype(rtype->atype);
|
||||||
|
rtype->atype = NULL;
|
||||||
|
}
|
||||||
|
if (rtype->wtype) {
|
||||||
|
free_wtype(rtype->wtype);
|
||||||
|
rtype->wtype = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
rtype->flags |= flags;
|
rtype->flags |= flags;
|
||||||
xmlFree(name);
|
xmlFree(name);
|
||||||
|
|
||||||
|
@ -858,10 +875,6 @@ static int parse_resources(xmlDocPtr doc)
|
||||||
}
|
}
|
||||||
xmlXPathFreeObject(result);
|
xmlXPathFreeObject(result);
|
||||||
|
|
||||||
if (xml_bvalue(node, "material", false)) {
|
|
||||||
rmt_create(rtype);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xml_bvalue(node, "limited", false)) {
|
if (xml_bvalue(node, "limited", false)) {
|
||||||
rtype->flags |= RTF_LIMITED;
|
rtype->flags |= RTF_LIMITED;
|
||||||
}
|
}
|
||||||
|
@ -869,6 +882,7 @@ static int parse_resources(xmlDocPtr doc)
|
||||||
result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath);
|
result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath);
|
||||||
rtype->modifiers = xml_readmodifiers(result, node);
|
rtype->modifiers = xml_readmodifiers(result, node);
|
||||||
xmlXPathFreeObject(result);
|
xmlXPathFreeObject(result);
|
||||||
|
|
||||||
/* reading eressea/resources/resource/resourcelimit/function */
|
/* reading eressea/resources/resource/resourcelimit/function */
|
||||||
xpath->node = node;
|
xpath->node = node;
|
||||||
result = xmlXPathEvalExpression(BAD_CAST "resourcelimit/function", xpath);
|
result = xmlXPathEvalExpression(BAD_CAST "resourcelimit/function", xpath);
|
||||||
|
@ -889,6 +903,11 @@ static int parse_resources(xmlDocPtr doc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xmlXPathFreeObject(result);
|
xmlXPathFreeObject(result);
|
||||||
|
|
||||||
|
if (xml_bvalue(node, "material", false)) {
|
||||||
|
assert(!rtype->itype || rtype->itype->construction);
|
||||||
|
rmt_create(rtype);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xmlXPathFreeObject(resources);
|
xmlXPathFreeObject(resources);
|
||||||
|
|
Loading…
Reference in a new issue