From 669712f04f12f1b1a9ba782406b28b833007dafc Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 8 Dec 2014 22:06:05 +0100 Subject: [PATCH 1/7] rename race_ to _race, to follow the style guide. --- src/kernel/config.h | 1 - src/kernel/unit.c | 8 ++++---- src/kernel/unit.h | 2 +- src/laws.test.c | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/kernel/config.h b/src/kernel/config.h index 570d7c953..08afc5c22 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -26,7 +26,6 @@ extern "C" { /* this should always be the first thing included after platform.h */ #include "types.h" - struct _dictionary_; /* experimental gameplay features (that don't affect the savefile) */ /* TODO: move these settings to settings.h or into configuration files */ #define GOBLINKILL /* Goblin-Spezialklau kann tödlich enden */ diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 9e2a72e3f..042002a48 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -858,7 +858,7 @@ bool leave(unit * u, bool force) const struct race *urace(const struct unit *u) { - return u->race_; + return u->_race; } bool can_survive(const unit * u, const region * r) @@ -1766,18 +1766,18 @@ const struct race *u_irace(const struct unit *u) if (u->irace && skill_enabled(SK_STEALTH)) { return u->irace; } - return u->race_; + return u->_race; } const struct race *u_race(const struct unit *u) { - return u->race_; + return u->_race; } void u_setrace(struct unit *u, const struct race *rc) { assert(rc); - u->race_ = rc; + u->_race = rc; } void unit_add_spell(unit * u, sc_mage * m, struct spell * sp, int level) diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 6a089d2d4..f091477dc 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -104,7 +104,7 @@ extern "C" { struct order *old_orders; /* race and illusionary race */ - const struct race *race_; + const struct race *_race; const struct race *irace; int flags; diff --git a/src/laws.test.c b/src/laws.test.c index 2280b155d..bc8fa7247 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -444,7 +444,7 @@ static void test_unarmed_races_can_guard(CuTest *tc) { race * rc; setup_guard(&fix, false); - rc = rc_get_or_create(fix.u->race_->_name); + rc = rc_get_or_create(fix.u->_race->_name); rc->flags |= RCF_UNARMEDGUARD; update_guards(); CuAssertTrue(tc, fval(fix.u, UFL_GUARD)); From b551edbdb3d6c1bca41f4b3d531b500cc9822d3c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 9 Dec 2014 05:55:16 +0100 Subject: [PATCH 2/7] refactoring: moving unitname to unit.c. also removing static-string some cruft from config.c. --- src/kernel/command.c | 1 + src/kernel/config.c | 44 +------------------------------------------- src/kernel/config.h | 8 ++------ src/kernel/unit.c | 18 ++++++++++++++++++ src/kernel/unit.h | 3 +++ src/vortex.c | 2 +- 6 files changed, 26 insertions(+), 50 deletions(-) diff --git a/src/kernel/command.c b/src/kernel/command.c index 284064621..c6d262dd0 100644 --- a/src/kernel/command.c +++ b/src/kernel/command.c @@ -15,6 +15,7 @@ #include "command.h" #include +#include #include #include diff --git a/src/kernel/config.c b/src/kernel/config.c index b2889af8a..a6c631573 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -1097,28 +1097,7 @@ typedef char name[OBJECTIDSIZE + 1]; static name idbuf[8]; static int nextbuf = 0; -char *estring_i(char *ibuf) -{ - char *p = ibuf; - - while (*p) { - if (isxspace(*(unsigned *)p) == ' ') { - *p = '~'; - } - ++p; - } - return ibuf; -} - -char *estring(const char *s) -{ - char *ibuf = idbuf[(++nextbuf) % 8]; - - strlcpy(ibuf, s, sizeof(name)); - return estring_i(ibuf); -} - -char *cstring_i(char *ibuf) +char *untilde(char *ibuf) { char *p = ibuf; @@ -1131,14 +1110,6 @@ char *cstring_i(char *ibuf) return ibuf; } -char *cstring(const char *s) -{ - char *ibuf = idbuf[(++nextbuf) % 8]; - - strlcpy(ibuf, s, sizeof(name)); - return cstring_i(ibuf); -} - building *largestbuilding(const region * r, cmp_building_cb cmp_gt, bool imaginary) { @@ -1157,19 +1128,6 @@ building *largestbuilding(const region * r, cmp_building_cb cmp_gt, return best; } -char *write_unitname(const unit * u, char *buffer, size_t size) -{ - slprintf(buffer, size, "%s (%s)", (const char *)u->name, itoa36(u->no)); - buffer[size - 1] = 0; - return buffer; -} - -const char *unitname(const unit * u) -{ - char *ubuf = idbuf[(++nextbuf) % 8]; - return write_unitname(u, ubuf, sizeof(name)); -} - /* -- Erschaffung neuer Einheiten ------------------------------ */ extern faction *dfindhash(int i); diff --git a/src/kernel/config.h b/src/kernel/config.h index 08afc5c22..cf0429993 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -34,6 +34,7 @@ extern "C" { #define INSECT_POTION /* Spezialtrank für Insekten */ #define ORCIFICATION /* giving snotlings to the peasants gets counted */ +// TODO: remove macro, move all alliance code into a module. #define ALLIED(f1, f2) (f1==f2 || (f1->alliance && f1->alliance==f2->alliance)) /* for some good prime numbers, check http://www.math.niu.edu/~rusin/known-math/98/pi_x */ @@ -179,12 +180,7 @@ extern "C" { struct faction *getfaction(void); - char *estring(const char *s); - char *estring_i(char *s); - char *cstring(const char *s); - char *cstring_i(char *s); - const char *unitname(const struct unit *u); - char *write_unitname(const struct unit *u, char *buffer, size_t size); + char *untilde(char *s); typedef int(*cmp_building_cb) (const struct building * b, const struct building * a); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 042002a48..6decd4a8b 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1843,3 +1843,21 @@ void remove_empty_units(void) remove_empty_units_in_region(r); } } + +typedef char name[OBJECTIDSIZE + 1]; +static name idbuf[8]; +static int nextbuf = 0; + +char *write_unitname(const unit * u, char *buffer, size_t size) +{ + slprintf(buffer, size, "%s (%s)", (const char *)u->name, itoa36(u->no)); + buffer[size - 1] = 0; + return buffer; +} + +const char *unitname(const unit * u) +{ + char *ubuf = idbuf[(++nextbuf) % 8]; + return write_unitname(u, ubuf, sizeof(name)); +} + diff --git a/src/kernel/unit.h b/src/kernel/unit.h index f091477dc..856e1ffe2 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -247,6 +247,9 @@ extern "C" { struct unit *findunitr(const struct region *r, int n); + const char *unitname(const struct unit *u); + char *write_unitname(const struct unit *u, char *buffer, size_t size); + #ifdef __cplusplus } #endif diff --git a/src/vortex.c b/src/vortex.c index a0791907d..f9993a561 100644 --- a/src/vortex.c +++ b/src/vortex.c @@ -86,7 +86,7 @@ static int a_readdirection(attrib * a, void *owner, struct storage *store) READ_TOK(store, NULL, 0); READ_TOK(store, lbuf, sizeof(lbuf)); - cstring_i(lbuf); + untilde(lbuf); for (; dl; dl = dl->next) { if (strcmp(lbuf, dl->oldname) == 0) { d->keyword = _strdup(dl->name); From 3428f40f811dd3fa0b78e75d6abd022a91a71f04 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 9 Dec 2014 06:01:10 +0100 Subject: [PATCH 3/7] load inifile in main, it is only used by the server. this should fix the broken CI build. --- src/kernel/config.c | 39 --------------------------------------- src/kernel/config.h | 1 - src/main.c | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/kernel/config.c b/src/kernel/config.c index a6c631573..27dcb2480 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -62,7 +62,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include #include #include #include @@ -2332,41 +2331,3 @@ int game_id(void) { return get_param_int(global.parameters, "game.id", 0); } -void load_inifile(dictionary * d) -{ - const char *reportdir = reportpath(); - const char *datadir = datapath(); - const char *basedir = basepath(); - const char *str; - - assert(d); - - str = iniparser_getstring(d, "eressea:base", basedir); - if (str != basedir) { - set_basepath(str); - } - str = iniparser_getstring(d, "eressea:report", reportdir); - if (str != reportdir) { - set_reportpath(str); - } - str = iniparser_getstring(d, "eressea:data", datadir); - if (str != datadir) { - set_datapath(str); - } - - lomem = iniparser_getint(d, "eressea:lomem", lomem) ? 1 : 0; - - str = iniparser_getstring(d, "eressea:encoding", NULL); - if (str && (_strcmpl(str, "utf8") == 0 || _strcmpl(str, "utf-8") == 0)) { - enc_gamedata = ENCODING_UTF8; - } - - verbosity = iniparser_getint(d, "eressea:verbose", 2); - battledebug = iniparser_getint(d, "eressea:debug", battledebug) ? 1 : 0; - - str = iniparser_getstring(d, "eressea:locales", "de,en"); - make_locales(str); - - if (global.inifile) iniparser_free(global.inifile); - global.inifile = d; -} diff --git a/src/kernel/config.h b/src/kernel/config.h index cf0429993..a3e218a82 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -301,7 +301,6 @@ extern "C" { const char *basepath(void); void set_basepath(const char *); - void load_inifile(struct _dictionary_ *d); const char *reportpath(void); void set_reportpath(const char *); diff --git a/src/main.c b/src/main.c index 7f74c9ea4..6868d36e9 100644 --- a/src/main.c +++ b/src/main.c @@ -22,6 +22,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include +#include #include "eressea.h" #ifdef USE_CURSES #include "gmtool.h" @@ -43,6 +45,45 @@ static const char *luafile = 0; static const char *inifile = "eressea.ini"; static int memdebug = 0; +static void load_inifile(dictionary * d) +{ + const char *reportdir = reportpath(); + const char *datadir = datapath(); + const char *basedir = basepath(); + const char *str; + + assert(d); + + str = iniparser_getstring(d, "eressea:base", basedir); + if (str != basedir) { + set_basepath(str); + } + str = iniparser_getstring(d, "eressea:report", reportdir); + if (str != reportdir) { + set_reportpath(str); + } + str = iniparser_getstring(d, "eressea:data", datadir); + if (str != datadir) { + set_datapath(str); + } + + lomem = iniparser_getint(d, "eressea:lomem", lomem) ? 1 : 0; + + str = iniparser_getstring(d, "eressea:encoding", NULL); + if (str && (_strcmpl(str, "utf8") == 0 || _strcmpl(str, "utf-8") == 0)) { + enc_gamedata = ENCODING_UTF8; + } + + verbosity = iniparser_getint(d, "eressea:verbose", 2); + battledebug = iniparser_getint(d, "eressea:debug", battledebug) ? 1 : 0; + + str = iniparser_getstring(d, "eressea:locales", "de,en"); + make_locales(str); + + if (global.inifile) iniparser_free(global.inifile); + global.inifile = d; +} + static void parse_config(const char *filename) { dictionary *d = iniparser_new(filename); From 9394c4324e6c0909342e2bb48e356c34791e5ab1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 9 Dec 2014 06:45:21 +0100 Subject: [PATCH 4/7] units without a name will use their race as a default name. --- src/kernel/unit.c | 7 ++++++- src/kernel/unit.test.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 6decd4a8b..22f138ead 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1850,7 +1850,12 @@ static int nextbuf = 0; char *write_unitname(const unit * u, char *buffer, size_t size) { - slprintf(buffer, size, "%s (%s)", (const char *)u->name, itoa36(u->no)); + if (u->name) { + slprintf(buffer, size, "%s (%s)", u->name, itoa36(u->no)); + } else { + const char * name = rc_name(u->_race, u->number == 1 ? NAME_SINGULAR : NAME_PLURAL); + slprintf(buffer, size, "%s (%s)", locale_string(u->faction->locale, name), itoa36(u->no)); + } buffer[size - 1] = 0; return buffer; } diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index 12a83d3ad..04996aafd 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include "alchemy.h" #include "faction.h" #include "unit.h" @@ -10,7 +12,9 @@ #include #include +#include #include +#include #include static void test_remove_empty_units(CuTest *tc) { @@ -123,10 +127,48 @@ static void test_scale_number(CuTest *tc) { test_cleanup(); } +static void test_unit_name(CuTest *tc) { + unit *u; + char name[32]; + + test_cleanup(); + test_create_world(); + u = test_create_unit(test_create_faction(test_create_race("human")), findregion(0, 0)); + unit_setname(u, "Hodor"); + _snprintf(name, sizeof(name), "Hodor (%s)", itoa36(u->no)); + CuAssertStrEquals(tc, name, unitname(u)); + test_cleanup(); +} + +static void test_unit_name_from_race(CuTest *tc) { + unit *u; + char name[32]; + struct locale *lang; + + test_cleanup(); + test_create_world(); + u = test_create_unit(test_create_faction(test_create_race("human")), findregion(0, 0)); + unit_setname(u, NULL); + lang = get_or_create_locale("de"); + locale_setstring(lang, rc_name(u->_race, NAME_SINGULAR), "Mensch"); + locale_setstring(lang, rc_name(u->_race, NAME_PLURAL), "Menschen"); + + _snprintf(name, sizeof(name), "Mensch (%s)", itoa36(u->no)); + CuAssertStrEquals(tc, name, unitname(u)); + + u->number = 2; + _snprintf(name, sizeof(name), "Menschen (%s)", itoa36(u->no)); + CuAssertStrEquals(tc, name, unitname(u)); + + test_cleanup(); +} + CuSuite *get_unit_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_scale_number); + SUITE_ADD_TEST(suite, test_unit_name); + SUITE_ADD_TEST(suite, test_unit_name_from_race); SUITE_ADD_TEST(suite, test_remove_empty_units); SUITE_ADD_TEST(suite, test_remove_units_ignores_spells); SUITE_ADD_TEST(suite, test_remove_units_without_faction); From bde56aa1f81bc006d0d6e752fce7f3269dce1d01 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 9 Dec 2014 06:46:45 +0100 Subject: [PATCH 5/7] eliminate unused variables, fix CI build. --- src/kernel/config.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/kernel/config.c b/src/kernel/config.c index 27dcb2480..c28357c31 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -1092,10 +1092,6 @@ void freestrlist(strlist * s) } /* - Namen der Strukturen -------------------------------------- */ -typedef char name[OBJECTIDSIZE + 1]; -static name idbuf[8]; -static int nextbuf = 0; - char *untilde(char *ibuf) { char *p = ibuf; From 0fead39b414206b749143cce38b8214efc226ee0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 9 Dec 2014 07:20:36 +0100 Subject: [PATCH 6/7] added a function that sets a monster's name to NULL if it is the name of its race. deprecate old rc_name function (renamed to rc_name_s) because it used a static return string. --- src/creport.c | 10 +- src/kernel/config.c | 6 +- src/kernel/race.c | 18 +-- src/kernel/race.h | 275 +++++++++++++++++++++-------------------- src/kernel/race.test.c | 8 +- src/kernel/unit.c | 14 ++- src/kernel/unit.h | 1 + src/kernel/unit.test.c | 31 ++++- src/laws.c | 4 +- src/modules/score.c | 2 +- src/monster.c | 1 - src/monster.h | 19 +-- src/monsters.c | 4 +- src/names.c | 2 +- src/report.c | 2 +- src/reports.c | 2 +- src/spells.c | 6 +- src/summary.c | 10 +- 18 files changed, 230 insertions(+), 185 deletions(-) diff --git a/src/creport.c b/src/creport.c index 3ac20fcc5..5f9700533 100644 --- a/src/creport.c +++ b/src/creport.c @@ -341,7 +341,7 @@ static int cr_race(variant var, char *buffer, const void *userdata) { const faction *report = (const faction *)userdata; const struct race *rc = (const race *)var.v; - const char *key = rc_name(rc, NAME_SINGULAR); + const char *key = rc_name_s(rc, NAME_SINGULAR); sprintf(buffer, "\"%s\"", translate(key, locale_string(report->locale, key))); return 0; @@ -834,20 +834,20 @@ static void cr_output_unit(FILE * F, const region * r, const faction * f, if (pzTmp) { fprintf(F, "\"%s\";Typ\n", pzTmp); if (u->faction == f && fval(u_race(u), RCF_SHAPESHIFTANY)) { - const char *zRace = rc_name(u_race(u), NAME_PLURAL); + const char *zRace = rc_name_s(u_race(u), NAME_PLURAL); fprintf(F, "\"%s\";wahrerTyp\n", translate(zRace, locale_string(f->locale, zRace))); } } else { const race *irace = u_irace(u); - const char *zRace = rc_name(irace, NAME_PLURAL); + const char *zRace = rc_name_s(irace, NAME_PLURAL); fprintf(F, "\"%s\";Typ\n", translate(zRace, locale_string(f->locale, zRace))); if (u->faction == f && irace != u_race(u)) { assert(skill_enabled(SK_STEALTH) || !"we're resetting this on load, so.. ircase should never be used"); - zRace = rc_name(u_race(u), NAME_PLURAL); + zRace = rc_name_s(u_race(u), NAME_PLURAL); fprintf(F, "\"%s\";wahrerTyp\n", translate(zRace, locale_string(f->locale, zRace))); } @@ -1548,7 +1548,7 @@ report_computer(const char *filename, report_context * ctx, const char *charset) fprintf(F, "%d;Punktedurchschnitt\n", avgscore); #endif { - const char *zRace = rc_name(f->race, NAME_PLURAL); + const char *zRace = rc_name_s(f->race, NAME_PLURAL); fprintf(F, "\"%s\";Typ\n", translate(zRace, LOC(f->locale, zRace))); } prefix = get_prefix(f->attribs); diff --git a/src/kernel/config.c b/src/kernel/config.c index c28357c31..baa86aab0 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -304,7 +304,7 @@ const char *dbrace(const struct race *rc) char *zPtr = zText; /* the english names are all in ASCII, so we don't need to worry about UTF8 */ - strcpy(zText, (const char *)LOC(get_locale("en"), rc_name(rc, NAME_SINGULAR))); + strcpy(zText, (const char *)LOC(get_locale("en"), rc_name_s(rc, NAME_SINGULAR))); while (*zPtr) { *zPtr = (char)(toupper(*zPtr)); ++zPtr; @@ -1482,9 +1482,9 @@ void init_locale(struct locale *lang) for (rc = races; rc; rc = rc->next) { const char *name; var.v = (void *)rc; - name = LOC(lang, rc_name(rc, NAME_PLURAL)); + name = LOC(lang, rc_name_s(rc, NAME_PLURAL)); if (name) addtoken(tokens, name, var); - name = LOC(lang, rc_name(rc, NAME_SINGULAR)); + name = LOC(lang, rc_name_s(rc, NAME_SINGULAR)); if (name) addtoken(tokens, name, var); } diff --git a/src/kernel/race.c b/src/kernel/race.c index e3953ea98..e83183564 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -219,8 +219,7 @@ bool r_insectstalled(const region * r) return fval(r->terrain, ARCTIC_REGION); } -const char *rc_name(const race * rc, name_t n) -{ +const char* rc_name(const race * rc, name_t n, char *name, size_t size) { const char * postfix = 0; if (!rc) { return NULL; @@ -230,16 +229,21 @@ const char *rc_name(const race * rc, name_t n) case NAME_PLURAL: postfix = "_p"; break; case NAME_DEFINITIVE: postfix = "_d"; break; case NAME_CATEGORY: postfix = "_x"; break; - default: assert(!"invalid name_t enum in rc_name"); + default: assert(!"invalid name_t enum in rc_name_s"); } if (postfix) { - static char name[64]; // FIXME: static return value - sprintf(name, "race::%s%s", rc->_name, postfix); + _snprintf(name, size, "race::%s%s", rc->_name, postfix); return name; } return NULL; } +const char *rc_name_s(const race * rc, name_t n) +{ + static char name[64]; // FIXME: static return value + return rc_name(rc, n, name, sizeof(name)); +} + const char *raceprefix(const unit * u) { const attrib *asource = u->faction->attribs; @@ -266,7 +270,7 @@ const char *racename(const struct locale *loc, const unit * u, const race * rc) if (wrptr(&bufp, &size, bytes) != 0) WARN_STATIC_BUFFER(); - bytes = (int)strlcpy(bufp, LOC(loc, rc_name(rc, u->number != 1)), size); + bytes = (int)strlcpy(bufp, LOC(loc, rc_name_s(rc, u->number != 1)), size); assert(~bufp[0] & 0x80 || !"unicode/not implemented"); ch = tolower(*(unsigned char *)bufp); bufp[0] = (char)ch; @@ -276,7 +280,7 @@ const char *racename(const struct locale *loc, const unit * u, const race * rc) return lbuf; } - str = LOC(loc, rc_name(rc, (u->number == 1) ? NAME_SINGULAR : NAME_PLURAL)); + str = LOC(loc, rc_name_s(rc, (u->number == 1) ? NAME_SINGULAR : NAME_PLURAL)); return str ? str : rc->_name; } diff --git a/src/kernel/race.h b/src/kernel/race.h index d7f9e12b8..b0801e5e5 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -1,7 +1,7 @@ /* Copyright (c) 1998-2010, Enno Rehling - Katja Zedel +Katja Zedel Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -24,7 +24,7 @@ extern "C" { #include "magic.h" /* wegen MAXMAGIETYP */ #include "skill.h" - + #define AT_NONE 0 #define AT_STANDARD 1 #define AT_DRAIN_EXP 2 @@ -40,150 +40,151 @@ extern "C" { #define RACESPOILCHANCE 5 /* Chance auf rassentypische Beute */ - struct param; - struct spell; + struct param; + struct spell; - typedef enum { - RC_DWARF, /* 0 - Zwerg */ - RC_ELF, - RC_GOBLIN = 3, - RC_HUMAN, + typedef enum { + RC_DWARF, /* 0 - Zwerg */ + RC_ELF, + RC_GOBLIN = 3, + RC_HUMAN, - RC_TROLL, - RC_DAEMON, - RC_INSECT, - RC_HALFLING, - RC_CAT, + RC_TROLL, + RC_DAEMON, + RC_INSECT, + RC_HALFLING, + RC_CAT, - RC_AQUARIAN, - RC_ORC, - RC_SNOTLING, - RC_UNDEAD, - RC_ILLUSION, + RC_AQUARIAN, + RC_ORC, + RC_SNOTLING, + RC_UNDEAD, + RC_ILLUSION, - RC_FIREDRAGON, - RC_DRAGON, - RC_WYRM, - RC_TREEMAN, - RC_BIRTHDAYDRAGON, + RC_FIREDRAGON, + RC_DRAGON, + RC_WYRM, + RC_TREEMAN, + RC_BIRTHDAYDRAGON, - RC_DRACOID, - RC_SPECIAL, - RC_SPELL, - RC_IRONGOLEM, - RC_STONEGOLEM, + RC_DRACOID, + RC_SPECIAL, + RC_SPELL, + RC_IRONGOLEM, + RC_STONEGOLEM, - RC_SHADOW, - RC_SHADOWLORD, - RC_IRONKEEPER, - RC_ALP, - RC_TOAD, + RC_SHADOW, + RC_SHADOWLORD, + RC_IRONKEEPER, + RC_ALP, + RC_TOAD, - RC_HIRNTOETER, - RC_PEASANT, - RC_WOLF = 32, + RC_HIRNTOETER, + RC_PEASANT, + RC_WOLF = 32, - RC_SONGDRAGON = 37, + RC_SONGDRAGON = 37, - RC_SEASERPENT = 51, - RC_SHADOWKNIGHT, - RC_CENTAUR, - RC_SKELETON, + RC_SEASERPENT = 51, + RC_SHADOWKNIGHT, + RC_CENTAUR, + RC_SKELETON, - RC_SKELETON_LORD, - RC_ZOMBIE, - RC_ZOMBIE_LORD, - RC_GHOUL, - RC_GHOUL_LORD, + RC_SKELETON_LORD, + RC_ZOMBIE, + RC_ZOMBIE_LORD, + RC_GHOUL, + RC_GHOUL_LORD, - RC_MUS_SPIRIT, - RC_GNOME, - RC_TEMPLATE, - RC_CLONE, + RC_MUS_SPIRIT, + RC_GNOME, + RC_TEMPLATE, + RC_CLONE, - MAXRACES, - NORACE = -1 - } race_t; + MAXRACES, + NORACE = -1 + } race_t; - typedef struct att { - int type; - union { - const char *dice; - const struct spell *sp; - } data; - int flags; - int level; - } att; + typedef struct att { + int type; + union { + const char *dice; + const struct spell *sp; + } data; + int flags; + int level; + } att; - extern int num_races; + extern int num_races; - typedef struct race { - struct param *parameters; - const char *_name; - float magres; - float maxaura; /* Faktor auf Maximale Aura */ - float regaura; /* Faktor auf Regeneration */ - float recruit_multi; /* Faktor für Bauernverbrauch */ - int index; - int recruitcost; - int maintenance; - int splitsize; - int weight; - int capacity; - float speed; - float aggression; /* chance that a monster will attack */ - int hitpoints; - const char *def_damage; - int armor; - int at_default; /* Angriffsskill Unbewaffnet (default: -2) */ - int df_default; /* Verteidigungsskill Unbewaffnet (default: -2) */ - int at_bonus; /* Verändert den Angriffsskill (default: 0) */ - int df_bonus; /* Verändert den Verteidigungskill (default: 0) */ - const struct spell *precombatspell; - struct att attack[10]; - signed char bonus[MAXSKILLS]; - signed char *study_speed; /* study-speed-bonus in points/turn (0=30 Tage) */ - bool __remove_me_nonplayer; - int flags; - int battle_flags; - int ec_flags; - race_t oldfamiliars[MAXMAGIETYP]; + typedef struct race { + struct param *parameters; + const char *_name; + float magres; + float maxaura; /* Faktor auf Maximale Aura */ + float regaura; /* Faktor auf Regeneration */ + float recruit_multi; /* Faktor für Bauernverbrauch */ + int index; + int recruitcost; + int maintenance; + int splitsize; + int weight; + int capacity; + float speed; + float aggression; /* chance that a monster will attack */ + int hitpoints; + const char *def_damage; + int armor; + int at_default; /* Angriffsskill Unbewaffnet (default: -2) */ + int df_default; /* Verteidigungsskill Unbewaffnet (default: -2) */ + int at_bonus; /* Verändert den Angriffsskill (default: 0) */ + int df_bonus; /* Verändert den Verteidigungskill (default: 0) */ + const struct spell *precombatspell; + struct att attack[10]; + signed char bonus[MAXSKILLS]; + signed char *study_speed; /* study-speed-bonus in points/turn (0=30 Tage) */ + bool __remove_me_nonplayer; + int flags; + int battle_flags; + int ec_flags; + race_t oldfamiliars[MAXMAGIETYP]; - const char *(*generate_name) (const struct unit *); - const char *(*describe) (const struct unit *, const struct locale *); - void (*age) (struct unit * u); - bool(*move_allowed) (const struct region *, const struct region *); - struct item *(*itemdrop) (const struct race *, int size); - void (*init_familiar) (struct unit *); + const char *(*generate_name) (const struct unit *); + const char *(*describe) (const struct unit *, const struct locale *); + void(*age) (struct unit * u); + bool(*move_allowed) (const struct region *, const struct region *); + struct item *(*itemdrop) (const struct race *, int size); + void(*init_familiar) (struct unit *); - const struct race *familiars[MAXMAGIETYP]; - struct attrib *attribs; - struct race *next; - } race; + const struct race *familiars[MAXMAGIETYP]; + struct attrib *attribs; + struct race *next; + } race; - typedef struct race_list { - struct race_list *next; - const struct race *data; - } race_list; + typedef struct race_list { + struct race_list *next; + const struct race *data; + } race_list; - extern void racelist_clear(struct race_list **rl); - extern void racelist_insert(struct race_list **rl, const struct race *r); + extern void racelist_clear(struct race_list **rl); + extern void racelist_insert(struct race_list **rl, const struct race *r); - struct race_list *get_familiarraces(void); - struct race *races; - struct race *get_race(race_t rt); - /** TODO: compatibility hacks: **/ - race_t old_race(const struct race *); + struct race_list *get_familiarraces(void); + struct race *races; + struct race *get_race(race_t rt); + /** TODO: compatibility hacks: **/ + race_t old_race(const struct race *); - extern race *rc_get_or_create(const char *name); - extern const race *rc_find(const char *); - void free_races(void); + extern race *rc_get_or_create(const char *name); + extern const race *rc_find(const char *); + void free_races(void); - typedef enum name_t { NAME_SINGULAR, NAME_PLURAL, NAME_DEFINITIVE, NAME_CATEGORY } name_t; - const char *rc_name(const race *, name_t); + typedef enum name_t { NAME_SINGULAR, NAME_PLURAL, NAME_DEFINITIVE, NAME_CATEGORY } name_t; + const char * rc_name_s(const race *rc, name_t n); + const char * rc_name(const race *rc, name_t n, char *name, size_t size); -/* Flags. Do not reorder these without changing json_race() in jsonconf.c */ + /* Flags. Do not reorder these without changing json_race() in jsonconf.c */ #define RCF_NPC (1<<0) /* cannot be the race for a player faction (and other limits?) */ #define RCF_KILLPEASANTS (1<<1) /* a monster that eats peasants */ #define RCF_SCAREPEASANTS (1<<2) /* a monster that scares peasants out of the hex */ @@ -214,7 +215,7 @@ extern "C" { #define RCF_STONEGOLEM (1<<27) /* race gets stonegolem properties */ #define RCF_IRONGOLEM (1<<28) /* race gets irongolem properties */ -/* Economic flags */ + /* Economic flags */ #define GIVEITEM (1<<1) /* gibt Gegenstände weg */ #define GIVEPERSON (1<<2) /* übergibt Personen */ #define GIVEUNIT (1<<3) /* Einheiten an andere Partei übergeben */ @@ -223,7 +224,7 @@ extern "C" { #define ECF_REC_ETHEREAL (1<<7) /* Rekrutiert aus dem Nichts */ #define ECF_REC_UNLIMITED (1<<8) /* Rekrutiert ohne Limit */ -/* Battle-Flags */ + /* Battle-Flags */ #define BF_EQUIPMENT (1<<0) /* Kann Ausrüstung benutzen */ #define BF_NOBLOCK (1<<1) /* Wird in die Rückzugsberechnung nicht einbezogen */ #define BF_RES_PIERCE (1<<2) /* Halber Schaden durch PIERCE */ @@ -232,9 +233,9 @@ extern "C" { #define BF_INV_NONMAGIC (1<<5) /* Immun gegen nichtmagischen Schaden */ #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 int unit_old_max_hp(struct unit *u); + extern const char *racename(const struct locale *lang, const struct unit *u, + const race * rc); #define omniscient(f) ((f)->race==get_race(RC_ILLUSION) || (f)->race==get_race(RC_TEMPLATE)) @@ -243,21 +244,21 @@ extern "C" { #define humanoidrace(rc) (fval((rc), RCF_UNDEAD) || (rc)==get_race(RC_DRACOID) || playerrace(rc)) #define illusionaryrace(rc) (fval(rc, RCF_ILLUSIONARY)) - extern bool allowed_dragon(const struct region *src, - const struct region *target); + extern bool allowed_dragon(const struct region *src, + const struct region *target); - extern bool r_insectstalled(const struct region *r); + extern bool r_insectstalled(const struct region *r); - extern void add_raceprefix(const char *); - extern char **race_prefixes; + extern void add_raceprefix(const char *); + extern char **race_prefixes; - extern void write_race_reference(const struct race *rc, + extern void write_race_reference(const struct race *rc, struct storage *store); - extern variant read_race_reference(struct storage *store); + extern variant read_race_reference(struct storage *store); - extern const char *raceprefix(const struct unit *u); + extern const char *raceprefix(const struct unit *u); - extern void give_starting_equipment(const struct equipment *eq, + extern void give_starting_equipment(const struct equipment *eq, struct unit *u); #ifdef __cplusplus diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index ed544cc48..31c058bea 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -9,10 +9,10 @@ static void test_rc_name(CuTest *tc) { struct race *rc = test_create_race("human"); - CuAssertStrEquals(tc, "race::human", rc_name(rc, NAME_SINGULAR)); - CuAssertStrEquals(tc, "race::human_p", rc_name(rc, NAME_PLURAL)); - CuAssertStrEquals(tc, "race::human_d", rc_name(rc, NAME_DEFINITIVE)); - CuAssertStrEquals(tc, "race::human_x", rc_name(rc, NAME_CATEGORY)); + CuAssertStrEquals(tc, "race::human", rc_name_s(rc, NAME_SINGULAR)); + CuAssertStrEquals(tc, "race::human_p", rc_name_s(rc, NAME_PLURAL)); + CuAssertStrEquals(tc, "race::human_d", rc_name_s(rc, NAME_DEFINITIVE)); + CuAssertStrEquals(tc, "race::human_x", rc_name_s(rc, NAME_CATEGORY)); } CuSuite *get_race_suite(void) diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 22f138ead..ddc1e0dc7 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1853,7 +1853,7 @@ char *write_unitname(const unit * u, char *buffer, size_t size) if (u->name) { slprintf(buffer, size, "%s (%s)", u->name, itoa36(u->no)); } else { - const char * name = rc_name(u->_race, u->number == 1 ? NAME_SINGULAR : NAME_PLURAL); + const char * name = rc_name_s(u->_race, u->number == 1 ? NAME_SINGULAR : NAME_PLURAL); slprintf(buffer, size, "%s (%s)", locale_string(u->faction->locale, name), itoa36(u->no)); } buffer[size - 1] = 0; @@ -1866,3 +1866,15 @@ const char *unitname(const unit * u) return write_unitname(u, ubuf, sizeof(name)); } +void update_monster_name(unit *u) { + char sing[32], plur[32]; + const struct locale *lang = u->faction->locale; + if (!u->name) return; + rc_name(u->_race, NAME_SINGULAR, sing, sizeof(sing)); + rc_name(u->_race, NAME_PLURAL, plur, sizeof(plur)); + if (strcmp(u->name, sing) == 0 || strcmp(u->name, plur) == 0 || + strcmp(u->name, locale_string(lang, sing)) == 0 || + strcmp(u->name, locale_string(lang, plur)) == 0) { + unit_setname(u, 0); + } +} diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 856e1ffe2..80fafae91 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -249,6 +249,7 @@ extern "C" { const char *unitname(const struct unit *u); char *write_unitname(const struct unit *u, char *buffer, size_t size); + void update_monster_name(struct unit *u); #ifdef __cplusplus } diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index 04996aafd..8af5504f8 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -150,8 +150,8 @@ static void test_unit_name_from_race(CuTest *tc) { u = test_create_unit(test_create_faction(test_create_race("human")), findregion(0, 0)); unit_setname(u, NULL); lang = get_or_create_locale("de"); - locale_setstring(lang, rc_name(u->_race, NAME_SINGULAR), "Mensch"); - locale_setstring(lang, rc_name(u->_race, NAME_PLURAL), "Menschen"); + locale_setstring(lang, rc_name_s(u->_race, NAME_SINGULAR), "Mensch"); + locale_setstring(lang, rc_name_s(u->_race, NAME_PLURAL), "Menschen"); _snprintf(name, sizeof(name), "Mensch (%s)", itoa36(u->no)); CuAssertStrEquals(tc, name, unitname(u)); @@ -163,12 +163,39 @@ static void test_unit_name_from_race(CuTest *tc) { test_cleanup(); } +static void test_update_monster_name(CuTest *tc) { + unit *u; + struct locale *lang; + + test_cleanup(); + test_create_world(); + u = test_create_unit(test_create_faction(test_create_race("human")), findregion(0, 0)); + lang = get_or_create_locale("de"); + locale_setstring(lang, rc_name_s(u->_race, NAME_SINGULAR), "Mensch"); + locale_setstring(lang, rc_name_s(u->_race, NAME_PLURAL), "Menschen"); + + unit_setname(u, "Hodor"); + update_monster_name(u); + CuAssertStrEquals(tc, "Hodor", u->name); + + unit_setname(u, "Mensch"); + update_monster_name(u); + CuAssertPtrEquals(tc, 0, u->name); + + unit_setname(u, "Menschen"); + update_monster_name(u); + CuAssertPtrEquals(tc, 0, u->name); + + test_cleanup(); +} + CuSuite *get_unit_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_scale_number); SUITE_ADD_TEST(suite, test_unit_name); SUITE_ADD_TEST(suite, test_unit_name_from_race); + SUITE_ADD_TEST(suite, test_update_monster_name); SUITE_ADD_TEST(suite, test_remove_empty_units); SUITE_ADD_TEST(suite, test_remove_units_ignores_spells); SUITE_ADD_TEST(suite, test_remove_units_without_faction); diff --git a/src/laws.c b/src/laws.c index bd2abc9d8..1f4af4a59 100755 --- a/src/laws.c +++ b/src/laws.c @@ -781,7 +781,7 @@ static void inactivefaction(faction * f) if (inactiveFILE) { fprintf(inactiveFILE, "%s:%s:%d:%d\n", factionid(f), - LOC(default_locale, rc_name(f->race, NAME_PLURAL)), + LOC(default_locale, rc_name_s(f->race, NAME_PLURAL)), modify(count_all(f)), turn - f->lastorders); fclose(inactiveFILE); @@ -2301,7 +2301,7 @@ static bool display_race(faction * f, unit * u, const race * rc) if (u && u_race(u) != rc) return false; - name = rc_name(rc, NAME_SINGULAR); + name = rc_name_s(rc, NAME_SINGULAR); bytes = slprintf(bufp, size, "%s: ", LOC(f->locale, name)); if (wrptr(&bufp, &size, bytes) != 0) diff --git a/src/modules/score.c b/src/modules/score.c index da9fc10a0..2706d0847 100644 --- a/src/modules/score.c +++ b/src/modules/score.c @@ -163,7 +163,7 @@ void score(void) f->score, f->score - average_score_of_age(f->age, f->age / 24 + 1), ((float)f->score / (float)allscores) * 100.0, (float)f->score / f->num_total, - f->name, LOC(default_locale, rc_name(f->race, NAME_SINGULAR)), factionid(f), + f->name, LOC(default_locale, rc_name_s(f->race, NAME_SINGULAR)), factionid(f), f->age); } fclose(scoreFP); diff --git a/src/monster.c b/src/monster.c index e413503b4..3683b7f09 100644 --- a/src/monster.c +++ b/src/monster.c @@ -243,4 +243,3 @@ void make_zombie(unit * u) u_setrace(u, get_race(RC_ZOMBIE)); u->irace = NULL; } - diff --git a/src/monster.h b/src/monster.h index 02eab5519..30095d924 100644 --- a/src/monster.h +++ b/src/monster.h @@ -1,7 +1,7 @@ /* Copyright (c) 1998-2010, Enno Rehling - Katja Zedel +Katja Zedel Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -22,14 +22,15 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif + struct unit; + + void monster_kills_peasants(struct unit *u); + bool monster_is_waiting(const struct unit *u); + struct faction *get_monsters(void); + struct faction *get_or_create_monsters(void); + void make_zombie(struct unit * u); + #define MONSTER_ID 666 - - void monster_kills_peasants(struct unit *u); - bool monster_is_waiting(const struct unit *u); - struct faction *get_monsters(void); - struct faction *get_or_create_monsters(void); - void make_zombie(struct unit * u); - #define is_monsters(f) (f && fval(f, FFL_NPC) && f==get_monsters()) diff --git a/src/monsters.c b/src/monsters.c index aa9fd20f4..659c47018 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -926,7 +926,7 @@ void spawn_dragons(void) if (verbosity >= 2) { log_printf(stdout, "%d %s in %s.\n", u->number, LOC(default_locale, - rc_name(u_race(u), (u->number==1) ? NAME_SINGULAR:NAME_PLURAL)), regionname(r, NULL)); + rc_name_s(u_race(u), (u->number==1) ? NAME_SINGULAR:NAME_PLURAL)), regionname(r, NULL)); } name_unit(u); @@ -1001,7 +1001,7 @@ void spawn_undead(void) if (verbosity >= 2) { log_printf(stdout, "%d %s in %s.\n", u->number, LOC(default_locale, - rc_name(u_race(u), (u->number == 1) ? NAME_SINGULAR : NAME_PLURAL)), regionname(r, NULL)); + rc_name_s(u_race(u), (u->number == 1) ? NAME_SINGULAR : NAME_PLURAL)), regionname(r, NULL)); } { diff --git a/src/names.c b/src/names.c index 1fb61930f..8f4ed75ce 100644 --- a/src/names.c +++ b/src/names.c @@ -215,7 +215,7 @@ const char *silbe3[SIL3] = { static const char *generic_name(const unit * u) { - const char * name = rc_name(u_race(u), (u->no == 1) ? NAME_SINGULAR : NAME_PLURAL); + const char * name = rc_name_s(u_race(u), (u->no == 1) ? NAME_SINGULAR : NAME_PLURAL); return LOC(u->faction->locale, name); } diff --git a/src/report.c b/src/report.c index 9f0c6ba32..1b21a4cc6 100644 --- a/src/report.c +++ b/src/report.c @@ -2179,7 +2179,7 @@ const char *charset) centre(F, gamedate_season(f->locale), true); rnl(F); sprintf(buf, "%s, %s/%s (%s)", factionname(f), - LOC(f->locale, rc_name(f->race, NAME_PLURAL)), + LOC(f->locale, rc_name_s(f->race, NAME_PLURAL)), LOC(f->locale, mkname("school", magic_school[f->magiegebiet])), f->email); centre(F, buf, true); if (f_get_alliance(f)) { diff --git a/src/reports.c b/src/reports.c index fba0eacea..2e0278775 100644 --- a/src/reports.c +++ b/src/reports.c @@ -2161,7 +2161,7 @@ static void eval_race(struct opstack **stack, const void *userdata) const struct locale *lang = report ? report->locale : default_locale; int j = opop(stack).i; const race *r = (const race *)opop(stack).v; - const char *c = LOC(lang, rc_name(r, (j == 1) ? NAME_SINGULAR : NAME_PLURAL)); + const char *c = LOC(lang, rc_name_s(r, (j == 1) ? NAME_SINGULAR : NAME_PLURAL)); size_t len = strlen(c); variant var; diff --git a/src/spells.c b/src/spells.c index 7929b004f..82714ed63 100644 --- a/src/spells.c +++ b/src/spells.c @@ -1546,7 +1546,7 @@ static int sp_create_irongolem(castorder * co) ADDMSG(&mage->faction->msgs, msg_message("magiccreate_effect", "region command unit amount object", mage->region, co->order, mage, number, - LOC(mage->faction->locale, rc_name(rc_find("irongolem"), (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); + LOC(mage->faction->locale, rc_name_s(rc_find("irongolem"), (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); return cast_level; } @@ -1607,7 +1607,7 @@ static int sp_create_stonegolem(castorder * co) ADDMSG(&mage->faction->msgs, msg_message("magiccreate_effect", "region command unit amount object", mage->region, co->order, mage, number, - LOC(mage->faction->locale, rc_name(rc_find("stonegolem"), (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); + LOC(mage->faction->locale, rc_name_s(rc_find("stonegolem"), (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); return cast_level; } @@ -5657,7 +5657,7 @@ int sp_showastral(castorder * co) } icat(u->number); scat(" "); - scat(LOC(mage->faction->locale, rc_name(u_race(u), (u->number==1) ? NAME_SINGULAR:NAME_PLURAL))); + scat(LOC(mage->faction->locale, rc_name_s(u_race(u), (u->number==1) ? NAME_SINGULAR:NAME_PLURAL))); scat(", Entfernung "); icat(distance(rl2->data, rt)); scat(")"); diff --git a/src/summary.c b/src/summary.c index df8bd1066..00b1eba8c 100644 --- a/src/summary.c +++ b/src/summary.c @@ -123,11 +123,11 @@ static void out_faction(FILE * file, const struct faction *f) if (alliances != NULL) { fprintf(file, "%s (%s/%d) (%.3s/%.3s), %d Einh., %d Pers., $%d, %d NMR\n", f->name, itoa36(f->no), f_get_alliance(f) ? f->alliance->id : 0, - LOC(default_locale, rc_name(f->race, NAME_SINGULAR)), magic_school[f->magiegebiet], + LOC(default_locale, rc_name_s(f->race, NAME_SINGULAR)), magic_school[f->magiegebiet], count_units(f), f->num_total, f->money, turn - f->lastorders); } else { fprintf(file, "%s (%.3s/%.3s), %d Einh., %d Pers., $%d, %d NMR\n", - factionname(f), LOC(default_locale, rc_name(f->race, NAME_SINGULAR)), + factionname(f), LOC(default_locale, rc_name_s(f->race, NAME_SINGULAR)), magic_school[f->magiegebiet], count_units(f), f->num_total, f->money, turn - f->lastorders); } @@ -216,7 +216,7 @@ void report_summary(summary * s, summary * o, bool full) if (i != RC_TEMPLATE && i != RC_CLONE && s->factionrace[i]) { const race *rc = get_race(i); if (rc && playerrace(rc)) { - fprintf(F, "%13s%s: %s\n", LOC(default_locale, rc_name(rc, NAME_CATEGORY)), + fprintf(F, "%13s%s: %s\n", LOC(default_locale, rc_name_s(rc, NAME_CATEGORY)), LOC(default_locale, "stat_tribe_p"), pcomp(s->factionrace[i], o->factionrace[i])); } @@ -246,7 +246,7 @@ void report_summary(summary * s, summary * o, bool full) for (i = 0; i < MAXRACES; i++) { if (s->poprace[i]) { const race *rc = get_race(i); - fprintf(F, "%20s: %s\n", LOC(default_locale, rc_name(rc, NAME_PLURAL)), + fprintf(F, "%20s: %s\n", LOC(default_locale, rc_name_s(rc, NAME_PLURAL)), rcomp(s->poprace[i], o->poprace[i])); } } @@ -255,7 +255,7 @@ void report_summary(summary * s, summary * o, bool full) if (i != RC_TEMPLATE && i != RC_CLONE && s->poprace[i]) { const race *rc = get_race(i); if (playerrace(rc)) { - fprintf(F, "%20s: %s\n", LOC(default_locale, rc_name(rc, NAME_PLURAL)), + fprintf(F, "%20s: %s\n", LOC(default_locale, rc_name_s(rc, NAME_PLURAL)), rcomp(s->poprace[i], o->poprace[i])); } } From 2c077c25e80d78063dd89d437fc379365de827df Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 9 Dec 2014 07:44:26 +0100 Subject: [PATCH 7/7] space savings: update data files, remove names from NPC units where their name is their race. --- src/kernel/save.c | 10 +++++++--- src/kernel/unit.c | 25 ++++++++++++++----------- src/kernel/unit.h | 2 +- src/kernel/unit.test.c | 18 ++++++++++++------ src/kernel/version.h | 4 ++-- 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/kernel/save.c b/src/kernel/save.c index c1140e9ca..153829ace 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -642,9 +642,6 @@ unit *read_unit(struct gamedata *data) READ_INT(data->store, &number); set_number(u, number); - - - READ_INT(data->store, &n); u->age = (short)n; @@ -1711,6 +1708,13 @@ int readgame(const char *filename, int backup) unit *u = read_unit(&gdata); sc_mage *mage; + if (gdata.version < AUTO_RACENAME_VERSION) { + if (u->name && fval(u->faction, FFL_NPC)) { + if (unit_name_equals_race(u)) { + unit_setname(u, NULL); + } + } + } assert(u->region == NULL); u->region = r; *up = u; diff --git a/src/kernel/unit.c b/src/kernel/unit.c index ddc1e0dc7..2170b888e 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1853,8 +1853,9 @@ char *write_unitname(const unit * u, char *buffer, size_t size) if (u->name) { slprintf(buffer, size, "%s (%s)", u->name, itoa36(u->no)); } else { + const struct locale * lang = u->faction ? u->faction->locale : default_locale; const char * name = rc_name_s(u->_race, u->number == 1 ? NAME_SINGULAR : NAME_PLURAL); - slprintf(buffer, size, "%s (%s)", locale_string(u->faction->locale, name), itoa36(u->no)); + slprintf(buffer, size, "%s (%s)", locale_string(lang, name), itoa36(u->no)); } buffer[size - 1] = 0; return buffer; @@ -1866,15 +1867,17 @@ const char *unitname(const unit * u) return write_unitname(u, ubuf, sizeof(name)); } -void update_monster_name(unit *u) { - char sing[32], plur[32]; - const struct locale *lang = u->faction->locale; - if (!u->name) return; - rc_name(u->_race, NAME_SINGULAR, sing, sizeof(sing)); - rc_name(u->_race, NAME_PLURAL, plur, sizeof(plur)); - if (strcmp(u->name, sing) == 0 || strcmp(u->name, plur) == 0 || - strcmp(u->name, locale_string(lang, sing)) == 0 || - strcmp(u->name, locale_string(lang, plur)) == 0) { - unit_setname(u, 0); +bool unit_name_equals_race(const unit *u) { + if (u->name) { + char sing[32], plur[32]; + const struct locale *lang = u->faction->locale; + rc_name(u->_race, NAME_SINGULAR, sing, sizeof(sing)); + rc_name(u->_race, NAME_PLURAL, plur, sizeof(plur)); + if (strcmp(u->name, sing) == 0 || strcmp(u->name, plur) == 0 || + strcmp(u->name, locale_string(lang, sing)) == 0 || + strcmp(u->name, locale_string(lang, plur)) == 0) { + return true; + } } + return false; } diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 80fafae91..bd5ffd493 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -249,7 +249,7 @@ extern "C" { const char *unitname(const struct unit *u); char *write_unitname(const struct unit *u, char *buffer, size_t size); - void update_monster_name(struct unit *u); + bool unit_name_equals_race(const struct unit *u); #ifdef __cplusplus } diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index 8af5504f8..76d708721 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -175,16 +175,22 @@ static void test_update_monster_name(CuTest *tc) { locale_setstring(lang, rc_name_s(u->_race, NAME_PLURAL), "Menschen"); unit_setname(u, "Hodor"); - update_monster_name(u); - CuAssertStrEquals(tc, "Hodor", u->name); + CuAssertTrue(tc, !unit_name_equals_race(u)); + + unit_setname(u, "Menschling"); + CuAssertTrue(tc, !unit_name_equals_race(u)); + + unit_setname(u, rc_name_s(u->_race, NAME_SINGULAR)); + CuAssertTrue(tc, unit_name_equals_race(u)); + + unit_setname(u, rc_name_s(u->_race, NAME_PLURAL)); + CuAssertTrue(tc, unit_name_equals_race(u)); unit_setname(u, "Mensch"); - update_monster_name(u); - CuAssertPtrEquals(tc, 0, u->name); + CuAssertTrue(tc, unit_name_equals_race(u)); unit_setname(u, "Menschen"); - update_monster_name(u); - CuAssertPtrEquals(tc, 0, u->name); + CuAssertTrue(tc, unit_name_equals_race(u)); test_cleanup(); } diff --git a/src/kernel/version.h b/src/kernel/version.h index 42f653070..e21c2c74b 100644 --- a/src/kernel/version.h +++ b/src/kernel/version.h @@ -73,8 +73,8 @@ #define INTFLAGS_VERSION 342 /* turn 876, FFL_NPC is now bit 25, flags is an int */ #define SAVEGAMEID_VERSION 343 /* instead of XMLNAME, save the game.id parameter from the config */ #define BUILDNO_VERSION 344 /* storing the build number in the save */ - +#define AUTO_RACENAME_VERSION 345 /* NPC units with name==NULL will automatically get their race for a name */ #define MIN_VERSION CURSETYPE_VERSION /* minimal datafile we support */ -#define RELEASE_VERSION BUILDNO_VERSION /* current datafile */ +#define RELEASE_VERSION AUTO_RACENAME_VERSION /* current datafile */ #define STREAM_VERSION 2 /* internal encoding of binary files */