From 6207211ba989b502f43501a7b08f5b6c84a6c72e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 24 Apr 2018 21:50:49 +0200 Subject: [PATCH 01/59] add skeleton for expat suport --- CMakeLists.txt | 1 + src/CMakeLists.txt | 13 +++++++++++++ src/exparse.c | 7 +++++++ src/exparse.h | 3 +++ src/jsonconf.c | 15 +++++++++++++-- 5 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 src/exparse.c create mode 100644 src/exparse.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 19e49c9c6..f73ba04a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ else() find_package (SQLite3 REQUIRED QUIET) endif() +find_package(EXPAT) find_package (LibXml2 REQUIRED) find_package (ToLua REQUIRED) if (TOLUA_FOUND) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bdf0465d2..21d07e9b2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -139,6 +139,11 @@ set (ERESSEA_SRC ${UTIL_SRC} ) +IF(EXPAT_FOUND) +set (ERESSEA_SRC ${ERESSEA_SRC} exparse.c) +ENDIF(EXPAT_FOUND) + + set(SERVER_SRC main.c console.c @@ -309,6 +314,14 @@ target_link_libraries(eressea ${CURSES_LIBRARIES}) add_definitions(-DUSE_CURSES) endif(CURSES_FOUND) +if (EXPAT_FOUND) +include_directories (${EXPAT_INCLUDE_DIRS}) +target_link_libraries(eressea ${EXPAT_LIBRARIES}) +target_link_libraries(convert ${EXPAT_LIBRARIES}) +target_link_libraries(test_eressea ${EXPAT_LIBRARIES}) +add_definitions(-DUSE_EXPAT) +endif (EXPAT_FOUND) + if (LIBXML2_FOUND) include_directories (${LIBXML2_INCLUDE_DIR}) target_link_libraries(eressea ${LIBXML2_LIBRARIES}) diff --git a/src/exparse.c b/src/exparse.c new file mode 100644 index 000000000..0a9722344 --- /dev/null +++ b/src/exparse.c @@ -0,0 +1,7 @@ +#include "exparse.h" + +#include + +int exparse_readfile(const char * filename) { + return 1; +} diff --git a/src/exparse.h b/src/exparse.h new file mode 100644 index 000000000..9401addc0 --- /dev/null +++ b/src/exparse.h @@ -0,0 +1,3 @@ +#pragma once + +int exparse_readfile(const char * filename); diff --git a/src/jsonconf.c b/src/jsonconf.c index c14ac9216..4d84fc1ca 100644 --- a/src/jsonconf.c +++ b/src/jsonconf.c @@ -46,6 +46,9 @@ without prior permission by the authors of Eressea. #include "move.h" #include "prefix.h" #include "skill.h" +#ifdef USE_EXPAT +#include "exparse.h" +#endif /* external libraries */ #include @@ -969,8 +972,16 @@ static int include_json(const char *uri) { static int include_xml(const char *uri) { char name[PATH_MAX]; const char *filename = uri_to_file(uri, name, sizeof(name)); - int err = read_xml(filename); - if (err < 0) { + int err; +#ifdef USE_EXPAT + err = exparse_readfile(filename); + if (err != 0) { + err = read_xml(filename); + } +#else + err = read_xml(filename); +#endif + if (err != 0) { log_error("could not parse XML from %s", uri); } return err; From b28cbd606d45b6c4ba2079ce8cd5a8075516ff84 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 24 Apr 2018 22:04:23 +0200 Subject: [PATCH 02/59] minimal expat parsing code --- src/exparse.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/exparse.c b/src/exparse.c index 0a9722344..70328e0ae 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -1,7 +1,41 @@ #include "exparse.h" +#include "util/log.h" + #include int exparse_readfile(const char * filename) { - return 1; + XML_Parser xp; + FILE *F; + int err = 1; + char buf[4096]; + + F = fopen(filename, "r"); + if (!F) { + return 2; + } + xp = XML_ParserCreate("UTF-8"); + for (;;) { + size_t len = (int) fread(buf, 1, sizeof(buf), F); + int done; + + if (ferror(F)) { + log_error("read error in %s", filename); + return -1; + } + done = feof(F); + if (XML_Parse(xp, buf, len, done) == XML_STATUS_ERROR) { + log_error("parse error at line %u of %s: %s", + XML_GetCurrentLineNumber(xp), + filename, + XML_ErrorString(XML_GetErrorCode(xp))); + return -1; + } + if (done) { + break; + } + } + XML_ParserFree(xp); + fclose(F); + return err; } From c3b25328d35ece6ee82f4802f91725bb8a8aa2f6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 24 Apr 2018 21:16:56 +0100 Subject: [PATCH 03/59] don't exist with a leak, fix MSVC compilation. --- src/exparse.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 70328e0ae..011212831 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -1,3 +1,6 @@ +#ifdef _MSC_VER +#include +#endif #include "exparse.h" #include "util/log.h" @@ -21,7 +24,8 @@ int exparse_readfile(const char * filename) { if (ferror(F)) { log_error("read error in %s", filename); - return -1; + err = -2; + break; } done = feof(F); if (XML_Parse(xp, buf, len, done) == XML_STATUS_ERROR) { @@ -29,7 +33,8 @@ int exparse_readfile(const char * filename) { XML_GetCurrentLineNumber(xp), filename, XML_ErrorString(XML_GetErrorCode(xp))); - return -1; + err = -1; + break; } if (done) { break; From 0b22b500139c4fc6d933fc8d61cd9ddad0eb62d5 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 28 Apr 2018 11:38:11 +0200 Subject: [PATCH 04/59] the presspass is cursed, attribute needs to be on item, not resource. --- res/core/common/items.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/core/common/items.xml b/res/core/common/items.xml index d04b6a252..67f2c1119 100644 --- a/res/core/common/items.xml +++ b/res/core/common/items.xml @@ -34,8 +34,8 @@ - - + + From 08663b6eb5c47b76f2c684699bc73c5189030079 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 28 Apr 2018 15:57:51 +0200 Subject: [PATCH 05/59] fix last commit. refactoring with the MSVC IDE is prone to errors. --- src/kernel/pathfinder.c | 36 ++++++++++++++++++------------------ src/kernel/pathfinder.h | 4 ++-- src/laws.c | 6 +++--- src/magic.c | 6 +++--- src/magic.h | 2 +- src/monsters.c | 8 ++++---- src/report.c | 34 +++++++++++++++++----------------- src/reports.c | 22 +++++++++++----------- src/util/filereader.c | 18 +++++++++--------- src/util/strings.c | 8 ++++---- src/util/translation.c | 6 +++--- 11 files changed, 75 insertions(+), 75 deletions(-) diff --git a/src/kernel/pathfinder.c b/src/kernel/pathfinder.c index 3c06fc3d7..61cead5fd 100644 --- a/src/kernel/pathfinder.c +++ b/src/kernel/pathfinder.c @@ -95,12 +95,12 @@ static void free_nodes(node * root) } } -struct selist *regions_in_range(struct region *start, int maxdist, +struct selist *regions_in_range(struct region *handle_start, int maxdist, bool(*allowed) (const struct region *, const struct region *)) { selist * rlist = NULL; - node *root = new_node(start, 0, NULL); - node **end = &root->next; + node *root = new_node(handle_start, 0, NULL); + node **handle_end = &root->next; node *n = root; while (n != NULL) { @@ -125,8 +125,8 @@ struct selist *regions_in_range(struct region *start, int maxdist, /* make sure we don't go here again, and put the region into the set for further BFS'ing */ fset(rn, RF_MARK); - *end = new_node(rn, depth, n); - end = &(*end)->next; + *handle_end = new_node(rn, depth, n); + handle_end = &(*handle_end)->next; } n = n->next; } @@ -135,17 +135,17 @@ struct selist *regions_in_range(struct region *start, int maxdist, return rlist; } -static region **internal_path_find(region * start, const region * target, +static region **internal_path_find(region * handle_start, const region * target, int maxlen, bool(*allowed) (const region *, const region *)) { static region *path[MAXDEPTH + 2]; /* STATIC_RETURN: used for return, not across calls */ direction_t d; - node *root = new_node(start, 0, NULL); - node **end = &root->next; + node *root = new_node(handle_start, 0, NULL); + node **handle_end = &root->next; node *n = root; bool found = false; assert(maxlen <= MAXDEPTH); - fset(start, RF_MARK); + fset(handle_start, RF_MARK); while (n != NULL) { region *r = n->r; @@ -173,8 +173,8 @@ static region **internal_path_find(region * start, const region * target, } else { fset(rn, RF_MARK); - *end = new_node(rn, depth, n); - end = &(*end)->next; + *handle_end = new_node(rn, depth, n); + handle_end = &(*handle_end)->next; } } if (found) @@ -188,22 +188,22 @@ static region **internal_path_find(region * start, const region * target, } bool -path_exists(region * start, const region * target, int maxlen, +path_exists(region * handle_start, const region * target, int maxlen, bool(*allowed) (const region *, const region *)) { - assert((!fval(start, RF_MARK) && !fval(target, RF_MARK)) + assert((!fval(handle_start, RF_MARK) && !fval(target, RF_MARK)) || !"Some Algorithm did not clear its RF_MARKs!"); - if (start == target) + if (handle_start == target) return true; - if (internal_path_find(start, target, maxlen, allowed) != NULL) + if (internal_path_find(handle_start, target, maxlen, allowed) != NULL) return true; return false; } -region **path_find(region * start, const region * target, int maxlen, +region **path_find(region * handle_start, const region * target, int maxlen, bool(*allowed) (const region *, const region *)) { - assert((!fval(start, RF_MARK) && !fval(target, RF_MARK)) + assert((!fval(handle_start, RF_MARK) && !fval(target, RF_MARK)) || !"Did you call path_init()?"); - return internal_path_find(start, target, maxlen, allowed); + return internal_path_find(handle_start, target, maxlen, allowed); } diff --git a/src/kernel/pathfinder.h b/src/kernel/pathfinder.h index 682fa4d25..a6c583139 100644 --- a/src/kernel/pathfinder.h +++ b/src/kernel/pathfinder.h @@ -22,10 +22,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif - extern struct region **path_find(struct region *start, + extern struct region **path_find(struct region *handle_start, const struct region *target, int maxlen, bool(*allowed) (const struct region *, const struct region *)); - extern bool path_exists(struct region *start, const struct region *target, + extern bool path_exists(struct region *handle_start, const struct region *target, int maxlen, bool(*allowed) (const struct region *, const struct region *)); extern bool allowed_swim(const struct region *src, diff --git a/src/laws.c b/src/laws.c index 1887d8657..15487ab47 100644 --- a/src/laws.c +++ b/src/laws.c @@ -4103,11 +4103,11 @@ static void reset_game(void) void turn_begin(void) { - int start = first_turn(); + int handle_start = first_turn(); assert(turn >= 0); - if (turn < start) { + if (turn < handle_start) { /* this should only happen during tests */ - turn = start; + turn = handle_start; } ++turn; reset_game(); diff --git a/src/magic.c b/src/magic.c index 1865b4f9e..0accc008d 100644 --- a/src/magic.c +++ b/src/magic.c @@ -2056,11 +2056,11 @@ void free_castorder(struct castorder *co) void add_castorder(spellrank * cll, castorder * co) { if (cll->begin == NULL) { - cll->end = &cll->begin; + cll->handle_end = &cll->begin; } - *cll->end = co; - cll->end = &co->next; + *cll->handle_end = co; + cll->handle_end = &co->next; return; } diff --git a/src/magic.h b/src/magic.h index ae43fd5af..4a00a7b13 100644 --- a/src/magic.h +++ b/src/magic.h @@ -272,7 +272,7 @@ extern "C" { typedef struct spellrank { struct castorder *begin; - struct castorder **end; + struct castorder **handle_end; } spellrank; struct castorder *create_castorder(struct castorder * co, struct unit *caster, diff --git a/src/monsters.c b/src/monsters.c index 9d113c0e9..46f63a92d 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -848,15 +848,15 @@ static double chaosfactor(region * r) return fval(r, RF_CHAOTIC) ? ((double)(1 + get_chaoscount(r)) / 1000.0) : 0.0; } -static int nrand(int start, int sub) +static int nrand(int handle_start, int sub) { int res = 0; do { - if (rng_int() % 100 < start) + if (rng_int() % 100 < handle_start) res++; - start -= sub; - } while (start > 0); + handle_start -= sub; + } while (handle_start > 0); return res; } diff --git a/src/report.c b/src/report.c index 319203e3b..9568d640a 100644 --- a/src/report.c +++ b/src/report.c @@ -181,7 +181,7 @@ paragraph(struct stream *out, const char *str, ptrdiff_t indent, int hanging_ind char marker) { size_t length = REPORTWIDTH; - const char *end, *begin, *mark = 0; + const char *handle_end, *begin, *mark = 0; if (!str) return; /* find out if there's a mark + indent already encoded in the string. */ @@ -200,7 +200,7 @@ paragraph(struct stream *out, const char *str, ptrdiff_t indent, int hanging_ind else { mark = ▮ } - begin = end = str; + begin = handle_end = str; do { const char *last_space = begin; @@ -217,25 +217,25 @@ paragraph(struct stream *out, const char *str, ptrdiff_t indent, int hanging_ind else { write_spaces(out, indent + hanging_indent); } - while (*end && end <= begin + length - indent) { - if (*end == ' ') { - last_space = end; + while (*handle_end && handle_end <= begin + length - indent) { + if (*handle_end == ' ') { + last_space = handle_end; } - ++end; + ++handle_end; } - if (*end == 0) - last_space = end; + if (*handle_end == 0) + last_space = handle_end; if (last_space == begin) { /* there was no space in this line. clip it */ - last_space = end; + last_space = handle_end; } swrite(begin, sizeof(char), last_space - begin, out); begin = last_space; while (*begin == ' ') { ++begin; } - if (begin > end) - begin = end; + if (begin > handle_end) + begin = handle_end; sputs("", out); } while (*begin); } @@ -1939,7 +1939,7 @@ static void nr_paragraph(struct stream *out, message * m, faction * f) typedef struct cb_data { struct stream *out; - char *start, *writep; + char *handle_start, *writep; size_t size; const faction *f; int maxtravel, counter; @@ -1948,7 +1948,7 @@ typedef struct cb_data { static void init_cb(cb_data *data, struct stream *out, char *buffer, size_t size, const faction *f) { data->out = out; data->writep = buffer; - data->start = buffer; + data->handle_start = buffer; data->size = size; data->f = f; data->maxtravel = 0; @@ -1965,7 +1965,7 @@ static void cb_write_travelthru(region *r, unit *u, void *cbdata) { if (travelthru_cansee(r, f, u)) { ++data->counter; do { - size_t len, size = data->size - (data->writep - data->start); + size_t len, size = data->size - (data->writep - data->handle_start); const char *str; char *writep = data->writep; @@ -2000,13 +2000,13 @@ static void cb_write_travelthru(region *r, unit *u, void *cbdata) { if (len >= size || data->counter == data->maxtravel) { /* buffer is full */ *writep = 0; - paragraph(data->out, data->start, 0, 0, 0); - data->writep = data->start; + paragraph(data->out, data->handle_start, 0, 0, 0); + data->writep = data->handle_start; if (data->counter == data->maxtravel) { break; } } - } while (data->writep == data->start); + } while (data->writep == data->handle_start); } } diff --git a/src/reports.c b/src/reports.c index f5b7f5531..568c66183 100644 --- a/src/reports.c +++ b/src/reports.c @@ -2242,7 +2242,7 @@ static void eval_regions(struct opstack **stack, const void *userdata) { /* order -> string */ const faction *report = (const faction *)userdata; int i = opop(stack).i; - int end, begin = opop(stack).i; + int handle_end, begin = opop(stack).i; const arg_regions *aregs = (const arg_regions *)opop(stack).v; char buf[256]; size_t size = sizeof(buf) - 1; @@ -2250,19 +2250,19 @@ static void eval_regions(struct opstack **stack, const void *userdata) char *bufp = buf; if (aregs == NULL) { - end = begin; + handle_end = begin; } else { if (i >= 0) - end = begin + i; + handle_end = begin + i; else - end = aregs->nregions + i; + handle_end = aregs->nregions + i; } - for (i = begin; i < end; ++i) { + for (i = begin; i < handle_end; ++i) { const char *rname = (const char *)regionname(aregs->regions[i], report); bufp = STRLCPY(bufp, rname, size); - if (i + 1 < end && size > 2) { + if (i + 1 < handle_end && size > 2) { strcat(bufp, ", "); bufp += 2; size -= 2; @@ -2295,9 +2295,9 @@ static void eval_trail(struct opstack **stack, const void *userdata) #endif if (aregs != NULL) { - int i, end = 0, begin = 0; - end = aregs->nregions; - for (i = begin; i < end; ++i) { + int i, handle_end = 0, begin = 0; + handle_end = aregs->nregions; + for (i = begin; i < handle_end; ++i) { region *r = aregs->regions[i]; const char *trail = trailinto(r, lang); const char *rn = f_regionid_s(r, report); @@ -2305,10 +2305,10 @@ static void eval_trail(struct opstack **stack, const void *userdata) if (wrptr(&bufp, &size, snprintf(bufp, size, trail, rn)) != 0) WARN_STATIC_BUFFER(); - if (i + 2 < end) { + if (i + 2 < handle_end) { bufp = STRLCPY(bufp, ", ", size); } - else if (i + 1 < end) { + else if (i + 1 < handle_end) { bufp = STRLCPY(bufp, LOC(lang, "list_and"), size); } } diff --git a/src/util/filereader.c b/src/util/filereader.c index d36d3ca71..e477b445c 100644 --- a/src/util/filereader.c +++ b/src/util/filereader.c @@ -136,11 +136,11 @@ static const char *getbuf_latin1(FILE * F) continue; } else if (c == CONTINUE_CHAR) { - const char *end = ++bp; - while (*end && isspace(*(unsigned char *)end)) - ++end; /* eatwhite */ - if (*end == '\0') { - bp = end; + const char *handle_end = ++bp; + while (*handle_end && isspace(*(unsigned char *)handle_end)) + ++handle_end; /* eatwhite */ + if (*handle_end == '\0') { + bp = handle_end; cont = true; continue; } @@ -303,11 +303,11 @@ static const char *getbuf_utf8(FILE * F) } else { if (*bp == CONTINUE_CHAR) { - const char *end; + const char *handle_end; eatwhite(bp + 1, &white); - end = bp + 1 + white; - if (*end == '\0') { - bp = end; + handle_end = bp + 1 + white; + if (*handle_end == '\0') { + bp = handle_end; cont = true; continue; } diff --git a/src/util/strings.c b/src/util/strings.c index 4959fba6c..81fdc3713 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -157,13 +157,13 @@ unsigned int str_hash(const char *s) const char *str_escape(const char *str, char *buffer, size_t len) { - const char *start = strchr(str, '\"'); - if (!start) start = strchr(str, '\\'); + const char *handle_start = strchr(str, '\"'); + if (!handle_start) handle_start = strchr(str, '\\'); assert(buffer); - if (start) { + if (handle_start) { const char *p; char *o; - size_t skip = start - str; + size_t skip = handle_start - str; if (skip > len) { skip = len; diff --git a/src/util/translation.c b/src/util/translation.c index da26806fe..4d032911e 100644 --- a/src/util/translation.c +++ b/src/util/translation.c @@ -77,7 +77,7 @@ void opstack_push(opstack ** stackp, variant data) #define BBUFSIZE 0x10000 static struct { char *begin; - char *end; + char *handle_end; char *last; char *current; } buffer; @@ -88,9 +88,9 @@ char *balloc(size_t size) if (!init) { init = 1; buffer.current = buffer.begin = malloc(BBUFSIZE * sizeof(char)); - buffer.end = buffer.begin + BBUFSIZE; + buffer.handle_end = buffer.begin + BBUFSIZE; } - assert(buffer.current + size <= buffer.end || !"balloc is out of memory"); + assert(buffer.current + size <= buffer.handle_end || !"balloc is out of memory"); buffer.last = buffer.current; buffer.current += size; return buffer.last; From edadf2cbabef1432f064e423499a985cf55ab97c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 28 Apr 2018 15:58:14 +0200 Subject: [PATCH 06/59] exparse: parse (most of) the resource data. --- src/exparse.c | 317 ++++++++++++++++++++++++++++++++++++++++- src/kernel/item.c | 10 +- src/kernel/item.h | 3 +- src/kernel/region.c | 12 +- src/kernel/resources.c | 18 +-- src/spells/unitcurse.c | 18 +-- src/xmlreader.c | 31 +++- 7 files changed, 374 insertions(+), 35 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 011212831..44593f3cf 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -3,21 +3,330 @@ #endif #include "exparse.h" +#include "kernel/build.h" +#include "kernel/item.h" +#include "kernel/resources.h" + #include "util/log.h" #include +#include +#include + +#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) { XML_Parser xp; FILE *F; int err = 1; char buf[4096]; + userdata ud; F = fopen(filename, "r"); if (!F) { return 2; } 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 (;;) { size_t len = (int) fread(buf, 1, sizeof(buf), F); int done; @@ -29,7 +338,7 @@ int exparse_readfile(const char * filename) { } done = feof(F); 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), filename, XML_ErrorString(XML_GetErrorCode(xp))); @@ -40,7 +349,11 @@ int exparse_readfile(const char * filename) { break; } } + assert(ud.depth == 0); XML_ParserFree(xp); fclose(F); - return err; + if (err != 0) { + return err; + } + return ud.errors; } diff --git a/src/kernel/item.c b/src/kernel/item.c index ab6ad8c8d..a573dc4ba 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -916,7 +916,11 @@ static void free_itype(item_type *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); free(wtype->damage[0]); free(wtype->damage[1]); @@ -931,7 +935,9 @@ void free_rtype(resource_type *rtype) { if (rtype->itype) { free_itype(rtype->itype); } - free(rtype->atype); + if (rtype->atype) { + free_atype(rtype->atype); + } free(rtype->modifiers); free(rtype->raw); free(rtype->_name); diff --git a/src/kernel/item.h b/src/kernel/item.h index e7bfef7cc..9079369e8 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -224,9 +224,10 @@ extern "C" { weapon_type *new_weapontype(item_type * itype, int wflags, variant magres, const char *damage[], int offmod, int defmod, int reload, skill_t sk); + void free_wtype(struct weapon_type *wtype); armor_type *new_armortype(item_type * itype, double penalty, variant magres, int prot, unsigned int flags); - + void free_atype(struct armor_type *wtype); /* these constants are used with get_resourcetype. * The order of the enum is not important for stored data. * The resourcenames array must be updated to match. diff --git a/src/kernel/region.c b/src/kernel/region.c index 790a8341c..7ceab2f18 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -971,16 +971,16 @@ static char *makename(void) size_t nk, ne, nv, ns; static char name[16]; const char *kons = "bcdfghklmnprstvwz", - *start = "bcdgtskpvfr", - *end = "nlrdst", + *handle_start = "bcdgtskpvfr", + *handle_end = "nlrdst", *vowels = "aaaaaaaaaaaeeeeeeeeeeeeiiiiiiiiiiioooooooooooouuuuuuuuuuyy"; /* const char * vowels_latin1 = "aaaaaaaaaàâeeeeeeeeeéèêiiiiiiiiiíîoooooooooóòôuuuuuuuuuúyy"; */ nk = strlen(kons); - ne = strlen(end); + ne = strlen(handle_end); nv = strlen(vowels); - ns = strlen(start); + ns = strlen(handle_start); for (s = rng_int() % 3 + 2; s > 0; s--) { int v; @@ -991,7 +991,7 @@ static char *makename(void) } else { k = rng_int() % (int)ns; - name[p] = start[k]; + name[p] = handle_start[k]; p++; } v = rng_int() % (int)nv; @@ -999,7 +999,7 @@ static char *makename(void) p++; if (rng_int() % 3 == 2 || s == 1) { e = rng_int() % (int)ne; - name[p] = end[e]; + name[p] = handle_end[e]; p++; x = 1; } diff --git a/src/kernel/resources.c b/src/kernel/resources.c index bcf26efb3..231b763f8 100644 --- a/src/kernel/resources.c +++ b/src/kernel/resources.c @@ -180,15 +180,15 @@ struct rawmaterial_type *rmt_create(struct resource_type *rtype) { rawmaterial_type *rmtype; - assert(!rtype->raw); - assert(!rtype->itype || rtype->itype->construction); - rmtype = rtype->raw = malloc(sizeof(rawmaterial_type)); - rmtype->rtype = rtype; - rmtype->terraform = terraform_default; - rmtype->update = NULL; - rmtype->use = use_default; - rmtype->visible = visible_default; - return rmtype; + if (!rtype->raw) { + rmtype = rtype->raw = malloc(sizeof(rawmaterial_type)); + rmtype->rtype = rtype; + rmtype->terraform = terraform_default; + rmtype->update = NULL; + rmtype->use = use_default; + rmtype->visible = visible_default; + } + return rtype->raw; } int limit_resource(const struct region *r, const resource_type *rtype) diff --git a/src/spells/unitcurse.c b/src/spells/unitcurse.c index 6fc979e38..a99eb082c 100644 --- a/src/spells/unitcurse.c +++ b/src/spells/unitcurse.c @@ -232,7 +232,7 @@ static message *cinfo_sparkle(const void *obj, objtype_t typ, const curse * c, "sparkle_18", NULL, /* end draig */ }; - int m, begin = 0, end = 0; + int m, begin = 0, handle_end = 0; unit *u; UNUSED_ARG(typ); @@ -243,18 +243,18 @@ static message *cinfo_sparkle(const void *obj, objtype_t typ, const curse * c, return NULL; for (m = 0; m != c->magician->faction->magiegebiet; ++m) { - while (effects[end] != NULL) - ++end; - begin = end + 1; - end = begin; + while (effects[handle_end] != NULL) + ++handle_end; + begin = handle_end + 1; + handle_end = begin; } - while (effects[end] != NULL) - ++end; - if (end == begin) + while (effects[handle_end] != NULL) + ++handle_end; + if (handle_end == begin) return NULL; 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, c->no); } diff --git a/src/xmlreader.c b/src/xmlreader.c index 66b04e611..a157569fd 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -559,8 +559,7 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) assert(sk != NOSKILL); xmlFree(propValue); - wtype = - new_weapontype(itype, flags, magres, NULL, offmod, defmod, reload, sk); + wtype = new_weapontype(itype, flags, magres, NULL, offmod, defmod, reload, sk); /* reading weapon/damage */ xpath->node = node; @@ -712,7 +711,14 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) flags |= ITF_ANIMAL; if (xml_bvalue(node, "vehicle", false)) flags |= ITF_VEHICLE; + 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->capacity = xml_ivalue(node, "capacity", 0); 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); continue; } + 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; xmlFree(name); @@ -858,10 +875,6 @@ static int parse_resources(xmlDocPtr doc) } xmlXPathFreeObject(result); - if (xml_bvalue(node, "material", false)) { - rmt_create(rtype); - } - if (xml_bvalue(node, "limited", false)) { rtype->flags |= RTF_LIMITED; } @@ -869,6 +882,7 @@ static int parse_resources(xmlDocPtr doc) result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath); rtype->modifiers = xml_readmodifiers(result, node); xmlXPathFreeObject(result); + /* reading eressea/resources/resource/resourcelimit/function */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "resourcelimit/function", xpath); @@ -889,6 +903,11 @@ static int parse_resources(xmlDocPtr doc) } } xmlXPathFreeObject(result); + + if (xml_bvalue(node, "material", false)) { + assert(!rtype->itype || rtype->itype->construction); + rmt_create(rtype); + } } } xmlXPathFreeObject(resources); From 03cff6d595bbc72d386840e2584ac2357afae27c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 28 Apr 2018 16:14:32 +0200 Subject: [PATCH 07/59] extract rc_mask, add it to exparse code. --- src/exparse.c | 14 ++++++++++++++ src/kernel/race.c | 17 +++++++++++++++++ src/kernel/race.h | 2 ++ src/kernel/race.test.c | 15 +++++++++++++++ src/xmlreader.c | 13 +------------ 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 44593f3cf..5b8b2a279 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -5,6 +5,7 @@ #include "kernel/build.h" #include "kernel/item.h" +#include "kernel/race.h" #include "kernel/resources.h" #include "util/log.h" @@ -156,6 +157,7 @@ static void handle_item(userdata *ud, const XML_Char *el, const XML_Char **attr) itype = it_get_or_create(rtype); } for (i = 0; attr[i]; i += 2) { + char buffer[64]; if (xml_strcmp(attr[i], "weight") == 0) { itype->weight = xml_int(attr[i + 1]); } @@ -165,6 +167,18 @@ static void handle_item(userdata *ud, const XML_Char *el, const XML_Char **attr) else if (xml_strcmp(attr[i], "score") == 0) { itype->score = xml_int(attr[i + 1]); } + else if (xml_strcmp(attr[i], "allow") == 0) { + size_t len = strlen(attr[i + 1]); + assert(len < sizeof(buffer)); + memcpy(buffer, attr[i + 1], len + 1); + itype->mask_allow = rc_mask(buffer); + } + else if (xml_strcmp(attr[i], "deny") == 0) { + size_t len = strlen(attr[i + 1]); + assert(len < sizeof(buffer)); + memcpy(buffer, attr[i + 1], len + 1); + itype->mask_deny = rc_mask(buffer); + } else if (!handle_flag(&flags, attr + i, flag_names)) { handle_bad_input(ud, el, attr[i]); } diff --git a/src/kernel/race.c b/src/kernel/race.c index edf415223..c9299d5bd 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -574,3 +574,20 @@ struct race * read_race_reference(struct storage *store) void register_race_function(race_func func, const char *name) { register_function((pf_generic)func, name); } + +static int race_mask = 1; + +int rc_mask(char *list) { + int mask = 0; + char * tok = strtok(list, " ,"); + while (tok) { + race * rc = rc_get_or_create(tok); + if (!rc->mask_item) { + rc->mask_item = race_mask; + race_mask = race_mask << 1; + } + mask |= rc->mask_item; + tok = strtok(NULL, " ,"); + } + return mask; +} diff --git a/src/kernel/race.h b/src/kernel/race.h index 1203eaed2..042cb5e78 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -197,6 +197,8 @@ extern "C" { #define MIGRANTS_NONE 0 #define MIGRANTS_LOG10 1 int rc_migrants_formula(const race *rc); + + int rc_mask(char *list); /* Flags. Do not reorder these without changing json_race() in jsonconf.c */ #define RCF_NPC (1<<0) /* cannot be the race for a player faction (and other limits?) */ diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index dcb4ce6f7..2f34c127e 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -172,6 +173,19 @@ static void test_racename(CuTest *tc) { test_teardown(); } +static void test_rc_mask(CuTest *tc) { + int mask; + char list[64]; + test_setup(); + strcpy(list, "goblin dwarf"); + mask = rc_mask(list); + CuAssertIntEquals(tc, 3, mask); + CuAssertStrEquals(tc, "goblin", list); + mask = rc_mask(list); + CuAssertIntEquals(tc, 1, mask); + test_teardown(); +} + CuSuite *get_race_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -180,6 +194,7 @@ CuSuite *get_race_suite(void) SUITE_ADD_TEST(suite, test_rc_name); SUITE_ADD_TEST(suite, test_rc_defaults); SUITE_ADD_TEST(suite, test_rc_find); + SUITE_ADD_TEST(suite, test_rc_mask); SUITE_ADD_TEST(suite, test_rc_set_param); SUITE_ADD_TEST(suite, test_rc_can_use); SUITE_ADD_TEST(suite, test_racename); diff --git a/src/xmlreader.c b/src/xmlreader.c index a157569fd..111ce624e 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -667,23 +667,12 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) return wtype; } -static int race_mask = 1; - static void mask_races(xmlNodePtr node, const char *key, int *maskp) { xmlChar *propValue = xmlGetProp(node, BAD_CAST key); int mask = 0; assert(maskp); if (propValue) { - char * tok = strtok((char *)propValue, " ,"); - while (tok) { - race * rc = rc_get_or_create(tok); - if (!rc->mask_item) { - rc->mask_item = race_mask; - race_mask = race_mask << 1; - } - mask |= rc->mask_item; - tok = strtok(NULL, " ,"); - } + mask = rc_mask((char *)propValue); xmlFree(propValue); } *maskp = mask; From ff4bae4da113aff14846fbe96dd70222f2441c66 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 28 Apr 2018 17:52:48 +0200 Subject: [PATCH 08/59] delete unused static functions. --- src/exparse.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 5b8b2a279..afaa3daf8 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -54,16 +54,6 @@ 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; @@ -75,13 +65,6 @@ 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); @@ -125,7 +108,6 @@ static void handle_resource(userdata *ud, const XML_Char *el, const XML_Char **a 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)) { @@ -229,7 +211,7 @@ static void XMLCALL handle_resources(userdata *ud, const XML_Char *el, const XML /* TODO */ } else if (xml_strcmp(el, "luxury") == 0) { - /* TODO */ + rtype->ltype = new_luxurytype(itype, 0); } else if (xml_strcmp(el, "potion") == 0) { /* TODO */ @@ -291,6 +273,7 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char switch (ud->type) { case EXP_RESOURCES: handle_resources(ud, el, attr); + break; default: /* not implemented */ handle_bad_input(ud, el, NULL); @@ -328,7 +311,7 @@ static void XMLCALL handle_data(void *data, const XML_Char *xs, int len) { int exparse_readfile(const char * filename) { XML_Parser xp; FILE *F; - int err = 1; + int err = 0; char buf[4096]; userdata ud; From ce50b888c922568ae50e453f38382fdc84a0abe3 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 28 Apr 2018 18:10:04 +0200 Subject: [PATCH 09/59] finish loading luxury items. --- src/xmlreader.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/xmlreader.c b/src/xmlreader.c index 111ce624e..60231688e 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -498,6 +498,10 @@ static void xml_readpotion(xmlXPathContextPtr xpath, item_type * itype) static luxury_type *xml_readluxury(xmlXPathContextPtr xpath, item_type * itype) { int price = xml_ivalue(xpath->node, "price", 0); + if (itype->rtype->ltype) { + itype->rtype->ltype->price = price; + return itype->rtype->ltype; + } return new_luxurytype(itype, price); } From 16cebed0132954ab4af9e06b4e5f7aec8d11f934 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 28 Apr 2018 18:40:14 +0200 Subject: [PATCH 10/59] implement weapons loading with expat. --- src/exparse.c | 65 +++++++++++++++++++++++++++++++++++++++++++---- src/kernel/item.c | 2 +- src/xmlreader.c | 4 +-- 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index afaa3daf8..8a45e3fe9 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -9,6 +9,7 @@ #include "kernel/resources.h" #include "util/log.h" +#include "util/strings.h" #include @@ -65,6 +66,13 @@ static int xml_int(const XML_Char *val) { return atoi((const char *)val); } +static variant xml_fraction(const XML_Char *val) { + int num, den = 100; + double fval = atof((const char *)val); + num = (int)(fval * den + 0.5); + return frac_make(num, den); +} + 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); @@ -168,6 +176,35 @@ static void handle_item(userdata *ud, const XML_Char *el, const XML_Char **attr) itype->flags = flags; } +static void handle_weapon(userdata *ud, const XML_Char *el, const XML_Char **attr) { + const char *flag_names[] = { "missile", "magical", "pierce", "cut", "bash", "siege", "armorpiercing", "horse", "useshield", NULL }; + resource_type *rtype = (resource_type *)ud->object; + item_type * itype = rtype->itype; + weapon_type *wtype = new_weapontype(itype, 0, frac_zero, NULL, 0, 0, 0, NOSKILL); + int i, flags = 0; + for (i = 0; attr[i]; i += 2) { + if (xml_strcmp(attr[i], "offmod") == 0) { + wtype->offmod = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "defmod") == 0) { + wtype->defmod = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "reload") == 0) { + wtype->reload = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "skill") == 0) { + wtype->skill = findskill(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "magres") == 0) { + wtype->magres = xml_fraction(attr[i + 1]);; + } + else if (!handle_flag(&flags, attr + i, flag_names)) { + handle_bad_input(ud, el, attr[i]); + } + } + wtype->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) { @@ -221,12 +258,30 @@ static void XMLCALL handle_resources(userdata *ud, const XML_Char *el, const XML 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 */ + handle_weapon(ud, el, attr); } - else if (xml_strcmp(el, "damage") == 0) { - assert(rtype->wtype); - /* TODO */ + else if (rtype->wtype) { + weapon_type *wtype = rtype->wtype; + if (xml_strcmp(el, "damage") == 0) { + int i, pos = 0; + for (i = 0; attr[i]; i += 2) { + if (xml_strcmp(attr[i], "type") == 0) { + /* damage vs. rider(1) or not(0)? */ + if (xml_strcmp(attr[i + 1], "rider") == 0) { + pos = 1; + } + } + else if (xml_strcmp(attr[i], "value") == 0) { + wtype->damage[pos] = str_strdup(attr[i + 1]); + } + else { + handle_bad_input(ud, el, NULL); + } + } + } + else { + handle_bad_input(ud, el, NULL); + } } else { handle_bad_input(ud, el, NULL); diff --git a/src/kernel/item.c b/src/kernel/item.c index a573dc4ba..ef0f46768 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -291,7 +291,7 @@ weapon_type *new_weapontype(item_type * itype, wtype->damage[1] = str_strdup(damage[1]); } wtype->defmod = defmod; - wtype->flags |= wflags; + wtype->flags = wflags; wtype->itype = itype; wtype->magres = magres; wtype->offmod = offmod; diff --git a/src/xmlreader.c b/src/xmlreader.c index 60231688e..af057fc03 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -548,7 +548,7 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) flags |= WTF_PIERCE; if (xml_bvalue(node, "cut", false)) flags |= WTF_CUT; - if (xml_bvalue(node, "blunt", false)) + if (xml_bvalue(node, "bash", false)) flags |= WTF_BLUNT; if (xml_bvalue(node, "siege", false)) flags |= WTF_SIEGE; @@ -581,8 +581,6 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) propValue = xmlGetProp(node, BAD_CAST "value"); wtype->damage[pos] = str_strdup((const char *)propValue); /* TODO: this is a memory leak */ - if (k == 0) - wtype->damage[1 - pos] = wtype->damage[pos]; xmlFree(propValue); } xmlXPathFreeObject(result); From e4a2b6cb357d2a3f97f07e0b28cf246a947c62da Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 28 Apr 2018 18:47:17 +0200 Subject: [PATCH 11/59] loading armor with expat. --- src/exparse.c | 33 +++++++++++++++++++++++++++++++-- src/kernel/item.h | 2 +- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 8a45e3fe9..e42b1c81a 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -66,6 +66,10 @@ static int xml_int(const XML_Char *val) { return atoi((const char *)val); } +static double xml_float(const XML_Char *val) { + return atof((const char *)val); +} + static variant xml_fraction(const XML_Char *val) { int num, den = 100; double fval = atof((const char *)val); @@ -176,6 +180,32 @@ static void handle_item(userdata *ud, const XML_Char *el, const XML_Char **attr) itype->flags = flags; } +static void handle_armor(userdata *ud, const XML_Char *el, const XML_Char **attr) { + const char *flag_names[] = { "shield", "laen", NULL }; + resource_type *rtype = (resource_type *)ud->object; + item_type * itype = rtype->itype; + armor_type *atype = new_armortype(itype, 0.0, frac_zero, 0, 0); + int i, flags = 0; + for (i = 0; attr[i]; i += 2) { + if (xml_strcmp(attr[i], "penalty") == 0) { + atype->penalty = xml_float(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "projectile") == 0) { + atype->projectile = xml_float(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "ac") == 0) { + atype->prot = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "magres") == 0) { + atype->magres = xml_fraction(attr[i + 1]); + } + else if (!handle_flag(&flags, attr + i, flag_names)) { + handle_bad_input(ud, el, attr[i]); + } + } + atype->flags = flags; +} + static void handle_weapon(userdata *ud, const XML_Char *el, const XML_Char **attr) { const char *flag_names[] = { "missile", "magical", "pierce", "cut", "bash", "siege", "armorpiercing", "horse", "useshield", NULL }; resource_type *rtype = (resource_type *)ud->object; @@ -254,8 +284,7 @@ static void XMLCALL handle_resources(userdata *ud, const XML_Char *el, const XML /* TODO */ } else if (xml_strcmp(el, "armor") == 0) { - /* TODO */ - rtype->atype = new_armortype(itype, 0.0, frac_zero, 0, 0); + handle_armor(ud, el, attr); } else if (xml_strcmp(el, "weapon") == 0) { handle_weapon(ud, el, attr); diff --git a/src/kernel/item.h b/src/kernel/item.h index 9079369e8..802c483a8 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -159,9 +159,9 @@ extern "C" { const item_type *itype; unsigned int flags; double penalty; + double projectile; /* chance, dass ein projektil abprallt */ variant magres; int prot; - float projectile; /* chance, dass ein projektil abprallt */ } armor_type; #define WTF_NONE 0x00 From 9d3385de9788c0ac1eeab91229f88b748d318845 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 28 Apr 2018 18:49:13 +0200 Subject: [PATCH 12/59] still cannot read potions, requirements, functions. --- src/exparse.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/exparse.c b/src/exparse.c index e42b1c81a..aca35c8ec 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -247,6 +247,7 @@ static void XMLCALL handle_resources(userdata *ud, const XML_Char *el, const XML } else if (xml_strcmp(el, "function") == 0) { assert(rtype); + ++ud->errors; /* TODO */ } else if (rtype->itype) { @@ -276,12 +277,14 @@ static void XMLCALL handle_resources(userdata *ud, const XML_Char *el, const XML else if (xml_strcmp(el, "requirement") == 0) { assert(itype->construction); /* TODO */ + ++ud->errors; } else if (xml_strcmp(el, "luxury") == 0) { rtype->ltype = new_luxurytype(itype, 0); } else if (xml_strcmp(el, "potion") == 0) { /* TODO */ + ++ud->errors; } else if (xml_strcmp(el, "armor") == 0) { handle_armor(ud, el, attr); From 9dbfaea708dcdd712b9edd327690445b8fb29981 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 28 Apr 2018 21:12:28 +0200 Subject: [PATCH 13/59] parse construction requirements for items. --- src/exparse.c | 52 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index aca35c8ec..0b76aa792 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -235,7 +235,11 @@ static void handle_weapon(userdata *ud, const XML_Char *el, const XML_Char **att wtype->flags = flags; } -static void XMLCALL handle_resources(userdata *ud, const XML_Char *el, const XML_Char **attr) { +#define MAX_REQUIREMENTS 8 +static requirement reqs[MAX_REQUIREMENTS]; +static int nreqs; + +static void XMLCALL start_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); @@ -273,11 +277,23 @@ static void XMLCALL handle_resources(userdata *ud, const XML_Char *el, const XML } } itype->construction = con; + nreqs = 0; } else if (xml_strcmp(el, "requirement") == 0) { + requirement *req; + int i; assert(itype->construction); - /* TODO */ - ++ud->errors; + assert(nreqs < MAX_REQUIREMENTS); + req = reqs + nreqs; + for (i = 0; attr[i]; i += 2) { + if (xml_strcmp(attr[i], "type") == 0) { + req->rtype = rt_get_or_create((const char *)attr[i + 1]); + } + else if (xml_strcmp(attr[i], "quantity") == 0) { + req->number = xml_int(attr[i + 1]); + } + } + ++nreqs; } else if (xml_strcmp(el, "luxury") == 0) { rtype->ltype = new_luxurytype(itype, 0); @@ -359,7 +375,7 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char else { switch (ud->type) { case EXP_RESOURCES: - handle_resources(ud, el, attr); + start_resources(ud, el, attr); break; default: /* not implemented */ @@ -369,14 +385,32 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char ++ud->depth; } +static void end_resources(userdata *ud, const XML_Char *el) { + resource_type *rtype = (resource_type *)ud->object; + if (xml_strcmp(el, "construction") == 0) { + if (nreqs > 0) { + construction *con = rtype->itype->construction; + con->materials = calloc(sizeof(requirement), nreqs + 1); + memcpy(con->materials, reqs, sizeof(requirement) * nreqs); + nreqs = 0; + } + } +} + 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->type == EXP_RESOURCES) { + end_resources(ud, el); } + else { + if (ud->cdata) { + free(ud->cdata); + ud->cdata = NULL; + ud->clength = 0; + } + } + --ud->depth; if (ud->depth == 0) { ud->type = EXP_UNKNOWN; } From e86f3e7589d3f753688e87f2d4bd32b55a85c98f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 28 Apr 2018 21:46:01 +0200 Subject: [PATCH 14/59] read callback fucntions for resources and weapons. --- src/exparse.c | 29 +++++++++++++++++++++++++++++ src/kernel/item.h | 4 ++++ src/xmlreader.c | 4 +--- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 0b76aa792..8bee331fc 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -8,6 +8,7 @@ #include "kernel/race.h" #include "kernel/resources.h" +#include "util/functions.h" #include "util/log.h" #include "util/strings.h" @@ -250,7 +251,35 @@ static void XMLCALL start_resources(userdata *ud, const XML_Char *el, const XML_ handle_item(ud, el, attr); } else if (xml_strcmp(el, "function") == 0) { + const XML_Char *name = NULL; + pf_generic fun = NULL; + int i; + + for (i = 0; attr[i]; i += 2) { + if (xml_strcmp(attr[i], "name") == 0) { + name = attr[i + 1]; + } + else if (xml_strcmp(attr[i], "value") == 0) { + fun = get_function((const char *)attr[i + 1]); + } + else { + handle_bad_input(ud, el, attr[i]); + } + } + assert(rtype); + if (name && fun) { + if (xml_strcmp(name, "change") == 0) { + rtype->uchange = (rtype_uchange)fun; + } + else if (xml_strcmp(name, "name") == 0) { + rtype->name = (rtype_name)fun; + } + else if (xml_strcmp(name, "attack") == 0) { + assert(rtype->wtype); + rtype->wtype->attack = (wtype_attack)fun; + } + } ++ud->errors; /* TODO */ } diff --git a/src/kernel/item.h b/src/kernel/item.h index 802c483a8..f0ee6050b 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -40,6 +40,7 @@ extern "C" { struct gamedata; struct rawmaterial_type; struct resource_mod; + struct weapon_type; typedef struct item { struct item *next; @@ -66,9 +67,12 @@ extern "C" { void item_done(void); + typedef bool(*wtype_attack)(const struct troop *, + const struct weapon_type *, int *); typedef int(*rtype_uchange) (struct unit * user, const struct resource_type * rtype, int delta); typedef char *(*rtype_name) (const struct resource_type * rtype, int flags); + typedef struct resource_type { /* --- constants --- */ char *_name; /* wie es hei�t */ diff --git a/src/xmlreader.c b/src/xmlreader.c index cffbb9a1e..c65a4ca9c 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -654,9 +654,7 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) } assert(propValue != NULL); if (strcmp((const char *)propValue, "attack") == 0) { - wtype->attack = - (bool(*)(const struct troop *, const struct weapon_type *, - int *))fun; + wtype->attack = (wtype_attack)fun; } else { log_error("unknown function type '%s' for item '%s'\n", (const char *)propValue, itype->rtype->_name); From dc891a94b4d44a002af255eebf60fa7c0e1fd4cc Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 29 Apr 2018 10:32:10 +0200 Subject: [PATCH 15/59] armor and weapon are harder to read than other items. modifier handling for weapons seems ok, except races. --- src/exparse.c | 382 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 297 insertions(+), 85 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 8bee331fc..7ceb60728 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -3,7 +3,10 @@ #endif #include "exparse.h" +#include "alchemy.h" + #include "kernel/build.h" +#include "kernel/building.h" #include "kernel/item.h" #include "kernel/race.h" #include "kernel/resources.h" @@ -35,22 +38,23 @@ enum { EXP_UNKNOWN, - EXP_RESOURCES, + EXP_WEAPON, + EXP_ARMOR, EXP_BUILDINGS, EXP_SHIPS, EXP_MESSAGES, EXP_STRINGS, }; -typedef struct userdata { +typedef struct parseinfo { int type; int depth; int errors; XML_Char *cdata; size_t clength; void *object; -} userdata; +} parseinfo; static int xml_strcmp(const XML_Char *xs, const char *cs) { return strcmp(xs, cs); @@ -64,28 +68,28 @@ static bool xml_bool(const XML_Char *val) { } static int xml_int(const XML_Char *val) { - return atoi((const char *)val); + return atoi(val); } static double xml_float(const XML_Char *val) { - return atof((const char *)val); + return atof(val); } static variant xml_fraction(const XML_Char *val) { int num, den = 100; - double fval = atof((const char *)val); + double fval = atof(val); num = (int)(fval * den + 0.5); return frac_make(num, den); } -static void handle_bad_input(userdata *ud, 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) { - log_error("unknown attribute in <%s>: %s", (const char *)el, (const char *)attr); + log_error("unknown attribute in <%s>: %s", el, attr); } else { - log_error("unexpected element <%s>", (const char *)el); + log_error("unexpected element <%s>", el); } - ++ud->errors; + ++pi->errors; } static bool handle_flag(int *flags, const XML_Char **pair, const char *names[]) { @@ -104,7 +108,7 @@ static bool handle_flag(int *flags, const XML_Char **pair, const char *names[]) return false; } -static void handle_resource(userdata *ud, const XML_Char *el, const XML_Char **attr) { +static void handle_resource(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { const char *flag_names[] = { "item", "limited", "pooled", NULL }; int i; const char *name = NULL, *appear = NULL; @@ -113,18 +117,18 @@ static void handle_resource(userdata *ud, const XML_Char *el, const XML_Char **a (void)el; for (i = 0; attr[i]; i += 2) { if (xml_strcmp(attr[i], "name") == 0) { - name = (const char *)attr[i + 1]; + name = 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]; + appear = attr[i + 1]; flags |= RTF_ITEM; } else if (xml_strcmp(attr[i], "material") == 0) { material = xml_bool(attr[i + 1]); } else if (!handle_flag(&flags, attr + i, flag_names)) { - handle_bad_input(ud, el, attr[i]); + handle_bad_input(pi, el, attr[i]); } } if (name) { @@ -138,14 +142,14 @@ static void handle_resource(userdata *ud, const XML_Char *el, const XML_Char **a if (material) { rmt_create(rtype); } - ud->object = rtype; + pi->object = rtype; } } -static void handle_item(userdata *ud, const XML_Char *el, const XML_Char **attr) { +static void handle_item(parseinfo *pi, 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; + resource_type *rtype = (resource_type *)pi->object; item_type * itype = rtype->itype; assert(rtype); if (!itype) { @@ -175,15 +179,15 @@ static void handle_item(userdata *ud, const XML_Char *el, const XML_Char **attr) itype->mask_deny = rc_mask(buffer); } else if (!handle_flag(&flags, attr + i, flag_names)) { - handle_bad_input(ud, el, attr[i]); + handle_bad_input(pi, el, attr[i]); } } itype->flags = flags; } -static void handle_armor(userdata *ud, const XML_Char *el, const XML_Char **attr) { +static void handle_armor(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { const char *flag_names[] = { "shield", "laen", NULL }; - resource_type *rtype = (resource_type *)ud->object; + resource_type *rtype = (resource_type *)pi->object; item_type * itype = rtype->itype; armor_type *atype = new_armortype(itype, 0.0, frac_zero, 0, 0); int i, flags = 0; @@ -201,15 +205,15 @@ static void handle_armor(userdata *ud, const XML_Char *el, const XML_Char **attr atype->magres = xml_fraction(attr[i + 1]); } else if (!handle_flag(&flags, attr + i, flag_names)) { - handle_bad_input(ud, el, attr[i]); + handle_bad_input(pi, el, attr[i]); } } atype->flags = flags; } -static void handle_weapon(userdata *ud, const XML_Char *el, const XML_Char **attr) { +static void handle_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { const char *flag_names[] = { "missile", "magical", "pierce", "cut", "bash", "siege", "armorpiercing", "horse", "useshield", NULL }; - resource_type *rtype = (resource_type *)ud->object; + resource_type *rtype = (resource_type *)pi->object; item_type * itype = rtype->itype; weapon_type *wtype = new_weapontype(itype, 0, frac_zero, NULL, 0, 0, 0, NOSKILL); int i, flags = 0; @@ -230,25 +234,132 @@ static void handle_weapon(userdata *ud, const XML_Char *el, const XML_Char **att wtype->magres = xml_fraction(attr[i + 1]);; } else if (!handle_flag(&flags, attr + i, flag_names)) { - handle_bad_input(ud, el, attr[i]); + handle_bad_input(pi, el, attr[i]); } } wtype->flags = flags; } + +static void XMLCALL start_armor(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { + resource_type *rtype = (resource_type *)pi->object; + + assert(rtype && rtype->atype); + if (xml_strcmp(el, "modifier") == 0) { + } + handle_bad_input(pi, el, NULL); +} + +#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) { + resource_type *rtype = (resource_type *)pi->object; + + assert(rtype && rtype->wtype); + if (xml_strcmp(el, "function") == 0) { + ++pi->errors; + } + else if (xml_strcmp(el, "modifier") == 0) { + const XML_Char *type = NULL; + race *rc = NULL; + int i, flags = 0; + int value = 0; + + 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 = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "race") == 0) { + rc = rc_get_or_create(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "offensive") == 0) { + if (xml_bool(attr[i + 1])) { + flags |= WMF_OFFENSIVE; + } + } + else if (xml_strcmp(attr[i], "defensive") == 0) { + if (xml_bool(attr[i + 1])) { + flags |= WMF_DEFENSIVE; + } + } + else if (xml_strcmp(attr[i], "walking") == 0) { + if (xml_bool(attr[i + 1])) { + flags |= WMF_WALKING; + } + } + else if (xml_strcmp(attr[i], "riding") == 0) { + if (xml_bool(attr[i + 1])) { + flags |= WMF_RIDING; + } + } + else if (xml_strcmp(attr[i], "against_riding") == 0) { + if (xml_bool(attr[i + 1])) { + flags |= WMF_AGAINST_RIDING; + } + } + else if (xml_strcmp(attr[i], "against_walking") == 0) { + if (xml_bool(attr[i + 1])) { + flags |= WMF_AGAINST_WALKING; + } + } + else { + handle_bad_input(pi, el, attr[i]); + } + } + if (type) { + weapon_mod *mod = wmods + nwmods; + + assert(nwmods < WMOD_MAX); + ++nwmods; + + /* weapon modifiers */ + if (xml_strcmp(type, "missile_target") == 0) { + flags |= WMF_MISSILE_TARGET; + } + else if (xml_strcmp(type, "require") == 0) { + /* does require even work? */ + flags = flags; + } + else if (xml_strcmp(type, "damage") == 0) { + flags |= WMF_DAMAGE; + } + else if (xml_strcmp(type, "skill") == 0) { + flags |= WMF_SKILL; + } + else { + handle_bad_input(pi, el, type); + } + mod->value = value; + mod->flags = flags; + mod->races = NULL; + } + else { + ++pi->errors; + } + } + else { + handle_bad_input(pi, el, NULL); + } +} + #define MAX_REQUIREMENTS 8 static requirement reqs[MAX_REQUIREMENTS]; static int nreqs; -static void XMLCALL start_resources(userdata *ud, const XML_Char *el, const XML_Char **attr) { - resource_type *rtype = (resource_type *)ud->object; +static void XMLCALL start_resources(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { + resource_type *rtype = (resource_type *)pi->object; if (xml_strcmp(el, "resource") == 0) { - handle_resource(ud, el, attr); + handle_resource(pi, el, attr); } else if (rtype) { if (xml_strcmp(el, "item") == 0) { assert(rtype); - handle_item(ud, el, attr); + handle_item(pi, el, attr); } else if (xml_strcmp(el, "function") == 0) { const XML_Char *name = NULL; @@ -260,10 +371,10 @@ static void XMLCALL start_resources(userdata *ud, const XML_Char *el, const XML_ name = attr[i + 1]; } else if (xml_strcmp(attr[i], "value") == 0) { - fun = get_function((const char *)attr[i + 1]); + fun = get_function(attr[i + 1]); } else { - handle_bad_input(ud, el, attr[i]); + handle_bad_input(pi, el, attr[i]); } } @@ -280,8 +391,6 @@ static void XMLCALL start_resources(userdata *ud, const XML_Char *el, const XML_ rtype->wtype->attack = (wtype_attack)fun; } } - ++ud->errors; - /* TODO */ } else if (rtype->itype) { item_type *itype = rtype->itype; @@ -290,7 +399,7 @@ static void XMLCALL start_resources(userdata *ud, const XML_Char *el, const XML_ int i; for (i = 0; attr[i]; i += 2) { if (xml_strcmp(attr[i], "skill") == 0) { - con->skill = findskill((const char *)attr[i + 1]); + con->skill = findskill(attr[i + 1]); } else if (xml_strcmp(attr[i], "maxsize") == 0) { con->maxsize = xml_int(attr[i + 1]); @@ -302,12 +411,50 @@ static void XMLCALL start_resources(userdata *ud, const XML_Char *el, const XML_ con->minskill = xml_int(attr[i + 1]); } else { - handle_bad_input(ud, el, attr[i]); + handle_bad_input(pi, el, attr[i]); } } itype->construction = con; nreqs = 0; } + else if (xml_strcmp(el, "modifier") == 0) { + int i; + double value = 0; + building_type * btype = NULL; + race *rc = NULL; + const XML_Char *type = 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], "building") == 0) { + btype = bt_get_or_create(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "race") == 0) { + rc = rc_get_or_create(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "value") == 0) { + value = xml_float(attr[i + 1]); + } + else { + handle_bad_input(pi, el, attr[i]); + } + } + /* resource modifiers */ + if (xml_strcmp(type, "skill") == 0) { + /* TODO: dupe with weapons! */ + } + else if (xml_strcmp(type, "save") == 0) { + } + else if (xml_strcmp(type, "require") == 0) { + } + else if (xml_strcmp(type, "material") == 0) { + } + else { + handle_bad_input(pi, el, type); + } + } else if (xml_strcmp(el, "requirement") == 0) { requirement *req; int i; @@ -316,11 +463,14 @@ static void XMLCALL start_resources(userdata *ud, const XML_Char *el, const XML_ req = reqs + nreqs; for (i = 0; attr[i]; i += 2) { if (xml_strcmp(attr[i], "type") == 0) { - req->rtype = rt_get_or_create((const char *)attr[i + 1]); + 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; } @@ -328,14 +478,24 @@ static void XMLCALL start_resources(userdata *ud, const XML_Char *el, const XML_ rtype->ltype = new_luxurytype(itype, 0); } else if (xml_strcmp(el, "potion") == 0) { - /* TODO */ - ++ud->errors; + int i, level = 0; + for (i = 0; attr[i]; i += 2) { + if (xml_strcmp(attr[i], "level") == 0) { + level = xml_int(attr[i + 1]); + } + else { + handle_bad_input(pi, el, attr[i]); + } + } + new_potiontype(itype, level); } else if (xml_strcmp(el, "armor") == 0) { - handle_armor(ud, el, attr); + pi->type = EXP_ARMOR; + handle_armor(pi, el, attr); } else if (xml_strcmp(el, "weapon") == 0) { - handle_weapon(ud, el, attr); + pi->type = EXP_WEAPON; + handle_weapon(pi, el, attr); } else if (rtype->wtype) { weapon_type *wtype = rtype->wtype; @@ -352,71 +512,114 @@ static void XMLCALL start_resources(userdata *ud, const XML_Char *el, const XML_ wtype->damage[pos] = str_strdup(attr[i + 1]); } else { - handle_bad_input(ud, el, NULL); + handle_bad_input(pi, el, NULL); } } } else { - handle_bad_input(ud, el, NULL); + handle_bad_input(pi, el, NULL); } } else { - handle_bad_input(ud, el, NULL); + handle_bad_input(pi, el, NULL); } } else { - handle_bad_input(ud, el, NULL); + handle_bad_input(pi, el, NULL); } } else { - handle_bad_input(ud, el, NULL); + handle_bad_input(pi, 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; + parseinfo *pi = (parseinfo *)data; + if (pi->depth == 0) { + pi->type = EXP_UNKNOWN; if (xml_strcmp(el, "eressea") != 0) { - handle_bad_input(ud, el, NULL); + handle_bad_input(pi, el, NULL); } } - else if (ud->depth == 1) { + else if (pi->depth == 1) { if (xml_strcmp(el, "resources") == 0) { - ud->type = EXP_RESOURCES; + pi->type = EXP_RESOURCES; } else if (xml_strcmp(el, "buildings") == 0) { - ud->type = EXP_BUILDINGS; + pi->type = EXP_BUILDINGS; } else if (xml_strcmp(el, "ships") == 0) { - ud->type = EXP_SHIPS; + pi->type = EXP_SHIPS; } else if (xml_strcmp(el, "messages") == 0) { - ud->type = EXP_MESSAGES; + pi->type = EXP_MESSAGES; } else if (xml_strcmp(el, "strings") == 0) { - ud->type = EXP_STRINGS; + pi->type = EXP_STRINGS; } else { - handle_bad_input(ud, el, NULL); + handle_bad_input(pi, el, NULL); } } else { - switch (ud->type) { + switch (pi->type) { case EXP_RESOURCES: - start_resources(ud, el, attr); + start_resources(pi, el, attr); + break; + case EXP_WEAPON: + start_weapon(pi, el, attr); + break; + case EXP_ARMOR: + start_armor(pi, el, attr); break; default: /* not implemented */ - handle_bad_input(ud, el, NULL); + handle_bad_input(pi, el, NULL); } } - ++ud->depth; + ++pi->depth; } -static void end_resources(userdata *ud, const XML_Char *el) { - resource_type *rtype = (resource_type *)ud->object; - if (xml_strcmp(el, "construction") == 0) { +static void end_armor(parseinfo *pi, const XML_Char *el) { + resource_type *rtype = (resource_type *)pi->object; + assert(rtype && rtype->atype); + + if (xml_strcmp(el, "armor") == 0) { + pi->type = EXP_RESOURCES; + } + else if (xml_strcmp(el, "modifier") == 0) { + } + else { + handle_bad_input(pi, el, NULL); + } +} + +static void end_weapon(parseinfo *pi, const XML_Char *el) { + resource_type *rtype = (resource_type *)pi->object; + assert(rtype && rtype->wtype); + + if (xml_strcmp(el, "weapon") == 0) { + pi->type = EXP_RESOURCES; + } + else if (xml_strcmp(el, "modifier") == 0) { + if (nwmods > 0) { + weapon_type *wtype = rtype->wtype; + wtype->modifiers = calloc(sizeof(weapon_mod), nwmods + 1); + memcpy(wtype->modifiers, wmods, sizeof(weapon_mod) * nwmods); + nwmods = 0; + } + } + else { + handle_bad_input(pi, el, NULL); + } +} + +static void end_resources(parseinfo *pi, const XML_Char *el) { + resource_type *rtype = (resource_type *)pi->object; + if (xml_strcmp(el, "resources") == 0) { + pi->type = EXP_UNKNOWN; + } + else if (xml_strcmp(el, "construction") == 0) { if (nreqs > 0) { construction *con = rtype->itype->construction; con->materials = calloc(sizeof(requirement), nreqs + 1); @@ -427,43 +630,52 @@ static void end_resources(userdata *ud, const XML_Char *el) { } static void XMLCALL handle_end(void *data, const XML_Char *el) { - userdata *ud = (userdata *)data; + parseinfo *pi = (parseinfo *)data; - if (ud->type == EXP_RESOURCES) { - end_resources(ud, el); - } - else { - if (ud->cdata) { - free(ud->cdata); - ud->cdata = NULL; - ud->clength = 0; + switch (pi->type) { + case EXP_RESOURCES: + end_resources(pi, el); + break; + case EXP_ARMOR: + end_armor(pi, el); + break; + case EXP_WEAPON: + end_weapon(pi, el); + break; + default: + if (pi->depth == 1) { + pi->type = EXP_UNKNOWN; + } + if (pi->cdata) { + free(pi->cdata); + pi->cdata = NULL; + pi->clength = 0; } } - --ud->depth; - if (ud->depth == 0) { - ud->type = EXP_UNKNOWN; + --pi->depth; + if (pi->depth == 0) { + assert(pi->type == EXP_UNKNOWN); } } static void XMLCALL handle_data(void *data, const XML_Char *xs, int len) { - userdata *ud = (userdata *)data; + parseinfo *pi = (parseinfo *)data; if (len > 0) { - if (ud->type == EXP_MESSAGES && ud->depth == 4) { + if (pi->type == EXP_MESSAGES && pi->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; + pi->cdata = realloc(pi->cdata, pi->clength + bytes); + memcpy(pi->cdata + pi->clength, xs, bytes); + pi->clength = pi->clength + bytes; } } } - int exparse_readfile(const char * filename) { XML_Parser xp; FILE *F; int err = 0; char buf[4096]; - userdata ud; + parseinfo pi; F = fopen(filename, "r"); if (!F) { @@ -472,8 +684,8 @@ int exparse_readfile(const char * filename) { 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)); + XML_SetUserData(xp, &pi); + memset(&pi, 0, sizeof(pi)); for (;;) { size_t len = (int) fread(buf, 1, sizeof(buf), F); int done; @@ -496,11 +708,11 @@ int exparse_readfile(const char * filename) { break; } } - assert(ud.depth == 0); + assert(pi.depth == 0); XML_ParserFree(xp); fclose(F); if (err != 0) { return err; } - return ud.errors; + return pi.errors; } From 10884c825ed2c74f19168d1007f6b55f44001a70 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 29 Apr 2018 16:11:35 +0200 Subject: [PATCH 16/59] fix compile, invalid use of rc_mask. --- src/exparse.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 7ceb60728..fba7188e1 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -170,13 +170,13 @@ static void handle_item(parseinfo *pi, const XML_Char *el, const XML_Char **attr size_t len = strlen(attr[i + 1]); assert(len < sizeof(buffer)); memcpy(buffer, attr[i + 1], len + 1); - itype->mask_allow = rc_mask(buffer); + itype->mask_allow = rc_get_mask(buffer); } else if (xml_strcmp(attr[i], "deny") == 0) { size_t len = strlen(attr[i + 1]); assert(len < sizeof(buffer)); memcpy(buffer, attr[i + 1], len + 1); - itype->mask_deny = rc_mask(buffer); + itype->mask_deny = rc_get_mask(buffer); } else if (!handle_flag(&flags, attr + i, flag_names)) { handle_bad_input(pi, el, attr[i]); @@ -263,8 +263,7 @@ static void XMLCALL start_weapon(parseinfo *pi, const XML_Char *el, const XML_Ch } else if (xml_strcmp(el, "modifier") == 0) { const XML_Char *type = NULL; - race *rc = NULL; - int i, flags = 0; + int i, flags = 0, race_mask = 0; int value = 0; for (i = 0; attr[i]; i += 2) { @@ -274,8 +273,10 @@ static void XMLCALL start_weapon(parseinfo *pi, const XML_Char *el, const XML_Ch else if (xml_strcmp(attr[i], "value") == 0) { value = xml_int(attr[i + 1]); } - else if (xml_strcmp(attr[i], "race") == 0) { - rc = rc_get_or_create(attr[i + 1]); + else if (xml_strcmp(type, "races") == 0) { + char list[64]; + strcpy(list, attr[i + 1]); + race_mask = rc_get_mask(list); } else if (xml_strcmp(attr[i], "offensive") == 0) { if (xml_bool(attr[i + 1])) { @@ -336,7 +337,7 @@ static void XMLCALL start_weapon(parseinfo *pi, const XML_Char *el, const XML_Ch } mod->value = value; mod->flags = flags; - mod->races = NULL; + mod->race_mask = race_mask; } else { ++pi->errors; From ec9038a5ea45c2bdb04f4fd504ec14913dbc2946 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 29 Apr 2018 17:27:12 +0200 Subject: [PATCH 17/59] fix copy/paste errors, remove armor element handlers. --- src/exparse.c | 72 +++++++++++++++++++-------------------------------- 1 file changed, 27 insertions(+), 45 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index fba7188e1..f76959e5d 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -40,7 +40,6 @@ enum { EXP_UNKNOWN, EXP_RESOURCES, EXP_WEAPON, - EXP_ARMOR, EXP_BUILDINGS, EXP_SHIPS, EXP_MESSAGES, @@ -241,15 +240,6 @@ static void handle_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **at } -static void XMLCALL start_armor(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { - resource_type *rtype = (resource_type *)pi->object; - - assert(rtype && rtype->atype); - if (xml_strcmp(el, "modifier") == 0) { - } - handle_bad_input(pi, el, NULL); -} - #define WMOD_MAX 8 static weapon_mod wmods[WMOD_MAX]; static int nwmods; @@ -273,7 +263,7 @@ static void XMLCALL start_weapon(parseinfo *pi, const XML_Char *el, const XML_Ch else if (xml_strcmp(attr[i], "value") == 0) { value = xml_int(attr[i + 1]); } - else if (xml_strcmp(type, "races") == 0) { + else if (xml_strcmp(attr[i], "races") == 0) { char list[64]; strcpy(list, attr[i + 1]); race_mask = rc_get_mask(list); @@ -352,6 +342,10 @@ static void XMLCALL start_weapon(parseinfo *pi, const XML_Char *el, const XML_Ch static requirement reqs[MAX_REQUIREMENTS]; static int nreqs; +#define RMOD_MAX 8 +static resource_mod rmods[RMOD_MAX]; +static int nrmods; + static void XMLCALL start_resources(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { resource_type *rtype = (resource_type *)pi->object; if (xml_strcmp(el, "resource") == 0) { @@ -420,37 +414,41 @@ static void XMLCALL start_resources(parseinfo *pi, const XML_Char *el, const XML } else if (xml_strcmp(el, "modifier") == 0) { int i; - double value = 0; - building_type * btype = NULL; - race *rc = NULL; const XML_Char *type = NULL; + resource_mod * mod = rmods + nrmods; + assert(nrmods < RMOD_MAX); + ++nrmods; for (i = 0; attr[i]; i += 2) { if (xml_strcmp(attr[i], "type") == 0) { type = attr[i + 1]; } else if (xml_strcmp(attr[i], "building") == 0) { - btype = bt_get_or_create(attr[i + 1]); + mod->btype = bt_get_or_create(attr[i + 1]); } - else if (xml_strcmp(attr[i], "race") == 0) { - rc = rc_get_or_create(attr[i + 1]); + else if (xml_strcmp(attr[i], "races") == 0) { + char list[64]; + strcpy(list, attr[i + 1]); + mod->race_mask = rc_get_mask(list); } else if (xml_strcmp(attr[i], "value") == 0) { - value = xml_float(attr[i + 1]); + mod->value = xml_fraction(attr[i + 1]); } else { handle_bad_input(pi, el, attr[i]); } } - /* resource modifiers */ if (xml_strcmp(type, "skill") == 0) { - /* TODO: dupe with weapons! */ - } - else if (xml_strcmp(type, "save") == 0) { - } - else if (xml_strcmp(type, "require") == 0) { + mod->type = RMT_PROD_SKILL; } else if (xml_strcmp(type, "material") == 0) { + mod->type = RMT_PROD_SAVE; + } + else if (xml_strcmp(type, "require") == 0) { + mod->type = RMT_PROD_REQUIRE; + } + else if (xml_strcmp(type, "save") == 0) { + mod->type = RMT_USE_SAVE; } else { handle_bad_input(pi, el, type); @@ -491,7 +489,6 @@ static void XMLCALL start_resources(parseinfo *pi, const XML_Char *el, const XML new_potiontype(itype, level); } else if (xml_strcmp(el, "armor") == 0) { - pi->type = EXP_ARMOR; handle_armor(pi, el, attr); } else if (xml_strcmp(el, "weapon") == 0) { @@ -570,9 +567,6 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char case EXP_WEAPON: start_weapon(pi, el, attr); break; - case EXP_ARMOR: - start_armor(pi, el, attr); - break; default: /* not implemented */ handle_bad_input(pi, el, NULL); @@ -581,20 +575,6 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char ++pi->depth; } -static void end_armor(parseinfo *pi, const XML_Char *el) { - resource_type *rtype = (resource_type *)pi->object; - assert(rtype && rtype->atype); - - if (xml_strcmp(el, "armor") == 0) { - pi->type = EXP_RESOURCES; - } - else if (xml_strcmp(el, "modifier") == 0) { - } - else { - handle_bad_input(pi, el, NULL); - } -} - static void end_weapon(parseinfo *pi, const XML_Char *el) { resource_type *rtype = (resource_type *)pi->object; assert(rtype && rtype->wtype); @@ -618,6 +598,11 @@ static void end_weapon(parseinfo *pi, const XML_Char *el) { static void end_resources(parseinfo *pi, const XML_Char *el) { resource_type *rtype = (resource_type *)pi->object; if (xml_strcmp(el, "resources") == 0) { + if (nrmods > 0) { + rtype->modifiers = calloc(sizeof(resource_mod), nrmods + 1); + memcpy(rtype->modifiers, rmods, sizeof(resource_mod) * nrmods); + nrmods = 0; + } pi->type = EXP_UNKNOWN; } else if (xml_strcmp(el, "construction") == 0) { @@ -637,9 +622,6 @@ static void XMLCALL handle_end(void *data, const XML_Char *el) { case EXP_RESOURCES: end_resources(pi, el); break; - case EXP_ARMOR: - end_armor(pi, el); - break; case EXP_WEAPON: end_weapon(pi, el); break; From 177e0159c4b9f69d6b66baf29a8357a8f781a6bf Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 29 Apr 2018 18:23:23 +0200 Subject: [PATCH 18/59] init construction defaults. --- src/exparse.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/exparse.c b/src/exparse.c index f76959e5d..a0daf41f8 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -392,6 +392,9 @@ static void XMLCALL start_resources(parseinfo *pi, const XML_Char *el, const XML if (xml_strcmp(el, "construction") == 0) { 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]); From 12416e8b0d616d241461fe6c840e56245e802b74 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 29 Apr 2018 18:44:17 +0200 Subject: [PATCH 19/59] fix reading skill modifiers. --- src/exparse.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index a0daf41f8..5db7f6b29 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -417,8 +417,10 @@ static void XMLCALL start_resources(parseinfo *pi, const XML_Char *el, const XML } else if (xml_strcmp(el, "modifier") == 0) { int i; + skill_t sk = NOSKILL; const XML_Char *type = NULL; resource_mod * mod = rmods + nrmods; + const XML_Char *value = NULL; assert(nrmods < RMOD_MAX); ++nrmods; @@ -429,13 +431,16 @@ static void XMLCALL start_resources(parseinfo *pi, const XML_Char *el, const XML else if (xml_strcmp(attr[i], "building") == 0) { mod->btype = bt_get_or_create(attr[i + 1]); } + else if (xml_strcmp(attr[i], "skill") == 0) { + sk = findskill(attr[i + 1]); + } else if (xml_strcmp(attr[i], "races") == 0) { char list[64]; strcpy(list, attr[i + 1]); mod->race_mask = rc_get_mask(list); } else if (xml_strcmp(attr[i], "value") == 0) { - mod->value = xml_fraction(attr[i + 1]); + value = attr[i + 1]; } else { handle_bad_input(pi, el, attr[i]); @@ -443,15 +448,19 @@ static void XMLCALL start_resources(parseinfo *pi, const XML_Char *el, const XML } if (xml_strcmp(type, "skill") == 0) { mod->type = RMT_PROD_SKILL; - } - else if (xml_strcmp(type, "material") == 0) { - mod->type = RMT_PROD_SAVE; + mod->value.sa[0] = (short)sk; + mod->value.sa[1] = (short)xml_int(value); } else if (xml_strcmp(type, "require") == 0) { mod->type = RMT_PROD_REQUIRE; } + else if (xml_strcmp(type, "material") == 0) { + mod->type = RMT_PROD_SAVE; + mod->value = xml_fraction(value); + } else if (xml_strcmp(type, "save") == 0) { mod->type = RMT_USE_SAVE; + mod->value = xml_fraction(value); } else { handle_bad_input(pi, el, type); @@ -601,12 +610,14 @@ static void end_weapon(parseinfo *pi, const XML_Char *el) { static void end_resources(parseinfo *pi, const XML_Char *el) { resource_type *rtype = (resource_type *)pi->object; if (xml_strcmp(el, "resources") == 0) { + pi->type = EXP_UNKNOWN; + } + else if (xml_strcmp(el, "resource") == 0) { if (nrmods > 0) { rtype->modifiers = calloc(sizeof(resource_mod), nrmods + 1); memcpy(rtype->modifiers, rmods, sizeof(resource_mod) * nrmods); nrmods = 0; } - pi->type = EXP_UNKNOWN; } else if (xml_strcmp(el, "construction") == 0) { if (nreqs > 0) { From 2579bf71b520baf4e843645592638dd18b3401f9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 29 Apr 2018 19:33:39 +0200 Subject: [PATCH 20/59] fix test_troll_quarrying_bonus --- src/exparse.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/exparse.c b/src/exparse.c index 5db7f6b29..7a337b023 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -422,6 +422,8 @@ static void XMLCALL start_resources(parseinfo *pi, const XML_Char *el, const XML resource_mod * mod = rmods + nrmods; const XML_Char *value = NULL; + mod->race_mask = 0; + mod->btype = NULL; assert(nrmods < RMOD_MAX); ++nrmods; for (i = 0; attr[i]; i += 2) { From a8f6f1a40c690c989a3f852e110fca4d46f17498 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 29 Apr 2018 20:23:41 +0200 Subject: [PATCH 21/59] there is no require element for weapons. oops. --- src/exparse.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 7a337b023..c98d28d6e 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -312,10 +312,6 @@ static void XMLCALL start_weapon(parseinfo *pi, const XML_Char *el, const XML_Ch if (xml_strcmp(type, "missile_target") == 0) { flags |= WMF_MISSILE_TARGET; } - else if (xml_strcmp(type, "require") == 0) { - /* does require even work? */ - flags = flags; - } else if (xml_strcmp(type, "damage") == 0) { flags |= WMF_DAMAGE; } From e5d3d77c067094c9dc8788a199928b1d261780c7 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 1 May 2018 18:52:48 +0200 Subject: [PATCH 22/59] begin parsing buildings. --- src/exparse.c | 68 +++++++++++++++++++++++++++++++++++++++++++ src/kernel/building.c | 1 + src/kernel/building.h | 10 ++++--- src/tests.c | 1 - src/xmlreader.c | 20 +++---------- 5 files changed, 79 insertions(+), 21 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index c98d28d6e..590cb446b 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -541,6 +541,70 @@ static void XMLCALL start_resources(parseinfo *pi, const XML_Char *el, const XML } } +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 void XMLCALL start_buildings(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { + const char *flag_names[] = { "nodestroy", "nobuild", "unique", "decay", "magic", "namechange", "fort", "oneperturn", NULL }; + if (xml_strcmp(el, "building") == 0) { + const XML_Char *name; + + name = attr_get(attr, "name"); + if (name) { + building_type *btype = bt_get_or_create(name); + int i, flags = BTF_DEFAULT; + + for (i = 0; attr[i]; i += 2) { + if (xml_strcmp(attr[i], "maxsize") == 0) { + btype->maxsize = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "capacity") == 0) { + btype->capacity = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "maxcapacity") == 0) { + btype->maxcapacity = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "magresbonus") == 0) { + btype->magresbonus = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "fumblebonus") == 0) { + btype->fumblebonus = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "taxes") == 0) { + btype->taxes = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "auraregen") == 0) { + btype->auraregen = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "magres") == 0) { + /* magres is specified in percent! */ + btype->magres = frac_make(xml_int(attr[i + 1]), 100); + } + 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]); + } + } + } + btype->flags = flags; + pi->object = btype; + } + } + else { + building_type *btype = (building_type *)pi->object; + assert(btype); + handle_bad_input(pi, el, NULL); + } +} + static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char **attr) { parseinfo *pi = (parseinfo *)data; if (pi->depth == 0) { @@ -571,6 +635,9 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char } else { switch (pi->type) { + case EXP_BUILDINGS: + start_buildings(pi, el, attr); + break; case EXP_RESOURCES: start_resources(pi, el, attr); break; @@ -639,6 +706,7 @@ static void XMLCALL handle_end(void *data, const XML_Char *el) { break; default: if (pi->depth == 1) { + pi->object = NULL; pi->type = EXP_UNKNOWN; } if (pi->cdata) { diff --git a/src/kernel/building.c b/src/kernel/building.c index c71cbc552..f3f01905f 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -144,6 +144,7 @@ building_type *bt_get_or_create(const char *name) if (btype == NULL) { btype = calloc(sizeof(building_type), 1); btype->_name = str_strdup(name); + btype->flags = BTF_DEFAULT; btype->auraregen = 1.0; btype->maxsize = -1; btype->capacity = 1; diff --git a/src/kernel/building.h b/src/kernel/building.h index 915a756b7..eacf42942 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -48,11 +48,13 @@ extern "C" { #define BTF_NOBUILD 0x02 /* special, can't be built */ #define BTF_UNIQUE 0x04 /* only one per struct region (harbour) */ #define BTF_DECAY 0x08 /* decays when not occupied */ -#define BTF_DYNAMIC 0x10 /* dynamic type, needs bt_write */ -#define BTF_MAGIC 0x40 /* magical effect */ +#define BTF_MAGIC 0x10 /* magical effect */ +#define BTF_NAMECHANGE 0x20 /* name and description can be changed more than once */ +#define BTF_FORTIFICATION 0x40 /* building_protection, safe from monsters */ #define BTF_ONEPERTURN 0x80 /* one one sizepoint can be added per turn */ -#define BTF_NAMECHANGE 0x100 /* name and description can be changed more than once */ -#define BTF_FORTIFICATION 0x200 /* building_protection, safe from monsters */ +#define BTF_DYNAMIC 0x100 /* dynamic type, needs bt_write */ + +#define BTF_DEFAULT (BTF_NAMECHANGE) typedef struct building_stage { /* construction of this building stage: */ diff --git a/src/tests.c b/src/tests.c index e3799c1b5..696baf447 100644 --- a/src/tests.c +++ b/src/tests.c @@ -338,7 +338,6 @@ building_type * test_create_buildingtype(const char * name) { construction *con; building_type *btype = bt_get_or_create(name); - btype->flags = BTF_NAMECHANGE; if (btype->stages) { con = btype->stages->construction; } else { diff --git a/src/xmlreader.c b/src/xmlreader.c index 45003e021..eea73e234 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -325,20 +325,20 @@ static int parse_buildings(xmlDocPtr doc) if (xml_bvalue(node, "nodestroy", false)) btype->flags |= BTF_INDESTRUCTIBLE; - if (xml_bvalue(node, "oneperturn", false)) - btype->flags |= BTF_ONEPERTURN; if (xml_bvalue(node, "nobuild", false)) btype->flags |= BTF_NOBUILD; - if (xml_bvalue(node, "namechange", true)) - btype->flags |= BTF_NAMECHANGE; if (xml_bvalue(node, "unique", false)) btype->flags |= BTF_UNIQUE; if (xml_bvalue(node, "decay", false)) btype->flags |= BTF_DECAY; if (xml_bvalue(node, "magic", false)) btype->flags |= BTF_MAGIC; + if (xml_bvalue(node, "namechange", true)) + btype->flags |= BTF_NAMECHANGE; if (xml_bvalue(node, "fort", false)) btype->flags |= BTF_FORTIFICATION; + if (xml_bvalue(node, "oneperturn", false)) + btype->flags |= BTF_ONEPERTURN; /* reading eressea/buildings/building/modifier */ xpath->node = node; @@ -1172,18 +1172,6 @@ static int parse_spells(xmlDocPtr doc) sp->syntax = str_strdup((const char *)propValue); xmlFree(propValue); } -#ifdef TODO /* no longer need it, spellbooks! */ - /* magic type */ - propValue = xmlGetProp(node, BAD_CAST "type"); - assert(propValue != NULL); - for (sp->magietyp = 0; sp->magietyp != MAXMAGIETYP; ++sp->magietyp) { - if (strcmp(magic_school[sp->magietyp], (const char *)propValue) == 0) - break; - } - assert(sp->magietyp != MAXMAGIETYP); - xmlFree(propValue); - /* level, rank and flags */ -#endif sp->rank = (char)xml_ivalue(node, "rank", -1); if (xml_bvalue(node, "los", false)) sp->sptyp |= TESTCANSEE; /* must see or have contact */ From 962b8082b7416218cca762e14c95199f00012acf Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 1 May 2018 19:05:04 +0200 Subject: [PATCH 23/59] fix test for lifepotion (tree growth was fuxxing it up) --- scripts/tests/e2/items.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/tests/e2/items.lua b/scripts/tests/e2/items.lua index e444a9c73..11bcdaed5 100644 --- a/scripts/tests/e2/items.lua +++ b/scripts/tests/e2/items.lua @@ -13,6 +13,7 @@ function setup() end function test_water_of_life() + eressea.settings.set("rules.grow.formula", 0) -- no tree growth local r = region.create(0, 0, "plain") r:set_flag(1, false) -- no mallorn local f = faction.create("human") From d2eccd56b923041d88f2e47c6dc28b038481cc60 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 1 May 2018 19:39:41 +0200 Subject: [PATCH 24/59] defaults --- src/kernel/building.test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/building.test.c b/src/kernel/building.test.c index 94dfd1b49..daa75b496 100644 --- a/src/kernel/building.test.c +++ b/src/kernel/building.test.c @@ -305,7 +305,7 @@ static void test_btype_defaults(CuTest *tc) { CuAssertIntEquals(tc, 0, btype->magres.sa[0]); CuAssertIntEquals(tc, 0, btype->magresbonus); CuAssertIntEquals(tc, 0, btype->fumblebonus); - CuAssertIntEquals(tc, 0, btype->flags); + CuAssertIntEquals(tc, BTF_DEFAULT, btype->flags); test_teardown(); } From 7128e1fb5c13601ec00b4489ec2176f94d422bd0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 1 May 2018 20:03:13 +0200 Subject: [PATCH 25/59] extract modifier parsing so it can be used for buildings. --- src/exparse.c | 136 +++++++++++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 56 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 590cb446b..23f1f6535 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -342,7 +342,61 @@ static int nreqs; static resource_mod rmods[RMOD_MAX]; static int nrmods; -static void XMLCALL start_resources(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; + skill_t sk = NOSKILL; + const XML_Char *type = NULL; + resource_mod * mod = rmods + nrmods; + const XML_Char *value = NULL; + + mod->race_mask = 0; + mod->btype = NULL; + assert(nrmods < RMOD_MAX); + ++nrmods; + for (i = 0; attr[i]; i += 2) { + if (xml_strcmp(attr[i], "type") == 0) { + type = attr[i + 1]; + } + else if (xml_strcmp(attr[i], "building") == 0) { + mod->btype = bt_get_or_create(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "skill") == 0) { + sk = findskill(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "races") == 0) { + char list[64]; + strcpy(list, attr[i + 1]); + mod->race_mask = rc_get_mask(list); + } + else if (xml_strcmp(attr[i], "value") == 0) { + value = attr[i + 1]; + } + else { + handle_bad_input(pi, el, attr[i]); + } + } + if (xml_strcmp(type, "skill") == 0) { + mod->type = RMT_PROD_SKILL; + mod->value.sa[0] = (short)sk; + mod->value.sa[1] = (short)xml_int(value); + } + else if (xml_strcmp(type, "require") == 0) { + mod->type = RMT_PROD_REQUIRE; + } + else if (xml_strcmp(type, "material") == 0) { + mod->type = RMT_PROD_SAVE; + mod->value = xml_fraction(value); + } + else if (xml_strcmp(type, "save") == 0) { + mod->type = RMT_USE_SAVE; + mod->value = xml_fraction(value); + } + else { + handle_bad_input(pi, el, type); + } +} + +static void start_resources(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { resource_type *rtype = (resource_type *)pi->object; if (xml_strcmp(el, "resource") == 0) { handle_resource(pi, el, attr); @@ -412,57 +466,7 @@ static void XMLCALL start_resources(parseinfo *pi, const XML_Char *el, const XML nreqs = 0; } else if (xml_strcmp(el, "modifier") == 0) { - int i; - skill_t sk = NOSKILL; - const XML_Char *type = NULL; - resource_mod * mod = rmods + nrmods; - const XML_Char *value = NULL; - - mod->race_mask = 0; - mod->btype = NULL; - assert(nrmods < RMOD_MAX); - ++nrmods; - for (i = 0; attr[i]; i += 2) { - if (xml_strcmp(attr[i], "type") == 0) { - type = attr[i + 1]; - } - else if (xml_strcmp(attr[i], "building") == 0) { - mod->btype = bt_get_or_create(attr[i + 1]); - } - else if (xml_strcmp(attr[i], "skill") == 0) { - sk = findskill(attr[i + 1]); - } - else if (xml_strcmp(attr[i], "races") == 0) { - char list[64]; - strcpy(list, attr[i + 1]); - mod->race_mask = rc_get_mask(list); - } - else if (xml_strcmp(attr[i], "value") == 0) { - value = attr[i + 1]; - } - else { - handle_bad_input(pi, el, attr[i]); - } - } - if (xml_strcmp(type, "skill") == 0) { - mod->type = RMT_PROD_SKILL; - mod->value.sa[0] = (short)sk; - mod->value.sa[1] = (short)xml_int(value); - } - else if (xml_strcmp(type, "require") == 0) { - mod->type = RMT_PROD_REQUIRE; - } - else if (xml_strcmp(type, "material") == 0) { - mod->type = RMT_PROD_SAVE; - mod->value = xml_fraction(value); - } - else if (xml_strcmp(type, "save") == 0) { - mod->type = RMT_USE_SAVE; - mod->value = xml_fraction(value); - } - else { - handle_bad_input(pi, el, type); - } + handle_modifier(pi, el, attr); } else if (xml_strcmp(el, "requirement") == 0) { requirement *req; @@ -598,6 +602,9 @@ static void XMLCALL start_buildings(parseinfo *pi, const XML_Char *el, const XML pi->object = btype; } } + else if (xml_strcmp(el, "modifier") == 0) { + handle_modifier(pi, el, attr); + } else { building_type *btype = (building_type *)pi->object; assert(btype); @@ -674,10 +681,7 @@ static void end_weapon(parseinfo *pi, const XML_Char *el) { static void end_resources(parseinfo *pi, const XML_Char *el) { resource_type *rtype = (resource_type *)pi->object; - if (xml_strcmp(el, "resources") == 0) { - pi->type = EXP_UNKNOWN; - } - else if (xml_strcmp(el, "resource") == 0) { + if (xml_strcmp(el, "resource") == 0) { if (nrmods > 0) { rtype->modifiers = calloc(sizeof(resource_mod), nrmods + 1); memcpy(rtype->modifiers, rmods, sizeof(resource_mod) * nrmods); @@ -692,12 +696,32 @@ static void end_resources(parseinfo *pi, const XML_Char *el) { nreqs = 0; } } + else if (xml_strcmp(el, "resources") == 0) { + pi->type = EXP_UNKNOWN; + } +} + +static void end_buildings(parseinfo *pi, const XML_Char *el) { + building_type *btype = (building_type *)pi->object; + if (xml_strcmp(el, "building") == 0) { + if (nrmods > 0) { + btype->modifiers = calloc(sizeof(resource_mod), nrmods + 1); + memcpy(btype->modifiers, rmods, sizeof(resource_mod) * nrmods); + nrmods = 0; + } + } + else if (xml_strcmp(el, "buildings") == 0) { + pi->type = EXP_UNKNOWN; + } } static void XMLCALL handle_end(void *data, const XML_Char *el) { parseinfo *pi = (parseinfo *)data; switch (pi->type) { + case EXP_BUILDINGS: + end_buildings(pi, el); + break; case EXP_RESOURCES: end_resources(pi, el); break; From 59f74d0a98f4821e4cb2fdb0629125aab4984fd0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 1 May 2018 20:58:30 +0200 Subject: [PATCH 26/59] parse building stages, too. --- src/exparse.c | 162 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 106 insertions(+), 56 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 23f1f6535..034343128 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -81,6 +81,20 @@ static variant xml_fraction(const XML_Char *val) { 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) { if (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; } - -#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) { 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 requirement reqs[MAX_REQUIREMENTS]; -static int nreqs; +static void handle_requirement(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { + requirement *req; + int i; -#define RMOD_MAX 8 -static resource_mod rmods[RMOD_MAX]; -static int nrmods; + assert(nreqs < MAX_REQUIREMENTS); + 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; +} static void handle_modifier(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { 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) { resource_type *rtype = (resource_type *)pi->object; 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) { item_type *itype = rtype->itype; if (xml_strcmp(el, "construction") == 0) { - 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 { - handle_bad_input(pi, el, attr[i]); - } - } - itype->construction = con; - nreqs = 0; + itype->construction = parse_construction(pi, el, attr); } else if (xml_strcmp(el, "modifier") == 0) { handle_modifier(pi, el, attr); } else if (xml_strcmp(el, "requirement") == 0) { - requirement *req; - int i; assert(itype->construction); - assert(nreqs < MAX_REQUIREMENTS); - 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; + handle_requirement(pi, el, attr); } else if (xml_strcmp(el, "luxury") == 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) { const XML_Char *name; + assert(stage == NULL); name = attr_get(attr, "name"); if (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; } } - else if (xml_strcmp(el, "modifier") == 0) { - handle_modifier(pi, el, attr); - } else { building_type *btype = (building_type *)pi->object; 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) { + /* stores the end of the building's stage list: */ + static building_stage **stage_ptr; + 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) { btype->modifiers = calloc(sizeof(resource_mod), nrmods + 1); memcpy(btype->modifiers, rmods, sizeof(resource_mod) * nrmods); From 6d9ecd1879dfbd9b9586d0c7f527096e6f3ec960 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 2 May 2018 21:37:57 +0200 Subject: [PATCH 27/59] finish loading buildings with expat. --- src/exparse.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/exparse.c b/src/exparse.c index 034343128..d50db46a0 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -83,6 +83,10 @@ static variant xml_fraction(const XML_Char *val) { static building_stage *stage; +#define UPKEEP_MAX 4 +static maintenance upkeep[UPKEEP_MAX]; +static int nupkeep; + #define MAX_REQUIREMENTS 8 static requirement reqs[MAX_REQUIREMENTS]; static int nreqs; @@ -363,6 +367,32 @@ static void handle_requirement(parseinfo *pi, const XML_Char *el, const XML_Char ++nreqs; } +static void handle_maintenance(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { + maintenance *up; + int i; + + assert(nupkeep < UPKEEP_MAX); + up = upkeep + nupkeep; + memset(up, 0, sizeof(maintenance)); + for (i = 0; attr[i]; i += 2) { + if (xml_strcmp(attr[i], "type") == 0) { + up->rtype = rt_get_or_create(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "amount") == 0) { + up->number = xml_int(attr[i + 1]); + } + else if (xml_strcmp(attr[i], "variable") == 0) { + if (xml_bool(attr[i + 1])) { + up->flags |= MTF_VARIABLE; + } + } + else { + handle_bad_input(pi, el, attr[i]); + } + } + ++nupkeep; +} + static void handle_modifier(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { int i; skill_t sk = NOSKILL; @@ -633,6 +663,10 @@ static void XMLCALL start_buildings(parseinfo *pi, const XML_Char *el, const XML stage = calloc(1, sizeof(building_stage)); stage->construction = parse_construction(pi, el, attr); } + else if (xml_strcmp(el, "maintenance") == 0) { + assert(!btype->maintenance); + handle_maintenance(pi, el, attr); + } else { handle_bad_input(pi, el, NULL); } @@ -754,6 +788,11 @@ static void end_buildings(parseinfo *pi, const XML_Char *el) { } else if (xml_strcmp(el, "building") == 0) { stage_ptr = NULL; + if (nupkeep > 0) { + btype->maintenance = calloc(sizeof(maintenance), nupkeep + 1); + memcpy(btype->maintenance, upkeep, sizeof(maintenance) * nupkeep); + nupkeep = 0; + } if (nrmods > 0) { btype->modifiers = calloc(sizeof(resource_mod), nrmods + 1); memcpy(btype->modifiers, rmods, sizeof(resource_mod) * nrmods); From cb27895b81cff33c52b92f689bb210c01716b417 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 3 May 2018 22:27:28 +0200 Subject: [PATCH 28/59] parsing ships, done! --- src/exparse.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 163 insertions(+), 6 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index d50db46a0..3e7e8b7a8 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -10,6 +10,8 @@ #include "kernel/item.h" #include "kernel/race.h" #include "kernel/resources.h" +#include "kernel/ship.h" +#include "kernel/terrain.h" #include "util/functions.h" #include "util/log.h" @@ -42,6 +44,7 @@ enum { EXP_WEAPON, EXP_BUILDINGS, EXP_SHIPS, + EXP_RACES, EXP_MESSAGES, EXP_STRINGS, }; @@ -81,6 +84,16 @@ static variant xml_fraction(const XML_Char *val) { 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; #define UPKEEP_MAX 4 @@ -393,6 +406,20 @@ static void handle_maintenance(parseinfo *pi, const XML_Char *el, const XML_Char ++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) { int i; 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) { - int i; - for (i = 0; attr[i]; i += 2) { - if (xml_strcmp(attr[i], key) == 0) { - return attr[i + 1]; +static void XMLCALL start_ships(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { + const char *flag_names[] = { "opensea", "fly", "nocoast", "speedy", NULL }; + if (xml_strcmp(el, "ship") == 0) { + const XML_Char *name; + + 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) { @@ -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) { pi->type = EXP_STRINGS; } + else if (xml_strcmp(el, "races") == 0) { + pi->type = EXP_RACES; + } else { 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: start_buildings(pi, el, attr); break; + case EXP_SHIPS: + start_ships(pi, el, attr); + break; case EXP_RESOURCES: start_resources(pi, el, attr); 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) { /* 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; if (xml_strcmp(el, "construction") == 0) { + assert(btype); if (stage) { if (nreqs > 0) { 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); nrmods = 0; } + pi->object = NULL; } else if (xml_strcmp(el, "buildings") == 0) { pi->type = EXP_UNKNOWN; @@ -808,6 +962,9 @@ static void XMLCALL handle_end(void *data, const XML_Char *el) { parseinfo *pi = (parseinfo *)data; switch (pi->type) { + case EXP_SHIPS: + end_ships(pi, el); + break; case EXP_BUILDINGS: end_buildings(pi, el); break; From 704148e4bd13d15183d8f58cbca83f25b55d51f0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 3 May 2018 23:04:32 +0200 Subject: [PATCH 29/59] more object types I haven't handled yet. --- src/exparse.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/exparse.c b/src/exparse.c index 3e7e8b7a8..d9cf52bf8 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -47,6 +47,8 @@ enum { EXP_RACES, EXP_MESSAGES, EXP_STRINGS, + EXP_SPELLS, + EXP_SPELLBOOKS, }; typedef struct parseinfo { @@ -819,6 +821,12 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char else if (xml_strcmp(el, "strings") == 0) { pi->type = EXP_STRINGS; } + else if (xml_strcmp(el, "spells") == 0) { + pi->type = EXP_SPELLS; + } + else if (xml_strcmp(el, "spellbooks") == 0) { + pi->type = EXP_SPELLBOOKS; + } else if (xml_strcmp(el, "races") == 0) { pi->type = EXP_RACES; } From 82ba0e62d4e2641d37579e700ebf43919a2ab7ba Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 4 May 2018 17:57:10 +0200 Subject: [PATCH 30/59] fix reading weapon damage. --- src/exparse.c | 51 +++++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index d9cf52bf8..aca7988fc 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -357,6 +357,24 @@ static void XMLCALL start_weapon(parseinfo *pi, const XML_Char *el, const XML_Ch ++pi->errors; } } + else if (xml_strcmp(el, "damage") == 0) { + weapon_type *wtype = rtype->wtype; + int i, pos = 0; + for (i = 0; attr[i]; i += 2) { + if (xml_strcmp(attr[i], "type") == 0) { + /* damage vs. rider(1) or not(0)? */ + if (xml_strcmp(attr[i + 1], "rider") == 0) { + pos = 1; + } + } + else if (xml_strcmp(attr[i], "value") == 0) { + wtype->damage[pos] = str_strdup(attr[i + 1]); + } + else { + handle_bad_input(pi, el, NULL); + } + } + } else { handle_bad_input(pi, el, NULL); } @@ -582,29 +600,6 @@ static void start_resources(parseinfo *pi, const XML_Char *el, const XML_Char ** pi->type = EXP_WEAPON; handle_weapon(pi, el, attr); } - else if (rtype->wtype) { - weapon_type *wtype = rtype->wtype; - if (xml_strcmp(el, "damage") == 0) { - int i, pos = 0; - for (i = 0; attr[i]; i += 2) { - if (xml_strcmp(attr[i], "type") == 0) { - /* damage vs. rider(1) or not(0)? */ - if (xml_strcmp(attr[i + 1], "rider") == 0) { - pos = 1; - } - } - else if (xml_strcmp(attr[i], "value") == 0) { - wtype->damage[pos] = str_strdup(attr[i + 1]); - } - else { - handle_bad_input(pi, el, NULL); - } - } - } - else { - handle_bad_input(pi, el, NULL); - } - } else { handle_bad_input(pi, el, NULL); } @@ -1028,9 +1023,9 @@ int exparse_readfile(const char * filename) { XML_SetUserData(xp, &pi); memset(&pi, 0, sizeof(pi)); for (;;) { - size_t len = (int) fread(buf, 1, sizeof(buf), F); + size_t len = (int)fread(buf, 1, sizeof(buf), F); int done; - + if (ferror(F)) { log_error("read error in %s", filename); err = -2; @@ -1039,9 +1034,9 @@ int exparse_readfile(const char * filename) { done = feof(F); if (XML_Parse(xp, buf, len, done) == XML_STATUS_ERROR) { log_error("parse error at line %" XML_FMT_INT_MOD " of %s: %" XML_FMT_STR, - XML_GetCurrentLineNumber(xp), - filename, - XML_ErrorString(XML_GetErrorCode(xp))); + XML_GetCurrentLineNumber(xp), + filename, + XML_ErrorString(XML_GetErrorCode(xp))); err = -1; break; } From 4e2171ace95932c48acff48dbf812e2e2bdf405d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 4 May 2018 17:58:26 +0200 Subject: [PATCH 31/59] fix finding resources if xml is not processed in predetermined order. --- src/xmlreader.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/xmlreader.c b/src/xmlreader.c index 6f7447bae..6fc87115a 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -386,7 +386,7 @@ static int parse_buildings(xmlDocPtr doc) propValue = xmlGetProp(node, BAD_CAST "type"); assert(propValue != NULL); - mt->rtype = rt_find((const char *)propValue); + mt->rtype = rt_get_or_create((const char *)propValue); assert(mt->rtype != NULL); xmlFree(propValue); @@ -1219,12 +1219,7 @@ static int parse_spells(xmlDocPtr doc) xmlNodePtr node = result->nodesetval->nodeTab[k]; propValue = xmlGetProp(node, BAD_CAST "name"); assert(propValue); - rtype = rt_find((const char *)propValue); - if (!rtype) { - log_error("spell %s uses unknown component %s.\n", sp->sname, (const char *)propValue); - xmlFree(propValue); - continue; - } + rtype = rt_get_or_create((const char *)propValue); component->type = rtype; xmlFree(propValue); component->amount = xml_ivalue(node, "amount", 1); @@ -1708,11 +1703,10 @@ static int parse_strings(xmlDocPtr doc) void register_xmlreader(void) { - xml_register_callback(parse_races); xml_register_callback(parse_resources); - xml_register_callback(parse_buildings); /* requires resources */ xml_register_callback(parse_ships); /* requires resources, terrains */ + xml_register_callback(parse_races); xml_register_callback(parse_equipment); /* requires resources */ xml_register_callback(parse_spells); /* requires resources */ From 85509cdf65de22280c184855e177308ec0688b77 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 4 May 2018 18:41:59 +0200 Subject: [PATCH 32/59] fix some bugs in reading weapons. --- res/adamantium.xml | 4 ++-- res/core/resources/laen.xml | 6 +++--- src/exparse.c | 33 +++++++++++++++++++++++++-------- src/xmlreader.c | 2 ++ 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/res/adamantium.xml b/res/adamantium.xml index 2e2311fcd..2bea686fe 100644 --- a/res/adamantium.xml +++ b/res/adamantium.xml @@ -6,8 +6,8 @@ - - + + diff --git a/res/core/resources/laen.xml b/res/core/resources/laen.xml index 1c14c2eff..95362280f 100644 --- a/res/core/resources/laen.xml +++ b/res/core/resources/laen.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/src/exparse.c b/src/exparse.c index aca7988fc..d00839283 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -277,7 +277,27 @@ static void XMLCALL start_weapon(parseinfo *pi, const XML_Char *el, const XML_Ch assert(rtype && rtype->wtype); if (xml_strcmp(el, "function") == 0) { - ++pi->errors; + const XML_Char *name = NULL, *type = NULL; + int i; + + for (i = 0; attr[i]; i += 2) { + if (xml_strcmp(attr[i], "name") == 0) { + type = attr[i + 1]; + } + else if (xml_strcmp(attr[i], "value") == 0) { + name = attr[i + 1]; + } + else { + handle_bad_input(pi, el, attr[i]); + } + } + if (type && xml_strcmp(type, "attack") == 0) { + pf_generic fun = get_function(name); + rtype->wtype->attack = (wtype_attack)fun; + } + else { + handle_bad_input(pi, el, attr[i]); + } } else if (xml_strcmp(el, "modifier") == 0) { const XML_Char *type = NULL; @@ -354,7 +374,7 @@ static void XMLCALL start_weapon(parseinfo *pi, const XML_Char *el, const XML_Ch mod->race_mask = race_mask; } else { - ++pi->errors; + handle_bad_input(pi, el, NULL); } } else if (xml_strcmp(el, "damage") == 0) { @@ -566,14 +586,14 @@ static void start_resources(parseinfo *pi, const XML_Char *el, const XML_Char ** } } } + else if (xml_strcmp(el, "modifier") == 0) { + handle_modifier(pi, el, attr); + } else if (rtype->itype) { item_type *itype = rtype->itype; if (xml_strcmp(el, "construction") == 0) { itype->construction = parse_construction(pi, el, attr); } - else if (xml_strcmp(el, "modifier") == 0) { - handle_modifier(pi, el, attr); - } else if (xml_strcmp(el, "requirement") == 0) { assert(itype->construction); handle_requirement(pi, el, attr); @@ -866,9 +886,6 @@ static void end_weapon(parseinfo *pi, const XML_Char *el) { nwmods = 0; } } - else { - handle_bad_input(pi, el, NULL); - } } static void end_resources(parseinfo *pi, const XML_Char *el) { diff --git a/src/xmlreader.c b/src/xmlreader.c index 6fc87115a..41b8fef78 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -1703,9 +1703,11 @@ static int parse_strings(xmlDocPtr doc) void register_xmlreader(void) { +#if 0 xml_register_callback(parse_resources); xml_register_callback(parse_buildings); /* requires resources */ xml_register_callback(parse_ships); /* requires resources, terrains */ +#endif xml_register_callback(parse_races); xml_register_callback(parse_equipment); /* requires resources */ From ad0f83dcca26add4449264ee8da87d71835ed3e5 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 4 May 2018 18:48:14 +0200 Subject: [PATCH 33/59] some xmlreader code still required that resources get loaded first. --- src/kernel/item.c | 15 +++++++-------- src/xmlreader.c | 14 ++++++++------ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/kernel/item.c b/src/kernel/item.c index 843107737..8afc6a5a9 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -243,17 +243,16 @@ item_type *it_find(const char *zname) } item_type *it_get_or_create(resource_type *rtype) { - item_type * itype; assert(rtype); - itype = it_find(rtype->_name); - if (!itype) { + if (!rtype->itype) { + item_type * itype; itype = (item_type *)calloc(sizeof(item_type), 1); + itype->rtype = rtype; + rtype->uchange = res_changeitem; + rtype->itype = itype; + rtype->flags |= RTF_ITEM; } - itype->rtype = rtype; - rtype->uchange = res_changeitem; - rtype->itype = itype; - rtype->flags |= RTF_ITEM; - return itype; + return rtype->itype; } static void lt_register(luxury_type * ltype) diff --git a/src/xmlreader.c b/src/xmlreader.c index 41b8fef78..48e0717f6 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -864,10 +864,12 @@ static void add_items(equipment * eq, xmlNodeSetPtr nsetItems) xmlNodePtr node = nsetItems->nodeTab[i]; xmlChar *propValue; const struct item_type *itype; + struct resource_type *rtype; propValue = xmlGetProp(node, BAD_CAST "name"); assert(propValue != NULL); - itype = it_find((const char *)propValue); + rtype = rt_get_or_create((const char *)propValue); + itype = it_get_or_create(rtype); xmlFree(propValue); if (itype != NULL) { propValue = xmlGetProp(node, BAD_CAST "amount"); @@ -1705,14 +1707,14 @@ void register_xmlreader(void) { #if 0 xml_register_callback(parse_resources); - xml_register_callback(parse_buildings); /* requires resources */ - xml_register_callback(parse_ships); /* requires resources, terrains */ + xml_register_callback(parse_buildings); + xml_register_callback(parse_ships); #endif xml_register_callback(parse_races); - xml_register_callback(parse_equipment); /* requires resources */ + xml_register_callback(parse_equipment); - xml_register_callback(parse_spells); /* requires resources */ - xml_register_callback(parse_spellbooks); /* requires spells */ + xml_register_callback(parse_spells); + xml_register_callback(parse_spellbooks); xml_register_callback(parse_strings); xml_register_callback(parse_messages); From 53f8b39e6e55436f61c2fdbf756201d335db0d95 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 4 May 2018 18:50:44 +0200 Subject: [PATCH 34/59] gcc and clang complain about unused function. --- src/xmlreader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xmlreader.c b/src/xmlreader.c index 48e0717f6..347b3f6eb 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -1705,7 +1705,7 @@ static int parse_strings(xmlDocPtr doc) void register_xmlreader(void) { -#if 0 +#ifdef _MSC_VER /* gcc and clang complain about unused function */ xml_register_callback(parse_resources); xml_register_callback(parse_buildings); xml_register_callback(parse_ships); From dca99ec79d2441ef68f580630a0f248d5e92f8c8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 4 May 2018 18:53:35 +0200 Subject: [PATCH 35/59] negative, sir! --- src/xmlreader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xmlreader.c b/src/xmlreader.c index 347b3f6eb..79c1ea094 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -1705,7 +1705,7 @@ static int parse_strings(xmlDocPtr doc) void register_xmlreader(void) { -#ifdef _MSC_VER /* gcc and clang complain about unused function */ +#ifndef _MSC_VER /* gcc and clang complain about unused function */ xml_register_callback(parse_resources); xml_register_callback(parse_buildings); xml_register_callback(parse_ships); From 3e2aa5b1a87390a6ea75c53f855f4a1917f25eca Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 5 May 2018 06:05:50 +0200 Subject: [PATCH 36/59] start ingesting spellbooks. --- src/exparse.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/exparse.c b/src/exparse.c index d00839283..0e5e6e8bf 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -11,6 +11,7 @@ #include "kernel/race.h" #include "kernel/resources.h" #include "kernel/ship.h" +#include "kernel/spellbook.h" #include "kernel/terrain.h" #include "util/functions.h" @@ -272,6 +273,42 @@ static void handle_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **at wtype->flags = flags; } +static void XMLCALL start_spellbooks(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { + spellbook * sb = (spellbook *)pi->object; + if (xml_strcmp(el, "spellbook") == 0) { + const XML_Char *name = attr_get(attr, "name"); + + if (name) { + pi->object = sb = get_spellbook(name); + } + else { + handle_bad_input(pi, el, NULL); + } + } + if (xml_strcmp(el, "entry") == 0) { + int i, level; + const XML_Char *name = NULL; + + assert(sb); + for (i = 0; attr[i]; i += 2) { + if (xml_strcmp(attr[i], "name") == 0) { + name = attr[i + 1]; + } + else if (xml_strcmp(attr[i], "level") == 0) { + level = xml_int(attr[i + 1]); + } + else { + handle_bad_input(pi, el, attr[i]); + } + } + + handle_bad_input(pi, el, NULL); + } + else { + handle_bad_input(pi, el, NULL); + } +} + static void XMLCALL start_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { resource_type *rtype = (resource_type *)pi->object; @@ -863,6 +900,9 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char case EXP_WEAPON: start_weapon(pi, el, attr); break; + case EXP_SPELLBOOKS: + start_spellbooks(pi, el, attr); + break; default: /* not implemented */ handle_bad_input(pi, el, NULL); From dc3918f4a647d49389a57a3eed8957b640246121 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 5 May 2018 07:48:38 +0200 Subject: [PATCH 37/59] read spellbook (expat) --- src/exparse.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 0e5e6e8bf..bbb1155cc 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -285,13 +285,13 @@ static void XMLCALL start_spellbooks(parseinfo *pi, const XML_Char *el, const XM handle_bad_input(pi, el, NULL); } } - if (xml_strcmp(el, "entry") == 0) { - int i, level; + else if (xml_strcmp(el, "entry") == 0) { + int i, level = 0; const XML_Char *name = NULL; assert(sb); for (i = 0; attr[i]; i += 2) { - if (xml_strcmp(attr[i], "name") == 0) { + if (xml_strcmp(attr[i], "spell") == 0) { name = attr[i + 1]; } else if (xml_strcmp(attr[i], "level") == 0) { @@ -301,8 +301,12 @@ static void XMLCALL start_spellbooks(parseinfo *pi, const XML_Char *el, const XM handle_bad_input(pi, el, attr[i]); } } - - handle_bad_input(pi, el, NULL); + if (name && level > 0) { + spellbook_addref(sb, name, level); + } + else { + handle_bad_input(pi, el, NULL); + } } else { handle_bad_input(pi, el, NULL); @@ -876,8 +880,9 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char else if (xml_strcmp(el, "spells") == 0) { pi->type = EXP_SPELLS; } - else if (xml_strcmp(el, "spellbooks") == 0) { + else if (xml_strcmp(el, "spellbook") == 0) { pi->type = EXP_SPELLBOOKS; + start_spellbooks(pi, el, attr); } else if (xml_strcmp(el, "races") == 0) { pi->type = EXP_RACES; From a44085de7a25f5a19ac0d7aea2b471ba834b00b2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 6 May 2018 13:57:28 +0200 Subject: [PATCH 38/59] spell flags, rearranged --- src/exparse.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/magic.h | 36 ++++++++++++++++++------------------ src/xmlreader.c | 4 ++-- 3 files changed, 68 insertions(+), 20 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index bbb1155cc..702c80557 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -273,6 +273,51 @@ static void handle_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **at wtype->flags = flags; } +static void XMLCALL start_spells(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { + const char *flag_names[] = { + "far", "variable", "ocean", "ship", "los", + "unittarget", "shiptarget", "buildingtarget", "regiontarget", NULL }; + if (xml_strcmp(el, "spell") == 0) { + spell *sp; + const XML_Char *name = NULL, *syntax = NULL, *parameter = NULL; + int i, rank = 0, flags = 0; + for (i = 0; attr[i]; i += 2) { + const XML_Char *key = attr[i], *val = attr[i + 1]; + if (xml_strcmp(key, "name") == 0) { + name = val; + } + else if (xml_strcmp(key, "syntax") == 0) { + syntax = val; + } + else if (xml_strcmp(key, "parameters") == 0) { + parameter = val; + } + else if (xml_strcmp(key, "rank") == 0) { + rank = xml_int(val); + } + else if (xml_strcmp(key, "combat") == 0) { + int mode = PRECOMBATSPELL; + int k = xml_int(val); + if (k > 1 && k <= 3) { + mode = mode << (k - 1); + } + flags |= mode; + } + else if (!handle_flag(&flags, attr + i, flag_names)) { + handle_bad_input(pi, el, attr[i]); + } + } + pi->object = sp = create_spell(name); + sp->rank = rank; + sp->syntax = str_strdup(syntax); + sp->parameter = str_strdup(parameter); + sp->sptyp = flags; + } + else { + handle_bad_input(pi, el, NULL); + } +} + static void XMLCALL start_spellbooks(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { spellbook * sb = (spellbook *)pi->object; if (xml_strcmp(el, "spellbook") == 0) { @@ -908,6 +953,9 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char case EXP_SPELLBOOKS: start_spellbooks(pi, el, attr); break; + case EXP_SPELLS: + start_spells(pi, el, attr); + break; default: /* not implemented */ handle_bad_input(pi, el, NULL); diff --git a/src/magic.h b/src/magic.h index 4a00a7b13..fd87428ae 100644 --- a/src/magic.h +++ b/src/magic.h @@ -154,28 +154,28 @@ extern "C" { #define FARCASTING (1<<0) /* ZAUBER [struct region x y] */ #define SPELLLEVEL (1<<1) /* ZAUBER [STUFE x] */ - /* ID's können zu drei unterschiedlichen Entitäten gehören: Einheiten, - * Gebäuden und Schiffen. */ -#define UNITSPELL (1<<2) /* ZAUBER .. [ ..] */ -#define SHIPSPELL (1<<3) /* ZAUBER .. [ ..] */ -#define BUILDINGSPELL (1<<4) /* ZAUBER .. [ ..] */ -#define REGIONSPELL (1<<5) /* wirkt auf struct region */ +#define OCEANCASTABLE (1<<2) /* Können auch nicht-Meermenschen auf + hoher See zaubern */ +#define ONSHIPCAST (1<<3) /* kann auch auf von Land ablegenden + Schiffen stehend gezaubert werden */ +#define TESTCANSEE (1<<4) /* alle Zielunits auf cansee prüfen */ -#define PRECOMBATSPELL (1<<7) /* PRÄKAMPFZAUBER .. */ -#define COMBATSPELL (1<<8) /* KAMPFZAUBER .. */ -#define POSTCOMBATSPELL (1<<9) /* POSTKAMPFZAUBER .. */ + /* ID's können zu drei unterschiedlichen Entitäten gehören: Einheiten, + * Gebäuden und Schiffen. */ +#define UNITSPELL (1<<5) /* ZAUBER .. [ ..] */ +#define SHIPSPELL (1<<6) /* ZAUBER .. [ ..] */ +#define BUILDINGSPELL (1<<7) /* ZAUBER .. [ ..] */ +#define REGIONSPELL (1<<8) /* wirkt auf struct region */ + +#define PRECOMBATSPELL (1<<9) /* PRÄKAMPFZAUBER .. */ +#define COMBATSPELL (1<<10) /* KAMPFZAUBER .. */ +#define POSTCOMBATSPELL (1<<11) /* POSTKAMPFZAUBER .. */ #define ISCOMBATSPELL (PRECOMBATSPELL|COMBATSPELL|POSTCOMBATSPELL) -#define OCEANCASTABLE (1<<10) /* Können auch nicht-Meermenschen auf - hoher See zaubern */ -#define ONSHIPCAST (1<<11) /* kann auch auf von Land ablegenden - Schiffen stehend gezaubert werden */ - /* */ -#define NOTFAMILIARCAST (1<<12) -#define TESTRESISTANCE (1<<13) /* alle Zielobjekte (u, s, b, r) auf +#define TESTRESISTANCE (1<<12) /* alle Zielobjekte (u, s, b, r) auf Magieresistenz prüfen */ -#define SEARCHLOCAL (1<<14) /* Ziel muss in der target_region sein */ -#define TESTCANSEE (1<<15) /* alle Zielunits auf cansee prüfen */ +#define SEARCHLOCAL (1<<13) /* Ziel muss in der target_region sein */ +#define NOTFAMILIARCAST (1<<14) /* not used by XML? */ #define ANYTARGET (UNITSPELL|REGIONSPELL|BUILDINGSPELL|SHIPSPELL) /* wirkt auf alle objekttypen (unit, ship, building, region) */ /* Flag Spruchkostenberechnung: */ diff --git a/src/xmlreader.c b/src/xmlreader.c index 006c37a8a..9d910f6fe 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -1174,7 +1174,7 @@ static int parse_spells(xmlDocPtr doc) sp->syntax = str_strdup((const char *)propValue); xmlFree(propValue); } - sp->rank = (char)xml_ivalue(node, "rank", 0); + sp->rank = (char)xml_ivalue(node, "rank", sp->rank); if (xml_bvalue(node, "los", false)) sp->sptyp |= TESTCANSEE; /* must see or have contact */ if (!xml_bvalue(node, "target_global", false)) @@ -1705,12 +1705,12 @@ void register_xmlreader(void) xml_register_callback(parse_resources); xml_register_callback(parse_buildings); xml_register_callback(parse_ships); + xml_register_callback(parse_spellbooks); #endif xml_register_callback(parse_races); xml_register_callback(parse_equipment); xml_register_callback(parse_spells); - xml_register_callback(parse_spellbooks); xml_register_callback(parse_strings); xml_register_callback(parse_messages); From adbf1098b91d3d885c6ae35d0e283ee336d98333 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 6 May 2018 14:02:44 +0200 Subject: [PATCH 39/59] we fail tests when not reading spell components. --- src/exparse.c | 8 +++++++- src/xmlreader.c | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 702c80557..411741c05 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -277,7 +277,13 @@ static void XMLCALL start_spells(parseinfo *pi, const XML_Char *el, const XML_Ch const char *flag_names[] = { "far", "variable", "ocean", "ship", "los", "unittarget", "shiptarget", "buildingtarget", "regiontarget", NULL }; - if (xml_strcmp(el, "spell") == 0) { + + if (xml_strcmp(el, "resource") == 0) { + spell_component *spc = NULL; + (void)spc; + handle_bad_input(pi, el, NULL); + } + else if (xml_strcmp(el, "spell") == 0) { spell *sp; const XML_Char *name = NULL, *syntax = NULL, *parameter = NULL; int i, rank = 0, flags = 0; diff --git a/src/xmlreader.c b/src/xmlreader.c index 9d910f6fe..afb639f1a 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -1706,11 +1706,11 @@ void register_xmlreader(void) xml_register_callback(parse_buildings); xml_register_callback(parse_ships); xml_register_callback(parse_spellbooks); + xml_register_callback(parse_spells); #endif xml_register_callback(parse_races); xml_register_callback(parse_equipment); - xml_register_callback(parse_spells); xml_register_callback(parse_strings); xml_register_callback(parse_messages); From b197bb395d48b5d5223006c9c4e59d31f5b0aeae Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 8 May 2018 23:06:33 +0200 Subject: [PATCH 40/59] parse spell components. --- src/exparse.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++---- src/magic.h | 12 ++++----- 2 files changed, 70 insertions(+), 11 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 411741c05..bc7218383 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -273,15 +273,50 @@ static void handle_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **at wtype->flags = flags; } +#define MAX_COMPONENTS 8 +static spell_component components[MAX_COMPONENTS]; +static int ncomponents; + static void XMLCALL start_spells(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { const char *flag_names[] = { "far", "variable", "ocean", "ship", "los", - "unittarget", "shiptarget", "buildingtarget", "regiontarget", NULL }; + "unittarget", "shiptarget", "buildingtarget", "regiontarget", "globaltarget", NULL }; if (xml_strcmp(el, "resource") == 0) { - spell_component *spc = NULL; - (void)spc; - handle_bad_input(pi, el, NULL); + spell_component *spc; + int i; + + assert(ncomponents < MAX_COMPONENTS); + spc = components + ncomponents; + spc->cost = SPC_FIX; + ++ncomponents; + memset(spc, 0, sizeof(spell_component)); + for (i = 0; attr[i]; i += 2) { + const XML_Char *key = attr[i], *val = attr[i + 1]; + if (xml_strcmp(key, "name") == 0) { + spc->type = rt_get_or_create(val); + } + else if (xml_strcmp(key, "amount") == 0) { + spc->amount = xml_int(val); + } + else if (xml_strcmp(key, "cost") == 0) { + if (xml_strcmp(val, "level") == 0) { + spc->cost = SPC_LEVEL; + } + else if (xml_strcmp(val, "linear") == 0) { + spc->cost = SPC_LINEAR; + } + else if (xml_strcmp(val, "fixed") == 0) { + spc->cost = SPC_FIX; + } + else { + handle_bad_input(pi, key, val); + } + } + else { + handle_bad_input(pi, el, key); + } + } } else if (xml_strcmp(el, "spell") == 0) { spell *sp; @@ -962,14 +997,33 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char case EXP_SPELLS: start_spells(pi, el, attr); break; + case EXP_UNKNOWN: + handle_bad_input(pi, el, NULL); + break; default: /* not implemented */ handle_bad_input(pi, el, NULL); + return; } } ++pi->depth; } +static void end_spells(parseinfo *pi, const XML_Char *el) { + if (xml_strcmp(el, "spells") == 0) { + pi->type = EXP_UNKNOWN; + } + else if (xml_strcmp(el, "spell") == 0) { + spell *sp = (spell *)pi->object; + if (ncomponents > 0) { + sp->components = calloc(sizeof(spell_component), ncomponents + 1); + memcpy(sp->components, components, sizeof(spell_component) * ncomponents); + ncomponents = 0; + } + pi->object = NULL; + } +} + static void end_weapon(parseinfo *pi, const XML_Char *el) { resource_type *rtype = (resource_type *)pi->object; assert(rtype && rtype->wtype); @@ -1093,6 +1147,9 @@ static void XMLCALL handle_end(void *data, const XML_Char *el) { case EXP_WEAPON: end_weapon(pi, el); break; + case EXP_SPELLS: + end_spells(pi, el); + break; default: if (pi->depth == 1) { pi->object = NULL; @@ -1160,7 +1217,9 @@ int exparse_readfile(const char * filename) { break; } } - assert(pi.depth == 0); + if (pi.depth != 0) { + err = -3; + } XML_ParserFree(xp); fclose(F); if (err != 0) { diff --git a/src/magic.h b/src/magic.h index b76bcfa75..654673245 100644 --- a/src/magic.h +++ b/src/magic.h @@ -166,15 +166,15 @@ extern "C" { #define SHIPSPELL (1<<6) /* ZAUBER .. [ ..] */ #define BUILDINGSPELL (1<<7) /* ZAUBER .. [ ..] */ #define REGIONSPELL (1<<8) /* wirkt auf struct region */ +#define GLOBALTARGET (1<<9) /* Ziel kann ausserhalb der region sein */ -#define PRECOMBATSPELL (1<<9) /* PRÄKAMPFZAUBER .. */ -#define COMBATSPELL (1<<10) /* KAMPFZAUBER .. */ -#define POSTCOMBATSPELL (1<<11) /* POSTKAMPFZAUBER .. */ +#define PRECOMBATSPELL (1<<10) /* PRÄKAMPFZAUBER .. */ +#define COMBATSPELL (1<<11) /* KAMPFZAUBER .. */ +#define POSTCOMBATSPELL (1<<12) /* POSTKAMPFZAUBER .. */ #define ISCOMBATSPELL (PRECOMBATSPELL|COMBATSPELL|POSTCOMBATSPELL) -#define TESTRESISTANCE (1<<12) /* alle Zielobjekte (u, s, b, r) auf - Magieresistenz prüfen */ -#define GLOBALTARGET (1<<13) /* Ziel muss in der target_region sein */ + +#define TESTRESISTANCE (1<<13) /* Zielobjekte auf Magieresistenz prüfen. not used in XML? */ #define NOTFAMILIARCAST (1<<14) /* not used by XML? */ #define ANYTARGET (UNITSPELL|REGIONSPELL|BUILDINGSPELL|SHIPSPELL) /* wirkt auf alle objekttypen (unit, ship, building, region) */ From 9e6ae0edc139c2c8a741c7127f4abf8ef2008985 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 9 May 2018 07:14:56 +0200 Subject: [PATCH 41/59] make str_strdup more forgiving --- src/util/strings.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/strings.c b/src/util/strings.c index 81fdc3713..ab85328ab 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -218,6 +218,7 @@ unsigned int wang_hash(unsigned int a) } char *str_strdup(const char *s) { + if (s == NULL) return NULL; #ifdef HAVE_STRDUP return strdup(s); #elif defined(_MSC_VER) From c05a65b881587ff66ef268997fa5351bc9c0b527 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 9 May 2018 22:16:30 +0200 Subject: [PATCH 42/59] expat parses (most of) races. fix canteach flag in XML. --- res/e3a/races.xml | 76 ++++++++-------- res/eressea.dtd | 190 +++++++++++++++++++++++++++++++++++++++ res/eressea/races.xml | 95 ++++++++++---------- res/races/dragon.xml | 2 +- res/races/goblin-3.xml | 2 +- res/races/halfling.xml | 2 +- src/exparse.c | 196 ++++++++++++++++++++++++++++++++++++++++- src/kernel/race.c | 15 ++-- src/kernel/race.h | 11 ++- src/kernel/race.test.c | 4 +- src/xmlreader.c | 22 ++--- 11 files changed, 498 insertions(+), 117 deletions(-) create mode 100644 res/eressea.dtd diff --git a/res/e3a/races.xml b/res/e3a/races.xml index bb70fa3df..00d34e58a 100644 --- a/res/e3a/races.xml +++ b/res/e3a/races.xml @@ -8,7 +8,7 @@ - + @@ -192,7 +192,7 @@ - + @@ -218,7 +218,7 @@ - + @@ -239,7 +239,7 @@ - + @@ -260,7 +260,7 @@ - + @@ -283,7 +283,7 @@ - + @@ -306,7 +306,7 @@ - + @@ -328,7 +328,7 @@ - + @@ -354,7 +354,7 @@ - + @@ -376,7 +376,7 @@ - + @@ -400,7 +400,7 @@ - + @@ -425,7 +425,7 @@ - + @@ -448,7 +448,7 @@ - + @@ -471,7 +471,7 @@ - + @@ -493,7 +493,7 @@ - + @@ -520,7 +520,7 @@ - + @@ -543,7 +543,7 @@ - + @@ -565,7 +565,7 @@ - + @@ -589,15 +589,15 @@ - + - + - + @@ -651,28 +651,28 @@ - + - + - + - + - + @@ -687,14 +687,14 @@ - + - + @@ -703,14 +703,14 @@ - + @@ -736,7 +736,7 @@ - + @@ -754,7 +754,7 @@ - + @@ -771,7 +771,7 @@ - + @@ -787,7 +787,7 @@ - + @@ -801,7 +801,7 @@ - + @@ -816,7 +816,7 @@ - + @@ -830,12 +830,12 @@ - + - + diff --git a/res/eressea.dtd b/res/eressea.dtd new file mode 100644 index 000000000..c58ea5f33 --- /dev/null +++ b/res/eressea.dtd @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/eressea/races.xml b/res/eressea/races.xml index 21ff5b028..eb85b6900 100644 --- a/res/eressea/races.xml +++ b/res/eressea/races.xml @@ -11,9 +11,8 @@ - + - @@ -27,7 +26,7 @@ - + @@ -60,7 +59,7 @@ - + @@ -88,7 +87,7 @@ - + @@ -115,7 +114,7 @@ - + @@ -144,7 +143,7 @@ - + @@ -173,7 +172,7 @@ - + @@ -203,7 +202,7 @@ - + @@ -237,7 +236,7 @@ - + @@ -267,7 +266,7 @@ - + @@ -299,7 +298,7 @@ - + @@ -329,7 +328,7 @@ - + @@ -358,7 +357,7 @@ - + @@ -388,7 +387,7 @@ - + @@ -417,7 +416,7 @@ - + @@ -448,7 +447,7 @@ - + @@ -479,7 +478,7 @@ - + @@ -508,7 +507,7 @@ - + @@ -540,7 +539,7 @@ - + @@ -570,16 +569,16 @@ - + - + + regaura="1.000000" weight="100" capacity="540" speed="1.000000" hp="20" damage="0d0" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="10" scarepeasants="yes" fly="yes" walk="yes" canteach="no" invinciblenonmagic="yes"> @@ -649,28 +648,28 @@ - + - + - + - + - + @@ -684,25 +683,25 @@ - + - + - + - + @@ -712,7 +711,7 @@ - + @@ -722,7 +721,7 @@ - + @@ -733,7 +732,7 @@ - + @@ -783,7 +782,7 @@ - + @@ -925,7 +924,7 @@ - + @@ -962,7 +961,7 @@ - + @@ -970,7 +969,7 @@ - + @@ -984,7 +983,7 @@ - + @@ -1001,7 +1000,7 @@ - + @@ -1017,7 +1016,7 @@ - + @@ -1032,7 +1031,7 @@ - + @@ -1045,7 +1044,7 @@ - + @@ -1059,7 +1058,7 @@ - + @@ -1072,11 +1071,11 @@ - + - + @@ -1203,7 +1202,7 @@ - + diff --git a/res/races/dragon.xml b/res/races/dragon.xml index 7e0da2056..c9692cd9b 100644 --- a/res/races/dragon.xml +++ b/res/races/dragon.xml @@ -3,7 +3,7 @@ diff --git a/res/races/goblin-3.xml b/res/races/goblin-3.xml index 636f8cc29..9eb7ea835 100644 --- a/res/races/goblin-3.xml +++ b/res/races/goblin-3.xml @@ -7,7 +7,7 @@ speed="1.0" hp="16" damage="1d5" unarmedattack="-2" unarmeddefense="0" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes" healing="2.0"> - + diff --git a/res/races/halfling.xml b/res/races/halfling.xml index 3628d2b35..1f326056f 100644 --- a/res/races/halfling.xml +++ b/res/races/halfling.xml @@ -1,7 +1,7 @@ - + diff --git a/src/exparse.c b/src/exparse.c index bc7218383..44455888a 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -128,7 +128,19 @@ static void handle_bad_input(parseinfo *pi, const XML_Char *el, const XML_Char * 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) { + const char * name = names[i]; + if (name[0] == '!') { + if (xml_strcmp(pair[0], name+1) == 0) { + if (xml_bool(pair[1])) { + *flags &= ~(1 << i); + } + else { + *flags |= (1 << i); + } + return true; + } + } + else if (xml_strcmp(pair[0], name) == 0) { if (xml_bool(pair[1])) { *flags |= (1 << i); } @@ -865,6 +877,173 @@ static void XMLCALL start_ships(parseinfo *pi, const XML_Char *el, const XML_Cha } } +static void XMLCALL start_races(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { + race *rc = (race *)pi->object; + const char *flag_names[] = { + "!playerrace", "killpeasants", "scarepeasants", "!cansteal", + "moverandom", "cannotmove", "learn", "fly", "swim", "walk", + "!canlearn", "!canteach", "horse", "desert", "illusionary", + "absorbpeasants", "noheal", "noweapons", "shapeshift", + "shapeshiftany", "undead", "dragon", "coastal", "unarmedguard", + "cansail", "invisible", "shipspeed", "moveattack", "migrants", NULL }; + const char *bflag_names[] = { + "equipment", "noblock", "resistpierce", "resistcut", "resistbash", + "invinciblenonmagic", "noattack", NULL }; + const char *eflag_names[] = { + "giveperson", "giveunit", "getitem", "recruitethereal", + "recruitunlimited", "stonegolem", "irongolem", NULL }; + + if (xml_strcmp(el, "attack") == 0) { + assert(rc); + } + else if (xml_strcmp(el, "familiar") == 0) { + assert(rc); + } + else if (xml_strcmp(el, "skill") == 0) { + const XML_Char *name = NULL; + int i, speed = 0, mod = 0; + + for (i = 0; attr[i]; i += 2) { + const XML_Char *key = attr[i], *val = attr[i + 1]; + if (xml_strcmp(key, "name") == 0) { + name = val; + } + else if (xml_strcmp(key, "modifier") == 0) { + mod = xml_int(val); + } + else if (xml_strcmp(key, "speed") == 0) { + speed = xml_int(val); + } + else { + handle_bad_input(pi, el, key); + } + } + if (name) { + skill_t sk = findskill(name); + if (sk != NOSKILL) { + rc->bonus[sk] = (char)mod; + if (speed != 0) { + set_study_speed(rc, sk, speed); + } + } + } + } + else if (xml_strcmp(el, "param") == 0) { + const XML_Char *key = attr_get(attr, "name"), *val = attr_get(attr, "value"); + if (key && val) { + rc_set_param(rc, key, val); + } + } + else if (xml_strcmp(el, "ai") == 0) { + /* AI flags are cumulative to race flags. XML format is dumb */ + int i, flags = 0; + assert(rc); + for (i = 0; attr[i]; i += 2) { + const XML_Char *key = attr[i], *val = attr[i + 1]; + if (xml_strcmp(key, "splitsize") == 0) { + rc->splitsize = xml_int(val); + } + else if (xml_strcmp(key, "scare") == 0) { + rc_set_param(rc, "scare", val); + } + else if (!handle_flag(&flags, attr + i, flag_names)) { + handle_bad_input(pi, el, key); + } + } + rc->flags |= flags; + } + else if (xml_strcmp(el, "race") == 0) { + const XML_Char *name; + + name = attr_get(attr, "name"); + if (name) { + assert(!rc); + pi->object = rc = rc_get_or_create(name); + int i; + + for (i = 0; attr[i]; i += 2) { + const XML_Char *key = attr[i], *val = attr[i + 1]; + if (xml_strcmp(key, "maxaura") == 0) { + rc->maxaura = (int)(100 * xml_float(val)); + } + else if (xml_strcmp(key, "magres") == 0) { + /* specified in percent: */ + rc->magres = frac_make(xml_int(val), 100); + } + else if (xml_strcmp(key, "healing") == 0) { + rc->healing = (int)(xml_float(val) * 100); + } + else if (xml_strcmp(key, "regaura") == 0) { + rc->regaura = xml_float(val); + } + else if (xml_strcmp(key, "recruitcost") == 0) { + rc->recruitcost = xml_int(val); + } + else if (xml_strcmp(key, "maintenance") == 0) { + rc->maintenance = xml_int(val); + } + else if (xml_strcmp(key, "income") == 0) { + rc->income = xml_int(val); + } + else if (xml_strcmp(key, "weight") == 0) { + rc->weight = xml_int(val); + } + else if (xml_strcmp(key, "capacity") == 0) { + rc->capacity = xml_int(val); + } + else if (xml_strcmp(key, "speed") == 0) { + rc->speed = xml_float(val); + } + else if (xml_strcmp(key, "hp") == 0) { + rc->hitpoints = xml_int(val); + } + else if (xml_strcmp(key, "ac") == 0) { + rc->armor = xml_int(val); + } + else if (xml_strcmp(key, "damage") == 0) { + rc->def_damage = str_strdup(val); + } + else if (xml_strcmp(key, "unarmedattack") == 0) { + rc->at_default = xml_int(val); + } + else if (xml_strcmp(key, "unarmeddefense") == 0) { + rc->df_default = xml_int(val); + } + else if (xml_strcmp(key, "attackmodifier") == 0) { + rc->at_bonus = xml_int(val); + } + else if (xml_strcmp(key, "defensemodifier") == 0) { + rc->df_bonus = xml_int(val); + } + else if (xml_strcmp(key, "studyspeed") == 0) { + int study_speed = xml_int(val); + if (study_speed != 0) { + skill_t sk; + for (sk = 0; sk < MAXSKILLS; ++sk) { + set_study_speed(rc, sk, study_speed); + } + } + + } + else if (!handle_flag(&rc->flags, attr + i, flag_names)) { + if (!handle_flag(&rc->battle_flags, attr + i, bflag_names)) { + if (!handle_flag(&rc->ec_flags, attr + i, eflag_names)) { + /* we already handled the name earlier: */ + if (xml_strcmp(key, "name") != 0) { + handle_bad_input(pi, el, attr[i]); + } + } + } + } + } + } + } + else { + assert(rc); + handle_bad_input(pi, el, NULL); + } +} + static void XMLCALL start_buildings(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { const char *flag_names[] = { "nodestroy", "nobuild", "unique", "decay", "magic", "namechange", "fort", "oneperturn", NULL }; if (xml_strcmp(el, "building") == 0) { @@ -979,6 +1158,9 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char } else { switch (pi->type) { + case EXP_RACES: + start_races(pi, el, attr); + break; case EXP_BUILDINGS: start_buildings(pi, el, attr); break; @@ -1063,6 +1245,15 @@ static void end_resources(parseinfo *pi, const XML_Char *el) { } } +static void end_races(parseinfo *pi, const XML_Char *el) { + if (xml_strcmp(el, "race") == 0) { + pi->object = NULL; + } + else if (xml_strcmp(el, "races") == 0) { + pi->type = EXP_UNKNOWN; + } +} + static void end_ships(parseinfo *pi, const XML_Char *el) { ship_type *stype = (ship_type *)pi->object; if (xml_strcmp(el, "construction") == 0) { @@ -1135,6 +1326,9 @@ static void XMLCALL handle_end(void *data, const XML_Char *el) { parseinfo *pi = (parseinfo *)data; switch (pi->type) { + case EXP_RACES: + end_races(pi, el); + break; case EXP_SHIPS: end_ships(pi, el); break; diff --git a/src/kernel/race.c b/src/kernel/race.c index ac81f7f78..596f1527f 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -451,6 +451,12 @@ int rc_herb_trade(const struct race *rc) return 500; } +void set_study_speed(race *rc, skill_t sk, int modifier) { + if (!rc->study_speed) + rc->study_speed = calloc(1, MAXSKILLS); + rc->study_speed[sk] = (char)modifier; +} + const race *rc_otherrace(const race *rc) { variant *v = rc_getoption(rc, RCO_OTHER); @@ -466,18 +472,13 @@ void rc_set_param(struct race *rc, const char *key, const char *value) { if (strcmp(key, "recruit_multi") == 0) { rc->recruit_multi = atof(value); } - else if (strcmp(key, "migrants.formula") == 0) { - if (value[0] == '1') { - rc->flags |= RCF_MIGRANTS; - } - } else if (strcmp(key, "other_race")==0) { rc_setoption(rc, RCO_OTHER, value); } - else if (strcmp(key, "ai.scare")==0) { + else if (strcmp(key, "scare")==0) { rc_setoption(rc, RCO_SCARE, value); } - else if (strcmp(key, "hunger.damage")==0) { + else if (strcmp(key, "hunger_damage")==0) { rc_setoption(rc, RCO_HUNGER, value); } else if (strcmp(key, "armor.stamina")==0) { diff --git a/src/kernel/race.h b/src/kernel/race.h index 7c38eec57..51c99e0f0 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -129,7 +129,7 @@ extern "C" { int weight; int capacity; int income; - float speed; + double speed; int hitpoints; char *def_damage; int armor; @@ -229,9 +229,11 @@ extern "C" { #define RCF_CANSAIL (1<<24) /* Einheit darf Schiffe betreten */ #define RCF_INVISIBLE (1<<25) /* not visible in any report */ #define RCF_SHIPSPEED (1<<26) /* race gets +1 on shipspeed */ -#define RCF_MIGRANTS (1<<27) /* may have migrant units (human bonus) */ -#define RCF_FAMILIAR (1<<28) /* may be a familiar */ -#define RCF_ATTACK_MOVED (1<<29) /* may attack if it has moved */ +#define RCF_ATTACK_MOVED (1<<27) /* may attack if it has moved */ +#define RCF_MIGRANTS (1<<28) /* may have migrant units (human bonus) */ +#define RCF_FAMILIAR (1<<29) /* may be a familiar */ + +#define RCF_DEFAULT (RCF_NOSTEAL|RCF_CANSAIL|RCF_NOLEARN) /* Economic flags */ #define ECF_GIVEPERSON (1<<2) /* �bergibt Personen */ @@ -271,6 +273,7 @@ extern "C" { const char *raceprefix(const struct unit *u); void register_race_function(race_func, const char *); + void set_study_speed(struct race *rc, skill_t sk, int modifier); #ifdef __cplusplus } #endif diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index dcbe26e0e..9a118bc74 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -113,9 +113,9 @@ static void test_rc_set_param(CuTest *tc) { rc_set_param(rc, "migrants.formula", "1"); CuAssertIntEquals(tc, RCF_MIGRANTS, rc->flags&RCF_MIGRANTS); CuAssertIntEquals(tc, MIGRANTS_LOG10, rc_migrants_formula(rc)); - rc_set_param(rc, "ai.scare", "400"); + rc_set_param(rc, "scare", "400"); CuAssertIntEquals(tc, 400, rc_scare(rc)); - rc_set_param(rc, "hunger.damage", "1d10+12"); + rc_set_param(rc, "hunger_damage", "1d10+12"); CuAssertStrEquals(tc, "1d10+12", rc_hungerdamage(rc)); test_teardown(); } diff --git a/src/xmlreader.c b/src/xmlreader.c index 3fd6c1b7b..b26bff66c 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -1256,7 +1256,7 @@ static void parse_ai(race * rc, xmlNodePtr node) propValue = xmlGetProp(node, BAD_CAST "scare"); if (propValue) { - rc_set_param(rc, "ai.scare", (const char *)propValue); + rc_set_param(rc, "scare", (const char *)propValue); xmlFree(propValue); } rc->splitsize = xml_ivalue(node, "splitsize", 0); @@ -1270,12 +1270,6 @@ static void parse_ai(race * rc, xmlNodePtr node) rc->flags |= RCF_ATTACK_MOVED; } -static void set_study_speed(race *rc, skill_t sk, int modifier) { - if (!rc->study_speed) - rc->study_speed = calloc(1, MAXSKILLS); - rc->study_speed[sk] = (char)modifier; -} - static int parse_races(xmlDocPtr doc) { xmlXPathContextPtr xpath = xmlXPathNewContext(doc); @@ -1319,7 +1313,7 @@ static int parse_races(xmlDocPtr doc) rc->income = xml_ivalue(node, "income", rc->income); rc->speed = (float)xml_fvalue(node, "speed", rc->speed); rc->hitpoints = xml_ivalue(node, "hp", rc->hitpoints); - rc->armor = (char)xml_ivalue(node, "ac", rc->armor); + rc->armor = xml_ivalue(node, "ac", rc->armor); study_speed_base = xml_ivalue(node, "studyspeed", 0); if (study_speed_base != 0) { for (sk = 0; sk < MAXSKILLS; ++sk) { @@ -1332,14 +1326,18 @@ static int parse_races(xmlDocPtr doc) rc->at_bonus = (char)xml_ivalue(node, "attackmodifier", rc->at_bonus); rc->df_bonus = (char)xml_ivalue(node, "defensemodifier", rc->df_bonus); + if (!xml_bvalue(node, "canteach", true)) + rc->flags |= RCF_NOTEACH; + if (!xml_bvalue(node, "cansteal", true)) + rc->flags |= RCF_NOSTEAL; + if (!xml_bvalue(node, "canlearn", true)) + rc->flags |= RCF_NOLEARN; if (!xml_bvalue(node, "playerrace", false)) { assert(rc->recruitcost == 0); rc->flags |= RCF_NPC; } if (xml_bvalue(node, "scarepeasants", false)) rc->flags |= RCF_SCAREPEASANTS; - if (!xml_bvalue(node, "cansteal", true)) - rc->flags |= RCF_NOSTEAL; if (xml_bvalue(node, "cansail", true)) rc->flags |= RCF_CANSAIL; if (xml_bvalue(node, "cannotmove", false)) @@ -1356,10 +1354,6 @@ static int parse_races(xmlDocPtr doc) rc->flags |= RCF_SWIM; if (xml_bvalue(node, "walk", false)) rc->flags |= RCF_WALK; - if (!xml_bvalue(node, "canlearn", true)) - rc->flags |= RCF_NOLEARN; - if (!xml_bvalue(node, "canteach", true)) - rc->flags |= RCF_NOTEACH; if (xml_bvalue(node, "horse", false)) rc->flags |= RCF_HORSE; if (xml_bvalue(node, "desert", false)) From 48a4de0768df37545e5efc41827fe5797e4cde16 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 10 May 2018 07:01:46 +0200 Subject: [PATCH 43/59] parse race/attack data --- src/exparse.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/exparse.c b/src/exparse.c index 44455888a..e266d55ce 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -877,6 +877,8 @@ static void XMLCALL start_ships(parseinfo *pi, const XML_Char *el, const XML_Cha } } +static int nattacks; + static void XMLCALL start_races(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { race *rc = (race *)pi->object; const char *flag_names[] = { @@ -894,7 +896,33 @@ static void XMLCALL start_races(parseinfo *pi, const XML_Char *el, const XML_Cha "recruitunlimited", "stonegolem", "irongolem", NULL }; if (xml_strcmp(el, "attack") == 0) { + int i; + struct att * at; assert(rc); + at = rc->attack + nattacks; + at->type = AT_NONE; + ++nattacks; + if (nattacks >= RACE_ATTACKS) { + log_fatal("too many attacks for race '%s'\n", rc->_name); + } + for (i = 0; attr[i]; i += 2) { + const XML_Char *key = attr[i], *val = attr[i + 1]; + if (xml_strcmp(key, "type") == 0) { + at->type = xml_int(val); + } + else if (xml_strcmp(key, "flags") == 0) { + at->flags = xml_int(val); + } + else if (xml_strcmp(key, "level") == 0) { + at->level = xml_int(val); + } + else if (xml_strcmp(key, "damage") == 0) { + at->data.dice = str_strdup(val); + } + else if (xml_strcmp(key, "spell") == 0) { + at->data.sp = spellref_create(NULL, val); + } + } } else if (xml_strcmp(el, "familiar") == 0) { assert(rc); @@ -1246,7 +1274,11 @@ static void end_resources(parseinfo *pi, const XML_Char *el) { } static void end_races(parseinfo *pi, const XML_Char *el) { + race *rc = (race *)pi->object; if (xml_strcmp(el, "race") == 0) { + assert(rc); + rc->attack[nattacks].type = AT_NONE; + nattacks = 0; pi->object = NULL; } else if (xml_strcmp(el, "races") == 0) { From 85cf8da383e3c229a39921b9c6292b7d09cf8f93 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 10 May 2018 20:37:37 +0200 Subject: [PATCH 44/59] rename canteach/canlearn to teach/learn race/function is never used (and there is no namedragon function). --- res/e3a/races.xml | 78 ++++++++++++++++---------------- res/eressea/races.xml | 94 +++++++++++++++++++-------------------- res/races/dragon.xml | 3 +- res/races/wyrm.xml | 1 - res/races/youngdragon.xml | 1 - src/exparse.c | 34 +++++++++++++- src/xmlreader.c | 6 +-- 7 files changed, 123 insertions(+), 94 deletions(-) diff --git a/res/e3a/races.xml b/res/e3a/races.xml index 07322d521..2fa889160 100644 --- a/res/e3a/races.xml +++ b/res/e3a/races.xml @@ -8,7 +8,7 @@ - + @@ -192,7 +192,7 @@ - + @@ -218,7 +218,7 @@ - + @@ -239,7 +239,7 @@ - + @@ -260,7 +260,7 @@ - + @@ -283,7 +283,7 @@ - + @@ -306,7 +306,7 @@ - + @@ -328,7 +328,7 @@ - + @@ -354,7 +354,7 @@ - + @@ -376,7 +376,7 @@ - + @@ -400,7 +400,7 @@ - + @@ -425,7 +425,7 @@ - + @@ -448,7 +448,7 @@ - + @@ -471,7 +471,7 @@ - + @@ -493,7 +493,7 @@ - + @@ -520,7 +520,7 @@ - + @@ -543,7 +543,7 @@ - + @@ -565,7 +565,7 @@ - + @@ -589,15 +589,15 @@ - + - + - + @@ -651,34 +651,34 @@ - + - + - + - + - + - + @@ -687,14 +687,14 @@ - + - + @@ -703,14 +703,14 @@ - + @@ -736,7 +736,7 @@ - + @@ -754,7 +754,7 @@ - + @@ -771,7 +771,7 @@ - + @@ -787,7 +787,7 @@ - + @@ -801,7 +801,7 @@ - + @@ -816,7 +816,7 @@ - + @@ -830,12 +830,12 @@ - + - + diff --git a/res/eressea/races.xml b/res/eressea/races.xml index 851d89de6..1acffa872 100644 --- a/res/eressea/races.xml +++ b/res/eressea/races.xml @@ -6,7 +6,7 @@ regaura="0" weight="500" capacity="200" equipment="no" speed="1" hp="1000" ac="4" damage="2d4" unarmedattack="10" unarmeddefense="10" attackmodifier="8" defensemodifier="8" - fly="no" walk="no" canteach="no" getitem="yes"> + fly="no" walk="no" teach="no" getitem="yes"> @@ -26,7 +26,7 @@ - + @@ -59,7 +59,7 @@ - + @@ -87,7 +87,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -143,7 +143,7 @@ - + @@ -172,7 +172,7 @@ - + @@ -202,7 +202,7 @@ - + @@ -236,7 +236,7 @@ - + @@ -266,7 +266,7 @@ - + @@ -298,7 +298,7 @@ - + @@ -328,7 +328,7 @@ - + @@ -357,7 +357,7 @@ - + @@ -387,7 +387,7 @@ - + @@ -416,7 +416,7 @@ - + @@ -447,7 +447,7 @@ - + @@ -478,7 +478,7 @@ - + @@ -507,7 +507,7 @@ - + @@ -539,7 +539,7 @@ - + @@ -569,16 +569,16 @@ - + - + + regaura="1.000000" weight="100" capacity="540" speed="1.000000" hp="20" damage="0d0" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="10" scarepeasants="yes" fly="yes" walk="yes" teach="no" invinciblenonmagic="yes"> @@ -648,34 +648,34 @@ - + - + - + - + - + - + @@ -683,25 +683,25 @@ - + - + - + - + @@ -711,7 +711,7 @@ - + @@ -721,7 +721,7 @@ - + @@ -732,7 +732,7 @@ - + @@ -924,7 +924,7 @@ - + @@ -961,7 +961,7 @@ - + @@ -969,7 +969,7 @@ - + @@ -983,7 +983,7 @@ - + @@ -1000,7 +1000,7 @@ - + @@ -1016,7 +1016,7 @@ - + @@ -1031,7 +1031,7 @@ - + @@ -1044,7 +1044,7 @@ - + @@ -1058,7 +1058,7 @@ - + @@ -1071,11 +1071,11 @@ - + - + @@ -1202,7 +1202,7 @@ - + diff --git a/res/races/dragon.xml b/res/races/dragon.xml index c9692cd9b..7625b914f 100644 --- a/res/races/dragon.xml +++ b/res/races/dragon.xml @@ -3,10 +3,9 @@ - diff --git a/res/races/wyrm.xml b/res/races/wyrm.xml index df2008a80..c69ca2953 100644 --- a/res/races/wyrm.xml +++ b/res/races/wyrm.xml @@ -7,7 +7,6 @@ damage="2d60" unarmedattack="0" unarmeddefense="0" attackmodifier="10" defensemodifier="10" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes" dragon="yes" income="5000"> - diff --git a/res/races/youngdragon.xml b/res/races/youngdragon.xml index d8b3d366f..bbfdb5a9f 100644 --- a/res/races/youngdragon.xml +++ b/res/races/youngdragon.xml @@ -6,7 +6,6 @@ damage="2d15" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="4" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes" dragon="yes" income="150"> - diff --git a/src/exparse.c b/src/exparse.c index e266d55ce..943b80741 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -878,13 +878,14 @@ static void XMLCALL start_ships(parseinfo *pi, const XML_Char *el, const XML_Cha } static int nattacks; +static int nfamiliars; static void XMLCALL start_races(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { race *rc = (race *)pi->object; const char *flag_names[] = { "!playerrace", "killpeasants", "scarepeasants", "!cansteal", "moverandom", "cannotmove", "learn", "fly", "swim", "walk", - "!canlearn", "!canteach", "horse", "desert", "illusionary", + "!learn", "!teach", "horse", "desert", "illusionary", "absorbpeasants", "noheal", "noweapons", "shapeshift", "shapeshiftany", "undead", "dragon", "coastal", "unarmedguard", "cansail", "invisible", "shipspeed", "moveattack", "migrants", NULL }; @@ -922,10 +923,31 @@ static void XMLCALL start_races(parseinfo *pi, const XML_Char *el, const XML_Cha else if (xml_strcmp(key, "spell") == 0) { at->data.sp = spellref_create(NULL, val); } + else { + handle_bad_input(pi, el, key); + } } } else if (xml_strcmp(el, "familiar") == 0) { + race *frc = NULL; + int i; + assert(rc); + for (i = 0; attr[i]; i += 2) { + const XML_Char *key = attr[i], *val = attr[i + 1]; + if (xml_strcmp(key, "race") == 0) { + frc = rc_get_or_create(val); + frc->flags |= RCF_FAMILIAR; + } + else { + handle_bad_input(pi, el, key); + } + } + if (frc) { + if (nfamiliars < MAXMAGIETYP) { + rc->familiars[nfamiliars++] = frc; + } + } } else if (xml_strcmp(el, "skill") == 0) { const XML_Char *name = NULL; @@ -983,6 +1005,9 @@ static void XMLCALL start_races(parseinfo *pi, const XML_Char *el, const XML_Cha else if (xml_strcmp(el, "race") == 0) { const XML_Char *name; + nfamiliars = 0; + nattacks = 0; + name = attr_get(attr, "name"); if (name) { assert(!rc); @@ -1279,6 +1304,13 @@ static void end_races(parseinfo *pi, const XML_Char *el) { assert(rc); rc->attack[nattacks].type = AT_NONE; nattacks = 0; + if (nfamiliars > 0 && nfamiliars < MAXMAGIETYP) { + int i; + for (i = nfamiliars - 1; i != MAXMAGIETYP; ++i) { + rc->familiars[i] = rc->familiars[nfamiliars - 1]; + } + } + nfamiliars = 0; pi->object = NULL; } else if (xml_strcmp(el, "races") == 0) { diff --git a/src/xmlreader.c b/src/xmlreader.c index 53a8c1365..cf63a3ccb 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -1326,11 +1326,11 @@ static int parse_races(xmlDocPtr doc) rc->at_bonus = (char)xml_ivalue(node, "attackmodifier", rc->at_bonus); rc->df_bonus = (char)xml_ivalue(node, "defensemodifier", rc->df_bonus); - if (!xml_bvalue(node, "canteach", true)) + if (!xml_bvalue(node, "teach", true)) rc->flags |= RCF_NOTEACH; if (!xml_bvalue(node, "cansteal", true)) rc->flags |= RCF_NOSTEAL; - if (!xml_bvalue(node, "canlearn", true)) + if (!xml_bvalue(node, "learn", true)) rc->flags |= RCF_NOLEARN; if (!xml_bvalue(node, "playerrace", false)) { assert(rc->recruitcost == 0); @@ -1695,8 +1695,8 @@ void register_xmlreader(void) xml_register_callback(parse_ships); xml_register_callback(parse_spellbooks); xml_register_callback(parse_spells); -#endif xml_register_callback(parse_races); +#endif xml_register_callback(parse_equipment); From 5de2a9e2aef1f5c72dd5ac8ca0f4951ef9ff3769 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 10 May 2018 21:05:51 +0200 Subject: [PATCH 45/59] fix ec_flags parsing (irongolem, etc) --- src/kernel/race.c | 2 +- src/kernel/race.h | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/kernel/race.c b/src/kernel/race.c index fa872778c..e77929fbf 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -310,7 +310,7 @@ static race *rc_find_i(const char *name) for (i = 0; rc_depr[i]; i += 2) { if (strcmp(name, rc_depr[i]) == 0) { rc = rc_find_i(rc_depr[i + 1]); - log_warning("a reference was made to the retired race '%s', returning '%s'.", name, rc->_name); + log_info("a reference was made to the retired race '%s', returning '%s'.", name, rc->_name); break; } } diff --git a/src/kernel/race.h b/src/kernel/race.h index 51c99e0f0..202b84d4b 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -236,13 +236,13 @@ extern "C" { #define RCF_DEFAULT (RCF_NOSTEAL|RCF_CANSAIL|RCF_NOLEARN) /* Economic flags */ -#define ECF_GIVEPERSON (1<<2) /* �bergibt Personen */ -#define ECF_GIVEUNIT (1<<3) /* Einheiten an andere Partei �bergeben */ -#define ECF_GETITEM (1<<4) /* nimmt Gegenst�nde an */ -#define ECF_REC_ETHEREAL (1<<7) /* Rekrutiert aus dem Nichts */ -#define ECF_REC_UNLIMITED (1<<8) /* Rekrutiert ohne Limit */ -#define ECF_STONEGOLEM (1<<9) /* race gets stonegolem properties */ -#define ECF_IRONGOLEM (1<<10) /* race gets irongolem properties */ +#define ECF_GIVEPERSON (1<<0) /* �bergibt Personen */ +#define ECF_GIVEUNIT (1<<1) /* Einheiten an andere Partei �bergeben */ +#define ECF_GETITEM (1<<2) /* nimmt Gegenst�nde an */ +#define ECF_REC_ETHEREAL (1<<3) /* Rekrutiert aus dem Nichts */ +#define ECF_REC_UNLIMITED (1<<4) /* Rekrutiert ohne Limit */ +#define ECF_STONEGOLEM (1<<5) /* race gets stonegolem properties */ +#define ECF_IRONGOLEM (1<<6) /* race gets irongolem properties */ /* Battle-Flags */ #define BF_EQUIPMENT (1<<0) /* Kann Ausr�stung benutzen */ From 9e16ebc01ad199165eeec4a633ae3e69351601c1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 10 May 2018 22:00:23 +0200 Subject: [PATCH 46/59] all kinds of race flag breakage repaired. but now, humans suddenly can't build a ship in E2? --- src/exparse.c | 2 +- src/jsonconf.c | 7 +++---- src/jsonconf.test.c | 6 +++--- src/kernel/race.c | 1 + src/kernel/race.h | 6 +++--- src/monsters.test.c | 14 +++++++++----- src/spy.test.c | 3 +++ src/tests.c | 2 +- src/xmlreader.c | 4 ++-- 9 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 943b80741..b016c89df 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -883,7 +883,7 @@ static int nfamiliars; static void XMLCALL start_races(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { race *rc = (race *)pi->object; const char *flag_names[] = { - "!playerrace", "killpeasants", "scarepeasants", "!cansteal", + "playerrace", "killpeasants", "scarepeasants", "!cansteal", "moverandom", "cannotmove", "learn", "fly", "swim", "walk", "!learn", "!teach", "horse", "desert", "illusionary", "absorbpeasants", "noheal", "noweapons", "shapeshift", diff --git a/src/jsonconf.c b/src/jsonconf.c index 51727fe52..29881d6cf 100644 --- a/src/jsonconf.c +++ b/src/jsonconf.c @@ -480,17 +480,16 @@ static void json_ship(cJSON *json, ship_type *st) { static void json_race(cJSON *json, race *rc) { cJSON *child; const char *flags[] = { - "npc", "killpeasants", "scarepeasants", + "player", "killpeasants", "scarepeasants", "nosteal", "moverandom", "cannotmove", "learn", "fly", "swim", "walk", "nolearn", "noteach", "horse", "desert", "illusionary", "absorbpeasants", "noheal", "noweapons", "shapeshift", "", "undead", "dragon", - "coastal", "", "cansail", 0 + "coastal", "", "cansail", NULL }; const char *ecflags[] = { - "", "keepitem", "giveperson", - "giveunit", "getitem", 0 + "giveperson", "giveunit", "getitem", NULL }; if (json->type != cJSON_Object) { log_error("race %s is not a json object: %d", json->string, json->type); diff --git a/src/jsonconf.test.c b/src/jsonconf.test.c index 482337e40..7c15b63f1 100644 --- a/src/jsonconf.test.c +++ b/src/jsonconf.test.c @@ -56,7 +56,7 @@ static void check_flag(CuTest *tc, const char *name, int flag) { static void test_flags(CuTest *tc) { test_setup(); - check_flag(tc, "npc", RCF_NPC); + check_flag(tc, "player", RCF_PLAYABLE); check_flag(tc, "scarepeasants", RCF_SCAREPEASANTS); check_flag(tc, "nosteal", RCF_NOSTEAL); check_flag(tc, "noheal", RCF_NOHEAL); @@ -181,7 +181,7 @@ static void test_races(CuTest * tc) "\"income\" : 30," "\"hp\" : 5," "\"ac\" : 6," - "\"flags\" : [ \"npc\", \"walk\", \"undead\" ]" + "\"flags\" : [ \"player\", \"walk\", \"undead\" ]" "}}}"; cJSON *json = cJSON_Parse(data); const struct race *rc; @@ -195,7 +195,7 @@ static void test_races(CuTest * tc) CuAssertPtrNotNull(tc, races); rc = rc_find("orc"); CuAssertPtrNotNull(tc, rc); - CuAssertIntEquals(tc, RCF_NPC | RCF_WALK | RCF_UNDEAD, rc->flags); + CuAssertIntEquals(tc, RCF_PLAYABLE | RCF_WALK | RCF_UNDEAD, rc->flags); CuAssertStrEquals(tc, "1d4", rc->def_damage); CuAssertTrue(tc, frac_equal(frac_one, rc->magres)); CuAssertIntEquals(tc, 200, rc->maxaura); diff --git a/src/kernel/race.c b/src/kernel/race.c index e77929fbf..ecdb7ae3d 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -356,6 +356,7 @@ race *rc_create(const char *zName) rc->magres.sa[1] = 1; rc->hitpoints = 1; + rc->flags = RCF_DEFAULT; rc->weight = PERSON_WEIGHT; rc->capacity = 540; rc->income = 20; diff --git a/src/kernel/race.h b/src/kernel/race.h index 202b84d4b..de0fd92e0 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -202,7 +202,7 @@ extern "C" { int rc_get_mask(char *list); /* Flags. Do not reorder these without changing json_race() in jsonconf.c */ -#define RCF_NPC (1<<0) /* cannot be the race for a player faction (and other limits?) */ +#define RCF_PLAYABLE (1<<0) /* cannot be the race for a player faction (and other limits?) */ #define RCF_KILLPEASANTS (1<<1) /* a monster that eats peasants */ #define RCF_SCAREPEASANTS (1<<2) /* a monster that scares peasants out of the hex */ #define RCF_NOSTEAL (1<<3) /* this race has high stealth, but is not allowed to steal */ @@ -233,7 +233,7 @@ extern "C" { #define RCF_MIGRANTS (1<<28) /* may have migrant units (human bonus) */ #define RCF_FAMILIAR (1<<29) /* may be a familiar */ -#define RCF_DEFAULT (RCF_NOSTEAL|RCF_CANSAIL|RCF_NOLEARN) +#define RCF_DEFAULT 0 /* Economic flags */ #define ECF_GIVEPERSON (1<<0) /* �bergibt Personen */ @@ -256,7 +256,7 @@ extern "C" { const char *racename(const struct locale *lang, const struct unit *u, const race * rc); -#define playerrace(rc) (!((rc)->flags & RCF_NPC)) +#define playerrace(rc) ((rc)->flags & RCF_PLAYABLE) #define dragonrace(rc) ((rc)->flags & RCF_DRAGON) #define humanoidrace(rc) (((rc)->flags & RCF_UNDEAD) || (rc)==get_race(RC_DRACOID) || playerrace(rc)) #define illusionaryrace(rc) ((rc)->flags & RCF_ILLUSIONARY) diff --git a/src/monsters.test.c b/src/monsters.test.c index 409b86dfe..8fe9a6b7f 100644 --- a/src/monsters.test.c +++ b/src/monsters.test.c @@ -55,12 +55,16 @@ static void create_monsters(unit **up, unit **um) { test_create_horse(); default_locale = test_create_locale(); fp = test_create_faction(NULL); + fm = get_or_create_monsters(); + fset(fm, FFL_NOIDLEOUT); + assert(fval(fm, FFL_NPC)); + assert(fval(fm, FFL_NOIDLEOUT)); + assert(rc_find(fm->race->_name)); rc = rc_get_or_create(fm->race->_name); - fset(rc, RCF_UNARMEDGUARD|RCF_NPC|RCF_DRAGON); - fset(fm, FFL_NOIDLEOUT); - assert(fval(fm, FFL_NPC) && fval(fm->race, RCF_UNARMEDGUARD) && fval(fm->race, RCF_NPC) && fval(fm, FFL_NOIDLEOUT)); + fset(rc, RCF_UNARMEDGUARD|RCF_DRAGON); + assert(!fval(fm->race, RCF_PLAYABLE)); test_create_region(-1, 0, test_create_terrain("ocean", SEA_REGION | SWIM_INTO | FLY_INTO)); test_create_region(1, 0, 0); @@ -261,12 +265,12 @@ static void test_spawn_seaserpent(CuTest *tc) { race *rc; test_setup(); rc = test_create_race("seaserpent"); - rc->flags |= RCF_NPC; + rc->flags &= ~RCF_PLAYABLE; r = test_create_region(0, 0, NULL); f = test_create_faction(NULL); u = spawn_seaserpent(r, f); CuAssertPtrNotNull(tc, u); - CuAssertPtrEquals(tc, 0, u->_name); + CuAssertPtrEquals(tc, NULL, u->_name); test_teardown(); } diff --git a/src/spy.test.c b/src/spy.test.c index c6a74822c..3c4503c98 100644 --- a/src/spy.test.c +++ b/src/spy.test.c @@ -196,7 +196,10 @@ static void test_setstealth_demon_bad(CuTest *tc) { lang = test_create_locale(); rc = test_create_race("demon"); u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL)); + rc = test_create_race("smurf"); + rc->flags &= ~RCF_PLAYABLE; + init_races(lang); u->thisorder = create_order(K_SETSTEALTH, lang, racename(lang, u, rc)); setstealth_cmd(u, u->thisorder); diff --git a/src/tests.c b/src/tests.c index 696baf447..ad9f8eddf 100644 --- a/src/tests.c +++ b/src/tests.c @@ -43,7 +43,7 @@ struct race *test_create_race(const char *name) rc->maintenance = 10; rc->hitpoints = 20; rc->maxaura = 100; - rc->flags |= RCF_WALK; + rc->flags |= (RCF_WALK|RCF_PLAYABLE); rc->ec_flags |= ECF_GETITEM; rc->battle_flags = BF_EQUIPMENT; return rc; diff --git a/src/xmlreader.c b/src/xmlreader.c index cf63a3ccb..b0a0aafcc 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -1332,9 +1332,9 @@ static int parse_races(xmlDocPtr doc) rc->flags |= RCF_NOSTEAL; if (!xml_bvalue(node, "learn", true)) rc->flags |= RCF_NOLEARN; - if (!xml_bvalue(node, "playerrace", false)) { + if (xml_bvalue(node, "playerrace", false)) { assert(rc->recruitcost == 0); - rc->flags |= RCF_NPC; + rc->flags |= RCF_PLAYABLE; } if (xml_bvalue(node, "scarepeasants", false)) rc->flags |= RCF_SCAREPEASANTS; From 84bc08a38116d650546fdd046948d4ed28773ad7 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 10 May 2018 22:10:26 +0200 Subject: [PATCH 47/59] all races can be on a boat by default. but now MAKETEMP is broken. prefer assert_(not_)nil over assert_(not_)equal --- scripts/tests/common.lua | 32 ++++++++++++++++---------------- scripts/tests/e2/production.lua | 4 ++-- src/kernel/race.h | 2 +- src/kernel/race.test.c | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index b77606266..511f275db 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -155,7 +155,7 @@ end function test_pure() local r = region.create(0, 0, "plain") - assert_not_equal(nil, r) + assert_not_nil(r) assert_equal(r, get_region(0, 0)) end @@ -170,21 +170,21 @@ function test_read_write() assert_equal(r.terrain, "plain") result = eressea.write_game("test.dat") assert_equal(result, 0) - assert_not_equal(get_region(0, 0), nil) - assert_not_equal(get_faction(fno), nil) - assert_not_equal(get_unit(uno), nil) + assert_not_nil(get_region(0, 0)) + assert_not_nil(get_faction(fno)) + assert_not_nil(get_unit(uno)) r = nil f = nil u = nil eressea.free_game() - assert_equal(get_region(0, 0), nil) - assert_equal(nil, get_faction(fno)) - assert_equal(nil, get_unit(uno)) + assert_nil(get_region(0, 0)) + assert_nil(get_faction(fno)) + assert_nil(get_unit(uno)) result = eressea.read_game("test.dat") assert_equal(0, result) - assert_not_equal(nil, get_region(0, 0)) - assert_not_equal(nil, get_faction(fno)) - assert_not_equal(nil, get_unit(uno)) + assert_not_nil(get_region(0, 0)) + assert_not_nil(get_faction(fno)) + assert_not_nil(get_unit(uno)) end function test_descriptions() @@ -238,7 +238,7 @@ function test_gmtool() selections=selections+1 end assert_equal(2, selections) - assert_equal(nil, gmtool.get_cursor()) + assert_nil(gmtool.get_cursor()) gmtool.close() end @@ -568,7 +568,7 @@ function test_coordinate_translation() local pe = plane.create(1, -8761, 3620, 23, 23) -- eternath local r = region.create(1000, 1000, "plain") local f = create_faction('human') - assert_not_equal(nil, r) + assert_not_nil(r) assert_equal(r.x, 1000) assert_equal(r.y, 1000) local nx, ny = plane.normalize(pl, r.x, r.y) @@ -634,8 +634,8 @@ end -- segfault above function test_config() - assert_not_equal(nil, config.basepath) - assert_not_equal(nil, config.locales) + assert_not_nil(config.basepath) + assert_not_nil(config.locales) end local function _test_create_laen() @@ -827,9 +827,9 @@ function test_swim_and_die() process_orders() r.terrain = "ocean" u = get_unit(uid) - assert_not_equal(get_unit(uid), nil) + assert_not_nil(get_unit(uid)) process_orders() - assert_equal(get_unit(uid), nil) + assert_nil(get_unit(uid)) end function test_ride_with_horse() diff --git a/scripts/tests/e2/production.lua b/scripts/tests/e2/production.lua index 5070d02f6..852d8f629 100644 --- a/scripts/tests/e2/production.lua +++ b/scripts/tests/e2/production.lua @@ -101,14 +101,14 @@ function test_build_boat_low_skill() u:add_item("log", 10) u:add_order("MACHE BOOT") process_orders() - assert_not_equal(nil, u.ship) + assert_not_nil(u.ship) assert_equal(4, u.ship.size) assert_equal(6, u:get_item('log')) end function test_build_boat_high_skill() local r = region.create(0, 0, "plain") - local f = faction.create("human", "build@example.com") + local f = faction.create("human", "skillz@example.com") local u = unit.create(f, r, 1) u:set_skill("shipcraft", 5) -- humans get +1 u:add_item("log", 10) diff --git a/src/kernel/race.h b/src/kernel/race.h index de0fd92e0..65cb0cf73 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -233,7 +233,7 @@ extern "C" { #define RCF_MIGRANTS (1<<28) /* may have migrant units (human bonus) */ #define RCF_FAMILIAR (1<<29) /* may be a familiar */ -#define RCF_DEFAULT 0 +#define RCF_DEFAULT RCF_CANSAIL /* Economic flags */ #define ECF_GIVEPERSON (1<<0) /* �bergibt Personen */ diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index e1c255ef2..ac0609a69 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -50,7 +50,7 @@ static void test_rc_defaults(CuTest *tc) { CuAssertDblEquals(tc, 1.0, rc->recruit_multi, 0.0); CuAssertDblEquals(tc, 1.0, rc->regaura, 0.0); CuAssertDblEquals(tc, 1.0, rc->speed, 0.0); - CuAssertIntEquals(tc, 0, rc->flags); + CuAssertIntEquals(tc, RCF_DEFAULT, rc->flags); CuAssertIntEquals(tc, 0, rc->recruitcost); CuAssertIntEquals(tc, 0, rc->maintenance); CuAssertIntEquals(tc, 540, rc->capacity); From 89ecc54bdd809604d3fe98eace262f9daa250460 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 10 May 2018 22:20:28 +0200 Subject: [PATCH 48/59] deal with jsonconf defaults. --- scripts/tests/laws.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/tests/laws.lua b/scripts/tests/laws.lua index 3a724a440..6dc37daf7 100644 --- a/scripts/tests/laws.lua +++ b/scripts/tests/laws.lua @@ -6,7 +6,7 @@ function setup() eressea.free_game() conf = [[{ "races": { - "human" : {} + "human" : { "flags" : [ "player" ] } }, "terrains" : { "plain": { "flags" : [ "land", "walk", "sail" ] } @@ -61,7 +61,7 @@ end function test_make_temp() local r = region.create(0, 0, "plain") - local f1 = faction.create("human", "owner@eressea.de", "de") + local f1 = faction.create("human", "temp@eressea.de", "de") local u1 = unit.create(f1, r, 10) local u, u2 From f8b8a5284c0ccdad4d6ded0f58b599c9702ad3a8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 18 May 2018 18:50:13 +0200 Subject: [PATCH 49/59] begin expat message parsing --- src/exparse.c | 27 +++++++++++++++++++++++---- src/util/message.c | 13 +++++-------- src/util/nrmessage.c | 8 ++++---- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index b016c89df..e323bb74c 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -16,6 +16,7 @@ #include "util/functions.h" #include "util/log.h" +#include "util/message.h" #include "util/strings.h" #include @@ -47,7 +48,6 @@ enum { EXP_SHIPS, EXP_RACES, EXP_MESSAGES, - EXP_STRINGS, EXP_SPELLS, EXP_SPELLBOOKS, }; @@ -285,6 +285,25 @@ static void handle_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **at wtype->flags = flags; } +static void XMLCALL start_messages(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { + if (xml_strcmp(el, "message") == 0) { + const XML_Char *name = NULL, *section = NULL; + int i; + for (i = 0; attr[i]; i += 2) { + const XML_Char *key = attr[i], *val = attr[i + 1]; + if (xml_strcmp(key, "name") == 0) { + name = val; + } + else if (xml_strcmp(key, "section") == 0) { + section = val; + } + } + if (name) { + pi->object = mt_new(name, NULL); + } + } +} + #define MAX_COMPONENTS 8 static spell_component components[MAX_COMPONENTS]; static int ncomponents; @@ -1192,9 +1211,6 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char else if (xml_strcmp(el, "messages") == 0) { pi->type = EXP_MESSAGES; } - else if (xml_strcmp(el, "strings") == 0) { - pi->type = EXP_STRINGS; - } else if (xml_strcmp(el, "spells") == 0) { pi->type = EXP_SPELLS; } @@ -1232,6 +1248,9 @@ static void XMLCALL handle_start(void *data, const XML_Char *el, const XML_Char case EXP_SPELLS: start_spells(pi, el, attr); break; + case EXP_MESSAGES: + start_messages(pi, el, attr); + break; case EXP_UNKNOWN: handle_bad_input(pi, el, NULL); break; diff --git a/src/util/message.c b/src/util/message.c index a919f5f7d..71795cfc7 100644 --- a/src/util/message.c +++ b/src/util/message.c @@ -79,16 +79,9 @@ message_type *mt_new(const char *name, const char *args[]) mtype->name = str_strdup(name); mtype->nparameters = nparameters; if (nparameters > 0) { + int i; mtype->pnames = (char **)malloc(sizeof(char *) * nparameters); mtype->types = (arg_type **)malloc(sizeof(arg_type *) * nparameters); - } - else { - mtype->pnames = NULL; - mtype->types = NULL; - } - if (args != NULL) { - int i; - for (i = 0; args[i]; ++i) { const char *x = args[i]; const char *spos = strchr(x, ':'); @@ -110,6 +103,10 @@ message_type *mt_new(const char *name, const char *args[]) } } } + else { + mtype->pnames = NULL; + mtype->types = NULL; + } return mtype; } diff --git a/src/util/nrmessage.c b/src/util/nrmessage.c index 2df1f4864..9461e11c5 100644 --- a/src/util/nrmessage.c +++ b/src/util/nrmessage.c @@ -27,10 +27,10 @@ #include typedef struct nrmessage_type { - const struct message_type *mtype; - char *vars; - struct nrmessage_type *next; - const char *section; + const struct message_type *mtype; + char *vars; + struct nrmessage_type *next; + const char *section; } nrmessage_type; #define NRT_MAXHASH 1021 From 19b3b5b35a271610f142189cdc7247fc25d38774 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 18 May 2018 19:58:49 +0200 Subject: [PATCH 50/59] change how message types are created (more prep work for expat) --- src/creport.c | 2 +- src/donations.test.c | 2 +- src/economy.test.c | 18 +++---- src/give.test.c | 34 ++++++------ src/kernel/build.test.c | 2 +- src/kernel/messages.c | 6 +-- src/kernel/messages.test.c | 8 +-- src/laws.test.c | 30 +++++------ src/market.test.c | 2 +- src/monsters.test.c | 5 +- src/move.test.c | 18 ++++--- src/orderfile.test.c | 2 +- src/piracy.test.c | 18 ++++--- src/renumber.test.c | 2 +- src/report.c | 15 +++--- src/spells.test.c | 6 ++- src/spells/flyingship.test.c | 3 +- src/spells/magicresistance.test.c | 6 ++- src/spy.test.c | 39 +++++++++----- src/study.test.c | 18 ++++--- src/tests.c | 9 ++-- src/triggers/shock.test.c | 3 +- src/util/message.c | 88 +++++++++++++++---------------- src/util/message.h | 7 +-- src/util/message.test.c | 3 +- src/util/nrmessage.c | 65 +++++++++-------------- src/util/nrmessage.h | 11 ++-- src/volcano.test.c | 12 +++-- src/wormhole.test.c | 12 +++-- src/xmlreader.c | 24 ++++----- 30 files changed, 250 insertions(+), 220 deletions(-) diff --git a/src/creport.c b/src/creport.c index 325d0dec0..17cf60fdb 100644 --- a/src/creport.c +++ b/src/creport.c @@ -519,7 +519,7 @@ static void report_crtypes(FILE * F, const struct locale *lang) fputc('\"', F); fputs(str_escape(nrt_string(kmt->mtype, lang), buffer, sizeof(buffer)), F); fputs("\";text\n", F); - fprintf(F, "\"%s\";section\n", nrt_section(kmt->mtype)); + fprintf(F, "\"%s\";section\n", kmt->mtype->section); } while (mtypehash[i]) { kmt = mtypehash[i]; diff --git a/src/donations.test.c b/src/donations.test.c index a3a428a73..2cdc8f174 100644 --- a/src/donations.test.c +++ b/src/donations.test.c @@ -13,7 +13,7 @@ static void test_add_donation(CuTest *tc) { region *r; test_setup(); - mt_register(mt_new_va("donation", "from:faction", "to:faction", "amount:int", MT_NEW_END)); + mt_create_va(mt_new("donation", NULL), "from:faction", "to:faction", "amount:int", MT_NEW_END); r = test_create_region(0, 0, NULL); f1 = test_create_faction(NULL); f2 = test_create_faction(NULL); diff --git a/src/economy.test.c b/src/economy.test.c index 0ed869ef0..3b5745be4 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -143,10 +143,10 @@ static struct unit *create_recruiter(void) { static void setup_production(void) { init_resources(); - mt_register(mt_new_va("produce", "unit:unit", "region:region", "amount:int", "wanted:int", "resource:resource", MT_NEW_END)); - mt_register(mt_new_va("income", "unit:unit", "region:region", "amount:int", "wanted:int", "mode:int", MT_NEW_END)); - mt_register(mt_new_va("buy", "unit:unit", "money:int", MT_NEW_END)); - mt_register(mt_new_va("buyamount", "unit:unit", "amount:int", "resource:resource", MT_NEW_END)); + mt_create_va(mt_new("produce", NULL), "unit:unit", "region:region", "amount:int", "wanted:int", "resource:resource", MT_NEW_END); + mt_create_va(mt_new("income", NULL), "unit:unit", "region:region", "amount:int", "wanted:int", "mode:int", MT_NEW_END); + mt_create_va(mt_new("buy", NULL), "unit:unit", "money:int", MT_NEW_END); + mt_create_va(mt_new("buyamount", NULL), "unit:unit", "amount:int", "resource:resource", MT_NEW_END); } static void test_heroes_dont_recruit(CuTest * tc) { @@ -378,11 +378,11 @@ static void test_tax_cmd(CuTest *tc) { } static void setup_economy(void) { - mt_register(mt_new_va("recruit", "unit:unit", "region:region", "amount:int", "want:int", MT_NEW_END)); - mt_register(mt_new_va("maintenance", "unit:unit", "building:building", MT_NEW_END)); - mt_register(mt_new_va("maintenancefail", "unit:unit", "building:building", MT_NEW_END)); - mt_register(mt_new_va("maintenance_nowork", "building:building", MT_NEW_END)); - mt_register(mt_new_va("maintenance_noowner", "building:building", MT_NEW_END)); + mt_create_va(mt_new("recruit", NULL), "unit:unit", "region:region", "amount:int", "want:int", MT_NEW_END); + mt_create_va(mt_new("maintenance", NULL), "unit:unit", "building:building", MT_NEW_END); + mt_create_va(mt_new("maintenancefail", NULL), "unit:unit", "building:building", MT_NEW_END); + mt_create_va(mt_new("maintenance_nowork", NULL), "building:building", MT_NEW_END); + mt_create_va(mt_new("maintenance_noowner", NULL), "building:building", MT_NEW_END); } /** diff --git a/src/give.test.c b/src/give.test.c index 3e58216c9..d02c27e6f 100644 --- a/src/give.test.c +++ b/src/give.test.c @@ -54,24 +54,24 @@ static void setup_give(struct give *env) { } /* success messages: */ - mt_register(mt_new_va("receive_person", "unit:unit", "target:unit", "amount:int", MT_NEW_END)); - mt_register(mt_new_va("give_person", "unit:unit", "target:unit", "amount:int", MT_NEW_END)); - mt_register(mt_new_va("give_person_peasants", "unit:unit", "amount:int", MT_NEW_END)); - mt_register(mt_new_va("give_person_ocean", "unit:unit", "amount:int", MT_NEW_END)); - mt_register(mt_new_va("receive", "unit:unit", "target:unit", "resource:resource", "amount:int", MT_NEW_END)); - mt_register(mt_new_va("give", "unit:unit", "target:unit", "resource:resource", "amount:int", MT_NEW_END)); - mt_register(mt_new_va("give_peasants", "unit:unit", "resource:resource", "amount:int", MT_NEW_END)); + mt_create_va(mt_new("receive_person", NULL), "unit:unit", "target:unit", "amount:int", MT_NEW_END); + mt_create_va(mt_new("give_person", NULL), "unit:unit", "target:unit", "amount:int", MT_NEW_END); + mt_create_va(mt_new("give_person_peasants", NULL), "unit:unit", "amount:int", MT_NEW_END); + mt_create_va(mt_new("give_person_ocean", NULL), "unit:unit", "amount:int", MT_NEW_END); + mt_create_va(mt_new("receive", NULL), "unit:unit", "target:unit", "resource:resource", "amount:int", MT_NEW_END); + mt_create_va(mt_new("give", NULL), "unit:unit", "target:unit", "resource:resource", "amount:int", MT_NEW_END); + mt_create_va(mt_new("give_peasants", NULL), "unit:unit", "resource:resource", "amount:int", MT_NEW_END); /* error messages: */ - mt_register(mt_new_va("too_many_units_in_faction", "unit:unit", "region:region", "command:order", "allowed:int", MT_NEW_END)); - mt_register(mt_new_va("too_many_units_in_alliance", "unit:unit", "region:region", "command:order", "allowed:int", MT_NEW_END)); - mt_register(mt_new_va("feedback_no_contact", "unit:unit", "region:region", "command:order", "target:unit", MT_NEW_END)); - mt_register(mt_new_va("feedback_give_forbidden", "unit:unit", "region:region", "command:order", MT_NEW_END)); - mt_register(mt_new_va("peasants_give_invalid", "unit:unit", "region:region", "command:order", MT_NEW_END)); - mt_register(mt_new_va("giverestriction", "unit:unit", "region:region", "command:order", "turns:int", MT_NEW_END)); - mt_register(mt_new_va("error_unit_size", "unit:unit", "region:region", "command:order", "maxsize:int", MT_NEW_END)); - mt_register(mt_new_va("nogive_reserved", "unit:unit", "region:region", "command:order", "resource:resource", "reservation:int", MT_NEW_END)); - mt_register(mt_new_va("race_notake", "unit:unit", "region:region", "command:order", "race:race", MT_NEW_END)); - mt_register(mt_new_va("race_noregroup", "unit:unit", "region:region", "command:order", "race:race", MT_NEW_END)); + mt_create_va(mt_new("too_many_units_in_faction", NULL), "unit:unit", "region:region", "command:order", "allowed:int", MT_NEW_END); + mt_create_va(mt_new("too_many_units_in_alliance", NULL), "unit:unit", "region:region", "command:order", "allowed:int", MT_NEW_END); + mt_create_va(mt_new("feedback_no_contact", NULL), "unit:unit", "region:region", "command:order", "target:unit", MT_NEW_END); + mt_create_va(mt_new("feedback_give_forbidden", NULL), "unit:unit", "region:region", "command:order", MT_NEW_END); + mt_create_va(mt_new("peasants_give_invalid", NULL), "unit:unit", "region:region", "command:order", MT_NEW_END); + mt_create_va(mt_new("giverestriction", NULL), "unit:unit", "region:region", "command:order", "turns:int", MT_NEW_END); + mt_create_va(mt_new("error_unit_size", NULL), "unit:unit", "region:region", "command:order", "maxsize:int", MT_NEW_END); + mt_create_va(mt_new("nogive_reserved", NULL), "unit:unit", "region:region", "command:order", "resource:resource", "reservation:int", MT_NEW_END); + mt_create_va(mt_new("race_notake", NULL), "unit:unit", "region:region", "command:order", "race:race", MT_NEW_END); + mt_create_va(mt_new("race_noregroup", NULL), "unit:unit", "region:region", "command:order", "race:race", MT_NEW_END); } static void test_give_unit(CuTest * tc) { diff --git a/src/kernel/build.test.c b/src/kernel/build.test.c index 1261e5496..9bae742c2 100644 --- a/src/kernel/build.test.c +++ b/src/kernel/build.test.c @@ -253,7 +253,7 @@ static void test_build_destroy_road(CuTest *tc) message *m; test_setup(); - mt_register(mt_new_va("destroy_road", "unit:unit", "from:region", "to:region", MT_NEW_END)); + mt_create_va(mt_new("destroy_road", NULL), "unit:unit", "from:region", "to:region", MT_NEW_END); r2 = test_create_region(1, 0, 0); r = test_create_region(0, 0, NULL); rsetroad(r, D_EAST, 100); diff --git a/src/kernel/messages.c b/src/kernel/messages.c index 9875d303e..e0513b00d 100644 --- a/src/kernel/messages.c +++ b/src/kernel/messages.c @@ -82,8 +82,8 @@ struct message *msg_feedback(const struct unit *u, struct order *ord, if (!mtype) { log_warning("trying to create message of unknown type \"%s\"\n", name); if (!mt_find("missing_feedback")) { - mt_register(mt_new_va("missing_feedback", "unit:unit", - "region:region", "command:order", "name:string", MT_NEW_END)); + mt_create_va(mt_new("missing_feedback", NULL), "unit:unit", + "region:region", "command:order", "name:string", MT_NEW_END); } return msg_message("missing_feedback", "name unit region command", name, u, u->region, ord); @@ -153,7 +153,7 @@ static message *missing_message(const char *name) { log_warning("trying to create undefined message of type \"%s\"\n", name); if (strcmp(name, "missing_message") != 0) { if (!mt_find("missing_message")) { - mt_register(mt_new_va("missing_message", "name:string", MT_NEW_END)); + mt_create_va(mt_new("missing_message", NULL), "name:string", MT_NEW_END); } return msg_message("missing_message", "name", name); } diff --git a/src/kernel/messages.test.c b/src/kernel/messages.test.c index ad6a08071..961d2e63a 100644 --- a/src/kernel/messages.test.c +++ b/src/kernel/messages.test.c @@ -22,10 +22,10 @@ void test_missing_message(CuTest *tc) { void test_message(CuTest *tc) { message *msg; - message_type *mtype = mt_new("custom", NULL); + message_type *mtype; test_setup(); - mt_register(mtype); + mtype = mt_create(mt_new("custom", NULL), NULL); CuAssertPtrEquals(tc, mtype, (void *)mt_find("custom")); CuAssertIntEquals(tc, 0, mtype->nparameters); CuAssertPtrEquals(tc, NULL, (void *)mtype->pnames); @@ -47,11 +47,11 @@ void test_message(CuTest *tc) { static void test_merge_split(CuTest *tc) { message_list *mlist = 0, *append = 0; struct mlist **split; /* TODO: why is this a double asterisk? */ - message_type *mtype = mt_new("custom", NULL); + message_type *mtype; message *msg; test_setup(); - mt_register(mtype); + mtype = mt_create(mt_new("custom", NULL), NULL); add_message(&mlist, msg = msg_message(mtype->name, "")); msg_release(msg); add_message(&append, msg = msg_message(mtype->name, "")); diff --git a/src/laws.test.c b/src/laws.test.c index f9b4cfcf3..8d13b7c81 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -258,7 +258,7 @@ static void test_force_leave_buildings(CuTest *tc) { building * b; test_setup(); - mt_register(mt_new_va("force_leave_building", "unit:unit", "owner:unit", "building:building", MT_NEW_END)); + mt_create_va(mt_new("force_leave_building", NULL), "unit:unit", "owner:unit", "building:building", MT_NEW_END); r = test_create_region(0, 0, test_create_terrain("plain", LAND_REGION)); u1 = test_create_unit(test_create_faction(NULL), r); u2 = test_create_unit(u1->faction, r); @@ -288,7 +288,7 @@ static void test_force_leave_ships(CuTest *tc) { ship *sh; test_setup(); - mt_register(mt_new_va("force_leave_ship", "unit:unit", "owner:unit", "ship:ship", MT_NEW_END)); + mt_create_va(mt_new("force_leave_ship", NULL), "unit:unit", "owner:unit", "ship:ship", MT_NEW_END); r = test_create_region(0, 0, test_create_terrain("plain", LAND_REGION)); u1 = test_create_unit(test_create_faction(NULL), r); u2 = test_create_unit(test_create_faction(NULL), r); @@ -876,7 +876,7 @@ static void test_luck_message(CuTest *tc) { attrib *a; test_setup(); - mt_register(mt_new_va("peasantluck_success", "births:int", MT_NEW_END)); + mt_create_va(mt_new("peasantluck_success", NULL), "births:int", MT_NEW_END); setup_terrains(tc); r = test_create_region(0, 0, NULL); rsetpeasants(r, 1); @@ -901,8 +901,8 @@ static unit * setup_name_cmd(void) { faction *f; test_setup(); - mt_register(mt_new_va("renamed_building_seen", "renamer:unit", "region:region", "building:building", MT_NEW_END)); - mt_register(mt_new_va("renamed_building_notseen", "region:region", "building:building", MT_NEW_END)); + mt_create_va(mt_new("renamed_building_seen", NULL), "renamer:unit", "region:region", "building:building", MT_NEW_END); + mt_create_va(mt_new("renamed_building_notseen", NULL), "region:region", "building:building", MT_NEW_END); f = test_create_faction(NULL); return test_create_unit(f, test_create_region(0, 0, NULL)); } @@ -1301,9 +1301,9 @@ static void test_ally_cmd(CuTest *tc) { static void test_nmr_warnings(CuTest *tc) { faction *f1, *f2; test_setup(); - mt_register(mt_new_va("nmr_warning", MT_NEW_END)); - mt_register(mt_new_va("nmr_warning_final", MT_NEW_END)); - mt_register(mt_new_va("warn_dropout", "faction:faction", "turn:int", MT_NEW_END)); + mt_create_va(mt_new("nmr_warning", NULL), MT_NEW_END); + mt_create_va(mt_new("nmr_warning_final", NULL), MT_NEW_END); + mt_create_va(mt_new("warn_dropout", NULL), "faction:faction", "turn:int", MT_NEW_END); config_set("nmr.timeout", "3"); f1 = test_create_faction(NULL); f2 = test_create_faction(NULL); @@ -1325,9 +1325,9 @@ static unit * setup_mail_cmd(void) { faction *f; test_setup(); - mt_register(mt_new_va("regionmessage", "region:region", "sender:unit", "string:string", MT_NEW_END)); - mt_register(mt_new_va("unitmessage", "region:region", "sender:unit", "string:string", "unit:unit", MT_NEW_END)); - mt_register(mt_new_va("mail_result", "message:string", "unit:unit", MT_NEW_END)); + mt_create_va(mt_new("regionmessage", NULL), "region:region", "sender:unit", "string:string", MT_NEW_END); + mt_create_va(mt_new("unitmessage", NULL), "region:region", "sender:unit", "string:string", "unit:unit", MT_NEW_END); + mt_create_va(mt_new("mail_result", NULL), "message:string", "unit:unit", MT_NEW_END); f = test_create_faction(NULL); return test_create_unit(f, test_create_region(0, 0, NULL)); } @@ -1444,7 +1444,7 @@ static void test_show_without_item(CuTest *tc) struct locale *loc; test_setup(); - mt_register(mt_new_va("displayitem", "weight:int", "item:resource", "description:string", MT_NEW_END)); + mt_create_va(mt_new("displayitem", NULL), "weight:int", "item:resource", "description:string", MT_NEW_END); loc = get_or_create_locale("de"); locale_setstring(loc, parameters[P_ANY], "ALLE"); @@ -1489,7 +1489,7 @@ static void test_show_race(CuTest *tc) { test_setup(); - mt_register(mt_new_va("msg_event", "string:string", MT_NEW_END)); + mt_create_va(mt_new("msg_event", NULL), "string:string", MT_NEW_END); test_create_race("human"); rc = test_create_race("elf"); @@ -1529,8 +1529,8 @@ static void test_show_both(CuTest *tc) { message * msg; test_setup(); - mt_register(mt_new_va("msg_event", "string:string", MT_NEW_END)); - mt_register(mt_new_va("displayitem", "weight:int", "item:resource", "description:string", MT_NEW_END)); + mt_create_va(mt_new("msg_event", NULL), "string:string", MT_NEW_END); + mt_create_va(mt_new("displayitem", NULL), "weight:int", "item:resource", "description:string", MT_NEW_END); rc = test_create_race("elf"); test_create_itemtype("elvenhorse"); diff --git a/src/market.test.c b/src/market.test.c index 452f75091..4877dbf29 100644 --- a/src/market.test.c +++ b/src/market.test.c @@ -33,7 +33,7 @@ static void test_market_curse(CuTest * tc) building_type *btype; test_setup(); - mt_register(mt_new_va("buyamount", "unit:unit", "amount:int", "resource:resource", MT_NEW_END)); + mt_create_va(mt_new("buyamount", NULL), "unit:unit", "amount:int", "resource:resource", MT_NEW_END); htype = test_create_itemtype("herb"); htype->flags |= ITF_HERB; diff --git a/src/monsters.test.c b/src/monsters.test.c index 8fe9a6b7f..54b3f7f87 100644 --- a/src/monsters.test.c +++ b/src/monsters.test.c @@ -51,7 +51,8 @@ static void create_monsters(unit **up, unit **um) { region *r; faction *fp, *fm; - mt_register(mt_new_va("dragon_growl", "dragon:unit", "number:int", "target:region", "growl:string", MT_NEW_END)); + mt_create_va(mt_new("dragon_growl", NULL), + "dragon:unit", "number:int", "target:region", "growl:string", MT_NEW_END); test_create_horse(); default_locale = test_create_locale(); fp = test_create_faction(NULL); @@ -223,8 +224,6 @@ static void test_dragon_moves(CuTest * tc) plan_monsters(m->faction); CuAssertPtrNotNull(tc, find_order("move east", m)); - mt_register(mt_new_va("dragon_growl", "dragon:unit", "number:int", "target:region", "growl:string", MT_NEW_END)); - random_growl(m, findregion(1, 0), 3); msg = test_get_last_message(r->msgs); diff --git a/src/move.test.c b/src/move.test.c index 07fde591c..a2fa4e760 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -28,8 +28,10 @@ #include static void setup_move(void) { - mt_register(mt_new_va("travel", "unit:unit", "start:region", "end:region", "mode:int", "regions:regions", MT_NEW_END)); - mt_register(mt_new_va("moveblocked", "unit:unit", "direction:int", MT_NEW_END)); + mt_create_va(mt_new("travel", NULL), + "unit:unit", "start:region", "end:region", "mode:int", "regions:regions", MT_NEW_END); + mt_create_va(mt_new("moveblocked", NULL), + "unit:unit", "direction:int", MT_NEW_END); } static void test_ship_not_allowed_in_coast(CuTest * tc) @@ -285,9 +287,12 @@ void setup_drift (struct drift_fixture *fix) { u_set_ship(fix->u, fix->sh = test_create_ship(fix->u->region, fix->st_boat)); assert(fix->sh); - mt_register(mt_new_va("ship_drift", "ship:ship", "dir:int", MT_NEW_END)); - mt_register(mt_new_va("shipsink", "ship:ship", MT_NEW_END)); - mt_register(mt_new_va("massive_overload", "ship:ship", MT_NEW_END)); + mt_create_va(mt_new("ship_drift", NULL), + "ship:ship", "dir:int", MT_NEW_END); + mt_create_va(mt_new("shipsink", NULL), + "ship:ship", MT_NEW_END); + mt_create_va(mt_new("massive_overload", NULL), + "ship:ship", MT_NEW_END); } static void test_ship_no_overload(CuTest *tc) { @@ -482,7 +487,8 @@ static void test_follow_ship_msg(CuTest * tc) { td->dir = D_NORTHWEST; td->age = 2; - mt_register(mt_new_va("error18", "unit:unit", "region:region", "command:order", MT_NEW_END)); + mt_create_va(mt_new("error18", NULL), + "unit:unit", "region:region", "command:order", MT_NEW_END); init_order_depr(ord); getstrtoken(); diff --git a/src/orderfile.test.c b/src/orderfile.test.c index 11eb9ea7b..ca98fdeb0 100644 --- a/src/orderfile.test.c +++ b/src/orderfile.test.c @@ -64,7 +64,7 @@ static void test_faction_password_bad(CuTest *tc) { const char *orders[] = { "ERESSEA 1 password", NULL }; test_setup(); - mt_register(mt_new_va("wrongpasswd", "password:string", MT_NEW_END)); + mt_create_va(mt_new("wrongpasswd", NULL), "password:string", MT_NEW_END); f = test_create_faction(NULL); renumber_faction(f, 1); diff --git a/src/piracy.test.c b/src/piracy.test.c index 110dc3dcf..096e267b7 100644 --- a/src/piracy.test.c +++ b/src/piracy.test.c @@ -30,12 +30,18 @@ static void setup_piracy(void) { st_boat = test_create_shiptype("boat"); st_boat->cargo = 1000; - mt_register(mt_new_va("piratenovictim", "ship:ship", "unit:unit", "region:region", MT_NEW_END)); - mt_register(mt_new_va("piratesawvictim", "ship:ship", "unit:unit", "region:region", "dir:int", MT_NEW_END)); - mt_register(mt_new_va("shipsail", "ship:ship", "from:region", "to:region", MT_NEW_END)); - mt_register(mt_new_va("shipfly", "ship:ship", "from:region", "to:region", MT_NEW_END)); - mt_register(mt_new_va("shipnoshore", "ship:ship", "region:region", MT_NEW_END)); - mt_register(mt_new_va("travel", "unit:unit", "start:region", "end:region", "mode:int", "regions:regions", MT_NEW_END)); + mt_create_va(mt_new("piratenovictim", NULL), + "ship:ship", "unit:unit", "region:region", MT_NEW_END); + mt_create_va(mt_new("piratesawvictim", NULL), + "ship:ship", "unit:unit", "region:region", "dir:int", MT_NEW_END); + mt_create_va(mt_new("shipsail", NULL), + "ship:ship", "from:region", "to:region", MT_NEW_END); + mt_create_va(mt_new("shipfly", NULL), + "ship:ship", "from:region", "to:region", MT_NEW_END); + mt_create_va(mt_new("shipnoshore", NULL), + "ship:ship", "region:region", MT_NEW_END); + mt_create_va(mt_new("travel", NULL), + "unit:unit", "start:region", "end:region", "mode:int", "regions:regions", MT_NEW_END); } static void setup_pirate(unit **pirate, int p_r_flags, int p_rc_flags, const char *p_shiptype, diff --git a/src/renumber.test.c b/src/renumber.test.c index f176cc3d2..98ca9b48b 100644 --- a/src/renumber.test.c +++ b/src/renumber.test.c @@ -38,7 +38,7 @@ static void test_renumber_faction_duplicate(CuTest *tc) { const struct locale *lang; test_setup_ex(tc); - mt_register(mt_new_va("renumber_inuse", "id:int", MT_NEW_END)); + mt_create_va(mt_new("renumber_inuse", NULL), "id:int", MT_NEW_END); f2 = test_create_faction(NULL); u = test_create_unit(f = test_create_faction(NULL), test_create_region(0, 0, NULL)); no = f->no; diff --git a/src/report.c b/src/report.c index 00089421a..4aee1eb2c 100644 --- a/src/report.c +++ b/src/report.c @@ -714,16 +714,17 @@ static void rp_messages(struct stream *out, message_list * msgs, faction * viewer, int indent, bool categorized) { - nrsection *section; - - if (!msgs) + int i; + if (!msgs) { return; - for (section = sections; section; section = section->next) { + } + for (i = 0; i != MAXSECTIONS && sections[i]; ++i) { + const char * section = sections[i]; int k = 0; struct mlist *m = msgs->begin; while (m) { /* messagetype * mt = m->type; */ - if (!categorized || strcmp(nrt_section(m->msg->type), section->name) == 0) { + if (!categorized || strcmp(m->msg->type->section, section) == 0) { char lbuf[8192]; if (!k && categorized) { @@ -731,14 +732,14 @@ rp_messages(struct stream *out, message_list * msgs, faction * viewer, int inden char cat_identifier[24]; newline(out); - sprintf(cat_identifier, "section_%s", section->name); + sprintf(cat_identifier, "section_%s", section); section_title = LOC(viewer->locale, cat_identifier); if (section_title) { centre(out, section_title, true); newline(out); } else { - log_error("no title defined for section %s in locale %s", section->name, locale_name(viewer->locale)); + log_error("no title defined for section %s in locale %s", section, locale_name(viewer->locale)); } k = 1; } diff --git a/src/spells.test.c b/src/spells.test.c index dc0644ecc..e6150cb46 100644 --- a/src/spells.test.c +++ b/src/spells.test.c @@ -130,8 +130,10 @@ static void test_view_reality(CuTest *tc) { test_setup(); setup_spells(); - mt_register(mt_new_va("spell_astral_only", "unit:unit", "region:region", "command:order", MT_NEW_END)); - mt_register(mt_new_va("viewreality_effect", "unit:unit", MT_NEW_END)); + mt_create_va(mt_new("spell_astral_only", NULL), + "unit:unit", "region:region", "command:order", MT_NEW_END); + mt_create_va(mt_new("viewreality_effect", NULL), + "unit:unit", MT_NEW_END); r = test_create_region(0, 0, NULL); ra = test_create_region(real2tp(r->x), real2tp(r->y), NULL); ra->_plane = get_astralplane(); diff --git a/src/spells/flyingship.test.c b/src/spells/flyingship.test.c index 4440c5fdf..1b1c4d7a1 100644 --- a/src/spells/flyingship.test.c +++ b/src/spells/flyingship.test.c @@ -29,7 +29,8 @@ static void test_flyingship(CuTest * tc) ship *sh1, *sh2; test_setup(); - mt_register(mt_new_va("flying_ship_result", "mage:unit", "ship:ship", MT_NEW_END)); + mt_create_va(mt_new("flying_ship_result", NULL), + "mage:unit", "ship:ship", MT_NEW_END); par.param = &par_data_ptr; par_data.typ = SPP_SHIP; diff --git a/src/spells/magicresistance.test.c b/src/spells/magicresistance.test.c index 86a66bc0e..cbfdeb4af 100644 --- a/src/spells/magicresistance.test.c +++ b/src/spells/magicresistance.test.c @@ -29,7 +29,8 @@ static void test_magicresistance_unit(CuTest *tc) { curse *c; test_setup(); - mt_register(mt_new_va("magicresistance_unit", "unit:unit", "id:int", MT_NEW_END)); + mt_create_va(mt_new("magicresistance_unit", NULL), + "unit:unit", "id:int", MT_NEW_END); r = test_create_plain(0, 0); f1 = test_create_faction(NULL); u1 = test_create_unit(f1, r); @@ -57,7 +58,8 @@ static void test_magicresistance_building(CuTest *tc) { curse *c; test_setup(); - mt_register(mt_new_va("magicresistance_building", "building:building", "id:int", MT_NEW_END)); + mt_create_va(mt_new("magicresistance_building", NULL), + "building:building", "id:int", MT_NEW_END); r = test_create_plain(0, 0); f1 = test_create_faction(NULL); u1 = test_create_unit(f1, r); diff --git a/src/spy.test.c b/src/spy.test.c index 3c4503c98..ed10c4b7e 100644 --- a/src/spy.test.c +++ b/src/spy.test.c @@ -33,19 +33,32 @@ typedef struct { } spy_fixture; static void setup_spy(spy_fixture *fix) { - mt_register(mt_new_va("spyreport", "spy:unit", "target:unit", "status:int", MT_NEW_END)); - mt_register(mt_new_va("spyreport_mage", "spy:unit", "target:unit", "type:int", MT_NEW_END)); - mt_register(mt_new_va("spyreport_faction", "spy:unit", "target:unit", "faction:faction", MT_NEW_END)); - mt_register(mt_new_va("spyreport_skills", "spy:unit", "target:unit", "skills:string", MT_NEW_END)); - mt_register(mt_new_va("spyreport_items", "spy:unit", "target:unit", "items:items", MT_NEW_END)); - mt_register(mt_new_va("destroy_ship_0", "unit:unit", "ship:ship", MT_NEW_END)); - mt_register(mt_new_va("destroy_ship_1", "unit:unit", "ship:ship", MT_NEW_END)); - mt_register(mt_new_va("destroy_ship_2", "unit:unit", "ship:ship", MT_NEW_END)); - mt_register(mt_new_va("destroy_ship_3", "ship:ship", MT_NEW_END)); - mt_register(mt_new_va("destroy_ship_4", "ship:ship", MT_NEW_END)); - mt_register(mt_new_va("sink_msg", "ship:ship", "region:region", MT_NEW_END)); - mt_register(mt_new_va("sink_lost_msg", "unit:unit", "region:region", "dead:int", MT_NEW_END)); - mt_register(mt_new_va("sink_saved_msg", "unit:unit", "region:region", MT_NEW_END)); + mt_create_va(mt_new("spyreport", NULL), + "spy:unit", "target:unit", "status:int", MT_NEW_END); + mt_create_va(mt_new("spyreport_mage", NULL), + "spy:unit", "target:unit", "type:int", MT_NEW_END); + mt_create_va(mt_new("spyreport_faction", NULL), + "spy:unit", "target:unit", "faction:faction", MT_NEW_END); + mt_create_va(mt_new("spyreport_skills", NULL), + "spy:unit", "target:unit", "skills:string", MT_NEW_END); + mt_create_va(mt_new("spyreport_items", NULL), + "spy:unit", "target:unit", "items:items", MT_NEW_END); + mt_create_va(mt_new("destroy_ship_0", NULL), + "unit:unit", "ship:ship", MT_NEW_END); + mt_create_va(mt_new("destroy_ship_1", NULL), + "unit:unit", "ship:ship", MT_NEW_END); + mt_create_va(mt_new("destroy_ship_2", NULL), + "unit:unit", "ship:ship", MT_NEW_END); + mt_create_va(mt_new("destroy_ship_3", NULL), + "ship:ship", MT_NEW_END); + mt_create_va(mt_new("destroy_ship_4", NULL), + "ship:ship", MT_NEW_END); + mt_create_va(mt_new("sink_msg", NULL), + "ship:ship", "region:region", MT_NEW_END); + mt_create_va(mt_new("sink_lost_msg", NULL), + "unit:unit", "region:region", "dead:int", MT_NEW_END); + mt_create_va(mt_new("sink_saved_msg", NULL), + "unit:unit", "region:region", MT_NEW_END); if (fix) { fix->r = test_create_region(0, 0, NULL); diff --git a/src/study.test.c b/src/study.test.c index 46722c0f6..c1d0b0841 100644 --- a/src/study.test.c +++ b/src/study.test.c @@ -58,9 +58,12 @@ typedef struct { } study_fixture; static void setup_study(void) { - mt_register(mt_new_va("studycost", "unit:unit", "region:region", "cost:int", "skill:int", MT_NEW_END)); - mt_register(mt_new_va("teach_teacher", "teacher:unit", "student:unit", "skill:int", "level:int", MT_NEW_END)); - mt_register(mt_new_va("teach_student", "teacher:unit", "student:unit", "skill:int", MT_NEW_END)); + mt_create_va(mt_new("studycost", NULL), + "unit:unit", "region:region", "cost:int", "skill:int", MT_NEW_END); + mt_create_va(mt_new("teach_teacher", NULL), + "teacher:unit", "student:unit", "skill:int", "level:int", MT_NEW_END); + mt_create_va(mt_new("teach_student", NULL), + "teacher:unit", "student:unit", "skill:int", MT_NEW_END); } static void setup_locale(struct locale *lang) { @@ -218,7 +221,8 @@ static void test_academy_building(CuTest *tc) { message * msg; test_setup(); - mt_register(mt_new_va("teach_asgood", "unit:unit", "region:region", "command:order", "student:unit", MT_NEW_END)); + mt_create_va(mt_new("teach_asgood", NULL), + "unit:unit", "region:region", "command:order", "student:unit", MT_NEW_END); random_source_inject_constant(0.0); init_resources(); @@ -636,8 +640,10 @@ static void test_teach_message(CuTest *tc) { teaching_info *teach; test_setup(); - mt_register(mt_new_va("teach_teacher", "teacher:unit", "student:unit", "skill:int", "level:int", MT_NEW_END)); - mt_register(mt_new_va("teach_student", "teacher:unit", "student:unit", "skill:int", MT_NEW_END)); + mt_create_va(mt_new("teach_teacher", NULL), + "teacher:unit", "student:unit", "skill:int", "level:int", MT_NEW_END); + mt_create_va(mt_new("teach_student", NULL), + "teacher:unit", "student:unit", "skill:int", MT_NEW_END); init_resources(); u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); scale_number(u, 20); diff --git a/src/tests.c b/src/tests.c index 306148af2..09f533a9f 100644 --- a/src/tests.c +++ b/src/tests.c @@ -246,9 +246,12 @@ static void test_reset(void) { } random_source_reset(); - mt_register(mt_new_va("changepasswd", "value:string", MT_NEW_END)); - mt_register(mt_new_va("starvation", "unit:unit", "region:region", "dead:int", "live:int", MT_NEW_END)); - mt_register(mt_new_va("malnourish", "unit:unit", "region:region", MT_NEW_END)); + mt_create_va(mt_new("changepasswd", NULL), + "value:string", MT_NEW_END); + mt_create_va(mt_new("starvation", NULL), + "unit:unit", "region:region", "dead:int", "live:int", MT_NEW_END); + mt_create_va(mt_new("malnourish", NULL), + "unit:unit", "region:region", MT_NEW_END); if (errno) { int error = errno; diff --git a/src/triggers/shock.test.c b/src/triggers/shock.test.c index dad675e64..43b8d394b 100644 --- a/src/triggers/shock.test.c +++ b/src/triggers/shock.test.c @@ -12,7 +12,8 @@ #include static void shock_setup(void) { - mt_register(mt_new_va("shock", "mage:unit", "reason:string", MT_NEW_END)); + mt_create_va(mt_new("shock", NULL), + "mage:unit", "reason:string", MT_NEW_END); } static void test_shock(CuTest *tc) { diff --git a/src/util/message.c b/src/util/message.c index 71795cfc7..0f8b7cc36 100644 --- a/src/util/message.c +++ b/src/util/message.c @@ -60,26 +60,34 @@ arg_type *find_argtype(const char *name) return NULL; } -message_type *mt_new(const char *name, const char *args[]) +static unsigned int mt_id(const message_type * mtype) +{ + unsigned int key = 0; + size_t i = strlen(mtype->name); + + while (i > 0) { + /* TODO: why not use str_hash? */ + key = (mtype->name[--i] + key * 37); + } + return key % 0x7FFFFFFF; +} + +#define MT_MAXHASH 1021 +static selist *messagetypes[MT_MAXHASH]; + +message_type *mt_create(message_type * mtype, const char *args[]) { int nparameters = 0; - message_type *mtype; + unsigned int hash = str_hash(mtype->name) % MT_MAXHASH; + selist **qlp = messagetypes + hash; - assert(name != NULL); - if (name == NULL) { - log_error("Trying to create message_type with name=0x0\n"); - return NULL; - } if (args != NULL) { /* count the number of parameters */ while (args[nparameters]) ++nparameters; } - mtype = (message_type *)malloc(sizeof(message_type)); - mtype->key = 0; - mtype->name = str_strdup(name); - mtype->nparameters = nparameters; if (nparameters > 0) { int i; + mtype->nparameters = nparameters; mtype->pnames = (char **)malloc(sizeof(char *) * nparameters); mtype->types = (arg_type **)malloc(sizeof(arg_type *) * nparameters); for (i = 0; args[i]; ++i) { @@ -103,20 +111,38 @@ message_type *mt_new(const char *name, const char *args[]) } } } - else { - mtype->pnames = NULL; - mtype->types = NULL; + if (selist_set_insert(qlp, mtype, NULL)) { + mtype->key = mt_id(mtype); } return mtype; } -message_type *mt_new_va(const char *name, ...) +message_type *mt_new(const char *name, const char *section) +{ + message_type *mtype; + + assert(name != NULL); + if (name == NULL) { + log_error("Trying to create message_type with name=0x0\n"); + return NULL; + } + mtype = (message_type *)malloc(sizeof(message_type)); + mtype->key = 0; + mtype->name = str_strdup(name); + mtype->section = section; + mtype->nparameters = 0; + mtype->pnames = NULL; + mtype->types = NULL; + return mtype; +} + +message_type *mt_create_va(message_type *mtype, ...) { const char *args[16]; int i = 0; va_list marker; - va_start(marker, name); + va_start(marker, mtype); for (;;) { const char *c = va_arg(marker, const char *); args[i++] = c; @@ -124,8 +150,8 @@ message_type *mt_new_va(const char *name, ...) break; } va_end(marker); - args[i] = 0; - return mt_new(name, args); + args[i] = NULL; + return mt_create(mtype, args); } static variant copy_arg(const arg_type * atype, variant data) @@ -165,9 +191,6 @@ message *msg_create(const struct message_type *mtype, variant args[]) return msg; } -#define MT_MAXHASH 1021 -static selist *messagetypes[MT_MAXHASH]; - static void mt_free(void *val) { message_type *mtype = (message_type *)val; int i; @@ -205,29 +228,6 @@ const message_type *mt_find(const char *name) return 0; } -static unsigned int mt_id(const message_type * mtype) -{ - unsigned int key = 0; - size_t i = strlen(mtype->name); - - while (i > 0) { - /* TODO: why not use str_hash? */ - key = (mtype->name[--i] + key * 37); - } - return key % 0x7FFFFFFF; -} - -const message_type *mt_register(message_type * type) -{ - unsigned int hash = str_hash(type->name) % MT_MAXHASH; - selist **qlp = messagetypes + hash; - - if (selist_set_insert(qlp, type, NULL)) { - type->key = mt_id(type); - } - return type; -} - void msg_free(message * msg) { int i; diff --git a/src/util/message.h b/src/util/message.h index 7521b8e24..41d58b448 100644 --- a/src/util/message.h +++ b/src/util/message.h @@ -29,6 +29,7 @@ extern "C" { typedef struct message_type { unsigned int key; char *name; + const char *section; int nparameters; char **pnames; struct arg_type ** types; @@ -43,8 +44,6 @@ extern "C" { void message_done(void); void mt_clear(void); - struct message_type *mt_new(const char *name, const char *args[]); - struct message_type *mt_new_va(const char *name, ...); #define MT_NEW_END ((const char *)0) /* mt_new("simple_sentence", "subject:string", "predicate:string", * "object:string", "lang:locale", MT_NEW_END); */ @@ -59,8 +58,10 @@ extern "C" { const char *mt_name(const struct message_type *mtype); + struct message_type *mt_new(const char *name, const char *section); /** message_type registry (optional): **/ - const struct message_type *mt_register(struct message_type *); + struct message_type *mt_create(struct message_type *, const char *args[]); + struct message_type *mt_create_va(struct message_type *, ...); const struct message_type *mt_find(const char *); void register_argtype(const char *name, void(*free_arg) (variant), diff --git a/src/util/message.test.c b/src/util/message.test.c index 4b00b4006..df8c75126 100644 --- a/src/util/message.test.c +++ b/src/util/message.test.c @@ -8,8 +8,7 @@ static void test_mt_new(CuTest *tc) { message_type *mt; test_setup(); - mt = mt_new_va("test", "name:string", "number:int", MT_NEW_END); - mt_register(mt); + mt = mt_create_va(mt_new("test", NULL), "name:string", "number:int", MT_NEW_END); CuAssertPtrNotNull(tc, mt); CuAssertStrEquals(tc, "test", mt->name); CuAssertIntEquals(tc, 2, mt->nparameters); diff --git a/src/util/nrmessage.c b/src/util/nrmessage.c index 9461e11c5..047d3565b 100644 --- a/src/util/nrmessage.c +++ b/src/util/nrmessage.c @@ -30,7 +30,6 @@ typedef struct nrmessage_type { const struct message_type *mtype; char *vars; struct nrmessage_type *next; - const char *section; } nrmessage_type; #define NRT_MAXHASH 1021 @@ -66,41 +65,44 @@ static nrmessage_type *nrt_find(const struct message_type * mtype) return found; } -nrsection *sections; +char *sections[MAXSECTIONS]; -const nrsection *section_find(const char *name) +const char *section_find(const char *name) { - nrsection **mcp = §ions; - if (name == NULL) + int i; + + if (name == NULL) { return NULL; - for (; *mcp; mcp = &(*mcp)->next) { - nrsection *mc = *mcp; - if (!strcmp(mc->name, name)) - break; } - return *mcp; + + for (i = 0; i != MAXSECTIONS && sections[i]; ++i) { + if (strcmp(sections[i], name) == 0) { + return sections[i]; + } + } + return NULL; } -const nrsection *section_add(const char *name) -{ - nrsection **mcp = §ions; - if (name == NULL) +const char *section_add(const char *name) { + int i; + if (name == NULL) { return NULL; - for (; *mcp; mcp = &(*mcp)->next) { - nrsection *mc = *mcp; - if (!strcmp(mc->name, name)) - break; } - if (!*mcp) { - nrsection *mc = calloc(sizeof(nrsection), 1); - mc->name = str_strdup(name); - *mcp = mc; + for (i = 0; i != MAXSECTIONS && sections[i]; ++i) { + if (strcmp(sections[i], name) == 0) { + return sections[i]; + } } - return *mcp; + assert(i < MAXSECTIONS); + assert(sections[i] == NULL); + if (i + 1 < MAXSECTIONS) { + sections[i + 1] = NULL; + } + return sections[i] = str_strdup(name); } void -nrt_register(const struct message_type *mtype, const char *section) +nrt_register(const struct message_type *mtype) { unsigned int hash = mtype->key % NRT_MAXHASH; nrmessage_type *nrt = nrtypes[hash]; @@ -118,15 +120,6 @@ nrt_register(const struct message_type *mtype, const char *section) nrt = malloc(sizeof(nrmessage_type)); nrt->mtype = mtype; nrt->next = nrtypes[hash]; - if (section) { - const nrsection *s = section_find(section); - if (s == NULL) { - s = section_add(section); - } - nrt->section = s->name; - } - else - nrt->section = NULL; nrtypes[hash] = nrt; *c = '\0'; for (i = 0; i != mtype->nparameters; ++i) { @@ -159,12 +152,6 @@ size_t size, const void *userdata) return 0; } -const char *nrt_section(const struct message_type * mtype) -{ - nrmessage_type *nrt = nrt_find(mtype); - return nrt ? nrt->section : NULL; -} - void free_nrmesssages(void) { int i; for (i = 0; i != NRT_MAXHASH; ++i) { diff --git a/src/util/nrmessage.h b/src/util/nrmessage.h index 357e5d5c5..c0d9257aa 100644 --- a/src/util/nrmessage.h +++ b/src/util/nrmessage.h @@ -25,19 +25,14 @@ extern "C" { struct message_type; struct nrmessage_type; - typedef struct nrsection { - char *name; - struct nrsection *next; - } nrsection; - - extern nrsection *sections; +#define MAXSECTIONS 8 + extern char *sections[MAXSECTIONS]; void free_nrmesssages(void); - void nrt_register(const struct message_type *mtype, const char *section); + void nrt_register(const struct message_type *mtype); const char *nrt_string(const struct message_type *mtype, const struct locale *lang); - const char *nrt_section(const struct message_type *mtype); size_t nr_render(const struct message *msg, const struct locale *lang, char *buffer, size_t size, const void *userdata); diff --git a/src/volcano.test.c b/src/volcano.test.c index 8a8358c1c..c62febc0d 100644 --- a/src/volcano.test.c +++ b/src/volcano.test.c @@ -20,7 +20,8 @@ static void test_volcano_update(CuTest *tc) { const struct terrain_type *t_volcano, *t_active; test_setup(); - mt_register(mt_new_va("volcanostopsmoke", "region:region", MT_NEW_END)); + mt_create_va(mt_new("volcanostopsmoke", NULL), + "region:region", MT_NEW_END); t_volcano = test_create_terrain("volcano", LAND_REGION); t_active = test_create_terrain("activevolcano", LAND_REGION); r = test_create_region(0, 0, t_active); @@ -42,9 +43,12 @@ static void test_volcano_outbreak(CuTest *tc) { const struct terrain_type *t_volcano, *t_active; test_setup(); - mt_register(mt_new_va("volcanooutbreak", "regionv:region", "regionn:region", MT_NEW_END)); - mt_register(mt_new_va("volcanooutbreaknn", "region:region", MT_NEW_END)); - mt_register(mt_new_va("volcano_dead", "unit:unit", "region:region", "dead:int", MT_NEW_END)); + mt_create_va(mt_new("volcanooutbreak", NULL), + "regionv:region", "regionn:region", MT_NEW_END); + mt_create_va(mt_new("volcanooutbreaknn", NULL), + "region:region", MT_NEW_END); + mt_create_va(mt_new("volcano_dead", NULL), + "unit:unit", "region:region", "dead:int", MT_NEW_END); t_volcano = test_create_terrain("volcano", LAND_REGION); t_active = test_create_terrain("activevolcano", LAND_REGION); r = test_create_region(0, 0, t_active); diff --git a/src/wormhole.test.c b/src/wormhole.test.c index e275d4d67..b8baaa79a 100644 --- a/src/wormhole.test.c +++ b/src/wormhole.test.c @@ -19,10 +19,14 @@ void sort_wormhole_regions(selist *rlist, region **match, int count); void make_wormholes(region **match, int count, const building_type *bt_wormhole); static void setup_wormholes(void) { - mt_register(mt_new_va("wormhole_appear", "region:region", MT_NEW_END)); - mt_register(mt_new_va("wormhole_dissolve", "region:region", MT_NEW_END)); - mt_register(mt_new_va("wormhole_exit", "unit:unit", "region:region", MT_NEW_END)); - mt_register(mt_new_va("wormhole_requirements", "unit:unit", "region:region", MT_NEW_END)); + mt_create_va(mt_new("wormhole_appear", NULL), + "region:region", MT_NEW_END); + mt_create_va(mt_new("wormhole_dissolve", NULL), + "region:region", MT_NEW_END); + mt_create_va(mt_new("wormhole_exit", NULL), + "unit:unit", "region:region", MT_NEW_END); + mt_create_va(mt_new("wormhole_requirements", NULL), + "unit:unit", "region:region", MT_NEW_END); } static void test_make_wormholes(CuTest *tc) { diff --git a/src/xmlreader.c b/src/xmlreader.c index 88ab51237..8ba33db84 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -1304,18 +1304,28 @@ static int parse_messages(xmlDocPtr doc) xmlXPathFreeObject(result); /* add the messagetype */ + propSection = xmlGetProp(node, BAD_CAST "section"); + if (propSection == NULL) { + propSection = BAD_CAST default_section; + } + propValue = xmlGetProp(node, BAD_CAST "name"); mtype = mt_find((const char *)propValue); if (mtype == NULL) { - mtype = mt_register(mt_new((const char *)propValue, (const char **)argv)); + mtype = mt_create(mt_new((const char *)propValue, (const char *)propSection), (const char **)argv); } else { assert(argv != NULL || !"cannot redefine arguments of message now"); } xmlFree(propValue); - /* register the type for the CR */ + if (propSection != BAD_CAST default_section) { + xmlFree(propSection); + } + + /* register the type for CR and NR */ crt_register(mtype); + nrt_register(mtype); /* let's clean up the mess */ if (argv != NULL) { @@ -1323,16 +1333,6 @@ static int parse_messages(xmlDocPtr doc) free(argv[k]); free(argv); } - - propSection = xmlGetProp(node, BAD_CAST "section"); - if (propSection == NULL) { - propSection = BAD_CAST default_section; - } - nrt_register(mtype, (const char *)propSection); - - if (propSection != BAD_CAST default_section) { - xmlFree(propSection); - } } xmlXPathFreeObject(messages); From 6b0f75339f0c31402277d59eaea5b94e9fc11015 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 18 May 2018 20:42:22 +0200 Subject: [PATCH 51/59] message parsing from exparse is working, but allocates too much. --- src/exparse.c | 88 +++++++++++++++++++++++++++++--------- src/kernel/messages.test.c | 4 +- src/util/message.c | 23 ++++++---- src/util/message.h | 8 ++-- src/xmlreader.c | 16 ++++--- 5 files changed, 97 insertions(+), 42 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index e323bb74c..271443c05 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -17,6 +17,8 @@ #include "util/functions.h" #include "util/log.h" #include "util/message.h" +#include "util/crmessage.h" +#include "util/nrmessage.h" #include "util/strings.h" #include @@ -285,8 +287,56 @@ static void handle_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **at wtype->flags = flags; } -static void XMLCALL start_messages(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { +static int msg_nargs; +static char * msg_args[MSG_MAXARGS]; + +static void end_messages(parseinfo *pi, const XML_Char *el) { if (xml_strcmp(el, "message") == 0) { + int i; + struct message_type *mtype = (struct message_type *)pi->object; + assert(mtype); + assert(msg_nargs < MSG_MAXARGS); + mt_create(mtype, (const char **)msg_args, msg_nargs); + /* register the type for CR and NR */ + crt_register(mtype); + nrt_register(mtype); + + for (i = 0; i != msg_nargs; ++i) { + free(msg_args[i]); + msg_args[i] = NULL; + } + msg_nargs = 0; + } + else if (xml_strcmp(el, "messages") == 0) { + pi->type = EXP_UNKNOWN; + } +} + +static void start_messages(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { + if (xml_strcmp(el, "arg") == 0) { + int i; + const XML_Char *name = NULL, *type = NULL; + + assert(msg_nargs < MSG_MAXARGS); + for (i = 0; attr[i]; i += 2) { + const XML_Char *key = attr[i], *val = attr[i + 1]; + if (xml_strcmp(key, "name") == 0) { + name = val; + } + else if (xml_strcmp(key, "type") == 0) { + type = val; + } + else { + handle_bad_input(pi, el, key); + } + } + if (name && type) { + char zBuffer[128]; + sprintf(zBuffer, "%s:%s", name, type); + msg_args[msg_nargs++] = str_strdup(zBuffer); + } + } + else if (xml_strcmp(el, "message") == 0) { const XML_Char *name = NULL, *section = NULL; int i; for (i = 0; attr[i]; i += 2) { @@ -297,18 +347,24 @@ static void XMLCALL start_messages(parseinfo *pi, const XML_Char *el, const XML_ else if (xml_strcmp(key, "section") == 0) { section = val; } + else { + handle_bad_input(pi, el, key); + } } if (name) { - pi->object = mt_new(name, NULL); + pi->object = mt_new(name, section); } } + else if (xml_strcmp(el, "type") != 0 && xml_strcmp(el, "text") != 0) { + handle_bad_input(pi, el, NULL); + } } #define MAX_COMPONENTS 8 static spell_component components[MAX_COMPONENTS]; static int ncomponents; -static void XMLCALL start_spells(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { +static void start_spells(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { const char *flag_names[] = { "far", "variable", "ocean", "ship", "los", "unittarget", "shiptarget", "buildingtarget", "regiontarget", "globaltarget", NULL }; @@ -390,7 +446,7 @@ static void XMLCALL start_spells(parseinfo *pi, const XML_Char *el, const XML_Ch } } -static void XMLCALL start_spellbooks(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { +static void start_spellbooks(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { spellbook * sb = (spellbook *)pi->object; if (xml_strcmp(el, "spellbook") == 0) { const XML_Char *name = attr_get(attr, "name"); @@ -430,7 +486,7 @@ static void XMLCALL start_spellbooks(parseinfo *pi, const XML_Char *el, const XM } } -static void XMLCALL start_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { +static void start_weapon(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { resource_type *rtype = (resource_type *)pi->object; assert(rtype && rtype->wtype); @@ -791,7 +847,7 @@ static void start_resources(parseinfo *pi, const XML_Char *el, const XML_Char ** } } -static void XMLCALL start_ships(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { +static void start_ships(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { const char *flag_names[] = { "opensea", "fly", "nocoast", "speedy", NULL }; if (xml_strcmp(el, "ship") == 0) { const XML_Char *name; @@ -899,7 +955,7 @@ static void XMLCALL start_ships(parseinfo *pi, const XML_Char *el, const XML_Cha static int nattacks; static int nfamiliars; -static void XMLCALL start_races(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { +static void start_races(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { race *rc = (race *)pi->object; const char *flag_names[] = { "playerrace", "killpeasants", "scarepeasants", "!cansteal", @@ -1116,7 +1172,7 @@ static void XMLCALL start_races(parseinfo *pi, const XML_Char *el, const XML_Cha } } -static void XMLCALL start_buildings(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { +static void start_buildings(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { const char *flag_names[] = { "nodestroy", "nobuild", "unique", "decay", "magic", "namechange", "fort", "oneperturn", NULL }; if (xml_strcmp(el, "building") == 0) { const XML_Char *name; @@ -1427,6 +1483,9 @@ static void XMLCALL handle_end(void *data, const XML_Char *el) { case EXP_SPELLS: end_spells(pi, el); break; + case EXP_MESSAGES: + end_messages(pi, el); + break; default: if (pi->depth == 1) { pi->object = NULL; @@ -1444,18 +1503,6 @@ static void XMLCALL handle_end(void *data, const XML_Char *el) { } } -static void XMLCALL handle_data(void *data, const XML_Char *xs, int len) { - parseinfo *pi = (parseinfo *)data; - if (len > 0) { - if (pi->type == EXP_MESSAGES && pi->depth == 4) { - size_t bytes = (size_t)len; - pi->cdata = realloc(pi->cdata, pi->clength + bytes); - memcpy(pi->cdata + pi->clength, xs, bytes); - pi->clength = pi->clength + bytes; - } - } -} - int exparse_readfile(const char * filename) { XML_Parser xp; FILE *F; @@ -1469,7 +1516,6 @@ int exparse_readfile(const char * filename) { } xp = XML_ParserCreate("UTF-8"); XML_SetElementHandler(xp, handle_start, handle_end); - XML_SetCharacterDataHandler(xp, handle_data); XML_SetUserData(xp, &pi); memset(&pi, 0, sizeof(pi)); for (;;) { diff --git a/src/kernel/messages.test.c b/src/kernel/messages.test.c index 961d2e63a..c017f6ec1 100644 --- a/src/kernel/messages.test.c +++ b/src/kernel/messages.test.c @@ -25,7 +25,7 @@ void test_message(CuTest *tc) { message_type *mtype; test_setup(); - mtype = mt_create(mt_new("custom", NULL), NULL); + mtype = mt_create(mt_new("custom", NULL), NULL, 0); CuAssertPtrEquals(tc, mtype, (void *)mt_find("custom")); CuAssertIntEquals(tc, 0, mtype->nparameters); CuAssertPtrEquals(tc, NULL, (void *)mtype->pnames); @@ -51,7 +51,7 @@ static void test_merge_split(CuTest *tc) { message *msg; test_setup(); - mtype = mt_create(mt_new("custom", NULL), NULL); + mtype = mt_create(mt_new("custom", NULL), NULL, 0); add_message(&mlist, msg = msg_message(mtype->name, "")); msg_release(msg); add_message(&append, msg = msg_message(mtype->name, "")); diff --git a/src/util/message.c b/src/util/message.c index 0f8b7cc36..b01993098 100644 --- a/src/util/message.c +++ b/src/util/message.c @@ -75,15 +75,22 @@ static unsigned int mt_id(const message_type * mtype) #define MT_MAXHASH 1021 static selist *messagetypes[MT_MAXHASH]; -message_type *mt_create(message_type * mtype, const char *args[]) -{ - int nparameters = 0; +static void mt_register(message_type * mtype) { unsigned int hash = str_hash(mtype->name) % MT_MAXHASH; selist **qlp = messagetypes + hash; - if (args != NULL) { + if (selist_set_insert(qlp, mtype, NULL)) { + mtype->key = mt_id(mtype); + } +} + +message_type *mt_create(message_type * mtype, const char *args[], int nparameters) +{ + if (args != NULL && args[nparameters]) { /* count the number of parameters */ - while (args[nparameters]) ++nparameters; + do { + ++nparameters; + } while (args[nparameters]); } if (nparameters > 0) { int i; @@ -111,9 +118,7 @@ message_type *mt_create(message_type * mtype, const char *args[]) } } } - if (selist_set_insert(qlp, mtype, NULL)) { - mtype->key = mt_id(mtype); - } + mt_register(mtype); return mtype; } @@ -151,7 +156,7 @@ message_type *mt_create_va(message_type *mtype, ...) } va_end(marker); args[i] = NULL; - return mt_create(mtype, args); + return mt_create(mtype, args, i - 1); } static variant copy_arg(const arg_type * atype, variant data) diff --git a/src/util/message.h b/src/util/message.h index 41d58b448..40cc09086 100644 --- a/src/util/message.h +++ b/src/util/message.h @@ -18,6 +18,9 @@ extern "C" { #endif +#define MSG_MAXARGS 8 +#define MT_NEW_END ((const char *)0) + typedef struct arg_type { struct arg_type *next; variant_type vtype; @@ -44,9 +47,6 @@ extern "C" { void message_done(void); void mt_clear(void); -#define MT_NEW_END ((const char *)0) - /* mt_new("simple_sentence", "subject:string", "predicate:string", - * "object:string", "lang:locale", MT_NEW_END); */ struct message *msg_create(const struct message_type *type, variant args[]); @@ -60,7 +60,7 @@ extern "C" { struct message_type *mt_new(const char *name, const char *section); /** message_type registry (optional): **/ - struct message_type *mt_create(struct message_type *, const char *args[]); + struct message_type *mt_create(struct message_type *, const char *args[], int nargs); struct message_type *mt_create_va(struct message_type *, ...); const struct message_type *mt_find(const char *); diff --git a/src/xmlreader.c b/src/xmlreader.c index 8ba33db84..2decd9cb5 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -1277,7 +1277,7 @@ static int parse_messages(xmlDocPtr doc) xmlChar *propSection; xmlChar *propValue; xmlXPathObjectPtr result; - int k; + int nargs = 0; char **argv = NULL; const message_type *mtype; @@ -1285,8 +1285,10 @@ static int parse_messages(xmlDocPtr doc) xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "type/arg", xpath); if (result->nodesetval && result->nodesetval->nodeNr > 0) { - argv = malloc(sizeof(char *) * (result->nodesetval->nodeNr + 1)); - for (k = 0; k != result->nodesetval->nodeNr; ++k) { + int k; + nargs = result->nodesetval->nodeNr; + argv = malloc(sizeof(char *) * (nargs + 1)); + for (k = 0; k != nargs; ++k) { xmlNodePtr node = result->nodesetval->nodeTab[k]; char zBuffer[128]; xmlChar *propName, *propType; @@ -1299,7 +1301,7 @@ static int parse_messages(xmlDocPtr doc) xmlFree(propType); argv[k] = str_strdup(zBuffer); } - argv[result->nodesetval->nodeNr] = NULL; + argv[nargs] = NULL; } xmlXPathFreeObject(result); @@ -1312,7 +1314,7 @@ static int parse_messages(xmlDocPtr doc) propValue = xmlGetProp(node, BAD_CAST "name"); mtype = mt_find((const char *)propValue); if (mtype == NULL) { - mtype = mt_create(mt_new((const char *)propValue, (const char *)propSection), (const char **)argv); + mtype = mt_create(mt_new((const char *)propValue, (const char *)propSection), (const char **)argv, nargs); } else { assert(argv != NULL || !"cannot redefine arguments of message now"); @@ -1329,8 +1331,10 @@ static int parse_messages(xmlDocPtr doc) /* let's clean up the mess */ if (argv != NULL) { - for (k = 0; argv[k] != NULL; ++k) + int k; + for (k = 0; argv[k] != NULL; ++k) { free(argv[k]); + } free(argv); } } From f5d6e6ac6e2a8bb4cc52c1ad053421ac91236a2a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 18 May 2018 20:43:22 +0200 Subject: [PATCH 52/59] we do not need xmlreader anymore! --- src/xmlreader.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/xmlreader.c b/src/xmlreader.c index 2decd9cb5..5a11eaf91 100644 --- a/src/xmlreader.c +++ b/src/xmlreader.c @@ -1354,8 +1354,6 @@ void register_xmlreader(void) xml_register_callback(parse_spellbooks); xml_register_callback(parse_spells); xml_register_callback(parse_races); -#endif - - xml_register_callback(parse_messages); +#endif } From ce37fd1bb7c77f3f3616973405d9fe7dbc60f8c0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 18 May 2018 21:14:14 +0200 Subject: [PATCH 53/59] remove libxml2 from dependencies remove the converter, that isn't a way we're going. --- CMakeLists.txt | 4 +- src/CMakeLists.txt | 29 +- src/bindings.c | 23 - src/convert.c | 37 -- src/eressea.c | 2 - src/gmtool.c | 1 - src/jsonconf.c | 12 +- src/kernel/build.c | 1 - src/kernel/config.c | 6 - src/kernel/ship.c | 1 - src/spells.c | 1 - src/util/CMakeLists.txt | 2 - src/util/xml.c | 131 ---- src/util/xml.h | 39 -- src/xmlreader.c | 1361 --------------------------------------- src/xmlreader.h | 28 - 16 files changed, 4 insertions(+), 1674 deletions(-) delete mode 100644 src/convert.c delete mode 100644 src/util/xml.c delete mode 100644 src/util/xml.h delete mode 100644 src/xmlreader.c delete mode 100644 src/xmlreader.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f73ba04a1..4b91565da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,8 +50,7 @@ else() find_package (SQLite3 REQUIRED QUIET) endif() -find_package(EXPAT) -find_package (LibXml2 REQUIRED) +find_package(EXPAT REQUIRED) find_package (ToLua REQUIRED) if (TOLUA_FOUND) if (${TOLUA_VERSION_STRING} VERSION_EQUAL "5.2") @@ -71,6 +70,7 @@ add_subdirectory (process) add_subdirectory (src eressea) install(DIRECTORY etc DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.txt") +install(DIRECTORY res conf DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.po") install(DIRECTORY res conf DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.xml") install(DIRECTORY res conf DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.json") install(DIRECTORY scripts DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.lua") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 21d07e9b2..5b267c0d5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -111,6 +111,7 @@ set (ERESSEA_SRC report.c steal.c economy.c + exparse.c give.c items.c laws.c @@ -127,7 +128,6 @@ set (ERESSEA_SRC travelthru.c monsters.c wormhole.c - xmlreader.c ${SPELLS_SRC} ${RACES_SRC} ${ITEMS_SRC} @@ -139,11 +139,6 @@ set (ERESSEA_SRC ${UTIL_SRC} ) -IF(EXPAT_FOUND) -set (ERESSEA_SRC ${ERESSEA_SRC} exparse.c) -ENDIF(EXPAT_FOUND) - - set(SERVER_SRC main.c console.c @@ -187,15 +182,6 @@ target_link_libraries(eressea ${INIPARSER_LIBRARIES} ) -add_executable(convert convert.c) -target_link_libraries(convert - game - ${LUA_MATH_LIBRARY} - ${STORAGE_LIBRARIES} - ${CLIBS_LIBRARIES} - ${INIPARSER_LIBRARIES} -) - set(TESTS_SRC test_eressea.c tests.c @@ -235,7 +221,6 @@ set(TESTS_SRC volcano.test.c vortex.test.c wormhole.test.c -# xmlreader.test.c spells/flyingship.test.c spells/magicresistance.test.c triggers/shock.test.c @@ -285,18 +270,15 @@ endif(HAVE_STRDUP) if (HAVE_LIBBSD) target_link_libraries(test_eressea bsd) target_link_libraries(eressea bsd) -target_link_libraries(convert bsd) endif (HAVE_LIBBSD) if (SQLITE3_FOUND) include_directories (${SQLITE3_INCLUDE_DIR}) target_link_libraries(eressea ${SQLITE3_LIBRARIES}) -target_link_libraries(convert ${SQLITE3_LIBRARIES}) target_link_libraries(test_eressea ${SQLITE3_LIBRARIES}) add_definitions(-DUSE_SQLITE) elseif (DB_FOUND) include_directories (${DB_INCLUDE_DIR}) -target_link_libraries(convert ${DB_LIBRARIES}) target_link_libraries(eressea ${DB_LIBRARIES}) target_link_libraries(test_eressea ${DB_LIBRARIES}) add_definitions(-DUSE_DB) @@ -317,14 +299,5 @@ endif(CURSES_FOUND) if (EXPAT_FOUND) include_directories (${EXPAT_INCLUDE_DIRS}) target_link_libraries(eressea ${EXPAT_LIBRARIES}) -target_link_libraries(convert ${EXPAT_LIBRARIES}) target_link_libraries(test_eressea ${EXPAT_LIBRARIES}) -add_definitions(-DUSE_EXPAT) endif (EXPAT_FOUND) - -if (LIBXML2_FOUND) -include_directories (${LIBXML2_INCLUDE_DIR}) -target_link_libraries(eressea ${LIBXML2_LIBRARIES}) -target_link_libraries(convert ${LIBXML2_LIBRARIES}) -target_link_libraries(test_eressea ${LIBXML2_LIBRARIES}) -endif (LIBXML2_FOUND) diff --git a/src/bindings.c b/src/bindings.c index 5c6174c75..d72bddac2 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -59,7 +59,6 @@ #include #include #include -#include #include #include @@ -833,33 +832,12 @@ static int tolua_get_spells(lua_State * L) return tolua_selist_push(L, "spell_list", "spell", spells); } -static int init_data(const char *filename) -{ - int l; - l = read_xml(filename); - reset_locales(); - if (l) { - return l; - } - if (turn <= 0) { - turn = first_turn(); - } - return 0; -} - static int tolua_equip_newunits(lua_State * L) { unit *u = (unit *)tolua_tousertype(L, 1, 0); equip_newunits(u); return 0; } -static int tolua_read_xml(lua_State * L) -{ - const char *filename = tolua_tostring(L, 1, "config.xml"); - lua_pushinteger(L, init_data(filename)); - return 1; -} - static int tolua_report_unit(lua_State * L) { char buffer[512]; @@ -1029,7 +1007,6 @@ int tolua_bindings_open(lua_State * L, const dictionary *inifile) tolua_function(L, TOLUA_CAST "set_key", tolua_setkey); tolua_function(L, TOLUA_CAST "translate", &tolua_translate); tolua_function(L, TOLUA_CAST "spells", tolua_get_spells); - tolua_function(L, TOLUA_CAST "read_xml", tolua_read_xml); tolua_function(L, TOLUA_CAST "equip_newunits", tolua_equip_newunits); } tolua_endmodule(L); return 1; diff --git a/src/convert.c b/src/convert.c deleted file mode 100644 index 6470c9e32..000000000 --- a/src/convert.c +++ /dev/null @@ -1,37 +0,0 @@ -#include - - -#include "xmlreader.h" -#include -#include -#include -#include - -#include - -#include - -static int usage(void) { - return -1; -} - -int main(int argc, char **argv) { - const char *mode; - - register_races(); - register_xmlreader(); - if (argc < 2) return usage(); - mode = argv[1]; - if (strcmp(mode, "rules")==0) { - const char *xmlfile; - if (argc < 4) return usage(); - xmlfile = argv[2]; - read_xml(xmlfile); - write_rules("rules.dat"); - return 0; - } - if (strcmp(mode, "po")==0) { - return 0; - } - return usage(); -} diff --git a/src/eressea.c b/src/eressea.c index 81f19b5a6..bdb20edcc 100644 --- a/src/eressea.c +++ b/src/eressea.c @@ -33,7 +33,6 @@ #include "spells.h" #include "vortex.h" #include "wormhole.h" -#include "xmlreader.h" #include #include @@ -80,7 +79,6 @@ void game_init(void) register_weapons(); register_xerewards(); - register_xmlreader(); register_attributes(); register_gmcmd(); diff --git a/src/gmtool.c b/src/gmtool.c index d63b93c5c..e13701f6f 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -55,7 +55,6 @@ #include "listbox.h" #include "wormhole.h" #include "teleport.h" -#include "xmlreader.h" #include #include diff --git a/src/jsonconf.c b/src/jsonconf.c index c91f8a749..fcd6f5c78 100644 --- a/src/jsonconf.c +++ b/src/jsonconf.c @@ -39,7 +39,6 @@ without prior permission by the authors of Eressea. #include "util/path.h" #include "util/pofile.h" #include "util/strings.h" -#include "util/xml.h" /* game modules */ #include "direction.h" @@ -47,9 +46,7 @@ without prior permission by the authors of Eressea. #include "move.h" #include "prefix.h" #include "skill.h" -#ifdef USE_EXPAT #include "exparse.h" -#endif /* external libraries */ #include @@ -1017,14 +1014,7 @@ static int include_xml(const char *uri) { char name[PATH_MAX]; const char *filename = uri_to_file(uri, name, sizeof(name)); int err; -#ifdef USE_EXPAT err = exparse_readfile(filename); - if (err != 0) { - err = read_xml(filename); - } -#else - err = read_xml(filename); -#endif if (err != 0) { log_error("could not parse XML from %s", uri); } @@ -1058,7 +1048,7 @@ static int include_po(const char *uri) { if (lang) { int err = pofile_read(filename, add_po_string, lang); if (err < 0) { - log_error("could not parse XML from %s", uri); + log_error("could not parse translations from %s", uri); } return err; } diff --git a/src/kernel/build.c b/src/kernel/build.c index 45a7d0898..310e4bd43 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -60,7 +60,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include /* from libc */ #include diff --git a/src/kernel/config.c b/src/kernel/config.c index 54d030b76..8eef66341 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -66,16 +66,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include #include "donations.h" #include "guard.h" #include "prefix.h" -/* libxml includes */ -#include -#include - /* external libraries */ #include #include @@ -559,7 +554,6 @@ void kernel_done(void) /* calling this function releases memory assigned to static variables, etc. * calling it is optional, e.g. a release server will most likely not do it. */ - xml_done(); attrib_done(); item_done(); message_done(); diff --git a/src/kernel/ship.c b/src/kernel/ship.c index def6dd1fa..4719945b0 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -42,7 +42,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include #include #include diff --git a/src/spells.c b/src/spells.c index bd2c8ea1a..4e98b1a2a 100644 --- a/src/spells.c +++ b/src/spells.c @@ -26,7 +26,6 @@ #include "randenc.h" #include "monsters.h" #include "teleport.h" -#include "xmlreader.h" /* triggers includes */ #include diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 19f9b608b..b462d2bd3 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -28,7 +28,6 @@ log.test.c umlaut.test.c unicode.test.c variant.test.c -# xml.test.c ) SET(_FILES @@ -59,7 +58,6 @@ translation.c umlaut.c unicode.c variant.c -xml.c ) FOREACH(_FILE ${_FILES}) diff --git a/src/util/xml.c b/src/util/xml.c deleted file mode 100644 index 7ce893916..000000000 --- a/src/util/xml.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - +-------------------+ Christian Schlittchen - | | Enno Rehling - | Eressea PBEM host | Katja Zedel - | (c) 1998 - 2003 | Henning Peters - | | Ingo Wilken - +-------------------+ Stefan Reich - - This program may not be used, modified or distributed - without prior permission by the authors of Eressea. - */ -#include -#include "xml.h" - -/* util includes */ -#include "log.h" -#include "assert.h" - -#include -#include - -/* libc includes */ -#include -#include -#include -#include - -int xml_ivalue(xmlNodePtr node, const char *name, int dflt) -{ - int i = dflt; - xmlChar *propValue = xmlGetProp(node, BAD_CAST name); - if (propValue != NULL) { - i = atoi((const char *)propValue); - xmlFree(propValue); - } - return i; -} - -bool xml_bvalue(xmlNodePtr node, const char *name, bool dflt) -{ - bool result = dflt; - xmlChar *propValue = xmlGetProp(node, BAD_CAST name); - if (propValue != NULL) { - if (strcmp((const char *)propValue, "no") == 0) - result = false; - else if (strcmp((const char *)propValue, "yes") == 0) - result = true; - else if (strcmp((const char *)propValue, "false") == 0) - result = false; - else if (strcmp((const char *)propValue, "true") == 0) - result = true; - else if (strcmp((const char *)propValue, "1") == 0) { - log_warning("bool value is '1': %s::%s\n", node->name, name); - result = true; - } - else if (strcmp((const char *)propValue, "0") == 0) { - log_warning("bool value is '0': %s::%s\n", node->name, name); - result = false; - } - xmlFree(propValue); - } - return result; -} - -double xml_fvalue(xmlNodePtr node, const char *name, double dflt) -{ - double result = dflt; - xmlChar *propValue = xmlGetProp(node, BAD_CAST name); - if (propValue != NULL) { - result = atof((const char *)propValue); - xmlFree(propValue); - } - return result; -} - -/* new xml functions */ -/* libxml includes */ -#include -#include - -typedef struct xml_reader { - struct xml_reader *next; - xml_callback callback; -} xml_reader; - -static xml_reader *xmlReaders; - -void xml_done(void) { - xml_reader ** xrp = &xmlReaders; - while (*xrp) { - xml_reader *xr = *xrp; - *xrp = xr->next; - free(xr); - } -} - -void xml_register_callback(xml_callback callback) -{ - xml_reader *reader = (xml_reader *)malloc(sizeof(xml_reader)); - xml_reader **insert = &xmlReaders; - assert_alloc(reader); - reader->callback = callback; - reader->next = NULL; - - while (*insert) - insert = &(*insert)->next; - *insert = reader; -} - -int read_xml(const char *filename) -{ - xml_reader *reader = xmlReaders; - xmlDocPtr doc; - int results = 0; - - doc = xmlReadFile(filename, NULL, XML_PARSE_NONET | XML_PARSE_PEDANTIC | XML_PARSE_COMPACT); - if (doc == NULL) { - log_error("could not open '%s'\n", filename); - return -1; - } - while (reader != NULL) { - int i = reader->callback(doc); - if (i < 0) { - return i; - } - results += i; - reader = reader->next; - } - xmlFreeDoc(doc); - return (results > 0) ? 0 : -1; -} diff --git a/src/util/xml.h b/src/util/xml.h deleted file mode 100644 index c7a67a82c..000000000 --- a/src/util/xml.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - +-------------------+ Christian Schlittchen - | | Enno Rehling - | Eressea PBEM host | Katja Zedel - | (c) 1998 - 2003 | Henning Peters - | | Ingo Wilken - +-------------------+ Stefan Reich - - This program may not be used, modified or distributed - without prior permission by the authors of Eressea. -*/ - -#ifndef H_UTIL_XML -#define H_UTIL_XML - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - /* new xml functions: */ -#include - - - typedef int (*xml_callback) (xmlDocPtr); - - void xml_register_callback(xml_callback callback); - double xml_fvalue(xmlNodePtr node, const char *name, double dflt); - int xml_ivalue(xmlNodePtr node, const char *name, int dflt); - bool xml_bvalue(xmlNodePtr node, const char *name, bool dflt); - - void xml_done(void); - int read_xml(const char *filename); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/xmlreader.c b/src/xmlreader.c deleted file mode 100644 index 2decd9cb5..000000000 --- a/src/xmlreader.c +++ /dev/null @@ -1,1361 +0,0 @@ -/* -+-------------------+ -| | Enno Rehling -| Eressea PBEM host | Christian Schlittchen -| (c) 1998 - 2004 | Katja Zedel -| | Henning Peters -+-------------------+ - -This program may not be used, modified or distributed -without prior permission by the authors of Eressea. -*/ - -#ifdef _MSC_VER -#include -#endif - -#include "xmlreader.h" - -#include "alchemy.h" -#include "guard.h" -#include "keyword.h" -#include "move.h" -#include "prefix.h" - -#include "attributes/attributes.h" -#include "modules/score.h" - -#include "kernel/building.h" -#include "kernel/calendar.h" -#include "kernel/item.h" -#include "kernel/messages.h" -#include "kernel/race.h" -#include "kernel/region.h" -#include "kernel/resources.h" -#include "kernel/ship.h" -#include "kernel/terrain.h" -#include "kernel/skills.h" -#include "kernel/spell.h" -#include "kernel/spellbook.h" - -#include "util/attrib.h" -#include "util/crmessage.h" -#include "util/functions.h" -#include "util/language.h" -#include "util/log.h" -#include "util/message.h" -#include "util/nrmessage.h" -#include "util/strings.h" -#include "util/xml.h" - -/* libxml includes */ -#include -#include -#include - -/* libc includes */ -#include -#include -#include -#include - - -static void mask_races(xmlNodePtr node, const char *key, int *maskp) { - xmlChar *propValue = xmlGetProp(node, BAD_CAST key); - int mask = 0; - assert(maskp); - if (propValue) { - mask = rc_get_mask((char *)propValue); - xmlFree(propValue); - } - *maskp = mask; -} - -static variant xml_fraction(xmlNodePtr node, const char *name) { - xmlChar *propValue = xmlGetProp(node, BAD_CAST name); - if (propValue != NULL) { - int num, den = 100; - double fval = atof((const char *)propValue); - num = (int)(fval * den + 0.5); - xmlFree(propValue); - return frac_make(num, den); - } - return frac_make(0, 1); -} - -static spellref *xml_spellref(xmlNode * node, const char *name) -{ - xmlChar *propValue = xmlGetProp(node, BAD_CAST name); - if (propValue != NULL) { - spellref *ref = spellref_create(NULL, (const char *)propValue); - xmlFree(propValue); - return ref; - } - return NULL; -} - -static resource_mod * xml_readmodifiers(xmlXPathObjectPtr result, xmlNodePtr node) { - /* reading eressea/resources/resource/modifier */ - if (result->nodesetval != NULL && result->nodesetval->nodeNr > 0) { - int k; - resource_mod * modifiers = - calloc(result->nodesetval->nodeNr + 1, sizeof(resource_mod)); - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - xmlChar *propValue; - building_type *btype = NULL; - - mask_races(node, "races", &modifiers[k].race_mask); - - propValue = xmlGetProp(node, BAD_CAST "building"); - if (propValue != NULL) { - btype = bt_get_or_create((const char *)propValue); - xmlFree(propValue); - } - modifiers[k].btype = btype; - - propValue = xmlGetProp(node, BAD_CAST "type"); - assert(propValue != NULL); - if (strcmp((const char *)propValue, "skill") == 0) { - xmlChar *propSkill; - skill_t sk = NOSKILL; - - modifiers[k].type = RMT_PROD_SKILL; - propSkill = xmlGetProp(node, BAD_CAST "skill"); - if (propSkill) { - sk = findskill((const char *)propSkill); - xmlFree(propSkill); - } - modifiers[k].value.sa[0] = (short)sk; - modifiers[k].value.sa[1] = (short)xml_ivalue(node, "value", 0); - } - else if (strcmp((const char *)propValue, "material") == 0) { - modifiers[k].value = xml_fraction(node, "value"); - modifiers[k].type = RMT_PROD_SAVE; - } - else { - if (strcmp((const char *)propValue, "require") == 0) { - modifiers[k].type = RMT_PROD_REQUIRE; - } - else if (strcmp((const char *)propValue, "save") == 0) { - modifiers[k].type = RMT_USE_SAVE; - modifiers[k].value = xml_fraction(node, "value"); - } - else { - log_error("unknown type '%s' for resourcelimit-modifier", (const char *)propValue); - } - } - xmlFree(propValue); - } - return modifiers; - } - return NULL; -} - -static void -xml_readrequirements(xmlNodePtr * nodeTab, int nodeNr, requirement ** reqArray) -{ - int req; - requirement *radd = *reqArray; - - assert(radd == NULL); - if (nodeNr == 0) - return; - - radd = *reqArray = calloc(sizeof(requirement), nodeNr + 1); - - for (req = 0; req != nodeNr; ++req) { - xmlNodePtr node = nodeTab[req]; - xmlChar *propValue; - - radd->number = xml_ivalue(node, "quantity", 1); - - propValue = xmlGetProp(node, BAD_CAST "type"); - radd->rtype = rt_get_or_create((const char *)propValue); - xmlFree(propValue); - - ++radd; - } -} - -static construction * -xml_readconstruction(xmlXPathContextPtr xpath, xmlNodePtr node) -{ - construction *con; - xmlChar *propValue; - xmlXPathObjectPtr req; - skill_t sk = NOSKILL; - - propValue = xmlGetProp(node, BAD_CAST "skill"); - if (propValue != NULL) { - sk = findskill((const char *)propValue); - if (sk == NOSKILL) { - log_error("construction requires skill '%s' that does not exist.\n", (const char *)propValue); - xmlFree(propValue); - return NULL; - } - xmlFree(propValue); - } - - con = (construction *)calloc(sizeof(construction), 1); - - con->skill = sk; - con->maxsize = xml_ivalue(node, "maxsize", -1); - con->minskill = xml_ivalue(node, "minskill", -1); - con->reqsize = xml_ivalue(node, "reqsize", 1); - - /* read construction/requirement */ - xpath->node = node; - req = xmlXPathEvalExpression(BAD_CAST "requirement", xpath); - xml_readrequirements(req->nodesetval->nodeTab, - req->nodesetval->nodeNr, &con->materials); - xmlXPathFreeObject(req); - - return con; -} - -static void -xml_readconstructions(xmlXPathContextPtr xpath, xmlNodeSetPtr nodeSet, building_type *btype) -{ - building_stage **stage_ptr = &btype->stages; - int k; - - for (k = 0; k != nodeSet->nodeNr; ++k) { - building_stage *stage = calloc(1, sizeof(building_stage)); - xmlNodePtr node = nodeSet->nodeTab[k]; - construction *con = xml_readconstruction(xpath, node); - xmlChar *propValue = xmlGetProp(node, BAD_CAST "name"); - - if (propValue != NULL) { - stage->name = str_strdup((const char *)propValue); - xmlFree(propValue); - } - stage->next = NULL; - stage->construction = con; - - *stage_ptr = stage; - stage_ptr = &stage->next; - } -} - -static int -parse_function(xmlNodePtr node, pf_generic * funPtr, xmlChar ** namePtr) -{ - pf_generic fun; - xmlChar *propValue = xmlGetProp(node, BAD_CAST "value"); - assert(propValue != NULL); - fun = get_function((const char *)propValue); - xmlFree(propValue); - propValue = xmlGetProp(node, BAD_CAST "name"); - *namePtr = propValue; - *funPtr = fun; - return 0; -} - -static int parse_buildings(xmlDocPtr doc) -{ - xmlXPathContextPtr xpath = xmlXPathNewContext(doc); - xmlXPathObjectPtr buildings; - int result = 0; - - /* reading eressea/buildings/building */ - buildings = - xmlXPathEvalExpression(BAD_CAST "/eressea/buildings/building", xpath); - if (buildings->nodesetval != NULL) { - xmlNodeSetPtr nodes = buildings->nodesetval; - int i; - result += nodes->nodeNr; - for (i = 0; i != nodes->nodeNr; ++i) { - xmlNodePtr node = nodes->nodeTab[i]; - xmlChar *propValue; - building_type *btype; - xmlXPathObjectPtr result; - int k; - - propValue = xmlGetProp(node, BAD_CAST "name"); - assert(propValue != NULL); - btype = bt_get_or_create((const char *)propValue); - xmlFree(propValue); - - btype->capacity = xml_ivalue(node, "capacity", btype->capacity); - btype->maxcapacity = xml_ivalue(node, "maxcapacity", btype->maxcapacity); - btype->maxsize = xml_ivalue(node, "maxsize", btype->maxsize); - - btype->magres = frac_make(xml_ivalue(node, "magres", 0), 100); - btype->magresbonus = xml_ivalue(node, "magresbonus", btype->magresbonus); - btype->fumblebonus = xml_ivalue(node, "fumblebonus", btype->fumblebonus); - btype->auraregen = xml_fvalue(node, "auraregen", btype->auraregen); - btype->taxes = xml_ivalue(node, "taxes", btype->taxes); - - if (xml_bvalue(node, "nodestroy", false)) - btype->flags |= BTF_INDESTRUCTIBLE; - if (xml_bvalue(node, "nobuild", false)) - btype->flags |= BTF_NOBUILD; - if (xml_bvalue(node, "unique", false)) - btype->flags |= BTF_UNIQUE; - if (xml_bvalue(node, "decay", false)) - btype->flags |= BTF_DECAY; - if (xml_bvalue(node, "magic", false)) - btype->flags |= BTF_MAGIC; - if (xml_bvalue(node, "namechange", true)) - btype->flags |= BTF_NAMECHANGE; - if (xml_bvalue(node, "fort", false)) - btype->flags |= BTF_FORTIFICATION; - if (xml_bvalue(node, "oneperturn", false)) - btype->flags |= BTF_ONEPERTURN; - - /* reading eressea/buildings/building/modifier */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath); - btype->modifiers = xml_readmodifiers(result, node); - xmlXPathFreeObject(result); - - /* reading eressea/buildings/building/construction */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "construction", xpath); - xml_readconstructions(xpath, result->nodesetval, btype); - xmlXPathFreeObject(result); - - /* reading eressea/buildings/building/function */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "function", xpath); - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - pf_generic fun; - parse_function(node, &fun, &propValue); - - if (fun == NULL) { - log_error("unknown function name '%s' for building %s\n", (const char *)propValue, btype->_name); - xmlFree(propValue); - continue; - } - assert(propValue != NULL); - log_error("unknown function type '%s' for building %s\n", (const char *)propValue, btype->_name); - xmlFree(propValue); - } - xmlXPathFreeObject(result); - - /* reading eressea/buildings/building/maintenance */ - result = xmlXPathEvalExpression(BAD_CAST "maintenance", xpath); - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - maintenance *mt; - - if (btype->maintenance == NULL) { - btype->maintenance = (struct maintenance *) - calloc(sizeof(struct maintenance), result->nodesetval->nodeNr + 1); - } - mt = btype->maintenance + k; - mt->number = xml_ivalue(node, "amount", 0); - - propValue = xmlGetProp(node, BAD_CAST "type"); - assert(propValue != NULL); - mt->rtype = rt_get_or_create((const char *)propValue); - assert(mt->rtype != NULL); - xmlFree(propValue); - - if (xml_bvalue(node, "variable", false)) - mt->flags |= MTF_VARIABLE; - } - xmlXPathFreeObject(result); - } - } - xmlXPathFreeObject(buildings); - - xmlXPathFreeContext(xpath); - return result; -} - -static int parse_ships(xmlDocPtr doc) -{ - xmlXPathContextPtr xpath = xmlXPathNewContext(doc); - xmlXPathObjectPtr ships; - int result = 0; - - /* reading eressea/ships/ship */ - ships = xmlXPathEvalExpression(BAD_CAST "/eressea/ships/ship", xpath); - if (ships->nodesetval != NULL) { - xmlNodeSetPtr nodes = ships->nodesetval; - int i; - result += nodes->nodeNr; - for (i = 0; i != nodes->nodeNr; ++i) { - xmlNodePtr child, node = nodes->nodeTab[i]; - xmlChar *propValue; - ship_type *st; - xmlXPathObjectPtr result; - int k, c; - - propValue = xmlGetProp(node, BAD_CAST "name"); - assert(propValue != NULL); - st = st_get_or_create((const char *)propValue); - xmlFree(propValue); - - st->cabins = xml_ivalue(node, "cabins", 0) * PERSON_WEIGHT; - st->cargo = xml_ivalue(node, "cargo", st->cargo); - st->combat = xml_ivalue(node, "combat", st->combat); - st->damage = xml_fvalue(node, "damage", st->damage); - if (xml_bvalue(node, "nocoast", false)) - st->flags |= SFL_NOCOAST; - if (xml_bvalue(node, "fly", false)) - st->flags |= SFL_FLY; - if (xml_bvalue(node, "opensea", false)) - st->flags |= SFL_OPENSEA; - if (xml_bvalue(node, "speedy", false)) - st->flags |= SFL_SPEEDY; - st->fishing = xml_ivalue(node, "fishing", st->fishing); - st->cptskill = xml_ivalue(node, "cptskill", st->cptskill); - st->minskill = xml_ivalue(node, "minskill", st->minskill); - st->sumskill = xml_ivalue(node, "sumskill", st->sumskill); - st->range = xml_ivalue(node, "range", st->range); - st->range_max = xml_ivalue(node, "maxrange", st->range_max); - st->storm = xml_fvalue(node, "storm", st->storm); - - for (child = node->children; child; child = child->next) { - if (strcmp((const char *)child->name, "modifier") == 0) { - propValue = xmlGetProp(child, BAD_CAST "type"); - if (strcmp((const char *)propValue, "tactics") == 0) { - st->tac_bonus = xml_fvalue(child, "factor", 1.0); - } - else { - int value = xml_ivalue(child, "value", 0); - if (strcmp((const char *)propValue, "attack") == 0) { - st->at_bonus = (int)value; - } - else if (strcmp((const char *)propValue, "defense") == 0) { - 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); - } - } - /* reading eressea/ships/ship/coast */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "coast", xpath); - for (c = 0, k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - - if (k == 0) { - assert(st->coasts == NULL); - st->coasts = - (terrain_type **)malloc(sizeof(terrain_type *) * - (result->nodesetval->nodeNr + 1)); - st->coasts[result->nodesetval->nodeNr] = NULL; - } - - propValue = xmlGetProp(node, BAD_CAST "terrain"); - assert(propValue != NULL); - st->coasts[c] = get_or_create_terrain((const char *)propValue); - if (st->coasts[c] != NULL) - ++c; - else { - log_warning("ship %s mentions a non-existing terrain %s.\n", st->_name, propValue); - } - xmlFree(propValue); - } - xmlXPathFreeObject(result); - } - } - xmlXPathFreeObject(ships); - - xmlXPathFreeContext(xpath); - return result; -} - -static void xml_readpotion(xmlNodePtr node, item_type * itype) -{ - 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(xmlNodePtr node, item_type * itype) -{ - int price = xml_ivalue(node, "price", 0); - if (itype->rtype->ltype) { - itype->rtype->ltype->price = price; - return itype->rtype->ltype; - } - return new_luxurytype(itype, price); -} - -static armor_type *xml_readarmor(xmlNodePtr node, item_type * itype) -{ - armor_type *atype = NULL; - unsigned int flags = ATF_NONE; - int ac = xml_ivalue(node, "ac", 0); - double penalty = xml_fvalue(node, "penalty", 0.0); - variant magres = xml_fraction(node, "magres"); - - if (xml_bvalue(node, "laen", false)) - flags |= ATF_LAEN; - if (xml_bvalue(node, "shield", false)) - flags |= ATF_SHIELD; - - atype = new_armortype(itype, penalty, magres, ac, flags); - atype->projectile = (float)xml_fvalue(node, "projectile", 0.0); - return atype; -} - -static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) -{ - xmlNodePtr node = xpath->node; - weapon_type *wtype = NULL; - unsigned int flags = WTF_NONE; - xmlXPathObjectPtr result; - xmlChar *propValue; - int k; - skill_t sk; - int offmod = xml_ivalue(node, "offmod", 0); - int defmod = xml_ivalue(node, "defmod", 0); - int reload = xml_ivalue(node, "reload", 0); - variant magres = xml_fraction(node, "magres"); - - if (xml_bvalue(node, "armorpiercing", false)) - flags |= WTF_ARMORPIERCING; - if (xml_bvalue(node, "magical", false)) - flags |= WTF_MAGICAL; - if (xml_bvalue(node, "missile", false)) - flags |= WTF_MISSILE; - if (xml_bvalue(node, "pierce", false)) - flags |= WTF_PIERCE; - if (xml_bvalue(node, "cut", false)) - flags |= WTF_CUT; - if (xml_bvalue(node, "bash", false)) - flags |= WTF_BLUNT; - if (xml_bvalue(node, "siege", false)) - flags |= WTF_SIEGE; - if (xml_bvalue(node, "horse", (flags & WTF_MISSILE) == 0)) - flags |= WTF_HORSEBONUS; - if (xml_bvalue(node, "useshield", true)) - flags |= WTF_USESHIELD; - - propValue = xmlGetProp(node, BAD_CAST "skill"); - assert(propValue != NULL); - sk = findskill((const char *)propValue); - assert(sk != NOSKILL); - xmlFree(propValue); - - wtype = new_weapontype(itype, flags, magres, NULL, offmod, defmod, reload, sk); - - /* reading weapon/damage */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "damage", xpath); - assert(result->nodesetval->nodeNr <= 2); - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - int pos = 0; - - propValue = xmlGetProp(node, BAD_CAST "type"); - if (strcmp((const char *)propValue, "footman") != 0) { - pos = 1; - } - xmlFree(propValue); - - propValue = xmlGetProp(node, BAD_CAST "value"); - wtype->damage[pos] = str_strdup((const char *)propValue); /* TODO: this is a memory leak */ - xmlFree(propValue); - } - xmlXPathFreeObject(result); - - /* reading weapon/modifier */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath); - assert(wtype->modifiers == NULL); - wtype->modifiers = calloc(result->nodesetval->nodeNr + 1, sizeof(weapon_mod)); - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - int flags = 0; - - if (xml_bvalue(node, "walking", false)) - flags |= WMF_WALKING; - if (xml_bvalue(node, "riding", false)) - flags |= WMF_RIDING; - if (xml_bvalue(node, "against_walking", false)) - flags |= WMF_AGAINST_WALKING; - if (xml_bvalue(node, "against_riding", false)) - flags |= WMF_AGAINST_RIDING; - if (xml_bvalue(node, "offensive", false)) - flags |= WMF_OFFENSIVE; - if (xml_bvalue(node, "defensive", false)) - flags |= WMF_DEFENSIVE; - - propValue = xmlGetProp(node, BAD_CAST "type"); - if (strcmp((const char *)propValue, "damage") == 0) - flags |= WMF_DAMAGE; - else if (strcmp((const char *)propValue, "skill") == 0) - flags |= WMF_SKILL; - else if (strcmp((const char *)propValue, "missile_target") == 0) - flags |= WMF_MISSILE_TARGET; - xmlFree(propValue); - - wtype->modifiers[k].flags = flags; - wtype->modifiers[k].value = xml_ivalue(node, "value", 0); - - mask_races(node, "races", &wtype->modifiers[k].race_mask); - wtype->modifiers[k].race_mask = 0; - } - xmlXPathFreeObject(result); - - /* reading weapon/function */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "function", xpath); - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - xmlChar *propValue; - pf_generic fun; - - parse_function(node, &fun, &propValue); - if (fun == NULL) { - log_error("unknown function name '%s' for item '%s'\n", (const char *)propValue, itype->rtype->_name); - xmlFree(propValue); - continue; - } - assert(propValue != NULL); - if (strcmp((const char *)propValue, "attack") == 0) { - wtype->attack = (wtype_attack)fun; - } - else { - log_error("unknown function type '%s' for item '%s'\n", (const char *)propValue, itype->rtype->_name); - } - xmlFree(propValue); - } - xmlXPathFreeObject(result); - - xpath->node = node; - return wtype; -} - -static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) -{ - xmlNodePtr child, node = xpath->node; - item_type *itype = NULL; - unsigned int flags = ITF_NONE; - - if (xml_bvalue(node, "cursed", false)) - flags |= ITF_CURSED; - if (xml_bvalue(node, "use", false)) - flags |= ITF_CANUSE; - if (xml_bvalue(node, "notlost", false)) - flags |= ITF_NOTLOST; - if (xml_bvalue(node, "herb", false)) - flags |= ITF_HERB; - if (xml_bvalue(node, "big", false)) - flags |= ITF_BIG; - if (xml_bvalue(node, "animal", false)) - flags |= ITF_ANIMAL; - if (xml_bvalue(node, "vehicle", false)) - flags |= ITF_VEHICLE; - - 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->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; - - 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); - } - 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); - } - } - - if (!itype->score) { - /* do this last, because score depends on itype data */ - itype->score = default_score(itype); - } - return itype; -} - -static int parse_resources(xmlDocPtr doc) -{ - xmlXPathContextPtr xpath = xmlXPathNewContext(doc); - xmlXPathObjectPtr resources; - int results = 0; - - /* reading eressea/resources/resource */ - resources = - xmlXPathEvalExpression(BAD_CAST "/eressea/resources/resource", xpath); - if (resources->nodesetval) { - int i; - xmlNodeSetPtr nodes = resources->nodesetval; - results = nodes->nodeNr; - for (i = 0; i != nodes->nodeNr; ++i) { - xmlNodePtr node = nodes->nodeTab[i]; - xmlChar *propValue, *name, *appearance; - resource_type *rtype; - unsigned int flags = RTF_NONE; - xmlXPathObjectPtr result; - - if (xml_bvalue(node, "pooled", true)) - flags |= RTF_POOLED; - - name = xmlGetProp(node, BAD_CAST "name"); - if (!name) { - assert(name); - log_error("invalid resource %d has no name", i); - continue; - } - - 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; - xmlFree(name); - - /* reading eressea/resources/resource/function */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "function", xpath); - if (result->nodesetval != NULL) { - int k; - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - pf_generic fun; - - parse_function(node, &fun, &propValue); - if (fun == NULL) { - log_error("unknown function name '%s' for resource %s\n", (const char *)propValue, rtype->_name); - xmlFree(propValue); - continue; - } - - assert(propValue != NULL); - if (strcmp((const char *)propValue, "change") == 0) { - rtype->uchange = (rtype_uchange)fun; - } - else if (strcmp((const char *)propValue, "name") == 0) { - rtype->name = (rtype_name)fun; - } - else { - log_error("unknown function type '%s' for resource %s\n", (const char *)propValue, rtype->_name); - } - xmlFree(propValue); - } - } - xmlXPathFreeObject(result); - - if (xml_bvalue(node, "limited", false)) { - rtype->flags |= RTF_LIMITED; - } - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath); - rtype->modifiers = xml_readmodifiers(result, node); - xmlXPathFreeObject(result); - - /* reading eressea/resources/resource/item */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "item", xpath); - assert(result->nodesetval->nodeNr <= 1); - if (result->nodesetval->nodeNr != 0) { - rtype->flags |= RTF_ITEM; - xpath->node = result->nodesetval->nodeTab[0]; - rtype->itype = xml_readitem(xpath, rtype); - appearance = xmlGetProp(node, BAD_CAST "appearance"); - if (appearance) { - it_set_appearance(rtype->itype, (const char *)appearance); - xmlFree(appearance); - } - } - xmlXPathFreeObject(result); - - if (xml_bvalue(node, "material", false)) { - assert(!rtype->itype || rtype->itype->construction); - rmt_create(rtype); - } - } - } - xmlXPathFreeObject(resources); - - xmlXPathFreeContext(xpath); - - /* make sure old items (used in requirements) are available */ - init_resources(); - - return results; -} - -static int parse_spellbooks(xmlDocPtr doc) -{ - xmlXPathContextPtr xpath = xmlXPathNewContext(doc); - xmlXPathObjectPtr spellbooks; - int results = 0; - - /* reading eressea/spells/spell */ - spellbooks = xmlXPathEvalExpression(BAD_CAST "/eressea/spellbook", xpath); - - if (spellbooks->nodesetval != NULL) { - xmlNodeSetPtr nodes = spellbooks->nodesetval; - int i, k; - - results += nodes->nodeNr; - for (i = 0; i != nodes->nodeNr; ++i) { - xmlXPathObjectPtr result; - xmlNodePtr node = nodes->nodeTab[i]; - xmlChar *propValue; - spellbook * sb; - - propValue = xmlGetProp(node, BAD_CAST "name"); - if (propValue) { - sb = get_spellbook((const char *)propValue); - xmlFree(propValue); - } - else { - log_error("spellbook at index '%d' has n name\n", i); - continue; - } - - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "entry", xpath); - - if (result->nodesetval->nodeNr > 0) { - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - int level = xml_ivalue(node, "level", -1); - - if (level > 0 && (propValue = xmlGetProp(node, BAD_CAST "spell")) != NULL) { - spellbook_addref(sb, (const char *)propValue, level); - xmlFree(propValue); - } - else { - log_error("invalid entry at index '%d' in spellbook '%s'\n", k, sb->name); - } - } - } - xmlXPathFreeObject(result); - } - } - xmlXPathFreeObject(spellbooks); - xmlXPathFreeContext(xpath); - return results; -} - -static int parse_spells(xmlDocPtr doc) -{ - xmlXPathContextPtr xpath = xmlXPathNewContext(doc); - xmlXPathObjectPtr spells; - int result = 0; - - /* reading eressea/spells/spell */ - spells = xmlXPathEvalExpression(BAD_CAST "/eressea/spells/spell", xpath); - if (spells->nodesetval != NULL) { - xmlNodeSetPtr nodes = spells->nodesetval; - int i; - - result += nodes->nodeNr; - for (i = 0; i != nodes->nodeNr; ++i) { - xmlXPathObjectPtr result; - xmlNodePtr node = nodes->nodeTab[i]; - xmlChar *propValue; - int k; - spell_component *component; - spell *sp; - static int modes[] = { 0, PRECOMBATSPELL, COMBATSPELL, POSTCOMBATSPELL }; - - /* spellname */ - propValue = xmlGetProp(node, BAD_CAST "name"); - assert(propValue != NULL); - sp = create_spell((const char *)propValue); - xmlFree(propValue); - if (!sp) { - continue; - } - - propValue = xmlGetProp(node, BAD_CAST "parameters"); - if (propValue) { - sp->parameter = str_strdup((const char *)propValue); - xmlFree(propValue); - } - - propValue = xmlGetProp(node, BAD_CAST "syntax"); - if (propValue) { - sp->syntax = str_strdup((const char *)propValue); - xmlFree(propValue); - } - sp->rank = (char)xml_ivalue(node, "rank", sp->rank); - if (xml_bvalue(node, "los", false)) - sp->sptyp |= TESTCANSEE; /* must see or have contact */ - if (xml_bvalue(node, "ship", false)) - sp->sptyp |= ONSHIPCAST; - if (xml_bvalue(node, "ocean", false)) - sp->sptyp |= OCEANCASTABLE; - if (xml_bvalue(node, "far", false)) - sp->sptyp |= FARCASTING; - if (xml_bvalue(node, "variable", false)) - sp->sptyp |= SPELLLEVEL; - - if (xml_bvalue(node, "globaltarget", false)) - sp->sptyp |= GLOBALTARGET; /* target need not be in same region */ - if (xml_bvalue(node, "buildingtarget", false)) - sp->sptyp |= BUILDINGSPELL; - if (xml_bvalue(node, "shiptarget", false)) - sp->sptyp |= SHIPSPELL; - if (xml_bvalue(node, "unittarget", false)) - sp->sptyp |= UNITSPELL; - if (xml_bvalue(node, "regiontarget", false)) - sp->sptyp |= REGIONSPELL; - - k = xml_ivalue(node, "combat", 0); - if (k >= 0 && k <= 3) { - sp->sptyp |= modes[k]; - } - /* reading eressea/spells/spell/resource */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "resource", xpath); - if (result->nodesetval->nodeNr) { - sp->components = - (spell_component *)malloc(sizeof(spell_component) * - (result->nodesetval->nodeNr + 1)); - sp->components[result->nodesetval->nodeNr].type = 0; - } - for (component = sp->components, k = 0; k != result->nodesetval->nodeNr; - ++k) { - const resource_type *rtype; - xmlNodePtr node = result->nodesetval->nodeTab[k]; - propValue = xmlGetProp(node, BAD_CAST "name"); - assert(propValue); - rtype = rt_get_or_create((const char *)propValue); - component->type = rtype; - xmlFree(propValue); - component->amount = xml_ivalue(node, "amount", 1); - component->cost = SPC_FIX; - propValue = xmlGetProp(node, BAD_CAST "cost"); - if (propValue != NULL) { - if (strcmp((const char *)propValue, "linear") == 0) { - if ((sp->sptyp&SPELLLEVEL) == 0) { - log_error("spell '%s' has linear cost but fixed level\n", sp->sname); - } - component->cost = SPC_LINEAR; - } - else if (strcmp((const char *)propValue, "level") == 0) { - if ((sp->sptyp&SPELLLEVEL) == 0) { - log_error("spell '%s' has levelled cost but fixed level\n", sp->sname); - } - component->cost = SPC_LEVEL; - } - xmlFree(propValue); - } - component++; - } - xmlXPathFreeObject(result); - } - } - - xmlXPathFreeObject(spells); - - xmlXPathFreeContext(xpath); - - return result; -} - -static void parse_ai(race * rc, xmlNodePtr node) -{ - xmlChar *propValue; - - propValue = xmlGetProp(node, BAD_CAST "scare"); - if (propValue) { - rc_set_param(rc, "scare", (const char *)propValue); - xmlFree(propValue); - } - rc->splitsize = xml_ivalue(node, "splitsize", 0); - if (xml_bvalue(node, "killpeasants", false)) - rc->flags |= RCF_KILLPEASANTS; - if (xml_bvalue(node, "moverandom", false)) - rc->flags |= RCF_MOVERANDOM; - if (xml_bvalue(node, "learn", false)) - rc->flags |= RCF_LEARN; - if (xml_bvalue(node, "moveattack", false)) - rc->flags |= RCF_ATTACK_MOVED; -} - -static int parse_races(xmlDocPtr doc) -{ - xmlXPathContextPtr xpath = xmlXPathNewContext(doc); - xmlXPathObjectPtr races; - int results = 0; - - /* reading eressea/races/race */ - races = xmlXPathEvalExpression(BAD_CAST "/eressea/races/race", xpath); - if (races->nodesetval) { - xmlNodeSetPtr nodes = races->nodesetval; - int i; - results += nodes->nodeNr; - for (i = 0; i != nodes->nodeNr; ++i) { - xmlNodePtr node = nodes->nodeTab[i]; - xmlNodePtr child; - xmlChar *propValue; - race *rc, *frc = 0; - xmlXPathObjectPtr result; - int k, study_speed_base, attacks; - struct att *attack; - skill_t sk; - - propValue = xmlGetProp(node, BAD_CAST "name"); - assert(propValue != NULL); - rc = rc_get_or_create((const char *)propValue); - xmlFree(propValue); - - propValue = xmlGetProp(node, BAD_CAST "damage"); - assert(propValue != NULL); - rc->def_damage = str_strdup((const char *)propValue); - xmlFree(propValue); - - rc->magres = frac_make(xml_ivalue(node, "magres", 100), 100); - rc->healing = (int)(xml_fvalue(node, "healing", rc->healing) * 100); /* TODO: store as int in XML */ - rc->maxaura = (int)(xml_fvalue(node, "maxaura", rc->maxaura) * 100); /* TODO: store as int in XML */ - rc->regaura = (float)xml_fvalue(node, "regaura", rc->regaura); - rc->recruitcost = xml_ivalue(node, "recruitcost", rc->recruitcost); - rc->maintenance = xml_ivalue(node, "maintenance", rc->maintenance); - rc->weight = xml_ivalue(node, "weight", rc->weight); - rc->capacity = xml_ivalue(node, "capacity", rc->capacity); - rc->income = xml_ivalue(node, "income", rc->income); - rc->speed = (float)xml_fvalue(node, "speed", rc->speed); - rc->hitpoints = xml_ivalue(node, "hp", rc->hitpoints); - rc->armor = xml_ivalue(node, "ac", rc->armor); - study_speed_base = xml_ivalue(node, "studyspeed", 0); - if (study_speed_base != 0) { - for (sk = 0; sk < MAXSKILLS; ++sk) { - set_study_speed(rc, sk, study_speed_base); - } - } - - rc->at_default = (char)xml_ivalue(node, "unarmedattack", rc->at_default); - rc->df_default = (char)xml_ivalue(node, "unarmeddefense", rc->df_default); - rc->at_bonus = (char)xml_ivalue(node, "attackmodifier", rc->at_bonus); - rc->df_bonus = (char)xml_ivalue(node, "defensemodifier", rc->df_bonus); - - if (!xml_bvalue(node, "teach", true)) - rc->flags |= RCF_NOTEACH; - if (!xml_bvalue(node, "cansteal", true)) - rc->flags |= RCF_NOSTEAL; - if (!xml_bvalue(node, "learn", true)) - rc->flags |= RCF_NOLEARN; - if (xml_bvalue(node, "playerrace", false)) { - assert(rc->recruitcost == 0); - rc->flags |= RCF_PLAYABLE; - } - if (xml_bvalue(node, "scarepeasants", false)) - rc->flags |= RCF_SCAREPEASANTS; - if (xml_bvalue(node, "cansail", true)) - rc->flags |= RCF_CANSAIL; - if (xml_bvalue(node, "cannotmove", false)) - rc->flags |= RCF_CANNOTMOVE; - if (xml_bvalue(node, "fly", false)) - rc->flags |= RCF_FLY; - if (xml_bvalue(node, "invisible", false)) - rc->flags |= RCF_INVISIBLE; - if (xml_bvalue(node, "coastal", false)) - rc->flags |= RCF_COASTAL; - if (xml_bvalue(node, "unarmedguard", false)) - rc->flags |= RCF_UNARMEDGUARD; - if (xml_bvalue(node, "swim", false)) - rc->flags |= RCF_SWIM; - if (xml_bvalue(node, "walk", false)) - rc->flags |= RCF_WALK; - if (xml_bvalue(node, "horse", false)) - rc->flags |= RCF_HORSE; - if (xml_bvalue(node, "desert", false)) - rc->flags |= RCF_DESERT; - if (xml_bvalue(node, "absorbpeasants", false)) - rc->flags |= RCF_ABSORBPEASANTS; - if (xml_bvalue(node, "noheal", false)) - rc->flags |= RCF_NOHEAL; - if (xml_bvalue(node, "noweapons", false)) - rc->flags |= RCF_NOWEAPONS; - if (xml_bvalue(node, "shapeshift", false)) - rc->flags |= RCF_SHAPESHIFT; - if (xml_bvalue(node, "shapeshiftany", false)) - rc->flags |= RCF_SHAPESHIFTANY; - if (xml_bvalue(node, "illusionary", false)) - rc->flags |= RCF_ILLUSIONARY; - if (xml_bvalue(node, "undead", false)) - rc->flags |= RCF_UNDEAD; - if (xml_bvalue(node, "dragon", false)) - rc->flags |= RCF_DRAGON; - if (xml_bvalue(node, "shipspeed", false)) - rc->flags |= RCF_SHIPSPEED; - - if (xml_bvalue(node, "giveperson", false)) - rc->ec_flags |= ECF_GIVEPERSON; - if (xml_bvalue(node, "giveunit", false)) - rc->ec_flags |= ECF_GIVEUNIT; - if (xml_bvalue(node, "getitem", false)) - rc->ec_flags |= ECF_GETITEM; - if (xml_bvalue(node, "recruitethereal", false)) - rc->ec_flags |= ECF_REC_ETHEREAL; - if (xml_bvalue(node, "recruitunlimited", false)) - rc->ec_flags |= ECF_REC_UNLIMITED; - if (xml_bvalue(node, "stonegolem", false)) - rc->ec_flags |= ECF_STONEGOLEM; - if (xml_bvalue(node, "irongolem", false)) - rc->ec_flags |= ECF_IRONGOLEM; - - if (xml_bvalue(node, "equipment", false)) - rc->battle_flags |= BF_EQUIPMENT; /* TODO: invert this flag, so rc_get_or_create gets simpler */ - if (xml_bvalue(node, "noblock", false)) - rc->battle_flags |= BF_NOBLOCK; - if (xml_bvalue(node, "invinciblenonmagic", false)) - rc->battle_flags |= BF_INV_NONMAGIC; - if (xml_bvalue(node, "resistbash", false)) - rc->battle_flags |= BF_RES_BASH; - if (xml_bvalue(node, "resistcut", false)) - rc->battle_flags |= BF_RES_CUT; - if (xml_bvalue(node, "resistpierce", false)) - rc->battle_flags |= BF_RES_PIERCE; - if (xml_bvalue(node, "noattack", false)) - rc->battle_flags |= BF_NO_ATTACK; - - rc->recruit_multi = 1.0; - for (child = node->children; child; child = child->next) { - if (strcmp((const char *)child->name, "ai") == 0) { - parse_ai(rc, child); - } - else if (strcmp((const char *)child->name, "param") == 0) { - xmlChar *propName = xmlGetProp(child, BAD_CAST "name"); - xmlChar *propValue = xmlGetProp(child, BAD_CAST "value"); - rc_set_param(rc, (const char *)propName, (const char *)propValue); - xmlFree(propName); - xmlFree(propValue); - } - } - - /* reading eressea/races/race/skill */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "skill", xpath); - memset(rc->bonus, 0, sizeof(rc->bonus)); - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - int mod = xml_ivalue(node, "modifier", 0); - int speed = xml_ivalue(node, "speed", study_speed_base); - - propValue = xmlGetProp(node, BAD_CAST "name"); - assert(propValue != NULL); - sk = findskill((const char *)propValue); - if (sk != NOSKILL) { - rc->bonus[sk] = (char)mod; - if (speed) { - set_study_speed(rc, sk, speed); - } - } - else { - log_error("unknown skill '%s' in race '%s'\n", (const char *)propValue, rc->_name); - } - xmlFree(propValue); - } - xmlXPathFreeObject(result); - - /* reading eressea/races/race/familiar */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "familiar", xpath); - if (result->nodesetval->nodeNr > MAXMAGIETYP) { - log_error("race %s has %d potential familiars", rc->_name, result->nodesetval->nodeNr); - } - else { - for (k = 0; k != MAXMAGIETYP; ++k) { - if (k < result->nodesetval->nodeNr) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - - propValue = xmlGetProp(node, BAD_CAST "race"); - assert(propValue != NULL); - frc = rc_get_or_create((const char *)propValue); - frc->flags |= RCF_FAMILIAR; - rc->familiars[k] = frc; - xmlFree(propValue); - } - else { - rc->familiars[k] = frc; - } - } - } - xmlXPathFreeObject(result); - - /* reading eressea/races/race/attack */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "attack", xpath); - attack = rc->attack; - attacks = 0; - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - while (attack->type != AT_NONE) { - ++attack; - if (attacks++ >= RACE_ATTACKS) { - log_error("too many attacks for race '%s'\n", rc->_name); - assert(!"aborting"); - } - } - - propValue = xmlGetProp(node, BAD_CAST "damage"); - if (propValue != NULL) { - attack->data.dice = str_strdup((const char *)propValue); - xmlFree(propValue); - } - else { - attack->data.sp = xml_spellref(node, "spell"); - if (attack->data.sp) { - attack->level = xml_ivalue(node, "level", 0); - if (attack->level <= 0) { - log_error("magical attack '%s' for race '%s' needs a level: %d\n", - spellref_name(attack->data.sp), rc->_name, attack->level); - } - } - } - attack->type = xml_ivalue(node, "type", 0); - attack->flags = xml_ivalue(node, "flags", 0); - } - xmlXPathFreeObject(result); - } - } - xmlXPathFreeObject(races); - - xmlXPathFreeContext(xpath); - - return results; -} - -static int parse_messages(xmlDocPtr doc) -{ - xmlXPathContextPtr xpath; - xmlXPathObjectPtr messages; - xmlNodeSetPtr nodes; - int i, results; - - xpath = xmlXPathNewContext(doc); - - /* reading eressea/messages/message */ - messages = - xmlXPathEvalExpression(BAD_CAST "/eressea/messages/message", xpath); - nodes = messages->nodesetval; - results = nodes->nodeNr; - for (i = 0; i != nodes->nodeNr; ++i) { - xmlNodePtr node = nodes->nodeTab[i]; - const char *default_section = "events"; - xmlChar *propSection; - xmlChar *propValue; - xmlXPathObjectPtr result; - int nargs = 0; - char **argv = NULL; - const message_type *mtype; - - /* arguments */ - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "type/arg", xpath); - if (result->nodesetval && result->nodesetval->nodeNr > 0) { - int k; - nargs = result->nodesetval->nodeNr; - argv = malloc(sizeof(char *) * (nargs + 1)); - for (k = 0; k != nargs; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - char zBuffer[128]; - xmlChar *propName, *propType; - - propName = xmlGetProp(node, BAD_CAST "name"); - propType = xmlGetProp(node, BAD_CAST "type"); - sprintf(zBuffer, "%s:%s", (const char *)propName, - (const char *)propType); - xmlFree(propName); - xmlFree(propType); - argv[k] = str_strdup(zBuffer); - } - argv[nargs] = NULL; - } - xmlXPathFreeObject(result); - - /* add the messagetype */ - propSection = xmlGetProp(node, BAD_CAST "section"); - if (propSection == NULL) { - propSection = BAD_CAST default_section; - } - - propValue = xmlGetProp(node, BAD_CAST "name"); - mtype = mt_find((const char *)propValue); - if (mtype == NULL) { - mtype = mt_create(mt_new((const char *)propValue, (const char *)propSection), (const char **)argv, nargs); - } - else { - assert(argv != NULL || !"cannot redefine arguments of message now"); - } - xmlFree(propValue); - - if (propSection != BAD_CAST default_section) { - xmlFree(propSection); - } - - /* register the type for CR and NR */ - crt_register(mtype); - nrt_register(mtype); - - /* let's clean up the mess */ - if (argv != NULL) { - int k; - for (k = 0; argv[k] != NULL; ++k) { - free(argv[k]); - } - free(argv); - } - } - - xmlXPathFreeObject(messages); - - xmlXPathFreeContext(xpath); - return results; -} - -void register_xmlreader(void) -{ -#ifndef _MSC_VER /* gcc and clang complain about unused function */ - xml_register_callback(parse_resources); - xml_register_callback(parse_buildings); - xml_register_callback(parse_ships); - xml_register_callback(parse_spellbooks); - xml_register_callback(parse_spells); - xml_register_callback(parse_races); -#endif - - - xml_register_callback(parse_messages); -} diff --git a/src/xmlreader.h b/src/xmlreader.h deleted file mode 100644 index 290b785c3..000000000 --- a/src/xmlreader.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -+-------------------+ -| | Enno Rehling -| Eressea PBEM host | Christian Schlittchen -| (c) 1998 - 2007 | Katja Zedel -| | Henning Peters -+-------------------+ - -This program may not be used, modified or distributed -without prior permission by the authors of Eressea. -*/ - -#ifndef H_KRNL_XMLREADER_H -#define H_KRNL_XMLREADER_H - -struct spell; - -#ifdef __cplusplus -extern "C" { -#endif - extern void register_xmlreader(void); - - /* game-specific callbacks */ - extern void(*set_spelldata_cb) (struct spell * sp); -#ifdef __cplusplus -} -#endif -#endif From bbae56633bed1f885f79176062f94e094e08ff40 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 18 May 2018 21:18:55 +0200 Subject: [PATCH 54/59] rules was part of convert, and we do never finished that branch. --- src/kernel/CMakeLists.txt | 1 - src/kernel/rules.c | 12 ------------ src/kernel/rules.h | 5 ----- 3 files changed, 18 deletions(-) delete mode 100644 src/kernel/rules.c delete mode 100644 src/kernel/rules.h diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index 59b8cb806..86c2fb90c 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -69,7 +69,6 @@ pool.c race.c region.c resources.c -rules.c save.c ship.c skills.c diff --git a/src/kernel/rules.c b/src/kernel/rules.c deleted file mode 100644 index c7499fe0c..000000000 --- a/src/kernel/rules.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include "rules.h" - -int write_rules(const char *filename) { - return -1; -} - -int read_rules(const char *filename) -{ - return -1; -} - diff --git a/src/kernel/rules.h b/src/kernel/rules.h deleted file mode 100644 index 98f0bf240..000000000 --- a/src/kernel/rules.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -int read_rules(const char *filename); -int write_rules(const char * filename); - From c11a0208460ff3ffed954ea086771954a6cd2de1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 18 May 2018 21:24:08 +0200 Subject: [PATCH 55/59] remove the text from messages.xml --- res/core/messages.xml | 1878 ----------------------------------------- src/exparse.c | 2 +- 2 files changed, 1 insertion(+), 1879 deletions(-) diff --git a/res/core/messages.xml b/res/core/messages.xml index b8f8125dc..757243d9f 100644 --- a/res/core/messages.xml +++ b/res/core/messages.xml @@ -2,58 +2,32 @@ - Es ist Winter, und Insekten können nur in Wüsten oder mit Hilfe des Nestwärme-Tranks Personen rekrutieren. - It is winter, and insects can only recruit in deserts or with the aid of nestwarmth potions. - Es ist Spätherbst, und diese Woche ist die letzte vor dem Winter, in der Insekten rekrutieren können. - It is the last week before winter in which insects can still recruit. - Bitte denke daran, deine Befehle mit dem Betreff - $subject an $email zu senden. - Remember to send your orders to - $email with the subject ${subject}. - "$unit($unit): '$command' - Dieser Befehl ist unbekannt." - "$unit($unit): '$command' - Parse error, unknown command." - Die Region ist verwüstet, der Boden karg. - The region is ravaged, the ground infertile. - 'Ho ho ho!' Ein dicker Gnom fliegt auf einem von - 8 Jungdrachen gezogenen Schlitten durch die Nacht und vermacht Deiner - Partei eine $resource($item,1). (Um diesen Gegenstand einer Einheit zu geben, gib - ihr den Befehl 'BEANSPRUCHE 1 $resource($item,1)'). - 'Ho ho ho!' A fat little gnome Gnom on a sled - pulled by 8 young dragons flies through the stary night and presents - your faction with a $resource($item,1). - 'Ho ho ho!' Ein dicker Gnom fliegt auf einem von - 8 Jungdrachen gezogenen Schlitten durch die Nacht und vermacht Deiner - Partei einen $resource($item,1). (Um diesen Gegenstand einer Einheit zu geben, gib - ihr den Befehl 'BEANSPRUCHE 1 $resource($item,1)'). - 'Ho ho ho!' A fat little gnome Gnom on a sled - pulled by 8 young dragons flies through the stary night and presents - your faction with a $resource($item,1). @@ -62,8 +36,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Ungültige Zielregion." - "$unit($unit) in $region($region): '$order($command)' - invalid target region." @@ -72,8 +44,6 @@ - "$unit($unit) in $region($region): '$order($command)' - keine Richtung angegeben." - "$unit($unit) in $region($region): '$order($command)' - no direction was specified." @@ -82,8 +52,6 @@ - "$unit($unit) in $region($region): '$order($command)' - In der Zielregion befinden sich noch Einheiten." - "$unit($unit) in $region($region): '$order($command)' - There are units in the target region." @@ -92,8 +60,6 @@ - $unit($owner) bittet $unit($unit), $ship($ship) zu verlassen. - $unit($owner) asks $unit($unit) to leave $ship($ship). @@ -101,15 +67,11 @@ - $unit($owner) bittet $unit($unit), $building($building) zu verlassen. - $unit($owner) asks $unit($unit) to leave $building($building). - "Einheiten können die folgenden Gegenstände beanspruchen: $resources($items)" - "Units can claim the following items: $resources($items)" @@ -117,67 +79,45 @@ - "$if($isnull($region),"Es","In $region($region)") wurde$if($eq($number,1),"","n") $int($number) $race($race,$number) gesichtet." - "$if($isnull($region),"","In $region($region), ")$int($number) $race($race,$number) were discovered." - "$unit($mage) läßt einen Teil seiner selbst in die Erde fliessen. Die Bäume, die Transformation überlebt haben, erscheinen nun viel kräftiger." - "The power of $unit($mage) flows into the ground and the trees which survived the spell appear much stronger now." - "$unit($mage) beschwört einen Luftgeist, der die $ship($ship) in die Wolken hebt." - "$unit($mage) summons a wind spirit that lifts the $ship($ship) into the clouds." - "$unit($mage) beschwört einen Schleier der Verwirrung." - "$unit($mage) summons a fog of confusion." - Eine Feuerwand blockiert die Ein- und Ausreise. ($int36($id)) - A wall of fire blocks entry and exit. ($int36($id)) - Der Magier besitzt die Gabe des Chaos. ($int36($id)) - The magician possesses the gift of Chaos. ($int36($id)) - Dieser mächtige Bann scheint die Einheit ihres freien Willens zu berauben. Solange der Zauber wirkt, wird sie nur den Befehlen ihres neuen Herrn gehorchen. ($int36($id)) - This powerful curse appears to rob the unit of its free will. As long as the curse is active, it will only obey the orders of its new lord. ($int36($id)) - Dieser Beeinflussungszauber scheint die Einheit einem ganz bestimmten Volk wohlgesonnen zu machen. ($int36($id)) - This enchantment appears to make the unit well-disposed towards a particular faction. ($int36($id)) - Der Mahlstrom in dieser Region wird alle Schiffe, die in seinen Sog geraten, schwer beschädigen. ($int36($id)) - The maelstrom in this area will heavily damage all ships coming into its wake. ($int36($id)) - Heilung ist in dieser Region magisch beeinflusst. ($int36($id)) - Healing in this region is affected by magic. ($int36($id)) - Dieses Schiff hat sich verfahren. ($int36($id)) - This ship has lost its path. ($int36($id)) @@ -185,151 +125,113 @@ - "$unit($unit) ist im Traum eine Fee erschienen. ($int36($id))" - "In a dream, a fairy appears to $unit($unit). ($int36($id))" - "$unit($unit) wird von bösen Alpträumen geplagt. ($int36($id))" - "$unit($unit) is haunted by terrbile nightmares. ($int36($id))" - "$unit($unit) wird von einem glitzernden Funkenregen umgeben. ($int36($id))" - "$unit($unit) is surrounded by a shower of glittering sparkles. ($int36($id))" - "Ein schimmernder Lichterkranz umgibt $unit($unit). ($int36($id))" - "A circle of shimmering lights surrounds $unit($unit). ($int36($id))" - "Eine Melodie erklingt, und $unit($unit) tanzt bis spät in die Nacht hinein. ($int36($id))" - "A haunting melody fills the air, and $unit($unit) dances until late into the night. ($int36($id))" - "$unit($unit) findet eine kleine Flöte, die eine wundersame Melodie spielt. ($int36($id))" - "$unit($unit) finds a small flute that plays a beautiful melody. ($int36($id))" - "Die Frauen des nahegelegenen Dorfes bewundern $unit($unit) verstohlen. ($int36($id))" - "The women of the nearby village cast furtive looks at $unit($unit). ($int36($id))" - "Eine Gruppe vorbeiziehender Bergarbeiter rufen $unit($unit) eindeutig Zweideutiges nach. ($int36($id))" - "A group of passing miners makes passes at $unit($unit). ($int36($id))" - "$unit($unit) bekommt von einer Schlange einen Apfel angeboten. ($int36($id))" - "A large green snake offers $unit($unit) a fine-looking apple. ($int36($id))" - "A spell is deflecting magical energies and weakening all other spells cast in the region. ($int36($id))" - "Dieser Zauber scheint magische Energien irgendwie abzuleiten und so alle in der Region gezauberten Sprüche in ihrer Wirkung zu schwächen oder ganz zu verhindern. ($int36($id))" - "Ein Einhorn berührt $unit($unit) mit seinem Horn und verschwindet kurz darauf im Unterholz. ($int36($id))" - "A unicorn touches $unit($unit) with its horn and vanishes into the forest quickly after. ($int36($id))" - "Vogelzwitschern begleitet $unit($unit) auf all seinen Wegen. ($int36($id))" - "Bird songs follow $unit($unit) on all his travels. ($int36($id))" - "Leuchtende Blumen erblühen rund um das Lager von $unit($unit). ($int36($id))" - "Brightly coloured flowers pop up all around $unit($unit)'s camp. ($int36($id))" - "Ãœber $unit($unit) zieht eine Gruppe Geier ihre Kreise. ($int36($id))" - "A group of vultures circles above $unit($unit). ($int36($id))" - "Der Kopf von $unit($unit) hat sich in einen grinsenden Totenschädel verwandelt. ($int36($id))" - "The head of $unit($unit) has turned into a madly grinning skull. ($int36($id))" - "Ratten folgen $unit($unit) auf Schritt und Tritt. ($int36($id))" - "Rats follow $unit($unit)'s every step. ($int36($id))" - "Pestbeulen befallen den Körper von $unit($unit). ($int36($id))" - "The body of $unit($unit) is disfigured by hideous boils. ($int36($id))" - "Eine dunkle Fee erscheint $unit($unit) im Schlaf. Sie ist von schauriger Schönheit. ($int36($id))" - "A dark and mysterious fairy appears before $unit($unit). She is of bewitching beauty. ($int36($id))" - "Fäulnisgeruch dringt $unit($unit) aus allen Körperöffnungen. ($int36($id))" - "The stench of decay is poring from all the orifices of $unit($unit). ($int36($id))" @@ -337,8 +239,6 @@ - "$unit($unit) scheint $faction($faction) zu mögen. ($int36($id))" - "$unit($unit) likes $faction($faction). ($int36($id))" @@ -346,8 +246,6 @@ - "$unit($unit) scheint $race($race, 0) zu mögen. ($int36($id))" - "$unit($unit) seems to like $race($race, 0). ($int36($id))" @@ -355,8 +253,6 @@ - "$unit($unit) ist ungewöhnlich ungeschickt in $skill($skill). ($int36($id))" - "$unit($unit) has some troubles with $skill($skill). ($int36($id))" @@ -364,8 +260,6 @@ - "$unit($unit) ist ungewöhnlich geschickt in $skill($skill). ($int36($id))" - "$unit($unit) is incredibly skilled at $skill($skill). ($int36($id))" @@ -373,8 +267,6 @@ - "$unit($unit) wird noch $int($duration) $if($eq($duration,1), "Woche", "Wochen") unter unserem Bann stehen. ($int36($id))" - "$unit($unit) will be under our influence for $int($duration) more $if($eq($duration,1), "week", "weeks"). ($int36($id))" @@ -383,8 +275,6 @@ - "$int($number) $if($eq($number,1), "Person", "Personen") von $unit($unit) $if($eq($number,1), "ist", "sind") noch $int($duration) $if($eq($duration,1), "Woche", "Wochen") beschleunigt. ($int36($id))" - "$int($number) $if($eq($number,1), "member", "members") of $unit($unit) $if($eq($number,1), "is", "are") accelerated for $int($duration) more $if($eq($duration,1), "week", "weeks"). ($int36($id))" @@ -392,270 +282,196 @@ - "$int($number) $if($eq($number,1), "Person", "Personen") von $unit($unit) $if($eq($number,1), "fühlt", "fühlen") sich vor Kälte geschützt. ($int36($id))" - "$int($number) $if($eq($number,1), "member", "members") of $unit($unit) $if($eq($number,1), "is", "are") protected from the cold. ($int36($id))" - "Ein unbekannter Zauber liegt auf dem Schiff. ($int36($id))" - "An unknown spell lies on this ship. ($int36($id))" - "Ein unbekannter Zauber liegt auf der Einheit. ($int36($id))" - "An unknown spell lies on this unit. ($int36($id))" - "Ein unbekannter Zauber liegt auf dem Gebäude. ($int36($id))" - "An unknown spell lies on this building. ($int36($id))" - "Ein unbekannter Zauber liegt auf der Region. ($int36($id))" - "An unknown spell lies on this region. ($int36($id))" - "Eine Wolke negativer Energie liegt über der Region. ($int36($id))" - "A fog of negative energy enshrouds the region. ($int36($id))" - "Die Leute strotzen nur so vor Kraft. ($int36($id))" - "Testosterone levels are at an all-time high. ($int36($id))" - "$unit($unit) wird von einem Alp geritten. ($int36($id))" - "$unit($unit) is chased by a nightmare. ($int36($id))" - "$unit($unit) stürzt sich von einem amourösen Abenteuer ins nächste. ($int36($id))" - "$unit($unit) goes from one amourous adventure to another. ($int36($id))" - "$unit($unit) kann sich kaum konzentrieren. ($int36($id))" - "$unit($unit) can hardly focus on anything. ($int36($id))" - "Die Ausrüstung von $unit($unit) scheint unsichtbar. ($int36($id))" - "$unit($unit)'s equipment is invisible. ($int36($id))" - "Die natürliche Widerstandskraft gegen Verzauberung ist gestärkt. ($int36($id))" - "The magical resistance has been strengthened. ($int36($id))" - "Die natürliche Widerstandskraft gegen Verzauberung ist gestärkt. ($int36($id))" - "The magical resistance has been strengthened. ($int36($id))" - "Die natürliche Widerstandskraft gegen Verzauberung bestimmter Einheiten in dieser Region wurde gestärkt. ($int36($id))" - "The magical resistance of some units in this region was boosted. ($int36($id))" - "Die natürliche Widerstandskraft gegen Verzauberung bestimmter Einheiten in dieser Region wurde geschwächt. ($int36($id))" - "The magical resistance of some units in this region was weakened. ($int36($id))" - "Diese Mauern wirken, als wären sie direkt aus der Erde gewachsen und nicht erbaut. ($int36($id))" - "These walls appear to have grown straight out of the earth. ($int36($id))" - "Ein magischer Schimmer liegt auf diesen Mauern. ($int36($id))" - "A magical shimmer lies on these walls. ($int36($id))" - "Die Straßen sind erstaunlich trocken und gut begehbar, doch an manchen Stellen bilden sich wieder die erste Schlammlöcher. ($int36($id))" - "The roads are extremely dry and well-kept, but some areas show the first signs of potholes reappearing. ($int36($id))" - "Die Straßen sind erstaunlich trocken und gut begehbar. ($int36($id))" - "The roads are extremely dry and well-kept. ($int36($id))" - "Albträume plagen die Leute. ($int36($id))" - "Nightmares plague the population. ($int36($id))" - "Die Leute haben schöne Träume. ($int36($id))" - "The people in this region have sweet dreams. ($int36($id))" - "Diese Region wurde von den Göttern verflucht. Das Meer ist eine ekelige Brühe, braunschwarze, stinkende Gase steigen aus den unergründlichen Tiefen hervor, und untote Seeungeheuer, Schiffe zerfressend und giftige grüne Galle geifernd, sind der Schrecken aller Seeleute, die diese Gewässer durchqueren. Niemand kann hier lange überleben. ($int36($id))" - "This region was cursed by the gods. The sea is a foul cesspool, noxious gases rise from the deep, undead seamonsters attack all ships. Noone can live here for long. ($int36($id))" - "Diese Region wurde von den Göttern verflucht. Stinkende Nebel ziehen über die tote Erde und furchtbare Kreaturen ziehen über das Land. Die Brunnen sind vergiftet, und die wenigen essbaren Früchte sind von einem rosa Pilz überzogen. Niemand kann hier lange überleben. ($int36($id))" - "This region was cursed by the gods. Stinking vapors billow over the dead ground and hideous creatures move about the country. The wells are poisened and the edible plants are covered by a pink fungus. Noone can live here for long. ($int36($id))" - "Ein Schleier der Verwirrung liegt über der Region. ($int36($id))" - "A veil of confusion lies over the region. ($int36($id))" - "In der Region treibt ein Giftelementar sein Unwesen. ($int36($id))" - "A poison elemental is spreading pestilence and death. ($int36($id))" - "Die ganze Region ist von einer friedlichen Stimmung erfasst. ($int36($id))" - "Everyone in this region seems to be in a peacful mood. ($int36($id))" - "Es herrscht eine fröhliche und ausgelassene Stimmung. ($int36($id))" - "Everyone in this region seems to be having a very good time. ($int36($id))" - "Die Bauern sind unzufrieden. ($int36($id))" - "The peasants are upset. ($int36($id))" - "Alle Leute in der Region haben Schlafstörungen. ($int36($id))" - "People in this region suffer from insomnia. ($int36($id))" - "In dieser Gegend herrscht eine Dürre. ($int36($id))" - "This region was hit by a drought. ($int36($id))" - "In dieser Gegend steht das Korn besonders gut im Feld. ($int36($id))" - "The grain in this region is especially healthy. ($int36($id))" - "Die Winde scheinen dieses Schiff besonders zu beguenstigen. ($int36($id))" - "The winds seem to favor this ship. ($int36($id))" - "Untote schrecken vor dieser Region zurück. ($int36($id))" - "The undead turn away from this region. ($int36($id))" - "Der Zahn der Zeit kann diesen Mauern nichts anhaben. ($int36($id))" - "Time cannot touch these walls. ($int36($id))" - "Dichte Nebel bedecken diese Woche die Region. Keine Einheit schafft es, diese Nebel zu durchdringen und die Region zu verlassen. ($int36($id))" - "Heavy fog makes it impossible to leave the region. ($int36($id))" - "$unit($unit) setzt ein Sonnensegel. Die Geschwindigkeit des Schiffes erhöht um $int($speed)." - "$unit($unit) sets a solar sail. The ship's speed is increased by $int($speed)." - "Interner Fehler: Meldung '$name' nicht definiert." - "Internal Error: Message '$name' is undefined." @@ -664,8 +480,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Interner Fehler: Meldung '$name' nicht definiert." - "$unit($unit) in $region($region): '$order($command)' - Internal Error: Message '$name' is undefined." @@ -673,8 +487,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier ist kein passendes Schloss." - "$unit($unit) in $region($region): '$order($command)' - No fitting lock can be found here." @@ -682,8 +494,6 @@ - "$unit($unit) öffnet eines der Schlösser in $region($region) mit $if($eq($key,1),"dem Achatenen Schlüssel","dem Saphirnen Schlüssel")." - "$unit($unit) unlocks one of the locks in $region($region) with $if($eq($key,1),"the Agate Key","the Sapphire Key")." @@ -691,31 +501,23 @@ - "$unit($unit) verschließt eines der Schlösser in $region($region) mit $if($eq($key,1),"dem Achatenen Schlüssel","dem Saphirnen Schlüssel")." - "$unit($unit) locks one of the locks in $region($region) with $if($eq($key,1),"the Agate Key","the Sapphire Key")." - "$unit($unit) in $region($region) verwandelt sich in ein Werwesen." - "$unit($unit) in $region($region) becomes a lycantrope." - "SIEG! $if($eq($n,1), "Die Partei $winners hat", "Die Parteien $winners haben") die Siegbedingung für die erforderliche Zeit erfüllt. Das Spiel ist damit beendet." - "VICTORY! $if($eq($n,1), "The faction $winners has", "The factions $winners have") fulfilled the victory condition for the necessary time. The game is over." - "Achtung: $faction($faction) hat die Siegbedingungen erfüllt und wird in $if($eq($remain,1),"einer Woche","$int($remain) Wochen") zum Sieger erklärt werden." - "Attention: $faction($faction) has fulfilled the victory condition and will be declared winner in $if($eq($remain,1),"one week","$int($remain) weeks")." @@ -723,8 +525,6 @@ - "$unit($unit) wurde in $region($region) von einem GM gelöscht: \"$string\"." - "$unit($unit) in $region($region) was removed by a GM: \"$string\"." @@ -732,14 +532,10 @@ - "$resource($item,1) (Gewicht: $weight($weight)): $description" - "$resource($item,1) (weight: $weight($weight)): $description" - "Ein Hauch des Lebens liegt über der Welt und alle Wesen fühlen sich frisch und erholt." - "Life itself touches the world and all beings are healed." @@ -747,16 +543,12 @@ - "$unit($unit) hat Glück und findet einen Hort von $int($amount) $resource($item,$amount)." - "$unit($unit) luckily finds a cache of $int($amount) $resource($item,$amount)." - "$int36($unit.id($unit))/$int($index) erzielt einen kritischen Treffer." - "$int36($unit.id($unit))/$int($index) does critical damage." @@ -765,8 +557,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) muß mindestens 2 Stufen besser sein als $unit($student)." - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) needs to be at least 2 levels better than $unit($student)." @@ -775,8 +565,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($student) lernt nicht." - "$unit($unit) in $region($region): '$order($command)' - $unit($student) is not learning." @@ -785,23 +573,17 @@ - "$unit($unit) in $region($region): '$order($command)' - Dafür braucht die Einheit $resources($required)." - "$unit($unit) in $region($region): '$order($command)' - For this, the unit needs $resources($required)." - $trailto($region) - $trailto($region) - "Deine Partei hat $int($units) Migranten und kann maximal $int($maxunits) Migranten aufnehmen." - "Your faction has $int($units) migrants out of a possible total of $int($maxunits)." @@ -810,16 +592,12 @@ - "Seit $int($age) Wochen Mitglied der Allianz '$name ($int36($id))', angeführt von $faction($leader)." - "Member of '$name ($int36($id))' for $int($age) weeks, led by $faction($leader)." - "Deine Partei hat $int($units) Helden und kann maximal $int($maxunits) Helden ernennen." - "Your faction has promoted $int($units) heroes out of a possible total of $int($maxunits)." @@ -827,180 +605,132 @@ - "Deine Partei hat $int($population) Personen in $int($units) von maximal $int($limit) Einheiten." - "Your faction has $int($population) people in $int($units) of $int($limit) possible units." - "Statistik für $region($region):" - "Statistics for $region($region):" - "Unterhaltung: max. $int($max) Silber" - "entertainment: max. $int($max) silver" - "Moral der Bauern: $int($morale)" - "peasant morale: $int($morale)" - "Luxusgüter zum angegebenen Preis: $int($max)" - "luxury goods at this price: $int($max)" - "Lohn für Arbeit: $int($max) Silber" - "worker salary: $int($max) silver" - "Bauerneinnahmen: $int($max) Silber" - "peasant wages: $int($max) silver" - "Personen: $int($max)" - "people: $int($max)" - "Rekruten: max. $int($max) Bauern" - "recruits: $int($max) peasants" - "Deine Partei hat ${score} Punkte. Der Durchschnitt für Parteien ähnlichen Alters ist ${average} Punkte." - "Your faction has a score of ${score}. The average score for similar factions is ${average}." - "Report für $game, $date" - "Report for $game, $date" - "Im $direction($dir) der Region liegt $trailto($region)" - "To the $direction($dir) lies $trailto($region)" - "$resource($product,0) $int($price) Silber" - "$resource($product,0) for $int($price) silver" - "Auf dem Markt wird für $resource($product,0) $int($price) Silber verlangt." - "The local market offers $resource($product,0) at a price of $int($price) silver." - "Auf dem Markt werden $resource($p1,0) und $resource($p2,0) feilgeboten." - "The local market offers $resource($p1,0) and $resource($p2,0)." - "Auf dem Markt wird $resource($p1,0) feilgeboten." - "The local market offers $resource($p1,0)." - "Auf der Einheit $if($eq($left,1),"liegt","liegen") $int($left) Wirkung$if($eq($left,1),"","en") $resource($potion,1)." - "There $if($eq($left,1),"is","are") $int($left) $if($eq($left,1),"use","uses") of $resource($potion,1) left." - "Die Region ist im Besitz von $faction($faction)." - "The region is owned by $faction($faction)." - "$if($transparent," befindet sich"," versperrt") ${object}$if($transparent,""," die Sicht")." - "$if($transparent," there is"," sight is blocked by ") ${object}." - ", belagert von $int($soldiers) Personen$if($lt($diff,0),""," (abgeschnitten)")" - ", besieged by $int($soldiers) soldiers$if($lt($diff,0),""," (cut off)")" - "Dein Passwort lautet ${password}." - "Your password is ${password}." - "Die Mannschaft krank vom vergifteten Wasser, Planken, Ruder und Segel zerfressen von den Wassern des verfluchten Meeres, ergibt sich die $ship($ship) in ihr Schicksal und sinkt." - "Her sailors sick from the poisened ocean, planks, rudder und sails corroded by the waters of the cursed ocean, the $ship($ship) finally succumbs to her destiny and sinks." - "$unit($unit) benutzt einen Talenttrunk und fühlt, wie sein Wissen zunimmt." - "$unit($unit) uses a potion of skills and feels his knowledge grow." - "$unit($unit) benutzt einen Astralkristall und gewinnt $int($aura) Aura hinzu." - "$unit($unit) uses an astral crystal and gains $int($aura) aura." @@ -1008,8 +738,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieses Luxusgut wird hier nicht verkauft." - "$unit($unit) in $region($region): '$order($command)' - These goods are not on sale here." @@ -1018,8 +746,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dazu benötigt man $resource($missing,0)." - "$unit($unit) in $region($region): '$order($command)' - This requires $resource($missing,0)." @@ -1028,8 +754,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $race($race,0) nehmen nichts an." - "$unit($unit) in $region($region): '$order($command)' - $race($race,0) will not accept anything." @@ -1038,8 +762,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $race($race,0) können nicht neu gruppiert werden." - "$unit($unit) in $region($region): '$order($command)' - $race($race,0) cannot be regrouped." @@ -1048,8 +770,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $race($race,0) können nichts stehelen." - "$unit($unit) in $region($region): '$order($command)' - $race($race,0) cannot steal anything." @@ -1057,8 +777,6 @@ - "Eine Botschaft von $unit.dative($sender) aus $region($region): '$string'" - "A message by $unit($sender) from $region($region): '$string'" @@ -1067,8 +785,6 @@ - "In $region($region) erhielt $unit($unit) eine Botschaft von $unit.dative($sender): '$string'" - "In $region($region), $unit($unit) received a message by $unit($sender): '$string'" @@ -1077,22 +793,16 @@ - "In $region($region) erhielt $unit($unit) von $unit.dative($sender) $resources($items)" - "In $region($region), $unit($unit) received $resources($items) from $unit($sender)" - "$building($building) hat diese Woche nicht funktioniert, da zu Beginn der Woche der Unterhalt nicht gezahlt werden konnte." - "$building($building) was nonfunctional because upkeep could not be paid at the beginning of the week." - "Plötzlich löst sich $building($building) in kleine Traumwolken auf." - "$building($building) suddenly dissolves into small pink clouds." @@ -1101,8 +811,6 @@ - "In $region($region) stürzte $building($building) ein.$if($road," Beim Einsturz wurde die halbe Straße vernichtet.","")$if($opfer," $int($opfer) Opfer $if($eq($opfer,1),"ist","sind") zu beklagen.","")" - "$building($building) in $region($region) collapses.$if($road," The collapse ruined half of the road.","")$if($opfer," There are $int($opfer) casualties.","")" @@ -1111,8 +819,6 @@ - "$unit($unit) in $region($region): '$order($command)' - In der Ebene der Herausforderung kann niemand rekrutiert werden." - "$unit($unit) in $region($region): '$order($command)' - You cannot recruit in this plane." @@ -1121,8 +827,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann sich nicht so gut tarnen." - "$unit($unit) in $region($region): '$order($command)' -The unit cannot hide that well." @@ -1130,8 +834,6 @@ - "$ship($ship) was destroyed by $unit($unit)." - "$ship($ship) wurde von $unit($unit) zerstört." @@ -1139,8 +841,6 @@ - "$unit($unit) could not destroy $ship($ship)." - "$unit($unit) konnte $ship($ship) nicht zerstören." @@ -1148,24 +848,18 @@ - "$unit($unit) was detected while trying to destroy $ship($ship)." - "$unit($unit) wurde beim Versuch $ship($ship) zu zerstören entdeckt." - "Somebody attempted to destroy $ship($ship)." - "Es wurde versucht, $ship($ship) zu zerstören." - "$ship($ship) was destroyed." - "$ship($ship) wurde zerstört." @@ -1174,8 +868,6 @@ - "$int($amount) Personen von $unit($unit) ertrinken.$if($isnull($region),""," Die Einheit rettet sich nach $region($region).")" - "$int($amount) people of $unit($unit) drown.$if($isnull($region),""," The unit makes it to $region($region).")" @@ -1183,8 +875,6 @@ - "$unit($unit) überlebt unbeschadet und rettet sich nach $region($region)." - "$unit($unit) survives unscathed and makes it to $region($region)." @@ -1192,8 +882,6 @@ - "$ship($ship) versinkt in den Fluten von $region($region)." - "$ship($ship) disappears in the depths of $region($region)." @@ -1201,8 +889,6 @@ - "$unit($unit) wurde beim versenken von $ship($ship) entdeckt." - "$unit($unit) was spotted sinking $ship($ship)." @@ -1211,8 +897,6 @@ - "$unit($unit) entdeckte $unit($saboteur) beim Versenken von $ship($ship)." - "$unit($unit) caught $unit($saboteur) trying to sink $ship($ship)." @@ -1220,8 +904,6 @@ - "$unit($unit) ertrinkt in $region($region)." - "$unit($unit) drowns in $region($region)." @@ -1229,8 +911,6 @@ - "$unit($unit) nimmt Schaden durch den Giftelementar in $region($region)." - "$unit($unit) is taking poison damage in $region($region)." @@ -1238,8 +918,6 @@ - "$unit($unit) stirbt am Schaden durch den Giftelementar in $region($region)." - "$unit($unit) dies from poison damage taken in $region($region)." @@ -1248,8 +926,6 @@ - "$unit($unit) stolpert bei der Erforschung der Region über $localize($location). Nähere Durchsuchung fördert ein zerfleddertes altes Buch mit dem Titel '$localize($book)' zu Tage. Der Wissensschub ist enorm." - "$unit($unit) stumbles upon $localize($location) while exploring the region. Closer inspection reveals a torn old book titled '$localize($book)'. The expansion of knowledge is tremendous." @@ -1257,8 +933,6 @@ - "$unit($unit) fühlt sich von starken magischen Energien durchströmt. ($int36($id))" - "Powerful magical energies are pulsing through $unit($unit). ($int36($id))" @@ -1266,8 +940,6 @@ - "$unit($unit) hat Schwierigkeiten seine magischen Energien zu sammeln. ($int36($id))" - "$unit($unit) finds it difficult to gather its magical energies. ($int36($id))" @@ -1276,8 +948,6 @@ - "$unit($mage) zaubert $spell($spell): $int($amount) Krieger sind für einen Moment benommen." - "$unit($mage) casts $spell($spell): $int($amount) fighters were momentarily stunned." @@ -1285,8 +955,6 @@ - "$unit($mage) besänftigt den Bauernaufstand in $region($region)." - "$unit($mage) quells the uprising in $region($region)." @@ -1294,8 +962,6 @@ - "$unit($mage) rief in $region($region) einen Riss in dem Gefüge der Magie hervor, der alle magische Kraft aus der Region riss." - "$unit($mage) in $region($region) caused a tear in the fabric of magic, that sucked all magical energies out of the region." @@ -1304,8 +970,6 @@ - "$unit($mage) zaubert $spell($spell): $int($amount) Krieger wurden in Schlaf versetzt." - "$unit($mage) casts $spell($spell): $int($amount) fighters have fallen asleep." @@ -1314,8 +978,6 @@ - "$unit($mage) zaubert $spell($spell): $int($amount) Kriegern wurde ihre Lebenskraft entzogen." - "$unit($mage) casts $spell($spell): $int($amount) fighters had their life energy drained." @@ -1324,8 +986,6 @@ - "$unit($mage) zaubert $spell($spell): $int($amount) Kriegern wurden versteinert." - "$unit($mage) casts $spell($spell): $int($amount) fighters were petrified." @@ -1334,8 +994,6 @@ - "$unit($mage) zaubert $spell($spell): $int($amount) Krieger wurden in einen Blutrausch versetzt." - "$unit($mage) casts $spell($spell): $int($amount) fighters went into a mindless rage." @@ -1344,8 +1002,6 @@ - "$unit($mage) zaubert $spell($spell): $int($amount) Krieger wurden eingeschüchtert." - "$unit($mage) casts $spell($spell): $int($amount) fighters were intimidated." @@ -1353,8 +1009,6 @@ - "$unit($mage) zaubert $spell($spell), aber es gab niemanden, der beeinflusst werden konnte." - "$unit($mage) casts $spell($spell), but nobody is affected." @@ -1363,8 +1017,6 @@ - "$unit($mage) zaubert $spell($spell): $int($amount) Krieger wurden von Furcht gepackt." - "$unit($mage) casts $spell($spell): $int($amount) fighters were consumed by fear." @@ -1372,8 +1024,6 @@ - "$unit($mage) zaubert $spell($spell): Das Kampfgetümmel erstirbt und er kann unbehelligt seines Weges ziehen." - "$unit($mage) casts $spell($spell): The noise of the battle dies down and the mage is able to slip away unharmed." @@ -1381,8 +1031,6 @@ - "$unit($mage) zaubert $spell($spell): Ein Sturm kommt auf und die Schützen können kaum noch zielen." - "$unit($mage) casts $spell($spell): Strong stormwinds are blowing and the archers are having a hard time aiming." @@ -1391,8 +1039,6 @@ - "$unit($mage) zaubert $spell($spell): $int($amount) Krieger schleppten sich müde in den Kampf." - "$unit($mage) casts $spell($spell): $int($amount) fighters had trouble staying awake." @@ -1401,8 +1047,6 @@ - "$unit($mage) zaubert $spell($spell): $int($amount) Krieger wurden moralisch gestärkt." - "$unit($mage) casts $spell($spell): $int($amount) fighters had their moral boosted." @@ -1411,32 +1055,24 @@ - "$unit($mage) zaubert $spell($spell): $int($amount) Krieger wurden magisch beschleunigt." - "$unit($mage) casts $spell($spell): $int($amount) fighters were magically accelerated." - "$unit($mage) ruft ein fürchterliches Unwetter über seine Feinde, doch es gab niemanden mehr, den dies treffen konnte." - "$unit($mage) calls forth a terrible torment over the enemy side, but there was nobody who could be affected by it." - "$unit($mage) ruft ein fürchterliches Unwetter über seine Feinde, doch der magische Regen zeigt keinen Effekt." - "$unit($mage) causes a terrible storm over the enemy, but the magic rain does not do any harm." - "$unit($mage) ruft ein fürchterliches Unwetter über seine Feinde. Der magischen Regen lässt alles Eisen rosten." - "$unit($mage) calls forth a terrible torment over the enemy. The magical rain makes all iron rusty." @@ -1444,8 +1080,6 @@ - "$unit($mage) kümmert sich um die Verletzten und heilt $int($amount) Verwundete." - "$unit($mage) sees after the wounded and heals $int($amount)." @@ -1454,8 +1088,6 @@ - "$unit($mage) kümmert sich um die Verletzten und benutzt ein $resource($item,1), um den Zauber zu verstärken. $int($amount) Verwundete werden geheilt." - "$unit($mage) sees after the wounded and heals $int($amount). A $resource($item,1) improves the spell." @@ -1464,8 +1096,6 @@ - "Mit einem Ritual bindet $unit($mage) die magischen Kräfte der Erde von $region($region) in die Mauern von $building($building)." - "$unit($mage) performs a ritual that binds the magical forces of $region($region) into the walls of $building($building)." @@ -1474,8 +1104,6 @@ - "$unit($mage) opfert $unit($target) $int($amount) Aura." - "$unit($mage) sacrifices $int($amount) aura for $unit($target)." @@ -1483,8 +1111,6 @@ - "$unit($mage) beginnt ein Ritual der Wiederbelebung. $int($amount) Krieger stehen von den Toten auf." - "$unit($mage) begins a ritual of resurrection. $int($amount) warriors rise from the dead." @@ -1493,21 +1119,15 @@ - "$unit($mage) beginnt ein Ritual der Wiederbelebung und benutzt ein $resource($item,1), um den Zauber zu verstärken. $int($amount) Krieger stehen von den Toten auf." - "$unit($mage) begins a ritual of resurrection augmented by a $resource($item,1). $int($amount) warriors rise from the dead." - "$unit($mage) öffnet ein Chaostor." - "$unit($mage) opens a chaos gate." - "Ein Wirbel aus blendendem Licht erscheint." - "A vortex of blinding light appears." @@ -1515,8 +1135,6 @@ - "$unit($mage) kann in $region($region) keine Untoten rufen." - "$unit($mage) cannot summon any undead in $region($region)." @@ -1525,8 +1143,6 @@ - "$unit($mage) erweckt in $region($region) $int($amount) Untote aus ihren Gräbern." - "$unit($mage) calls $int($amount) undead from their graves in $region($region)." @@ -1534,16 +1150,12 @@ - "$unit($mage) stört in $region($region) die Ruhe der Toten." - "$unit($mage) communicates with the dead in $region($region)." - "$unit($unit) gelingt es, durch die Nebel auf die Realität zu blicken." - "$unit($unit) manages to catch a glimpse of reality through the fog." @@ -1551,8 +1163,6 @@ - "$unit($mage) konnte $int($amount) $if($eq($amount,1),"Bauer","Bauern") anwerben." - "$unit($mage) managed to recruit $int($amount) $if($eq($amount,1),"peasant","peasants")." @@ -1561,67 +1171,49 @@ - "$unit($unit) in $region($region): '$order($command)' - Eine höhere Macht hindert $unit($unit) daran, das Objekt zu übergeben. 'ES IST DEINS, MEIN KIND. DEINS GANZ ALLEIN'." - "$unit($unit) in $region($region): '$order($command)' - A higher power prevents $unit($unit) from giving the object away. 'IT IS YOURS MY CHILD. ONLY YOURS.'." - "Der Eisberg $region($region) schmilzt." - "The iceberg $region($region) melts." - "Der Gletscher von $region($region) bricht und treibt davon." - "The glacier in $region($region) breaks up and drifts away." - "Der Eisberg $region($region) treibt an eine Küste." - "The iceberg $region($region) drifts onto a coast." - "Die $ship($ship) wird bei einer Kollision mit einem Eisberg zerstört." - "The $ship($ship) has been destroyed by a collision with an iceberg." - "Die $ship($ship) wird bei einer Kollision mit einem Eisberg beschädigt." - "The $ship($ship) has been damaged by a collision with an iceberg." - "Die $ship($ship) ist zu stark überladen und wird stark beschädigt." - "The $ship($ship) is massively overloaded and is damaged heavily." - "Die $ship($ship) treibt nach $direction($dir)." - "The ship $ship($ship) drifts to the $direction($dir)." - "Der Eisberg $region($region) treibt nach $direction($dir)." - "The iceberg $region($region) drifts $direction($dir)." @@ -1631,8 +1223,6 @@ - "$unit($unit) verlor $int($fallen) Personen$if($alive,", $int($alive) überlebten","")$if($run," und $int($run) flohen$if($isnull($runto),""," nach $region($runto)")","")." - "$unit($unit) lost $int($fallen) people$if($alive,", $int($alive) survived","")$if($run," and $int($run) fled$if($isnull($runto),""," to $region($runto)")","")." @@ -1640,31 +1230,23 @@ - "$unit($unit) erzielte $int($hits) Treffer und tötete $int($kills) Gegner." - "$unit($unit) hit $int($hits) times and killed $int($kills) enemies." - "$string" - "$string" - "Heer $int($index): $name" - "Army $int($index): $name" - "Verwundert blicken die Bauern von $region($region) auf ein neues Gebäude." - "Flabbergasted, the peasants of $region($region) behold a new building." @@ -1674,8 +1256,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) gewinnt durch das Ritual $int($amount) Aura." - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) receives $int($amount) aura." @@ -1683,8 +1263,6 @@ - "$unit($mage) beschwört Naturgeister in den Boden von $region($region)." - "$unit($mage) summons natural spirits into the ground of $region($region)." @@ -1693,8 +1271,6 @@ - "$unit($mage) verwandelt $int($amount) aus $unit($target) in $race($race,0)." - "$unit($mage) transforms $int($amount) from $unit($target) into $race($race,0)." @@ -1702,38 +1278,28 @@ - "$unit($mage) verwandelt $unit($target) in $race($race,0)." - "$unit($mage) tranforms $unit($target) to $race($race,0)." - "$unit($mage) erlöst die gequälten Seelen der Toten." - "$unit($mage) redeems the tormented souls of the dead." - "$unit($mage) verwandelt sich in einen Wyrm." - "$unit($mage) turns into a wyrm." - "$unit($mage) erschafft in $region($region) eine Wand aus Feuer." - "$unit($mage) creates a wall of fire in $region($region)." - "$unit($mage) wiegelt in $region($region) die Bauern zum Aufstand auf." - "$unit($mage) incites a revolt among the peasants of $region($region)." @@ -1742,8 +1308,6 @@ - "$unit($mage) wiegelt in $region($region) $int($amount) Bauern zum Aufstand auf." - "$unit($mage) incites a revolt among $int($amount) peasants of $region($region)." @@ -1751,8 +1315,6 @@ - "$unit($mage) sorgt in $region($region) für Trübsal unter den Bauern." - "$unit($mage) causes great sadness among the peasants of $region($region)." @@ -1761,8 +1323,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Magier erschafft ein Traumgebäude." - "$unit($unit) in $region($region): '$order($command)' - The magician creates an illusionary building." @@ -1772,8 +1332,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($target) kann nicht $race($race,1) werden." - "$unit($unit) in $region($region): '$order($command)' - $unit($target) cannot take the form of $race($race,1)." @@ -1782,8 +1340,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Elementar ist zu klein, um das Gebäude zu tragen." - "$unit($unit) in $region($region): '$order($command)' - The elemental is too small to carry the building." @@ -1793,8 +1349,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Elementar weigert sich, nach $direction($direction) zu gehen." - "$unit($unit) in $region($region): '$order($command)' - The elemental refuses to go $direction($direction)." @@ -1804,8 +1358,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($target) ist von unserer Art, das Ritual wäre verschwendete Aura." - "$unit($unit) in $region($region): '$order($command)' - $unit($target) is one of our kind, we should not waste aura on this." @@ -1814,8 +1366,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($target) wird von uns aufgenommen." - "$unit($unit) in $region($region): '$order($command)' - $unit($target) has become one of our kind." @@ -1824,8 +1374,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) ruft Drachen nach $region($target)." - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) calls dragons to $region($target)." @@ -1836,8 +1384,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) erschafft $int($amount) ${object}." - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) creates $int($amount) ${object}." @@ -1845,8 +1391,6 @@ - "Ein Beben erschüttert $building($building). Viele kleine Pseudopodien erheben das Gebäude und tragen es in Richtung $direction($direction)." - "An tremor shakes $building($building). Many little pseudopods lift up the building and carry it to $direction($direction)." @@ -1854,15 +1398,11 @@ - "$unit($unit) benutzt in $region($region) ein Traumauge." - "$unit($unit) uses a dreameye in $region($region)." - "$unit($unit) benutzt einen Antimagiekristall." - "$unit($unit) uses an antimagic crystal." @@ -1870,8 +1410,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Sphären des Chaos geben dem Magier einen Teil ihrer Kraft." - "$unit($unit) in $region($region): '$order($command)' - The Spheres of Chaos return a part of his power to the magician." @@ -1879,8 +1417,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Magier konnte keinen Fluch zerstören." - "$unit($unit) in $region($region): '$order($command)' - The magician could not destroy any curse." @@ -1888,8 +1424,6 @@ - "In $region($region) dehnt $unit($unit) die Zeit für $int($amount) Personen." - "In $region($region), $unit($unit) bends time for $int($amount) men." @@ -1899,8 +1433,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Magier zerstört $int($succ) Flüche auf ${target}." - "$unit($unit) in $region($region): '$order($command)' - The magician destroys $int($succ) spells on ${target}." @@ -1910,8 +1442,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Magier zerstört den Fluch ($id) auf ${target}." - "$unit($unit) in $region($region): '$order($command)' - The magician destroys the spell ($id) on ${target}." @@ -1921,16 +1451,12 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Zauber ist nicht stark genug, um den Fluch ($id) auf ${target} zu zerstören." - "$unit($unit) in $region($region): '$order($command)' - The spell is not strong enough to destroy the curse ($id) on ${target}." - "$unit($mage) beschwört einen Giftelementar in $region($region)." - "$unit($mage) summons a poison elemental in $region($region)." @@ -1938,8 +1464,6 @@ - "$unit($unit) in $region($region) wird von einem Unbekannten verflucht." - "$unit($unit) in $region($region) was cursed by an unknown magician." @@ -1947,24 +1471,18 @@ - "$unit($mage) belegt $unit($target) mit einem Zauber." - "$unit($mage) puts a spell on $unit($target)." - "$unit($mage) belegt $unit($target) mit einem Kälteschutz." - "$unit($mage) puts protection from cold on $unit($target)." - "$unit($mage) legt einen Rosthauch auf $unit($target), doch der Rosthauch fand keine Nahrung." - "$unit($mage) puts a spell of rust on $unit($target) but it found nothing to consume." @@ -1972,61 +1490,45 @@ - "$unit($mage) legt einen Rosthauch auf $unit($target). $int($amount) Waffen wurden vom Rost zerfressen." - "$unit($mage) puts a spell of rust on $unit($target). $int($amount) weapons are eaten by rust." - $if($isnull($mage),"Ein unentdeckter Magier",$unit($mage)) erschuf einen heiligen Hain von $int($amount) Schößlingen. - $if($isnull($mage),"An unknown magician",$unit($mage)) created a holy forest of $int($amount) young trees. - "$if($isnull($mage),"Ein unentdeckter Magier",$unit($mage)) führt einen sonderbaren Tanz auf. Kurz darauf beginnt es zu regnen." - "$if($isnull($mage),"an unseen magician",$unit($mage)) dances a strange dance. Shortly after, rain begins to fall on the fields." - "$if($isnull($mage),"Ein unentdeckter Magier",$unit($mage)) segnet in einem kurzen Ritual die Felder." - "$if($isnull($mage),"An unseen magician",$unit($mage)) blesses the fields in a short ritual." - "$unit($mage) beschwört die Mächte des Wassers und ein gigantischer Strudel bildet sich." - "$unit($mage) summons the power of the seas and a giant maelstrom forms." - "$unit($mage) belebt $int($amount) Bäume." - "$unit($mage) animates $int($amount) trees." - "$unit($mage) sorgt für trockene Straßen in $region($region)." - "$unit($mage) creates dry and well-repaired roads in $region($region)." - "$unit($mage) erfleht den Segen der Götter des Windes und des Wassers für $ship($ship)." - "$unit($mage) asks the gods of wind and water on behalf of the $ship($ship)." @@ -2034,8 +1536,6 @@ - "$unit($unit) transferiert $int($aura) Aura auf $unit($target)." - "$unit($unit) transfers $int($aura) aura to $unit($target)." @@ -2043,31 +1543,23 @@ - "$unit($mage) entzieht $unit($target) $int($aura) Aura." - "$unit($mage) draws $int($aura) aura from $unit($target)." - "$unit($unit) fühlt seine magischen Kräfte schwinden und verliert $int($aura) Aura." - "$unit($unit) feels the powers of magic fade and loses $int($aura) aura." - "$unit($unit) fühlt sich einen Moment seltsam geschwächt." - "$unit($unit) fühlt strangely weakened." - "$unit($unit) konnte $unit($target) keine Aura entziehen." - "$unit($unit) could not draw aura from $unit($target)." @@ -2075,8 +1567,6 @@ - "$unit($unit) wurde von $region($source) nach $unit($target) teleportiert." - "$unit($unit) was teleported from $region($source) to $unit($target)." @@ -2085,8 +1575,6 @@ - "$unit($mage) fand heraus, dass auf $ship($ship) der Zauber '$curse($curse)' liegt, der noch etwa $int($months) Wochen bestehen bleibt." - "$unit($mage) discovers that $ship($ship) is charmed with '$curse($curse)', which will last for, about $int($months) more weeks." @@ -2095,8 +1583,6 @@ - "$unit($mage) fand heraus, dass auf $building($building) der Zauber '$curse($curse)' liegt, der noch etwa $int($months) Wochen bestehen bleibt." - "$unit($mage) discovers that $building($building) is charmed with '$curse($curse)', which will last for about $int($months) more weeks." @@ -2105,8 +1591,6 @@ - "$unit($mage) fand heraus, dass auf $unit($unit) der Zauber '$curse($curse)' liegt, der noch etwa $int($months) Wochen bestehen bleibt." - "$unit($mage) discovers that $unit($unit) is charmed with '$curse($curse)' that will last for about $int($months) more weeks." @@ -2115,8 +1599,6 @@ - "$unit($mage) fand heraus, dass auf $region($region) der Zauber '$curse($curse)' liegt, der noch etwa $int($months) Wochen bestehen bleibt." - "$unit($mage) discovers that $region($region) is charmed with '$curse($curse)', which will last for about $int($months) more weeks." @@ -2124,8 +1606,6 @@ - "$unit($mage) fand heraus, dass auf $ship($ship) der Zauber '$curse($curse)' liegt, dessen Kraft ausreicht, um noch Jahrhunderte bestehen zu bleiben." - "$unit($mage) discovers that $ship($ship) is charmed with '$curse($curse)', which will last for centuries." @@ -2133,8 +1613,6 @@ - "$unit($mage) fand heraus, dass auf $building($building) der Zauber '$curse($curse)' liegt, dessen Kraft ausreicht, um noch Jahrhunderte bestehen zu bleiben." - "$unit($mage) discovers that $building($building) is charmed with '$curse($curse)', which will last for centuries." @@ -2142,8 +1620,6 @@ - "$unit($mage) fand heraus, dass auf $unit($unit) der Zauber '$curse($curse)' liegt, dessen Kraft ausreicht, um noch Jahrhunderte bestehen zu bleiben." - "$unit($mage) discovers that $unit($unit) is charmed with '$curse($curse)', which will last for centuries." @@ -2151,72 +1627,54 @@ - "$unit($mage) fand heraus, dass auf $region($region) der Zauber '$curse($curse)' liegt, dessen Kraft ausreicht, um noch Jahrhunderte bestehen zu bleiben." - "$unit($mage) discovers that $region($region) is charmed with '$curse($curse)', which will last for centuries." - "$unit($mage) meint, dass auf $ship($ship) ein Zauber liegt, konnte aber über den Zauber nichts herausfinden." - "It appears to $unit($mage) that $ship($ship) is charmed, but no details have been revealed." - "$unit($mage) meint, dass auf $building($building) ein Zauber liegt, konnte aber über den Zauber nichts herausfinden." - "It appears to $unit($mage) that $building($building) is charmed, but no details have been revealed." - "$unit($mage) meint, dass $unit($unit) verzaubert ist, konnte aber über den Zauber nichts herausfinden." - "It appears to $unit($mage) that $unit($unit) is charmed, but no details have been revealed." - "$unit($mage) meint, dass auf $region($region) ein Zauber liegt, konnte aber über den Zauber nichts herausfinden." - "It appears to $unit($mage) that $region($region) is charmed, but no details have been revealed." - "$unit($mage) meint, dass auf $ship($ship) kein Zauber liegt." - "It appears to $unit($mage) that $ship($ship) is not charmed." - "$unit($mage) meint, dass auf $building($building) kein Zauber liegt." - "It appears to $unit($mage) that $building($building) is not charmed." - "$unit($mage) meint, dass auf $unit($target) kein Zauber liegt." - "It appears to $unit($mage) that $unit($target) is not charmed." - "$unit($mage) meint, dass auf $region($region) kein Zauber liegt." - "It appears to $unit($mage) that $region($region) is not charmed." @@ -2224,8 +1682,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Region konnte nicht verzaubert werden." - "$unit($unit) in $region($region): '$order($command)' - The region could not be charmed." @@ -2234,8 +1690,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $ship($ship) widersteht dem Zauber." - "$unit($unit) in $region($region): '$order($command)' - $ship($ship) resists the spell." @@ -2244,8 +1698,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Gebäude $int36($id) konnte nicht verzaubert werden." - "$unit($unit) in $region($region): '$order($command)' - Building $int36($id) could not be charmed." @@ -2254,8 +1706,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($target) widersteht dem Zauber." - "$unit($unit) in $region($region): '$order($command)' - $unit($target) resists the spell." @@ -2264,8 +1714,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Schiff $int36($id) wurde nicht gefunden." - "$unit($unit) in $region($region): '$order($command)' - Ship $int36($id) could not be located." @@ -2274,8 +1722,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Gebäude $int36($id) wurde nicht gefunden." - "$unit($unit) in $region($region): '$order($command)' - Building $int36($id) could not be located." @@ -2284,8 +1730,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Einheit $id wurde nicht gefunden." - "$unit($unit) in $region($region): '$order($command)' - Unit $id could not be located." @@ -2293,16 +1737,12 @@ - "$unit($unit) in $region($region): '$order($command)' - Es wurde kein Ziel gefunden." - "$unit($unit) in $region($region): '$order($command)' - The spell could not find a target." - "$unit($mage) erleidet durch den Tod seines Vertrauten einen Schock." - "$unit($mage) receives a shock when his familiar dies." @@ -2310,8 +1750,6 @@ - "$unit($unit) schafft es nicht, genug Kraft aufzubringen, um $spell($spell) auf Stufe $int($level) zu zaubern." - "$unit($unit) cannot muster enough energy to cast $spell($spell) on level $int($level)." @@ -2320,8 +1758,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Für diesen Zauber fehlen noch $resources($list)." - "$unit($unit) in $region($region): '$order($command)' - Casting this spell requires an additional $resources($list)." @@ -2329,8 +1765,6 @@ - "$unit($unit) hat nicht genügend Komponenten um $spell($spell) auf Stufe $int($level) zu zaubern." - "$unit($unit) has insufficient components to cast $spell($spell) on level $int($level)." @@ -2338,8 +1772,6 @@ - "$unit($unit) unterläuft in $region($region) beim Zaubern von $spell($spell) ein Patzer." - "$unit($unit) fumbles while casting $spell($spell) in $region($region)." @@ -2347,8 +1779,6 @@ - "Als $unit($unit) in $region($region) versucht, $spell($spell) zu zaubern, scheint plötzlich ein Beben durch die magische Essenz zu laufen und ein furchtbarer Sog versucht $unit($unit) in eine andere Dimension zu ziehen. Mit letzter Kraft gelingt es $unit($unit) sich zu retten." - "When $unit($unit) in $region($region) tries to cast $spell($spell), a sudden disturbance ripples through the magical realm and a terrible force attempts to drag the magician to another dimension. However, with a final effort of strength, $unit($unit) manages to save himself." @@ -2356,8 +1786,6 @@ - "Als $unit($unit) in $region($region) versucht, $spell($spell) zu zaubern erhebt sich plötzlich ein dunkler Wind. Bizarre geisterhafte Gestalten kreisen um den Magier und scheinen sich von den magischen Energien des Zaubers zu ernähren. Mit letzter Kraft gelingt es $unit($unit) dennoch den Spruch zu zaubern." - "When $unit($unit) in $region($region) tries to cast $spell($spell), strong winds suddenly rise. Bizarre ghostlike creatures circle around the magician and seem to be leeching magical energy. However, with a final effort of strength, $unit($unit) manages to complete the spell." @@ -2365,8 +1793,6 @@ - "Eine Botschaft von $unit.dative($unit) in $region($region): 'Ups! Quack, Quack!'" - "A message from $unit($unit) in $region($region): 'Oops! Croak, Croak!'" @@ -2375,8 +1801,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($mage) kann Zauber, die durch $unit($unit) gewirkt werden, nicht zusätzlich in die Ferne richten." - "$unit($unit) in $region($region): '$order($command)' - $unit($mage) cannot direct spells that are channeled through $unit($unit) into distant regions." @@ -2385,8 +1809,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($mage) kann nicht genug Energie aufbringen, um diesen Spruch durch $unit($unit) zu wirken." - "$unit($unit) in $region($region): '$order($command)' - $unit($mage) cannot raise enough energy to channel the spell through $unit($unit)." @@ -2394,8 +1816,6 @@ - "$unit($mage) ruft einen Vertrauten. $race($race, 0) können $skills lernen." - "$unit($mage) summons a familiar. $race($race, 0) can learn ${skills}." @@ -2403,16 +1823,12 @@ - "$unit($unit) hat einen feuchtfröhlichen Abend in der Taverne verbracht. Ausser einem fürchterlichen Brummschädel ist da auch noch das dumme Gefühl $unit($mage) seine ganze Lebensgeschichte erzählt zu haben." - "$unit($unit) spent the evening carousing in the tavern. In addition to a terrible headache, there remains this feeling of having told $unit($mage) the story of his entire life." - "$unit($unit) hat einen feuchtfröhlichen Abend in der Taverne verbracht. Ausser einem fürchterlichen Brummschädel ist da auch noch das dumme Gefühl die ganze Taverne mit seiner Lebensgeschichte unterhalten zu haben." - "$unit($unit) spent the evening carousing in the tavern. In addition to a terrible headache, there remains this feeling of having told everyone the story of his entire life." @@ -2421,8 +1837,6 @@ - "$unit($mage) gelingt es $unit($unit) zu verzaubern. $unit($unit) wird für etwa $int($duration) Wochen unseren Befehlen gehorchen." - "$unit($mage) chamrs $unit($unit). $unit($unit) will obey our orders for approximatley $int($duration) more weeks." @@ -2431,8 +1845,6 @@ - "$unit($unit) gelingt es $spell($spell) zu zaubern, doch der Spruch zeigt keine Wirkung." - "$unit($unit) manages to cast $spell($spell), but the spell seems to have no effect." @@ -2440,16 +1852,12 @@ - "$unit($unit) fühlt sich nach dem Zaubern von $spell($spell) viel erschöpfter als sonst und hat das Gefühl, dass alle weiteren Zauber deutlich mehr Kraft als normalerweise kosten werden." - "$unit($unit) feels far more exhausted than he should after casting $spell($spell) and assumes that any following spells will cost far more energy than usual." - "$unit($unit) in $region($region) hat rasende Kopfschmerzen und kann sich nicht mehr richtig konzentrieren. Irgendwas bei diesem Zauber ist fürchterlich schiefgelaufen." - "$unit($unit) in $region($region) is hit by a massive headache and cannot concentrate on the spell. Some part of this ritual has gone very wrong indeed." @@ -2457,12 +1865,8 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Magier verfängt sich im eigenen Zauber." - "$unit($unit) in $region($region): '$order($command)' - The magician is caught in their own spell." - "In der Region erstrahlen des Nachts bunte Lichter, Gloeckchen klingeln und frohes Kindergelaechter klingt durch den Wald." - "At night, colourful lights can be seen in this region, bells are a-ringing and the laughter of happy children seems to be everywhere in the forests." @@ -2470,8 +1874,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Zauber von $unit.dative($unit) war viel zu schwach und löst sich gleich wieder auf." - "$unit($unit) in $region($region): '$order($command)' - The spell of $unit($unit) was way to weak and its magic dissolves immediately." @@ -2480,8 +1882,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) verzaubert ${target}." - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) puts a spell on ${target}." @@ -2489,8 +1889,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) gelingt es zwar die Region zu verzaubern, aber irgendwas ging schief." - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) manages to put a spell on the region, but something went wrong nonetheless." @@ -2498,16 +1896,12 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) gelingt es die Region zu verzaubern." - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) puts a spell on the region." - "$unit($mage) erhöht die Körperkraft von $unit.dative($target) beträchtlich." - "$unit($mage) increases the strength of $unit($target) dramatically." @@ -2515,8 +1909,6 @@ - "$unit($unit) in $region($region) regeneriert $int($amount) Aura." - "$unit($unit) regenerates $int($amount) aura in $region($region)." @@ -2525,16 +1917,12 @@ - "$unit($unit) in $region($region) verbraucht $int($cost) Silber für das Studium von $skill($skill)." - "$unit($unit) spends $int($cost) silver in $region($region) to study $skill($skill)." - "$unit($teacher) kann durch Dumpfbackenbrot nur $int($amount) Schüler lehren." - "Due to the effect of duncebuns, $unit($teacher) can only teach $int($amount) students." @@ -2543,8 +1931,6 @@ - "$unit($teacher) lehrt $unit($student) $skill($skill) auf Stufe $int($level)." - "$unit($teacher) teaches $unit($student) $skill($skill) to level $int($level)." @@ -2552,8 +1938,6 @@ - "$unit($teacher) lehrt $unit($student) $skill($skill)." - "$unit($teacher) teaches $unit($student) $skill($skill)." @@ -2561,8 +1945,6 @@ - "$unit($unit) verkauft $int($amount) $resource($resource,$amount)." - "$unit($unit) sells $int($amount) $resource($resource,$amount)." @@ -2570,16 +1952,12 @@ - "$unit($unit) kauft $int($amount) $resource($resource,$amount)." - "$unit($unit) buys $int($amount) $resource($resource,$amount)." - "$unit($unit) bezahlt $int($money) Silber für den Kauf von Luxusgütern." - "$unit($unit) pays $int($money) silver for luxury items." @@ -2587,8 +1965,6 @@ - "$unit($unit) verdient in $region($region) $int($amount) Silber durch den Verkauf von Luxusgütern." - "$unit($unit) earned $int($amount) silver in $region($region) by selling luxury items." @@ -2597,8 +1973,6 @@ - "$unit($unit) arbeitet in $region($region) für einen Lohn von $int($amount)$if($eq($wanted,$amount),""," statt $int($wanted)") Silber." - "$unit($unit) works in $region($region) for a wage of $int($amount) $if($eq($wanted,$amount),""," out of $int($wanted)") silver." @@ -2606,8 +1980,6 @@ - "$unit($unit) arbeitet in $region($region) für einen Lohn von $int($amount) Silber." - "In $region($region), $unit($unit) works for a wage of $int($amount) silver." @@ -2616,8 +1988,6 @@ - "$unit($unit) verdient in $region($region) $int($amount)$if($eq($wanted,$amount),""," statt $int($wanted)") Silber durch Unterhaltung." - "In $region($region), $unit($unit) earns only $int($amount) instead of$if($eq($wanted,$amount),""," of$if($eq($wanted,$amount),""," of $int($wanted)") ") with entertainment." @@ -2625,8 +1995,6 @@ - "$unit($unit) fängt in $region($region) Fische im Wert von $int($amount) Silber." - "In $region($region), $unit($unit) catches fish worth $int($amount) silver." @@ -2634,8 +2002,6 @@ - "$unit($unit) verdient in $region($region) $int($amount) Silber durch Unterhaltung." - "$unit($unit) earns $int($amount) in $region($region) with entertainment." @@ -2644,8 +2010,6 @@ - "$unit($unit) verdient in $region($region) $int($amount)$if($eq($wanted,$amount),""," statt $int($wanted)") Silber durch Zauberei." - "$unit($unit) in $region($region) earns $int($amount)$if($eq($wanted,$amount),""," instead of $int($wanted)") silver through magic." @@ -2653,8 +2017,6 @@ - "$unit($unit) verdient in $region($region) $int($amount) Silber durch Zauberei." - "$unit($unit) earns $int($amount) silver through simple magical services in $region($region)." @@ -2663,8 +2025,6 @@ - "$unit($unit) klaut in $region($region) $int($amount)$if($eq($wanted,$amount),""," statt $int($wanted)") Silber." - "$unit($unit) steals only $int($amount) silver instead of$if($eq($wanted,$amount),""," of$if($eq($wanted,$amount),""," of $int($wanted)") ") in $region($region)." @@ -2672,8 +2032,6 @@ - "$unit($unit) klaut in $region($region) $int($amount) Silber." - "$unit($unit) steals $int($amount) silver in $region($region)." @@ -2682,8 +2040,6 @@ - "$unit($unit) treibt in $region($region) Steuern in Höhe von $int($amount)$if($eq($wanted,$amount),""," statt $int($wanted)") Silber ein." - "$unit($unit) collects taxes of$if($eq($wanted,$amount),""," only") $int($amount) silver$if($eq($wanted,$amount),""," instead of $int($wanted) silver") ") in $region($region)." @@ -2691,8 +2047,6 @@ - "$unit($unit) treibt in $region($region) Steuern in Höhe von $int($amount) Silber ein." - "$unit($unit) collects taxes of $int($amount) silver in $region($region)." @@ -2702,8 +2056,6 @@ - "$unit($unit) verdient$if($eq($mode,4)," am Handel","") in $region($region) $int($amount)$if($eq($wanted,$amount),""," statt $int($wanted)") Silber$if($eq($mode,1)," durch Unterhaltung",$if($eq($mode,2)," durch Steuern",$if($eq($mode,3)," durch Handel",$if($eq($mode,5)," durch Diebstahl",$if($eq($mode,6)," durch Zauberei",$if($eq($mode,7)," durch Plündern",""))))))." - "$unit($unit) earns $int($amount)$if($eq($wanted,$amount),""," of $int($wanted)") in $region($region) $if($eq($mode,1)," by entertainment",$if($eq($mode,2)," by taxes",$if($eq($mode,3)," by trade",$if($eq($mode,5)," by stealing",$if($eq($mode,6)," by magic",$if($eq($mode,7)," by pillaging",""))))))." @@ -2712,16 +2064,12 @@ - "$unit($unit) in $region($region) findet $int($amount) $resource($herb,$amount)." - "$unit($unit) in $region($region) finds $int($amount) $resource($herb,$amount)." - "$unit($unit) züchtet $int($amount) Pferde." - "$unit($unit) breeds $int($amount) horses." @@ -2730,23 +2078,17 @@ - "$unit($unit) pflanzt in $region($region) $int($amount) $resource($herb,$amount)." - "$unit($unit) plants $int($amount) $resource($herb,$amount) in $region($region)." - "$unit($unit) in $region($region) entdeckt eine Laenader." - "$unit($unit) discovers laen in $region($region)." - "Die Laenader in $region($region) ist erschöpft." - "There is no more laen left in $region($region)." @@ -2754,8 +2096,6 @@ - "$unit($unit) in $region($region) hat ein zu niedriges Talent, um $resource($resource,0) abzubauen." - "$unit($unit) in $region($region) is not proficient enough to produce $resource($resource,0)." @@ -2765,8 +2105,6 @@ - "$unit($unit) in $region($region) produziert $int($amount)$if($eq($wanted,$amount),""," von $int($wanted)") $resource($resource,$wanted)." - "$unit($unit) in $region($region) produces $int($amount)$if($eq($wanted,$amount),""," of $int($wanted)") $resource($resource,$amount)." @@ -2774,8 +2112,6 @@ - "$unit($unit) baut für $int($size) an $building($building) weiter." - "$unit($unit) builds $int($size) more on $building($building)." @@ -2783,24 +2119,18 @@ - "$unit($unit) baut für $int($size) an $ship($ship) weiter." - "$unit($unit) builds $int($size) more on $ship($ship)." - "$unit($unit) stirbt beim Versuch, die Feuerwand nach $region($region) zu durchqueren." - "$unit($unit) dies trying to cross the wall of fire into $region($region)." - "$unit($unit) erleidet beim Durchqueren der Feuerwand nach $region($region) schwere Verbrennungen." - "$unit($unit) steps through the wall of fire into $region($region) and receives severe burn damage." @@ -2809,8 +2139,6 @@ - "$unit($unit) transportiert $unit($target) von $region($start) nach $region($end)." - "$unit($unit) transported $unit($target) from $region($start) to $region($end)." @@ -2820,8 +2148,6 @@ - "$unit($unit) $if($eq($mode,1),"reitet", "wandert") von $region($start) nach $region($end).$if($isnull($regions),""," Dabei wurde $trail($regions) durchquert.")" - "$unit($unit) $if($eq($mode,1),"rides", "walks") from $region($start) to $region($end)$if($isnull($regions),""," by way of $trail($regions)")." @@ -2829,72 +2155,54 @@ - "$unit($unit) entdeckt, dass $region($region) $localize($terrain) ist." - "$unit($unit) discovered that $region($region) is $localize($terrain)." - "$unit($unit) ist in dieser Runde gelandet und kann nicht weiter ins Landesinnere nach $region($region) vorstossen." - "$unit($unit) has just landed and cannot continue moving to $region($region)." - "Die Mannschaft der $ship($ship) kann in letzter Sekunde verhindern, dass das Schiff in $region($region) auf Land aufläuft." - "At the very last moment, the crew of the $ship($ship) saved the ship from running aground in $region($region)." - "Die $ship($ship) konnte in $region($region) nicht einreisen, die Küste ist zu gefährlich für das Schiff." - "The $ship($ship) could not berth in $region($region). The coast is too dangerous for the vessel." - "Die Mannschaft der $ship($ship) weigert sich, nach $direction($direction) zu reisen." - "The crew of the $ship($ship) refuses to travel to the $direction($direction)." - "Die Mannschaft der $ship($ship) weigert sich, nach $region($region) zu reisen." - "The crew of the $ship($ship) refuses to travel to $region($region)." - "$unit($unit) weigert sich, nach $direction($direction) zu reisen." - "$unit($unit) refuses to travel to the $direction($direction)." - "$unit($unit) weigert sich, nach $region($region) zu reisen." - "$unit($unit) refuses to travel to $region($region)." - "Die $ship($ship) konnte $region($region) nicht verlassen." - "The $ship($ship) could not leave $region($region)." @@ -2902,8 +2210,6 @@ - "$unit($unit) wurde in $region($region) von $unit.dative($guard) aufgehalten." - "$unit($unit) was kept in $region($region) by $unit($guard)." @@ -2911,40 +2217,30 @@ - "$unit($unit) konnte nicht von $region($region) nach $region($target) reisen, da der Besitzer der Region es verhinderte." - "$unit($unit) could not travel from $region($region) to $region($target) because the owner denied entrance." - "$unit($unit) konnte aus $region($region) nicht ausreisen." - "$unit($unit) could not leave $region($region)." - "$unit($follower) ist $unit($unit) gefolgt." - "$unit($follower) followed $unit($unit)." - "$unit($follower) konnte $unit($unit) nicht folgen." - "$unit($follower) could not follow $unit($unit)." - "$unit($unit) entdeckt, dass es keinen Weg nach $direction($direction) gibt." - "$unit($unit) discovers that there is no route going $direction($direction)." @@ -2952,22 +2248,16 @@ - "$unit($unit) konnte von $region($region) nicht nach $direction($direction) ausreisen, der Nebel war zu dicht." - "$unit($unit) could not travel $direction($direction) from $region($region), the fog was too dense." - "In $region($region) erschienen die Herren der Bäume." - "In $region($region), the Lords of the Trees have risen." - "In $region($region) erhoben sich die Toten aus den Gräbern." - "The dead rise from their graves in $region($region)." @@ -2975,30 +2265,22 @@ - "$unit($unit) vermehrt sich um $int($amount) $race($race,$amount)." - "$unit($unit) breeds $int($amount) new $race($race,$amount)." - "Die Partei bekommt einen Spitznamen." - "Your faction received a nickname." - "Die Partei bekommt von $unit.dative($unit) in $region($region) einen Spitznamen." - "Your faction received a nickname from $unit($unit) in $region($region)." - "$building($building) in $region($region) bekommt einen Spitznamen." - "$building($building) in $region($region) received a nickname." @@ -3006,16 +2288,12 @@ - "$building($building) in $region($region) bekommt von $unit.dative($renamer) einen Spitznamen." - "$building($building) in $region($region) received a nickname from $unit($renamer)." - "Die $ship($ship) in $region($region) bekommt einen Spitznamen." - "$ship($ship) in $region($region) received a nickname." @@ -3023,16 +2301,12 @@ - "Die $ship($ship) in $region($region) bekommt von $unit.dative($renamer) einen Spitznamen." - "$ship($ship) in $region($region) received a nickname from $unit($renamer)." - "$unit($renamed) in $region($region) bekommt einen Spitznamen." - "$unit($renamed) in $region($region) received a nickname." @@ -3040,30 +2314,22 @@ - "$unit($renamed) in $region($region) bekommt von $unit.dative($renamer) einen Spitznamen." - "$unit($renamed) in $region($region) received a nickname from $unit($renamer)." - "$if($eq($dead,1),"Ein Bauer verhungert","$int($dead) Bauern verhungern")." - "$if($eq($dead,1),"One peasant starves","$int($dead) peasants starve")." - "Der Vulkan in $region($region) bricht aus." - "The volcano in $region($region) erupts." - "Der Vulkan in $region($regionv) bricht aus. Die Lavamassen verwüsten $region($regionn)." - "The volcano in $region($regionv) erupts. The lava devastates $region($regionn)." @@ -3071,30 +2337,22 @@ - "Beim Vulkanausbruch in $region($region) sterben $int($dead) Personen in $unit($unit)." - "$int($dead) people in $unit($unit) perish when the volcano in $region($region) erupts." - "Aus dem Vulkankrater von $region($region) steigt kein Rauch mehr." - "The volcano of $region($region) stops releasing smoke." - "Aus dem Vulkankrater von $region($region) steigt plötzlich Rauch." - "Columns of smoke are released by the volcano of $region($region)." - "$unit($unit) in $region($region) desertiert." - "$unit($unit) in $region($region) abandons your cause." @@ -3102,16 +2360,12 @@ - "$unit($unit) reißt die Straße zwischen $region($from) und $region($to) ein." - "$unit($unit) demolishes the road between $region($from) and $region($to)." - "$unit($unit) in $region($region) kann keine Kräuter finden." - "$unit($unit) could not find any herbs in $region($region)." @@ -3120,24 +2374,18 @@ - "$unit($unit) in $region($region) stellt fest, dass es hier $localize($amount) $resource($herb,0) gibt." - "$unit($unit) discovers that $localize($amount) $resource($herb,0) grow in $region($region)." - "$unit($unit) reißt einen Teil von $building($building) ein." - "$unit($unit) tears down parts of $building($building)." - "$unit($unit) zerstört $building($building)." - "$unit($unit) destroys $building($building)." @@ -3145,8 +2393,6 @@ - "$unit($unit) erweitert in $region($region) das Straßennetz um $int($size)." - "$unit($unit) extends the road network in $region($region) by $int($size)." @@ -3154,16 +2400,12 @@ - "$unit($unit) $if($eq($amount,1),"schließt","schließen") sich $int($amount) $resource($rtype,$amount) an." - "$int($amount) $resource($rtype,$amount) $if($eq($amount,1),"joins","join") $unit($unit)." - "$unit($mage) legt einen Schleier um die Ausrüstung von $unit.dative($target)." - "$unit($mage) shrouds the equipment of $unit($target) in shadows." @@ -3172,8 +2414,6 @@ - "$if($isnull($ship),"$unit($unit)","Die $ship($ship)") in $region($region) entdeckt ein Opfer im $direction($dir)." - "$if($isnull($ship),"$unit($unit)","The $ship($ship)") in $region($region) made $direction($dir) a target." @@ -3181,22 +2421,16 @@ - "$if($isnull($ship),"$unit($unit)","Die $ship($ship)") in $region($region) kann keine Schiffe aufbringen." - "$if($isnull($ship),"$unit($unit)","The $ship($ship)") could not capture other ships in $region($region)." - "Langsam kehren andere Völker nach $region($region) zurück." - "Little by little, people return to $region($region)." - "Vor den vielen Orks in $region($region) fliehen die anderen Einwohner." - "People in $region($region) flee because of too many orcs." @@ -3204,8 +2438,6 @@ - "$unit($unit) in $region($region) beschädigt die $ship($ship)." - "$unit($unit) in $region($region) damages the $ship($ship)." @@ -3213,23 +2445,17 @@ - "$unit($unit) in $region($region) versenkt die $ship($ship)." - "$unit($unit) sunk $ship($ship) in $region($region)." - "$unit($unit) marschiert in eine Antimagiezone und löst sich auf." - "$unit($unit) walks into an antimagical zone and dissolves." - "$int($amount) Bauern flohen aus Furcht vor $unit($unit)." - "$int($amount) peasants fled in fear of $unit($unit)." @@ -3237,59 +2463,43 @@ - "$int($amount) Bauern werden zu $race($race,0) und schliessen sich $unit($unit) an." - "$int($amount) peasants become $race($race,0) and join the ranks of $unit($unit)." - "$unit($unit) verspeiste $int($amount) Pferde." - "$unit($unit) ate $int($amount) horses." - "$unit($unit) verspeiste $int($amount) Bauern." - "$unit($unit) ate $int($amount) peasants." - "Deine Befehle hatten ein falsches Passwort (${password})." - "Your orders had the wrong password (${password})." - "Das Passwort für diese Partei lautet ${value}." - "The password of this faction is '$value'." - "Die Reportadresse wurde nicht geändert, '${value}' ist keine gültige email." - "Address not changed, '$value' is an invalid email." - "Die Reportadresse wurde auf ${value} geändert." - "Address has been changed to '$value'." - "Das Banner wurde auf '$value' geändert." - "Banner has been changed to '$value'." @@ -3298,8 +2508,6 @@ - "Eine Partei muß mindestens $int($turns) Wochen alt sein, bevor sie angegriffen oder bestohlen werden kann." - "A faction must be at least $int($turns) weeks old before it can be attacked or stolen from." @@ -3307,47 +2515,35 @@ - "$unit($unit) wurden in $region($region) $int($amount) Silberstücke geklaut." - "In $region($region), thieves stole $int($amount) silver from $unit($unit)." - "$unit($target) ertappte $unit($unit) beim versuchten Diebstahl." - "$unit($target) caught $unit($unit) in attempted theft." - "$unit($unit) wurde von $unit.dative($target) beim versuchten Diebstahl ertappt." - "$unit($unit) was caught by $unit($target) in attempted theft." - "$unit($unit) fühlt sich beobachtet." - "$unit($unit) feels watched." - "$unit($unit) gelang es nicht, sich nahe genug an $unit($target) heranzuschleichen." - "$unit($unit) could not sneak close enough to $unit($target)." - "$unit($spy) gelang es nicht, etwas über $unit($target) herauszufinden." - "$unit($spy) could not find out anything about $unit($target)." @@ -3355,8 +2551,6 @@ - "$unit($spy) gelang es, Informationen über $unit($target) herauszubekommen: Kampfstatus ${status}." - "$unit($spy) managed to gather information about $unit($target): combat status ${status}." @@ -3364,8 +2558,6 @@ - "$unit($target) ist ein ${type}-Magier." - "$unit($target) is a ${type}-magician" @@ -3373,8 +2565,6 @@ - "$unit($target) beherrscht ${skills}." - "$unit($target) knows ${skills}." @@ -3382,8 +2572,6 @@ - "Im Gepäck von $unit($target) sind $resources($items)." - "$unit($target) carries $resources($items)" @@ -3391,16 +2579,12 @@ - "$unit($target) gehört der Partei $faction($faction) an." - "$unit($target) belongs to $faction($faction)." - "$unit($target) fühlt sich $if($isnull($spy),"","durch $unit($spy) ")beobachtet." - "$unit($target) feels watched$if($isnull($spy),""," by $unit($spy)")." @@ -3408,8 +2592,6 @@ - "$faction($from) gibt ein Almosen von $int($amount) Silber an $faction($to)." - "$faction($from) donates $int($amount) silver to $faction($to)." @@ -3417,16 +2599,12 @@ - "$unit($unit) vergisst durch Dumpfbackenbrot $int($weeks) Wochen des Talentes $skill($skill)." - "$unit($unit) eats a duncebuns and forgets $int($weeks) weeks worth of $skill($skill)." - "$unit($unit) in $region($region) wird durch unzureichende Nahrung geschwächt." - "$unit($unit) is weakened due to malnourishment." @@ -3435,8 +2613,6 @@ - "$unit($unit) verliert in $region($region) $int($dead) von $int($add($live,$dead)) Personen durch Unterernährung." - "$unit($unit) loses $int($dead) of $int($add($live,$dead)) people due to starvation in $region($region)." @@ -3444,30 +2620,22 @@ - "$unit($unit): '$order($command)' - Die Einheit benutzt bereits $resource($using,0)." - "$unit($unit): '$order($command)' - The unit already uses $resource($using,0)." - "$if($eq($births,1),"Einen Bauern","$int($births) Bauern") besucht unverhofft der Storch." - "The stork paid an unexpected visit to $if($eq($births,1),"a peasant","$int($births) peasants")." - "Die $ship($ship) ist zu stark beschädigt und sinkt." - "The $ship($ship) has suffered too much damage and sinks." - "Die $ship($ship) entdeckt, dass $region($region) Festland ist." - "The $ship($ship) discovers that $region($region) is dry land." @@ -3475,8 +2643,6 @@ - "Die $ship($ship) fliegt von $region($from) nach $region($to)." - "The $ship($ship) flies from $region($from) to $region($to)." @@ -3484,8 +2650,6 @@ - "Die $ship($ship) segelt von $region($from) nach $region($to)." - "The $ship($ship) sails from $region($from) to $region($to)." @@ -3493,8 +2657,6 @@ - "Die $ship($ship) wird in $region($region) von Stürmen abgetrieben$if($sink," und sinkt","")." - "The $ship($ship) in $region($region) gets off course in heavy storm$if($sink," and sinks","")." @@ -3503,24 +2665,18 @@ - "Die $ship($ship) fährt in den Mahlstrom von $region($region) und nimmt $int($damage) Schaden$if($sink," und sinkt","")." - "The $ship($ship) sails into the maelstrom of $region($region) and takes $int($damage) damage$if($sink,". The ship sinks","")." - "$unit($unit) vergisst $skill($skill)." - "$unit($unit) forgets $skill($skill)." - "$unit($unit) gibt das Kommando an $unit($recipient)." - "$unit($unit) gave control to $unit($recipient)." @@ -3528,8 +2684,6 @@ - "$unit($unit) gibt $int($amount) Dumpfbackenbrot an $unit($recipient)." - "$unit($unit) administers $int($amount) duncebuns to $unit($recipient)." @@ -3538,8 +2692,6 @@ - "$unit($unit) in $region($region) rekrutiert $int($amount) von $int($want) Personen." - "$unit($unit) in $region($region) recruits $int($amount) of $int($want) people." @@ -3547,16 +2699,12 @@ - "$unit($unit) belagert $building($building). Dabei richten die Katapulte Zerstörungen von $int($destruction) Größenpunkten an." - "$building($building) is under siege by $unit($unit). During siege, catapults caused $int($destruction) points destruction." - "$unit($unit) belagert $building($building)." - "$building($building) is under siege by $unit($unit)." @@ -3564,8 +2712,6 @@ - "$unit($unit) ertrinkt beim Untergang der $ship($ship) in $region($region)." - "$unit($unit) drowns when $ship($ship) in $region($region) sinks." @@ -3574,10 +2720,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann nicht bewachen, da sie versucht zu fliehen." - "$unit($unit) in $region($region): - '$order($command)' - The unit cannot guard the region because it - is trying to flee." @@ -3586,8 +2728,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann den Befehl in dieser Runde nicht ausführen, da sie an einem Kampf teilgenommen hat." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot execute this command because it has been in combat." @@ -3596,8 +2736,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Gebäude kann nur einmal pro Runde erweitert werden." - "$unit($unit) in $region($region): '$order($command)' - The building can be expanded only once per turn." @@ -3606,8 +2744,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieses Objekt ist unzerstörbar." - "$unit($unit) in $region($region): '$order($command)' - This object is indestructible." @@ -3615,8 +2751,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Ohne Zutaten kann ein Alchemist nichts herstellen." - "$unit($unit) in $region($region): '$order($command)' - Without ingredients an alchemist can not produce anything." @@ -3624,8 +2758,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Nicht alle Zutaten vorhanden." - "$unit($unit) in $region($region): '$order($command)' - Not all ingredients present." @@ -3633,8 +2765,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Eine Partei kann nur einmal neu starten." - "$unit($unit) in $region($region): '$order($command)' - Restart can only be used once." @@ -3642,8 +2772,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Werwesen können nicht arbeiten." - "$unit($unit) in $region($region): '$order($command)' - Lycantropes don't work." @@ -3651,8 +2779,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Werwesen können nicht mit anderen Personen gemischt werden." - "$unit($unit) in $region($region): '$order($command)' - Lycantropes may not be mixed with normal people." @@ -3660,8 +2786,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann sich nicht verwandeln." - "$unit($unit) in $region($region): '$order($command)' - This unit can not change shape." @@ -3669,8 +2793,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diese Einheit ist kein Werwesen." - "$unit($unit) in $region($region): '$order($command)' - This unit is not in lycantropic form." @@ -3678,8 +2800,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diese Einheit ist schon ein Werwesen." - "$unit($unit) in $region($region): '$order($command)' - This unit already assumed lycantropic form." @@ -3687,8 +2807,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieses Talent kann nicht höher gelernt werden." - "$unit($unit) in $region($region): '$order($command)' - This skill cannot be raised any higher." @@ -3696,8 +2814,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Snotlinge sind zu dumm, um auf den Feldern zu arbeiten." - "$unit($unit) in $region($region): '$order($command)' - We snotlings is too stupid fer dat!" @@ -3705,8 +2821,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Partei muß mindestens 9 Wochen alt sein, um einen Neustart zu versuchen." - "$unit($unit) in $region($region): '$order($command)' - Your faction is not old enough to start over." @@ -3714,8 +2828,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Optionen ZIP und BZIP2 können nur um-, nicht ausgeschaltet werden." - "$unit($unit) in $region($region): '$order($command)' - Options ZIP and BZIP2 can only be switched, not turned off." @@ -3723,8 +2835,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Einheiten einer Partei, die noch immun gegen Angriffe ist, dürfen nicht bewachen." - "$unit($unit) in $region($region): '$order($command)' - Units of a faction that can't be attacked may not guard." @@ -3732,8 +2842,6 @@ - "$unit($unit) in $region($region): '$order($command)' - In dieser Region kann man nichts verkaufen." - "$unit($unit) in $region($region): '$order($command)' - No trade is possible in this region." @@ -3741,8 +2849,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Bereits ein Synonym gesetzt." - "$unit($unit) in $region($region): '$order($command)' - Synonym already set." @@ -3750,8 +2856,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Kein Synonym angegeben." - "$unit($unit) in $region($region): '$order($command)' - Synonym missing." @@ -3759,8 +2863,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Ungültiges Synonym." - "$unit($unit) in $region($region): '$order($command)' - Invalid synonym." @@ -3768,8 +2870,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Ungültiges Prefix." - "$unit($unit) in $region($region): '$order($command)' - Invalid prefix." @@ -3777,8 +2877,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Magier hat bereits einen Klon." - "$unit($unit) in $region($region): '$order($command)' - The magician already has a clone." @@ -3786,8 +2884,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Gebäude auf dem Ozean können nicht betreten werden." - "$unit($unit) in $region($region): '$order($command)' - Buildings on the ocean may not be entered." @@ -3795,8 +2891,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier werden niemals Bäume wachsen." - "$unit($unit) in $region($region): '$order($command)' - Trees won't grow here." @@ -3804,8 +2898,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Nur ein Magier kann einen Astralkristall benutzen." - "$unit($unit) in $region($region): '$order($command)' - Only mages may use an astralcrystal." @@ -3813,7 +2905,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Verbände können nur zwischen Einheiten derselben Partei gebildet werden." @@ -3821,7 +2912,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist in keinem Verband." @@ -3829,7 +2919,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Eine Einheit kann nur in einem Verband Mitglied sein." @@ -3837,8 +2926,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Wie sollen wir uns tarnen?" - "$unit($unit) in $region($region): '$order($command)' - What should we disguise as?" @@ -3846,8 +2933,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Wieviel sollen wir einreißen?" - "$unit($unit) in $region($region): '$order($command)' - How much shall we tear down?" @@ -3855,8 +2940,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dorthin können wir die Einheit nicht transportieren." - "$unit($unit) in $region($region): '$order($command)' - We cannot transport this unit there." @@ -3864,8 +2947,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit transportiert uns nicht." - "$unit($unit) in $region($region): '$order($command)' - The unit is not transporting us." @@ -3873,8 +2954,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diese Einheit kennt keine Trankrezepte." - "$unit($unit) in $region($region): '$order($command)' - This unit knows no recipes for potions." @@ -3882,8 +2961,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Nur noch nicht gestärkte Untote können das Ziel dieses Zaubers sein." - "$unit($unit) in $region($region): '$order($command)' - Undead can only be affected once by this spell." @@ -3891,8 +2968,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Passwort darf nur Buchstaben und Ziffern enthalten." - "$unit($unit) in $region($region): '$order($command)' - Your password may only contain alphanumeric symbols." @@ -3900,8 +2975,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Gegen diese Rasse kann kein Jihad ausgerufen werden." - "$unit($unit) in $region($region): '$order($command)' - You cannot start a jihad against this race." @@ -3909,8 +2982,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Gegen welche Rasse soll der Jihad ausgerufen werden?" - "$unit($unit) in $region($region): '$order($command)' - What race did you want the jihad to be against?" @@ -3918,7 +2989,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dazu muss erst die Spezialeigenschaft erworben werden." @@ -3926,8 +2996,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Name und Beschreibung des Gebäudes können nicht geändert werden." - "$unit($unit) in $region($region): '$order($command)' - You cannot change the name and description of this building." @@ -3935,8 +3003,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das kann die Einheit nicht." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot do this." @@ -3944,8 +3010,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier kann man keine Schiffe bauen." - "$unit($unit) in $region($region): '$order($command)' - Ships cannot be built here." @@ -3953,8 +3017,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier kann man keine Gebäude errichten." - "$unit($unit) in $region($region): '$order($command)' - Buildings cannot be built here." @@ -3962,8 +3024,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann nicht unterrichten." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot teach." @@ -3971,8 +3031,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier kann man nicht unterrichten." - "$unit($unit) in $region($region): '$order($command)' - You cannot teach here." @@ -3980,8 +3038,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Pferde müssen leider draußen bleiben." - "$unit($unit) in $region($region): '$order($command)' - Horses are not allowed inside." @@ -3989,8 +3045,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier kann man niemanden angreifen." - "$unit($unit) in $region($region): '$order($command)' - You cannot attack here." @@ -3998,7 +3052,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier kann man niemanden bestehlen." @@ -4006,8 +3059,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier kann man nicht zaubern." - "$unit($unit) in $region($region): '$order($command)' - You cannot cast spells here." @@ -4015,8 +3066,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier kann man nichts übergeben." - "$unit($unit) in $region($region): '$order($command)' - You cannot transfer items here." @@ -4024,8 +3073,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Nur eine Einzelperson kann das Ticket benutzen." - "$unit($unit) in $region($region): '$order($command)' - Only a single person can use the ticket." @@ -4033,8 +3080,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Gegenstand funktioniert nur in der Eingangshalle." - "$unit($unit) in $region($region): '$order($command)' - This item only functions in the entry hall." @@ -4042,8 +3087,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Gegenstand funktioniert nur in der normalen Welt." - "$unit($unit) in $region($region): '$order($command)' - This item only works in the normal world." @@ -4051,8 +3094,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieses Gut hat die Einheit nicht." - "$unit($unit) in $region($region): '$order($command)' - The unit does not have this good." @@ -4060,8 +3101,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieses Gut wird hier produziert." - "$unit($unit) in $region($region): '$order($command)' - This good is not produced here." @@ -4069,8 +3108,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Partei kann keine weiteren Wyrme besitzen." - "$unit($unit) in $region($region): '$order($command)' - The faction cannot have any more wyrms." @@ -4078,8 +3115,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Vor den Besitzer eines Schiffes oder Gebäudes kann nicht sortiert werden." - "$unit($unit) in $region($region): '$order($command)' - You cannot sort before the owner of a ship or a building." @@ -4087,8 +3122,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Besitzer eines Schiffes oder Gebäudes kann nicht neu sortiert werden." - "$unit($unit) in $region($region): '$order($command)' - The owner of a ship or a building cannot be sorted." @@ -4096,8 +3129,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Befehl ist nur auf Einheiten innerhalb des selben Gebäudes oder Schiffes anwendbar." - "$unit($unit) in $region($region): '$order($command)' - That order only applies to units in the same building or ship." @@ -4105,8 +3136,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Zieleinheit ist ungültig." - "$unit($unit) in $region($region): '$order($command)' - The target unit is invalid." @@ -4114,8 +3143,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Ungültiges Locale." - "$unit($unit) in $region($region): '$order($command)' - Invalid locale." @@ -4123,8 +3150,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Um so etwas kann man nicht beten." - "$unit($unit) in $region($region): '$order($command)' - You cannot pray for this." @@ -4132,8 +3157,6 @@ - "$unit($unit) in $region($region): '$order($command)' - So etwas kann man nicht opfern." - "$unit($unit) in $region($region): '$order($command)' - You cannot sacrifice this." @@ -4141,8 +3164,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Auraangabe fehlerhaft oder zuwenig Aura." - "$unit($unit) in $region($region): '$order($command)' - Invalid aura specification or not enough aura." @@ -4150,8 +3171,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Magier ist nicht stark genug, sich den Göttern zu opfern." - "$unit($unit) in $region($region): '$order($command)' - This magician is not strong enough to be sacrificed to the gods." @@ -4159,8 +3178,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Was und wieviel soll geopfert werden?" - "$unit($unit) in $region($region): '$order($command)' - What and how much should be sacrificed?" @@ -4168,8 +3185,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diese Kraft können selbst die Götter nicht mehr mächtiger machen." - "$unit($unit) in $region($region): '$order($command)' - Even the gods cannot improve this power." @@ -4177,8 +3192,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Nicht genug Karma." - "$unit($unit) in $region($region): '$order($command)' - Not enough karma." @@ -4186,8 +3199,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Schiff kann nicht aufs offene Meer hinaus segeln." - "$unit($unit) in $region($region): '$order($command)' - The ship cannot sail into the open seas." @@ -4195,8 +3206,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Partei muß mindestens 10 Runden alt sein." - "$unit($unit) in $region($region): '$order($command)' - The faction has to be 10 turns old." @@ -4204,8 +3213,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Partei hat schon einen Namen." - "$unit($unit) in $region($region): '$order($command)' - The faction is already named." @@ -4213,8 +3220,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Gebäude hat schon einen Namen." - "$unit($unit) in $region($region): '$order($command)' - The building is already named." @@ -4222,8 +3227,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Schiff hat schon einen Namen." - "$unit($unit) in $region($region): '$order($command)' - The ship is already named." @@ -4231,8 +3234,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat schon einen Namen." - "$unit($unit) in $region($region): '$order($command)' - The unit is already named." @@ -4240,8 +3241,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Keine gültige Rasse angegeben." - "$unit($unit) in $region($region): '$order($command)' - You did not specify a valid race." @@ -4249,8 +3248,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit muß sich an Land befinden." - "$unit($unit) in $region($region): '$order($command)' - The unit must be on land." @@ -4260,8 +3257,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $building($building) ist kein Steinkreis." - "$unit($unit) in $region($region): '$order($command)' - $building($building) is not a stone circle." @@ -4271,8 +3266,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $building($building) muss vor der Weihe fertiggestellt sein." - "$unit($unit) in $region($region): '$order($command)' - $building($building) has to be complete before it can be blessed." @@ -4282,8 +3275,6 @@ - "$unit($unit) in $region($region): '$order($command)' - In $region($target) sind keine Gräber." - "$unit($unit) in $region($region): '$order($command)' - There are no graves in $region($target)." @@ -4291,8 +3282,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Partei muß mindestens 81 Wochen alt sein, um einen Neustart mit einer anderen Rasse zu versuchen." - "$unit($unit) in $region($region): '$order($command)' - The faction must be at least 81 weeks old to restart with a new race." @@ -4300,8 +3289,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Soll eine Einheit oder ein Schiff verfolgt werden?" - "$unit($unit) in $region($region): '$order($command)' - Is a unit or a ship supposed to be followed?" @@ -4309,8 +3296,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Soll eine Einheit oder ein Schiff eine neue Nummer bekommen?" - "$unit($unit) in $region($region): '$order($command)' - Is a unit or a ship supposed to get a new number?" @@ -4318,8 +3303,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier können nur Orks rekrutiert werden." - "$unit($unit) in $region($region): '$order($command)' - You can recruit only orcs here." @@ -4327,8 +3310,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Region befindet sich in Aufruhr." - "$unit($unit) in $region($region): '$order($command)' - There are riots in this region." @@ -4336,8 +3317,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Gebäude ist noch nicht fertig gebaut." - "$unit($unit) in $region($region): '$order($command)' - The building is not finished yet." @@ -4345,8 +3324,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Für das Gebäude wurde noch kein Unterhalt bezahlt." - "$unit($unit) in $region($region): '$order($command)' - Maintenance has not been paid yet." @@ -4354,8 +3331,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist mit Ausschiffen beschäftigt.." - "$unit($unit) in $region($region): '$order($command)' - The unit is busy disembarking." @@ -4363,8 +3338,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Typ Einheit kann keine Schiffe betreten." - "$unit($unit) in $region($region): '$order($command)' - Swimmers cannot enter ships." @@ -4372,8 +3345,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Typ Einheit kann keine Gebäude betreten." - "$unit($unit) in $region($region): '$order($command)' - This type of unit cannot enter a building." @@ -4381,8 +3352,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit oder ihre Tiere würden dort nicht überleben." - "$unit($unit) in $region($region): '$order($command)' - The unit or its animals would not survive there." @@ -4390,8 +3359,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dorthin kann die Einheit uns nicht transportieren." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot transport us to this place." @@ -4400,8 +3367,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $building($building) wird belagert." - "$unit($unit) in $region($region): '$order($command)' - $building($building) is under siege." @@ -4410,8 +3375,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Eintritt in $building($building) wurde verwehrt." - "$unit($unit) in $region($region): '$order($command)' - Entrance to $building($building) was denied." @@ -4419,8 +3382,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Ein Vertrauter wird beschworen, verschwindet jedoch wieder, als er keine Verbindung zu seinem Element herstellen kann." - "$unit($unit) in $region($region): '$order($command)' - A familiar is summoned, but it disappears again when it cannot get in contact with its natural element." @@ -4428,8 +3389,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Nur normale Personen können Steuern eintreiben." - "$unit($unit) in $region($region): '$order($command)' - Only normal characters can collect taxes." @@ -4437,8 +3396,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dafür braucht ein Einheit mindestens Kräuterkunde 7." - "$unit($unit) in $region($region): '$order($command)' - A herbalism skill of 7 or higher is required." @@ -4446,8 +3403,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Einheiten in den hinteren Reihen können nicht angreifen." - "$unit($unit) in $region($region): '$order($command)' - Units from the backmost rows cannot attack." @@ -4455,8 +3410,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Unbekannter Kampfstatus." - "$unit($unit) in $region($region): '$order($command)' - Unknown combat status." @@ -4464,8 +3417,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist nicht bewaffnet und kampffähig." - "$unit($unit) in $region($region): '$order($command)' - The unit is not armed and ready to fight." @@ -4473,8 +3424,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Partei hat bereits ein Magiegebiet." - "$unit($unit) in $region($region): '$order($command)' - The faction has already chosen a magical school." @@ -4483,8 +3432,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $race($race,0) können nicht arbeiten." - "$unit($unit) in $region($region): '$order($command)' - $race($race,0) cannot work." @@ -4492,8 +3439,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hungernde Soldaten kämpfen nicht." - "$unit($unit) in $region($region): '$order($command)' - Starving units do not fight." @@ -4501,8 +3446,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hungernde Einheiten können nicht zaubern." - "$unit($unit) in $region($region): '$order($command)' - Starving units cannot cast spells." @@ -4510,8 +3453,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hungernde Einheiten können nicht bewachen." - "$unit($unit) in $region($region): '$order($command)' - Starving units cannot guard." @@ -4519,8 +3460,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Zeige alle was?" - "$unit($unit) in $region($region): '$order($command)' - Show all what?" @@ -4528,8 +3467,6 @@ - "$unit($unit) in $region($region): '$order($command)' - So etwas kann man hier nicht bauen." - "$unit($unit) in $region($region): '$order($command)' - You cannot build this here." @@ -4537,8 +3474,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Im astralen Nebel konnte niemand entdeckt werden." - "$unit($unit) in $region($region): '$order($command)' - No one could be seen in the astral fog." @@ -4546,8 +3481,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Ein Zauber in dieser Region verhindert das." - "$unit($unit) in $region($region): '$order($command)' - There is an active spell in this region that prevents this." @@ -4555,8 +3488,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Zauber kann nur im Astralraum gezaubert werden." - "$unit($unit) in $region($region): '$order($command)' - This spell can only be cast on the astral plane." @@ -4564,8 +3495,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier gibt es keine Verbindung zur astralen Welt." - "$unit($unit) in $region($region): '$order($command)' - There is no connection to the astral plane here." @@ -4573,8 +3502,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Von hier aus kann man die astrale Ebene nicht erreichen." - "$unit($unit) in $region($region): '$order($command)' - You cannot reach the astral plane from here." @@ -4582,8 +3509,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Einheit ist kein Magier." - "$unit($unit) in $region($region): '$order($command)' - Unit is not a magician." @@ -4591,8 +3516,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Parameter nicht korrekt angegeben." - "$unit($unit) in $region($region): '$order($command)' - Incorrect parameter." @@ -4600,8 +3523,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Magier befindet sich nicht auf einem Schiff." - "$unit($unit) in $region($region): '$order($command)' - The magician is not on board a ship." @@ -4609,8 +3530,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Auf dem Schiff liegt bereits so ein Zauber." - "$unit($unit) in $region($region): '$order($command)' - The ship is already under this spell." @@ -4618,8 +3537,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es ist zu gefährlich, ein sturmgepeitschtes Schiff fliegen zu lassen." - "$unit($unit) in $region($region): '$order($command)' - It is too dangerous to fly the ship in the storm." @@ -4627,8 +3544,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Syntax Error." - "$unit($unit) in $region($region): '$order($command)' - Syntax Error." @@ -4636,8 +3551,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Auraangabe fehlerhaft." - "$unit($unit) in $region($region): '$order($command)' - Wrong aura values." @@ -4645,8 +3558,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Zu dieser Einheit kann keine Aura übertragen werden." - "$unit($unit) in $region($region): '$order($command)' - You cannot transfer aura to this unit." @@ -4654,8 +3565,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Auf dem Gebäude liegt bereits so ein Zauber." - "$unit($unit) in $region($region): '$order($command)' - There is alrady a spell on that building." @@ -4664,8 +3573,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Zauber kann nicht auf hoher See gezaubert werden." - "$unit($unit) in $region($region): '$order($command)' - This spell cannot be cast while you are on the ocean." @@ -4674,8 +3581,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Zauber kann nicht auf Monster gezaubert werden." - "$unit($unit) in $region($region): '$order($command)' - This spell cannot be cast on monsters." @@ -4684,8 +3589,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Zauber kann nicht auf Untote gezaubert werden." - "$unit($unit) in $region($region): '$order($command)' - This spell cannot be cast on undead." @@ -4694,8 +3597,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Stimmung in der Region ist so schlecht, dass niemand auf den Zauber reagiert." - "$unit($unit) in $region($region): '$order($command)' - The mood in this region is so bad that nobody reacts to the spell." @@ -4706,8 +3607,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($target) wusste trotz intensivem Verhör nichts über $region($tregion) zu berichten." - "$unit($unit) in $region($region): '$order($command)' - Despite intense questioning, $unit($target) did not have anything to tell about $region($tregion)." @@ -4716,8 +3615,6 @@ - "$unit($unit) in $region($region): '$order($command)' - So viele Persoenen übersteigen die Kräfte des Magiers." - "$unit($unit) in $region($region): '$order($command)' - This many people exceed the powers of the magician." @@ -4727,8 +3624,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($target) hat unaufkündbare Bindungen an seine alte Partei." - "$unit($unit) in $region($region): '$order($command)' - $unit($target) have unbreakable commitments to their faction." @@ -4737,8 +3632,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Zauber gelingt nur in einer Ozeanregion." - "$unit($unit) in $region($region): '$order($command)' - This spell works only in an ocean region." @@ -4746,8 +3639,6 @@ - "$unit($unit) in $region($region): '$order($command)' - In einer Region ohne Bäume kann man diesen Zauber nicht wirken." - "$unit($unit) in $region($region): '$order($command)' - You cannot cast this spell in a region without trees." @@ -4755,8 +3646,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Ziel wurde vergessen." - "$unit($unit) in $region($region): '$order($command)' - No target has been supplied." @@ -4764,8 +3653,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das ist keine gültige Rasse." - "$unit($unit) in $region($region): '$order($command)' - This is not a valid race." @@ -4773,8 +3660,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Rasse und Zieleinheit wurden vergessen." - "$unit($unit) in $region($region): '$order($command)' - Race and target unit have not been supplied." @@ -4782,8 +3667,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die maximale Aura reicht nicht für diesen Zauber." - "$unit($unit) in $region($region): '$order($command)' - Magician's maximum aura is not high enough for this spell." @@ -4791,8 +3674,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Magier hat bereits einen Vertrauten." - "$unit($unit) in $region($region): '$order($command)' - The magician already has a familiar." @@ -4800,8 +3681,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Flammen finden keine Nahrung. Das Feuer erlischt, ohne Schaden anzurichten." - "$unit($unit) in $region($region): '$order($command)' - The flames find no kindling. The fire dies quickly, causing no damage whatsoever." @@ -4809,8 +3688,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Um einen Heimstein zu erschaffen, muß der Zauberer in einer Burg sein." - "$unit($unit) in $region($region): '$order($command)' - The magician has to be in a castle to create a homestone." @@ -4818,8 +3695,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das ist keine Waldregion." - "$unit($unit) in $region($region): '$order($command)' - This is not a forest region." @@ -4827,8 +3702,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dorthin führt kein Weg." - "$unit($unit) in $region($region): '$order($command)' - There is no route leading there." @@ -4836,8 +3709,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Zielregion wurde nicht korrekt angegeben." - "$unit($unit) in $region($region): '$order($command)' - Target region was supplied incorrectly." @@ -4845,8 +3716,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Zauber funktioniert nur in der Geisterwelt." - "$unit($unit) in $region($region): '$order($command)' - This spell will only work in the realm of spirits." @@ -4854,8 +3723,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Wege zwischen Geisterwelt und Realität scheinen blockiert zu sein." - "$unit($unit) in $region($region): '$order($command)' - The paths to the spirit world seem to be blocked." @@ -4863,8 +3730,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Zauber funktioniert nur in Wäldern." - "$unit($unit) in $region($region): '$order($command)' - This spell works only in forests." @@ -4872,8 +3737,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Zauber funktioniert nur in der materiellen Welt." - "$unit($unit) in $region($region): '$order($command)' - This spell works only in the material world." @@ -4881,8 +3744,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Selbst der mächtigste Magier der Welt könnte keinen Ozean austrocknen lassen." - "$unit($unit) in $region($region): '$order($command)' - Even the gods cannot dry out an entire ocean." @@ -4890,8 +3751,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Zauber kann nicht im Sumpf gezaubert werden." - "$unit($unit) in $region($region): '$order($command)' - You cannot cast this spell in a swamp." @@ -4899,8 +3758,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Zauber kann nur auf Land gelegt werden." - "$unit($unit) in $region($region): '$order($command)' - This spell only works on dry land." @@ -4908,8 +3765,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Zauber scheint ungewöhnlich schwach zu sein. Irgendetwas hat die magischen Energien abgeleitet." - "$unit($unit) in $region($region): '$order($command)' - The spell seems exceptionally weak. Something has interfred with the magical energies." @@ -4917,8 +3772,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann den Befehl in dieser Runde nicht ausführen, da sie sich bewegt hat." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot execute this command because it has moved." @@ -4926,8 +3779,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit bewegt sich nicht." - "$unit($unit) in $region($region): '$order($command)' - The unit does not move." @@ -4935,8 +3786,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Magier befindet sich nicht auf einem Schiff." - "$unit($unit) in $region($region): '$order($command)' - The magician is not on board a ship." @@ -4944,8 +3793,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Schiff kann in diese Richtung nicht ablegen." - "$unit($unit) in $region($region): '$order($command)' - The ship cannot leave in this direction." @@ -4953,8 +3800,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dazu muß sich der Magier in der Burg oder an Bord des Schiffes befinden." - "$unit($unit) in $region($region): '$order($command)' - To do this, the magician has to be in a castle or on board a ship." @@ -4962,8 +3807,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Zauber schlägt fehl." - "$unit($unit) in $region($region): '$order($command)' - The spell fails." @@ -4971,8 +3814,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieses Magiegebiet kann die Einheit nicht lernen." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot learn this magic sphere." @@ -4980,8 +3821,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es wurde kein Magiegebiet angegeben." - "$unit($unit) in $region($region): '$order($command)' - No magic sphere was supplied." @@ -4989,8 +3828,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diesen Spruch kann der Vertraute nicht zaubern." - "$unit($unit) in $region($region): '$order($command)' - The familiar cannot cast this spell." @@ -4998,8 +3835,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diesen Spruch kann man nicht in die Ferne richten." - "$unit($unit) in $region($region): '$order($command)' - You cannot cast this spell on a distant target." @@ -5007,8 +3842,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diesen Spruch kann man nicht auf einem sich bewegenden Schiff stehend zaubern." - "$unit($unit) in $region($region): '$order($command)' - You cannot cast this spell while standing on a moving ship." @@ -5016,8 +3849,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Zauber ist nur im Kampf sinnvoll." - "$unit($unit) in $region($region): '$order($command)' - This spell only makes sense in combat." @@ -5025,8 +3856,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Selbst in der Bibliothek von Xontormia konnte dieser Spruch nicht gefunden werden." - "$unit($unit) in $region($region): '$order($command)' - Even in the Xontormia Library, this spell could not be found." @@ -5034,8 +3863,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es wurde kein Zauber angegeben." - "$unit($unit) in $region($region): '$order($command)' - There was no spell supplied." @@ -5043,8 +3870,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diesen Kampfzauber gibt es nicht." - "$unit($unit) in $region($region): '$order($command)' - This combat spell does not exist." @@ -5052,8 +3877,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Bauern nehmen dieses großzügige Geschenk nicht an." - "$unit($unit) in $region($region): '$order($command)' - The peasants did not accept this gracious gift." @@ -5061,8 +3884,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diesen Zauber kennt die Einheit nicht." - "$unit($unit) in $region($region): '$order($command)' - The unit does not know this spell." @@ -5070,8 +3891,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es konnten keine Luxusgüter verkauft werden." - "$unit($unit) in $region($region): '$order($command)' - No luxury items could be sold." @@ -5079,8 +3898,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit geht nicht zu den Bauern." - "$unit($unit) in $region($region): '$order($command)' - The unit does not go to the peasants." @@ -5088,8 +3905,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diese Rasse kann eine Burg nicht belagern." - "$unit($unit) in $region($region): '$order($command)' - This race cannot besiege a castle." @@ -5097,8 +3912,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Trank bekommt der Einheit nicht." - "$unit($unit) in $region($region): '$order($command)' - The potion does not agree with the unit." @@ -5106,8 +3919,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Nestwärme kann nur von Insektenvölkern benutzt werden." - "$unit($unit) in $region($region): '$order($command)' - This potion can only be used by insects." @@ -5115,8 +3926,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Heiltrank wird automatisch bei Bedarf benutzt." - "$unit($unit) in $region($region): '$order($command)' - This healing potion will be automatically used when needed." @@ -5124,8 +3933,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit besitzt den Trank nicht." - "$unit($unit) in $region($region): '$order($command)' - The unit does not have this potion." @@ -5133,8 +3940,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es konnten keine Luxusgüter gekauft werden." - "$unit($unit) in $region($region): '$order($command)' - No luxury items could be bought." @@ -5142,8 +3947,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es konnten keine Personen übergeben werden." - "$unit($unit) in $region($region): '$order($command)' - No person could be handed over." @@ -5151,8 +3954,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Magier arbeiten grundsätzlich nur alleine!" - "$unit($unit) in $region($region): '$order($command)' - Magicians always work alone!" @@ -5160,8 +3961,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Partei hat ein anderes Magiegebiet." - "$unit($unit) in $region($region): '$order($command)' - The faction has a different magic sphere." @@ -5169,8 +3968,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Zuviele Alchemisten in der Partei." - "$unit($unit) in $region($region): '$order($command)' - Too many alchemists in the faction." @@ -5178,8 +3975,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Zuviele Magier in der Partei." - "$unit($unit) in $region($region): '$order($command)' - Too many magicians in the faction." @@ -5187,8 +3982,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hochqualifizierte Personen weigern sich, für andere Parteien zu arbeiten." - "$unit($unit) in $region($region): '$order($command)' - Highly qualified people refuse to work for other parties." @@ -5196,8 +3989,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit schließt sich den Bauern an." - "$unit($unit) in $region($region): '$order($command)' - The unit joins the local peasants." @@ -5205,8 +3996,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit springt über Bord und ertrinkt." - "$unit($unit) in $region($region): '$order($command)' - The unit jumps over board and drowns." @@ -5214,8 +4003,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Region wird bewacht." - "$unit($unit) in $region($region): '$order($command)' - The region is guarded." @@ -5223,8 +4010,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Unbekannte Option." - "$unit($unit) in $region($region): '$order($command)' - Unknown option." @@ -5232,8 +4017,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit wird belagert." - "$unit($unit) in $region($region): '$order($command)' - The unit is under siege." @@ -5241,8 +4024,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Zum Straßenbau braucht man Steine." - "$unit($unit) in $region($region): '$order($command)' - You need stones to build a road." @@ -5250,8 +4031,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Wohin soll die Botschaft gehen?" - "$unit($unit) in $region($region): '$order($command)' - Who is supposed to get this message?" @@ -5259,8 +4038,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist nicht der Burgherr." - "$unit($unit) in $region($region): '$order($command)' - The unit is not in command of a castle." @@ -5268,8 +4045,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist nicht Burgherr der größten Burg in der Region." - "$unit($unit) in $region($region): '$order($command)' - The unit is not in command of the largest castle in the region." @@ -5277,8 +4052,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist nicht der Kapitän des Schiffes." - "$unit($unit) in $region($region): '$order($command)' - The unit is not captain of a ship." @@ -5286,8 +4059,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist in keiner Burg." - "$unit($unit) in $region($region): '$order($command)' - The unit is not in a castle." @@ -5295,8 +4066,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist auf keinem Schiff." - "$unit($unit) in $region($region): '$order($command)' - The unit is not on board a ship." @@ -5304,8 +4073,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist auf einem Schiff." - "$unit($unit) in $region($region): '$order($command)' - The unit is on board a ship." @@ -5313,8 +4080,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat zuwenig Silber, um zu rekrutieren." - "$unit($unit) in $region($region): '$order($command)' - The unit does not have enough silver for recruiting." @@ -5322,8 +4087,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat nicht mehr genug Kristalle für so viele Personen." - "$unit($unit) in $region($region): '$order($command)' - The unit does not have enough crystals left for this many people." @@ -5331,8 +4094,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit befindet sich weder in einer Burg noch auf einem Schiff." - "$unit($unit) in $region($region): '$order($command)' - The unit is neither in a castle nor on board a ship." @@ -5340,8 +4101,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Unterschiedliche Typen können nicht gemischt werden." - "$unit($unit) in $region($region): '$order($command)' - Different types do not mix." @@ -5349,8 +4108,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Uns gehört nichts, was man abreißen oder versenken könnte." - "$unit($unit) in $region($region): '$order($command)' - We do not have anything that could be demolished." @@ -5358,8 +4115,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Unbekannter Hilfe-Modus." - "$unit($unit) in $region($region): '$order($command)' - Unknown help mode." @@ -5367,8 +4122,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Unbekannte Meldungs-Option." - "$unit($unit) in $region($region): '$order($command)' - Unknown report option." @@ -5376,8 +4129,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Um in Wüsten Straßen bauen zu können, muß zuerst eine Karawanserei errichtet werden." - "$unit($unit) in $region($region): '$order($command)' - You must build a caravansary before building roads through deserts." @@ -5385,8 +4136,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Um in Sümpfen Straßen bauen zu können, muß zuerst ein Damm errichtet werden." - "$unit($unit) in $region($region): '$order($command)' - You must build a dam before building roads through swamps." @@ -5394,8 +4143,6 @@ - "$unit($unit) in $region($region): '$order($command)' - So viele Leute kann die Partei nicht aufnehmen." - "$unit($unit) in $region($region): '$order($command)' - The faction cannot hire so many people." @@ -5403,8 +4150,6 @@ - "$unit($unit) in $region($region): '$order($command)' - So viele Fremde kann die Partei nicht aufnehmen." - "$unit($unit) in $region($region): '$order($command)' - The faction cannot hire so many strangers." @@ -5412,8 +4157,6 @@ - "$unit($unit) in $region($region): '$order($command)' - So viele Fremde kann Deine Partei nicht aufnehmen." - "$unit($unit) in $region($region): '$order($command)' - Your faction cannot hire so many strangers." @@ -5421,8 +4164,6 @@ - "$unit($unit) in $region($region): '$order($command)' - So etwas kann man nicht verkaufen." - "$unit($unit) in $region($region): '$order($command)' - You cannot sell this." @@ -5430,8 +4171,6 @@ - "$unit($unit) in $region($region): '$order($command)' - So etwas kann man nicht machen." - "$unit($unit) in $region($region): '$order($command)' - You cannot produce this." @@ -5439,8 +4178,6 @@ - "$unit($unit) in $region($region): '$order($command)' - So etwas kann man nicht auf dem Markt kaufen." - "$unit($unit) in $region($region): '$order($command)' - You cannot buy that on a market place." @@ -5448,8 +4185,6 @@ - "$unit($unit) in $region($region): '$order($command)' - So etwas hat die Einheit nicht." - "$unit($unit) in $region($region): '$order($command)' - The unit does not have such a thing." @@ -5457,8 +4192,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Pferde kann man nur in einer Pferdezucht züchten." - "$unit($unit) in $region($region): '$order($command)' - You can only breed horses in a stable." @@ -5466,8 +4199,6 @@ - "$unit($unit) in $region($region): '$order($command)' - So etwas gibt es hier nicht." - "$unit($unit) in $region($region): '$order($command)' - That resource does not exist in this region." @@ -5475,8 +4206,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Personen können nur an Menschen übergeben werden." - "$unit($unit) in $region($region): '$order($command)' - Characters can be given only to human parties." @@ -5484,8 +4213,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Ohne einen Handelsposten gibt es keinen Markt." - "$unit($unit) in $region($region): '$order($command)' - There is no marketplace without at least a tradepost." @@ -5493,8 +4220,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diesen Gegenstand kann die Einheit nicht herstellen." - "$unit($unit) in $region($region): '$order($command)' - This unit cannot produce that." @@ -5502,8 +4227,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diese Rasse kann das nicht herstellen." - "$unit($unit) in $region($region): '$order($command)' - This race cannot produce that." @@ -5511,8 +4234,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Nummer kann nicht vergeben werden." - "$unit($unit) in $region($region): '$order($command)' - Number can not be assigned." @@ -5520,8 +4241,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Nummer ist schon belegt." - "$unit($unit) in $region($region): '$order($command)' - Number is already in use." @@ -5529,8 +4248,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Nummer ist nicht im gültigen Bereich." - "$unit($unit) in $region($region): '$order($command)' - Number is not valid." @@ -5538,8 +4255,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Nichts angegeben, was wir übergeben sollen." - "$unit($unit) in $region($region): '$order($command)' - Item to be handed over was not supplied." @@ -5547,8 +4262,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Namen dürfen keine Klammern enthalten." - "$unit($unit) in $region($region): '$order($command)' - Names may not contain parenthesis." @@ -5556,8 +4269,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Nachricht zu lang - gekürzt." - "$unit($unit) in $region($region): '$order($command)' - Message has been cut (too long)." @@ -5565,8 +4276,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Man muß angeben, ob eine Burg, ein Schiff, eine Region oder eine Einheit beschrieben werden soll." - "$unit($unit) in $region($region): '$order($command)' - Specify if description is for a castle, a ship, a region, or a unit." @@ -5574,8 +4283,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Man muß angeben, ob eine Burg, ein Schiff, eine Einheit, eine Region oder eine Partei benannt werden soll." - "$unit($unit) in $region($region): '$order($command)' - Specify if a castle, a ship, a region, or a unit is supposed to be named." @@ -5583,8 +4290,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es sind keine Kräuter zu finden." - "$unit($unit) in $region($region): '$order($command)' - No herbs could be found." @@ -5592,8 +4297,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Man braucht mindestens zwei Pferde, um sie zu züchten." - "$unit($unit) in $region($region): '$order($command)' - You need at least two horses to breed more." @@ -5601,8 +4304,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Magier müssen zum studieren allein sein." - "$unit($unit) in $region($region): '$order($command)' - When studying, magicians need to be alone." @@ -5610,8 +4311,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Leere Einheiten können nicht übergeben werden." - "$unit($unit) in $region($region): '$order($command)' - Empty units can not be handed over." @@ -5619,8 +4318,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieses Metall kann nur in einem Bergwerk abgebaut werden." - "$unit($unit) in $region($region): '$order($command)' - This metal can be excavated only in a mine." @@ -5628,8 +4325,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Keiner hier kann Straßen bauen." - "$unit($unit) in $region($region): '$order($command)' - Nobody here can build roads." @@ -5637,8 +4332,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann keine weiteren Güter handeln." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot trade any more goods." @@ -5646,8 +4339,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Keiner hier kann ein Gebäude errichten." - "$unit($unit) in $region($region): '$order($command)' - Nobody here can construct a building." @@ -5655,8 +4346,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Keiner hier ist gelernter Schiffbauer." - "$unit($unit) in $region($region): '$order($command)' - Nobody here is a skilled ship builder." @@ -5664,8 +4353,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit will nicht transportiert werden." - "$unit($unit) in $region($region): '$order($command)' - The unit does not want to be transported." @@ -5673,8 +4360,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Insekten können im Winter nur in Wüsten rekrutiert werden." - "$unit($unit) in $region($region): '$order($command)' - In winter, insects can be recruited only in deserts." @@ -5682,8 +4367,6 @@ - "$unit($unit) in $region($region): '$order($command)' - In Gletschern können keine Insekten rekrutiert werden." - "$unit($unit) in $region($region): '$order($command)' - Insects cannot be recruited in glacier regions." @@ -5691,8 +4374,6 @@ - "$unit($unit) in $region($region): '$order($command)' - In dieser Einheit gibt es niemanden, den man transferieren könnte." - "$unit($unit) in $region($region): '$order($command)' - Nobody in this unit can be transferred." @@ -5700,8 +4381,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Illusionen können eine Region nicht bewachen." - "$unit($unit) in $region($region): '$order($command)' - Illusions cannot guard a region." @@ -5709,8 +4388,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier kann man keine Straße bauen." - "$unit($unit) in $region($region): '$order($command)' - You cannot build a road here." @@ -5718,8 +4395,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier gibt es schon einen Hafen." - "$unit($unit) in $region($region): '$order($command)' - There is already a port in this region." @@ -5727,8 +4402,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier gibt es keine Bauern." - "$unit($unit) in $region($region): '$order($command)' - There are no peasants in this region." @@ -5736,8 +4409,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier gibt es keinen normalen Wald." - "$unit($unit) in $region($region): '$order($command)' - There is no normal forest in this region." @@ -5745,8 +4416,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Hier gibt es keine Mallornbäume." - "$unit($unit) in $region($region): '$order($command)' - There are no mallorn trees here." @@ -5754,8 +4423,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit fährt nicht mit uns." - "$unit($unit) in $region($region): '$order($command)' - The unit does not have travel with us." @@ -5763,8 +4430,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Geldgebot fehlt." - "$unit($unit) in $region($region): '$order($command)' - Money offer is missing." @@ -5772,8 +4437,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat nicht genügend Materialien für den Schiffbau." - "$unit($unit) in $region($region): '$order($command)' - The unit is lacking materials for building the ship." @@ -5781,8 +4444,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Für das Elixier benötigt man Drachenblut." - "$unit($unit) in $region($region): '$order($command)' - Dragon blood is required for this elixir." @@ -5790,8 +4451,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Falsches Passwort." - "$unit($unit) in $region($region): '$order($command)' - Wrong password." @@ -5799,8 +4458,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es wurde keine Emailadresse angegeben." - "$unit($unit) in $region($region): '$order($command)' - No email address was supplied." @@ -5808,8 +4465,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es wurde kein Name angegeben." - "$unit($unit) in $region($region): '$order($command)' - No name was supplied." @@ -5817,8 +4472,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es konnte kein Bauer gefangen werden." - "$unit($unit) in $region($region): '$order($command)' - No peasant could be caught." @@ -5826,8 +4479,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es gibt keine Abstimmung mit dieser Nummer." - "$unit($unit) in $region($region): '$order($command)' - There is no agreement with this number." @@ -5835,8 +4486,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Einheit muß zuerst die Region bewachen." - "$unit($unit) in $region($region): '$order($command)' - The unit must first guard the region." @@ -5844,8 +4493,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Einheit ist nicht bewaffnet und kampffähig." - "$unit($unit) in $region($region): '$order($command)' - The unit is not armed and ready to fight." @@ -5853,8 +4500,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Ein Schiff oder eine Burg muß angegeben werden." - "$unit($unit) in $region($region): '$order($command)' - A ship or a castle must be supplied." @@ -5862,8 +4507,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Ein Fluch verhindert die Ãœbergabe." - "$unit($unit) in $region($region): '$order($command)' - A curse prevented the transfer from happening." @@ -5871,8 +4514,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieses Talent wurde nicht erkannt." - "$unit($unit) in $region($region): '$order($command)' - The skill could not be recognized." @@ -5880,8 +4521,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieses Talent kann die Einheit nicht lernen." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot learn this skill." @@ -5889,8 +4528,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diesen Gegenstand kann man nicht benutzen." - "$unit($unit) in $region($region): '$order($command)' - This item cannot be used." @@ -5898,8 +4535,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit nimmt niemanden an." - "$unit($unit) in $region($region): '$order($command)' - This unit does not accept anybody." @@ -5907,8 +4542,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Eine hungernde Einheit kann niemanden weggeben." - "$unit($unit) in $region($region): '$order($command)' - Hungry units cannot give anybody away." @@ -5916,8 +4549,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diese Einheit kann niemanden weggeben." - "$unit($unit) in $region($region): '$order($command)' - This unit cannot give anybody away." @@ -5927,8 +4558,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($target) hat keinen Kontakt mit uns aufgenommen." - "$unit($unit) in $region($region): '$order($command)' - $unit($target) did not contact us." @@ -5937,8 +4566,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es kann hier kein Kontakt zur Astralwelt aufgenommen werden." - "$unit($unit) in $region($region): '$order($command)' - There is no connection to the astral plane here." @@ -5948,8 +4575,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($target) hat keinen Kontakt mit uns aufgenommen und widersteht dem Zauber." - "$unit($unit) in $region($region): '$order($command)' - $unit($target) did not contact us, and resists the spell." @@ -5958,8 +4583,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($target) hat keinen Kontakt mit uns aufgenommen, aber widersteht dem Zauber nicht." - "$unit($unit) in $region($region): '$order($command)' - $unit($target) did not contact us, but cannot resist the spell." @@ -5967,8 +4590,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Richtung wurde nicht erkannt." - "$unit($unit) in $region($region): '$order($command)' - The given direction was not recognized." @@ -5977,8 +4598,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Richtung '$dirname' wurde nicht erkannt." - "$unit($unit) in $region($region): '$order($command)' - Direction '$dirname' was not recognized." @@ -5986,8 +4605,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Region wird von Nichtalliierten bewacht." - "$unit($unit) in $region($region): '$order($command)' - This region is guarded by a non-allied faction." @@ -5996,8 +4613,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Region wird von $unit($guard), einer nichtalliierten Einheit, bewacht." - "$unit($unit) in $region($region): '$order($command)' - This region is guarded by $unit($guard), a non-allied unit." @@ -6005,8 +4620,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Pferde würden ertrinken." - "$unit($unit) in $region($region): '$order($command)' - The horses would drown." @@ -6014,8 +4627,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Partei wurde nicht gefunden." - "$unit($unit) in $region($region): '$order($command)' - The faction could not be found." @@ -6023,8 +4634,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Lernkosten können nicht bezahlt werden." - "$unit($unit) in $region($region): '$order($command)' - Tuition was too high to be paid." @@ -6032,8 +4641,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Gegenstand kann nur in der realen Welt benutzt werden." - "$unit($unit) in $region($region): '$order($command)' - This object can only be used in the real world." @@ -6041,8 +4648,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) ist nicht ausreichend getarnt." - "$unit($unit) in $region($region): '$order($command)' - $unit($unit) is not sufficiently stealthy." @@ -6050,8 +4655,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit wurde nicht gefunden." - "$unit($unit) in $region($region): '$order($command)' - The unit could not be found." @@ -6060,8 +4663,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Einheit kann nichts gegeben werden." - "$unit($unit) in $region($region): '$order($command)' - You cannot give anything to this unit." @@ -6070,8 +4671,6 @@ - "$unit($mage) horcht $unit($unit) über $region($tregion) aus." - "$unit($mage) questions $unit($unit) about $region($tregion)." @@ -6079,16 +4678,12 @@ - "$unit($mage) verschafft $unit($unit) einige feuchtfröhliche Stunden mit heftigen Nachwirkungen." - "$unit($mage) invites $unit($unit) for a few too many drinks and a massive hangover." - "$unit($unit) hat höllische Kopfschmerzen und kann sich an die vergangene Woche nicht mehr erinnern. Nur noch daran, wie alles mit einer fröhlichen Feier in irgendeiner Taverne anfing...." - "$unit($unit) has a splitting headache and can hardly remember last week. Except that it all started in the tavern..." @@ -6096,16 +4691,12 @@ - "$unit($mage) besänftigt $unit($unit)." - "$unit($mage) calms $unit($unit)." - "$unit($unit) verfiel dem Glücksspiel und hat fast sein ganzes Hab und gut verspielt." - "$unit($unit) gambles for high stakes and loses almost everything." @@ -6114,8 +4705,6 @@ - "$unit($unit) schenkt $unit($mage) $resources($items)." - "$unit($unit) gives $unit($mage) $resources($items)." @@ -6124,16 +4713,12 @@ - "$unit($mage) läßt $unit($target) als $race($race,$unit.size($target)) erscheinen." - "$unit($mage) makes $unit($target) appear as $race($race,$unit.size($target))." - "$unit($unit) wird kurz von einem magischen Licht umhüllt." - "$unit($unit) is briefly surrounded by a magical light." @@ -6141,15 +4726,11 @@ - "$unit($unit) konnte nur $int($ships) von $int($maxships) Schiffen verzaubern." - "$unit($unit) could only enchant $int($ships) of $int($maxships) ships." - "$unit($unit) beschwört einen magischen Wind, der die Schiffe über das Wasser treibt." - "$unit($unit) calls up a magical storm that whips the ship over the waters." @@ -6157,8 +4738,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit weiß nichts über Botanik." - "$unit($unit) in $region($region): '$order($command)' - The unit does not know anything about herbalism." @@ -6166,8 +4745,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit weiß nicht, wie man gaukelt." - "$unit($unit) in $region($region): '$order($command)' - The unit does not know how to entertain." @@ -6175,8 +4752,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit trägt zuviel Gewicht, um sich bewegen zu können." - "$unit($unit) in $region($region): '$order($command)' - The unit is too heavily loaded to move." @@ -6184,8 +4759,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann soviele Pferde nicht bändigen." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot tame that many horses." @@ -6193,8 +4766,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann sich nicht fortbewegen." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot move." @@ -6202,8 +4773,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann nicht handeln." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot trade." @@ -6211,8 +4780,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann keine Tränke herstellen." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot make potions." @@ -6220,8 +4787,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann keine weiteren langen Befehle ausführen." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot execute more long orders." @@ -6229,8 +4794,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat nicht genug Silber." - "$unit($unit) in $region($region): '$order($command)' - The unit does not have enough silver." @@ -6238,8 +4801,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist nicht erfahren genug dafür." - "$unit($unit) in $region($region): '$order($command)' - The unit is not experienced enough to do this." @@ -6247,8 +4808,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist nicht der Eigentümer." - "$unit($unit) in $region($region): '$order($command)' - The unit is not the owner." @@ -6256,8 +4815,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist nicht geschult im Eintreiben von Steuern." - "$unit($unit) in $region($region): '$order($command)' - The unit does not now how to tax." @@ -6266,8 +4823,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist nicht bewaffnet und kampffähig." - "$unit($unit) in $region($region): '$order($command)' - The unit is not armed and ready to fight." @@ -6275,8 +4830,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist mit uns alliiert." - "$unit($unit) in $region($region): '$order($command)' - This unit is one of our allies." @@ -6284,8 +4837,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist in keiner Taverne." - "$unit($unit) in $region($region): '$order($command)' - The unit is not in a tavern." @@ -6293,8 +4844,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist eine der unsrigen." - "$unit($unit) in $region($region): '$order($command)' - This unit is one of our own." @@ -6302,8 +4851,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist auf hoher See." - "$unit($unit) in $region($region): '$order($command)' - The unit is off shore." @@ -6311,8 +4858,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat so etwas nicht." - "$unit($unit) in $region($region): '$order($command)' - The unit does not have this." @@ -6320,8 +4865,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat nicht genug Wagenlenker oder zuviel andere Fracht, um die Wagen aufzuladen." - "$unit($unit) in $region($region): '$order($command)' - The unit does not have enough coachmen or has too much freights to lad the wagons." @@ -6329,8 +4872,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat nicht genug Silber." - "$unit($unit) in $region($region): '$order($command)' - The unit does not have enough silver." @@ -6338,8 +4879,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat keinen Kontakt mit uns aufgenommen." - "$unit($unit) in $region($region): '$order($command)' - The unit did not contact us." @@ -6347,8 +4886,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat keine Spionage gelernt." - "$unit($unit) in $region($region): '$order($command)' - The unit has not yet learned espionage." @@ -6356,8 +4893,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat keine Kräuter." - "$unit($unit) in $region($region): '$order($command)' - The unit does not have any herbs." @@ -6365,8 +4900,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat diesen Trank nicht." - "$unit($unit) in $region($region): '$order($command)' - The unit does not have this potion." @@ -6374,8 +4907,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat diesen Gegenstand nicht." - "$unit($unit) in $region($region): '$order($command)' - The unit does not have this item." @@ -6385,8 +4916,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat diesen Gegenstand zwar, aber sämtliche $int($reservation) $resource($resource,$reservation) sind reserviert." - "$unit($unit) in $region($region): '$order($command)' - The unit has this item, but all $int($reservation) $resource($resource,$reservation) are reserved." @@ -6394,8 +4923,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat diese Kräuter nicht." - "$unit($unit) in $region($region): '$order($command)' - The unit does not have these herbs." @@ -6404,8 +4931,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Einheiten dürfen nicht mehr als $int($maxsize) Personen enthalten." - "$unit($unit) in $region($region): '$order($command)' - Units may not have more than $int($maxsize) members." @@ -6413,8 +4938,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit darf nicht an Bord kommen, da sie das Schiff überladen würde." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot go aboard, the ship would be overloaded." @@ -6422,8 +4945,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit darf nicht an Bord kommen." - "$unit($unit) in $region($region): '$order($command)' - This unit has no permission to come on board." @@ -6431,8 +4952,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit befindet sich nicht in unserer Burg." - "$unit($unit) in $region($region): '$order($command)' - The unit is not in our castle." @@ -6440,8 +4959,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit befindet sich nicht an Bord unseres Schiffes." - "$unit($unit) in $region($region): '$order($command)' - The unit is not on board our ship." @@ -6449,8 +4966,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Burg wurde nicht gefunden." - "$unit($unit) in $region($region): '$order($command)' - The castle could not be found." @@ -6458,8 +4973,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Botschaft enthält keinen Text." - "$unit($unit) in $region($region): '$order($command)' - The message does not contain text." @@ -6467,8 +4980,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Bauern sind schlecht gelaunt." - "$unit($unit) in $region($region): '$order($command)' - The peasant morale is low." @@ -6476,8 +4987,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Anzahl zu verkaufender Produkte fehlt." - "$unit($unit) in $region($region): '$order($command)' - The amount of items for sale is missing." @@ -6485,8 +4994,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Anzahl zu kaufender Produkte fehlt." - "$unit($unit) in $region($region): '$order($command)' - The amount of items to buy is missing." @@ -6494,8 +5001,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Fluch verhindert das." - "$unit($unit) in $region($region): '$order($command)' - A curse prevents this from happening." @@ -6503,8 +5008,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Belagerungszustand macht Spionage unmöglich." - "$unit($unit) in $region($region): '$order($command)' - Espionage was not possible due to siege." @@ -6512,8 +5015,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Belagerungszustand macht die Kontaktaufnahme unmöglich." - "$unit($unit) in $region($region): '$order($command)' - Contact was not possible due to siege." @@ -6521,8 +5022,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Befehl wurde nicht erkannt." - "$unit($unit) in $region($region): '$order($command)' - Unknown command." @@ -6530,8 +5029,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dazu gibt es keine Informationen." - "$unit($unit) in $region($region): '$order($command)' - There is no information available for the request." @@ -6539,8 +5036,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Schiff wurde nicht gefunden." - "$unit($unit) in $region($region): '$order($command)' - The ship could not be found." @@ -6548,8 +5043,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Schiff muß erst verlassen werden." - "$unit($unit) in $region($region): '$order($command)' - First you have to leave the ship." @@ -6557,8 +5050,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Schiff ist zu schwer beladen, um in See zu stechen." - "$unit($unit) in $region($region): '$order($command)' - The ship is too heavily loaded to sail." @@ -6567,8 +5058,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $ship($ship) ist zu groß, um fliegen zu können." - "$unit($unit) in $region($region): '$order($command)' - $ship($ship) is too bulky to fly." @@ -6576,8 +5065,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Schiff ist schon fertig." - "$unit($unit) in $region($region): '$order($command)' - The ship is already completed." @@ -6585,8 +5072,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Schiff ist noch nicht fertig gebaut." - "$unit($unit) in $region($region): '$order($command)' - The ship has not yet been completed." @@ -6594,8 +5079,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Schiff ist auf hoher See." - "$unit($unit) in $region($region): '$order($command)' - The ship is off shore." @@ -6603,8 +5086,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Schiff hat sich bereits bewegt." - "$unit($unit) in $region($region): '$order($command)' - The ship has moved already." @@ -6612,8 +5093,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Besitzer muss das Gebäude zuerst verlassen." - "$unit($unit) in $region($region): '$order($command)' - The owner must first LEAVE the building." @@ -6621,8 +5100,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Schiff gehört uns nicht." - "$unit($unit) in $region($region): '$order($command)' - The ship is not ours." @@ -6630,8 +5107,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Gebäude gehört uns nicht." - "$unit($unit) in $region($region): '$order($command)' - The building is not ours." @@ -6639,8 +5114,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Schiff befindet sich auf hoher See." - "$unit($unit) in $region($region): '$order($command)' - The ship is still off shore." @@ -6648,8 +5121,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das macht wenig Sinn." - "$unit($unit) in $region($region): '$order($command)' - That does not make much sense." @@ -6657,8 +5128,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das kann man nicht sabotieren." - "$unit($unit) in $region($region): '$order($command)' - That cannot be sabotaged." @@ -6666,8 +5135,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das ist sinnlos." - "$unit($unit) in $region($region): '$order($command)' - That is useless." @@ -6675,8 +5142,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das geht nicht mehr." - "$unit($unit) in $region($region): '$order($command)' - This is no longer possible." @@ -6684,8 +5149,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Gebäude wurde nicht gefunden." - "$unit($unit) in $region($region): '$order($command)' - Building could not be found." @@ -6693,8 +5156,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Gebäude gehört uns nicht." - "$unit($unit) in $region($region): '$order($command)' - The building is not ours." @@ -6702,8 +5163,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Das Gebäude ist bereits fertig." - "$unit($unit) in $region($region): '$order($command)' - The building is already completed." @@ -6711,8 +5170,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann nicht unterrichtet werden." - "$unit($unit) in $region($region): '$order($command)' - This unit cannot be taught." @@ -6720,8 +5177,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Beschreibung zu lang - gekürzt." - "$unit($unit) in $region($region): '$order($command)' - Description has been cut (too long)." @@ -6729,8 +5184,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Auf hoher See kann man nicht bewachen." - "$unit($unit) in $region($region): '$order($command)' - You cannot guard off shore." @@ -6738,8 +5191,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Auf dem Schiff befinden sich zuwenig erfahrene Seeleute." - "$unit($unit) in $region($region): '$order($command)' - There are not enough experienced sailors on board the ship." @@ -6748,16 +5199,12 @@ - "$unit($unit) in $region($region): '$order($command)' - ${error}." - "$unit($unit) in $region($region): '$order($command)' - ${error}." - "$unit($unit) benutzt $resource($potion,1)." - "$unit($unit) uses $resource($potion,1)." @@ -6765,8 +5212,6 @@ - "$unit($unit) benutzt $int($amount) $resource($item,$amount)." - "$unit($unit) uses $int($amount) $resource($item,$amount)." @@ -6774,8 +5219,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit ist noch zu erschöpft vom Einmarsch um zu attackieren." - "'$order($command)' - $unit($unit) marched into $region($region) during the last turn and is too exhausted to attack." @@ -6784,8 +5227,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $race($race,0) sind friedliebend und attackieren niemand." - "'$order($command)' - $race($race,0) are peace-loving and will not attack anyone." @@ -6794,8 +5235,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit steht nicht im benötigten Gebäude, $localize($building)." - "$unit($unit) in $region($region): '$order($command)' - The unit must be in a $localize($building) to produce this." @@ -6804,8 +5243,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dazu braucht man das Talent $skill($skill)." - "$unit($unit) in $region($region): '$order($command)' - This requires the skill $skill($skill)." @@ -6816,8 +5253,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Man benötigt mindestens $int($minskill) $skill($skill), um $resource($product,0) zu pflanzen." - "$unit($unit) in $region($region): '$order($command)' - At least $skill($skill) $int($minskill) is needed for planting $resource($product,0)." @@ -6828,15 +5263,11 @@ - "$unit($unit) in $region($region): '$order($command)' - Man benötigt mindestens $int($minskill) $skill($skill), um $resource($product,0) zu produzieren." - "$unit($unit) in $region($region): '$order($command)' - You need at least $int($minskill) $skill($skill), to produce $resource($product,0)." - "$string" - "$string" @@ -6845,8 +5276,6 @@ - "$unit($unit) übergibt $int($amount) Person$if($eq($amount,1),"","en") an $unit($target)." - "$unit($unit) transfers $int($amount) person$if($eq($amount,1),"","s") to $unit($target)." @@ -6855,8 +5284,6 @@ - "$unit($target) erhält $int($amount) Person$if($eq($amount,1),"","en") von $unit($unit)." - "$unit($target) receives $int($amount) person$if($eq($amount,1),"","s") from $unit($unit)." @@ -6866,8 +5293,6 @@ - "$unit($unit) übergibt $int($amount) $resource($resource,$amount) an $unit($target)." - "$unit($unit) gives $int($amount) $resource($resource,$amount) to $unit($target)." @@ -6877,8 +5302,6 @@ - "$unit($target) erhält $int($amount) $resource($resource,$amount) von $unit($unit)." - "$unit($target) receives $int($amount) $resource($resource,$amount) from $unit($unit)." @@ -6886,8 +5309,6 @@ - "$unit($unit) ertränkt $int($amount) Person$if($eq($amount,1),"","en")." - "$unit($unit) drowns $int($amount)." @@ -6895,8 +5316,6 @@ - "$unit($unit) übergibt $int($amount) Person$if($eq($amount,1),"","en") an die Bauern." - "$unit($unit) transfers $int($amount) person$if($eq($amount,1),"","s") to the local peasants." @@ -6905,8 +5324,6 @@ - "$unit($unit) übergibt $int($amount) $resource($resource,$amount) an die Bauern." - "$unit($unit) gives $int($amount) $resource($resource,$amount) to the local peasants." @@ -6914,8 +5331,6 @@ - "$unit($unit) bezahlt den Unterhalt von $building($building)." - "$unit($unit) pays the maintenance for $building($building)." @@ -6923,23 +5338,17 @@ - "$unit($unit) fehlen $resource($item,0) für den Betrieb von $building($building)." - "$unit($unit) lacks $resource($item,0) to operate $building($building)." - "$unit($unit) kann den Unterhalt von $building($building) nicht bezahlen." - "$unit($unit) cannot pay the maintenance for $building($building)." - "Der Unterhalt von $building($building) konnte nicht gezahlt werden, das Gebäude war diese Woche nicht funktionstüchtig." - "The upkeep for $building($building) was not paid, the building was not operational this week." @@ -6947,15 +5356,11 @@ - "$unit($unit) verdient am Handel in $region($region) Steuern in Höhe von $int($amount) Silber." - "$unit($unit) collected $int($amount) silver trade tax in $region($region)." - "Hier wütete die Pest, und $int($dead) Bauern starben." - "The region is visited by the plague and $int($dead) peasants died." @@ -6963,8 +5368,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Um in Gletschern Straßen bauen zu können, muß zuerst ein Tunnel errichtet werden." - "$unit($unit) in $region($region): '$order($command)' - You must build a tunnel before building roads through glaciers." @@ -6972,8 +5375,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Syntax: MAGIEGEBIET [1-5]." - "$unit($unit) in $region($region): '$order($command)' - Syntax: MAGIC SPHERE [1-5]." @@ -6982,30 +5383,18 @@ - "$unit($unit) in $region($region): '$order($command)' - Deine Partei muss mindestens $int($turns) alt sein, um etwas an andere Parteien übergeben zu können." - "$unit($unit) in $region($region): '$order($command)' - Your faction must be at least $int($turns) weeks old to give something to another faction." - - Deine Partei hat letzte Runde keinen Zug - abgegeben! - No orders were received for your faction! - Aucun ordre reçu pour votre faction ! - - "Bitte sende die Befehle nächste Runde ein, wenn du weiterspielen möchtest." - "Please send in orders for the next turn if you want to continue playing." - "Deine Partei ist noch $int($turns) Wochen immun gegen Angriffe." - "Your faction is immune against assaults for $int($turns) more weeks." @@ -7013,23 +5402,17 @@ - "$faction($member) ist mit $int($votes) Stimmen aus $alliance($alliance) ausgeschlossen worden." - "$faction($member) was kicked from $alliance($alliance) by $int($votes) of the alliance's members." - "$alliance($alliance) scheidet aus dem Spiel aus, nachdem alle Tempel verloren gingen." - "$alliance($alliance) has to leave the game after all their temples were lost." - "$int($votes) Mitglieder von $alliance($alliance) haben versucht, Deine Partei aus der Allianz auszuschliessen." - "$int($votes) members of $alliance($alliance) tried to kick you out of the alliance." @@ -7037,8 +5420,6 @@ - "$unit($unit) in $region($region): '$order($command)' - In dieser Regione können Pyramiden gebaut werden." - "$unit($unit) in $region($region): '$order($command)' - Pyramids may be build in this region." @@ -7048,8 +5429,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Auf $ship($ship) liegt beeits ein Zauber." - "$unit($unit) in $region($region): '$order($command)' - There is already a spell on $ship($ship)." @@ -7059,8 +5438,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es ist zu gefährlich, diesen Zauber auf das fliegende Schiff $ship($ship) zu legen." - "$unit($unit) in $region($region): '$order($command)' - It is far too dangerous to put this spell on the flying ship $ship($ship)." @@ -7071,8 +5448,6 @@ - "$unit($unit) in $region($region): '$order($command)' - In dieser Region können keine Pyramiden gebaut werden. Die nächste Pyramidenregion ist zwischen $int($mindist) und $int($maxdist) Regionen entfernt." - "$unit($unit) in $region($region): '$order($command)' - No pyramids may be build in this region. The closest region to build a pyramid in is between $int($mindist) and $int($maxdist) regions away." @@ -7080,110 +5455,80 @@ - "$unit($unit) kann in $region($region) nicht durch das Wurmloch reisen, da die Einheit entweder zu gross ist oder teure Talente besitzt." - "$unit($unit) cannot travel through the wormhole in $region($region) because the unit is either too big or has restricted skills." - "$unit($unit) reist durch ein Wurmloch nach $region($region)." - "$unit($unit) travels through a wormhole to $region($region)." - "In $region($region) erscheint ein Wurmloch." - "A wormhole appears in $region($region)." - "Das Wurmloch in $region($region) schließt sich." - "The wormhole in $region($region) disappears." - "$int($amount) Krieger von $unit($unit) benutzen ihre Flammenschwerter." - "$int($amount) fighters of $unit($unit) are using their flaming sword." - "$int($amount) Krieger von $unit($unit) feuern ihre Katapulte ab." - "$int($amount) fighters of $unit($unit) launch their catapults." - "Der Kampf wurde ausgelöst von ${factions}." - "The battle was initiated by ${factions}." - "Eine Person von $unit($unit) konnte durch einen Heiltrank überleben." - "A fighter of $unit($unit) was saved by a healing potion." - "$unit($unit) konnte dem Gegner eine Falle stellen." - "$unit($unit) lured the enemy into an ambush." - "$unit($unit) überrascht den Gegner." - "$unit($unit) surprises the enemies." - "$unit($unit) versucht $spell($spell) zu zaubern, doch der Zauber schlägt fehl!" - "$unit($unit) tries to cast $spell($spell), but the spell fails!" - "Der Kampf wurde abgebrochen, da alle Verteidiger flohen." - "The battle was aborted because all enemies escaped." - "... in der $int($row). Kampflinie:" - "... in combat rank $int($row):" - "$unit($mage) zaubert $spell($spell), aber niemand war in Reichweite." - "$unit($mage) casts $spell($spell), but nobody was in range." - "Einheiten nach dem Kampf:" - "Units after the battle:" @@ -7192,48 +5537,36 @@ - "$unit($mage) ruft $int($amount) $race($race, $amount) zu Hilfe." - "$unit($mage) calls for the help of $int($amount) $race($race, $amount)." - "$unit($mage) beschwört Trugbilder herauf." - "$unit($mage) summons a mirage." - "$unit($mage) murmelt eine düster klingende Formel. Ein plötzlicher Tumult entsteht, der sich jedoch schnell wieder legt." - "$unit($mage) mumbles arcane words. There is a sudden hubbub, but order is restored quickly." - "$unit($mage) murmelt eine düster klingende Formel. Ein plötzlicher Tumult entsteht und bringt die Kampfaufstellung durcheinander." - "$unit($mage) mumbles arcane words. There is a sudden hubbub and the battle order is disturbed." - "$unit($mage) stimmt einen seltsamen Gesang an. Ein plötzlicher Tumult entsteht, der sich jedoch schnell wieder legt." - "$unit($mage) intones a mysterious chant. There is a sudden hubbub, but order is restored quickly." - "$unit($mage) stimmt einen seltsamen Gesang an. Ein plötzlicher Tumult entsteht und bringt die Kampfaufstellung durcheinander." - "$unit($mage) begins a mysterious chant. Great confusion sweeps through the ranks of the enemy." @@ -7241,23 +5574,17 @@ - "$unit($mage) läßt die Mauern von $building($building) in einem unheimlichen magischen Licht erglühen." - "$unit($mage) causes the walls of $building($building) to glow in an eerie magic light." - "Einheiten vor der $int($turn). Runde:" - "Units before turn $int($turn):" - "In $region($region) findet ein Kampf statt." - "There is a battle in $region($region)." @@ -7265,8 +5592,6 @@ - "$unit($mage) zaubert $spell($spell): $int($dead) $if($eq($dead,1),"Krieger wurde", "Krieger wurden") getötet." - "$unit($mage) casts $spell($spell): $int($dead) $if($eq($dead,1),"enemy was", "enemies were") killed." @@ -7274,8 +5599,6 @@ - "$unit($mage) läßt die Erde in $region($region) erzittern." - "$unit($mage) makes the earth shake in $region($region)." @@ -7283,16 +5606,12 @@ - "$unit($mage) verflucht das Land in $region($region), und eine Dürreperiode beginnt." - "$unit($mage) puts a curse on the lands of $region($region) and a drought sets in." - "$unit($mage) erschafft einen Klon." - "$unit($mage) creates a clone." @@ -7301,8 +5620,6 @@ - "$unit($mage) verliert sich in die Träume von $unit($unit) und erhält einen Eindruck von $region($region)." - "$unit($mage) is lost in the dreams of $unit($unit) and gets a glimps into $region($region)." @@ -7311,8 +5628,6 @@ - "$unit($mage) verschafft $unit($unit) ein schönes Nachtleben in $region($region)." - "$unit($mage) causes $unit($unit) to have a wonderful night in $region($region)." @@ -7320,8 +5635,6 @@ - "$unit($mage) sorgt für schlechten Schlaf in $region($region)." - "$unit($mage) disturbs everyone's dreams in $region($region)." @@ -7330,8 +5643,6 @@ - "$unit($mage) beschwört $int($amount) $race($race,$amount)." - "$unit($mage) summons $int($amount) $race($race,$amount)." @@ -7340,8 +5651,6 @@ - "$unit($mage) erschafft in $region($region) eine verheerende Feuersbrunst. $int($amount) Bäume fallen den Flammen zum Opfer." - "$unit($mage) creates a flaming inferno in $region($region). $int($amount) trees fall victim to the flames." @@ -7349,8 +5658,6 @@ - "Mit einem Ritual bindet $unit($mage) die magischen Kräfte der Erde in die Mauern von $building($building)." - "A magic ritual by $unit($mage) binds magic energies to the walls of $building($building)." @@ -7358,8 +5665,6 @@ - "$unit($mage) weiht $building($building)." - "$unit($mage) blesses $building($building)." @@ -7367,8 +5672,6 @@ - "$unit($mage) ruft das Feuer der Sonne auf $region($region) hinab. Eis schmilzt und verwandelt sich in Morast. Reißende Ströme spülen die mageren Felder weg und ersäufen Mensch und Tier. Was an Bauten nicht den Fluten zum Opfer fiel, verschlingt der Morast. Die sengende Hitze verändert die Region für immer." - "$unit($mage) calls the torching power of the sun upon $region($region). Ice melts and turns the lands into swamps. Powerful rivers wash away the fertile soil and drown people and animals alike. What buildings have not succumbed to the floods sink into the mire. The torrid sun changes the region forever." @@ -7376,8 +5679,6 @@ - "$unit($mage) ruft das Feuer der Sonne auf $region($region) hinab. Die Felder verdorren und Pferde verdursten. Die Hungersnot kostet vielen Bauern das Leben. Vertrocknete Bäume recken ihre kahlen Zweige in den blauen Himmel, von dem erbarmungslos die sengende Sonne brennt." - "$unit($mage) calls the torching power of the sun upon $region($region). The crops wither, horses die of thirst. A famine claims the lives of many peasants. The trees die and their bald branches cannot protect from the torrid sun that mercilessly burns the grounds." @@ -7385,8 +5686,6 @@ - "$unit($mage) ruft das Feuer der Sonne auf $region($region) hinab. Die Felder verdorren und Pferde verdursten. Die Hungersnot kostet vielen Bauern das Leben. Vertrocknete Bäume recken ihre kahlen Zweige in den blauen Himmel, von dem erbarmungslos die sengende Sonne brennt. Die Dürre verändert die Region für immer." - "$unit($mage) calls the torching power of the sun upon $region($region). The crops wither, horses die of thirst. A famine claims the lives of many peasants. The trees die and their bald branches cannot protect from the torrid sun that mercilessly burns the grounds. The drought permanently alters the region." @@ -7394,40 +5693,28 @@ - "$unit($mage) ruft das Feuer der Sonne auf $region($region) hinab. Das Eis zerbricht und eine gewaltige Flutwelle verschlingt die Region." - "$unit($mage) calls the torching power of the sun upon $region($region). The ice melts and and the region is consumed by a tidal wave." - "Die Darbietungen eines fahrenden Gauklers begeistern die Leute. Die fröhliche und ausgelassene Stimmung seiner Lieder überträgt sich auf alle Zuhörer." - "A touring minstrel entertains the locals. The joyous and generous disposition of his songs prove infectious." - "Die Darbietungen von $unit($mage) begeistern die Leute. Die fröhliche und ausgelassene Stimmung seiner Lieder überträgt sich auf alle Zuhörer." - "$unit($mage) entertains the locals. The joyous and generous disposition of his songs prove infectious." - "In der Luft liegt ein wunderschönes Lied, dessen friedfertiger Stimmung sich niemand entziehen kann. Einige Leute werfen sogar ihre Waffen weg." - "A wondrous song fills the air and enchants the public. The song's peaceful melody makes several listeners drop their weapons." - "Die Gesangskunst von $unit($mage) begeistert die Leute. Die friedfertige Stimmung des Lieds überträgt sich auf alle Zuhörer. Einige werfen ihre Waffen weg." - "The marvelous singing of $unit($mage) enchants the public. The song's peaceful melody makes several listeners drop their weapons." - "$unit($mage) beschwört $int($number) Dämonen aus dem Reich der Schatten." - "$unit($mage) summons $int($number) demons from the realm of shadows." @@ -7435,8 +5722,6 @@ - "$unit($mage) zaubert $spell($spell)." - "$unit($mage) casts $spell($spell)." @@ -7446,8 +5731,6 @@ - "$unit($mage) zaubert $spell($spell). $int($amount) Krieger verloren Erinnerungen, $int($dead) wurden getötet." - "$unit($mage) casts $spell($spell). $int($amount) warriors lose their memories, $int($dead) were killed." @@ -7456,8 +5739,6 @@ - "$unit($mage) zaubert $spell($spell). $int($amount) Krieger verloren kurzzeitig ihr Gedächtnis." - "$unit($mage) casts $spell($spell). $int($amount) fighters are temporarily losing some of their memories." @@ -7465,8 +5746,6 @@ - "$unit($unit) tötete $int($dead) Krieger." - "$unit($unit) killed $int($dead) opponents." @@ -7476,8 +5755,6 @@ - "Heer $int($index)($abbrev): $int($dead) Tote, $int($fled) Geflohene, $int($survived) Ãœberlebende." - "Army $int($index)($abbrev): $int($dead) dead, $int($fled) fled, $int($survived) survivors." @@ -7485,8 +5762,6 @@ - "$unit($mage) in $region($region): '$order($command)' - Dieser Zauber kann nicht mit Stufenangabe gezaubert werden." - "$unit($mage) in $region($region): '$order($command)' - This spell cannot be cast with variable level." @@ -7494,8 +5769,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dorthin führt kein Weg." - "$unit($unit) in $region($region): '$order($command)' - There is no route leading there." @@ -7504,8 +5777,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Zu $region($target) kann kein Kontakt hergestellt werden." - "$unit($unit) in $region($region): '$order($command)' - $region($target) could not be contacted." @@ -7514,8 +5785,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit $unit($target) hat keinen Kontakt mit uns aufgenommen." - "$unit($unit) in $region($region): '$order($command)' - The unit $unit($target) did not contact us." @@ -7524,8 +5793,6 @@ - "Antimagie von $unit.dative($self) blockiert in $region($region) einen Zauber von $unit.dative($mage)." - "In $region($region), anti-magic from $unit($self) blocks the spell of $unit($mage)." @@ -7534,8 +5801,6 @@ - "$unit($self) schwächt in $region($region) einen Zauber von $unit.dative($mage) durch Antimagie ab." - "In $region($region), anti-magic from $unit($self) reduces the effect of $unit($mage)'s spell." @@ -7545,8 +5810,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $int($pacified) Regionen wurden befriedet." - "$unit($unit) in $region($region): '$order($command)' - $int($pacified) regions have been pacified." @@ -7556,8 +5819,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Keine Region konnte befriedet werden." - "$unit($unit) in $region($region): '$order($command)' - No region could be pacified." @@ -7565,8 +5826,6 @@ - "$unit($unit) in $region($region) bläst das Horn des Tanzes. In der ganzen Region breitet sich eine friedliche Feststimmmung aus." - "$unit($unit) in $region($region) blows the Horn of Dancing. Peaceful harmony spreads over the region." @@ -7574,8 +5833,6 @@ - "$unit($unit) in $region($region) bläst das Horn des Tanzes, doch niemand hier lässt sich von Stimmung anstecken." - "$unit($unit) in $region($region) blows the Horn of Dancing, but nobody here gets into the mood." @@ -7585,8 +5842,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die $ship($ship) wird jetzt schneller ihr Ziel erreichen." - "$unit($unit) in $region($region): '$order($command)' - The $ship($ship) will now be faster." @@ -7595,8 +5850,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Magier fühlt sich durch den Trank magische gestärkt." - "$unit($unit) in $region($region): '$order($command)' - The mage is magically invigorated." @@ -7606,8 +5859,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Ausser sich vor Furcht geben die Bauern dem Barden $int($money) Silber." - "$unit($unit) in $region($region): '$order($command)' - Stricken with fear the peasants give the bard $int($money) silver." @@ -7615,8 +5866,6 @@ - "$unit($unit) spielt einen Dudelsack. Ausser sich vor Furcht geben die Bauern $int($money) Silber." - "$unit($unit) plays the bagpipe. Stricken with fear the peasants give $int($money) silver." @@ -7626,8 +5875,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Region ist zu weit entfernt." - "$unit($unit) in $region($region): '$order($command)' - That region is too far away." @@ -7636,24 +5883,18 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Wege aus dieser Region sind blockiert." - "$unit($unit) in $region($region): '$order($command)' - The connections from to this regions are blocked." - "$unit($unit) erscheint plötzlich." - "$unit($unit) appears." - "$unit($unit) wird durchscheinend und verschwindet." - "$unit($unit) disappears." @@ -7663,8 +5904,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($target) ist zu schwer." - "$unit($unit) in $region($region): '$order($command)' - $unit($target) is too heavy." @@ -7675,8 +5914,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Partei hat bereits $int($count) von $int($max) Helden." - "$unit($unit) in $region($region): '$order($command)' - The faction already has $int($count) of $int($max) heroes." @@ -7686,8 +5923,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $race($race,0) können keine Helden erwählen." - "$unit($unit) in $region($region): '$order($command)' - $race($race,0) cannot be heroes." @@ -7695,8 +5930,6 @@ - "$unit($unit) wird mit $int($cost) Silber zum Helden ernannt." - "$unit($unit) uses $int($cost) silber for a promotion." @@ -7707,16 +5940,12 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat nur $int($have) von $int($cost) benötigtem Silber." - "$unit($unit) in $region($region): '$order($command)' - The unit has $int($have) of $int($cost) silver required." - "Eine gewaltige Flutwelle verschlingt $region($region) und alle Bewohner." - "A tidal wave wipes out $region($region) and all who lived there." @@ -7724,8 +5953,6 @@ - "Eine gewaltige Flutwelle verschlingt $unit($unit) in $region($region)." - "A tidal wave wipes out $region($region) and kills $unit($unit)." @@ -7733,8 +5960,6 @@ - "$unit($unit) reaktiviert den astralen Schutzschild in $region($region)." - "$unit($unit) reactivates the astral protection shield in $region($region)." @@ -7744,8 +5969,6 @@ - "$unit($unit) in $region($region): $int($number) $race($race,$number) $if($eq($number,1),"kehrte auf seine", "kehrten auf ihre") Felder zurück." - "$unit($unit) in $region($region): $int($number) $race($race,$number) returned to the fields." @@ -7755,8 +5978,6 @@ - "$unit($unit) in $region($region): $int($number) $race($race,$number) $if($eq($number,1),"wurde zum Baum", "wurden zu Bäumen")." - "$unit($unit) in $region($region): $int($number) $race($race,$number) turned into $if($eq($number,1),"a tree", "trees")." @@ -7766,8 +5987,6 @@ - "$unit($unit) in $region($region): $int($number) $race($race,$number) $if($eq($number,1),"verfaulte", "verfaulten")." - "$unit($unit) in $region($region): $int($number) $race($race,$number) whithered and died." @@ -7777,8 +5996,6 @@ - "$unit($unit) in $region($region): $int($number) $race($race,$number) $if($eq($number,1),"zerfiel", "zerfielen") zu Staub." - "$unit($unit) in $region($region): $int($number) $race($race,$number) turned to dust." @@ -7788,9 +6005,6 @@ - "$unit($unit) in $region($region): $int($number) $race($race,$number) $if($eq($number,1),"verschwand", "verschwanden") über Nacht." - "$unit($unit) in $region($region): $int($number) - $race($race,$number) disappeared in the night." @@ -7799,8 +6013,6 @@ - "Der Waldbrand in $region($region) griff auch auf $region($next) über, und $int($trees) verbrannten." - "The fire in $region($region) spread to $region($next) and $int($trees) were burned." @@ -7808,8 +6020,6 @@ - "$unit($mage) ruft in $region($region) eine Pest hervor." - "$unit($mage) sends the plague on $region($region)." @@ -7819,8 +6029,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Eine Partei darf nicht aus mehr als $int($allowed) Einheiten bestehen." - "$unit($unit) in $region($region): '$order($command)' - A faction may not consist of more than $int($allowed) units." @@ -7830,8 +6038,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Eine Allianz darf aus nicht mehr als $int($allowed) Einheiten bestehen." - "$unit($unit) in $region($region): '$order($command)' - An alliance may not consist of more than $int($allowed) units." @@ -7841,8 +6047,6 @@ - "$unit($unit) in $region($region): $int($amount) $resource($item,$amount) zerfallen zu Staub." - "$unit($unit) in $region($region): $int($amount) $resource($item,$amount) turn to dust." @@ -7851,24 +6055,18 @@ - "Die $ship($ship) ist mit gutem Wind gesegnet$if($lt($duration,3),", doch der Zauber beginnt sich bereits aufzulösen",""). ($int36($id))" - "The $ship($ship) is blessed with favourable winds$if($lt($duration,3),", but the spell is starting to wear thin",""). ($int36($id))" - "Kräftige Stürme haben dieses Schiff in die Luft gehoben. ($int36($id))" - "Powerful storms have lifted this ship high into the air. ($int36($id))" - "Mächtige Magie verhindert den Kontakt zur Realität. ($int36($id))" - "Powerful magic disrupts our contact with reality. ($int36($id))" @@ -7876,8 +6074,6 @@ - "Ein silberner Schimmer umgibt die $ship($ship). ($int36($id))" - "A silvery shimmer surrounds the $ship($ship). ($int36($id))" @@ -7885,8 +6081,6 @@ - "Auf den Mauern von $building($building) erkennt man seltsame Runen. ($int36($id))" - "The walls of $building($building) are inscribed with strange runes. ($int36($id))" @@ -7895,8 +6089,6 @@ - "$unit($mage) erschafft $int($number) $resource($item,$number)." - "$unit($mage) creates $int($number) $resource($item,$number)." @@ -7904,8 +6096,6 @@ - "Auf den Planken von $ship($ship) erkennt man seltsame Runen. ($int36($id))" - "The plank of $ship($ship) are inscribed with strange runes. ($int36($id))" @@ -7913,8 +6103,6 @@ - "$unit($unit) wird aus der astralen Ebene nach $region($region) geschleudert." - "$unit($unit) is sent from the astral plain to $region($region)." @@ -7922,8 +6110,6 @@ - "$unit($target) wird von $unit($unit) in eine andere Welt geschleudert." - "$unit($unit) sends $unit($target) to another world." @@ -7931,16 +6117,12 @@ - "$unit($unit) versuchte erfolglos, $unit($target) in eine andere Welt zu schleudern." - "$unit($unit) tried but failed to send $unit($target) to another world." - "NUMMER PARTEI $int36($id): Diese Nummer wird von einer anderen Partei benutzt." - "NUMBER FACTION $int36($id): This number is being used by another faction." @@ -7948,21 +6130,15 @@ - "Eine Botschaft von $unit($unit): '$message'" - "A message from $unit($unit): '$message'" - "Ein Bauernmob erhebt sich und macht Jagd auf Schwarzmagier." - "An angry mob forms and hunts practitioners of the dark arts." - "Vertrauter von $unit($unit)" - "Familiar of $unit($unit)" @@ -7971,37 +6147,27 @@ - "$unit($unit) rekrutiert $int($amount) $localize($archetype)." - "$unit($unit) recruits $int($amount) $localize($archetype)." - "Dein Passwort enthält Zeichen, die bei der Nachsendung von Reports Probleme bereiten können. Bitte beachte, dass Passwortenur aus Buchstaben von A bis Z und Zahlen bestehen dürfen. Dein neues Passwort ist '${newpass}'." - "Your password was changed because it contained illegal characters. Legal passwords may only contain numbers and letters from A to Z. Your new Password is '${newpass}'." - "Miiauuuuuu..." - "Meeoooooow..." - "Der Versuch, die Greifenschwingen zu benutzen, schlug fehl. $unit($unit) konnte die Ebene der Herausforderung nicht verlassen." - "The attempt to use wings of the gryphon failed. $unit($unit) could not leave the Plane of Challenge." - "$unit($unit) springt in die ewigen Feuer des Kraters." - "$unit($unit) jumps into the eternal flame of the caldera." @@ -8009,8 +6175,6 @@ - "$unit($unit) springt in die ewigen Feuer des Kraters." - "$unit($unit) jumps into the eternal flame of the caldera." @@ -8018,8 +6182,6 @@ - "In $region($region) erklingt die Stimme des Torwächters: 'Nur wer ohne materielle Güter und noch lernbegierig ist, der darf die Ebene der Herausforderung betreten. Und vergiß nicht mein Trinkgeld.'. $unit($unit) erhielt keinen Einlaß." - "$region($region) reverberates from the voice of the gate keeper: 'Only those who forgo material riches and who are willing to learn my enter the Plane of Challenge. And don't forget about my tip!'. $unit($unit) was not admitted." @@ -8027,16 +6189,12 @@ - "In $region($region) öffnet sich ein Portal. Eine Stimme ertönt, und spricht: 'Willkommen in der Ebene der Herausforderung'. $unit($unit) durchschreitet das Tor zu einer anderen Welt." - "A portal opens in $region($region). A voice calls: 'Welcome to the Plane of Challenge'. $unit($unit) walks through the gate to another world." - "$unit($unit) scheint von einer seltsamen Krankheit befallen." - "$unit($unit) is stricken by a strange disease." @@ -8045,8 +6203,6 @@ - "$unit($unit) erbeutet $int($amount) $resource($item,$amount)." - "$unit($unit) collects $int($amount) $resource($item,$amount)." @@ -8055,9 +6211,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es ist so schön friedlich, man möchte hier niemanden angreifen." - "$unit($unit) in $region($region): - '$order($command)' - It is so quiet and peaceful, nobody wants to attack anybody right now." @@ -8067,8 +6220,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $race($race,0) können nichts lernen." - "$unit($unit) in $region($region): '$order($command)' - $race($race,0) cannot study." @@ -8077,8 +6228,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Migranten können keine kostenpflichtigen Talente lernen." - "$unit($unit) in $region($region): '$order($command)' - Migrants cannot study this." @@ -8088,8 +6237,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es kann maximal $int($amount) Magier pro Partei geben." - "$unit($unit) in $region($region): '$order($command)' - There may not be more than $int($amount) magicians in your faction." @@ -8099,8 +6246,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Es kann maximal $int($amount) Alchemisten pro Partei geben." - "$unit($unit) in $region($region): '$order($command)' - There may not be more tha $int($amount) alchemists in your faction." @@ -8110,8 +6255,6 @@ - "$unit($unit) in $region($region): '$order($command)' - $unit($target) versteht unsere Art von Magie nicht." - "$unit($unit) in $region($region): '$order($command)' - $unit($target) does not understand our kind of magic." @@ -8122,8 +6265,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Der Kapitän muß ein Segeltalent von mindestens $int($value) haben, um $ship($ship) zu befehligen." - "$unit($unit) in $region($region): '$order($command)' - The captain needs a sailing skill of at least $int($value), to command $ship($ship)." @@ -8132,8 +6273,6 @@ - "$unit($unit) in $region($region): '$order($command)' - In dieser Richtung gibt es keine Brücken und Straßen mehr zu bauen." - "$unit($unit) in $region($region): '$order($command)' - The roads and bridges in that direction are complete." @@ -8143,8 +6282,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Um das zu bauen, braucht man ein Talent von mindestens $int($value)." - "$unit($unit) in $region($region): '$order($command)' - This requires a skill of at least $int($value) to build." @@ -8153,8 +6290,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Diese Einheit kämpft nicht." - "$unit($unit) in $region($region): '$order($command)' - This unit will not fight." @@ -8163,8 +6298,6 @@ - "$unit($unit) erhielt $resources($items) von der $ship($ship)." - "$unit($unit) received $resources($items) from the $ship($ship)." @@ -8173,8 +6306,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Dieser Zauber kann nicht auf Untote gezaubert werden." - "$unit($unit) in $region($region): '$order($command)' - This spell cannot be cast upon undead." @@ -8182,11 +6313,6 @@ - "Achtung: $faction($faction) hat seit $int($turns) Wochen keine - Züge eingeschickt und könnte dadurch in Kürze aus dem Spiel - ausscheiden." - "Warning: $faction($faction) has not been sending in - orders for $int($turns) turns and may be leaving the game soon." @@ -8195,8 +6321,6 @@ - "$unit($unit) in $region($region): '$order($command)' - Helden können nicht rekrutieren." - "$unit($unit) in $region($region): '$order($command)' - Heroes cannot recruit." @@ -8206,8 +6330,6 @@ - "$unit($dragon): \"$localize($growl) $if($eq($number,1), "Ich rieche", "Wir riechen") etwas in $region($target)\"." - "$unit($dragon): \"$localize($growl) $if($eq($number,1), "I smell", "We smell") something in $region($target)\"." diff --git a/src/exparse.c b/src/exparse.c index 271443c05..dfba3f5d0 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -355,7 +355,7 @@ static void start_messages(parseinfo *pi, const XML_Char *el, const XML_Char **a pi->object = mt_new(name, section); } } - else if (xml_strcmp(el, "type") != 0 && xml_strcmp(el, "text") != 0) { + else if (xml_strcmp(el, "type") != 0) { handle_bad_input(pi, el, NULL); } } From 22f6d4feed230edaa505ea149cff4b9289b5d278 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 18 May 2018 21:36:10 +0200 Subject: [PATCH 56/59] fix sections handling, remove it from nrmessage. --- src/util/message.c | 42 +++++++++++++++++++++++++++++++++++++++++- src/util/message.h | 3 +++ src/util/nrmessage.c | 36 ------------------------------------ src/util/nrmessage.h | 3 --- 4 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/util/message.c b/src/util/message.c index b01993098..64c161d24 100644 --- a/src/util/message.c +++ b/src/util/message.c @@ -122,6 +122,42 @@ message_type *mt_create(message_type * mtype, const char *args[], int nparameter return mtype; } +char *sections[MAXSECTIONS]; + +const char *section_find(const char *name) +{ + int i; + + if (name == NULL) { + return NULL; + } + + for (i = 0; i != MAXSECTIONS && sections[i]; ++i) { + if (strcmp(sections[i], name) == 0) { + return sections[i]; + } + } + return NULL; +} + +const char *section_add(const char *name) { + int i; + if (name == NULL) { + return NULL; + } + for (i = 0; i != MAXSECTIONS && sections[i]; ++i) { + if (strcmp(sections[i], name) == 0) { + return sections[i]; + } + } + assert(i < MAXSECTIONS); + assert(sections[i] == NULL); + if (i + 1 < MAXSECTIONS) { + sections[i + 1] = NULL; + } + return sections[i] = str_strdup(name); +} + message_type *mt_new(const char *name, const char *section) { message_type *mtype; @@ -134,7 +170,10 @@ message_type *mt_new(const char *name, const char *section) mtype = (message_type *)malloc(sizeof(message_type)); mtype->key = 0; mtype->name = str_strdup(name); - mtype->section = section; + mtype->section = section_find(section); + if (!mtype->section) { + mtype->section = section_add(section); + } mtype->nparameters = 0; mtype->pnames = NULL; mtype->types = NULL; @@ -267,3 +306,4 @@ void message_done(void) { free(at); } } + diff --git a/src/util/message.h b/src/util/message.h index 40cc09086..5aa16232b 100644 --- a/src/util/message.h +++ b/src/util/message.h @@ -20,6 +20,9 @@ extern "C" { #define MSG_MAXARGS 8 #define MT_NEW_END ((const char *)0) +#define MAXSECTIONS 16 + + extern char *sections[MAXSECTIONS]; typedef struct arg_type { struct arg_type *next; diff --git a/src/util/nrmessage.c b/src/util/nrmessage.c index 047d3565b..1fdde6935 100644 --- a/src/util/nrmessage.c +++ b/src/util/nrmessage.c @@ -65,42 +65,6 @@ static nrmessage_type *nrt_find(const struct message_type * mtype) return found; } -char *sections[MAXSECTIONS]; - -const char *section_find(const char *name) -{ - int i; - - if (name == NULL) { - return NULL; - } - - for (i = 0; i != MAXSECTIONS && sections[i]; ++i) { - if (strcmp(sections[i], name) == 0) { - return sections[i]; - } - } - return NULL; -} - -const char *section_add(const char *name) { - int i; - if (name == NULL) { - return NULL; - } - for (i = 0; i != MAXSECTIONS && sections[i]; ++i) { - if (strcmp(sections[i], name) == 0) { - return sections[i]; - } - } - assert(i < MAXSECTIONS); - assert(sections[i] == NULL); - if (i + 1 < MAXSECTIONS) { - sections[i + 1] = NULL; - } - return sections[i] = str_strdup(name); -} - void nrt_register(const struct message_type *mtype) { diff --git a/src/util/nrmessage.h b/src/util/nrmessage.h index c0d9257aa..15914841b 100644 --- a/src/util/nrmessage.h +++ b/src/util/nrmessage.h @@ -25,9 +25,6 @@ extern "C" { struct message_type; struct nrmessage_type; -#define MAXSECTIONS 8 - extern char *sections[MAXSECTIONS]; - void free_nrmesssages(void); void nrt_register(const struct message_type *mtype); From 33a6d7fa0ed9028e801999d9314f08805237af5a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 18 May 2018 21:40:26 +0200 Subject: [PATCH 57/59] free sections memory. --- src/kernel/config.c | 1 + src/util/message.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/kernel/config.c b/src/kernel/config.c index 8eef66341..ff2457971 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -561,6 +561,7 @@ void kernel_done(void) curses_done(); crmessage_done(); translation_done(); + mt_clear(); } bool rule_stealth_other(void) diff --git a/src/util/message.c b/src/util/message.c index 64c161d24..8915dca8f 100644 --- a/src/util/message.c +++ b/src/util/message.c @@ -255,6 +255,10 @@ void mt_clear(void) { selist_free(ql); messagetypes[i] = 0; } + for (i = 0; i != MAXSECTIONS && sections[i]; ++i) { + free(sections[i]); + sections[i] = NULL; + } } const message_type *mt_find(const char *name) From 6699e8940ec6b7ea664a86b664a175c0689e580b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 18 May 2018 21:44:03 +0200 Subject: [PATCH 58/59] some cleanup is good. --- src/eressea.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eressea.c b/src/eressea.c index bdb20edcc..982dfe6ee 100644 --- a/src/eressea.c +++ b/src/eressea.c @@ -53,9 +53,9 @@ void game_done(void) free_config(); free_special_directions(); free_locales(); +#endif kernel_done(); dblib_close(); -#endif } void game_init(void) From adfc4ad7ce9e2ae2bad77a0a34e7c7c4b267a6e1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 18 May 2018 21:54:46 +0200 Subject: [PATCH 59/59] add a header to po files, charset UTF-8 --- .gitignore | 1 + res/translations/messages.de.po | 13 +++++++++++++ res/translations/messages.en.po | 13 +++++++++++++ res/translations/strings-e3.de.po | 13 +++++++++++++ res/translations/strings-e3.en.po | 13 +++++++++++++ res/translations/strings.de.po | 13 +++++++++++++ res/translations/strings.en.po | 13 +++++++++++++ 7 files changed, 79 insertions(+) diff --git a/.gitignore b/.gitignore index d7c102f5a..d5e8e1b10 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,4 @@ tests/data/185.dat /quicklist/ /cutest/ /critbit/ +*.mo diff --git a/res/translations/messages.de.po b/res/translations/messages.de.po index 8e882a435..98800fd31 100644 --- a/res/translations/messages.de.po +++ b/res/translations/messages.de.po @@ -1,3 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"X-Generator: Poedit 2.0.7\n" + msgid "homestone_effect" msgstr "\"Mit einem Ritual bindet $unit($mage) die magischen Kräfte der Erde in die Mauern von $building($building).\"" diff --git a/res/translations/messages.en.po b/res/translations/messages.en.po index 558b75ee9..9f11a6312 100644 --- a/res/translations/messages.en.po +++ b/res/translations/messages.en.po @@ -1,3 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: en\n" +"X-Generator: Poedit 2.0.7\n" + msgid "homestone_effect" msgstr "\"A magic ritual by $unit($mage) binds magic energies to the walls of $building($building).\"" diff --git a/res/translations/strings-e3.de.po b/res/translations/strings-e3.de.po index 2652d9436..71e9363f9 100644 --- a/res/translations/strings-e3.de.po +++ b/res/translations/strings-e3.de.po @@ -1,3 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"X-Generator: Poedit 2.0.7\n" + msgid "catamaran_a" msgstr "ein Katamaran" diff --git a/res/translations/strings-e3.en.po b/res/translations/strings-e3.en.po index 169a80a68..311abcf40 100644 --- a/res/translations/strings-e3.en.po +++ b/res/translations/strings-e3.en.po @@ -1,3 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: en\n" +"X-Generator: Poedit 2.0.7\n" + msgid "catamaran_a" msgstr "a catamaran" diff --git a/res/translations/strings.de.po b/res/translations/strings.de.po index d739a0b6d..b7881b3f8 100644 --- a/res/translations/strings.de.po +++ b/res/translations/strings.de.po @@ -1,3 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"X-Generator: Poedit 2.0.7\n" + msgid "rustychainmail" msgstr "Rostiges Kettenhemd" diff --git a/res/translations/strings.en.po b/res/translations/strings.en.po index 1e2dfdb1a..774874bf1 100644 --- a/res/translations/strings.en.po +++ b/res/translations/strings.en.po @@ -1,3 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: en\n" +"X-Generator: Poedit 2.0.7\n" + msgid "rustychainmail" msgstr "rustychainmail"