From 260d518fa131bcd30f2a29178bebdc1997c97d0d Mon Sep 17 00:00:00 2001 From: Enno Rehling <enno@eressea.de> Date: Tue, 26 Jun 2007 09:32:28 +0000 Subject: [PATCH] WIP, does not compile: Unicode (UTF8) conversion of absolutely everything. Mi'kmaq hieroglyphic writing FTW! --- src/common/gamecode/archetype.c | 6 +- src/common/gamecode/archetype.h | 2 +- src/common/gamecode/creation.c | 4 +- src/common/gamecode/creport.c | 23 +- src/common/gamecode/economy.c | 80 +++--- src/common/gamecode/give.c | 33 ++- src/common/gamecode/laws.c | 170 +++++++++--- src/common/gamecode/monster.c | 44 ++-- src/common/gamecode/randenc.c | 179 +++++-------- src/common/gamecode/report.c | 36 +++ src/common/gamecode/study.c | 50 ++-- src/common/gamecode/study.h | 2 +- src/common/gamecode/xmlreport.c | 4 +- src/common/kernel/alliance.c | 13 +- src/common/kernel/battle.c | 2 +- src/common/kernel/building.c | 5 +- src/common/kernel/building.h | 6 +- src/common/{util => kernel}/command.c | 44 ++-- src/common/{util => kernel}/command.h | 4 +- src/common/kernel/eressea.c | 112 ++++---- src/common/kernel/eressea.h | 46 ++-- src/common/kernel/faction.c | 21 +- src/common/kernel/faction.h | 12 +- src/common/kernel/item.c | 6 +- src/common/kernel/item.h | 4 +- src/common/kernel/kernel.vcproj | 6 + src/common/kernel/magic.c | 54 ++-- src/common/kernel/magic.h | 8 +- src/common/kernel/message.c | 4 +- src/common/kernel/movement.c | 72 ++--- src/common/kernel/names.c | 74 +++--- src/common/kernel/names.h | 16 +- src/common/kernel/order.c | 215 ++++++++------- src/common/kernel/order.h | 23 +- src/common/kernel/pool.c | 7 +- src/common/kernel/race.c | 2 +- src/common/kernel/race.h | 6 +- src/common/kernel/region.c | 27 +- src/common/kernel/region.h | 8 +- src/common/kernel/reports.c | 53 +++- src/common/kernel/reports.h | 8 +- src/common/kernel/save.c | 261 +++++++----------- src/common/kernel/save.h | 2 +- src/common/kernel/ship.c | 15 +- src/common/kernel/ship.h | 6 +- src/common/kernel/skill.c | 4 +- src/common/kernel/skill.h | 3 +- src/common/kernel/spell.c | 4 +- src/common/kernel/spell.h | 1 + src/common/kernel/teleport.c | 1 - src/common/kernel/unit.c | 42 +-- src/common/kernel/unit.h | 16 +- src/common/kernel/xmlreader.c | 8 +- src/common/modules/arena.c | 52 ++-- src/common/modules/arena.h | 2 + src/common/modules/autoseed.c | 10 +- src/common/modules/autoseed.h | 2 +- src/common/modules/gmcmd.c | 202 ++++++-------- src/common/modules/museum.c | 10 +- src/common/modules/score.c | 9 +- src/common/modules/xecmd.c | 2 +- src/common/spells/alp.c | 27 +- src/common/spells/combatspells.c | 78 ++---- src/common/spells/spells.c | 310 ++++++++-------------- src/common/triggers/unitmessage.c | 8 +- src/common/util/Jamfile | 1 + src/common/util/language.c | 25 +- src/common/util/language.h | 11 +- src/common/util/language_struct.h | 2 +- src/common/util/nrmessage.c | 4 +- src/common/util/nrmessage.h | 2 +- src/common/util/parser.c | 121 +++++++-- src/common/util/parser.h | 6 +- src/common/util/umlaut.c | 260 +++++++++--------- src/common/util/umlaut.h | 4 +- src/common/util/unicode.h | 1 - src/common/util/util.vcproj | 20 +- src/config.h | 2 + src/eressea.sln | 13 + src/eressea/korrektur.c | 31 +-- src/eressea/lua/faction.cpp | 4 +- src/eressea/main.c | 2 +- src/res/de/strings.xml | 132 ++++++++++ src/res/messages.xml | 363 ++++++++++++++++++++++++-- src/res/races.xml | 13 +- 85 files changed, 2006 insertions(+), 1577 deletions(-) rename src/common/{util => kernel}/command.c (71%) rename src/common/{util => kernel}/command.h (90%) diff --git a/src/common/gamecode/archetype.c b/src/common/gamecode/archetype.c index 5587a4494..de16dadc0 100644 --- a/src/common/gamecode/archetype.c +++ b/src/common/gamecode/archetype.c @@ -30,7 +30,7 @@ struct attrib_type at_recruit = { }; const struct archetype * -find_archetype(const char * s, const struct locale * lang) +find_archetype(const xmlChar * s, const struct locale * lang) { struct tnode * tokens = get_translations(lang, UT_ARCHETYPES); variant token; @@ -57,13 +57,13 @@ init_archetypes(void) archetype * arch = archetypes; struct tnode * tokens = get_translations(lang, UT_ARCHETYPES); for (;arch;arch=arch->next) { - const char *s1, *s2; + const xmlChar *s1, *s2; var.v = arch; s1 = LOC(lang, arch->name[0]); addtoken(tokens, s1, var); s2 = LOC(lang, arch->name[1]); - if (strcmp(s2, s1)!=0) { + if (xmlStrcmp(s2, s1)!=0) { addtoken(tokens, s2, var); } } diff --git a/src/common/gamecode/archetype.h b/src/common/gamecode/archetype.h index f500794bc..977ffce5d 100644 --- a/src/common/gamecode/archetype.h +++ b/src/common/gamecode/archetype.h @@ -33,7 +33,7 @@ extern "C" { struct rule * rules; } archetype; - extern const struct archetype * find_archetype(const char * s, const struct locale * lang); + extern const struct archetype * find_archetype(const xmlChar * s, const struct locale * lang); extern void init_archetypes(void); extern void register_archetype(struct archetype * arch); extern void register_archetypes(void); diff --git a/src/common/gamecode/creation.c b/src/common/gamecode/creation.c index d7c61c458..69c3d1463 100644 --- a/src/common/gamecode/creation.c +++ b/src/common/gamecode/creation.c @@ -68,8 +68,8 @@ createmonsters(void) /* alles ist auf null gesetzt, ausser dem folgenden. achtung - partei * no 0 muss keine orders einreichen! */ - set_string(&f->email, "monsters@eressea.de"); - set_string(&f->name, "Monster"); + f->email = strdup("monsters@eressea.de"); + set_string(&f->name, (xmlChar*)"Monster"); f->alive = 1; f->options = (char)(1<<O_REPORT); addlist(&factions, f); diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index b8646730d..c6e2c0862 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -229,7 +229,7 @@ print_curses(FILE * F, const faction * viewer, const void * obj, typ_t typ) unit *u = (unit *)obj; a = u->attribs; r = u->region; - if (u->faction == viewer){ + if (u->faction == viewer) { self = 2; } } else if (typ == TYP_REGION) { @@ -422,6 +422,26 @@ cr_resources(variant var, char * buffer, const void * userdata) return 0; } +static int +cr_regions(variant var, char * buffer, const void * userdata) +{ + const faction * report = (const faction*)userdata; + const arg_regions * rdata = (const arg_regions *)var.v; + char * wp = buffer; + if (rdata!=NULL && rdata->nregions>0) { + region * r = rdata->regions[0]; + int i, z = r->planep?r->planep->id:0; + wp += sprintf(wp, "\"%d %d %d", r->x, r->y, z); + for (i=1;i!=rdata->nregions;++i) { + r = rdata->regions[i]; + z = r->planep?r->planep->id:0; + wp += sprintf(wp, ", %d %d %d", r->x, r->y, z); + } + strcat(wp, "\""); + } + return 0; +} + static int cr_spell(variant var, char * buffer, const void * userdata) { @@ -1495,6 +1515,7 @@ creport_init(void) tsf_register("direction", &cr_int); tsf_register("alliance", &cr_alliance); tsf_register("resources", &cr_resources); + tsf_register("regions", &cr_regions); register_reporttype("cr", &report_computer, 1<<O_COMPUTER); } diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index 2cf6e8871..73453a514 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -64,6 +64,12 @@ #include <util/parser.h> #include <util/rng.h> +#include <attributes/reduceproduction.h> +#include <attributes/racename.h> +#include <attributes/orcification.h> + +#include <items/seed.h> + /* libs includes */ #include <math.h> #include <stdio.h> @@ -71,11 +77,6 @@ #include <assert.h> #include <limits.h> -#include <attributes/reduceproduction.h> -#include <attributes/racename.h> -#include <attributes/orcification.h> - -#include <items/seed.h> typedef struct request { struct request * next; @@ -443,15 +444,15 @@ recruit(unit * u, struct order * ord, request ** recruitorders) init_tokens(ord); skip_token(); - n = geti(); + n = getuint(); if (f->no==MONSTER_FACTION) { /* Monster d�rfen REKRUTIERE 15 dracoid machen */ - const char * str = getstrtoken(); + const xmlChar * str = getstrtoken(); if (str!=NULL && *str) { for (rc = races;rc;rc=rc->next) { - if (strncasecmp(LOC(f->locale, rc->_name[0]), str, strlen(str))==0) + if (xmlStrncasecmp(LOC(f->locale, rc->_name[0]), str, xmlStrlen(str))==0) break; - if (strncasecmp(LOC(f->locale, rc->_name[1]), str, strlen(str))==0) + if (xmlStrncasecmp(LOC(f->locale, rc->_name[1]), str, xmlStrlen(str))==0) break; } } @@ -571,7 +572,7 @@ give_cmd(unit * u, order * ord) { region * r = u->region; unit *u2; - const char *s; + const xmlChar *s; int i, n; const item_type * itype; param_t p; @@ -606,6 +607,8 @@ give_cmd(unit * u, order * ord) p = findparam(s, u->faction->locale); if (p == P_CONTROL) { + message * msg; + if (!u2) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", "")); return; @@ -633,13 +636,12 @@ give_cmd(unit * u, order * ord) freset(u, UFL_OWNER); fset(u2, UFL_OWNER); - ADDMSG(&u->faction->msgs, - msg_message("givecommand", "unit receipient", u, u2)); + msg = msg_message("givecommand", "unit receipient", u, u2); + add_message(&u->faction->msgs, msg); if (u->faction != u2->faction) { - ADDMSG(&u2->faction->msgs, - msg_message("givecommand", "unit receipient", - ucansee(u2->faction, u, u_unknown()), u2)); + add_message(&u2->faction->msgs, msg); } + msg_release(msg); return; } @@ -721,7 +723,7 @@ give_cmd(unit * u, order * ord) } else if (p==P_ANY) { - const char * s = getstrtoken(); + const xmlChar * s = getstrtoken(); if (*s == 0) { /* Alle Gegenst�nde �bergeben */ @@ -802,7 +804,7 @@ give_cmd(unit * u, order * ord) s = getstrtoken(); /* skip one ahead to get the amount. */ } - n = atoip(s); /* n: anzahl */ + n = atoip((const char *)s); /* n: anzahl */ if (p==P_EACH) { n *= u2->number; } @@ -857,7 +859,7 @@ static int forget_cmd(unit * u, order * ord) { skill_t sk; - const char *s; + const xmlChar *s; init_tokens(ord); skip_token(); @@ -1061,11 +1063,11 @@ static int recruit_archetype(unit * u, order * ord) { int want; - const char * s; + const xmlChar * s; init_tokens(ord); skip_token(); - want = geti(); + want = getuint(); s = getstrtoken(); if (want>0 && s && s[0]) { int n = want; @@ -1733,16 +1735,16 @@ make_cmd(unit * u, struct order * ord) param_t p; int m; const item_type * itype; - const char *s; + const xmlChar *s; const struct locale * lang = u->faction->locale; init_tokens(ord); skip_token(); s = getstrtoken(); - m = atoi(s); + m = atoi((const char *)s); sprintf(buf, "%d", m); - if (!strcmp(buf, s)) { + if (!strcmp(buf, (const char *)s)) { /* first came a want-paramter */ s = getstrtoken(); } else { @@ -1797,22 +1799,22 @@ make_cmd(unit * u, struct order * ord) /* if the item cannot be made, we probably didn't mean to make it */ itype = NULL; } else if (stype!=NULL) { - const char * sname = LOC(lang, stype->name[0]); - const char * iname = LOC(lang, resourcename(itype->rtype, 0)); - if (strlen(iname)<strlen(sname)) stype = NULL; + const xmlChar * sname = LOC(lang, stype->name[0]); + const xmlChar * iname = LOC(lang, resourcename(itype->rtype, 0)); + if (xmlStrlen(iname)<xmlStrlen(sname)) stype = NULL; else itype = NULL; } else { - const char * bname = LOC(lang, btype->_name); - const char * iname = LOC(lang, resourcename(itype->rtype, 0)); - if (strlen(iname)<strlen(bname)) btype = NULL; + const xmlChar * bname = LOC(lang, btype->_name); + const xmlChar * iname = LOC(lang, resourcename(itype->rtype, 0)); + if (xmlStrlen(iname)<xmlStrlen(bname)) btype = NULL; else itype = NULL; } } if (btype!=NULL && stype!=NULL) { - const char * bname = LOC(lang, btype->_name); - const char * sname = LOC(lang, stype->name[0]); - if (strlen(sname)<strlen(bname)) btype = NULL; + const xmlChar * bname = LOC(lang, btype->_name); + const xmlChar * sname = LOC(lang, stype->name[0]); + if (xmlStrlen(sname)<xmlStrlen(bname)) btype = NULL; else stype = NULL; } @@ -1980,7 +1982,7 @@ buy(unit * u, request ** buyorders, struct order * ord) init_tokens(ord); skip_token(); - n = geti(); + n = getuint(); if (!n) { cmistake(u, ord, 26, MSG_COMMERCE); return; @@ -2245,7 +2247,7 @@ sell(unit * u, request ** sellorders, struct order * ord) const luxury_type * ltype=NULL; int n; region * r = u->region; - const char *s; + const xmlChar *s; if (u->ship && is_guarded(r, u, GUARD_CREWS)) { cmistake(u, ord, 69, MSG_INCOME); @@ -2268,7 +2270,7 @@ sell(unit * u, request ** sellorders, struct order * ord) return false; } } else { - n = atoi(s); + n = atoi((const char *)s); if (n==0) { cmistake(u, ord, 27, MSG_COMMERCE); return false; @@ -2635,7 +2637,7 @@ static void breed_cmd(unit *u, struct order * ord) { int m; - const char *s; + const xmlChar *s; param_t p; region *r = u->region; const resource_type * rtype = NULL; @@ -2650,7 +2652,7 @@ breed_cmd(unit *u, struct order * ord) skip_token(); s = getstrtoken(); - m = atoi(s); + m = atoi((const char *)s); if (m!=0) { /* first came a want-paramter */ s = getstrtoken(); @@ -2936,7 +2938,7 @@ entertain_cmd(unit * u, struct order * ord) init_tokens(ord); skip_token(); - max_e = geti(); + max_e = getuint(); if (max_e != 0) { u->wants = min(u->wants,max_e); } @@ -3092,7 +3094,7 @@ tax_cmd(unit * u, struct order * ord, request ** taxorders) init_tokens(ord); skip_token(); - max = geti(); + max = getuint(); if (max == 0) max = INT_MAX; if (!playerrace(u->race)) { diff --git a/src/common/gamecode/give.c b/src/common/gamecode/give.c index f578d4586..973f79b97 100644 --- a/src/common/gamecode/give.c +++ b/src/common/gamecode/give.c @@ -66,16 +66,15 @@ add_give(unit * u, unit * u2, int n, const resource_type * rtype, struct order * if (error) { cmistake(u, ord, error, MSG_COMMERCE); } - else if (!u2 || u2->faction!=u->faction) { - assert(rtype); + else if (u2==NULL) { ADDMSG(&u->faction->msgs, - msg_message("give", "unit target resource amount", - u, u2?ucansee(u->faction, u2, u_unknown()):u_peasants(), rtype, n)); - if (u2) { - ADDMSG(&u2->faction->msgs, - msg_message("give", "unit target resource amount", - ucansee(u2->faction, u, u_unknown()), u2, rtype, n)); - } + msg_message("give_peasants", "unit resource amount", + u, rtype, n)); + } else if (u2->faction!=u->faction) { + message * msg = msg_message("give", "unit target resource amount", u, u2, rtype, n); + add_message(&u->faction->msgs, msg); + add_message(&u2->faction->msgs, msg); + msg_release(msg); } } @@ -300,14 +299,14 @@ give_men(int n, unit * u, unit * u2, struct order * ord) } if (error>0) { cmistake(u, ord, error, MSG_COMMERCE); - } - else if (!u2 || u2->faction!=u->faction) { - ADDMSG(&u->faction->msgs, msg_message("give_person", "unit target amount", - u, u2?ucansee(u->faction, u2, u_unknown()):u_peasants(), n)); - if (u2) { - ADDMSG(&u2->faction->msgs, msg_message("give_person", "unit target amount", - ucansee(u2->faction, u, u_unknown()), u2, n)); - } + } else if (!u2) { + ADDMSG(&u->faction->msgs, + msg_message("give_person_peasants", "unit amount", u, n)); + } else if (u2->faction!=u->faction) { + message * msg = msg_message("give_person", "unit target amount", u, u2, n); + add_message(&u->faction->msgs, msg); + add_message(&u2->faction->msgs, msg); + msg_release(msg); } } diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 6b5444084..bfc1f479d 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -81,6 +81,7 @@ #include <util/rand.h> #include <util/rng.h> #include <util/sql.h> +#include <util/umlaut.h> #include <util/message.h> #include <util/rng.h> @@ -913,7 +914,7 @@ restart_cmd(unit * u, struct order * ord) if (!fval(u->region->terrain, LAND_REGION)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_onlandonly", "")); } else { - const char * s_race = getstrtoken(), * s_pass; + const xmlChar * s_race = getstrtoken(), * s_pass; const race * frace = findrace(s_race, u->faction->locale); if (!frace) { @@ -965,7 +966,7 @@ static int quit_cmd(unit * u, struct order * ord) { faction * f = u->faction; - const char * passwd; + const xmlChar * passwd; init_tokens(ord); skip_token(); /* skip keyword */ @@ -973,8 +974,7 @@ quit_cmd(unit * u, struct order * ord) passwd = getstrtoken(); if (checkpasswd(f, passwd, false)) { if (EnhancedQuit()) { - const char * token = getstrtoken(); - int f2_id = atoi36(token); + int f2_id = getid(); if (f2_id>0) { faction *f2 = findfaction(f2_id); @@ -988,6 +988,7 @@ quit_cmd(unit * u, struct order * ord) cmistake(u, ord, 316, MSG_EVENT); return 0; } else { + const char * token = itoa36(f2_id); set_variable(&f->attribs, "quit", token); } } @@ -1062,8 +1063,7 @@ parse_restart(void) continue; } if (fval(f, FFL_OVERRIDE)) { - free(f->override); - f->override = strdup(itoa36(rng_int())); + set_string(&f->override, (xmlChar*)strdup(itoa36(rng_int()))); freset(f, FFL_OVERRIDE); } if (turn!=f->lastorders) { @@ -1124,7 +1124,7 @@ ally_cmd(unit * u, struct order * ord) ally * sf, ** sfp; faction *f; int keyword, not_kw; - const char *s; + const xmlChar *s; init_tokens(ord); skip_token(); @@ -1230,12 +1230,61 @@ ally_cmd(unit * u, struct order * ord) return 0; } +static struct local_names * pnames; + +static void +init_prefixnames(void) +{ + int i; + for (i=0;localenames[i];++i) { + const struct locale * lang = find_locale(localenames[i]); + boolean exist = false; + struct local_names * in = pnames; + + while (in!=NULL) { + if (in->lang==lang) { + exist = true; + break; + } + in = in->next; + } + if (in==NULL) in = calloc(sizeof(local_names), 1); + in->next = pnames; + in->lang = lang; + + if (!exist) { + int key; + for (key=0;race_prefixes[key];++key) { + variant var; + const xmlChar * pname = locale_string(lang, race_prefixes[key]); + if (findtoken(&in->names, pname, &var)==E_TOK_NOMATCH || var.i!=key) { + var.i = key; + addtoken(&in->names, pname, var); + addtoken(&in->names, locale_string(lang, race_prefixes[key]), var); + } + } + } + pnames = in; + } +} + static int prefix_cmd(unit * u, struct order * ord) { attrib **ap; - int i; - const char *s; + const xmlChar *s; + local_names * in = pnames; + variant var; + const struct locale * lang = u->faction->locale; + + while (in!=NULL) { + if (in->lang==lang) break; + in = in->next; + } + if (in==NULL) { + init_prefixnames(); + for (in=pnames;in->lang!=lang;in=in->next) ; + } init_tokens(ord); skip_token(); @@ -1255,34 +1304,65 @@ prefix_cmd(unit * u, struct order * ord) return 0; } - for(i=0; race_prefixes[i] != NULL; i++) { - const char * tag = mkname("prefix", race_prefixes[i]); - if (strncasecmp(s, LOC(u->faction->locale, tag), strlen(s)) == 0) { - break; - } - } - - if (race_prefixes[i] == NULL) { - cmistake(u, ord, 299, MSG_EVENT); + if (findtoken(&in->names, s, &var)==E_TOK_NOMATCH) { return 0; + } else if (race_prefixes[var.i] == NULL) { + cmistake(u, ord, 299, MSG_EVENT); + } else { + ap = &u->faction->attribs; + if (fval(u, UFL_GROUP)) { + attrib * a = a_find(u->attribs, &at_group); + group * g = (group*)a->data.v; + if (a) ap = &g->attribs; + } + set_prefix(ap, race_prefixes[var.i]); } - - ap = &u->faction->attribs; - if (fval(u, UFL_GROUP)) { - attrib * a = a_find(u->attribs, &at_group); - group * g = (group*)a->data.v; - if (a) ap = &g->attribs; - } - set_prefix(ap, race_prefixes[i]); - return 0; } +static struct local_names * synonyms; + +static void +init_synonyms(void) +{ + int i; + for (i=0;localenames[i];++i) { + const struct locale * lang = find_locale(localenames[i]); + boolean exist = false; + struct local_names * in = synonyms; + + while (in!=NULL) { + if (in->lang==lang) { + exist = true; + break; + } + in = in->next; + } + if (in==NULL) in = calloc(sizeof(local_names), 1); + in->next = synonyms; + in->lang = lang; + + if (!exist) { + int key; + for (key=0;race_prefixes[key];++key) { + variant var; + const xmlChar * pname = locale_string(lang, race_prefixes[key]); + if (findtoken(&in->names, pname, &var)==E_TOK_NOMATCH || var.i!=key) { + var.i = key; + addtoken(&in->names, pname, var); + addtoken(&in->names, locale_string(lang, race_prefixes[key]), var); + } + } + } + synonyms = in; + } +} + static int display_cmd(unit * u, struct order * ord) { building * b = u->building; - char **s = NULL; + xmlChar **s = NULL; region * r = u->region; init_tokens(ord); @@ -1332,7 +1412,7 @@ display_cmd(unit * u, struct order * ord) case P_PRIVAT: { - const char *d = getstrtoken(); + const xmlChar *d = getstrtoken(); if(d == NULL || *d == 0) { usetprivate(u, NULL); } else { @@ -1363,10 +1443,10 @@ display_cmd(unit * u, struct order * ord) } if (s!=NULL) { - const char * s2 = getstrtoken(); + const xmlChar * s2 = getstrtoken(); if (strlen(s2)>=DISPLAYSIZE) { - char * s3 = strdup(s2); + xmlChar * s3 = strdup(s2); s3[DISPLAYSIZE] = 0; set_string(s, s3); free(s3); @@ -3763,6 +3843,33 @@ static void reset_rng(void) { else rng_init(turn); } +/** warn about passwords that are not US ASCII. + * even though passwords are technically UTF8 strings, the server receives + * them as part of the Subject of an email when reports are requested. + * This means that we need to limit them to ASCII characters until that + * mechanism has been changed. + */ +static int +warn_password(void) +{ + faction * f = factions; + while (f) { + boolean pwok = true; + const char * c = f->passw; + while (*c) { + if (!isalnum((unsigned char)*c)) pwok = false; + c++; + } + if (pwok == false) { + free(f->passw); + f->passw = strdup(itoa36(rng_int())); + ADDMSG(&f->msgs, msg_message("illegal_password", "newpass", f->passw)); + } + f = f->next; + } + return 0; +} + void processorders (void) { @@ -3938,6 +4045,7 @@ processorders (void) /* immer ausf�hren, wenn neue Spr�che dazugekommen sind, oder sich * Beschreibungen ge�ndert haben */ update_spells(); + warn_password(); } int diff --git a/src/common/gamecode/monster.c b/src/common/gamecode/monster.c index 6d650c2e7..e4d4aad2a 100644 --- a/src/common/gamecode/monster.c +++ b/src/common/gamecode/monster.c @@ -59,6 +59,7 @@ /* util includes */ #include <util/attrib.h> #include <util/base36.h> +#include <util/bsdstring.h> #include <util/event.h> #include <util/lists.h> #include <util/rand.h> @@ -136,7 +137,7 @@ monster_attack(unit * u, const unit * target) sprintf(zText, "%s %s", locale_string(u->faction->locale, keywords[K_ATTACK]), unitid(target)); - return parse_order(zText, u->faction->locale); + return parse_order((xmlChar*)zText, u->faction->locale); } @@ -157,7 +158,9 @@ get_money_for_dragon(region * r, unit * u, int wanted) /* falls genug geld in der region ist, treiben wir steuern ein. */ if (rmoney(r) >= wanted) { /* 5% chance, dass der drache aus einer laune raus attackiert */ - if (chance(1.0-u->race->aggression)) return parse_order(keywords[K_TAX], default_locale); + if (chance(1.0-u->race->aggression)) { + return parse_order(LOC(default_locale, keywords[K_TAX]), default_locale); + } } /* falls der drache launisch ist, oder das regionssilber knapp, greift er alle an */ @@ -179,7 +182,7 @@ get_money_for_dragon(region * r, unit * u, int wanted) /* falls die einnahmen erreicht werden, bleibt das monster noch eine * runde hier. */ if (n + rmoney(r) >= wanted) { - return parse_order(keywords[K_TAX], default_locale); + return parse_order(LOC(default_locale, keywords[K_TAX]), default_locale); } /* wenn wir NULL zur�ckliefern, macht der drache was anderes, z.b. weggehen */ @@ -352,6 +355,7 @@ static order * monster_move(region * r, unit * u) { direction_t d = NODIRECTION; + xmlChar zOrder[64]; if (is_waiting(u)) return NULL; switch(old_race(u->race)) { @@ -374,11 +378,11 @@ monster_move(region * r, unit * u) if (d == NODIRECTION) return NULL; - sprintf(buf, "%s %s", locale_string(u->faction->locale, keywords[K_MOVE]), + sprintf((char*)zOrder, "%s %s", locale_string(u->faction->locale, keywords[K_MOVE]), locale_string(u->faction->locale, directions[d])); reduce_weight(u); - return parse_order(buf, u->faction->locale); + return parse_order(zOrder, u->faction->locale); } /* Wir machen das mal autoconf-style: */ @@ -441,9 +445,11 @@ set_new_dragon_target(unit * u, region * r, int range) } else { a->data.v = max_region; } +#if 0 sprintf(buf, "Kommt aus: %s, Will nach: %s", regionname(r, u->faction), regionname(max_region, u->faction)); usetprivate(u, buf); +#endif return a; } return NULL; @@ -455,27 +461,26 @@ make_movement_order(unit * u, const region * target, int moves, boolean (*allowe region * r = u->region; region ** plan; int position = 0; - char * c; + xmlChar zOrder[128]; + char * c = (char*)zOrder; if (is_waiting(u)) return NULL; plan = path_find(r, target, DRAGON_RANGE*5, allowed); if (plan==NULL) return NULL; - strcpy(buf, locale_string(u->faction->locale, keywords[K_MOVE])); - c = buf + strlen(buf); + c += strlcpy(c, (const char *)LOC(u->faction->locale, keywords[K_MOVE]), sizeof(zOrder)); - while (position!=moves && plan[position+1]) { + while (position!=moves && plan[position+1]) { region * prev = plan[position]; region * next = plan[++position]; direction_t dir = reldirection(prev, next); assert(dir!=NODIRECTION && dir!=D_SPECIAL); *c++ = ' '; - strcpy(c, locale_string(u->faction->locale, directions[dir])); - c += strlen(c); + c += strlcpy(c, (const char *)LOC(u->faction->locale, directions[dir]), sizeof(zOrder)-(c-(const char *)zOrder)); } - return parse_order(buf, u->faction->locale); + return parse_order(zOrder, u->faction->locale); } static order * @@ -486,6 +491,7 @@ monster_seeks_target(region *r, unit *u) int dist, dist2; direction_t i; region *nr; + xmlChar zOrder[128]; /* Das Monster sucht ein bestimmtes Opfer. Welches, steht * in einer Referenz/attribut @@ -533,9 +539,9 @@ monster_seeks_target(region *r, unit *u) } assert(d != NODIRECTION ); - sprintf(buf, "%s %s", locale_string(u->faction->locale, keywords[K_MOVE]), + sprintf((char *)zOrder, "%s %s", locale_string(u->faction->locale, keywords[K_MOVE]), locale_string(u->faction->locale, directions[d])); - return parse_order(buf, u->faction->locale); + return parse_order(zOrder, u->faction->locale); } unit * @@ -751,9 +757,10 @@ monster_learn(unit *u) for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { if (sv->level>0) { if (++c == n) { - sprintf(buf, "%s \"%s\"", locale_string(lang, keywords[K_STUDY]), + xmlChar zOrder[128]; + sprintf((char*)zOrder, "%s \"%s\"", locale_string(lang, keywords[K_STUDY]), skillname(sv->id, lang)); - return parse_order(buf, lang); + return parse_order(zOrder, lang); } } } @@ -809,12 +816,13 @@ recruit_dracoids(unit * dragon, int size) setstatus(un, ST_FIGHT); for (weapon=un->items;weapon;weapon=weapon->next) { const weapon_type * wtype = weapon->type->rtype->wtype; + xmlChar zOrder[128]; if (wtype && (wtype->flags & WTF_MISSILE)) { setstatus(un, ST_BEHIND); } - sprintf(buf, "%s \"%s\"", keywords[K_STUDY], + sprintf((char*)zOrder, "%s \"%s\"", keywords[K_STUDY], skillname(weapon->type->rtype->wtype->skill, f->locale)); - new_order = parse_order(buf, default_locale); + new_order = parse_order(zOrder, default_locale); } if (new_order!=NULL) { diff --git a/src/common/gamecode/randenc.c b/src/common/gamecode/randenc.c index 14e1c8113..d68f2a947 100644 --- a/src/common/gamecode/randenc.c +++ b/src/common/gamecode/randenc.c @@ -179,107 +179,78 @@ improve_all(faction * f, skill_t sk, int by_weeks) void find_manual(region * r, unit * u) { + char zLocation[32]; + char zBook[32]; skill_t skill = NOSKILL; - sprintf(buf, "%s stolper%c bei der Erforschung der Region �ber ", - unitname(u), "nt"[u->number == 1]); - - switch (rng_int() % 4) { - case 0: - scat("die Ruine eines alten Tempels"); - break; - case 1: - scat("eine alte Burgruine"); - break; - case 2: - scat("ein zerfallenes Bauernhaus"); - break; - case 3: - scat("eine Leiche am Wegesrand"); - break; - } - - scat(". Bei der Durchsuchung "); - if (u->number == 1) { - scat("st��t"); - } else { - scat("sto�en"); - } - scat(" sie auf das zerfledderte Exemplar eines alten Buches, betitelt "); - + message * msg; + switch (rng_int() % 36) { case 0: - scat("\'Magie der Elemente\'"); skill = SK_MAGIC; break; case 1: case 2: case 3: case 4: - scat("\'Schwerter, Armbr�ste, Langb�gen\'"); skill = SK_WEAPONSMITH; break; case 5: case 6: - scat("\'Gorms Almanach der Rationellen Kriegsf�hrung\'"); skill = SK_TACTICS; break; case 7: case 8: case 9: case 10: - scat("\'Katamarane, Koggen, Karavellen\'"); skill = SK_SHIPBUILDING; break; case 11: case 12: case 13: case 14: - scat("\'Wege der Sterne\'"); skill = SK_SAILING; break; case 15: case 16: case 17: - scat("\'Nadishahs Kleine Gift- und Kr�uterkunde\'"); skill = SK_HERBALISM; break; case 18: case 19: - scat("\'Mandricks Kompendium der Alchemie\'"); skill = SK_ALCHEMY; break; case 20: case 21: case 22: case 23: - scat("\'Die Konstruktion der Burgen und Schl�sser von Zentralandune\'"); skill = SK_BUILDING; break; case 24: case 25: case 26: case 27: - scat("\'Die Esse\'"); skill = SK_ARMORER; break; case 28: case 29: case 30: case 31: - scat("\'�ber die Gewinnung von Erzen\'"); skill = SK_MINING; break; case 32: case 33: case 34: case 35: - scat("\'Barinions Lieder, eine Einf�hrung f�r Unbedarfte\'"); skill = SK_ENTERTAINMENT; break; } - - scat(". Der Wissensschub ist enorm."); - addmessage(r, u->faction, buf, MSG_EVENT, ML_IMPORTANT); + + sprintf(zLocation, "manual_location_%d", rng_int() % 4); + sprintf(zBook, "manual_title_%s", skillnames[skill]); + + msg = msg_message("find_manual", "unit location book", u, zLocation, zBook); + r_addmessage(r, u->faction, msg); + msg_release(msg); if (improve_all(u->faction, skill, 3) == 3) { int i; @@ -288,22 +259,17 @@ find_manual(region * r, unit * u) } static void -get_unit(region * r, unit * u) +get_villagers(region * r, unit * u) { unit *newunit; - sprintf(buf, "%s entdeck%s ein kleines Dorf. Die meisten H�user " - "wurden durch einen �ber die Ufer getretenen Flu� zerst�rt. Eine " - "Gruppe der verzweifelten Menschen schlie�t sich deiner Partei an.", - unitname(u), "en\0t" + (3 - 3 * (u->number == 1))); + message * msg = msg_message("encounter_villagers", "unit", u); + const xmlChar * name = LOC(u->faction->locale, "villagers"); - addmessage(r, u->faction, buf, MSG_EVENT, ML_IMPORTANT); + r_addmessage(r, u->faction, msg); + msg_release(msg); - newunit = createunit(r, u->faction, rng_int() % 20 + 3, u->faction->race); + newunit = create_unit(r, u->faction, rng_int() % 20 + 3, u->faction->race, 0, name, u); fset(newunit, UFL_ISNEW|UFL_MOVED); - set_string(&newunit->name, "Dorfbewohner"); - if (fval(u, UFL_PARTEITARNUNG)) { - fset(newunit, UFL_PARTEITARNUNG); - } equip_unit(newunit, get_equipment("random_villagers")); } @@ -311,17 +277,21 @@ static void get_allies(region * r, unit * u) { unit *newunit = NULL; + const char * name; + const char * equip; + int number; + message * msg; + assert(u->number); - switch (rterrain(r)) { - + switch (rterrain(r)) { case T_PLAIN: if (!r_isforest(r)) { if (get_money(u) / u->number < 100 + rng_int() % 200) return; - newunit = createunit(r, u->faction, rng_int() % 8 + 2, u->faction->race); - set_string(&newunit->name, "S�ldner"); - equip_unit(newunit, get_equipment("random_plain")); + name = "random_plain_men"; + equip = "random_plain"; + number = rng_int() % 8 + 2; break; } else { if (eff_skill(u, SK_LONGBOW, r) < 3 @@ -329,9 +299,9 @@ get_allies(region * r, unit * u) && eff_skill(u, SK_MAGIC, r) < 2) { return; } - newunit = createunit(r, u->faction, rng_int() % 6 + 2, u->faction->race); - set_string(&newunit->name, "Waldbewohner"); - equip_unit(newunit, get_equipment("random_forest")); + name = "random_forest_men"; + equip = "random_forest"; + number = rng_int() % 6 + 2; } break; @@ -339,67 +309,65 @@ get_allies(region * r, unit * u) if (eff_skill(u, SK_OBSERVATION, r) <= 3) { return; } - newunit = createunit(r, u->faction, rng_int() % 6 + 2, u->faction->race); - set_string(&newunit->name, "Sumpfbewohner"); - equip_unit(newunit, get_equipment("random_swamp")); + name = "random_swamp_men"; + equip = "random_swamp"; + number = rng_int() % 6 + 2; break; case T_DESERT: if (eff_skill(u, SK_RIDING, r) <= 2) { return; } - newunit = createunit(r, u->faction, rng_int() % 12 + 2, u->faction->race); - set_string(&newunit->name, "Berber"); - equip_unit(newunit, get_equipment("random_desert")); + name = "random_desert_men"; + equip = "random_desert"; + number = rng_int() % 12 + 2; break; case T_HIGHLAND: if (eff_skill(u, SK_MELEE, r) <= 1) { return; } - newunit = createunit(r, u->faction, rng_int() % 8 + 2, u->faction->race); - set_string(&newunit->name, "Hochlandbarbaren"); - equip_unit(newunit, get_equipment("random_highland")); + name = "random_highland_men"; + equip = "random_highland"; + number = rng_int() % 8 + 2; break; case T_MOUNTAIN: - if (eff_skill(u, SK_MELEE, r) <= 1 - || eff_skill(u, SK_TRADE, r) <= 2) { - return; - } - newunit = createunit(r, u->faction, rng_int() % 6 + 2, u->faction->race); - set_string(&newunit->name, "Bergbewohner"); - equip_unit(newunit, get_equipment("random_mountain")); - + if (eff_skill(u, SK_MELEE, r) <= 1 || eff_skill(u, SK_TRADE, r) <= 2) { + return; + } + name = "random_mountain_men"; + equip = "random_mountain"; + number = rng_int() % 6 + 2; break; case T_GLACIER: - if (eff_skill(u, SK_MELEE, r) <= 1 - || eff_skill(u, SK_TRADE, r) <= 1) { + if (eff_skill(u, SK_MELEE, r) <= 1 || eff_skill(u, SK_TRADE, r) <= 1) { return; } - newunit = createunit(r, u->faction, rng_int() % 4 + 2, u->faction->race); - set_string(&newunit->name, "Eisleute"); - equip_unit(newunit, get_equipment("random_glacier")); - + name = "random_glacier_men"; + equip = "random_glacier"; + number = rng_int() % 4 + 2; break; + + default: + return; } - if (newunit!=NULL) { - u_setfaction(newunit, u->faction); - set_racename(&newunit->attribs, get_racename(u->attribs)); - if(u->race->flags & RCF_SHAPESHIFT) { - newunit->irace = u->irace; - } - if (fval(u, UFL_PARTEITARNUNG)) fset(newunit, UFL_PARTEITARNUNG); - fset(newunit, UFL_ISNEW); + newunit = create_unit(r, u->faction, number, u->faction->race, 0, LOC(u->faction->locale, name), u); + equip_unit(newunit, get_equipment(equip)); - sprintf(buf, "Pl�tzlich stolper%c %s �ber einige %s. Nach kurzem " - "Z�gern entschlie�en sich die %s, sich Deiner Partei anzuschlie�en.", - u->number == 1 ? 't' : 'n', unitname(u), newunit->name, newunit->name); + u_setfaction(newunit, u->faction); + set_racename(&newunit->attribs, get_racename(u->attribs)); + if(u->race->flags & RCF_SHAPESHIFT) { + newunit->irace = u->irace; + } + if (fval(u, UFL_PARTEITARNUNG)) fset(newunit, UFL_PARTEITARNUNG); + fset(newunit, UFL_ISNEW); - addmessage(r, u->faction, buf, MSG_EVENT, ML_IMPORTANT); - } + msg = msg_message("encounter_allies", "unit name", u, name); + r_addmessage(r, u->faction, msg); + msg_release(msg); } static void @@ -413,7 +381,7 @@ encounter(region * r, unit * u) find_manual(r, u); break; case 1: - get_unit(r, u); + get_villagers(r, u); break; case 2: get_allies(r, u); @@ -484,9 +452,7 @@ chaos(region * r) if (!fval(r->terrain, SEA_REGION)) { u = random_unit(r); if (u && playerrace(u->race)) { - sprintf(buf, "%s scheint von einer seltsamen Krankheit befallen.", - unitname(u)); - addmessage(0, u->faction, buf, MSG_EVENT, ML_IMPORTANT); + ADDMSG(&u->faction->msgs, msg_message("chaos_disease", "unit", u)); u_setfaction(u, findfaction(MONSTER_FACTION)); u->race = new_race[RC_GHOUL]; } @@ -499,29 +465,14 @@ chaos(region * r) case 0: mfac = 100; u = createunit(r, findfaction(MONSTER_FACTION), rng_int() % 8 + 1, new_race[RC_FIREDRAGON]); - if (u->number == 1) { - set_string(&u->name, "Feuerdrache"); - } else { - set_string(&u->name, "Feuerdrachen"); - } break; case 1: mfac = 500; u = createunit(r, findfaction(MONSTER_FACTION), rng_int() % 4 + 1, new_race[RC_DRAGON]); - if (u->number == 1) { - set_string(&u->name, "Drache"); - } else { - set_string(&u->name, "Drachen"); - } break; case 2: mfac = 1000; u = createunit(r, findfaction(MONSTER_FACTION), rng_int() % 2 + 1, new_race[RC_WYRM]); - if (u->number == 1) { - set_string(&u->name, "Wyrm"); - } else { - set_string(&u->name, "Wyrme"); - } break; } if (mfac) set_money(u, u->number * (rng_int() % mfac)); diff --git a/src/common/gamecode/report.c b/src/common/gamecode/report.c index d42c128cd..27f3318da 100644 --- a/src/common/gamecode/report.c +++ b/src/common/gamecode/report.c @@ -3057,6 +3057,41 @@ eval_resources(struct opstack ** stack, const void * userdata) /* order -> strin opush(stack, var); } +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; + const arg_regions * regions = (const arg_regions *)opop(stack).v; + static char buf[256]; + size_t len = sizeof(buf); + variant var; + char * edit = buf; + + if (regions==NULL) { + end = begin; + } else { + if (i>=0) end = begin+i; + else end = regions->nregions+i; + } + for (i=begin;i<end;++i) { + const char * rname = (const char*)regionname(regions->regions[i], report); + size_t written = strlcpy(edit, rname, len); + len -= written; + edit += written; + + if (i+1<end && len>2) { + strcat(edit, ", "); + edit += 2; + len -= 2; + } + } + *edit = 0; + var.v = strcpy(balloc(edit-buf+1), buf); + opush(stack, var); +} + static void eval_direction(struct opstack ** stack, const void * userdata) { @@ -3122,6 +3157,7 @@ report_init(void) add_function("localize", &eval_localize); add_function("spell", &eval_spell); add_function("resources", &eval_resources); + add_function("regions", &eval_regions); register_reporttype("nr", &report_plaintext, 1<<O_REPORT); register_reporttype("txt", &report_template, 1<<O_ZUGVORLAGE); diff --git a/src/common/gamecode/study.c b/src/common/gamecode/study.c index d2564900f..6ede37837 100644 --- a/src/common/gamecode/study.c +++ b/src/common/gamecode/study.c @@ -48,6 +48,7 @@ #include <util/base36.h> #include <util/parser.h> #include <util/rand.h> +#include <util/umlaut.h> /* libc includes */ #include <assert.h> @@ -65,16 +66,17 @@ getskill(const struct locale * lang) return findskill(getstrtoken(), lang); } -static magic_t -findmagicskill(const char *s) -{ - return (char) findstr(magietypen, s, MAXMAGIETYP); -} - magic_t -getmagicskill(void) +getmagicskill(const struct locale * lang) { - return findmagicskill(getstrtoken()); + struct tnode * tokens = get_translations(lang, UT_MAGIC); + variant token; + const xmlChar * s = getstrtoken(); + + if (findtoken(tokens, s, &token)==E_TOK_SUCCESS) { + return (magic_t)token.i; + } + return M_NONE; } /* ------------------------------------------------------------- */ @@ -346,13 +348,13 @@ teach_cmd(unit * u, struct order * ord) else #endif { - static char zOrder[BUFSIZE]; + static xmlChar zOrder[BUFSIZE]; order * new_order; init_tokens(ord); skip_token(); - strcpy(zOrder, locale_string(u->faction->locale, keywords[K_TEACH])); + strcpy((char*)zOrder, (const char *)locale_string(u->faction->locale, keywords[K_TEACH])); while (!parser_end()) { unit * u2 = getunit(r, u->faction); @@ -361,7 +363,9 @@ teach_cmd(unit * u, struct order * ord) /* Falls die Unit nicht gefunden wird, Fehler melden */ if (!u2) { - const char * token; + xmlChar tbuf[20]; + const xmlChar * uid; + const xmlChar * token; /* Finde den string, der den Fehler verursacht hat */ parser_pushstate(); init_tokens(ord); @@ -377,16 +381,16 @@ teach_cmd(unit * u, struct order * ord) /* Beginne die Fehlermeldung */ strcpy(buf, "Die Einheit '"); - if (findparam(token, u->faction->locale) == P_TEMP) { - /* F�r: "Die Einheit 'TEMP ZET' wurde nicht gefunden" oder "Die Einheit - * 'TEMP' wurde nicht gefunden" */ - scat(token); + if (findparam(token, u->faction->locale) != P_TEMP) { + uid = token; + } else { token = getstrtoken(); - if (*token) scat(" "); + sprintf((char*)tbuf, "%s %s", LOC(u->faction->locale, + parameters[P_TEMP]), token); + uid = tbuf; } - scat(token); - scat("' wurde nicht gefunden"); - mistake(u, ord, buf, MSG_EVENT); + ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "unitnotfound_id", + "id", uid)); parser_popstate(); continue; @@ -394,8 +398,8 @@ teach_cmd(unit * u, struct order * ord) /* Neuen Befehl zusammenbauen. TEMP-Einheiten werden automatisch in * ihre neuen Nummern �bersetzt. */ - strcat(zOrder, " "); - strcat(zOrder, unitid(u2)); + strcat((char*)zOrder, " "); + strcat((char*)zOrder, unitid(u2)); if (get_keyword(u2->thisorder) != K_STUDY) { ADDMSG(&u->faction->msgs, @@ -558,7 +562,7 @@ learn_cmd(unit * u, order * ord) mistake(u, ord, buf, MSG_EVENT); return 0; } - mtyp = getmagicskill(); + mtyp = getmagicskill(u->faction->locale); if (mtyp == M_NONE || mtyp == M_GRAU) { /* wurde kein Magiegebiet angegeben, wird davon * ausgegangen, da� das normal gelernt werden soll */ @@ -588,7 +592,7 @@ learn_cmd(unit * u, order * ord) /* ist schon ein Magier und kein Vertrauter */ if(u->faction->magiegebiet == 0){ /* die Partei hat noch kein Magiegebiet gew�hlt. */ - mtyp = getmagicskill(); + mtyp = getmagicskill(u->faction->locale); if (mtyp == M_NONE){ cmistake(u, ord, 178, MSG_MAGIC); return 0; diff --git a/src/common/gamecode/study.h b/src/common/gamecode/study.h index 0397f1a7a..efbaa8c8c 100644 --- a/src/common/gamecode/study.h +++ b/src/common/gamecode/study.h @@ -22,7 +22,7 @@ extern "C" { extern int teach_cmd(struct unit * u, struct order * ord); extern int learn_cmd(struct unit * u, struct order * ord); -extern magic_t getmagicskill(void); +extern magic_t getmagicskill(const struct locale * lang); extern boolean is_migrant(struct unit *u); extern int study_cost(struct unit *u, skill_t talent); diff --git a/src/common/gamecode/xmlreport.c b/src/common/gamecode/xmlreport.c index edaaf6abb..9953d37b9 100644 --- a/src/common/gamecode/xmlreport.c +++ b/src/common/gamecode/xmlreport.c @@ -107,9 +107,9 @@ report_faction(report_context * ctx, faction * f) { xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "faction"); xmlNewProp(node, BAD_CAST "id", xml_i(f->no)); - xmlNewProp(node, BAD_CAST "name", xml_s(f->name)); + xmlNewProp(node, BAD_CAST "name", f->name); xmlNewProp(node, BAD_CAST "email", xml_s(f->email)); - if (f->banner && *f->banner) xmlNewProp(node, BAD_CAST "banner", xml_s(f->banner)); + if (f->banner && *f->banner) xmlNewProp(node, BAD_CAST "banner", f->banner); if (f==ctx->f) { const char * s; xmlNewProp(node, BAD_CAST "locale", BAD_CAST locale_name(f->locale)); diff --git a/src/common/kernel/alliance.c b/src/common/kernel/alliance.c index 787eafdd2..074520dc6 100644 --- a/src/common/kernel/alliance.c +++ b/src/common/kernel/alliance.c @@ -24,12 +24,13 @@ #include <kernel/region.h> #include <kernel/unit.h> #include <kernel/item.h> +#include <kernel/command.h> /* util includes */ #include <util/attrib.h> #include <util/base36.h> -#include <util/command.h> #include <util/lists.h> +#include <util/parser.h> #include <util/umlaut.h> /* libc includes */ @@ -88,10 +89,10 @@ add_kick(attrib * a, const faction * f) } static void -alliance_kick(const tnode * tnext, const char * str, void * data, struct order * ord) +alliance_kick(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; - faction * f = findfaction(atoi36(igetstrtoken(str))); + faction * f = findfaction(getid()); attrib * a; unused(tnext); @@ -105,10 +106,10 @@ alliance_kick(const tnode * tnext, const char * str, void * data, struct order * } static void -alliance_join(const tnode * tnext, const char * str, void * data, struct order * ord) +alliance_join(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; - alliance * al = findalliance(atoi36(igetstrtoken(str))); + alliance * al = findalliance(getid()); unused(tnext); if (u->faction->alliance!=NULL || al==NULL) { @@ -236,7 +237,7 @@ alliancename(const alliance * al) char *ibuf = idbuf[(++nextbuf) % 8]; if (al && al->name) { - snprintf(ibuf, sizeof(name), "%s (%s)", strcheck(al->name, NAMESIZE), itoa36(al->id)); + snprintf(ibuf, sizeof(name), "%s (%s)", al->name, itoa36(al->id)); ibuf[sizeof(name)-1] = 0; } else { return NULL; diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index 69732fe30..b0cdc9a03 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -2879,7 +2879,7 @@ print_stats(battle * b) faction * f = bf->faction; const char * loc_army = LOC(f->locale, "battle_army"); char * bufp; - const char * header; + const xmlChar * header; size_t rsize, size; int komma; diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c index f0b8ab015..e38ede2bb 100644 --- a/src/common/kernel/building.c +++ b/src/common/kernel/building.c @@ -344,7 +344,7 @@ wdw_pyramid_level(const struct building *b) static local_names * bnames; const building_type * -findbuildingtype(const char * name, const struct locale * lang) +findbuildingtype(const xmlChar * name, const struct locale * lang) { variant type; local_names * bn = bnames; @@ -359,7 +359,7 @@ findbuildingtype(const char * name, const struct locale * lang) bn->next = bnames; bn->lang = lang; while (btl) { - const char * n = locale_string(lang, btl->type->_name); + const xmlChar * n = locale_string(lang, btl->type->_name); type.v = (void*)btl->type; addtoken(&bn->names, n, type); btl=btl->next; @@ -440,7 +440,6 @@ new_building(const struct building_type * btype, region * r, const struct locale bhash(b); b->type = btype; - set_string(&b->display, ""); b->region = r; addlist(&r->buildings, b); diff --git a/src/common/kernel/building.h b/src/common/kernel/building.h index 239d336e7..3b8c29f2b 100644 --- a/src/common/kernel/building.h +++ b/src/common/kernel/building.h @@ -89,8 +89,8 @@ typedef struct building { const struct building_type * type; struct region *region; - char *name; - char *display; + xmlChar *name; + xmlChar *display; struct attrib * attribs; int no; int size; @@ -123,7 +123,7 @@ void bunhash(struct building * b); int buildingcapacity(const struct building * b); void destroy_building(struct building * b); -const struct building_type * findbuildingtype(const char * name, const struct locale * lang); +const struct building_type * findbuildingtype(const xmlChar * name, const struct locale * lang); #include "build.h" #define NOBUILDING NULL diff --git a/src/common/util/command.c b/src/common/kernel/command.c similarity index 71% rename from src/common/util/command.c rename to src/common/kernel/command.c index 556ebe7bf..2e6e39ee3 100644 --- a/src/common/util/command.c +++ b/src/common/kernel/command.c @@ -11,11 +11,15 @@ */ #include <config.h> +#include "eressea.h" #include "command.h" -#include "umlaut.h" -#include "language.h" -#include "log.h" +#include <kernel/order.h> + +#include <util/umlaut.h> +#include <util/language.h> +#include <util/log.h> +#include <util/parser.h> /* libc includes */ #include <assert.h> @@ -55,7 +59,7 @@ stree_create(void) void add_command(struct tnode * keys, struct tnode * tnext, - const char * str, parser fun) + const xmlChar * str, parser fun) { command * cmd = (command *)malloc(sizeof(command)); variant var; @@ -67,43 +71,33 @@ add_command(struct tnode * keys, struct tnode * tnext, } static int -do_command_i(const struct tnode * keys, void * u, const char * str, struct order * ord) +do_command_i(const struct tnode * keys, void * u, struct order * ord) { - size_t i; - char zText[16]; - const char * c; + const xmlChar * c; variant var; - while (isspace(*str)) ++str; - c = str; - while (isalnum(*c)) ++c; - i = min(16, c-str); - strncpy(zText, str, i); - zText[i]=0; - if (findtoken(keys, zText, &var)==E_TOK_SUCCESS) { + c = getstrtoken(); + if (findtoken(keys, c, &var)==E_TOK_SUCCESS) { command * cmd = (command *)var.v; if (cmd->nodes && *c) { assert(!cmd->fun); - return do_command_i(cmd->nodes, u, ++c, ord); + return do_command_i(cmd->nodes, u, ord); } else if (cmd->fun) { - cmd->fun(cmd->nodes, ++c, u, ord); + cmd->fun(cmd->nodes, u, ord); return E_TOK_SUCCESS; } } return E_TOK_NOMATCH; } -struct unit; -struct order; -extern char * getcommand(struct order * ord); -extern char * unitname(struct unit * u); - void do_command(const struct tnode * keys, void * u, struct order * ord) { - char * cmd = getcommand(ord); - if (do_command_i(keys, u, cmd, ord)!=E_TOK_SUCCESS) { + init_tokens(ord); + skip_token(); + if (do_command_i(keys, u, ord)!=E_TOK_SUCCESS) { + xmlChar * cmd = getcommand(ord); log_warning(("%s failed GM command '%s'\n", unitname(u), cmd)); + free(cmd); } - free(cmd); } diff --git a/src/common/util/command.h b/src/common/kernel/command.h similarity index 90% rename from src/common/util/command.h rename to src/common/kernel/command.h index 33fe98d10..cfdb8267d 100644 --- a/src/common/util/command.h +++ b/src/common/kernel/command.h @@ -26,8 +26,8 @@ typedef struct syntaxtree { struct syntaxtree * next; } syntaxtree; -typedef void (*parser)(const struct tnode *, const char*, void *, struct order*); -extern void add_command(struct tnode * troot, struct tnode * tnext, const char * str, parser fun); +typedef void (*parser)(const struct tnode *, void *, struct order*); +extern void add_command(struct tnode * troot, struct tnode * tnext, const xmlChar * str, parser fun); extern void do_command(const struct tnode * troot, void * u, struct order *); extern struct syntaxtree * stree_create(void); diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index 3fab50fea..103b0c741 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -91,7 +91,6 @@ region *regions; faction *factions; settings global; -char buf[BUFSIZE + 1]; FILE *logfile; FILE *updatelog; const struct race * new_race[MAXRACES]; @@ -252,12 +251,16 @@ const char *directions[MAXDIRECTIONS+2] = "pause" }; +/** Returns the English name of the race, which is what the database uses. + */ const char * dbrace(const struct race * rc) { static char zText[32]; char * zPtr = zText; - strcpy(zText, LOC(find_locale("en"), rc_name(rc, 0))); + + /* the english names are all in ASCII, so we don't need to worry about UTF8 */ + strcpy(zText, (const char*)LOC(find_locale("en"), rc_name(rc, 0))); while (*zPtr) { *zPtr = (char)(toupper(*zPtr)); ++zPtr; @@ -785,7 +788,7 @@ change_hitpoints (unit * u, int value) return hp; } -int +unsigned int atoip(const char *s) { int n; @@ -798,22 +801,6 @@ atoip(const char *s) return n; } -void -scat (const char *s) -{ - strncat (buf, s, BUFSIZE - strlen (buf)); -} - -void -icat (int n) -{ - char s[12]; - - sprintf (s, "%d", n); - scat (s); -} - - region * findunitregion (const unit * su) { @@ -1291,7 +1278,7 @@ count_maxmigrants(const faction * f) void init_tokens(const struct order * ord) { - char * cmd = getcommand(ord); + xmlChar * cmd = getcommand(ord); init_tokens_str(cmd, cmd); } @@ -1320,8 +1307,8 @@ parse(keyword_t kword, int (*dofun)(unit *, struct order *), boolean thisorder) } } -const char * -igetstrtoken(const char * initstr) +const xmlChar * +igetstrtoken(const xmlChar * initstr) { if (initstr!=NULL) { init_tokens_str(initstr, NULL); @@ -1330,36 +1317,20 @@ igetstrtoken(const char * initstr) return getstrtoken(); } -int -geti (void) +unsigned int +getuint (void) { - return atoip (getstrtoken ()); + return atoip((const char *)getstrtoken()); } -/* GET KEYWORD, SKILL, ITEM, SPELL benutzen FINDSTR - welche Item um Item eine - * Liste durchsucht. - * - * FIND wird immer von GET aufgerufen. GET braucht keine Parameter, IGET braucht - * einen String aus dem gelesen wird. In FIND stehen dann listen etc drinnen. - * FIND kann man auch allein verwenden, wenn der string _nur_ noch das gesuchte - * object enthaelt. Steht noch weitere info darin, sollte man GET verwenden, - * bzw. GETI wenn die info am Anfang eines neuen Stringes steht. */ - int -findstr(const char **v, const char *s, unsigned char n) +getint (void) { - int i; - size_t ss = strlen(s); - if (!ss) - return -1; - for (i = 0; i != n; i++) - if (!strncasecmp(s, v[i], ss)) - return i; - return -1; + return atoi((const char *)getstrtoken()); } const struct race * -findrace(const char * s, const struct locale * lang) +findrace(const xmlChar * s, const struct locale * lang) { struct tnode * tokens = get_translations(lang, UT_RACES); variant token; @@ -1371,7 +1342,7 @@ findrace(const char * s, const struct locale * lang) } int -findoption(const char *s, const struct locale * lang) +findoption(const xmlChar *s, const struct locale * lang) { struct tnode * tokens = get_translations(lang, UT_OPTIONS); variant token; @@ -1383,7 +1354,7 @@ findoption(const char *s, const struct locale * lang) } skill_t -findskill(const char *s, const struct locale * lang) +findskill(const xmlChar *s, const struct locale * lang) { struct tnode * tokens = get_translations(lang, UT_SKILLS); variant token; @@ -1393,7 +1364,7 @@ findskill(const char *s, const struct locale * lang) } keyword_t -findkeyword(const char *s, const struct locale * lang) +findkeyword(const xmlChar *s, const struct locale * lang) { struct tnode * tokens = get_translations(lang, UT_KEYWORDS); variant token; @@ -1405,7 +1376,7 @@ findkeyword(const char *s, const struct locale * lang) } param_t -findparam(const char *s, const struct locale * lang) +findparam(const xmlChar *s, const struct locale * lang) { struct tnode * tokens = get_translations(lang, UT_PARAMS); variant token; @@ -1518,19 +1489,19 @@ read_newunitid (const faction * f, const region * r) int read_unitid (const faction * f, const region * r) { - const char * s = getstrtoken (); + const xmlChar * s = getstrtoken(); /* Da s nun nur einen string enthaelt, suchen wir ihn direkt in der * paramliste. machen wir das nicht, dann wird getnewunit in s nach der * nummer suchen, doch dort steht bei temp-units nur "temp" drinnen! */ - switch (findparam (s, f->locale)) { + switch (findparam(s, f->locale)) { case P_TEMP: return read_newunitid(f, r); } if (!s || *s == 0) return -1; - return atoi36(s); + return atoi36((const char *)s); } /* exported symbol */ @@ -1647,7 +1618,7 @@ buildingname (const building * b) { char *ibuf = idbuf[(++nextbuf) % 8]; - snprintf(ibuf, sizeof(name), "%s (%s)", strcheck(b->name, NAMESIZE), itoa36(b->no)); + snprintf(ibuf, sizeof(name), "%s (%s)", b->name, itoa36(b->no)); ibuf[sizeof(name)-1] = 0; return ibuf; } @@ -1679,7 +1650,7 @@ const char * unitname(const unit * u) { char *ubuf = idbuf[(++nextbuf) % 8]; - snprintf(ubuf, sizeof(name), "%s (%s)", strcheck(u->name, NAMESIZE), itoa36(u->no)); + snprintf(ubuf, sizeof(name), "%s (%s)", u->name, itoa36(u->no)); ubuf[sizeof(name)-1] = 0; return ubuf; } @@ -1988,17 +1959,17 @@ use_birthdayamulet(region * r, unit * magician, order * ord) { region *tr; direction_t d; + message * msg = msg_message("meow", ""); unused(ord); unused(magician); + add_message(&r->msgs, msg); for(d=0;d<MAXDIRECTIONS;d++) { tr = rconnect(r, d); - if(tr) addmessage(tr, 0, "Miiauuuuuu...", MSG_MESSAGE, ML_IMPORTANT); + if (tr) add_message(&tr->msgs, msg); } - - tr = r; - addmessage(r, 0, "Miiauuuuuu...", MSG_MESSAGE, ML_IMPORTANT); + msg_release(msg); } static void @@ -2036,7 +2007,7 @@ init_directions(tnode * root, const struct locale * lang) } direction_t -finddirection(const char *s, const struct locale * lang) +finddirection(const xmlChar *s, const struct locale * lang) { struct tnode * tokens = get_translations(lang, UT_DIRECTIONS); variant token; @@ -2054,6 +2025,13 @@ init_locale(const struct locale * lang) int i; const struct race * rc; struct tnode * tokens; + const terrain_type * terrain; + + tokens = get_translations(lang, UT_MAGIC); + for (i=0;i!=MAXMAGIETYP;++i) { + var.i = i; + addtoken(tokens, LOC(lang, magietypen[i]), var); + } tokens = get_translations(lang, UT_DIRECTIONS); init_directions(tokens, lang); @@ -2074,7 +2052,7 @@ init_locale(const struct locale * lang) tokens = get_translations(lang, UT_SKILLS); for (i=0;i!=MAXSKILLS;++i) { if (i!=SK_TRADE || !TradeDisabled()) { - const char * skname = skillname((skill_t)i, lang); + const xmlChar * skname = skillname((skill_t)i, lang); if (skname!=NULL) { var.i = i; addtoken(tokens, skname, var); @@ -2093,6 +2071,12 @@ init_locale(const struct locale * lang) var.i = i; addtoken(tokens, LOC(lang, options[i]), var); } + + tokens = get_translations(lang, UT_TERRAINS); + for (terrain=terrains();terrain!=NULL;terrain=terrain->next) { + var.v = terrain; + addtoken(tokens, LOC(lang, terrain->_name), var); + } } typedef struct param { @@ -2633,16 +2617,16 @@ wage(const region *r, const faction * f, const race * rc) static region * -findspecialdirection(const region *r, const char *token) +findspecialdirection(const region *r, const xmlChar *token) { attrib *a; spec_direction *d; - if (strlen(token)==0) return NULL; + if (xmlStrlen(token)==0) return NULL; for (a = a_find(r->attribs, &at_direction);a && a->type==&at_direction;a=a->next) { d = (spec_direction *)(a->data.v); - if (d->active && strncasecmp(d->keyword, token, strlen(token)) == 0) { + if (d->active && xmlStrncasecmp(d->keyword, token, xmlStrlen(token)) == 0) { return findregion(d->x, d->y); } } @@ -2663,7 +2647,7 @@ maintenance_cost(const struct unit * u) } message * -movement_error(unit * u, const char * token, order * ord, int error_code) +movement_error(unit * u, const xmlChar * token, order * ord, int error_code) { direction_t d; switch (error_code) { @@ -2677,7 +2661,7 @@ movement_error(unit * u, const char * token, order * ord, int error_code) } int -movewhere(const unit *u, const char * token, region * r, region** resultp) +movewhere(const unit *u, const xmlChar * token, region * r, region** resultp) { region * r2; direction_t d; diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index d7bdae1fb..eb6ca25db 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -177,13 +177,9 @@ extern int count_skill(struct faction * f, skill_t sk); /* direction, geography */ extern const char *directions[]; -extern direction_t finddirection(const char *s, const struct locale *); +extern direction_t finddirection(const xmlChar *s, const struct locale *); -extern int findoption(const char *s, const struct locale * lang); - -/* shared character-buffer */ -#define BUFSIZE 32765 -extern char buf[BUFSIZE + 1]; +extern int findoption(const xmlChar *s, const struct locale * lang); /* special units */ void make_undead_unit(struct unit *); @@ -195,27 +191,22 @@ void addstrlist(strlist ** SP, const char *s); int armedmen(const struct unit * u); -void scat(const char *s); -void icat(int n); +unsigned int atoip(const char *s); +unsigned int getuint(void); +int getint(void); -int atoip(const char *s); -int geti(void); - -extern int findstr(const char **v, const char *s, unsigned char n); - -extern const char *igetstrtoken(const char *s); +extern const xmlChar *igetstrtoken(const xmlChar *s); extern void init_tokens(const struct order * ord); /* initialize token parsing */ -extern skill_t findskill(const char *s, const struct locale * lang); +extern skill_t findskill(const xmlChar *s, const struct locale * lang); -extern keyword_t findkeyword(const char *s, const struct locale * lang); +extern keyword_t findkeyword(const xmlChar *s, const struct locale * lang); -extern param_t findparam(const char *s, const struct locale * lang); +extern param_t findparam(const xmlChar *s, const struct locale * lang); extern param_t getparam(const struct locale * lang); extern int atoi36(const char * s); -#define getid() atoi36(getstrtoken()) -#define getstruct unitid() getid() +#define getid() atoi36((const char *)getstrtoken()) #define unitid(x) itoa36((x)->no) #define getshipid() getid() @@ -276,14 +267,14 @@ extern int count_migrants (const struct faction * f); extern int count_maxmigrants(const struct faction * f); extern boolean teure_talente(const struct unit * u); -extern const struct race * findrace(const char *, const struct locale *); +extern const struct race * findrace(const xmlChar *, const struct locale *); int eff_stealth(const struct unit * u, const struct region * r); void scale_number(struct unit * u, int n); int unit_max_hp(const struct unit * u); int ispresent(const struct faction * f, const struct region * r); -char * set_string(char **s, const char *neu); +xmlChar * set_string(xmlChar **s, const xmlChar *neu); int check_option(struct faction * f, int option); extern void parse(keyword_t kword, int (*dofun)(struct unit *, struct order *), boolean thisorder); @@ -313,19 +304,12 @@ struct unit *ufindhash(int i); void fhash(struct faction * f); void funhash(struct faction * f); -#ifndef NDEBUG -const char *strcheck(const char *s, size_t maxlen); - -#else -#define strcheck(s, ml) (s) -#endif - boolean idle(struct faction * f); boolean unit_has_cursed_item(struct unit *u); /* simple garbage collection: */ void * gc_add(void * p); -void addmessage(struct region * r, struct faction * f, const char *s, msg_t mtype, int level); +void addmessage(struct region * r, struct faction * f, const xmlChar *s, msg_t mtype, int level); /* grammatik-flags: */ #define GF_NONE 0 @@ -376,7 +360,7 @@ extern int maxworkingpeasants(const struct region * r); extern int wage(const struct region *r, const struct faction *f, const struct race * rc); extern int maintenance_cost(const struct unit * u); -extern struct message * movement_error(struct unit * u, const char * token, struct order * ord, int error_code); +extern struct message * movement_error(struct unit * u, const xmlChar * token, struct order * ord, int error_code); extern boolean move_blocked(const struct unit * u, const struct region *src, const struct region *dest); extern void add_income(struct unit * u, int type, int want, int qty); @@ -386,7 +370,7 @@ enum { E_MOVE_NOREGION, /* no region exists in this direction */ E_MOVE_BLOCKED /* cannot see this region, there is a blocking border. */ }; -extern int movewhere(const struct unit *u, const char * token, struct region * r, struct region** resultp); +extern int movewhere(const struct unit *u, const xmlChar * token, struct region * r, struct region** resultp); extern const char * basepath(void); extern const char * resourcepath(void); diff --git a/src/common/kernel/faction.c b/src/common/kernel/faction.c index 125872f3f..8859e191c 100644 --- a/src/common/kernel/faction.c +++ b/src/common/kernel/faction.c @@ -72,7 +72,7 @@ factionname(const faction * f) char *ibuf = idbuf[(++nextbuf) % 8]; if (f && f->name) { - snprintf(ibuf, sizeof(name), "%s (%s)", strcheck(f->name, NAMESIZE), itoa36(f->no)); + snprintf(ibuf, sizeof(name), "%s (%s)", f->name, itoa36(f->no)); ibuf[sizeof(name)-1] = 0; } else { strcpy(ibuf, "Unbekannte Partei (?)"); @@ -100,12 +100,12 @@ unused_faction_id(void) } faction * -addfaction(const char *email, const char * password, +addfaction(const char *email, const xmlChar * password, const struct race * frace, const struct locale *loc, int subscription) { - int i; faction * f = calloc(sizeof(faction), 1); + const char * pass = itoa36(rng_int()); assert(frace && frace != new_race[RC_ORC]); @@ -113,14 +113,13 @@ addfaction(const char *email, const char * password, log_error(("Invalid email address for faction %s: %s\n", itoa36(f->no), email)); } + set_string(&f->override, (const xmlChar *)pass); if (password) { set_string(&f->passw, password); } else { - for (i = 0; i < 6; i++) buf[i] = (char) (97 + rng_int() % 26); buf[i] = 0; - set_string(&f->passw, buf); + pass = itoa36(rng_int()); + set_string(&f->passw, (const xmlChar *)pass); } - for (i = 0; i < 6; i++) buf[i] = (char) (97 + rng_int() % 26); buf[i] = 0; - set_string(&f->override, buf); f->lastorders = turn; f->alive = 1; @@ -137,7 +136,7 @@ addfaction(const char *email, const char * password, fhash(f); sprintf(buf, "%s %s", LOC(loc, "factiondefault"), factionid(f)); - set_string(&f->name, buf); + set_string(&f->name, (const xmlChar*)buf); return f; } @@ -166,7 +165,7 @@ addplayer(region *r, faction * f) } boolean -checkpasswd(const faction * f, const char * passwd, boolean shortp) +checkpasswd(const faction * f, const xmlChar * passwd, boolean shortp) { #ifdef SHORTPWDS shortpwd * slist = f->shortpwds; @@ -178,8 +177,8 @@ checkpasswd(const faction * f, const char * passwd, boolean shortp) slist = slist->next; } #endif - if (strcasecmp(f->passw, passwd)==0) return true; - if (strcasecmp(f->override, passwd)==0) return true; + if (xmlStrcmp(f->passw, passwd)==0) return true; + if (xmlStrcmp(f->override, passwd)==0) return true; return false; } diff --git a/src/common/kernel/faction.h b/src/common/kernel/faction.h index dea2ab082..1b2f43903 100644 --- a/src/common/kernel/faction.h +++ b/src/common/kernel/faction.h @@ -64,11 +64,11 @@ typedef struct faction { int no; int subscription; unsigned int flags; - char *name; - char *banner; + xmlChar *name; + xmlChar *banner; char *email; - char *passw; - char *override; + xmlChar *passw; + xmlChar *override; #ifdef SHORTPWDS struct shortpwd * shortpwds; #endif @@ -121,10 +121,10 @@ extern const struct unit * random_unit_in_faction(const struct faction *f); extern const char * factionname(const struct faction * f); extern void * resolve_faction(variant data); extern struct unit * addplayer(struct region *r, faction * f); -extern struct faction * addfaction(const char *email, const char* password, +extern struct faction * addfaction(const char *email, const xmlChar* password, const struct race * frace, const struct locale *loc, int subscription); -extern boolean checkpasswd(const faction * f, const char * passwd, boolean shortp); +extern boolean checkpasswd(const faction * f, const xmlChar * passwd, boolean shortp); extern void destroyfaction(faction * f); extern void set_alliance(struct faction * a, struct faction * b, int status); diff --git a/src/common/kernel/item.c b/src/common/kernel/item.c index 206b83cf4..e3fcbf0ed 100644 --- a/src/common/kernel/item.c +++ b/src/common/kernel/item.c @@ -952,7 +952,7 @@ change_money(unit * u, int v) static local_names * rnames; const resource_type * -findresourcetype(const char * name, const struct locale * lang) +findresourcetype(const xmlChar * name, const struct locale * lang) { local_names * rn = rnames; variant token; @@ -1011,7 +1011,7 @@ init_itemnames(void) const item_type * itl; for (itl=itemtypes[key];itl;itl=itl->next) { variant var; - const char * iname = locale_string(lang, itl->rtype->_name[0]); + const xmlChar * iname = locale_string(lang, itl->rtype->_name[0]); if (findtoken(&in->names, iname, &var)==E_TOK_NOMATCH || var.v!=itl) { var.v = (void*)itl; addtoken(&in->names, iname, var); @@ -1025,7 +1025,7 @@ init_itemnames(void) } const item_type * -finditemtype(const char * name, const struct locale * lang) +finditemtype(const xmlChar * name, const struct locale * lang) { local_names * in = inames; variant var; diff --git a/src/common/kernel/item.h b/src/common/kernel/item.h index fe2c4ef26..6d2286967 100644 --- a/src/common/kernel/item.h +++ b/src/common/kernel/item.h @@ -73,7 +73,7 @@ typedef struct resource_type { } resource_type; extern resource_type * resourcetypes; extern const char* resourcename(const resource_type * rtype, int flags); -extern const resource_type * findresourcetype(const char * name, const struct locale * lang); +extern const resource_type * findresourcetype(const xmlChar * name, const struct locale * lang); /* resource-limits for regions */ #define RMF_SKILL 0x01 /* int, bonus on resource production skill */ @@ -135,7 +135,7 @@ typedef struct item_type { struct item_type * next; } item_type; -extern const item_type * finditemtype(const char * name, const struct locale * lang); +extern const item_type * finditemtype(const xmlChar * name, const struct locale * lang); extern void init_itemnames(void); typedef struct luxury_type { diff --git a/src/common/kernel/kernel.vcproj b/src/common/kernel/kernel.vcproj index 02f6af4a7..9a0f0058d 100644 --- a/src/common/kernel/kernel.vcproj +++ b/src/common/kernel/kernel.vcproj @@ -195,6 +195,9 @@ <File RelativePath=".\calendar.h"> </File> + <File + RelativePath=".\command.h"> + </File> <File RelativePath=".\creation.h"> </File> @@ -316,6 +319,9 @@ <File RelativePath=".\calendar.c"> </File> + <File + RelativePath=".\command.c"> + </File> <File RelativePath=".\curse.c"> </File> diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index be5c536c7..9b9dc9313 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -1535,7 +1535,7 @@ msg_unitnotfound(const struct unit * mage, struct order * ord, const struct spll parameters[P_TEMP]), itoa36(spobj->data.i)); uid = tbuf; } - return msg_message("spellunitnotfound", + return msg_message("unitnotfound_id", "unit region command id", mage, mage->region, ord, uid); } @@ -1791,34 +1791,34 @@ free_spellparameter(spellparameter *pa) } static int -addparam_string(char ** param, spllprm ** spobjp) +addparam_string(const xmlChar ** param, spllprm ** spobjp) { spllprm * spobj = *spobjp = malloc(sizeof(spllprm)); assert(param[0]); spobj->flag = 0; spobj->typ = SPP_STRING; - spobj->data.s = strdup(param[0]); + spobj->data.xs = xmlStrdup(param[0]); return 1; } static int -addparam_int(char ** param, spllprm ** spobjp) +addparam_int(const xmlChar ** param, spllprm ** spobjp) { spllprm * spobj = *spobjp = malloc(sizeof(spllprm)); assert(param[0]); spobj->flag = 0; spobj->typ = SPP_INT; - spobj->data.i = atoi(param[0]); + spobj->data.i = atoi((char*)param[0]); return 1; } static int -addparam_ship(char ** param, spllprm ** spobjp) +addparam_ship(const xmlChar ** param, spllprm ** spobjp) { spllprm * spobj = *spobjp = malloc(sizeof(spllprm)); - int id = atoi36(param[0]); + int id = atoi36((const char *)param[0]); spobj->flag = 0; spobj->typ = SPP_SHIP; @@ -1827,10 +1827,10 @@ addparam_ship(char ** param, spllprm ** spobjp) } static int -addparam_building(char ** param, spllprm ** spobjp) +addparam_building(const xmlChar ** param, spllprm ** spobjp) { spllprm * spobj = *spobjp = malloc(sizeof(spllprm)); - int id = atoi36(param[0]); + int id = atoi36((const char *)param[0]); spobj->flag = 0; spobj->typ = SPP_BUILDING; @@ -1839,7 +1839,7 @@ addparam_building(char ** param, spllprm ** spobjp) } static int -addparam_region(char ** param, spllprm ** spobjp, const unit * u, order * ord) +addparam_region(const xmlChar ** param, spllprm ** spobjp, const unit * u, order * ord) { assert(param[0]); if (param[1]==0) { @@ -1847,7 +1847,7 @@ addparam_region(char ** param, spllprm ** spobjp, const unit * u, order * ord) cmistake(u, ord, 194, MSG_MAGIC); return -1; } else { - int tx = atoi(param[0]), ty = atoi(param[1]); + int tx = atoi((const char*)param[0]), ty = atoi((const char*)param[1]); short x = rel_to_abs(0, u->faction, (short)tx, 0); short y = rel_to_abs(0, u->faction, (short)ty, 1); region *rt = findregion(x,y); @@ -1869,7 +1869,7 @@ addparam_region(char ** param, spllprm ** spobjp, const unit * u, order * ord) static int -addparam_unit(char ** param, spllprm ** spobjp, const unit * u, order * ord) +addparam_unit(const xmlChar ** param, spllprm ** spobjp, const unit * u, order * ord) { spllprm *spobj; int i = 0; @@ -1889,13 +1889,13 @@ addparam_unit(char ** param, spllprm ** spobjp, const unit * u, order * ord) spobj = *spobjp = malloc(sizeof(spllprm)); spobj->flag = 0; spobj->typ = otype; - spobj->data.i = atoi36(param[i]); + spobj->data.i = atoi36((const char*)param[i]); return i+1; } static spellparameter * -add_spellparameter(region *target_r, unit *u, const char *syntax, char ** param, int size, struct order * ord) +add_spellparameter(region *target_r, unit *u, const char *syntax, xmlChar ** param, int size, struct order * ord) { boolean fail = false; int i = 0; @@ -2443,7 +2443,7 @@ cast_cmd(unit * u, order * ord) region * target_r = r; int level, range; unit *familiar = NULL, *mage = u; - const char * s; + const xmlChar * s; spell * sp; spellparameter *args = NULL; @@ -2462,8 +2462,8 @@ cast_cmd(unit * u, order * ord) s = getstrtoken(); /* f�r Syntax ' STUFE x REGION y z ' */ if (findparam(s, u->faction->locale) == P_LEVEL) { - s = getstrtoken(); - level = min(atoip(s), level); + int p = getint(); + level = min(p, level); if (level < 1) { /* Fehler "Das macht wenig Sinn" */ cmistake(u, ord, 10, MSG_MAGIC); @@ -2472,8 +2472,8 @@ cast_cmd(unit * u, order * ord) s = getstrtoken(); } if (findparam(s, u->faction->locale) == P_REGION) { - short t_x = (short)atoi(getstrtoken()); - short t_y = (short)atoi(getstrtoken()); + short t_x = (short)getint(); + short t_y = (short)getint(); t_x = rel_to_abs(getplane(u->region),u->faction,t_x,0); t_y = rel_to_abs(getplane(u->region),u->faction,t_y,1); target_r = findregion(t_x, t_y); @@ -2488,16 +2488,16 @@ cast_cmd(unit * u, order * ord) /* f�r Syntax ' REGION x y STUFE z ' * hier nach REGION nochmal auf STUFE pr�fen */ if (findparam(s, u->faction->locale) == P_LEVEL) { - s = getstrtoken(); - level = min(atoip(s), level); - s = getstrtoken(); + int p = getint(); + level = min(p, level); if (level < 1) { /* Fehler "Das macht wenig Sinn" */ cmistake(u, ord, 10, MSG_MAGIC); return 0; } + s = getstrtoken(); } - if (!s[0] || strlen(s) == 0) { + if (!s[0] || xmlStrlen(s) == 0) { /* Fehler "Es wurde kein Zauber angegeben" */ cmistake(u, ord, 172, MSG_MAGIC); return 0; @@ -2619,7 +2619,7 @@ cast_cmd(unit * u, order * ord) } /* Weitere Argumente zusammenbasten */ if (sp->parameter) { - char ** params = malloc(2*sizeof(char*)); + xmlChar ** params = malloc(2*sizeof(char*)); int p = 0, size = 2; for (;;) { s = getstrtoken(); @@ -2628,7 +2628,7 @@ cast_cmd(unit * u, order * ord) size*=2; params = realloc(params, sizeof(char*)*size); } - params[p++] = strdup(s); + params[p++] = xmlStrdup(s); } params[p] = 0; args = add_spellparameter(target_r, mage, sp->parameter, params, p, ord); @@ -2818,13 +2818,13 @@ magic(void) remove_empty_units(); } -const char * +const xmlChar * spell_info(const spell * sp, const struct locale * lang) { return LOC(lang, mkname("spellinfo", sp->sname)); } -const char * +const xmlChar * spell_name(const spell * sp, const struct locale * lang) { return LOC(lang, mkname("spell", sp->sname)); diff --git a/src/common/kernel/magic.h b/src/common/kernel/magic.h index a5a66eb9b..215a954d4 100644 --- a/src/common/kernel/magic.h +++ b/src/common/kernel/magic.h @@ -60,6 +60,7 @@ typedef struct spllprm{ struct building *b; struct ship *sh; char *s; + xmlChar * xs; int i; } data; } spllprm; @@ -269,9 +270,6 @@ boolean is_familiar(const struct unit *u); /* gibt true, wenn eine Familiar-Relation besteht. */ /* Spr�che */ -spell *get_spellfromtoken(struct unit *u, const char *s, const struct locale * lang); - /* versucht einen Spruch �ber den Namen zu identifizieren, gibt - * ansonsten NULL zur�ck */ int get_combatspelllevel(const struct unit *u, int nr); /* versucht, eine eingestellte maximale Kampfzauberstufe * zur�ckzugeben. 0 = Maximum, -1 u ist kein Magier. */ @@ -373,8 +371,8 @@ extern boolean create_newfamiliar(struct unit * mage, struct unit * familiar); extern void create_newclone(struct unit * mage, struct unit * familiar); extern struct unit * has_clone(struct unit * mage); -extern const char * spell_info(const struct spell * sp, const struct locale * lang); -extern const char * spell_name(const struct spell * sp, const struct locale * lang); +extern const xmlChar * spell_info(const struct spell * sp, const struct locale * lang); +extern const xmlChar * spell_name(const struct spell * sp, const struct locale * lang); extern struct message * msg_unitnotfound(const struct unit * mage, struct order * ord, const struct spllprm * spobj); diff --git a/src/common/kernel/message.c b/src/common/kernel/message.c index 2909fd77d..a1d5c56ae 100644 --- a/src/common/kernel/message.c +++ b/src/common/kernel/message.c @@ -177,7 +177,7 @@ msg_message(const char * name, const char* sig, ...) } static void -caddmessage(region * r, faction * f, const char *s, msg_t mtype, int level) +caddmessage(region * r, faction * f, const xmlChar *s, msg_t mtype, int level) { message * m = NULL; @@ -230,7 +230,7 @@ caddmessage(region * r, faction * f, const char *s, msg_t mtype, int level) } void -addmessage(region * r, faction * f, const char *s, msg_t mtype, int level) +addmessage(region * r, faction * f, const xmlChar *s, msg_t mtype, int level) { caddmessage(r, f, s, mtype, level); } diff --git a/src/common/kernel/movement.c b/src/common/kernel/movement.c index b4ec71953..a563a6cfb 100644 --- a/src/common/kernel/movement.c +++ b/src/common/kernel/movement.c @@ -48,6 +48,7 @@ /* util includes */ #include <util/attrib.h> #include <util/base36.h> +#include <util/bsdstring.h> #include <util/goodies.h> #include <util/language.h> #include <util/lists.h> @@ -55,18 +56,18 @@ #include <util/rand.h> #include <util/rng.h> -/* libc includes */ -#include <assert.h> -#include <math.h> -#include <stdio.h> -#include <string.h> - /* attributes includes */ #include <attributes/follow.h> #include <attributes/targetregion.h> #include <attributes/movement.h> #include <attributes/otherfaction.h> +/* libc includes */ +#include <assert.h> +#include <math.h> +#include <stdio.h> +#include <string.h> + int * storms; typedef struct traveldir { @@ -907,18 +908,19 @@ static void cycle_route(order * ord, unit *u, int gereist) { int cm = 0; - char tail[1024]; - char neworder[2048]; - const char *token; + xmlChar tail[1024]; + xmlChar neworder[2048]; + const xmlChar *token; direction_t d = NODIRECTION; boolean paused = false; boolean pause; order * norder; + xmlChar * tail_end = tail; if (get_keyword(ord) != K_ROUTE) return; tail[0] = '\0'; - strcpy(neworder, locale_string(u->faction->locale, keywords[K_ROUTE])); + xmlStrcpy(neworder, locale_string(u->faction->locale, keywords[K_ROUTE])); init_tokens(ord); skip_token(); @@ -936,24 +938,34 @@ cycle_route(order * ord, unit *u, int gereist) if (cm<gereist) { /* hier sollte keine PAUSE auftreten */ assert(!pause); - if (!pause) strcat(strcat(tail, " "), LOC(lang, shortdirections[d])); + if (!pause) { + size_t size = sizeof(tail)-(tail_end-tail); + const xmlChar * loc = LOC(lang, shortdirections[d]); + *tail_end++ = ' '; + tail_end += strlcpy((char*)tail_end, (const char *)loc, size-1); + } } - else if (strlen(neworder)>sizeof(neworder)/2) break; + else if (xmlStrlen(neworder)>sizeof(neworder)/2) break; else if (cm == gereist && !paused && pause) { - strcat(strcat(tail, " "), LOC(lang, parameters[P_PAUSE])); - paused=true; + size_t size = sizeof(tail)-(tail_end-tail); + const xmlChar * loc = LOC(lang, parameters[P_PAUSE]); + *tail_end++ = ' '; + tail_end += strlcpy((char*)tail_end, (const char *)loc, size-1); + paused = true; } else if (pause) { /* da PAUSE nicht in ein shortdirections[d] umgesetzt wird (ist * hier keine normale direction), muss jede PAUSE einzeln * herausgefiltert und explizit gesetzt werden */ - strcat(strcat(neworder, " "), LOC(lang, parameters[P_PAUSE])); + strcat((char *)neworder, " "); + strcat((char *)neworder, (const char *)LOC(lang, parameters[P_PAUSE])); } else { - strcat(strcat(neworder, " "), LOC(lang, shortdirections[d])); + strcat((char *)neworder, " "); + strcat((char *)neworder, (const char *)LOC(lang, shortdirections[d])); } } - strcat(neworder, tail); + strcat((char *)neworder, (const char *)tail); norder = parse_order(neworder, u->faction->locale); #ifdef LASTORDER set_order(&u->lastorder, norder); @@ -1217,7 +1229,7 @@ make_route(unit * u, order * ord, region_list ** routep) region_list **iroute = routep; region * current = u->region; region * next = NULL; - const char * token = getstrtoken(); + const xmlChar * token = getstrtoken(); int error = movewhere(u, token, current, &next); if (error!=E_MOVE_OK) { @@ -1472,8 +1484,7 @@ travel_route(unit * u, region_list * route_begin, region_list * route_end, order if (iroute!=route_begin) { /* the unit has moved at least one region */ int walkmode; - region_list *rlist = route_begin; - char * p = buf; + region_list **rlist = &route_begin; region * next = r; setguard(u, GUARD_NONE); @@ -1490,23 +1501,22 @@ travel_route(unit * u, region_list * route_begin, region_list * route_end, order /* Berichte �ber Durchreiseregionen */ - *p = 0; - while (rlist!=iroute) { + while (*rlist!=iroute) { if (next!=u->region && next!=current) { MSG(("travelthru_trail", "region", next), p, sizeof(buf) - (p-buf), u->faction->locale, u->faction); - if (rlist->data!=current) { - if (rlist->next->data == current) scat(" und "); - else scat(", "); - } - p += strlen(p); } next = rlist->data; rlist = rlist->next; } + /* remove excess regions */ + *rlist = NULL; + free_regionlist(iroute); + iroute = NULL; + if (mode!=TRAVEL_TRANSPORTED) { ADDMSG(&u->faction->msgs, msg_message("travel", - "unit mode start end regions", u, walkmode, r, current, buf)); + "unit mode start end regions", u, walkmode, r, current, route_begin)); } mark_travelthru(u, r, route_begin, iroute); @@ -1621,7 +1631,7 @@ sail(unit * u, order * ord, boolean move_on_land, region_list **routep) faction * f = u->faction; region * next_point = NULL; int error; - const char * token = getstrtoken(); + const xmlChar * token = getstrtoken(); if (routep) *routep = NULL; @@ -1653,7 +1663,7 @@ sail(unit * u, order * ord, boolean move_on_land, region_list **routep) * befahrene Region. */ while (next_point && current_point!=next_point && step < k) { - const char * token; + const xmlChar * token; int error; const terrain_type * tthis = current_point->terrain; /* these values need to be updated if next_point changes (due to storms): */ @@ -2327,7 +2337,7 @@ hunt(unit *u, order * ord) locale_string(u->faction->locale, directions[dir])); moves = 1; - speed = geti(); + speed = getuint(); if (speed==0) { speed = shipspeed(u->ship, u); } else { diff --git a/src/common/kernel/names.c b/src/common/kernel/names.c index 6dc33d3ec..c5a1593a9 100644 --- a/src/common/kernel/names.c +++ b/src/common/kernel/names.c @@ -47,7 +47,7 @@ #define UNTOT_VOR 23 -static const char *untot_vor[UNTOT_VOR] = +static const xmlChar *untot_vor[UNTOT_VOR] = { "Grausige ", "St�hnende ", @@ -76,7 +76,7 @@ static const char *untot_vor[UNTOT_VOR] = #define UNTOT 13 -static const char *untot[UNTOT] = +static const xmlChar *untot[UNTOT] = { "Geister", "Phantome", @@ -95,7 +95,7 @@ static const char *untot[UNTOT] = #define UNTOT_NACH 14 -static const char *untot_nach[UNTOT_NACH] = +static const xmlChar *untot_nach[UNTOT_NACH] = { " der Nacht", " der Schatten", @@ -113,7 +113,7 @@ static const char *untot_nach[UNTOT_NACH] = " aus der Unterwelt" }; -static const char * +const xmlChar * describe_braineater(unit * u, const struct locale * lang) { return LOC(lang, "describe_braineater"); @@ -151,7 +151,7 @@ untoten_name(const unit * u) #define SKEL_VOR 19 -static const char *skel_vor[SKEL_VOR] = +static const xmlChar *skel_vor[SKEL_VOR] = { "Klapperige ", "St�hnende ", @@ -176,7 +176,7 @@ static const char *skel_vor[SKEL_VOR] = #define SKEL 5 -static const char *skel[SKEL] = +static const xmlChar *skel[SKEL] = { "Skelette", "Kreaturen", @@ -187,7 +187,7 @@ static const char *skel[SKEL] = #define SKEL_NACH 14 -static const char *skel_nach[SKEL_NACH] = +static const xmlChar *skel_nach[SKEL_NACH] = { " der Nacht", " der Schatten", @@ -205,7 +205,7 @@ static const char *skel_nach[SKEL_NACH] = " aus der Unterwelt" }; -const char * +const xmlChar * skeleton_name(const unit * u) { int uv, uu, un; @@ -238,7 +238,7 @@ skeleton_name(const unit * u) #define ZOM_VOR 16 -static const char *zombie_vor[ZOM_VOR] = +static const xmlChar *zombie_vor[ZOM_VOR] = { "Faulende ", "Zerschlagene ", @@ -260,7 +260,7 @@ static const char *zombie_vor[ZOM_VOR] = #define ZOM 5 -static const char *zombie[ZOM] = +static const xmlChar *zombie[ZOM] = { "Zombies", "Kreaturen", @@ -271,7 +271,7 @@ static const char *zombie[ZOM] = #define ZOM_NACH 13 -static const char *zombie_nach[ZOM_NACH] = +static const xmlChar *zombie_nach[ZOM_NACH] = { " der Nacht", " der Schatten", @@ -288,7 +288,7 @@ static const char *zombie_nach[ZOM_NACH] = " aus der Unterwelt" }; -const char * +const xmlChar * zombie_name(const unit * u) { int uv, uu, un; @@ -321,7 +321,7 @@ zombie_name(const unit * u) #define GHOUL_VOR 17 -static const char *ghoul_vor[GHOUL_VOR] = +static const xmlChar *ghoul_vor[GHOUL_VOR] = { "Faulende ", "Angsteinfl��ende ", @@ -344,7 +344,7 @@ static const char *ghoul_vor[GHOUL_VOR] = #define GHOUL 6 -static const char *ghoul[GHOUL] = +static const xmlChar *ghoul[GHOUL] = { "Ghoule", "Kreaturen", @@ -356,7 +356,7 @@ static const char *ghoul[GHOUL] = #define GHOUL_NACH 13 -static const char *ghoul_nach[GHOUL_NACH] = +static const xmlChar *ghoul_nach[GHOUL_NACH] = { " der Nacht", " der Schatten", @@ -373,7 +373,7 @@ static const char *ghoul_nach[GHOUL_NACH] = " aus der Unterwelt" }; -const char * +const xmlChar * ghoul_name(const unit * u) { int uv, uu, un; @@ -407,7 +407,7 @@ ghoul_name(const unit * u) #define SIL1 15 -const char *silbe1[SIL1] = { +const xmlChar *silbe1[SIL1] = { "Tar", "Ter", "Tor", @@ -427,7 +427,7 @@ const char *silbe1[SIL1] = { #define SIL2 19 -const char *silbe2[SIL2] = { +const xmlChar *silbe2[SIL2] = { "da", "do", "dil", @@ -451,7 +451,7 @@ const char *silbe2[SIL2] = { #define SIL3 14 -const char *silbe3[SIL3] = { +const xmlChar *silbe3[SIL3] = { "gul", "gol", "dol", @@ -470,7 +470,7 @@ const char *silbe3[SIL3] = { #define DTITEL 5 -const char *dtitel[6][DTITEL] = +const xmlChar *dtitel[6][DTITEL] = { { /* Ebene, Hochland */ "der Weise", @@ -516,21 +516,21 @@ const char *dtitel[6][DTITEL] = } }; -const char * -shadow_name(const unit *u) +const xmlChar * +generic_name(const unit *u) { - if(u->no == 1) { - return "Schattend�mon"; - } - return "Schattend�monen"; + if (u->no == 1) { + return LOC(u->faction->locale, u->race->_name[0]); + } + return LOC(u->faction->locale, u->race->_name[1]); } -const char * +const xmlChar * drachen_name(const unit *u) { static char name[NAMESIZE + 1]; int rnd = rng_int() % DTITEL; - const char *t = dtitel[0][rnd]; + const xmlChar *t = dtitel[0][rnd]; int anzahl = 1; if (u) { @@ -583,7 +583,7 @@ drachen_name(const unit *u) /* Dracoide */ #define DRAC_PRE 13 -static const char *drac_pre[DRAC_PRE] = { +static const xmlChar *drac_pre[DRAC_PRE] = { "Siss", "Xxaa", "Shht", @@ -600,7 +600,7 @@ static const char *drac_pre[DRAC_PRE] = { }; #define DRAC_MID 12 -static const char *drac_mid[DRAC_MID] = { +static const xmlChar *drac_mid[DRAC_MID] = { "siss", "xxaa", "shht", @@ -616,7 +616,7 @@ static const char *drac_mid[DRAC_MID] = { }; #define DRAC_SUF 10 -static const char *drac_suf[DRAC_SUF] = { +static const xmlChar *drac_suf[DRAC_SUF] = { "xil", "shh", "s", @@ -629,7 +629,7 @@ static const char *drac_suf[DRAC_SUF] = { "k" }; -const char * +const xmlChar * dracoid_name(const unit *u) { static char name[NAMESIZE + 1]; @@ -650,11 +650,11 @@ dracoid_name(const unit *u) return name; } -const char * -abkz(const char *s, size_t max) +const xmlChar * +abkz(const xmlChar *s, size_t max) { static char buf[32]; - const char *p = s; + const xmlChar *p = s; unsigned int c = 0; size_t bpt, i; @@ -662,7 +662,7 @@ abkz(const char *s, size_t max) /* Pr�fen, ob Kurz genug */ - if (strlen(s) <= max) { + if (xmlStrlen(s) <= max) { return s; } /* Anzahl der W�rter feststellen */ @@ -728,7 +728,7 @@ register_names(void) register_function((pf_generic)ghoul_name, "nameghoul"); register_function((pf_generic)drachen_name, "namedragon"); register_function((pf_generic)dracoid_name, "namedracoid"); - register_function((pf_generic)shadow_name, "nameshadow"); + register_function((pf_generic)generic_name, "namegeneric"); } diff --git a/src/common/kernel/names.h b/src/common/kernel/names.h index 4ff7af503..cb2daf475 100644 --- a/src/common/kernel/names.h +++ b/src/common/kernel/names.h @@ -19,14 +19,14 @@ extern "C" { #endif extern void register_names(void); -const char *untoten_name(const struct unit * u); -const char *skeleton_name(const struct unit * u); -const char *zombie_name(const struct unit * u); -const char *ghoul_name(const struct unit * u); -const char *drachen_name(const struct unit *u); -const char *dracoid_name(const struct unit *u); -const char *shadow_name(const struct unit *u); -const char *abkz(const char *s, size_t max); +const xmlChar *untoten_name(const struct unit * u); +const xmlChar *skeleton_name(const struct unit * u); +const xmlChar *zombie_name(const struct unit * u); +const xmlChar *ghoul_name(const struct unit * u); +const xmlChar *drachen_name(const struct unit *u); +const xmlChar *dracoid_name(const struct unit *u); +const xmlChar *generic_name(const struct unit *u); +const xmlChar *abkz(const xmlChar *s, size_t max); #ifdef __cplusplus } diff --git a/src/common/kernel/order.c b/src/common/kernel/order.c index 35e865de6..63faa87e1 100644 --- a/src/common/kernel/order.c +++ b/src/common/kernel/order.c @@ -16,6 +16,7 @@ #include "skill.h" +#include <util/base36.h> #include <util/bsdstring.h> #include <util/language.h> #include <util/parser.h> @@ -26,40 +27,27 @@ #include <stdlib.h> #include <string.h> -#define SHORT_STRINGS - -#ifdef SHARE_ORDERS # define ORD_KEYWORD(ord) (ord)->data->_keyword # define ORD_LOCALE(ord) locale_array[(ord)->data->_lindex]->lang # define ORD_STRING(ord) (ord)->data->_str -#else -# define ORD_KEYWORD(ord) (ord)->data._keyword -# define ORD_LOCALE(ord) locale_array[ord->data._lindex]->lang -# define ORD_STRING(ord) (ord)->data._str -#endif typedef struct locale_data { -#ifdef SHARE_ORDERS struct order_data * short_orders[MAXKEYWORDS]; struct order_data * study_orders[MAXSKILLS]; -#endif const struct locale * lang; } locale_data; static struct locale_data * locale_array[16]; static int nlocales = 0; -#ifdef SHARE_ORDERS typedef struct order_data { - char * _str; + xmlChar * _str; int _refcount : 20; int _lindex : 4; keyword_t _keyword; } order_data; -#endif -#ifdef SHARE_ORDERS static void release_data(order_data * data) { @@ -70,7 +58,6 @@ release_data(order_data * data) } } } -#endif void replace_order(order ** dlist, order * orig, const order * src) @@ -97,38 +84,34 @@ get_keyword(const order * ord) return ORD_KEYWORD(ord); } -static char * -get_command(const order * ord, char * sbuffer, size_t bufsize) +static xmlChar * +get_command(const order * ord, xmlChar * sbuffer, size_t bufsize) { - char * str = sbuffer; - const char * text = ORD_STRING(ord); -#ifdef SHORT_STRINGS + xmlChar * str = sbuffer; + const xmlChar * text = ORD_STRING(ord); keyword_t kwd = ORD_KEYWORD(ord); -#endif if (ord->_persistent) *str++ = '@'; -#ifdef SHORT_STRINGS if (kwd!=NOKEYWORD) { const struct locale * lang = ORD_LOCALE(ord); size_t size = bufsize-(str-sbuffer); if (text) --size; - str += strlcpy(str, LOC(lang, keywords[kwd]), size); + str += strlcpy((char*)str, (const char*)LOC(lang, keywords[kwd]), size); if (text) { *str++ = ' '; } } -#endif if (text) { - str += strlcpy(str, text, bufsize-(str-sbuffer)); + str += strlcpy((char*)str, (const char *)text, bufsize-(str-sbuffer)); } return sbuffer; } -char * +xmlChar * getcommand(const order * ord) { - char sbuffer[DISPLAYSIZE*2]; - return strdup(get_command(ord, sbuffer, sizeof(sbuffer))); + xmlChar sbuffer[DISPLAYSIZE*2]; + return xmlStrdup(get_command(ord, sbuffer, sizeof(sbuffer))); } void @@ -137,11 +120,7 @@ free_order(order * ord) if (ord!=NULL) { assert(ord->next==0); -#ifdef SHARE_ORDERS release_data(ord->data); -#else - if (ord->data._str) free(ord->data._str); -#endif free(ord); } } @@ -154,9 +133,7 @@ copy_order(const order * src) ord->next = NULL; ord->_persistent = src->_persistent; ord->data = src->data; -#ifdef SHARE_ORDERS ++ord->data->_refcount; -#endif return ord; } return NULL; @@ -181,13 +158,15 @@ free_orders(order ** olist) } } -#ifdef SHARE_ORDERS static order_data * -create_data(keyword_t kwd, const char * s, const char * sptr, int lindex) +create_data(keyword_t kwd, const xmlChar * sptr, int lindex) { + const xmlChar * s = sptr; order_data * data; const struct locale * lang = locale_array[lindex]->lang; + if (kwd!=NOKEYWORD) s = (*sptr)?sptr:NULL; + /* learning, only one order_data per skill required */ if (kwd==K_STUDY) { skill_t sk = findskill(parse_token(&sptr), lang); @@ -199,26 +178,21 @@ create_data(keyword_t kwd, const char * s, const char * sptr, int lindex) default: /* nur skill als Parameter, keine extras */ data = locale_array[lindex]->study_orders[sk]; if (data==NULL) { - const char * skname = skillname(sk, lang); + const xmlChar * skname = skillname(sk, lang); data = (order_data*)malloc(sizeof(order_data)); locale_array[lindex]->study_orders[sk] = data; data->_keyword = kwd; data->_lindex = lindex; -#ifdef SHORT_STRINGS - if (strchr(skname, ' ')!=NULL) { - sprintf(buf, "\"%s\"", skname); - data->_str = strdup(buf); + if (xmlStrchr(skname, ' ')!=NULL) { + size_t len = xmlStrlen(skname); + data->_str = (xmlChar*)malloc(len+3); + data->_str[0]='\"'; + memcpy(data->_str+1, skname, len); + data->_str[len+1]='\"'; + data->_str[len+2]='\0'; } else { - data->_str = strdup(skname); + data->_str = xmlStrdup(skname); } -#else - if (strchr(skname, ' ')!=NULL) { - sprintf(buf, "%s \"%s\"", LOC(lang, keywords[kwd]), skname); - } else { - sprintf(buf, "%s %s", LOC(lang, keywords[kwd]), skname); - } - data->_str = strdup(buf); -#endif data->_refcount = 1; } ++data->_refcount; @@ -234,11 +208,7 @@ create_data(keyword_t kwd, const char * s, const char * sptr, int lindex) locale_array[lindex]->short_orders[kwd] = data; data->_keyword = kwd; data->_lindex = lindex; -#ifdef SHORT_STRINGS data->_str = NULL; -#else - data->_str = strdup(LOC(lang, keywords[kwd])); -#endif data->_refcount = 1; } ++data->_refcount; @@ -247,23 +217,88 @@ create_data(keyword_t kwd, const char * s, const char * sptr, int lindex) data = (order_data*)malloc(sizeof(order_data)); data->_keyword = kwd; data->_lindex = lindex; - data->_str = s?strdup(s):NULL; + data->_str = s?xmlStrdup(s):NULL; data->_refcount = 1; return data; } -#endif + +static order * +create_order_i(keyword_t kwd, const xmlChar * sptr, int persistent, const struct locale * lang) +{ + order * ord = NULL; + int lindex; + + /* if this is just nonsense, then we skip it. */ + if (lomem) { + switch (kwd) { + case K_KOMMENTAR: + case NOKEYWORD: + return NULL; + case K_LIEFERE: + kwd = K_GIVE; + persistent = 1; + break; + default: + break; + } + } + + for (lindex=0;lindex!=nlocales;++lindex) { + if (locale_array[lindex]->lang==lang) break; + } + if (lindex==nlocales) { + locale_array[nlocales] = (locale_data*)calloc(1, sizeof(locale_data)); + locale_array[nlocales]->lang = lang; + ++nlocales; + } + + ord = (order*)malloc(sizeof(order)); + ord->_persistent = persistent; + ord->next = NULL; + + ord->data = create_data(kwd, sptr, lindex); + + return ord; +} + +order * +create_order(keyword_t kwd, const struct locale * lang, const char * params, ...) +{ + va_list marker; + char zBuffer[DISPLAYSIZE]; + char * sptr = zBuffer; + + va_start(marker, params); + while (params) { + switch (*params) { + case '%': + case ' ': + /* ignore these, they are syntactical sugar */ + break; + case 's': + sptr += strlcpy(sptr, va_arg(marker, const char *), sizeof(zBuffer)-(sptr-zBuffer)); + break; + case 'd': + sptr += strlcpy(sptr, itoa10(va_arg(marker, int)), sizeof(zBuffer)-(sptr-zBuffer)); + break; + case 'i': + sptr += strlcpy(sptr, itoa36(va_arg(marker, int)), sizeof(zBuffer)-(sptr-zBuffer)); + break; + } + } + va_end(marker); + + return create_order_i(kwd, (const xmlChar*)sptr, 0, lang); +} order * -parse_order(const char * s, const struct locale * lang) +parse_order(const xmlChar * s, const struct locale * lang) { while (*s && !isalnum(*(unsigned char*)s) && !ispunct(*(unsigned char*)s)) ++s; - if (*s==0) return NULL; - else { + if (*s!=0) { keyword_t kwd; - const char * sptr; - order * ord = NULL; + const xmlChar * sptr; int persistent = 0; - int lindex; while (*s=='@') { persistent = 1; @@ -271,51 +306,13 @@ parse_order(const char * s, const struct locale * lang) } sptr = s; kwd = findkeyword(parse_token(&sptr), lang); - while (isspace(*(unsigned char*)sptr)) ++sptr; - - /* if this is just nonsense, then we skip it. */ - if (lomem) { - switch (kwd) { - case K_KOMMENTAR: - case NOKEYWORD: - return NULL; -#ifdef SHORT_STRINGS - case K_LIEFERE: - kwd = K_GIVE; - persistent = 1; - break; -#endif - default: - break; - } + if (kwd!=NOKEYWORD) { + while (isspace(*(unsigned char*)sptr)) ++sptr; + s = sptr; } - - for (lindex=0;lindex!=nlocales;++lindex) { - if (locale_array[lindex]->lang==lang) break; - } - if (lindex==nlocales) { - locale_array[nlocales] = (locale_data*)calloc(1, sizeof(locale_data)); - locale_array[nlocales]->lang = lang; - ++nlocales; - } - - ord = (order*)malloc(sizeof(order)); - ord->_persistent = persistent; - ord->next = NULL; - -#ifdef SHORT_STRINGS - if (kwd!=NOKEYWORD) s = (*sptr)?sptr:NULL; -#endif -#ifdef SHARE_ORDERS - ord->data = create_data(kwd, s, sptr, lindex); -#else - ord->data._keyword = kwd; - ord->data._lindex = lindex; - ord->data._str = s?strdup(s):NULL; -#endif - - return ord; + return create_order_i(kwd, s, persistent, lang); } + return NULL; } boolean @@ -456,16 +453,16 @@ is_persistent(const order * ord) return persist || is_repeated(ord); } -char * -write_order(const order * ord, const struct locale * lang, char * buffer, size_t size) +xmlChar * +write_order(const order * ord, const struct locale * lang, xmlChar * buffer, size_t size) { if (ord==0) { buffer[0]=0; } else { keyword_t kwd = ORD_KEYWORD(ord); if (kwd==NOKEYWORD) { - const char * text = ORD_STRING(ord); - strlcpy(buffer, text, size); + const xmlChar * text = ORD_STRING(ord); + strlcpy((char *)buffer, (const char *)text, size); } else { get_command(ord, buffer, size); } diff --git a/src/common/kernel/order.h b/src/common/kernel/order.h index fd3d1fcc1..02d56adb3 100644 --- a/src/common/kernel/order.h +++ b/src/common/kernel/order.h @@ -25,9 +25,6 @@ extern "C" { * implemented yet) saving approx. 50% of all string-related memory. */ -#define SHARE_ORDERS - -#ifdef SHARE_ORDERS struct order_data; typedef struct order { @@ -36,23 +33,9 @@ typedef struct order { struct order_data * data; int _persistent : 1; } order; -#else -typedef struct order_data { - char * _str; - int _lindex : 8; - keyword_t _keyword; -} order_data; - -typedef struct order { - struct order * next; - /* do not access this data: */ - struct order_data data; - int _persistent : 1; -} order; -#endif /* constructor */ -extern order * parse_order(const char * s, const struct locale * lang); +extern order * parse_order(const xmlChar * s, const struct locale * lang); extern void replace_order(order ** dst, order * orig, const order * src); /* reference counted copies of orders: */ @@ -63,12 +46,12 @@ extern void free_orders(order ** olist); /* access functions for orders */ extern keyword_t get_keyword(const order * ord); extern void set_order(order ** destp, order * src); -extern char * getcommand(const order * ord); +extern xmlChar * getcommand(const order * ord); extern boolean is_persistent(const order *ord); extern boolean is_exclusive(const order *ord); extern boolean is_repeated(const order * ord); -extern char * write_order(const order * ord, const struct locale * lang, char * buffer, size_t size); +extern xmlChar * write_order(const order * ord, const struct locale * lang, xmlChar * buffer, size_t size); #ifdef __cplusplus diff --git a/src/common/kernel/pool.c b/src/common/kernel/pool.c index 60b4a8bf8..e20c6aec6 100644 --- a/src/common/kernel/pool.c +++ b/src/common/kernel/pool.c @@ -270,16 +270,15 @@ reserve_cmd(unit * u, struct order *ord) if (u->number > 0 && (urace(u)->ec_flags & GETITEM)) { int use, count; const resource_type * rtype; - const char * s; + const xmlChar * s; init_tokens(ord); skip_token(); s = getstrtoken(); - count = atoip(s); + count = atoip((const char *)s); if (count == 0 && findparam(s, u->faction->locale)==P_EACH) { - s = getstrtoken(); - count = atoip(s) * u->number; + count = getint() * u->number; } rtype = findresourcetype(getstrtoken(), u->faction->locale); diff --git a/src/common/kernel/race.c b/src/common/kernel/race.c index b4a609437..d9b1b6bcc 100644 --- a/src/common/kernel/race.c +++ b/src/common/kernel/race.c @@ -284,7 +284,7 @@ raceprefix(const unit *u) return get_prefix(asource); } -const char * +const xmlChar * racename(const struct locale *loc, const unit *u, const race * rc) { const char * prefix = raceprefix(u); diff --git a/src/common/kernel/race.h b/src/common/kernel/race.h index 792fdcf9a..37e85cd90 100644 --- a/src/common/kernel/race.h +++ b/src/common/kernel/race.h @@ -78,8 +78,8 @@ typedef struct race { int ec_flags; race_t oldfamiliars[MAXMAGIETYP]; - const char *(*generate_name) (const struct unit *); - const char *(*describe) (const struct unit *, const struct locale *); + const xmlChar *(*generate_name) (const struct unit *); + const xmlChar *(*describe) (const struct unit *, const struct locale *); void (*age)(struct unit *u); boolean (*move_allowed)(const struct region *, const struct region *); struct item * (*itemdrop)(const struct race *, int size); @@ -155,7 +155,7 @@ extern int rc_specialdamage(const race *, const race *, const struct weapon_type #define BF_CANATTACK (1<<6) /* Kann keine ATTACKIERE Befehle ausfuehren */ extern int unit_old_max_hp(struct unit * u); -extern const char * racename(const struct locale *lang, const struct unit *u, const race * rc); +extern const xmlChar * racename(const struct locale *lang, const struct unit *u, const race * rc); #define omniscient(f) (((f)->race)==new_race[RC_ILLUSION] || ((f)->race)==new_race[RC_TEMPLATE]) diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c index 1dab44237..183e31d8c 100644 --- a/src/common/kernel/region.c +++ b/src/common/kernel/region.c @@ -100,7 +100,8 @@ dir_invert(direction_t dir) assert(!"illegal direction"); return NODIRECTION; } -const char * + +const xmlChar * regionname(const region * r, const faction * f) { static char buf[65]; @@ -729,7 +730,6 @@ new_region(short x, short y) r->y = y; r->age = 1; r->planep = findplane(x, y); - set_string(&r->display, ""); rhash(r); if (last) addlist(&last, r); @@ -1074,18 +1074,21 @@ r_getmessages(const struct region * r, const struct faction * viewer) struct message * r_addmessage(struct region * r, const struct faction * viewer, struct message * msg) { - struct individual_message * imsg; assert(r); - imsg = r->individual_messages; - while (imsg && imsg->viewer!=viewer) imsg = imsg->next; - if (imsg==NULL) { - imsg = malloc(sizeof(struct individual_message)); - imsg->next = r->individual_messages; - imsg->msgs = NULL; - r->individual_messages = imsg; - imsg->viewer = viewer; + if (viewer) { + struct individual_message * imsg; + imsg = r->individual_messages; + while (imsg && imsg->viewer!=viewer) imsg = imsg->next; + if (imsg==NULL) { + imsg = malloc(sizeof(struct individual_message)); + imsg->next = r->individual_messages; + imsg->msgs = NULL; + r->individual_messages = imsg; + imsg->viewer = viewer; + } + return add_message(&imsg->msgs, msg); } - return add_message(&imsg->msgs, msg); + return add_message(&r->msgs, msg); } struct faction * diff --git a/src/common/kernel/region.h b/src/common/kernel/region.h index 38c5fc47b..68fe4df52 100644 --- a/src/common/kernel/region.h +++ b/src/common/kernel/region.h @@ -97,7 +97,7 @@ typedef struct region { and lastregion */ short x, y; struct plane *planep; - char *display; + xmlChar *display; unsigned int flags; unsigned short age; struct message_list *msgs; @@ -131,8 +131,8 @@ typedef struct spec_direction { short x, y; int duration; boolean active; - char *desc; - char *keyword; + xmlChar *desc; + xmlChar *keyword; } spec_direction; typedef struct { @@ -217,7 +217,7 @@ extern const char * rname(const struct region * r, const struct locale * lang); extern void r_setdemand(struct region * r, const struct luxury_type * ltype, int value); extern int r_demand(const struct region * r, const struct luxury_type * ltype); -extern const char * regionname(const struct region * r, const struct faction * f); +extern const xmlChar * regionname(const struct region * r, const struct faction * f); extern void * resolve_region(variant data); extern struct region * new_region(short x, short y); extern void terraform(struct region * r, terrain_t terrain); diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c index e3444492b..3304fbdff 100644 --- a/src/common/kernel/reports.c +++ b/src/common/kernel/reports.c @@ -231,7 +231,7 @@ buforder(char * bufp, size_t size, const order * ord, int mode) } int -bufunit(const faction * f, const unit * u, int indent, int mode) +bufunit(const faction * f, const unit * u, int indent, int mode, char * buf, size_t size) { int i, dh; int getarnt = fval(u, UFL_PARTEITARNUNG); @@ -247,7 +247,7 @@ bufunit(const faction * f, const unit * u, int indent, int mode) boolean itemcloak = false; static const curse_type * itemcloak_ct = 0; static boolean init = false; - size_t size = sizeof(buf), rsize; + size_t rsize; if (!init) { init = true; @@ -1319,9 +1319,10 @@ write_reports(faction * f, time_t ltime) } if (errno) { + char zText[64]; puts(" ERROR"); - sprintf(buf, "Waiting %u seconds before retry", backup); - perror(buf); + sprintf(zText, "Waiting %u seconds before retry", backup); + perror(zText); sleep(backup); if (backup<maxbackup) { backup *= 2; @@ -1387,6 +1388,7 @@ static void write_script(FILE * F, const faction * f) { report_type * rtype; + char buf[1024]; fprintf(F, "faction=%s:email=%s", factionid(f), f->email); if (f->options & (1<<O_BZIP2)) fputs(":compression=bz2", F); @@ -1446,15 +1448,16 @@ reports(void) time_t ltime = time(NULL); const char * str; int retval = 0; + char path[MAX_PATH]; nmr_warnings(); report_donations(); remove_empty_units(); - sprintf(buf, "%s/reports.txt", reportpath()); - mailit = fopen(buf, "w"); + sprintf(path, "%s/reports.txt", reportpath()); + mailit = fopen(path, "w"); if (mailit == NULL) { - log_error(("%s konnte nicht ge�ffnet werden!\n", buf)); + log_error(("%s konnte nicht ge�ffnet werden!\n", path)); } for (f = factions; f; f = f->next) { @@ -1467,8 +1470,8 @@ reports(void) str = get_param(global.parameters, "globalreport"); #ifdef GLOBAL_REPORT if (str!=NULL) { - sprintf(buf, "%s/%s.%u.cr", reportpath(), str, turn); - global_report(buf); + sprintf(path, "%s/%s.%u.cr", reportpath(), str, turn); + global_report(path); } #endif return retval; @@ -1529,6 +1532,37 @@ var_free_resources(variant x) } } +static variant +var_copy_regions(variant x) +{ + region_list * rsrc; + size_t size = 0; + + for (rsrc = (region_list*)x.v; rsrc!=NULL; rsrc=rsrc->next) { + ++size; + } + + if (size>0) { + arg_regions * dst = (arg_regions *)malloc(sizeof(arg_regions) + sizeof(region*) * size); + dst->nregions = size; + dst->regions = (region**)(dst+1); + size = 0; + for (rsrc = (region_list*)x.v; rsrc!=NULL; rsrc=rsrc->next) { + dst->regions[size++] = rsrc->data; + } + x.v = dst; + } else { + x.v = NULL; + } + return x; +} + +static void +var_free_regions(variant x) +{ + free(x.v); +} + void reports_init(void) { @@ -1549,6 +1583,7 @@ reports_init(void) register_argtype("order", var_free_order, var_copy_order, VAR_VOIDPTR); register_argtype("resources", var_free_resources, NULL, VAR_VOIDPTR); register_argtype("items", var_free_resources, var_copy_items, VAR_VOIDPTR); + register_argtype("regions", var_free_regions, var_copy_regions, VAR_VOIDPTR); /* register alternative visibility functions */ register_function((pf_generic)view_neighbours, "view_neighbours"); diff --git a/src/common/kernel/reports.h b/src/common/kernel/reports.h index f0cd9e044..5182397e4 100644 --- a/src/common/kernel/reports.h +++ b/src/common/kernel/reports.h @@ -99,7 +99,7 @@ extern void register_reporttype(const char * extension, report_fun write, int fl extern void report_item(const struct unit * owner, const struct item * i, const struct faction * viewer, const char ** name, const char ** basename, int * number, boolean singular); extern void report_building(FILE *F, const struct region * r, const struct building * b, const struct faction * f, int mode); -extern int bufunit(const struct faction * f, const struct unit * u, int indent, int mode); +extern int bufunit(const struct faction * f, const struct unit * u, int indent, int mode, char * buf, size_t size); extern const char * reportpath(void); extern const char * trailinto(const struct region * r, const struct locale * lang); @@ -112,6 +112,12 @@ extern const char * report_kampfstatus(const struct unit * u, const struct local extern struct message * msg_curse(const struct curse * c, const void * obj, typ_t typ, int slef); + typedef struct arg_regions { + int nregions; + struct region ** regions; + } arg_regions; + + #ifdef __cplusplus } #endif diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index 6a2f7749d..edf677c67 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -57,6 +57,7 @@ #include <util/base36.h> #include <util/bsdstring.h> #include <util/event.h> +#include <util/filereader.h> #include <util/goodies.h> #include <util/lists.h> #include <util/parser.h> @@ -66,6 +67,8 @@ #include <util/rng.h> #include <util/umlaut.h> +#include <libxml/encoding.h> + /* libc includes */ #include <string.h> #include <stdio.h> @@ -328,6 +331,8 @@ rs(FILE * F, char *s) *s = 0; } +#define rss(F, buf, size) rs(F, buf) /* should check size but doesn't */ + static int ri(FILE * F) { @@ -355,12 +360,14 @@ ri(FILE * F) static int ri36(FILE * F) { - char buf[64]; + char buf[10]; int i = 0; rc(F); while (!isalnum(nextc)) rc(F); while (isalnum(nextc)) { - buf[i++]=(char)nextc; + if (i+1<sizeof(buf)) { + buf[i++]=(char)nextc; + } rc(F); } buf[i]=0; @@ -368,92 +375,6 @@ ri36(FILE * F) return i; } -#define MAXLINE 4096*16 -static char lbuf[MAXLINE]; -static char * -getbuf(FILE * F) -{ - boolean cont = false; - boolean quote = false; - boolean comment = false; - char * cp = buf; - - lbuf[MAXLINE-1] = '@'; - - do { - boolean eatwhite = true; - boolean start = true; - unsigned char * end; - unsigned char * bp = (unsigned char * )fgets(lbuf, MAXLINE, F); - - comment = (boolean)(comment && cont); - - if (!bp) return NULL; - - end = bp + strlen((const char *)bp); - if (*(end-1)=='\n') *(--end) = 0; - else { - /* wenn die zeile l�nger als erlaubt war, ist sie ung�ltig, - * und wird mit dem rest weggeworfen: */ - for (;;) { - bp = (unsigned char *)fgets(lbuf, MAXLINE, F); - if (bp==NULL) break; - end = bp + strlen((const char *)bp); - if (*(end-1)=='\n') break; - lbuf[MAXLINE-1] = 0; - } - comment = false; - bp = NULL; - } - cont = false; - while (bp!=NULL && *bp && cp!=buf+MAXLINE && (char*)bp!=lbuf+MAXLINE) { - if (isspace(*bp)) { - if (cont) ++bp; /* removes spaces and \r afer a backslash */ - else if (eatwhite) { - do { ++bp; } while ((char*)bp!=lbuf+MAXLINE && isspace(*bp)); - if (!quote && !start && !comment) *(cp++)=' '; - } - else { - if (!comment) *(cp++)=*(bp++); - while (cp!=buf+MAXLINE && (char*)bp!=lbuf+MAXLINE && isspace(*bp)) { - if (!comment) *(cp++)=*bp; - ++bp; - } - if (*bp==0) --cp; - } - } - else if (iscntrl(*bp)) { - *(cp++) = '?'; - ++bp; - } else { - cont = false; - if (*bp==COMMENT_CHAR && !quote) { - comment=true; - } - else { - if (*bp=='"') { - quote = (boolean)!quote; - *cp++ = *bp; - eatwhite=true; - } - else if (*bp=='\\') cont=true; - else { - if (!comment) *(cp++) = *bp; - eatwhite = (boolean)!quote; - } - } - ++bp; - } - start = false; - } - if (cp==buf+MAXLINE) { - --cp; - } - *cp=0; - } while (cont || cp==buf); - return buf; -} - #ifdef ENEMIES static void read_enemies(FILE * F, faction * f) @@ -485,7 +406,7 @@ write_enemies(FILE * F, const faction_list * flist) #endif static unit * -unitorders(FILE * F, struct faction * f) +unitorders(FILE * F, int enc, struct faction * f) { int i; unit *u; @@ -527,14 +448,15 @@ unitorders(FILE * F, struct faction * f) ordp = &u->orders; for (;;) { - const char * s; + const xmlChar * s; /* Erst wenn wir sicher sind, dass kein Befehl * eingegeben wurde, checken wir, ob nun eine neue * Einheit oder ein neuer Spieler drankommt */ - if (!getbuf(F)) break; + s = getbuf(F, enc); + if (s==NULL) break; - init_tokens_str(buf, NULL); + init_tokens_str(s, NULL); s = getstrtoken(); if (findkeyword(s, u->faction->locale) == NOKEYWORD) { @@ -549,9 +471,9 @@ unitorders(FILE * F, struct faction * f) } if (quit) break; } - if (buf[0]) { + if (s[0]) { /* Nun wird der Befehl erzeut und eingeh�ngt */ - *ordp = parse_order(buf, u->faction->locale); + *ordp = parse_order(s, u->faction->locale); if (*ordp) ordp = &(*ordp)->next; } } @@ -619,25 +541,26 @@ version(void) /* ------------------------------------------------------------- */ static param_t -igetparam (const char *s, const struct locale *lang) +igetparam (const xmlChar *s, const struct locale *lang) { return findparam (igetstrtoken (s), lang); } int -readorders(const char *filename) +readorders(const char *filename, const char * encoding) { FILE * F = NULL; char *b; int nfactions=0; struct faction *f = NULL; + int enc = xmlParseCharEncoding(encoding); if (filename) F = cfopen(filename, "rt"); if (F==NULL) return 0; puts(" - lese Befehlsdatei...\n"); - b = getbuf(F); + b = getbuf(F, enc); /* Auffinden der ersten Partei, und danach abarbeiten bis zur letzten * Partei */ @@ -657,7 +580,7 @@ readorders(const char *filename) } #endif - b = getbuf(F); + b = getbuf(F, enc); break; case P_GAMENAME: case P_FACTION: @@ -666,7 +589,7 @@ readorders(const char *filename) ++nfactions; } - b = getbuf(F); + b = getbuf(F, enc); break; /* in factionorders wird nur eine zeile gelesen: @@ -675,8 +598,8 @@ readorders(const char *filename) * vermerkt. */ case P_UNIT: - if (!f || !unitorders(F, f)) do { - b = getbuf(F); + if (!f || !unitorders(F, enc, f)) do { + b = getbuf(F, enc); if (!b) break; p = igetparam(b, lang); } while ((p != P_UNIT || !f) && p != P_FACTION && p != P_NEXT && p != P_GAMENAME); @@ -691,11 +614,11 @@ readorders(const char *filename) case P_NEXT: f = NULL; - b = getbuf(F); + b = getbuf(F, enc); break; default: - b = getbuf(F); + b = getbuf(F, enc); break; } } @@ -781,10 +704,11 @@ void read_items(FILE *F, item **ilist) { for (;;) { + char ibuf[32]; const item_type * itype; - rs(F, buf); - if (!strcmp("end", buf)) break; - itype = it_find(buf); + rss(F, ibuf, sizeof(ibuf)); + if (!strcmp("end", ibuf)) break; + itype = it_find(ibuf); assert(itype!=NULL); if (itype!=NULL) { i_change(ilist, itype, ri(F)); @@ -801,10 +725,11 @@ read_alliances(FILE * F) if (!AllianceRestricted() && !AllianceAuto()) return; } - rs(F, pbuf); + rss(F, pbuf, sizeof(pbuf)); while (strcmp(pbuf, "end")!=0) { - rs(F, buf); - makealliance(atoi36(pbuf), buf); + char aname[128]; + rss(F, aname, sizeof(aname)); + makealliance(atoi36(pbuf), aname); rs(F, pbuf); } } @@ -943,8 +868,9 @@ lastturn(void) void fwriteorder(FILE * F, const struct order * ord, const struct locale * lang) { - write_order(ord, lang, buf, sizeof(buf)); - if (buf[0]) fwritestr(F, buf); + char obuf[1024]; + write_order(ord, lang, obuf, sizeof(obuf)); + if (obuf[0]) fwritestr(F, obuf); } unit * @@ -954,6 +880,7 @@ readunit(FILE * F) unit * u; int number, n, p; order ** orderp; + char obuf[1024]; n = rid(F); u = findunit(n); @@ -990,9 +917,10 @@ readunit(FILE * F) u->irace = new_race[(race_t)ri(F)]; } else { char * space; + char rname[32]; - rs(F, buf); - space = strchr(buf, ' '); + rss(F, rname, sizeof(rname)); + space = strchr(rname, ' '); if (space!=NULL) { char * inc = space+1; char * outc = space; @@ -1005,10 +933,10 @@ readunit(FILE * F) } while (*inc); *outc = 0; } - u->race = rc_find(buf); + u->race = rc_find(rname); assert(u->race); - rs(F, buf); - if (strlen(buf)) u->irace = rc_find(buf); + rss(F, rname, sizeof(rname)); + if (strlen(rname)) u->irace = rc_find(rname); else u->irace = u->race; } if (u->race->describe) { @@ -1069,11 +997,11 @@ readunit(FILE * F) } /* Persistente Befehle einlesen */ free_orders(&u->orders); - freadstr(F, buf, sizeof(buf)); + freadstr(F, obuf, sizeof(obuf)); p = n = 0; orderp = &u->orders; - while (*buf != 0) { - order * ord = parse_order(buf, u->faction->locale); + while (obuf[0]) { + order * ord = parse_order(obuf, u->faction->locale); if (ord!=NULL) { if (++n<MAXORDERS) { if (!is_persistent(ord) || ++p<MAXPERSISTENT) { @@ -1088,12 +1016,12 @@ readunit(FILE * F) } if (ord!=NULL) free_order(ord); } - freadstr(F, buf, sizeof(buf)); + freadstr(F, obuf, sizeof(obuf)); } if (global.data_version<NOLASTORDER_VERSION) { order * ord; - freadstr(F, buf, sizeof(buf)); - ord = parse_order(buf, u->faction->locale); + freadstr(F, obuf, sizeof(obuf)); + ord = parse_order(obuf, u->faction->locale); if (ord!=NULL) { #ifdef LASTORDER set_order(&u->lastorder, ord); @@ -1250,6 +1178,7 @@ readregion(FILE * F, short x, short y) { region * r = findregion(x, y); const terrain_type * terrain; + char token[32]; if (r==NULL) { r = new_region(x, y); @@ -1338,12 +1267,12 @@ readregion(FILE * F, short x, short y) assert(*pres==NULL); for (;;) { rawmaterial * res; - rs(F, buf); - if (strcmp(buf, "end")==0) break; + rss(F, token, sizeof(token)); + if (strcmp(token, "end")==0) break; res = calloc(sizeof(rawmaterial), 1); - res->type = rmt_find(buf); + res->type = rmt_find(token); if (res->type==NULL) { - log_error(("invalid resourcetype %s in data.\n", buf)); + log_error(("invalid resourcetype %s in data.\n", token)); } assert(res->type!=NULL); res->level = ri(F); @@ -1368,9 +1297,9 @@ readregion(FILE * F, short x, short y) pres=&res->next; } } - rs(F, buf); - if (strcmp(buf, "noherb") != 0) { - const resource_type * rtype = rt_find(buf); + rss(F, token, sizeof(token)); + if (strcmp(token, "noherb") != 0) { + const resource_type * rtype = rt_find(token); assert(rtype && rtype->itype && fval(rtype->itype, ITF_HERB)); rsetherbtype(r, rtype->itype); } else { @@ -1389,9 +1318,9 @@ readregion(FILE * F, short x, short y) if (r->land) { for (;;) { const struct item_type * itype; - rs(F, buf); - if (!strcmp(buf, "end")) break; - itype = it_find(buf); + rss(F, token, sizeof(token)); + if (!strcmp(token, "end")) break; + itype = it_find(token); assert(itype->rtype->ltype); r_setdemand(r, itype->rtype->ltype, ri(F)); } @@ -1498,6 +1427,7 @@ readfaction(FILE * F) int i = rid(F); faction * f = findfaction(i); char * email = NULL; + char token[32]; if (f==NULL) { f = (faction *) calloc(1, sizeof(faction)); @@ -1544,8 +1474,8 @@ readfaction(FILE * F) if (global.data_version < LOCALE_VERSION) { f->locale = find_locale("de"); } else { - rs(F, buf); - f->locale = find_locale(buf); + rss(F, token, sizeof(token)); + f->locale = find_locale(token); } f->lastorders = ri(F); f->age = ri(F); @@ -1553,8 +1483,8 @@ readfaction(FILE * F) race_t rc = (char) ri(F); f->race = new_race[rc]; } else { - rs(F, buf); - f->race = rc_find(buf); + rss(F, token, sizeof(token)); + f->race = rc_find(token); assert(f->race); } #ifdef CONVERT_DBLINK @@ -1577,8 +1507,8 @@ readfaction(FILE * F) } for (;;) { int level; - fscanf(F, "%s", buf); - if (strcmp("end", buf)==0) break; + fscanf(F, "%s", token); + if (strcmp("end", token)==0) break; fscanf(F, "%d ", &level); } planes = ri(F); @@ -1619,10 +1549,10 @@ readfaction(FILE * F) } } else { for (;;) { - rs(F, buf); - if (strcmp(buf, "end")==0) break; + rs(F, token); + if (strcmp(token, "end")==0) break; else { - int aid = atoi36(buf); + int aid = atoi36(token); int state = ri(F); sfp = addally(f, sfp, aid, state); } @@ -1711,11 +1641,13 @@ readgame(const char * filename, int backup) unit *u; FILE * F; int rmax = maxregions; + char path[MAX_PATH]; + char token[32]; - sprintf(buf, "%s/%s", datapath(), filename); + sprintf(path, "%s/%s", datapath(), filename); log_printf("- reading game data from %s\n", filename); - if (backup) create_backup(buf); - F = cfopen(buf, "r"); + if (backup) create_backup(path); + F = cfopen(path, "r"); if (F==NULL) { log_error(("Keine Spieldaten gefunden.\n")); return -1; @@ -1767,16 +1699,16 @@ readgame(const char * filename, int backup) pl->maxy = (short)ri(F); pl->flags = ri(F); if (global.data_version>WATCHERS_VERSION) { - rs(F, buf); - while (strcmp(buf, "end")!=0) { + rss(F, token, sizeof(token)); + while (strcmp(token, "end")!=0) { watcher * w = calloc(sizeof(watcher),1); variant fno; - fno.i = atoi36(buf); + fno.i = atoi36(token); w->mode = (unsigned char)ri(F); w->next = pl->watchers; pl->watchers = w; ur_add(fno, (void**)&w->faction, resolve_faction); - rs(F, buf); + rss(F, token, sizeof(token)); } } a_read(F, &pl->attribs); @@ -1845,9 +1777,10 @@ readgame(const char * filename, int backup) } if (skip) { char * r; + char buffer[128]; do { - r = fgets(buf, BUFSIZE, F); /* skip region */ - } while (r && buf[0]!='\n'); + r = fgets(buffer, sizeof(buffer), F); /* skip region */ + } while (r && buffer[0]!='\n'); continue; } --rmax; @@ -1878,8 +1811,8 @@ readgame(const char * filename, int backup) /* b->type = oldbuildings[ri(F)]; */ } else { - rs(F, buf); - b->type = bt_find(buf); + rss(F, token, sizeof(token)); + b->type = bt_find(token); } b->region = r; a_read(F, &b->attribs); @@ -1904,8 +1837,12 @@ readgame(const char * filename, int backup) if (sh->display && strlen(sh->display)>=DISPLAYSIZE) sh->display[DISPLAYSIZE] = 0; #endif - rs(F, buf); - sh->type = st_find(buf); + rss(F, token, sizeof(token)); + sh->type = st_find(token); + if (sh->type==NULL) { + /* old datafiles */ + sh->type = st_find(locale_string(default_locale, token)); + } assert(sh->type || !"ship_type not registered!"); sh->size = ri(F); sh->damage = ri(F); @@ -1999,23 +1936,21 @@ writegame(const char *filename, int quiet) unit *u; plane *pl; FILE * F; -#ifdef USE_PLAYERS - char playerfile[MAX_PATH]; -#endif + char path[MAX_PATH]; #ifdef USE_PLAYERS - sprintf(buf, "%s/%d.players", datapath(), turn); - export_players(playerfile); + sprintf(path, "%s/%d.players", datapath(), turn); + export_players(path); #endif - sprintf(buf, "%s/%s", datapath(), filename); + sprintf(path, "%s/%s", datapath(), filename); #ifdef HAVE_UNISTD_H - if (access(buf, R_OK) == 0) { + if (access(path, R_OK) == 0) { /* make sure we don't overwrite some hardlinkedfile */ - unlink(buf); + unlink(path); } #endif - F = cfopen(buf, "w"); + F = cfopen(path, "w"); if (F==NULL) return -1; diff --git a/src/common/kernel/save.h b/src/common/kernel/save.h index e3852d81d..36c49b982 100644 --- a/src/common/kernel/save.h +++ b/src/common/kernel/save.h @@ -34,7 +34,7 @@ double version(void); * dass hier ein Fehler (fehlende ") vorliegt */ FILE * cfopen(const char *filename, const char *mode); -int readorders(const char *); +int readorders(const char *filename, const char * encoding); int creategame(void); extern int readgame(const char * filename, int backup); int writegame(const char *filename, int quiet); diff --git a/src/common/kernel/ship.c b/src/common/kernel/ship.c index bded2a964..643b2db0b 100644 --- a/src/common/kernel/ship.c +++ b/src/common/kernel/ship.c @@ -41,7 +41,7 @@ ship_typelist *shiptypes = NULL; static local_names * snames; const ship_type * -findshiptype(const char * name, const struct locale * lang) +findshiptype(const xmlChar * name, const struct locale * lang) { local_names * sn = snames; variant var; @@ -57,7 +57,7 @@ findshiptype(const char * name, const struct locale * lang) sn->lang = lang; while (stl) { variant var; - const char * n = locale_string(lang, stl->type->name[0]); + const xmlChar * n = locale_string(lang, stl->type->name[0]); var.v = (void*)stl->type; addtoken(&sn->names, n, var); stl = stl->next; @@ -73,10 +73,6 @@ st_find(const char* name) { const struct ship_typelist * stl = shiptypes; while (stl && strcasecmp(stl->type->name[0], name)) stl = stl->next; - if (!stl) { /* compatibility for old datafiles */ - stl = shiptypes; - while (stl && strcasecmp(locale_string(default_locale, stl->type->name[0]), name)) stl = stl->next; - } return stl?stl->type:NULL; } @@ -170,7 +166,7 @@ captain(ship *sh, region *r) ship * new_ship(const ship_type * stype, const struct locale * lang, region * r) { - static char buffer[7 + IDSIZE + 1]; + static xmlChar buffer[7 + IDSIZE + 1]; ship *sh = (ship *) calloc(1, sizeof(ship)); sh->no = newcontainerid(); @@ -178,9 +174,8 @@ new_ship(const ship_type * stype, const struct locale * lang, region * r) sh->type = stype; sh->region = r; - sprintf(buffer, "%s %s", LOC(lang, stype->name[0]), shipid(sh)); + sprintf((char*)buffer, "%s %s", LOC(lang, stype->name[0]), shipid(sh)); set_string(&sh->name, buffer); - set_string(&sh->display, ""); shash(sh); addlist(&r->ships, sh); return sh; @@ -210,7 +205,7 @@ shipname(const ship * sh) static name idbuf[8]; static int nextbuf = 0; char *ibuf = idbuf[(++nextbuf) % 8]; - sprintf(ibuf, "%s (%s)", strcheck(sh->name, NAMESIZE), itoa36(sh->no)); + sprintf(ibuf, "%s (%s)", sh->name, itoa36(sh->no)); return ibuf; } diff --git a/src/common/kernel/ship.h b/src/common/kernel/ship.h index 2ed7e0eb8..34bcdf137 100644 --- a/src/common/kernel/ship.h +++ b/src/common/kernel/ship.h @@ -70,8 +70,8 @@ typedef struct ship { struct ship *nexthash; int no; struct region *region; - char *name; - char *display; + xmlChar *name; + xmlChar *display; struct attrib * attribs; int size; int damage; /* damage in 100th of a point of size */ @@ -91,7 +91,7 @@ extern const char *shipname(const struct ship * sh); extern struct ship *findship(int n); extern struct ship *findshipr(const struct region *r, int n); -extern const struct ship_type * findshiptype(const char *s, const struct locale * lang); +extern const struct ship_type * findshiptype(const xmlChar *s, const struct locale * lang); extern void register_ships(void); diff --git a/src/common/kernel/skill.c b/src/common/kernel/skill.c index 352753eef..a51309231 100644 --- a/src/common/kernel/skill.c +++ b/src/common/kernel/skill.c @@ -44,7 +44,7 @@ #include <stdlib.h> #include <string.h> -static const char *skillnames[MAXSKILLS] = +const char *skillnames[MAXSKILLS] = { "alchemy", "crossbow", @@ -79,7 +79,7 @@ static const char *skillnames[MAXSKILLS] = static boolean skill_enabled[MAXSKILLS]; -const char * +const xmlChar * skillname(skill_t sk, const struct locale * lang) { if (skill_enabled[sk]) { diff --git a/src/common/kernel/skill.h b/src/common/kernel/skill.h index a04022e7a..beca07b3f 100644 --- a/src/common/kernel/skill.h +++ b/src/common/kernel/skill.h @@ -46,7 +46,7 @@ extern void skill_init(void); extern void skill_done(void); extern struct attrib * make_skillmod(skill_t sk, unsigned int flags, skillmod_fun special, double multiplier, int bonus); -extern const char * skillname(skill_t, const struct locale *); +extern const xmlChar * skillname(skill_t, const struct locale *); extern skill_t sk_find(const char * name); extern void enable_skill(const char * name, boolean value); extern int level_days(int level); @@ -59,6 +59,7 @@ extern int skill_compare(const skill * sk, const skill * sc); extern void sk_set(skill * sv, int level); +extern const char *skillnames[]; #ifdef __cplusplus } diff --git a/src/common/kernel/spell.c b/src/common/kernel/spell.c index 45c86a864..d4ad9e3b7 100644 --- a/src/common/kernel/spell.c +++ b/src/common/kernel/spell.c @@ -124,7 +124,7 @@ get_spellnames(const struct locale * lang, magic_t mtype) } static spell * -get_spellfromtoken_i(const char *name, const struct locale * lang, magic_t mtype) +get_spellfromtoken_i(const xmlChar *name, const struct locale * lang, magic_t mtype) { variant token = { 0 }; spell_names * sn; @@ -147,7 +147,7 @@ get_spellfromtoken_i(const char *name, const struct locale * lang, magic_t mtype } spell * -get_spellfromtoken(unit *u, const char *name, const struct locale * lang) +get_spellfromtoken(unit *u, const xmlChar *name, const struct locale * lang) { sc_mage * m = get_mage(u); spell * sp; diff --git a/src/common/kernel/spell.h b/src/common/kernel/spell.h index c636ee118..3ef5b2123 100644 --- a/src/common/kernel/spell.h +++ b/src/common/kernel/spell.h @@ -44,6 +44,7 @@ extern "C" { extern void register_spell(struct spell * sp); extern struct spell * find_spell(magic_t mtype, const char * name); extern struct spell * find_spellbyid(magic_t mtype, spellid_t i); + extern struct spell *get_spellfromtoken(struct unit *u, const xmlChar *s, const struct locale * lang); #ifdef __cplusplus } diff --git a/src/common/kernel/teleport.c b/src/common/kernel/teleport.c index 7772cff82..b2fbbba23 100644 --- a/src/common/kernel/teleport.c +++ b/src/common/kernel/teleport.c @@ -153,7 +153,6 @@ spawn_braineaters(float chance) if (next-- == 0) { unit *u = createunit(r, f0, 1+rng_int()%10+rng_int()%10, new_race[RC_HIRNTOETER]); - set_string(&u->name, "Hirnt�ter"); set_level(u, SK_STEALTH, 1); set_level(u, SK_OBSERVATION, 1); next = rng_int() % (int)(chance*100); diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index bd46bd3a1..1b15c1171 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -66,28 +66,6 @@ attrib_type at_creator = { /* Rest ist NULL; tempor�res, nicht alterndes Attribut */ }; -const unit * -u_peasants(void) -{ - static unit peasants = { 0 }; - if (peasants.name==NULL) { - peasants.name = strdup("die Bauern"); - peasants.no = 2; - } - return &peasants; -} - -const unit * -u_unknown(void) -{ - static unit unknown = { 0 }; - if (unknown.name==NULL) { - unknown.name =strdup("eine unbekannte Einheit"); - unknown.no = 1; - } - return &unknown; -} - #define DMAXHASH 7919 typedef struct dead { struct dead * nexthash; @@ -237,7 +215,7 @@ destroy_unit(unit * u) } if (*p_item == item) p_item=&item->next; } - if (u->items && (u->faction==NULL || strlen(u->faction->passw)>0)) { + if (u->items && (u->faction==NULL || u->faction->passw[0])) { distribute_items(u); } } @@ -346,7 +324,7 @@ attrib_type at_private = { a_readstring }; -const char * +const xmlChar * u_description(const unit * u, const struct locale * lang) { if (u->display && u->display[0]) { @@ -357,15 +335,15 @@ u_description(const unit * u, const struct locale * lang) return NULL; } -const char * +const xmlChar * uprivate(const unit * u) { attrib * a = a_find(u->attribs, &at_private); if (!a) return NULL; - return (const char*)a->data.v; + return (const xmlChar*)a->data.v; } void -usetprivate(unit * u, const char * str) { +usetprivate(unit * u, const xmlChar * str) { attrib * a = a_find(u->attribs, &at_private); if(str == NULL) { @@ -374,7 +352,7 @@ usetprivate(unit * u, const char * str) { } if (!a) a = a_add(&u->attribs, a_new(&at_private)); if (a->data.v) free(a->data.v); - a->data.v = strdup(str); + a->data.v = strdup((const char*)str); } /*********************/ @@ -1293,12 +1271,11 @@ createunitid(unit *u, int id) void name_unit(unit *u) { - char name[16]; - if (u->race->generate_name) { set_string(&u->name, (u->race->generate_name(u))); } else { - sprintf(name, "%s %s", LOC(u->faction->locale, "unitdefault"), itoa36(u->no)); + xmlChar name[16]; + sprintf((char*)name, "%s %s", LOC(u->faction->locale, "unitdefault"), itoa36(u->no)); set_string(&u->name, name); } } @@ -1309,7 +1286,7 @@ name_unit(unit *u) * @param creator: unit to inherit stealth, group, building, ship, etc. from */ unit * -create_unit(region * r, faction * f, int number, const struct race *urace, int id, const char * dname, unit *creator) +create_unit(region * r, faction * f, int number, const struct race *urace, int id, const xmlChar * dname, unit *creator) { unit * u = calloc(1, sizeof(unit)); order * deford = default_order(f->locale); @@ -1346,7 +1323,6 @@ create_unit(region * r, faction * f, int number, const struct race *urace, int i name_unit(u); } else set_string(&u->name, dname); - set_string(&u->display, ""); if (count_unit(u)) f->no_units++; diff --git a/src/common/kernel/unit.h b/src/common/kernel/unit.h index 4f355e143..0f9a8f945 100644 --- a/src/common/kernel/unit.h +++ b/src/common/kernel/unit.h @@ -82,8 +82,8 @@ typedef struct unit { struct region *region; int no; int hp; - char *name; - char *display; + xmlChar *name; + xmlChar *display; struct faction *faction; struct building *building; struct ship *ship; @@ -155,8 +155,8 @@ void usettarget(struct unit * u, const struct unit * b); extern const struct race * urace(const struct unit * u); -const char* uprivate(const struct unit * u); -void usetprivate(struct unit * u, const char * c); +const xmlChar* uprivate(const struct unit * u); +void usetprivate(struct unit * u, const xmlChar * c); const struct potion_type * ugetpotionuse(const struct unit * u); /* benutzt u einein trank? */ void usetpotionuse(struct unit * u, const struct potion_type * p); /* u benutzt trank p (es darf halt nur einer pro runde) */ @@ -166,12 +166,8 @@ void usetcontact(struct unit * u, const struct unit * c); struct unit * findnewunit (const struct region * r, const struct faction *f, int alias); -#define upotions(u) fval(u, UFL_POTIONS) -extern const struct unit * u_peasants(void); -extern const struct unit * u_unknown(void); - extern struct unit * udestroy; -extern const char * u_description(const unit * u, const struct locale * lang); +extern const xmlChar * u_description(const unit * u, const struct locale * lang); extern struct skill * add_skill(struct unit * u, skill_t id); extern void remove_skill(struct unit *u, skill_t sk); extern struct skill * get_skill(const struct unit * u, skill_t id); @@ -219,7 +215,7 @@ extern int invisible(const struct unit *target, const struct unit * viewer); extern void stripunit(struct unit * u); extern void name_unit(struct unit *u); -extern struct unit * create_unit(struct region * r1, struct faction * f, int number, const struct race * rc, int id, const char * dname, struct unit *creator); +extern struct unit * create_unit(struct region * r1, struct faction * f, int number, const struct race * rc, int id, const xmlChar * dname, struct unit *creator); extern struct attrib_type at_creator; #ifdef __cplusplus diff --git a/src/common/kernel/xmlreader.c b/src/common/kernel/xmlreader.c index a98695a04..efc1176ef 100644 --- a/src/common/kernel/xmlreader.c +++ b/src/common/kernel/xmlreader.c @@ -86,7 +86,7 @@ xml_to_locale(const xmlChar * xmlStr) static char zText[1024]; const xmlChar * inbuf = xmlStr; char * outbuf = zText; - int inbytes = (int)strlen((const char*)xmlStr)+1; + int inbytes = (int)xmlStrlen(xmlStr)+1; int outbytes = (int)sizeof(zText); if (UTF8Toisolat1((xmlChar*)outbuf, &outbytes, inbuf, &inbytes)<0) { @@ -1531,9 +1531,9 @@ parse_races(xmlDocPtr doc) } assert(property!=NULL); if (strcmp((const char*)property, "name")==0) { - rc->generate_name = (const char* (*)(const struct unit*))fun; + rc->generate_name = (const xmlChar* (*)(const struct unit*))fun; } else if (strcmp((const char*)property, "describe")==0) { - rc->describe = (const char* (*)(const struct unit*, const struct locale *))fun; + rc->describe = (const xmlChar* (*)(const struct unit*, const struct locale *))fun; } else if (strcmp((const char*)property, "age")==0) { rc->age = (void(*)(struct unit*))fun; } else if (strcmp((const char*)property, "move")==0) { @@ -1852,7 +1852,7 @@ xml_readstrings(xmlXPathContextPtr xpath, xmlNodePtr * nodeTab, int nodeNr, bool if (text!=NULL) { assert(strcmp(zName, (const char*)xml_cleanup_string(BAD_CAST zName))==0); xml_cleanup_string(text); - locale_setstring(lang, zName, xml_to_locale(text)); + locale_setstring(lang, zName, text); xmlFree(text); } else { log_warning(("string %s has no text in locale %s\n", diff --git a/src/common/modules/arena.c b/src/common/modules/arena.c index b72fe8cf8..aee9bbf3b 100644 --- a/src/common/modules/arena.c +++ b/src/common/modules/arena.c @@ -75,19 +75,21 @@ static region * start_region[6]; static int newarena = 0; static region * -arena_region(int magic) { +arena_region(int magic) +{ return tower_region[magic]; } static building * -arena_tower(int magic) { +arena_tower(int magic) +{ return arena_region(magic)->buildings; } static int -leave_fail(unit * u) { - sprintf(buf, "Der Versuch, die Greifenschwingen zu benutzen, schlug fehl. %s konnte die Ebene der Herausforderung nicht verlassen.", unitname(u)); - addmessage(NULL, u->faction, buf, MSG_MESSAGE, ML_IMPORTANT); +leave_fail(unit * u) +{ + ADDMSG(&u->faction->msgs, msg_message("arena_leave_fail", "unit", u)); return 1; } @@ -104,9 +106,9 @@ leave_arena(struct unit * u, const struct item_type * itype, int amount, order * } static int -enter_fail(unit * u) { - sprintf(buf, "In %s 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.'. %s erhielt keinen Einla�.", regionname(u->region, u->faction), unitname(u)); - addmessage(NULL, u->faction, buf, MSG_MESSAGE, ML_IMPORTANT); +enter_fail(unit * u) +{ + ADDMSG(&u->faction->msgs, msg_message("arena_enter_fail", "region unit", u->region, u)); return 1; } @@ -146,8 +148,7 @@ enter_arena(unit * u, const item_type * itype, int amount, order * ord) if (u2) change_money(u2, get_money(u) - fee); else if (enter_fail(u)) return -1; } - sprintf(buf, "In %s �ffnet sich ein Portal. Eine Stimme ert�nt, und spricht: 'Willkommen in der Ebene der Herausforderung'. %s durchschreitet das Tor zu einer anderen Welt.", regionname(u->region, u->faction), unitname(u)); - addmessage(NULL, u->faction, buf, MSG_MESSAGE, ML_IMPORTANT); + ADDMSG(&u->faction->msgs, msg_message("arena_enter_fail", "region unit", u->region, u)); use_pooled(u, itype->rtype, GET_SLACK|GET_RESERVE, 1); use_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, fee); set_money(u, 109); @@ -233,6 +234,7 @@ static attrib_type at_hurting = { "hurting", NULL, NULL, age_hurting, write_hurting, read_hurting }; +#ifdef ARENA_CREATION static void make_temple(region * r) { @@ -253,10 +255,12 @@ make_temple(region * r) b->display = strdup("Ein Schrein aus spitzen Knochen und lodernden Flammen, gewidmet dem Wyrm der Wyrme"); a_add(&b->attribs, a_new(&at_hurting))->data.v=b; } +#endif /** * Initialisierung T�rme */ +#ifdef ARENA_CREATION static void tower_init(void) { @@ -294,7 +298,9 @@ tower_init(void) set_string(&b->name, "H�hle des Greifen"); } } +#endif +#ifdef ARENA_CREATION static void guardian_faction(plane * pl, int id) { @@ -342,9 +348,11 @@ guardian_faction(plane * pl, int id) set_money(u, 1000); } } +#endif #define BLOCKSIZE 9 +#ifdef ARENA_CREATION static void block_create(short x1, short y1, char terrain) { @@ -356,6 +364,7 @@ block_create(short x1, short y1, char terrain) } } } +#endif #ifdef CENTRAL_VOLCANO @@ -371,28 +380,26 @@ caldera_handle(trigger * t, void * data) while (*up) { unit * u = *up; if (u->building==b) { - sprintf(buf, "%s springt in die ewigen Feuer des Kraters.", unitname(u)); + message * msg; if (u->items) { item ** ip = &u->items; - strcat(buf, " Mit der sterblichen H�lle des Helden vergl�hen"); + msg = msg_message("caldera_handle_1", "unit items", u, u->items); while (*ip) { item * i = *ip; - char zText[10]; - sprintf(zText, " %d %s", i->number, locale_string(default_locale, resourcename(i->type->rtype, i->number!=1))); - strcat(buf, zText); i_remove(ip, i); if (*ip==i) ip=&i->next; - if (i->next) strcat(buf, ","); } - strcat(buf, "."); - } - addmessage(u->region, NULL, buf, MSG_MESSAGE, ML_IMPORTANT); + } else { + msg = msg_message("caldera_handle_0", "unit", u); + } + add_message(&u->region->msgs, msg); set_number(u, 0); } if (*up==u) up = &u->next; } - } else + } else { log_error(("could not perform caldera::handle()\n")); + } unused(data); return 0; } @@ -435,6 +442,7 @@ trigger_caldera(building * b) return t; } +#ifdef ARENA_CREATION static void init_volcano(void) { @@ -451,7 +459,9 @@ init_volcano(void) tt_register(&tt_caldera); } #endif +#endif +#ifdef ARENA_CREATION void create_arena(void) { @@ -500,7 +510,7 @@ create_arena(void) rsetpeasants(arena_center, 0); tower_init(); } - +#endif void register_arena(void) { diff --git a/src/common/modules/arena.h b/src/common/modules/arena.h index 4ddf92873..368fab09f 100644 --- a/src/common/modules/arena.h +++ b/src/common/modules/arena.h @@ -25,7 +25,9 @@ extern "C" { extern struct plane * arena; extern void register_arena(void); +#ifdef ARENA_CREATION extern void create_arena(void); +#endif #ifdef __cplusplus } diff --git a/src/common/modules/autoseed.c b/src/common/modules/autoseed.c index 6f32e55ca..66a4621cb 100644 --- a/src/common/modules/autoseed.c +++ b/src/common/modules/autoseed.c @@ -185,6 +185,8 @@ read_newfactions(const char * filename) { newfaction * newfactions = NULL; FILE * F = fopen(filename, "r"); + char buf[1024]; + if (F==NULL) return NULL; for (;;) { faction * f; @@ -218,7 +220,7 @@ read_newfactions(const char * filename) itoa36(subscription), email)); continue; } - nf->password = strdup(password); + nf->password = (xmlChar *)strdup(password); nf->race = rc_find(race); nf->subscription = subscription; if (alliances!=NULL) { @@ -232,7 +234,11 @@ read_newfactions(const char * filename) } else { nf->allies = NULL; } - if (nf->race==NULL) nf->race = findrace(race, default_locale); + if (nf->race==NULL) { + /* if the script didn't supply the race as a token, then it gives us a + * race in the default locale (which means that itis a UTF8 string) */ + nf->race = findrace((const xmlChar*)race, default_locale); + } nf->lang = find_locale(lang); nf->bonus = bonus; assert(nf->race && nf->email && nf->lang); diff --git a/src/common/modules/autoseed.h b/src/common/modules/autoseed.h index 3b807d2d1..4c0e3d49c 100644 --- a/src/common/modules/autoseed.h +++ b/src/common/modules/autoseed.h @@ -23,7 +23,7 @@ struct newfaction; typedef struct newfaction { struct newfaction * next; char * email; - char * password; + xmlChar * password; const struct locale * lang; const struct race * race; int bonus; diff --git a/src/common/modules/gmcmd.c b/src/common/modules/gmcmd.c index d6e04426b..c05538510 100644 --- a/src/common/modules/gmcmd.c +++ b/src/common/modules/gmcmd.c @@ -139,17 +139,17 @@ make_atgmcreate(const struct item_type * itype) } static void -gm_create(const tnode * tnext, const char * str, void * data, struct order * ord) +gm_create(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; int i; attrib * permissions = a_find(u->faction->attribs, &at_permissions); if (permissions) permissions = (attrib*)permissions->data.v; if (!permissions) return; - i = atoi(igetstrtoken(str)); + i = getint(); if (i>0) { - const char * iname = getstrtoken(); + const xmlChar * iname = getstrtoken(); const item_type * itype = finditemtype(iname, u->faction->locale); if (itype==NULL) { mistake(u, ord, "Unbekannter Gegenstand.", 0); @@ -175,13 +175,13 @@ has_permission(const attrib * permissions, unsigned int key) ** requires: permission-key "gmgate" **/ static void -gm_gate(const tnode * tnext, const char * str, void * data, struct order * ord) +gm_gate(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; const struct plane * p = rplane(u->region); - int id = atoi36(igetstrtoken(str)); - short x = rel_to_abs(p, u->faction, (short)atoi(getstrtoken()), 0); - short y = rel_to_abs(p, u->faction, (short)atoi(getstrtoken()), 1); + int id = getid(); + short x = rel_to_abs(p, u->faction, (short)getint(), 0); + short y = rel_to_abs(p, u->faction, (short)getint(), 1); region * r = findregion(x, y); building * b = findbuilding(id); if (b==NULL || r==NULL || p!=rplane(b->region) || p!=rplane(r)) { @@ -208,15 +208,16 @@ gm_gate(const tnode * tnext, const char * str, void * data, struct order * ord) ** requires: permission-key "gmterf" **/ static void -gm_terraform(const tnode * tnext, const char * str, void * data, struct order * ord) +gm_terraform(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; const struct plane * p = rplane(u->region); - short x = rel_to_abs(p, u->faction, (short)atoi(igetstrtoken(str)), 0); - short y = rel_to_abs(p, u->faction, (short)atoi(getstrtoken()), 1); - const char * c = getstrtoken(); + short x = rel_to_abs(p, u->faction, (short)getint(), 0); + short y = rel_to_abs(p, u->faction, (short)getint(), 1); + const xmlChar * c = getstrtoken(); region * r = findregion(x, y); - const terrain_type * terrain; + variant token; + tnode * tokens = get_translations(u->faction->locale, UT_TERRAINS); if (r==NULL || p!=rplane(r)) { mistake(u, ord, "Diese Region kann die Einheit nicht umwandeln.", 0); @@ -226,11 +227,10 @@ gm_terraform(const tnode * tnext, const char * str, void * data, struct order * attrib * permissions = a_find(u->faction->attribs, &at_permissions); if (!permissions || !has_permission(permissions, atoi36("gmterf"))) return; } - for (terrain=terrains();terrain!=NULL;terrain=terrain->next) { - if (!strcasecmp(locale_string(u->faction->locale, terrain->_name), c)) { - terraform_region(r, terrain); - break; - } + + if (findtoken(tokens, c, &token)!=E_TOK_NOMATCH) { + const terrain_type * terrain = (const terrain_type *)token.v; + terraform_region(r, terrain); } } @@ -239,13 +239,13 @@ gm_terraform(const tnode * tnext, const char * str, void * data, struct order * ** requires: permission-key "gmtele" **/ static void -gm_teleport(const tnode * tnext, const char * str, void * data, struct order * ord) +gm_teleport(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; const struct plane * p = rplane(u->region); - unit * to = findunit(atoi36(igetstrtoken(str))); - short x = rel_to_abs(p, u->faction, (short)atoi(getstrtoken()), 0); - short y = rel_to_abs(p, u->faction, (short)atoi(getstrtoken()), 1); + unit * to = findunit(getid()); + short x = rel_to_abs(p, u->faction, (short)getint(), 0); + short y = rel_to_abs(p, u->faction, (short)getint(), 1); region * r = findregion(x, y); if (r==NULL || p!=rplane(r)) { @@ -269,11 +269,11 @@ gm_teleport(const tnode * tnext, const char * str, void * data, struct order * o ** requires: permission-key "gmmsgr" **/ static void -gm_messageplane(const tnode * tnext, const char * str, void * data, struct order * ord) +gm_messageplane(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; const struct plane * p = rplane(u->region); - const char * zmsg = igetstrtoken(str); + const xmlChar * zmsg = getstrtoken(); if (p==NULL) { mistake(u, ord, "In diese Ebene kann keine Nachricht gesandt werden.", 0); } else { @@ -304,12 +304,12 @@ gm_messageplane(const tnode * tnext, const char * str, void * data, struct order } static void -gm_messagefaction(const tnode * tnext, const char * str, void * data, struct order * ord) +gm_messagefaction(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; - int n = atoi36(igetstrtoken(str)); + int n = getid(); faction * f = findfaction(n); - const char * msg = getstrtoken(); + const xmlChar * msg = getstrtoken(); plane * p = rplane(u->region); attrib * permissions = a_find(u->faction->attribs, &at_permissions); if (!permissions || !has_permission(permissions, atoi36("gmmsgr"))) { @@ -334,13 +334,13 @@ gm_messagefaction(const tnode * tnext, const char * str, void * data, struct ord ** requires: permission-key "gmmsgr" **/ static void -gm_messageregion(const tnode * tnext, const char * str, void * data, struct order * ord) +gm_messageregion(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; const struct plane * p = rplane(u->region); - short x = rel_to_abs(p, u->faction, (short)atoi(igetstrtoken(str)), 0); - short y = rel_to_abs(p, u->faction, (short)atoi(getstrtoken()), 1); - const char * msg = getstrtoken(); + short x = rel_to_abs(p, u->faction, (short)getint(), 0); + short y = rel_to_abs(p, u->faction, (short)getint(), 1); + const xmlChar * msg = getstrtoken(); region * r = findregion(x, y); if (r==NULL || p!=rplane(r)) { @@ -362,12 +362,12 @@ gm_messageregion(const tnode * tnext, const char * str, void * data, struct orde ** requires: permission-key "gmkill" **/ static void -gm_killunit(const tnode * tnext, const char * str, void * data, struct order * ord) +gm_killunit(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; const struct plane * p = rplane(u->region); - unit * target = findunit(atoi36(igetstrtoken(str))); - const char * msg = getstrtoken(); + unit * target = findunit(getid()); + const xmlChar * msg = getstrtoken(); region * r = target->region; if (r==NULL || p!=rplane(r)) { @@ -392,12 +392,12 @@ gm_killunit(const tnode * tnext, const char * str, void * data, struct order * o ** requires: permission-key "gmmsgr" **/ static void -gm_killfaction(const tnode * tnext, const char * str, void * data, struct order * ord) +gm_killfaction(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; - int n = atoi36(igetstrtoken(str)); + int n = getid(); faction * f = findfaction(n); - const char * msg = getstrtoken(); + const xmlChar * msg = getstrtoken(); plane * p = rplane(u->region); attrib * permissions = a_find(u->faction->attribs, &at_permissions); if (!permissions || !has_permission(permissions, atoi36("gmkill"))) { @@ -426,12 +426,12 @@ gm_killfaction(const tnode * tnext, const char * str, void * data, struct order ** requires: permission-key "gmmsgr" **/ static void -gm_messageunit(const tnode * tnext, const char * str, void * data, struct order * ord) +gm_messageunit(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; const struct plane * p = rplane(u->region); - unit * target = findunit(atoi36(igetstrtoken(str))); - const char * msg = getstrtoken(); + unit * target = findunit(getid()); + const xmlChar * msg = getstrtoken(); region * r; if (target == NULL) { @@ -461,11 +461,11 @@ gm_messageunit(const tnode * tnext, const char * str, void * data, struct order ** requires: permission-key "gmgive" **/ static void -gm_give(const tnode * tnext, const char * str, void * data, struct order * ord) +gm_give(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; - unit * to = findunit(atoi36(igetstrtoken(str))); - int num = atoi(getstrtoken()); + unit * to = findunit(getid()); + int num = getint(); const item_type * itype = finditemtype(getstrtoken(), u->faction->locale); if (to==NULL || rplane(to->region) != rplane(u->region)) { @@ -496,11 +496,11 @@ gm_give(const tnode * tnext, const char * str, void * data, struct order * ord) ** requires: permission-key "gmtake" **/ static void -gm_take(const tnode * tnext, const char * str, void * data, struct order * ord) +gm_take(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; - unit * to = findunit(atoi36(igetstrtoken(str))); - int num = atoi(getstrtoken()); + unit * to = findunit(getid()); + int num = getint(); const item_type * itype = finditemtype(getstrtoken(), u->faction->locale); if (to==NULL || rplane(to->region) != rplane(u->region)) { @@ -531,12 +531,12 @@ gm_take(const tnode * tnext, const char * str, void * data, struct order * ord) ** requires: permission-key "gmskil" **/ static void -gm_skill(const tnode * tnext, const char * str, void * data, struct order * ord) +gm_skill(const tnode * tnext, void * data, struct order * ord) { unit * u = (unit*)data; - unit * to = findunit(atoi36(igetstrtoken(str))); + unit * to = findunit(getid()); skill_t skill = findskill(getstrtoken(), u->faction->locale); - int num = atoi(getstrtoken()); + int num = getint(); if (to==NULL || rplane(to->region) != rplane(u->region)) { /* unknown or in another plane */ @@ -569,22 +569,22 @@ init_gmcmd(void) { at_register(&at_gmcreate); at_register(&at_permissions); - add_command(&g_root, &g_keys, "gm", NULL); - add_command(&g_keys, NULL, "terraform", &gm_terraform); - add_command(&g_keys, NULL, "create", &gm_create); - add_command(&g_keys, NULL, "gate", &gm_gate); - add_command(&g_keys, NULL, "give", &gm_give); - add_command(&g_keys, NULL, "take", &gm_take); - add_command(&g_keys, NULL, "teleport", &gm_teleport); - add_command(&g_keys, NULL, "skill", &gm_skill); - add_command(&g_keys, &g_tell, "tell", NULL); - add_command(&g_tell, NULL, "region", &gm_messageregion); - add_command(&g_tell, NULL, "unit", &gm_messageunit); - add_command(&g_tell, NULL, "plane", &gm_messageplane); - add_command(&g_tell, NULL, "faction", &gm_messagefaction); - add_command(&g_keys, &g_kill, "kill", NULL); - add_command(&g_kill, NULL, "unit", &gm_killunit); - add_command(&g_kill, NULL, "faction", &gm_killfaction); + add_command(&g_root, &g_keys, (const xmlChar *)"gm", NULL); + add_command(&g_keys, NULL, (const xmlChar *)"terraform", &gm_terraform); + add_command(&g_keys, NULL, (const xmlChar *)"create", &gm_create); + add_command(&g_keys, NULL, (const xmlChar *)"gate", &gm_gate); + add_command(&g_keys, NULL, (const xmlChar *)"give", &gm_give); + add_command(&g_keys, NULL, (const xmlChar *)"take", &gm_take); + add_command(&g_keys, NULL, (const xmlChar *)"teleport", &gm_teleport); + add_command(&g_keys, NULL, (const xmlChar *)"skill", &gm_skill); + add_command(&g_keys, &g_tell, (const xmlChar *)"tell", NULL); + add_command(&g_tell, NULL, (const xmlChar *)"region", &gm_messageregion); + add_command(&g_tell, NULL, (const xmlChar *)"unit", &gm_messageunit); + add_command(&g_tell, NULL, (const xmlChar *)"plane", &gm_messageplane); + add_command(&g_tell, NULL, (const xmlChar *)"faction", &gm_messagefaction); + add_command(&g_keys, &g_kill, (const xmlChar *)"kill", NULL); + add_command(&g_kill, NULL, (const xmlChar *)"unit", &gm_killunit); + add_command(&g_kill, NULL, (const xmlChar *)"faction", &gm_killfaction); } /* @@ -618,43 +618,12 @@ faction * gm_addquest(const char * email, const char * name, short radius, unsigned int flags) { plane * p; - attrib * a; - unit * u; watcher * w = calloc(sizeof(watcher), 1); region * center; boolean invalid = false; short minx, miny, maxx, maxy, cx, cy; short x; - int i; - faction * f = calloc(1, sizeof(faction)); - - /* GM faction */ - a_add(&f->attribs, make_key(atoi36("quest"))); - f->banner = strdup("Questenpartei"); - f->passw = strdup(itoa36(rng_int())); - f->override = strdup(itoa36(rng_int())); - f->override = strdup(itoa36(rng_int())); - if (set_email(&f->email, email)!=0) { - log_error(("Invalid email address for faction %s: %s\n", itoa36(f->no), email)); - } - f->name = strdup("Questenpartei"); - f->race = new_race[RC_TEMPLATE]; - f->age = 0; - f->lastorders = turn; - f->alive = true; - f->locale = find_locale("de"); - f->options = want(O_COMPRESS) | want(O_REPORT) | want(O_COMPUTER) | want(O_ADRESSEN); - { - faction * xist; - int i = atoi36("gm00")-1; - do { - xist = findfaction(++i); - } while (xist); - - f->no = i; - addlist(&factions, f); - fhash(f); - } + faction * f; /* GM playfield */ do { @@ -690,35 +659,12 @@ gm_addquest(const char * email, const char * name, short radius, unsigned int fl } /* watcher: */ + f = gm_addfaction(email, p, center); w->faction = f; w->mode = see_unit; w->next = p->watchers; p->watchers = w; - /* generic permissions */ - a = a_add(&f->attribs, a_new(&at_permissions)); - - add_key((attrib**)&a->data.v, atoi36("gmterf")); - add_key((attrib**)&a->data.v, atoi36("gmtele")); - add_key((attrib**)&a->data.v, atoi36("gmgive")); - add_key((attrib**)&a->data.v, atoi36("gmskil")); - add_key((attrib**)&a->data.v, atoi36("gmtake")); - add_key((attrib**)&a->data.v, atoi36("gmmsgr")); - add_key((attrib**)&a->data.v, atoi36("gmmsgu")); - add_key((attrib**)&a->data.v, atoi36("gmgate")); - - a_add((attrib**)&a->data.v, make_atgmcreate(resource2item(r_silver))); - - for (i=0;i<=I_HORSE;++i) { - a_add((attrib**)&a->data.v, make_atgmcreate(olditemtype[i])); - } - - /* one initial unit */ - u = createunit(center, f, 1, new_race[RC_TEMPLATE]); - u->irace = new_race[RC_GNOME]; - u->number = 1; - set_string(&u->name, "Questenmeister"); - return f; } @@ -733,18 +679,19 @@ gm_addfaction(const char * email, plane * p, region * r) assert(p!=NULL); /* GM faction */ - add_key(&f->attribs, atoi36("quest")); - f->banner = strdup("Questenpartei"); - f->passw = strdup(itoa36(rng_int())); + a_add(&f->attribs, make_key(atoi36("quest"))); + f->banner = (xmlChar*)strdup("quest faction"); + f->name = (xmlChar*)strdup("quest faction"); + f->passw = (xmlChar*)strdup(itoa36(rng_int())); + f->override = (xmlChar*)strdup(itoa36(rng_int())); if (set_email(&f->email, email)!=0) { log_error(("Invalid email address for faction %s: %s\n", itoa36(f->no), email)); } - f->name = strdup("Questenpartei"); f->race = new_race[RC_TEMPLATE]; f->age = 0; f->lastorders = turn; f->alive = true; - f->locale = find_locale("de"); + f->locale = default_locale; f->options = want(O_COMPRESS) | want(O_REPORT) | want(O_COMPUTER) | want(O_ADRESSEN); { faction * xist; @@ -757,6 +704,7 @@ gm_addfaction(const char * email, plane * p, region * r) addlist(&factions, f); fhash(f); } + /* generic permissions */ a = a_add(&f->attribs, a_new(&at_permissions)); @@ -775,10 +723,8 @@ gm_addfaction(const char * email, plane * p, region * r) a_add((attrib**)&a->data.v, make_atgmcreate(olditemtype[i])); } /* one initial unit */ - u = createunit(r, f, 1, new_race[RC_TEMPLATE]); + u = create_unit(r, f, 1, new_race[RC_TEMPLATE], 1, (const xmlChar*)"quest master", NULL); u->irace = new_race[RC_GNOME]; - u->number = 1; - set_string(&u->name, "Questenmeister"); return f; } diff --git a/src/common/modules/museum.c b/src/common/modules/museum.c index 326843165..cdbfed719 100644 --- a/src/common/modules/museum.c +++ b/src/common/modules/museum.c @@ -187,6 +187,7 @@ warden_add_give(unit *src, unit *u, const item_type *itype, int n) void create_museum(void) { +#if 0 /* TODO: move this to LUA. It should be possible. */ unsigned int museum_id = hashstring("museum"); plane *museum = getplanebyid(museum_id); region *r; @@ -201,7 +202,7 @@ create_museum(void) 9500, 9550, PFL_MUSEUM); } - if(findregion(9525, 9525) == NULL) { + if (findregion(9525, 9525) == NULL) { /* Eingangshalle */ r = new_region(9525, 9525); terraform_region(r, terrain_hall); @@ -280,6 +281,7 @@ create_museum(void) rsetpeasants(r, 0); set_string(&r->display, "Die S�dliche Promenade f�hrt den Besucher in den kulturgeschichtlichen Teil des Museums."); } +#endif } static int @@ -308,7 +310,7 @@ use_museumexitticket(unit *u, const struct item_type *itype, int amount, order * unit_cookie = a->data.i; a_remove(&u->attribs, a); - if(a) { + if (a) { for(a = a_find(warden->attribs, &at_museumgiveback); a && a->type==&at_museumgiveback; a = a->next) { if(((museumgiveback *)(a->data.v))->cookie == unit_cookie) break; } @@ -316,10 +318,10 @@ use_museumexitticket(unit *u, const struct item_type *itype, int amount, order * museumgiveback *gb = (museumgiveback *)(a->data.v); item *it; - for(it = gb->items; it; it = it->next) { + for (it = gb->items; it; it = it->next) { i_change(&u->items, it->type, it->number); } - ADDMSG(&u->faction->msgs, msg_message("unitmessage", "region unit sender string", r, u, warden, buf)); + ADDMSG(&u->faction->msgs, msg_message("museumgiveback", "region unit sender items", r, u, warden, gb->items)); a_remove(&warden->attribs, a); } } diff --git a/src/common/modules/score.c b/src/common/modules/score.c index 80e998c63..c19a1b124 100644 --- a/src/common/modules/score.c +++ b/src/common/modules/score.c @@ -70,6 +70,7 @@ score(void) region *r; faction *f; int allscores = 0; + char path[MAX_PATH]; for (f = factions; f; f = f->next) f->score = 0; @@ -164,8 +165,8 @@ score(void) allscores = 1; } - sprintf(buf, "%s/score", basepath()); - scoreFP = fopen(buf, "w"); + sprintf(path, "%s/score", basepath()); + scoreFP = fopen(path, "w"); for (f = factions; f; f = f->next) if (f->num_total != 0) { fprintf(scoreFP, "%8d (%8d/%4.2f%%/%5.2f) %30.30s (%3.3s) %5s (%3d)\n", f->score, f->score - average_score_of_age(f->age, f->age / 24 + 1), @@ -179,8 +180,8 @@ score(void) alliance *a; const item_type * token = it_find("conquesttoken"); - sprintf(buf, "%s/score.alliances", basepath()); - scoreFP = fopen(buf, "w"); + sprintf(path, "%s/score.alliances", basepath()); + scoreFP = fopen(path, "w"); fprintf(scoreFP, "# alliance:factions:persons:score\n"); for (a = alliances; a; a = a->next) { diff --git a/src/common/modules/xecmd.c b/src/common/modules/xecmd.c index 754251c68..5991f8c54 100644 --- a/src/common/modules/xecmd.c +++ b/src/common/modules/xecmd.c @@ -86,7 +86,7 @@ xe_giveballon(unit *u, struct order *ord) sh = new_ship(st_find("balloon"), u2->faction->locale, u2->region); sh->size = 5; - set_string(&sh->name,"Xontormia-Ballon"); + set_string(&sh->name, (const xmlChar*)"Xontormia-Ballon"); leave(u2->region, u2); u2->ship = sh; fset(u2, UFL_OWNER); diff --git a/src/common/spells/alp.c b/src/common/spells/alp.c index c0669f4d3..73420b9b5 100644 --- a/src/common/spells/alp.c +++ b/src/common/spells/alp.c @@ -16,7 +16,10 @@ #include "alp.h" #include <kernel/eressea.h> +#include <kernel/faction.h> #include <kernel/magic.h> +#include <kernel/message.h> +#include <kernel/race.h> #include <kernel/region.h> #include <kernel/skill.h> #include <kernel/unit.h> @@ -98,6 +101,9 @@ sp_summon_alp(struct castorder *co) unit *mage = co->magician.u; int cast_level = co->level; spellparameter *pa = co->par; + const struct race * rc = new_race[RC_ALP]; + struct faction * f = findfaction(MONSTER_FACTION); + struct message * msg; opfer = pa->param[0]->data.u; @@ -105,7 +111,7 @@ sp_summon_alp(struct castorder *co) * Regionsberichte von ihm. Er erh�lt aber sp�ter eine Mitteilung, * sobald der Alp sein Opfer erreicht hat. */ - alp = create_unit(r, findfaction(MONSTER_FACTION), 1, new_race[RC_ALP], 0, "Alp", NULL); + alp = create_unit(r, f, 1, rc, 0, NULL, NULL); set_level(alp, SK_STEALTH, 7); setstatus(alp, ST_FLEE); /* flieht */ @@ -119,14 +125,14 @@ sp_summon_alp(struct castorder *co) { /* Wenn der Alp stirbt, den Magier nachrichtigen */ add_trigger(&alp->attribs, "destroy", trigger_unitmessage(mage, - "Ein Alp starb, ohne sein Ziel zu erreichen.", MSG_EVENT, ML_INFO)); + "trigger_alp_destroy", MSG_EVENT, ML_INFO)); /* Wenn Opfer oder Magier nicht mehr existieren, dann stirbt der Alp */ add_trigger(&mage->attribs, "destroy", trigger_killunit(alp)); add_trigger(&opfer->attribs, "destroy", trigger_killunit(alp)); } - sprintf(buf, "%s beschw�rt den Alp %s f�r %s.", unitname(mage), - unitname(alp), unitname(opfer)); - addmessage(r, mage->faction, buf, MSG_MAGIC, ML_INFO); + msg = msg_message("summon_alp_effect", "mage alp target", mage, alp, opfer); + r_addmessage(r, mage->faction, msg); + msg_release(msg); return cast_level; } @@ -141,17 +147,16 @@ alp_findet_opfer(unit *alp, region *r) unit *mage = ad->mage; unit *opfer = ad->target; variant effect; + message * msg; assert(opfer); assert(mage); /* Magier und Opfer Bescheid geben */ - strcpy(buf, "Ein Alp hat sein Opfer gefunden!"); - addmessage(r, mage->faction, buf, MSG_MAGIC, ML_INFO); - - sprintf(buf, "Ein Alp springt auf den R�cken von %s.", - unitname(opfer)); - addmessage(r, opfer->faction, buf, MSG_EVENT, ML_IMPORTANT); + msg = msg_message("alp_success", "target", opfer); + add_message(&mage->faction->msgs, msg); + r_addmessage(opfer->region, opfer->faction, msg); + msg_release(msg); /* Relations werden in destroy_unit(alp) automatisch gel�scht. * Die Aktionen, die beim Tod des Alps ausgel�st werden sollen, diff --git a/src/common/spells/combatspells.c b/src/common/spells/combatspells.c index 445462774..f05a0995f 100644 --- a/src/common/spells/combatspells.c +++ b/src/common/spells/combatspells.c @@ -716,7 +716,6 @@ sp_shadowcall(fighter * fi, int level, double power, spell * sp) u = create_unit(r, mage->faction, force, rc, 0, NULL, mage); setstatus(u, ST_FIGHT); - set_string(&u->name, racename(mage->faction->locale, u, u->race)); set_level(u, SK_WEAPONLESS, (int)(power/2)); set_level(u, SK_AUSDAUER, (int)(power/2)); u->hp = u->number * unit_max_hp(u); @@ -746,7 +745,6 @@ sp_wolfhowl(fighter * fi, int level, double power, spell * sp) setstatus(u, ST_FIGHT); - set_string(&u->name, racename(mage->faction->locale, u, u->race)); set_level(u, SK_WEAPONLESS, (int)(power/3)); set_level(u, SK_AUSDAUER, (int)(power/3)); u->hp = u->number * unit_max_hp(u); @@ -781,7 +779,6 @@ sp_shadowknights(fighter * fi, int level, double power, spell * sp) u = create_unit(r, mage->faction, force, new_race[RC_SHADOWKNIGHT], 0, NULL, mage); setstatus(u, ST_FIGHT); - set_string(&u->name, "Schattenritter"); u->hp = u->number * unit_max_hp(u); if (fval(mage, UFL_PARTEITARNUNG)) @@ -1441,25 +1438,12 @@ sp_reanimate(fighter * fi, int level, double power, spell * sp) battle *b = fi->side->battle; unit *mage = fi->unit; int healable, j=0; - double c = 0.50; + double c = 0.50 + 0.02 * power; double k = EFFECT_HEALING_SPELL * power; + boolean use_item = get_item(mage, I_AMULET_OF_HEALING) > 0; + message * msg; - switch(sp->id) { - case SPL_REANIMATE: - sprintf(buf, "%s beginnt ein Ritual der Wiederbelebung", - unitname(mage)); - c += 0.02 * power; - break; - - default: - sprintf(buf, "%s zaubert %s", - unitname(mage), - spell_name(sp, default_locale)); - } - if (get_item(mage, I_AMULET_OF_HEALING) > 0) { - scat(" und benutzt das "); - scat(locale_string(default_locale, resourcename(oldresourcetype[R_AMULET_OF_HEALING], 0))); - scat(", um den Zauber zu verst�rken"); + if (use_item) { k *= 2; c += 0.10; } @@ -1490,18 +1474,16 @@ sp_reanimate(fighter * fi, int level, double power, spell * sp) ++j; } } - if (j == 0) { - scat(", kann aber niemanden wiederbeleben."); - level = 0; - } else if (j == 1) { - scat(" und belebt einen Toten wieder."); - level = 1; - } else { - scat(" und belebt "); - icat(j); - scat(" Tote wieder."); + if (j <= 0) { + level = j; } - battlerecord(b, buf); + if (use_item) { + msg = msg_message("reanimate_effect_1", "mage amount item", mage, j, oldresourcetype[R_AMULET_OF_HEALING]); + } else { + msg = msg_message("reanimate_effect_0", "mage amount", mage, j); + } + message_all(b, msg); + msg_release(msg); return level; } @@ -1566,19 +1548,15 @@ sp_healing(fighter * fi, int level, double power, spell * sp) battle *b = fi->side->battle; unit *mage = fi->unit; int j = 0; - int healhp = (int)power; + int healhp = (int)power * 200; cvector *fgs; - - sprintf(buf, "%s k�mmert sich um die Verletzten", unitname(mage)); + message * msg; + boolean use_item = get_item(mage, I_AMULET_OF_HEALING) > 0; /* bis zu 11 Personen pro Stufe (einen HP m�ssen sie ja noch - * haben, sonst w�ren sie tot) k�nnen geheilt werden */ - healhp *= 200; + * haben, sonst w�ren sie tot) k�nnen geheilt werden */ - if (get_item(mage, I_AMULET_OF_HEALING) > 0) { - scat(" und benutzt das "); - scat(locale_string(default_locale, resourcename(oldresourcetype[R_AMULET_OF_HEALING], 0))); - scat(", um die Heilzauber zu verst�rken"); + if (use_item) { healhp *= 2; } @@ -1592,18 +1570,16 @@ sp_healing(fighter * fi, int level, double power, spell * sp) cv_kill(fgs); free(fgs); - if (j == 0) { - scat(", doch niemand mu�te magisch geheilt werden."); - level = 0; - } else if (j == 1) { - scat(" und heilt einen Verwundeten."); - level = 1; - } else { - scat(" und heilt "); - icat(j); - scat(" Verwundete."); + if (j <= 0) { + level = j; } - battlerecord(b, buf); + if (use_item) { + msg = msg_message("healing_effect_1", "mage amount item", mage, j, oldresourcetype[R_AMULET_OF_HEALING]); + } else { + msg = msg_message("healing_effect_0", "mage amount", mage, j); + } + message_all(b, msg); + msg_release(msg); return level; } diff --git a/src/common/spells/spells.c b/src/common/spells/spells.c index 9c4a3fd4b..55a57c471 100644 --- a/src/common/spells/spells.c +++ b/src/common/spells/spells.c @@ -23,7 +23,8 @@ #include "alp.h" #include "combatspells.h" -#include <curse.h> +#include <kernel/curse.h> +#include <util/nrmessage.h> struct curse_type; extern void ct_register(const struct curse_type * ct); @@ -541,6 +542,9 @@ sp_summon_familiar(castorder *co) skill_t sk; int dh, dh1; direction_t d; + message * msg; + xmlChar zText[NAMESIZE]; + if (get_familiar(mage) != NULL ) { cmistake(mage, co->order, 199, MSG_MAGIC); return 0; @@ -573,15 +577,11 @@ sp_summon_familiar(castorder *co) target_region = rconnect(r,d); } - familiar = create_unit(target_region, mage->faction, 1, rc, 0, NULL, mage); - if (target_region==mage->region) { - familiar->building = mage->building; - familiar->ship = mage->ship; - } + msg = msg_message("familiar_name", "unit", mage); + nr_render(msg, mage->faction->locale, zText, sizeof(zText), mage->faction); + msg_release(msg); + familiar = create_unit(target_region, mage->faction, 1, rc, 0, zText, mage); setstatus(familiar, ST_FLEE); - sprintf(buf, "Vertrauter von %s", unitname(mage)); - set_string(&familiar->name, buf); - if (fval(mage, UFL_PARTEITARNUNG)) fset(familiar, UFL_PARTEITARNUNG); fset(familiar, UFL_LOCKED); make_familiar(familiar, mage); @@ -590,24 +590,24 @@ sp_summon_familiar(castorder *co) for (sk=0;sk<MAXSKILLS;sk++) { if (rc->bonus[sk] > -5) dh++; } - buf[0] = 0; - for(sk=0;sk<MAXSKILLS;sk++) { + zText[0] = 0; + for (sk=0;sk<MAXSKILLS;sk++) { if (rc->bonus[sk] > -5) { dh--; if (dh1 == 0) { dh1 = 1; } else { if (dh == 0) { - scat(LOC(mage->faction->locale, "list_and")); + strncat((char*)zText, (const char*)LOC(mage->faction->locale, "list_and"), sizeof(zText)); } else { - scat(", "); + strncat((char*)zText, (const char*)", ", sizeof(zText)); } } - scat(skillname(sk, mage->faction->locale)); + strncat((char*)zText, (const char*)skillname(sk, mage->faction->locale), sizeof(zText)); } } ADDMSG(&mage->faction->msgs, msg_message("familiar_describe", - "mage race skills", mage, rc, buf)); + "mage race skills", mage, rc, zText)); return cast_level; } @@ -898,7 +898,7 @@ sp_summonent(castorder *co) ents = (int)min(power*power, rtrees(r,2)); - u = create_unit(r, mage->faction, ents, new_race[RC_TREEMAN], 0, LOC(mage->faction->locale, rc_name(new_race[RC_TREEMAN], ents!=1)), mage); + u = create_unit(r, mage->faction, ents, new_race[RC_TREEMAN], 0, NULL, mage); a = a_new(&at_unitdissolve); a->data.ca[0] = 2; /* An r->trees. */ @@ -941,6 +941,7 @@ sp_blessstonecircle(castorder *co) unit *mage = co->magician.u; int cast_level = co->level; spellparameter *p = co->par; + message * msg; /* wenn kein Ziel gefunden, Zauber abbrechen */ if (p->param[0]->flag == TARGET_NOTFOUND) return 0; @@ -961,8 +962,9 @@ sp_blessstonecircle(castorder *co) b->type = bt_find("blessedstonecircle"); - sprintf(buf, "%s weiht %s.", unitname(mage), buildingname(b)); - addmessage(r, 0, buf, MSG_MAGIC, ML_INFO); + msg = msg_message("blessedstonecircle_effect", "mage building", mage, b); + add_message(&r->msgs, msg); + msg_release(msg); return cast_level; } @@ -1206,8 +1208,7 @@ patzer_ents(castorder *co) } ents = (int)(force*10); - u = create_unit(r, findfaction(MONSTER_FACTION), ents, new_race[RC_TREEMAN], 0, - LOC(default_locale, rc_name(new_race[RC_TREEMAN], ents!=1)), NULL); + u = create_unit(r, findfaction(MONSTER_FACTION), ents, new_race[RC_TREEMAN], 0, NULL, NULL); /* 'Erfolg' melden */ ADDMSG(&mage->faction->msgs, msg_message( @@ -1489,8 +1490,7 @@ sp_create_irongolem(castorder *co) return 0; } - u2 = create_unit(r, mage->faction, number, new_race[RC_IRONGOLEM], 0, - LOC(mage->faction->locale, rc_name(new_race[RC_IRONGOLEM], 1)), mage); + u2 = create_unit(r, mage->faction, number, new_race[RC_IRONGOLEM], 0, NULL, mage); set_level(u2, SK_ARMORER, 1); set_level(u2, SK_WEAPONSMITH, 1); @@ -1551,8 +1551,7 @@ sp_create_stonegolem(castorder *co) return 0; } - u2 = create_unit(r, mage->faction, number, new_race[RC_STONEGOLEM], 0, - LOC(mage->faction->locale, rc_name(new_race[RC_STONEGOLEM], 1)), mage); + u2 = create_unit(r, mage->faction, number, new_race[RC_STONEGOLEM], 0, NULL, mage); set_level(u2, SK_ROAD_BUILDING, 1); set_level(u2, SK_BUILDING, 1); @@ -1675,44 +1674,36 @@ sp_great_drought(castorder *co) } } - /* melden, 1x pro partei */ - for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - - for (u = r->units; u; u = u->next) { - if (!fval(u->faction, FFL_SELECT)) { - fset(u->faction, FFL_SELECT); - sprintf(buf, "%s ruft das Feuer der Sonne auf %s hinab.", - cansee(u->faction, r, mage, 0)? unitname(mage) : "Jemand", - regionname(r, u->faction)); - if (!fval(r->terrain, SEA_REGION)) { - if (r->terrain == newterrain(T_SWAMP) && terraform) { - scat(" 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."); - } else { - scat(" 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."); - if (terraform) { - scat(" Die D�rre ver�nderte die Region f�r immer."); - } - } - addmessage(r, u->faction, buf, MSG_EVENT, ML_WARN); - } else { /* ist Ozean */ - scat(" Das Eis zerbricht und eine gewaltige Flutwelle verschlingt" - "die Region."); - /* es kann gut sein, das in der Region niemand �berlebt, also - * besser eine Globalmeldung */ - addmessage(0, u->faction, buf, MSG_EVENT, ML_IMPORTANT); + if (!fval(r->terrain, SEA_REGION)) { + /* not destroying the region, so it should be safe to make this a local + * message */ + message * msg; + const char * mtype; + if (r->terrain == newterrain(T_SWAMP) && terraform) { + mtype = "drought_effect_1"; + } else if (!terraform) { + mtype = "drought_effect_2"; + } else { + mtype = "drought_effect_3"; + } + msg = msg_message(mtype, "mage region", mage, r); + add_message(&r->msgs, msg); + msg_release(msg); + } else { + /* possible that all units here get killed so better to inform with a global + * message */ + message * msg = msg_message("drought_effect_4", "mage region", mage, r); + for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); + for (u = r->units; u; u = u->next) { + if (!fval(u->faction, FFL_SELECT)) { + fset(u->faction, FFL_SELECT); + add_message(&u->faction->msgs, msg); } } - } - if (!fval(mage->faction, FFL_SELECT)) { - ADDMSG(&mage->faction->msgs, msg_message( - "drought_effect", "mage region", mage, r)); + if (!fval(mage->faction, FFL_SELECT)) { + add_message(&mage->faction->msgs, msg); + } + msg_release(msg); } return cast_level; } @@ -2018,7 +2009,7 @@ sp_homestone(castorder *co) int cast_level = co->level; double force = co->force; variant effect; - + message * msg; if (!mage->building || mage->building->type != bt_find("castle")) { cmistake(mage, co->order, 197, MSG_MAGIC); return 0; @@ -2041,17 +2032,16 @@ sp_homestone(castorder *co) /* melden, 1x pro Partei in der Burg */ for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); + msg = msg_message("homestone_effect", "mage building", mage, mage->building); for (u = r->units; u; u = u->next) { if (!fval(u->faction, FFL_SELECT)) { fset(u->faction, FFL_SELECT); - if (u->building == mage->building) { - sprintf(buf, "Mit einem Ritual bindet %s die magischen Kr�fte " - "der Erde in die Mauern von %s", unitname(mage), - buildingname(mage->building)); - addmessage(r, u->faction, buf, MSG_EVENT, ML_INFO); + if (u->building == mage->building) { + r_addmessage(r, u->faction, msg); } } } + msg_release(msg); return cast_level; } @@ -2075,12 +2065,12 @@ static int sp_drought(castorder *co) { curse *c; - unit *u; region *r = co->rt; unit *mage = co->magician.u; int cast_level = co->level; double power = co->force; int duration = (int)power+1; + message * msg; if (fval(r->terrain, SEA_REGION) ) { cmistake(mage, co->order, 189, MSG_MAGIC); @@ -2089,20 +2079,9 @@ sp_drought(castorder *co) } /* melden, 1x pro Partei */ - for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - for(u = r->units; u; u = u->next ) { - if (!fval(u->faction, FFL_SELECT) ) { - fset(u->faction, FFL_SELECT); - sprintf(buf, "%s verflucht das Land, und eine D�rreperiode beginnt.", - cansee(u->faction, r, mage, 0) ? unitname(mage) : "Jemand"); - addmessage(r, u->faction, buf, MSG_EVENT, ML_INFO); - } - } - if (!fval(mage->faction, FFL_SELECT)) { - sprintf(buf, "%s verflucht das Land, und eine D�rreperiode beginnt.", - unitname(mage)); - addmessage(0, mage->faction, buf, MSG_MAGIC, ML_INFO); - } + msg = msg_message("drought_effect", "mage", mage); + r_addmessage(r, NULL, msg); + msg_release(msg); /* Wenn schon Duerre herrscht, dann setzen wir nur den Power-Level * hoch (evtl dauert dann die Duerre laenger). Ansonsten volle @@ -2218,13 +2197,14 @@ sp_ironkeeper(castorder *co) region *r = co->rt; unit *mage = co->magician.u; int cast_level = co->level; + message * msg; if (rterrain(r) != T_MOUNTAIN && rterrain(r) != T_GLACIER) { report_failure(mage, co->order); return 0; } - keeper = create_unit(r, mage->faction, 1, new_race[RC_IRONKEEPER], 0, "Bergw�chter", mage); + keeper = create_unit(r, mage->faction, 1, new_race[RC_IRONKEEPER], 0, NULL, mage); /*keeper->age = cast_level + 2;*/ guard(keeper, GUARD_MINING); @@ -2237,8 +2217,9 @@ sp_ironkeeper(castorder *co) add_trigger(&keeper->attribs, "timer", trigger_timeout(cast_level+2, tkill)); } - sprintf(buf, "%s beschw�rt einen Bergw�chter.", unitname(mage)); - addmessage(r, mage->faction, buf, MSG_MAGIC, ML_INFO); + msg = msg_message("summon_effect", "mage amount race", mage, 1, keeper->race); + r_addmessage(r, NULL, msg); + msg_release(msg); return cast_level; } @@ -2289,14 +2270,11 @@ sp_stormwinds(castorder *co) /* mit C_SHIP_NODRIFT haben wir kein Problem */ if (is_cursed(sh->attribs, C_SHIP_FLYING, 0) ) { - sprintf(buf, "Es ist zu gef�hrlich, diesen Zauber auf ein " - "fliegendes Schiff zu legen."); - addmessage(r, mage->faction, buf, MSG_MAGIC, ML_MISTAKE); + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_spell_on_flying_ship", "ship", sh)) continue; } if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0) ) { - sprintf(buf, "Auf %s befindet sich bereits ein Zauber", shipname(sh)); - addmessage(r, mage->faction, buf, MSG_MAGIC, ML_MISTAKE); + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_spell_on_ship_already", "ship", sh)) continue; } @@ -2355,6 +2333,7 @@ sp_earthquake(castorder *co) region *r = co->rt; unit *mage = co->magician.u; int cast_level = co->level; + message * msg; for (burg = r->buildings; burg; burg = burg->next) { if (burg->size == 0 ) @@ -2385,17 +2364,9 @@ sp_earthquake(castorder *co) } /* melden, 1x pro Partei */ - for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - for (u = r->units; u; u = u->next ) { - if (!fval(u->faction, FFL_SELECT) ) { - fset(u->faction, FFL_SELECT); - sprintf(buf, "%s l��t die Erde in %s erzittern.", - cansee(u->faction, r, mage, 0) ? unitname(mage) : "Jemand", - regionname(r, u->faction)); - - addmessage(r, u->faction, buf, MSG_EVENT, ML_INFO); - } - } + msg = msg_message("earthquake_effect", "mage region", mage, r); + r_addmessage(r, NULL, msg); + msg_release(msg); return cast_level; } @@ -2421,15 +2392,15 @@ patzer_peasantmob(castorder *co) if (r->land) { faction * f = findfaction(MONSTER_FACTION); const struct locale * lang = f->locale; + message * msg; anteil += rng_int() % 4; n = rpeasants(r) * anteil / 10; rsetpeasants(r, rpeasants(r) - n); assert(rpeasants(r) >= 0); - u = createunit(r, f, n, new_race[RC_PEASANT]); + u = create_unit(r, f, n, new_race[RC_PEASANT], 0, LOC(f->locale, "angry_mob"), NULL); fset(u, UFL_ISNEW); - set_string(&u->name, "Bauernmob"); /* guard(u, GUARD_ALL); hier zu fr�h! Befehl BEWACHE setzten */ addlist(&u->orders, parse_order(LOC(lang, keywords[K_GUARD]), lang)); set_order(&u->thisorder, default_order(lang)); @@ -2439,8 +2410,9 @@ patzer_peasantmob(castorder *co) a_add(&u->attribs, a); a_add(&u->attribs, make_hate(mage)); - sprintf(buf, "Ein Bauernmob erhebt sich und macht Jagd auf Schwarzmagier."); - addmessage(r, 0, buf, MSG_MAGIC, ML_INFO); + msg = msg_message("mob_warning", ""); + r_addmessage(r, NULL, msg); + msg_release(msg); } return; } @@ -2483,6 +2455,7 @@ sp_forest_fire(castorder *co) int cast_level = co->level; double probability; double percentage = (rng_int() % 8 + 1) * 0.1; /* 10 - 80% */ + message * msg; int vernichtet_schoesslinge = (int)(rtrees(r, 1) * percentage); int destroyed = (int)(rtrees(r, 2) * percentage); @@ -2498,26 +2471,12 @@ sp_forest_fire(castorder *co) /* melden, 1x pro Partei */ for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); + msg = msg_message("forestfire_effect", "mage region amount", mage, r, destroyed+vernichtet_schoesslinge); + r_addmessage(r, NULL, msg); + add_message(&mage->faction->msgs, msg); + msg_release(msg); - for(u = r->units; u; u = u->next ) { - if (!fval(u->faction, FFL_SELECT) ) { - fset(u->faction, FFL_SELECT); - sprintf(buf, "%s erzeugt eine verheerende Feuersbrunst. %d %s " - "den Flammen zum Opfer.", - cansee(u->faction, r, mage, 0) ? unitname(mage) : "Jemand", - destroyed, - destroyed == 1 ? "Baum fiel" : "B�ume fielen"); - addmessage(r, u->faction, buf, MSG_EVENT, ML_INFO); - } - } - if (!fval(mage->faction, FFL_SELECT)) { - sprintf(buf, "%s erzeugt eine verheerende Feuersbrunst. %d %s " - "den Flammen zum Opfer.", unitname(mage), destroyed+vernichtet_schoesslinge, - destroyed+vernichtet_schoesslinge == 1 ? "Baum fiel" : "B�ume fielen"); - addmessage(0, mage->faction, buf, MSG_MAGIC, ML_INFO); - } - - for(i = 0; i < MAXDIRECTIONS; i++ ) { + for (i = 0; i < MAXDIRECTIONS; i++ ) { nr = rconnect(r, i); assert(nr); destroyed = 0; @@ -2940,7 +2899,7 @@ sp_firewall(castorder *co) direction_t dir; region * r2; - dir = finddirection(pa->param[0]->data.s, mage->faction->locale); + dir = finddirection(pa->param[0]->data.xs, mage->faction->locale); if (dir<MAXDIRECTIONS && dir!=NODIRECTION) { r2 = rconnect(r, dir); } else { @@ -3067,7 +3026,7 @@ sp_wisps(castorder *co) double force = co->force; spellparameter *pa = co->par; - dir = finddirection(pa->param[0]->data.s, mage->faction->locale); + dir = finddirection(pa->param[0]->data.xs, mage->faction->locale); r2 = rconnect(r, dir); if (!r2) { @@ -3448,9 +3407,8 @@ sp_summonshadowlords(castorder *co) /* Bekommen Tarnung = Magie und Wahrnehmung 5. */ set_level(u, SK_STEALTH, get_level(mage, SK_MAGIC)); set_level(u, SK_OBSERVATION, 5); - sprintf(buf, "%s beschw�rt %d Schattenmeister.", - unitname(mage), (int)(force*force)); - addmessage(0, mage->faction, buf, MSG_MAGIC, ML_INFO); + + ADDMSG(&mage->faction->msgs, msg_message("summon_effect", "mage amount race", mage, 1, u->race)); return cast_level; } @@ -3469,7 +3427,6 @@ sp_summonshadowlords(castorder *co) static int sp_chaossuction(castorder *co) { - unit *u; region *rt; region *r = co->rt; unit *mage = co->magician.u; @@ -3497,25 +3454,8 @@ sp_chaossuction(castorder *co) "Wirbel"); new_border(&bt_chaosgate, r, rt); - freset(mage->faction, FFL_SELECT); - for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - for (u = r->units; u; u = u->next) { - if (!fval(u->faction, FFL_SELECT)) { - fset(u->faction, FFL_SELECT); - sprintf(buf, "%s �ffnete ein Chaostor.", - cansee(u->faction, r, mage, 0)?unitname(mage):"Jemand"); - addmessage(r, u->faction, buf, MSG_EVENT, ML_INFO); - } - } - for (u = rt->units; u; u = u->next) freset(u->faction, FFL_SELECT); - - for (u = rt->units; u; u = u->next) { - if (!fval(u->faction, FFL_SELECT)) { - fset(u->faction, FFL_SELECT); - addmessage(r, u->faction, "Ein Wirbel aus blendendem Licht erscheint.", - MSG_EVENT, ML_INFO); - } - } + add_message(&r->msgs, msg_message("chaosgate_effect_1", "mage", mage)); + add_message(&rt->msgs, msg_message("chaosgate_effect_2", "")); return cast_level; } @@ -3665,12 +3605,9 @@ sp_summonundead(castorder *co) int cast_level = co->level; int force = (int)(co->force*10); const race * race = new_race[RC_SKELETON]; - message * m = NULL; if (!r->land || deathcount(r) == 0) { - sprintf(buf, "%s in %s: In %s sind keine Gr�ber.", unitname(mage), - regionname(mage->region, mage->faction), regionname(r, mage->faction)); - addmessage(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE); + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_nograves", "target", r)); return 0; } @@ -3687,21 +3624,8 @@ sp_summonundead(castorder *co) u = create_unit(r, mage->faction, undead, race, 0, NULL, mage); make_undead_unit(u); - sprintf(buf, "%s erweckt %d Untote aus ihren Gr�bern.", - unitname(mage), undead); - addmessage(0, mage->faction, buf, MSG_MAGIC, ML_INFO); - - /* melden, 1x pro Partei */ - for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - - for (u = r->units; u; u = u->next ) { - if (!fval(u->faction, FFL_SELECT) ) { - if (!m) m = msg_message("summonundead_effect", "unit", mage); - fset(u->faction, FFL_SELECT); - add_message(&u->faction->msgs, m); - } - } - if (m) msg_release(m); + ADDMSG(&mage->faction->msgs, msg_message("summonundead_effect_1", "mage amount", mage, undead)); + ADDMSG(&r->msgs, msg_message("summonundead_effect_2", "mage", mage)); return cast_level; } @@ -4156,6 +4080,7 @@ sp_raisepeasantmob(castorder *co) int cast_level = co->level; double force = co->force; int duration = (int)force+1; + faction * monsters = findfaction(MONSTER_FACTION); anteil.i = 6 + (rng_int()%4); @@ -4171,9 +4096,8 @@ sp_raisepeasantmob(castorder *co) rsetpeasants(r, rpeasants(r) - n); assert(rpeasants(r) >= 0); - u = createunit(r, findfaction(MONSTER_FACTION), n, new_race[RC_PEASANT]); + u = create_unit(r, monsters, n, new_race[RC_PEASANT], 0, LOC(monsters->locale, "furious_mob"), NULL); fset(u, UFL_ISNEW); - set_string(&u->name, "Aufgebrachte Bauern"); guard(u, GUARD_ALL); a = a_new(&at_unitdissolve); a->data.ca[0] = 1; /* An rpeasants(r). */ @@ -4270,26 +4194,15 @@ sp_migranten(castorder *co) for (ord = target->orders; ord; ord = ord->next) { if (get_keyword(ord) == K_CONTACT) { - const char *c; - /* So weit, so gut. S->s ist also ein KONTAKTIERE. Nun gilt es, - * herauszufinden, wer kontaktiert wird. Das ist nicht trivial. - * Zuerst mu� der Parameter herausoperiert werden. */ - /* Leerzeichen finden */ + int kontakt; init_tokens(ord); skip_token(); - c = getstrtoken(); + kontakt = getid(); - /* Wenn ein Leerzeichen da ist, ist *c != 0 und zeigt auf das - * Leerzeichen. */ - - if (c!=NULL) { - int kontakt = atoi36(c); - - if (kontakt == mage->no) { - kontaktiert = 1; - break; - } + if (kontakt == mage->no) { + kontaktiert = 1; + break; } } } @@ -4445,7 +4358,7 @@ sp_recruit(castorder *co) rsetpeasants(r, maxp - n); } - u = create_unit(r, f, n, f->race, 0, (n == 1 ? "Bauer" : "Bauern"), mage); + u = create_unit(r, f, n, f->race, 0, LOC(f->locale,(n == 1 ? "peasant" : "peasant_p")), mage); set_order(&u->thisorder, default_order(f->locale)); ADDMSG(&mage->faction->msgs, msg_message("recruit_effect", "mage amount", mage, n)); @@ -4472,6 +4385,7 @@ sp_bigrecruit(castorder *co) int cast_level = co->level; double force = co->force; faction *f = mage->faction; + message * msg; if (maxp <= 0) { report_failure(mage, co->order); @@ -4491,12 +4405,13 @@ sp_bigrecruit(castorder *co) rsetpeasants(r, maxp - n); } - u = create_unit(r, f, n, f->race, 0, (n == 1 ? "Bauer" : "Bauern"), mage); + u = create_unit(r, f, n, f->race, 0, LOC(f->locale,(n == 1 ? "peasant" : "peasant_p")), mage); set_order(&u->thisorder, default_order(f->locale)); - sprintf(buf, "%s konnte %d %s anwerben", unitname(mage), n, - n == 1 ? "Bauer" : "Bauern"); - addmessage(r, mage->faction, buf, MSG_MAGIC, ML_INFO); + msg = msg_message("recruit_effect", "mage amount", mage, n); + r_addmessage(r, mage->faction, msg); + msg_release(msg); + return cast_level; } @@ -4561,8 +4476,7 @@ sp_pump(castorder *co) addmessage(r, mage->faction, buf, MSG_MAGIC, ML_INFO); } - u = createunit(rt, mage->faction, RS_FARVISION, new_race[RC_SPELL]); - set_string(&u->name, "Zauber: Aushorchen"); + u = create_unit(rt, mage->faction, RS_FARVISION, new_race[RC_SPELL], 0, (const xmlChar*)"spell/pump", NULL); u->age = 2; set_level(u, SK_OBSERVATION, eff_skill(target, SK_OBSERVATION, u->region)); @@ -4999,7 +4913,7 @@ sp_icastle(castorder *co) spellparameter *pa = co->par; icastle_data * data; - if ((type=findbuildingtype(pa->param[0]->data.s, mage->faction->locale)) == NULL) { + if ((type=findbuildingtype(pa->param[0]->data.xs, mage->faction->locale)) == NULL) { type = bt_find("castle"); } @@ -5070,7 +4984,7 @@ sp_illusionary_shapeshift(castorder *co) u = pa->param[0]->data.u; - rc = findrace(pa->param[1]->data.s, mage->faction->locale); + rc = findrace(pa->param[1]->data.xs, mage->faction->locale); if (rc == NULL) { cmistake(mage, co->order, 202, MSG_MAGIC); return 0; @@ -5641,7 +5555,7 @@ sp_resist_magic_bonus(castorder *co) /* "ZAUBERE [STUFE n] \"Astraler Weg\" <Einheit-Nr> [<Einheit-Nr> ...]", * * Parameter: - * pa->param[0]->data.s + * pa->param[0]->data.xs */ int sp_enterastral(castorder *co) @@ -6480,7 +6394,7 @@ sp_movecastle(castorder *co) if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; b = pa->param[0]->data.b; - dir = finddirection(pa->param[1]->data.s, mage->faction->locale); + dir = finddirection(pa->param[1]->data.xs, mage->faction->locale); if (dir == NODIRECTION) { /* Die Richtung wurde nicht erkannt */ @@ -6988,7 +6902,7 @@ sp_break_curse(castorder *co) obj = pa->param[0]->typ; - c = findcurse(atoi36(pa->param[1]->data.s)); + c = findcurse(atoi36(pa->param[1]->data.xs)); if (!c) { /* Es wurde kein Ziel gefunden */ ADDMSG(&mage->faction->msgs, msg_message( @@ -7046,7 +6960,7 @@ sp_break_curse(castorder *co) ADDMSG(&mage->faction->msgs, msg_message( "destroy_curse_effect", "unit region command id target", - mage, mage->region, co->order, strdup(pa->param[1]->data.s), + mage, mage->region, co->order, strdup(pa->param[1]->data.xs), strdup(ts))); } else { ADDMSG(&mage->faction->msgs, msg_message( diff --git a/src/common/triggers/unitmessage.c b/src/common/triggers/unitmessage.c index d7ac44f34..b4d2190ee 100644 --- a/src/common/triggers/unitmessage.c +++ b/src/common/triggers/unitmessage.c @@ -18,6 +18,7 @@ /* kernel includes */ #include <kernel/unit.h> +#include <kernel/faction.h> /* util includes */ #include <util/attrib.h> @@ -25,6 +26,7 @@ #include <util/event.h> #include <util/base36.h> #include <util/goodies.h> +#include <util/language.h> /* ansi includes */ #include <stdio.h> @@ -65,9 +67,11 @@ unitmessage_handle(trigger * t, void * data) */ unitmessage_data * td = (unitmessage_data*)t->data.v; if (td->target!=NULL) { - addmessage(td->target->region, td->target->faction, td->string, td->type, td->level); - } else + struct faction * f = td->target->faction; + addmessage(td->target->region, f, LOC(f->locale, td->string), td->type, td->level); + } else { log_error(("could not perform unitmessage::handle()\n")); + } unused(data); return 0; } diff --git a/src/common/util/Jamfile b/src/common/util/Jamfile index adfb469b9..5f3694951 100644 --- a/src/common/util/Jamfile +++ b/src/common/util/Jamfile @@ -32,6 +32,7 @@ SOURCES = strncpy.c translation.c umlaut.c + unicode.c vmap.c vset.c windir.c diff --git a/src/common/util/language.c b/src/common/util/language.c index 610a1bb92..fd97221f2 100644 --- a/src/common/util/language.c +++ b/src/common/util/language.c @@ -76,7 +76,7 @@ debug_language(const char * log) s_logfile = strdup(log); } -const char * +const xmlChar * locale_getstring(const locale * lang, const char * key) { unsigned int hkey = hashstring(key); @@ -102,7 +102,7 @@ locale_getstring(const locale * lang, const char * key) return NULL; } -const char * +const xmlChar * locale_string(const locale * lang, const char * key) { if (key!=NULL) { @@ -111,7 +111,7 @@ locale_string(const locale * lang, const char * key) struct locale_str * find; if (key == NULL || *key==0) return NULL; - if (lang == NULL) return key; + if (lang == NULL) return BAD_CAST key; find = lang->strings[id]; while (find) { if (find->hashkey == hkey) { @@ -125,7 +125,7 @@ locale_string(const locale * lang, const char * key) find = find->nexthash; } if (!find) { - const char * s = key; + const xmlChar * s = BAD_CAST key; log_warning(("missing translation for \"%s\" in locale %s\n", key, lang->name)); if (lang!=default_locale) { s = locale_string(default_locale, key); @@ -146,7 +146,7 @@ locale_string(const locale * lang, const char * key) } void -locale_setstring(locale * lang, const char * key, const char * value) +locale_setstring(locale * lang, const char * key, const xmlChar * value) { unsigned int hkey = hashstring(key); unsigned int id = hkey & (SMAXHASH-1); @@ -163,13 +163,13 @@ locale_setstring(locale * lang, const char * key, const char * value) lang->strings[id] = find; find->hashkey = hkey; find->key = strdup(key); - find->str = strdup(value); + find->str = xmlStrdup(value); } else { - if (strcmp(find->str, value)!=0) { + if (xmlStrcmp(find->str, value)!=0) { log_error(("Duplicate key %s for '%s' and '%s'\n", key, value, find->str)); } - assert(!strcmp(find->str, value) || !"duplicate string for key"); + assert(!xmlStrcmp(find->str, value) || !"duplicate string for key"); } } @@ -181,24 +181,23 @@ locale_name(const locale * lang) } const char * -reverse_lookup(const locale * lang, const char * str) +reverse_lookup(const locale * lang, const xmlChar * str) { int i; assert(lang); - if (strlen(str)) { + if (xmlStrlen(str)) { if (lang!=NULL) { for (i=0;i!=SMAXHASH;++i) { struct locale_str * ls; for (ls=lang->strings[i];ls;ls=ls->nexthash) { - if (strcasecmp(ls->key, str)==0) return ls->key; - if (strcasecmp(ls->str, str)==0) return ls->key; + if (xmlStrcasecmp(ls->str, str)==0) return ls->key; } } } log_error(("could not do a reverse_lookup for \"%s\" in locale %s\n", str, lang->name)); assert(!"failed to do a reverse_lookup"); } - return str; + return NULL; } char * diff --git a/src/common/util/language.h b/src/common/util/language.h index 5c60e36b6..6266b42cf 100644 --- a/src/common/util/language.h +++ b/src/common/util/language.h @@ -18,19 +18,20 @@ extern "C" { #endif struct locale; +typedef unsigned char xmlChar; /** managing multiple locales: **/ extern struct locale * find_locale(const char * name); extern struct locale * make_locale(const char * key); /** operations on locales: **/ -extern void locale_setstring(struct locale * lang, const char * key, const char * value); -extern const char * locale_getstring(const struct locale * lang, const char * key); -extern const char * locale_string(const struct locale * lang, const char * key); /* does fallback */ +extern void locale_setstring(struct locale * lang, const char * key, const xmlChar * value); +extern const xmlChar * locale_getstring(const struct locale * lang, const char * key); +extern const xmlChar * locale_string(const struct locale * lang, const char * key); /* does fallback */ extern unsigned int locale_hashkey(const struct locale * lang); extern const char * locale_name(const struct locale * lang); -extern const char * reverse_lookup(const struct locale * lang, const char * str); +extern const char * reverse_lookup(const struct locale * lang, const xmlChar * str); extern const char * mkname(const char * namespc, const char * key); extern char * mkname_buf(const char * namespc, const char * key, char * buffer); @@ -50,6 +51,8 @@ enum { UT_OPTIONS, UT_DIRECTIONS, UT_ARCHETYPES, + UT_MAGIC, + UT_TERRAINS, UT_MAX }; diff --git a/src/common/util/language_struct.h b/src/common/util/language_struct.h index 1f09a071b..7cb84cc16 100644 --- a/src/common/util/language_struct.h +++ b/src/common/util/language_struct.h @@ -10,7 +10,7 @@ typedef struct locale_str { unsigned int hashkey; struct locale_str * nexthash; - char * str; + xmlChar * str; char * key; } locale_str; diff --git a/src/common/util/nrmessage.c b/src/common/util/nrmessage.c index 84b18c982..47097b368 100644 --- a/src/common/util/nrmessage.c +++ b/src/common/util/nrmessage.c @@ -131,14 +131,14 @@ nrt_register(const struct message_type * mtype, const struct locale * lang, cons } size_t -nr_render(const struct message * msg, const struct locale * lang, char * buffer, size_t size, const void * userdata) +nr_render(const struct message * msg, const struct locale * lang, xmlChar * buffer, size_t size, const void * userdata) { struct nrmessage_type * nrt = nrt_find(lang, msg->type); if (nrt) { const char * m = translate(nrt->string, userdata, nrt->vars, msg->parameters); if (m) { - return strlcpy(buffer, m, size); + return strlcpy((char*)buffer, m, size); } else { log_error(("Couldn't render message %s\n", nrt->mtype->name)); } diff --git a/src/common/util/nrmessage.h b/src/common/util/nrmessage.h index d9a931570..89668998e 100644 --- a/src/common/util/nrmessage.h +++ b/src/common/util/nrmessage.h @@ -37,7 +37,7 @@ extern const char * nrt_string(const struct nrmessage_type *type); extern const char * nrt_section(const struct nrmessage_type * mt); extern size_t nr_render(const struct message * msg, const struct locale * lang, - char * buffer, size_t size, const void * userdata); + xmlChar * buffer, size_t size, const void * userdata); extern int nr_level(const struct message *msg); extern const char * nr_section(const struct message *msg); diff --git a/src/common/util/parser.c b/src/common/util/parser.c index 881664e90..f1bd63817 100644 --- a/src/common/util/parser.c +++ b/src/common/util/parser.c @@ -1,30 +1,59 @@ #include <config.h> #include "parser.h" +#include "unicode.h" +#include "log.h" #include <assert.h> #include <ctype.h> +#include <memory.h> #define SPACE_REPLACEMENT '~' #define ESCAPE_CHAR '\\' #define MAXTOKENSIZE 8192 typedef struct parser_state { - const unsigned char *current_token; - char * current_cmd; + const xmlChar *current_token; + xmlChar * current_cmd; struct parser_state * next; } parser_state; static parser_state * state; +static int +eatwhitespace_c(const xmlChar ** str) +{ + int ret; + wint_t ucs; + size_t len; + + /* skip over potential whitespace */ + for (;;) { + xmlChar utf8_character = (*str)[0]; + if (utf8_character <= 0x7F) { + if (!isspace(utf8_character)) break; + ++*str; + } else { + ret = unicode_utf8_to_ucs4(&ucs, *str, &len); + if (ret!=0) { + log_warning(("illegal character sequence in UTF8 string: %s\n", *str)); + return ret; + } + if (!iswspace(ucs)) break; + *str+=len; + } + } + return 0; +} + void -init_tokens_str(const char * initstr, char * cmd) +init_tokens_str(const xmlChar * initstr, xmlChar * cmd) { if (state==NULL) { state = malloc(sizeof(parser_state)); } else if (state->current_cmd) free(state->current_cmd); state->current_cmd = cmd; - state->current_token = (const unsigned char *)initstr; + state->current_token = (const xmlChar *)initstr; } void @@ -49,7 +78,7 @@ parser_popstate(void) boolean parser_end(void) { - while (isspace(*state->current_token)) ++state->current_token; + eatwhitespace_c(&state->current_token); return *state->current_token == 0; } @@ -57,73 +86,107 @@ void skip_token(void) { char quotechar = 0; + eatwhitespace_c(&state->current_token); - while (isspace(*state->current_token)) ++state->current_token; while (*state->current_token) { - if (isspace(*state->current_token) && quotechar==0) { + wint_t ucs; + size_t len; + + xmlChar utf8_character = state->current_token[0]; + if (utf8_character <= 0x7F) { + ucs = utf8_character; + ++state->current_token; + } else { + int ret = unicode_utf8_to_ucs4(&ucs, state->current_token, &len); + if (ret==0) { + state->current_token+=len; + } else { + log_warning(("illegal character sequence in UTF8 string: %s\n", state->current_token)); + } + } + if (iswspace(ucs) && quotechar==0) { return; } else { - switch(*state->current_token) { + switch(utf8_character) { case '"': case '\'': - if (*state->current_token==quotechar) return; - quotechar = *state->current_token; + if (utf8_character==quotechar) return; + quotechar = utf8_character; break; case ESCAPE_CHAR: ++state->current_token; break; } } - ++state->current_token; } } -const char * -parse_token(const char ** str) +const xmlChar * +parse_token(const xmlChar ** str) { - static char lbuf[MAXTOKENSIZE]; - char * cursor = lbuf; + static xmlChar lbuf[MAXTOKENSIZE]; + xmlChar * cursor = lbuf; char quotechar = 0; boolean escape = false; - const unsigned char * ctoken = (const unsigned char*)*str; + const xmlChar * ctoken = *str; assert(ctoken); - while (isspace(*ctoken)) ++ctoken; + eatwhitespace_c(&ctoken); while (*ctoken && cursor-lbuf < MAXTOKENSIZE-1) { + wint_t ucs; + size_t len; + boolean copy = false; + + xmlChar utf8_character = *ctoken; + if (utf8_character <= 0x7F) { + ucs = utf8_character; + len = 1; + } else { + int ret = unicode_utf8_to_ucs4(&ucs, ctoken, &len); + if (ret!=0) { + log_warning(("illegal character sequence in UTF8 string: %s\n", ctoken)); + break; + } + } if (escape) { - *cursor++ = *ctoken++; - } else if (isspace(*ctoken)) { + copy = true; + } else if (iswspace(ucs)) { if (quotechar==0) break; - *cursor++ = *ctoken++; - } else if (*ctoken=='"' || *ctoken=='\'') { - if (*ctoken==quotechar) { + copy = true; + } else if (utf8_character=='"' || utf8_character=='\'') { + if (utf8_character==quotechar) { ++ctoken; break; } else if (quotechar==0) { - quotechar = *ctoken; + quotechar = utf8_character; ++ctoken; } else { *cursor++ = *ctoken++; } - } else if (*ctoken==SPACE_REPLACEMENT) { + } else if (utf8_character==SPACE_REPLACEMENT) { *cursor++ = ' '; ++ctoken; - } else if (*ctoken==ESCAPE_CHAR) { + } else if (utf8_character==ESCAPE_CHAR) { escape = true; ++ctoken; } else { - *cursor++ = *ctoken++; + copy = true; + } + if (copy) { + memcpy(cursor, ctoken, len); + cursor+=len; + ctoken+=len; } } *cursor = '\0'; - *str = (const char *)ctoken; + *str = ctoken; return lbuf; } -const char * +const xmlChar * getstrtoken(void) { - return parse_token((const char**)&state->current_token); + return parse_token((const xmlChar**)&state->current_token); } diff --git a/src/common/util/parser.h b/src/common/util/parser.h index fecb5ff9f..27330cf5e 100644 --- a/src/common/util/parser.h +++ b/src/common/util/parser.h @@ -14,13 +14,13 @@ extern "C" { #endif -extern void init_tokens_str(const char * initstr, char * cmd); /* initialize token parsing, take ownership of cmd */ +extern void init_tokens_str(const xmlChar * initstr, xmlChar * cmd); /* initialize token parsing, take ownership of cmd */ extern void skip_token(void); -extern const char * parse_token(const char ** str); +extern const xmlChar * parse_token(const xmlChar ** str); extern void parser_pushstate(void); extern void parser_popstate(void); extern boolean parser_end(void); -extern const char *getstrtoken(void); +extern const xmlChar *getstrtoken(void); #ifdef __cplusplus } diff --git a/src/common/util/umlaut.c b/src/common/util/umlaut.c index d35219eff..442dcdd8c 100644 --- a/src/common/util/umlaut.c +++ b/src/common/util/umlaut.c @@ -1,162 +1,162 @@ /* vi: set ts=2: - * - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea-pbem.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * based on: - * - * Atlantis v1.0 13 September 1993 Copyright 1993 by Russell Wallace - * Atlantis v1.7 Copyright 1996 by Alex Schr�der - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - * This program may not be sold or used commercially without prior written - * permission from the authors. - */ +* +* +* Eressea PB(E)M host Copyright (C) 1998-2003 +* Christian Schlittchen (corwin@amber.kn-bremen.de) +* Katja Zedel (katze@felidae.kn-bremen.de) +* Henning Peters (faroul@beyond.kn-bremen.de) +* Enno Rehling (enno@eressea-pbem.de) +* Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) +* +* based on: +* +* Atlantis v1.0 13 September 1993 Copyright 1993 by Russell Wallace +* Atlantis v1.7 Copyright 1996 by Alex Schr�der +* +* This program may not be used, modified or distributed without +* prior permission by the authors of Eressea. +* This program may not be sold or used commercially without prior written +* permission from the authors. +*/ #include <config.h> #include "umlaut.h" +#include "log.h" +#include "unicode.h" + #include <ctype.h> #include <stdlib.h> #include <string.h> #include <assert.h> typedef struct tref { - struct tref * nexthash; - char c; - struct tnode * node; + struct tref * nexthash; + wint_t ucs; + struct tnode * node; } tref; #define LEAF 1 /* leaf node for a word. always matches */ #define SHARED 2 /* at least two words share the node */ void -addtoken(tnode * root, const char* str, variant id) +addtoken(tnode * root, const xmlChar * str, variant id) { - static struct replace { - char c; - const char * str; - } replace[] = { - {'�', "ae"}, - {'�', "ae"}, - {'�', "oe"}, - {'�', "oe"}, - {'�', "ue"}, - {'�', "ue"}, - {'�', "ss"}, - { 0, 0 } - }; - if (!*str) { - root->id = id; - root->flags |= LEAF; - } else { - tref * next; - int index, i = 0; - register char c = *str; - if (c<'a' || c>'z') c = (char)tolower((unsigned char)c); -#if NODEHASHSIZE == 8 - index = c & 7; -#else - index = ((unsigned char)c) % NODEHASHSIZE; -#endif - next = root->next[index]; - if (!(root->flags & LEAF)) root->id = id; - while (next && next->c != c) next = next->nexthash; - if (!next) { - tref * ref; - char u = (char)toupper((unsigned char)c); - tnode * node = calloc(1, sizeof(tnode)); + static struct replace { + wint_t ucs; + const char str[3]; + } replace[] = { + /* match lower-case (!) umlauts and others to transcriptions */ + { 228, "AE"}, + { 246, "OE"}, + { 252, "UE"}, + { 223, "SS"}, + { 230, "AE"}, + { 248, "OE"}, + { 229, "AA"}, + { 0, 0 } + }; + + if (!*str) { + root->id = id; + root->flags |= LEAF; + } else { + tref * next; + int ret, index, i = 0; + wint_t ucs, lcs; + size_t len; + + ret = unicode_utf8_to_ucs4(&ucs, str, &len); + assert(ret==0 || !"invalid utf8 string"); + lcs = ucs; - ref = malloc(sizeof(tref)); - ref->c = c; - ref->node = node; - ref->nexthash=root->next[index]; - root->next[index] = ref; - - if (u!=c) { #if NODEHASHSIZE == 8 - index = u & 7; + index = ucs & 7; #else - index = ((unsigned char)u) % NODEHASHSIZE; + index = ucs % NODEHASHSIZE; #endif - ref = malloc(sizeof(tref)); - ref->c = u; - ref->node = node; - ref->nexthash = root->next[index]; - root->next[index] = ref; - } - next=ref; - } else { - next->node->flags |= SHARED; - if ((next->node->flags & LEAF) == 0) next->node->id.v = NULL; /* why?*/ - } - addtoken(next->node, str+1, id); - while (replace[i].str) { - if (*str==replace[i].c) { - char zText[1024]; - strcat(strcpy(zText, replace[i].str), str+1); - addtoken(root, zText, id); - break; - } - ++i; - } - } + next = root->next[index]; + if (!(root->flags & LEAF)) root->id = id; + while (next && next->ucs != ucs) next = next->nexthash; + if (!next) { + tref * ref; + tnode * node = calloc(1, sizeof(tnode)); + + if (ucs<'a' || ucs>'z') { + lcs = towlower(ucs); + } + if (ucs==lcs) { + ucs = towupper(ucs); + } + + ref = malloc(sizeof(tref)); + ref->ucs = ucs; + ref->node = node; + ref->nexthash=root->next[index]; + root->next[index] = ref; + + /* try lower/upper casing the character, and try again */ + if (ucs!=lcs) { +#if NODEHASHSIZE == 8 + index = lcs & 7; +#else + index = lcs % NODEHASHSIZE; +#endif + ref = malloc(sizeof(tref)); + ref->ucs = lcs; + ref->node = node; + ref->nexthash = root->next[index]; + root->next[index] = ref; + } + next=ref; + } else { + next->node->flags |= SHARED; + if ((next->node->flags & LEAF) == 0) next->node->id.v = NULL; /* why?*/ + } + addtoken(next->node, str+len, id); + while (replace[i].str[0]) { + if (lcs==replace[i].ucs) { + xmlChar zText[1024]; + memcpy(zText, replace[i].str, 3); + strcpy((char*)zText+2, (const char*)str+len); + addtoken(root, zText, id); + break; + } + ++i; + } + } } int -findtoken(const tnode * tk, const char * str, variant* result) +findtoken(const tnode * tk, const xmlChar * str, variant* result) { - if (!str || *str==0) return E_TOK_NOMATCH; + if (!str || *str==0) return E_TOK_NOMATCH; - do { - int index; - const tref * ref; - char c = *str; + do { + int index; + const tref * ref; + wint_t ucs; + size_t len; + int ret = unicode_utf8_to_ucs4(&ucs, str, &len); + if (ret!=0) { + /* encoding is broken. youch */ + return E_TOK_NOMATCH; + } #if NODEHASHSIZE == 8 - index = c & 7; + index = ucs & 7; #else - index = ((unsigned char)c) % NODEHASHSIZE; + index = ucs % NODEHASHSIZE; #endif - ref = tk->next[index]; - while (ref && ref->c!=c) ref = ref->nexthash; - ++str; - if (!ref) return E_TOK_NOMATCH; - tk = ref->node; - } while (*str); - if (tk) { - *result = tk->id; - return E_TOK_SUCCESS; - } - return E_TOK_NOMATCH; + ref = tk->next[index]; + while (ref && ref->ucs!=ucs) ref = ref->nexthash; + str+=len; + if (!ref) return E_TOK_NOMATCH; + tk = ref->node; + } while (*str); + if (tk) { + *result = tk->id; + return E_TOK_SUCCESS; + } + return E_TOK_NOMATCH; } - -#ifdef TEST_UMLAUT -#include <stdio.h> -tnode root; - -int -main(int argc, char ** argv) -{ - char buf[1024]; - int i = 0; - for (;;) { - int k; - fgets(buf, sizeof(buf), stdin); - buf[strlen(buf)-1]=0; - if (findtoken(&root, buf, (void**)&k)==0) { - printf("%s returned %d\n", buf, k); - } else { - addtoken(&root, buf, (void*)++i); - printf("added %s=%d\n", buf, i); - } - } - return 0; -} -#endif diff --git a/src/common/util/umlaut.h b/src/common/util/umlaut.h index 09d4e8c04..5f3ef7746 100644 --- a/src/common/util/umlaut.h +++ b/src/common/util/umlaut.h @@ -32,8 +32,8 @@ typedef struct tnode { variant id; } tnode; -int findtoken(const struct tnode * tk, const char * str, variant* result); -void addtoken(struct tnode * root, const char* str, variant id); +int findtoken(const struct tnode * tk, const xmlChar * str, variant* result); +void addtoken(struct tnode * root, const xmlChar* str, variant id); typedef struct local_names { struct local_names * next; diff --git a/src/common/util/unicode.h b/src/common/util/unicode.h index 1fadd0a91..aa404a25e 100644 --- a/src/common/util/unicode.h +++ b/src/common/util/unicode.h @@ -20,7 +20,6 @@ extern "C" { #endif #include <wchar.h> -#include <libxml/xmlstring.h> extern int unicode_utf8_to_ucs4(wint_t *ucs4_character, const xmlChar *utf8_string, size_t *length); diff --git a/src/common/util/util.vcproj b/src/common/util/util.vcproj index 1bfa97bab..9522f6eab 100644 --- a/src/common/util/util.vcproj +++ b/src/common/util/util.vcproj @@ -283,9 +283,6 @@ <File RelativePath=".\bsdstring.h"> </File> - <File - RelativePath=".\command.h"> - </File> <File RelativePath=".\crmessage.h"> </File> @@ -319,6 +316,9 @@ <File RelativePath=".\nrmessage.h"> </File> + <File + RelativePath=".\parser.h"> + </File> <File RelativePath=".\rand.h"> </File> @@ -403,7 +403,7 @@ RelativePath=".\base36.c"> </File> <File - RelativePath=".\command.c"> + RelativePath="..\..\config.h"> </File> <File RelativePath=".\crmessage.c"> @@ -417,6 +417,9 @@ <File RelativePath=".\event.c"> </File> + <File + RelativePath=".\filereader.c"> + </File> <File RelativePath=".\functions.c"> </File> @@ -447,6 +450,9 @@ <File RelativePath=".\nrmessage.c"> </File> + <File + RelativePath=".\parser.c"> + </File> <File RelativePath=".\rand.c"> </File> @@ -462,6 +468,12 @@ <File RelativePath=".\umlaut.c"> </File> + <File + RelativePath=".\unicode.c"> + </File> + <File + RelativePath=".\unicode.h"> + </File> <File RelativePath=".\vmap.c"> </File> diff --git a/src/config.h b/src/config.h index ecd3bd9b8..c2b542bdf 100644 --- a/src/config.h +++ b/src/config.h @@ -253,5 +253,7 @@ extern char * strdup(const char *s); # define INLINE_FUNCTION #endif +#include <libxml/xmlstring.h> + #endif diff --git a/src/eressea.sln b/src/eressea.sln index 9edd334e7..0d34374d9 100644 --- a/src/eressea.sln +++ b/src/eressea.sln @@ -81,12 +81,19 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmtool", "eressea\gmtool.vc {4C837BEC-A428-4287-84B3-8F8F9DE7FA00} = {4C837BEC-A428-4287-84B3-8F8F9DE7FA00} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test\test.vcproj", "{9569C30D-742F-4F95-9C5D-BBF2B69C0727}" + ProjectSection(ProjectDependencies) = postProject + {1D80D05F-BCF5-4971-8F06-D9581FD3B1F4} = {1D80D05F-BCF5-4971-8F06-D9581FD3B1F4} + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Profile = Profile Release = Release EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {330712B5-8B27-4B17-B3CF-7A02CC0F93C3}.Debug.ActiveCfg = Debug|Win32 {330712B5-8B27-4B17-B3CF-7A02CC0F93C3}.Debug.Build.0 = Debug|Win32 @@ -160,6 +167,12 @@ Global {57BA2AEE-5C65-4839-9294-C0FA2915A06C}.Profile.Build.0 = Profile|Win32 {57BA2AEE-5C65-4839-9294-C0FA2915A06C}.Release.ActiveCfg = Release|Win32 {57BA2AEE-5C65-4839-9294-C0FA2915A06C}.Release.Build.0 = Release|Win32 + {9569C30D-742F-4F95-9C5D-BBF2B69C0727}.Debug.ActiveCfg = Debug|Win32 + {9569C30D-742F-4F95-9C5D-BBF2B69C0727}.Debug.Build.0 = Debug|Win32 + {9569C30D-742F-4F95-9C5D-BBF2B69C0727}.Profile.ActiveCfg = Release|Win32 + {9569C30D-742F-4F95-9C5D-BBF2B69C0727}.Profile.Build.0 = Release|Win32 + {9569C30D-742F-4F95-9C5D-BBF2B69C0727}.Release.ActiveCfg = Release|Win32 + {9569C30D-742F-4F95-9C5D-BBF2B69C0727}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/src/eressea/korrektur.c b/src/eressea/korrektur.c index 7d3048820..84966ea95 100644 --- a/src/eressea/korrektur.c +++ b/src/eressea/korrektur.c @@ -251,9 +251,7 @@ no_teurefremde(boolean convert) if (convert) { u->race = f->race; u->irace = f->race; - sprintf(buf, "Die G�tter segnen %s mit der richtigen Rasse", - unitname(u)); - addmessage(0, u->faction, buf, MSG_MESSAGE, ML_IMPORTANT); + ADDMSG(&u->faction->msgs, msg_message("migrant_conversion", "unit", u)); } } } @@ -391,7 +389,7 @@ fix_icastles(void) a = a_add(&b->attribs, a_new(&at_icastle)); } if (b->type!=bt_find("illusion")) { - /* geb�udetyp war falsch */ + /* wrong building type */ btype = b->type; b->type = bt_find("illusion"); } @@ -405,7 +403,7 @@ fix_icastles(void) data->type = btype; } if (data->building!=b) { - /* r�ckw�rtszeiger auf das geb�ude reparieren */ + /* fix reverse pointer to the building */ data->building=b; } } @@ -715,28 +713,6 @@ fix_astralplane(void) return 0; } -static int -warn_password(void) -{ - faction * f = factions; - while (f) { - boolean pwok = true; - const char * c = f->passw; - while (*c) { - if (!isalnum((unsigned char)*c)) pwok = false; - c++; - } - if (pwok == false) { - ADDMSG(&f->msgs, msg_message("msg_errors", "string", - "Dein Passwort enth�lt Zeichen, die bei der Nachsendung " - "von Reports Probleme bereiten k�nnen. Bitte w�hle ein neues " - "Passwort, bevorzugt nur aus Buchstaben und Zahlen bestehend.")); - } - f = f->next; - } - return 0; -} - extern border *borders[]; static void @@ -973,7 +949,6 @@ korrektur(void) } fix_allies(); /* fix_unitrefs(); */ - warn_password(); fix_road_borders(); if (turn>1000) curse_emptiness(); /*** disabled ***/ /* seems something fishy is going on, do this just diff --git a/src/eressea/lua/faction.cpp b/src/eressea/lua/faction.cpp index 38aac4c33..b9ed5382b 100644 --- a/src/eressea/lua/faction.cpp +++ b/src/eressea/lua/faction.cpp @@ -175,8 +175,8 @@ faction_additem(faction& f, const char * iname, int number) static void faction_addnotice(faction& f, const char * str) { - str = LOC(f.locale, str); - ADDMSG(&f.msgs, msg_message("msg_event", "string", str)); + const xmlChar * loc = LOC(f.locale, str); + ADDMSG(&f.msgs, msg_message("msg_event", "string", loc)); } static const char * diff --git a/src/eressea/main.c b/src/eressea/main.c index 86204c8e6..51eb94d51 100644 --- a/src/eressea/main.c +++ b/src/eressea/main.c @@ -253,7 +253,7 @@ processturn(char *filename) #endif begin = make_summary(); turn++; - if ((i=readorders(filename))!=0) return i; + if ((i=readorders(filename, "ISO-8859-1"))!=0) return i; if (!nomonsters) { if (turn == 0) rng_init((int)time(0)); else rng_init(turn); diff --git a/src/res/de/strings.xml b/src/res/de/strings.xml index 24d298a9e..ea7e5834e 100644 --- a/src/res/de/strings.xml +++ b/src/res/de/strings.xml @@ -6823,4 +6823,136 @@ <text locale="de"> und </text> <text locale="en"> and </text> </string> + + <string name="villagers"> + <text locale="de">Dorfbewohner</text> + <text locale="en">Villagers</text> + </string> + + <string name="angry_mob"> + <text locale="de">Bauernmob</text> + <text locale="en">Angry mob</text> + </string> + + <string name="furious_mob"> + <text locale="de">Aufgebrachte Bauern</text> + <text locale="en">Furious peasants</text> + </string> + + <string name="random_plain_men"> + <text locale="de">S�ldner</text> + <text locale="en">Mercenaries</text> + </string> + + <string name="random_swamp_men"> + <text locale="de">Sumpfbewohner</text> + <text locale="en">Swamp people</text> + </string> + + <string name="random_forest_men"> + <text locale="de">Waldbewohner</text> + <text locale="en">Woodsmen</text> + </string> + + <string name="random_desert_men"> + <text locale="de">Nomaden</text> + <text locale="en">Nomads</text> + </string> + + <string name="random_glacier_men"> + <text locale="de">Eisleute</text> + <text locale="en">Ice people</text> + </string> + + <string name="random_mountain_men"> + <text locale="de">Bergbewohner</text> + <text locale="en">Mountain people</text> + </string> + + <string name="manual_title_magic"> + <text locale="de">Magie der Elemente</text> + <text locale="en">Magic of the Elements</text> + </string> + + <string name="manual_title_weaponsmithing"> + <text locale="de">Schwerter, Armbr�ste, Langb�gen</text> + <text locale="en">Swords, Crossbows and Longbows</text> + </string> + + <string name="manual_title_tactics"> + <text locale="de">Gorms Almanach der Rationellen Kriegsf�hrung</text> + <text locale="en">Gorm's Almanach of Rational War</text> + </string> + + <string name="manual_title_shipcraft"> + <text locale="de">Katamarane, Koggen, Karavellen</text> + <text locale="en">The dragonship, the caravell and the longboat</text> + </string> + + <string name="manual_title_sailing"> + <text locale="de">Wege der Sterne</text> + <text locale="en">Ways of the Start</text> + </string> + + <string name="manual_title_herbalism"> + <text locale="de">Nadishahs Kleine Gift- und Kr�uterkunde</text> + <text locale="en">Nadishah's collected lore on poisonous and beneficial herbs</text> + </string> + + <string name="manual_title_alchemy"> + <text locale="de">Mandricks Kompendium der Alchemie</text> + <text locale="en">Mandrick's alchemistic compendium</text> + </string> + + <string name="manual_title_building"> + <text locale="de">Die Konstruktion der Burgen und Schl�sser von Zentralandune</text> + </string> + + <string name="manual_title_armorer"> + <text locale="de">Die Esse</text> + </string> + + <string name="manual_title_mining"> + <text locale="de">�ber die Gewinnung von Erzen</text> + </string> + + <string name="manual_title_entertainment"> + <text locale="de">Barinions Lieder, eine Einf�hrung f�r Unbedarfte</text> + </string> + + <string name="manual_location_0"> + <text locale="de">die Ruine eines alten Tempels</text> + <text locale="en">the ruins of an ancient temple</text> + </string> + + <string name="manual_location_1"> + <text locale="de">eine alte Burgruine</text> + <text locale="en">the ruins of a castle</text> + </string> + + <string name="manual_location_2"> + <text locale="de">ein zerfallenes Bauernhaus</text> + <text locale="en">a dilapitated farm</text> + </string> + + <string name="manual_location_3"> + <text locale="de">eine Leiche am Wegesrand</text> + <text locale="en">a corpse by the wayside</text> + </string> + + <string name="manual_location_3"> + <text locale="de">eine Leiche am Wegesrand</text> + <text locale="en">a corpse by the wayside</text> + </string> + + <string name="firedragon"> + <text locale="de">Feuerdrache</text> + <text locale="en">fire dragon</text> + </string> + + <string name="trigger_alp_destroy"> + <text locale="de">Ein Alp starb, ohne sein Ziel zu erreichen.</text> + <text locale="en">An alp died before it reached its target.</text> + </string> + </strings> diff --git a/src/res/messages.xml b/src/res/messages.xml index 721a57f1e..fd925f2d9 100644 --- a/src/res/messages.xml +++ b/src/res/messages.xml @@ -961,6 +961,16 @@ <text locale="de">"In $region($region) erhielt $unit($unit) eine Botschaft von $unit.dative($sender): '$string'"</text> <text locale="en">"In $region($region), $unit($unit) received a message by $unit($sender): '$string'"</text> </message> + <message name="museumgiveback" section="mail"> + <type> + <arg name="unit" type="unit"/> + <arg name="region" type="region"/> + <arg name="items" type="items"/> + <arg name="sender" type="unit"/> + </type> + <text locale="de">"In $region($region) erhielt $unit($unit) von $unit.dative($sender) $resources($items)"</text> + <text locale="en">"In $region($region), $unit($unit) received $resources($items) from $unit($sender)"</text> + </message> <message name="maintenance_nowork" section="events"> <type> <arg name="building" type="building"/> @@ -1036,6 +1046,86 @@ </type> <text locale="de">"$unit($unit) schwenkt sein Szepter und sorgt f�r Verwirrung und Chaos in der Region."</text> </message> + + <message name="find_manual" section="events"> + <type> + <arg name="unit" type="unit"/> + <arg name="location" type="string"/> + <arg name="book" type="string"/> + </type> + <text locale="de">"$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."</text> + </message> + + <message name="alp_success" section="events"> + <text locale="de">"Ein Alp hat sein Opfer gefunden und springt auf den R�cken von $unit($target)!"</text> + </message> + + <message name="summon_alp_effect" section="events"> + <type> + <arg name="mage" type="unit"/> + <arg name="alp" type="unit"/> + <arg name="target" type="unit"/> + </type> + <text locale="de">"$unit($mage) beschw�rt den Alp $unit($alp) f�r $unit($target)."</text> + <text locale="en">"$unit($mage) summons the alp $unit($alp) for $unit($target)."</text> + </message> + + <message name="healing_effect_0" section="events"> + <type> + <arg name="mage" type="unit"/> + <arg name="amount" type="int"/> + </type> + <text locale="de">"$unit($mage) k�mmert sich um die Verletzten und heilt $int($amount) Verwundete."</text> + </message> + + <message name="healing_effect_1" section="events"> + <type> + <arg name="mage" type="unit"/> + <arg name="amount" type="int"/> + <arg name="item" type="resource"/> + </type> + <text locale="de">"$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."</text> + </message> + + <message name="reanimate_effect_0" section="events"> + <type> + <arg name="mage" type="unit"/> + <arg name="amount" type="int"/> + </type> + <text locale="de">"$unit($mage) beginnt ein Ritual der Wiederbelebung. $int($amount) Krieger stehen von den Toten auf."</text> + </message> + + <message name="reanimate_effect_1" section="events"> + <type> + <arg name="mage" type="unit"/> + <arg name="amount" type="int"/> + <arg name="item" type="resource"/> + </type> + <text locale="de">"$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."</text> + </message> + + <message name="chaosgate_effect_1" section="events"> + <type> + <arg name="mage" type="unit"/> + </type> + <text locale="de">"$unit($mage) �ffnet ein Chaostor."</text> + <text locale="en">"$unit($mage) opens a chaos gate."</text> + </message> + + <message name="chaosgate_effect_2" section="events"> + <text locale="de">Ein Wirbel aus blendendem Licht erscheint."</text> + <text locale="en">"A vortex of blinding light appears."</text> + </message> + + <message name="summonundead_effect_1" section="events"> + <type> + <arg name="mage" type="unit"/> + <arg name="amount" type="int"/> + </type> + <text locale="de">"$unit($mage) erweckt $int($amount) Untote aus ihren Gr�bern."</text> + <text locale="en">"$unit($mage) calls $int($amount) undead from their graves."</text> + </message> + <message name="viewreality_effect" section="events"> <type> <arg name="unit" type="unit"/> @@ -1043,6 +1133,7 @@ <text locale="de">"$unit($unit) gelingt es, durch die Nebel auf die Realit�t zu blicken."</text> <text locale="en">"$unit($unit) manages to catch a glimpse of reality through the fog."</text> </message> + <message name="recruit_effect" section="events"> <type> <arg name="mage" type="unit"/> @@ -1398,15 +1489,7 @@ <text locale="de">"$unit($unit) in $region($region) wird von einem Unbekannten verflucht."</text> <text locale="en">"$unit($unit) in $region($region) was cursed by an unknown magician."</text> </message> - <message name="drought_effect" section="magic"> - <type> - <arg name="mage" type="unit"/> - <arg name="region" type="region"/> - <arg name="extended" type="string"/> - </type> - <text locale="de">"$unit($mage) ruft das Feuer der Sonne auf $region($region) herab."</text> - <text locale="en">"$unit($mage) calls the fires of the sun upon $region($region)."</text> - </message> + <message name="sparkle_effect" section="magic"> <type> <arg name="mage" type="unit"/> @@ -1759,7 +1842,7 @@ <text locale="fr">"$unit($unit) in $region($region): '$order($command)' - Building $int36($id) could not be located."</text> <text locale="en">"$unit($unit) in $region($region): '$order($command)' - Building $int36($id) could not be located."</text> </message> - <message name="spellunitnotfound" section="magic"> + <message name="unitnotfound_id" section="errors"> <type> <arg name="unit" type="unit"/> <arg name="region" type="region"/> @@ -1945,7 +2028,7 @@ <text locale="de">"$unit($unit) in $region($region): '$order($command)' - $unit($unit) gelingt es zwar die Region zu verzaubern, aber irgendwas ging schief."</text> <text locale="en">"$unit($unit) in $region($region): '$order($command)' - $unit($unit) manages to put a spell on the region, but something went wrong nonetheless."</text> </message> - <message name="summonundead_effect" section="magic"> + <message name="summonundead_effect_2" section="magic"> <type> <arg name="unit" type="unit"/> </type> @@ -2328,11 +2411,11 @@ <arg name="mode" type="int"/> <arg name="start" type="region"/> <arg name="end" type="region"/> - <arg name="regions" type="string"/> + <arg name="regions" type="regions"/> </type> - <text locale="de">"$unit($unit) $if($eq($mode,1),"reitet", "wandert") von $region($start) nach $region($end).$if($strlen($regions)," Dabei wurde $regions durchquert.","")"</text> - <text locale="fr">"$unit($unit) $if($eq($mode,1),"chevauche", "marche") de $region($start) vers $region($end) trans $regions"</text> - <text locale="en">"$unit($unit) $if($eq($mode,1),"rides", "walks") from $region($start) to $region($end)$if($strlen($regions)," by way of $regions","")."</text> + <text locale="de">"$unit($unit) $if($eq($mode,1),"reitet", "wandert") von $region($start) nach $region($end).$if($isnull($regions),""," Dabei wurde $regions($regions,1,-2) durchquert.")"</text> + <text locale="fr">"$unit($unit) $if($eq($mode,1),"chevauche", "marche") de $region($start) vers $region($end) trans $regions($regions,1,-2)"</text> + <text locale="en">"$unit($unit) $if($eq($mode,1),"rides", "walks") from $region($start) to $region($end)$if($isnull($regions),""," by way of $regions($regions,1,-2)")."</text> </message> <message name="detectoceandir" section="movement"> <type> @@ -3863,6 +3946,16 @@ <text locale="de">"$unit($unit) in $region($region): '$order($command)' - Die Einheit mu� sich an Land befinden."</text> <text locale="en">"$unit($unit) in $region($region): '$order($command)' - The unit must be on land."</text> </message> + <message name="error_nograves" section="errors"> + <type> + <arg name="unit" type="unit"/> + <arg name="region" type="region"/> + <arg name="command" type="order"/> + <arg name="target" type="region"/> + </type> + <text locale="de">"$unit($unit) in $region($region): '$order($command)' - In $region($target) sind keine Gr�ber."</text> + <text locale="en">"$unit($unit) in $region($region): '$order($command)' - There are no graves in $region($target)."</text> + </message> <message name="error241" section="errors"> <type> <arg name="unit" type="unit"/> @@ -6468,9 +6561,18 @@ <arg name="target" type="unit"/> </type> <text locale="de">"$unit($unit) �bergibt $int($amount) Person$if($eq($amount,1),"","en") an $unit($target)."</text> - <text locale="fr">"$unit($unit) transfers $int($amount) person$if($eq($amount,1),"","s") to $unit($target)."</text> <text locale="en">"$unit($unit) transfers $int($amount) person$if($eq($amount,1),"","s") to $unit($target)."</text> </message> + + <message name="give_person_peasants" section="economy"> + <type> + <arg name="unit" type="unit"/> + <arg name="amount" type="int"/> + </type> + <text locale="de">"$unit($unit) �bergibt $int($amount) Person$if($eq($amount,1),"","en") an die Bauern."</text> + <text locale="en">"$unit($unit) transfers $int($amount) person$if($eq($amount,1),"","s") to the local peasants."</text> + </message> + <message name="give" section="economy"> <type> <arg name="unit" type="unit"/> @@ -6478,9 +6580,14 @@ <arg name="resource" type="resource"/> <arg name="target" type="unit"/> </type> - <text locale="de">"$unit($unit) �bergibt $int($amount) $resource($resource,$amount) an $unit($target)."</text> - <text locale="fr">"$unit($unit) gives $int($amount) $resource($resource,$amount) to $unit($target)."</text> - <text locale="en">"$unit($unit) gives $int($amount) $resource($resource,$amount) to $unit($target)."</text> + <message name="give_peasants" section="economy"> + <type> + <arg name="unit" type="unit"/> + <arg name="amount" type="int"/> + <arg name="resource" type="resource"/> + </type> + <text locale="de">"$unit($unit) �bergibt $int($amount) $resource($resource,$amount) an die Bauern."</text> + <text locale="en">"$unit($unit) gives $int($amount) $resource($resource,$amount) to the local peasants."</text> </message> <message name="maintenance" section="economy"> <type> @@ -6627,6 +6734,29 @@ <text locale="en">"$unit($unit) in $region($region): '$order($command)' - Pyramids may be build in this region."</text> <text locale="fr">"$unit($unit) in $region($region): '$order($command)' - Pyramids may be build in this region."</text> </message> + + <message name="error_spell_on_ship_already" section="errors"> + <type> + <arg name="unit" type="unit"/> + <arg name="region" type="region"/> + <arg name="command" type="order"/> + <arg name="ship" type="ship"/> + </type> + <text locale="de">"$unit($unit) in $region($region): '$order($command)' - Auf $ship($ship) liegt beeits ein Zauber."</text> + <text locale="en">"$unit($unit) in $region($region): '$order($command)' - There is already a spell on $ship($ship)."</text> + </message> + + <message name="error_spell_on_flying_ship" section="errors"> + <type> + <arg name="unit" type="unit"/> + <arg name="region" type="region"/> + <arg name="command" type="order"/> + <arg name="ship" type="ship"/> + </type> + <text locale="de">"$unit($unit) in $region($region): '$order($command)' - Es ist zu gef�hrlich, diesen Zauber auf das fliegende Schiff $ship($ship) zu legen."</text> + <text locale="en">"$unit($unit) in $region($region): '$order($command)' - It is far too dangerous to put this spell on the flying ship $ship($ship)."</text> + </message> + <message name="wdw_pyramidspell_notfound" section="events"> <type> <arg name="unit" type="unit"/> @@ -6639,6 +6769,7 @@ <text locale="en">"$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."</text> <text locale="fr">"$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."</text> </message> + <message name="wormhole_requirements" section="events"> <type> <arg name="unit" type="unit"/> @@ -6759,10 +6890,108 @@ <text locale="de">"$unit($mage) zaubert $spell($spell): $int($dead) $if($eq($dead,1),"Krieger wurde", "Krieger wurden") get�tet."</text> <text locale="en">"$unit($mage) casts $spell($spell): $int($dead) $if($eq($dead,1),"enemy was", "enemies were") killed."</text> </message> + + <message name="earthquake_effect" section="magic"> + <type> + <arg name="mage" type="unit"/> + <arg name="region" type="region"/> + </type> + <text locale="de">"$unit($mage) l��t die Erde in $region($region) erzittern."</text> + <text locale="en">"$unit($mage) shakes the earth in $region($region)."</text> + </message> + + <message name="drought_effect" section="magic"> + <type> + <arg name="mage" type="unit"/> + </type> + <text locale="de">"$unit($mage) verflucht das Land, und eine D�rreperiode beginnt."</text> + <text locale="en">"$unit($mage) puts a curse on the land and a drought sets in."</text> + </message> + + <message name="summon_effect" section="magic"> + <type> + <arg name="mage" type="unit"/> + <arg name="amount" type="int"/> + <arg name="race" type="race"/> + </type> + <text locale="de">"$unit($mage) beschw�rt $int($amount) $race($race,$amount)."</text> + <text locale="en">"$unit($mage) summons $int($amount) $race($race,$amount)."</text> + </message> + + <message name="forestfire_effect" section="magic"> + <type> + <arg name="mage" type="unit"/> + <arg name="region" type="region"/> + <arg name="amount" type="int"/> + </type> + <text locale="de">"$unit($mage) erschafft in $region($region) eine verheerende Feuersbrunst. $int($amount) B�ume fallen den Flammen zum Opfer."</text> + <text locale="de">"$unit($mage) creates a flaming inferno in $region($region). $int($amount) trees fall vistim to the flames."</text> +</text> + </message> + + <message name="recruit_effect" section="magic"> + <type> + <arg name="mage" type="unit"/> + <arg name="amount" type="int"/> + </type> + <text locale="de">"$unit($mage) konnte $int($amount) Bauern anwerben."</text> + <text locale="en">"$unit($mage) recruited $int($amount) peasants."</text> + </message> + + <message name="homestone_effect" section="magic"> + <type> + <arg name="mage" type="unit"/> + <arg name="building" type="building"/> + </type> + <text locale="de">"Mit einem Ritual bindet $unit($unit) die magischen Kr�fte der Erde in die Mauern von $building($building)."</text> + </message> + + <message name="blessedstonecircle_effect" section="magic"> + <type> + <arg name="mage" type="unit"/> + <arg name="building" type="building"/> + </type> + <text locale="de">"$unit($mage) weight $building($building)."</text> + <text locale="en">"$unit($mage) blesses $building($building)."</text> + </message> + + <message name="drought_effect_1" section="magic"> + <type> + <arg name="mage" type="unit"/> + <arg name="region" type="region"/> + </type> + <text locale="de">"$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."</text> + </message> + + <message name="drought_effect_2" section="magic"> + <type> + <arg name="mage" type="unit"/> + <arg name="region" type="region"/> + </type> + <text locale="de">"$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."</text> + </message> + + <message name="drought_effect_3" section="magic"> + <type> + <arg name="mage" type="unit"/> + <arg name="region" type="region"/> + </type> + <text locale="de">"$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."</text> + </message> + + <message name="drought_effect_4" section="magic"> + <type> + <arg name="mage" type="unit"/> + <arg name="region" type="region"/> + </type> + <text locale="de">"$unit($mage) ruft das Feuer der Sonne auf $region($region) hinab. Das Eis zerbricht und eine gewaltige Flutwelle verschlingt die Region."</text> + </message> + <message name="generous_effect_1" section="magic"> <text locale="de">"Die Darbietungen eines fahrenden Gauklers begeistern die Leute. Die fr�hliche und ausgelassene Stimmung seiner Lieder �bertr�gt sich auf alle Zuh�rer."</text> <text locale="en">"A touring minstrel entertains the locals. The joyous and generous disposition of his songs prove infectious."</text> </message> + <message name="generous_effect_0" section="magic"> <type> <arg name="mage" type="unit"/> @@ -7264,6 +7493,35 @@ <text locale="en">"A message from $unit($unit): '$message'"</text> </message> + <message name="encounter_allies" section="events"> + <type> + <arg name="unit" type="unit"/> + <arg name="name" type="string"/> + </type> + <text locale="de">"Pl�tzlich stolpert $unit($unit) �ber einige $localize($name). Nach kurzem Z�gern entschlie�en die $localize($name), sich Deiner Partei anzuschlie�en."</text> + </message> + + <message name="encounter_villagers" section="events"> + <type> + <arg name="unit" type="unit"/> + </type> + <text locale="de">"$unit($unit) entdeckt ein kleines Dorf. Die meisten H�user wurden durch einen �ber die Ufer getretenen Flu� zerst�rt. Eine Gruppe der verzweifelten Menschen schlie�t sich deiner Partei an."</text> + <text locale="en">"$unit($unit) discovers a small village. Most of the houses have been destroyed by flooding, and a group of the distressed villagers join your faction."</text> + </message> + + <message name="mob_warning" section="events"> + <text locale="de">"Ein Bauernmob erhebt sich und macht Jagd auf Schwarzmagier."</text> + <text locale="en">"An angry mob forms and hunts practitioners of the dark arts."</text> + </message> + + <message name="familiar_name" section="events"> + <type> + <arg name="unit" type="unit"/> + </type> + <text locale="de">"Vertrauter von $unit($unit)"</text> + <text locale="en">"Familiar of $unit($unit)"</text> + </message> + <message name="recruit_archetype" section="events"> <type> <arg name="unit" type="unit"/> @@ -7274,4 +7532,71 @@ <text locale="en">"$unit($unit) recruits $int($amount) $localize($archetype)."</text> </message> + <message name="illegal_password" section="events"> + <type> + <arg name="newpass" type="string"/> + </type> + <text locale="de">"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}'."</text> + <text locale="en">"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}'."</text> + </message> + + <message name="meow" section="events"> + <text locale="de">"Miiauuuuuu..."</text> + <text locale="en">"Meeoooooow..."</text> + </message> + + <message name="migrant_conversion" section="events"> + <type> + <arg name="unit" type="unit"/> + </type> + <text locale="de">"Die G�tter segnen $unit($unit) mit der richtigen Rasse."</text> + <text locale="en">"The gods are blessing $unit($unit) with the correct race."</text> + </message> + + <message name="arena_leave_fail" section="events"> + <type> + <arg name="unit" type="unit"/> + </type> + <text locale="de">"Der Versuch, die Greifenschwingen zu benutzen, schlug fehl. $unit($unit) konnte die Ebene der Herausforderung nicht verlassen."</text> + </message> + + <message name="caldera_handle_0" section="events"> + <type> + <arg name="unit" type="unit"/> + </type> + <text locale="de">"$unit($unit) springt in die ewigen Feuer des Kraters."</text> + </message> + + <message name="caldera_handle_1" section="events"> + <type> + <arg name="unit" type="unit"/> + <arg name="items" type="items"/> + </type> + <text locale="de">"$unit($unit) springt in die ewigen Feuer des Kraters."</text> + </message> + + <message name="arena_enter_fail" section="events"> + <type> + <arg name="region" type="region"/> + <arg name="unit" type="unit"/> + </type> + <text locale="de">"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�."</text> + </message> + + <message name="arena_enter" section="events"> + <type> + <arg name="region" type="region"/> + <arg name="unit" type="unit"/> + </type> + <text locale="de">"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."</text> + </message> + + <message name="chaos_disease" section="events"> + <type> + <arg name="unit" type="unit"/> + </type> + <text locale="de">"$unit($unit) scheint von einer seltsamen Krankheit befallen."</text> + <text locale="en">"$unit($unit) is stricken by a strange disease."</text> + </message> + </messages> diff --git a/src/res/races.xml b/src/res/races.xml index 33078c19e..4fd8d6745 100644 --- a/src/res/races.xml +++ b/src/res/races.xml @@ -314,6 +314,7 @@ </race> <race name="wolf" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="25" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="3" scarepeasants="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> <ai splitsize="5000"/> + <function name="name" value="namegeneric"/> <function name="initfamiliar" value="oldfamiliars"/> <skill name="alchemy" modifier="-99"/> <skill name="crossbow" modifier="-99"/> @@ -572,7 +573,7 @@ </race> <race name="braineater" magres="0.900000" maxaura="1.000000" regaura="1.000000" recruitcost="50000" weight="100" capacity="540" speed="1.000000" hp="20" ac="1" damage="0d0" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="10" scarepeasants="yes" fly="yes" walk="yes" teach="no" invinciblenonmagic="yes"> <ai splitsize="500" killpeasants="yes" moverandom="yes" learn="yes"/> - <function name="describe" value="describe_braineater"/> + <function name="name" value="namegeneric"/> <attack type="2" damage="3d15"/> <attack type="3" damage="1d1"/> <attack type="4" damage="1d1"/> @@ -643,15 +644,17 @@ </race> <race name="alp" magres="0.950000" maxaura="1.000000" regaura="1.000000" recruitcost="50000" weight="0" capacity="0" speed="1.500000" hp="20" ac="2" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="2" defensemodifier="20" fly="yes" walk="yes" canlearn="no" canteach="no"> <ai splitsize="1"/> + <function name="name" value="namegeneric"/> <attack type="1" damage="1d4"/> </race> <race name="mountainguard" unarmedguard="yes" magres="0.500000" maxaura="1.000000" regaura="0.500000" recruitcost="50000" weight="10000" capacity="2000" speed="0.000000" hp="1000" ac="12" damage="2d40" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="8" cannotmove="yes" canlearn="no" teach="no" noweapons="yes" giveitem="yes"> <ai splitsize="1"/> + <function name="name" value="namegeneric"/> <attack type="4" damage="2d40"/> </race> <race name="shadowmaster" cansail="no" cansteal="no" canlearn="no" magres="0.750000" maxaura="1.000000" regaura="2.000000" recruitcost="50000" weight="500" capacity="540" speed="1.000000" hp="150" ac="4" damage="2d5" unarmedattack="0" unarmeddefense="0" attackmodifier="11" defensemodifier="13" scarepeasants="yes" walk="yes" teach="no" desert="yes" nogive="yes"> <ai splitsize="50" killpeasants="yes" moverandom="yes" learn="yes"/> - <function name="name" value="nameshadow"/> + <function name="name" value="namegeneric"/> <attack type="4" damage="2d4"/> <attack type="2" damage="2d30"/> <attack type="3" damage="1d2"/> @@ -670,6 +673,7 @@ </race> <race name="irongolem" magres="0.250000" maxaura="1.000000" regaura="0.100000" recruitcost="5000" weight="10000" capacity="2000" speed="1.000000" hp="50" ac="2" damage="2d10+4" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="2" walk="yes" canlearn="no" teach="no" giveitem="yes"> <ai splitsize="50"/> + <function name="name" value="namegeneric"/> <skill name="armorer" modifier="14"/> <skill name="weaponsmithing" modifier="14"/> <attack type="4" damage="2d8+4"/> @@ -698,6 +702,7 @@ </race> <race name="ent" magres="0.250000" maxaura="1.000000" regaura="0.500000" recruitcost="5000" weight="5000" capacity="2500" speed="1.000000" hp="50" ac="4" damage="2d4+12" unarmedattack="0" unarmeddefense="0" attackmodifier="9" defensemodifier="7" scarepeasants="yes" walk="yes" teach="no"> <ai splitsize="1000" moverandom="yes" learn="yes"/> + <function name="name" value="namegeneric"/> <attack type="4" damage="2d12"/> <attack type="4" damage="2d12"/> </race> @@ -1150,6 +1155,7 @@ </race> <race name="shadowknight" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" nogive="yes" walk="yes" canlearn="no" teach="no" noblock="yes"> <ai splitsize="20000" moverandom="yes"/> + <function name="name" value="namegeneric"/> <attack type="1" damage="1d1"/> </race> <race name="seaserpent" magres="0.500000" maxaura="1.000000" regaura="1.000000" recruitcost="5000" weight="20000" capacity="5000" speed="1.000000" hp="600" ac="3" damage="2d15" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="4" scarepeasants="yes" swim="yes" teach="no" getitem="yes" resistbash="yes"> @@ -1328,11 +1334,13 @@ </race> <race name="shadowbat" magres="0.800000" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="500" capacity="540" speed="1.000000" hp="1" ac="4" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes"> <ai splitsize="5000" killpeasants="yes"/> + <function name="name" value="namegeneric"/> <attack type="4" damage="1d6"/> <attack type="3" damage="1d1"/> </race> <race name="nightmare" magres="0.500000" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="100" capacity="540" speed="1.000000" hp="80" ac="10" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" invinciblenonmagic="yes"> <ai splitsize="500" killpeasants="yes"/> + <function name="name" value="namegeneric"/> <attack type="4" damage="1d4"/> <attack type="4" damage="1d4"/> <attack type="4" damage="1d4"/> @@ -1341,6 +1349,7 @@ </race> <race name="vampunicorn" magres="1.000000" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="5000" capacity="2000" speed="1.000000" hp="30" ac="4" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" walk="yes" teach="no" getitem="yes"> <ai splitsize="5000" killpeasants="yes"/> + <function name="name" value="namegeneric"/> <attack type="4" damage="2d10"/> <attack type="3" damage="1d4"/> <attack type="3" damage="1d4"/>