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.
This commit is contained in:
Enno Rehling 2014-12-09 07:20:36 +01:00
parent bde56aa1f8
commit 0fead39b41
18 changed files with 230 additions and 185 deletions

View file

@ -341,7 +341,7 @@ static int cr_race(variant var, char *buffer, const void *userdata)
{ {
const faction *report = (const faction *)userdata; const faction *report = (const faction *)userdata;
const struct race *rc = (const race *)var.v; 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\"", sprintf(buffer, "\"%s\"",
translate(key, locale_string(report->locale, key))); translate(key, locale_string(report->locale, key)));
return 0; return 0;
@ -834,20 +834,20 @@ static void cr_output_unit(FILE * F, const region * r, const faction * f,
if (pzTmp) { if (pzTmp) {
fprintf(F, "\"%s\";Typ\n", pzTmp); fprintf(F, "\"%s\";Typ\n", pzTmp);
if (u->faction == f && fval(u_race(u), RCF_SHAPESHIFTANY)) { 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", fprintf(F, "\"%s\";wahrerTyp\n",
translate(zRace, locale_string(f->locale, zRace))); translate(zRace, locale_string(f->locale, zRace)));
} }
} }
else { else {
const race *irace = u_irace(u); 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", fprintf(F, "\"%s\";Typ\n",
translate(zRace, locale_string(f->locale, zRace))); translate(zRace, locale_string(f->locale, zRace)));
if (u->faction == f && irace != u_race(u)) { if (u->faction == f && irace != u_race(u)) {
assert(skill_enabled(SK_STEALTH) assert(skill_enabled(SK_STEALTH)
|| !"we're resetting this on load, so.. ircase should never be used"); || !"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", fprintf(F, "\"%s\";wahrerTyp\n",
translate(zRace, locale_string(f->locale, zRace))); 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); fprintf(F, "%d;Punktedurchschnitt\n", avgscore);
#endif #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))); fprintf(F, "\"%s\";Typ\n", translate(zRace, LOC(f->locale, zRace)));
} }
prefix = get_prefix(f->attribs); prefix = get_prefix(f->attribs);

View file

@ -304,7 +304,7 @@ const char *dbrace(const struct race *rc)
char *zPtr = zText; char *zPtr = zText;
/* the english names are all in ASCII, so we don't need to worry about UTF8 */ /* 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) { while (*zPtr) {
*zPtr = (char)(toupper(*zPtr)); *zPtr = (char)(toupper(*zPtr));
++zPtr; ++zPtr;
@ -1482,9 +1482,9 @@ void init_locale(struct locale *lang)
for (rc = races; rc; rc = rc->next) { for (rc = races; rc; rc = rc->next) {
const char *name; const char *name;
var.v = (void *)rc; 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); 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); if (name) addtoken(tokens, name, var);
} }

View file

@ -219,8 +219,7 @@ bool r_insectstalled(const region * r)
return fval(r->terrain, ARCTIC_REGION); 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; const char * postfix = 0;
if (!rc) { if (!rc) {
return NULL; return NULL;
@ -230,16 +229,21 @@ const char *rc_name(const race * rc, name_t n)
case NAME_PLURAL: postfix = "_p"; break; case NAME_PLURAL: postfix = "_p"; break;
case NAME_DEFINITIVE: postfix = "_d"; break; case NAME_DEFINITIVE: postfix = "_d"; break;
case NAME_CATEGORY: postfix = "_x"; 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) { if (postfix) {
static char name[64]; // FIXME: static return value _snprintf(name, size, "race::%s%s", rc->_name, postfix);
sprintf(name, "race::%s%s", rc->_name, postfix);
return name; return name;
} }
return NULL; 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 char *raceprefix(const unit * u)
{ {
const attrib *asource = u->faction->attribs; 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) if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER(); 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"); assert(~bufp[0] & 0x80 || !"unicode/not implemented");
ch = tolower(*(unsigned char *)bufp); ch = tolower(*(unsigned char *)bufp);
bufp[0] = (char)ch; bufp[0] = (char)ch;
@ -276,7 +280,7 @@ const char *racename(const struct locale *loc, const unit * u, const race * rc)
return lbuf; 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; return str ? str : rc->_name;
} }

View file

@ -1,7 +1,7 @@
/* /*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de> Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de> Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@ -40,150 +40,151 @@ extern "C" {
#define RACESPOILCHANCE 5 /* Chance auf rassentypische Beute */ #define RACESPOILCHANCE 5 /* Chance auf rassentypische Beute */
struct param; struct param;
struct spell; struct spell;
typedef enum { typedef enum {
RC_DWARF, /* 0 - Zwerg */ RC_DWARF, /* 0 - Zwerg */
RC_ELF, RC_ELF,
RC_GOBLIN = 3, RC_GOBLIN = 3,
RC_HUMAN, RC_HUMAN,
RC_TROLL, RC_TROLL,
RC_DAEMON, RC_DAEMON,
RC_INSECT, RC_INSECT,
RC_HALFLING, RC_HALFLING,
RC_CAT, RC_CAT,
RC_AQUARIAN, RC_AQUARIAN,
RC_ORC, RC_ORC,
RC_SNOTLING, RC_SNOTLING,
RC_UNDEAD, RC_UNDEAD,
RC_ILLUSION, RC_ILLUSION,
RC_FIREDRAGON, RC_FIREDRAGON,
RC_DRAGON, RC_DRAGON,
RC_WYRM, RC_WYRM,
RC_TREEMAN, RC_TREEMAN,
RC_BIRTHDAYDRAGON, RC_BIRTHDAYDRAGON,
RC_DRACOID, RC_DRACOID,
RC_SPECIAL, RC_SPECIAL,
RC_SPELL, RC_SPELL,
RC_IRONGOLEM, RC_IRONGOLEM,
RC_STONEGOLEM, RC_STONEGOLEM,
RC_SHADOW, RC_SHADOW,
RC_SHADOWLORD, RC_SHADOWLORD,
RC_IRONKEEPER, RC_IRONKEEPER,
RC_ALP, RC_ALP,
RC_TOAD, RC_TOAD,
RC_HIRNTOETER, RC_HIRNTOETER,
RC_PEASANT, RC_PEASANT,
RC_WOLF = 32, RC_WOLF = 32,
RC_SONGDRAGON = 37, RC_SONGDRAGON = 37,
RC_SEASERPENT = 51, RC_SEASERPENT = 51,
RC_SHADOWKNIGHT, RC_SHADOWKNIGHT,
RC_CENTAUR, RC_CENTAUR,
RC_SKELETON, RC_SKELETON,
RC_SKELETON_LORD, RC_SKELETON_LORD,
RC_ZOMBIE, RC_ZOMBIE,
RC_ZOMBIE_LORD, RC_ZOMBIE_LORD,
RC_GHOUL, RC_GHOUL,
RC_GHOUL_LORD, RC_GHOUL_LORD,
RC_MUS_SPIRIT, RC_MUS_SPIRIT,
RC_GNOME, RC_GNOME,
RC_TEMPLATE, RC_TEMPLATE,
RC_CLONE, RC_CLONE,
MAXRACES, MAXRACES,
NORACE = -1 NORACE = -1
} race_t; } race_t;
typedef struct att { typedef struct att {
int type; int type;
union { union {
const char *dice; const char *dice;
const struct spell *sp; const struct spell *sp;
} data; } data;
int flags; int flags;
int level; int level;
} att; } att;
extern int num_races; extern int num_races;
typedef struct race { typedef struct race {
struct param *parameters; struct param *parameters;
const char *_name; const char *_name;
float magres; float magres;
float maxaura; /* Faktor auf Maximale Aura */ float maxaura; /* Faktor auf Maximale Aura */
float regaura; /* Faktor auf Regeneration */ float regaura; /* Faktor auf Regeneration */
float recruit_multi; /* Faktor für Bauernverbrauch */ float recruit_multi; /* Faktor für Bauernverbrauch */
int index; int index;
int recruitcost; int recruitcost;
int maintenance; int maintenance;
int splitsize; int splitsize;
int weight; int weight;
int capacity; int capacity;
float speed; float speed;
float aggression; /* chance that a monster will attack */ float aggression; /* chance that a monster will attack */
int hitpoints; int hitpoints;
const char *def_damage; const char *def_damage;
int armor; int armor;
int at_default; /* Angriffsskill Unbewaffnet (default: -2) */ int at_default; /* Angriffsskill Unbewaffnet (default: -2) */
int df_default; /* Verteidigungsskill Unbewaffnet (default: -2) */ int df_default; /* Verteidigungsskill Unbewaffnet (default: -2) */
int at_bonus; /* Verändert den Angriffsskill (default: 0) */ int at_bonus; /* Verändert den Angriffsskill (default: 0) */
int df_bonus; /* Verändert den Verteidigungskill (default: 0) */ int df_bonus; /* Verändert den Verteidigungskill (default: 0) */
const struct spell *precombatspell; const struct spell *precombatspell;
struct att attack[10]; struct att attack[10];
signed char bonus[MAXSKILLS]; signed char bonus[MAXSKILLS];
signed char *study_speed; /* study-speed-bonus in points/turn (0=30 Tage) */ signed char *study_speed; /* study-speed-bonus in points/turn (0=30 Tage) */
bool __remove_me_nonplayer; bool __remove_me_nonplayer;
int flags; int flags;
int battle_flags; int battle_flags;
int ec_flags; int ec_flags;
race_t oldfamiliars[MAXMAGIETYP]; race_t oldfamiliars[MAXMAGIETYP];
const char *(*generate_name) (const struct unit *); const char *(*generate_name) (const struct unit *);
const char *(*describe) (const struct unit *, const struct locale *); const char *(*describe) (const struct unit *, const struct locale *);
void (*age) (struct unit * u); void(*age) (struct unit * u);
bool(*move_allowed) (const struct region *, const struct region *); bool(*move_allowed) (const struct region *, const struct region *);
struct item *(*itemdrop) (const struct race *, int size); struct item *(*itemdrop) (const struct race *, int size);
void (*init_familiar) (struct unit *); void(*init_familiar) (struct unit *);
const struct race *familiars[MAXMAGIETYP]; const struct race *familiars[MAXMAGIETYP];
struct attrib *attribs; struct attrib *attribs;
struct race *next; struct race *next;
} race; } race;
typedef struct race_list { typedef struct race_list {
struct race_list *next; struct race_list *next;
const struct race *data; const struct race *data;
} race_list; } race_list;
extern void racelist_clear(struct race_list **rl); extern void racelist_clear(struct race_list **rl);
extern void racelist_insert(struct race_list **rl, const struct race *r); extern void racelist_insert(struct race_list **rl, const struct race *r);
struct race_list *get_familiarraces(void); struct race_list *get_familiarraces(void);
struct race *races; struct race *races;
struct race *get_race(race_t rt); struct race *get_race(race_t rt);
/** TODO: compatibility hacks: **/ /** TODO: compatibility hacks: **/
race_t old_race(const struct race *); race_t old_race(const struct race *);
extern race *rc_get_or_create(const char *name); extern race *rc_get_or_create(const char *name);
extern const race *rc_find(const char *); extern const race *rc_find(const char *);
void free_races(void); void free_races(void);
typedef enum name_t { NAME_SINGULAR, NAME_PLURAL, NAME_DEFINITIVE, NAME_CATEGORY } name_t; typedef enum name_t { NAME_SINGULAR, NAME_PLURAL, NAME_DEFINITIVE, NAME_CATEGORY } name_t;
const char *rc_name(const race *, 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_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_KILLPEASANTS (1<<1) /* a monster that eats peasants */
#define RCF_SCAREPEASANTS (1<<2) /* a monster that scares peasants out of the hex */ #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_STONEGOLEM (1<<27) /* race gets stonegolem properties */
#define RCF_IRONGOLEM (1<<28) /* race gets irongolem properties */ #define RCF_IRONGOLEM (1<<28) /* race gets irongolem properties */
/* Economic flags */ /* Economic flags */
#define GIVEITEM (1<<1) /* gibt Gegenstände weg */ #define GIVEITEM (1<<1) /* gibt Gegenstände weg */
#define GIVEPERSON (1<<2) /* übergibt Personen */ #define GIVEPERSON (1<<2) /* übergibt Personen */
#define GIVEUNIT (1<<3) /* Einheiten an andere Partei übergeben */ #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_ETHEREAL (1<<7) /* Rekrutiert aus dem Nichts */
#define ECF_REC_UNLIMITED (1<<8) /* Rekrutiert ohne Limit */ #define ECF_REC_UNLIMITED (1<<8) /* Rekrutiert ohne Limit */
/* Battle-Flags */ /* Battle-Flags */
#define BF_EQUIPMENT (1<<0) /* Kann Ausrüstung benutzen */ #define BF_EQUIPMENT (1<<0) /* Kann Ausrüstung benutzen */
#define BF_NOBLOCK (1<<1) /* Wird in die Rückzugsberechnung nicht einbezogen */ #define BF_NOBLOCK (1<<1) /* Wird in die Rückzugsberechnung nicht einbezogen */
#define BF_RES_PIERCE (1<<2) /* Halber Schaden durch PIERCE */ #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_INV_NONMAGIC (1<<5) /* Immun gegen nichtmagischen Schaden */
#define BF_CANATTACK (1<<6) /* Kann keine ATTACKIERE Befehle ausfuehren */ #define BF_CANATTACK (1<<6) /* Kann keine ATTACKIERE Befehle ausfuehren */
extern int unit_old_max_hp(struct unit *u); extern int unit_old_max_hp(struct unit *u);
extern const char *racename(const struct locale *lang, const struct unit *u, extern const char *racename(const struct locale *lang, const struct unit *u,
const race * rc); const race * rc);
#define omniscient(f) ((f)->race==get_race(RC_ILLUSION) || (f)->race==get_race(RC_TEMPLATE)) #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 humanoidrace(rc) (fval((rc), RCF_UNDEAD) || (rc)==get_race(RC_DRACOID) || playerrace(rc))
#define illusionaryrace(rc) (fval(rc, RCF_ILLUSIONARY)) #define illusionaryrace(rc) (fval(rc, RCF_ILLUSIONARY))
extern bool allowed_dragon(const struct region *src, extern bool allowed_dragon(const struct region *src,
const struct region *target); 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 void add_raceprefix(const char *);
extern char **race_prefixes; 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); 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); struct unit *u);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -9,10 +9,10 @@
static void test_rc_name(CuTest *tc) { static void test_rc_name(CuTest *tc) {
struct race *rc = test_create_race("human"); struct race *rc = test_create_race("human");
CuAssertStrEquals(tc, "race::human", rc_name(rc, NAME_SINGULAR)); CuAssertStrEquals(tc, "race::human", rc_name_s(rc, NAME_SINGULAR));
CuAssertStrEquals(tc, "race::human_p", rc_name(rc, NAME_PLURAL)); CuAssertStrEquals(tc, "race::human_p", rc_name_s(rc, NAME_PLURAL));
CuAssertStrEquals(tc, "race::human_d", rc_name(rc, NAME_DEFINITIVE)); CuAssertStrEquals(tc, "race::human_d", rc_name_s(rc, NAME_DEFINITIVE));
CuAssertStrEquals(tc, "race::human_x", rc_name(rc, NAME_CATEGORY)); CuAssertStrEquals(tc, "race::human_x", rc_name_s(rc, NAME_CATEGORY));
} }
CuSuite *get_race_suite(void) CuSuite *get_race_suite(void)

View file

@ -1853,7 +1853,7 @@ char *write_unitname(const unit * u, char *buffer, size_t size)
if (u->name) { if (u->name) {
slprintf(buffer, size, "%s (%s)", u->name, itoa36(u->no)); slprintf(buffer, size, "%s (%s)", u->name, itoa36(u->no));
} else { } 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)); slprintf(buffer, size, "%s (%s)", locale_string(u->faction->locale, name), itoa36(u->no));
} }
buffer[size - 1] = 0; buffer[size - 1] = 0;
@ -1866,3 +1866,15 @@ const char *unitname(const unit * u)
return write_unitname(u, ubuf, sizeof(name)); 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);
}
}

View file

@ -249,6 +249,7 @@ extern "C" {
const char *unitname(const struct unit *u); const char *unitname(const struct unit *u);
char *write_unitname(const struct unit *u, char *buffer, size_t size); char *write_unitname(const struct unit *u, char *buffer, size_t size);
void update_monster_name(struct unit *u);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -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)); u = test_create_unit(test_create_faction(test_create_race("human")), findregion(0, 0));
unit_setname(u, NULL); unit_setname(u, NULL);
lang = get_or_create_locale("de"); lang = get_or_create_locale("de");
locale_setstring(lang, rc_name(u->_race, NAME_SINGULAR), "Mensch"); locale_setstring(lang, rc_name_s(u->_race, NAME_SINGULAR), "Mensch");
locale_setstring(lang, rc_name(u->_race, NAME_PLURAL), "Menschen"); locale_setstring(lang, rc_name_s(u->_race, NAME_PLURAL), "Menschen");
_snprintf(name, sizeof(name), "Mensch (%s)", itoa36(u->no)); _snprintf(name, sizeof(name), "Mensch (%s)", itoa36(u->no));
CuAssertStrEquals(tc, name, unitname(u)); CuAssertStrEquals(tc, name, unitname(u));
@ -163,12 +163,39 @@ static void test_unit_name_from_race(CuTest *tc) {
test_cleanup(); 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 *get_unit_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_scale_number); SUITE_ADD_TEST(suite, test_scale_number);
SUITE_ADD_TEST(suite, test_unit_name); SUITE_ADD_TEST(suite, test_unit_name);
SUITE_ADD_TEST(suite, test_unit_name_from_race); 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_empty_units);
SUITE_ADD_TEST(suite, test_remove_units_ignores_spells); SUITE_ADD_TEST(suite, test_remove_units_ignores_spells);
SUITE_ADD_TEST(suite, test_remove_units_without_faction); SUITE_ADD_TEST(suite, test_remove_units_without_faction);

View file

@ -781,7 +781,7 @@ static void inactivefaction(faction * f)
if (inactiveFILE) { if (inactiveFILE) {
fprintf(inactiveFILE, "%s:%s:%d:%d\n", fprintf(inactiveFILE, "%s:%s:%d:%d\n",
factionid(f), 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); modify(count_all(f)), turn - f->lastorders);
fclose(inactiveFILE); fclose(inactiveFILE);
@ -2301,7 +2301,7 @@ static bool display_race(faction * f, unit * u, const race * rc)
if (u && u_race(u) != rc) if (u && u_race(u) != rc)
return false; return false;
name = rc_name(rc, NAME_SINGULAR); name = rc_name_s(rc, NAME_SINGULAR);
bytes = slprintf(bufp, size, "%s: ", LOC(f->locale, name)); bytes = slprintf(bufp, size, "%s: ", LOC(f->locale, name));
if (wrptr(&bufp, &size, bytes) != 0) if (wrptr(&bufp, &size, bytes) != 0)

View file

@ -163,7 +163,7 @@ void score(void)
f->score, f->score - average_score_of_age(f->age, f->age / 24 + 1), f->score, f->score - average_score_of_age(f->age, f->age / 24 + 1),
((float)f->score / (float)allscores) * 100.0, ((float)f->score / (float)allscores) * 100.0,
(float)f->score / f->num_total, (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); f->age);
} }
fclose(scoreFP); fclose(scoreFP);

View file

@ -243,4 +243,3 @@ void make_zombie(unit * u)
u_setrace(u, get_race(RC_ZOMBIE)); u_setrace(u, get_race(RC_ZOMBIE));
u->irace = NULL; u->irace = NULL;
} }

View file

@ -1,7 +1,7 @@
/* /*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de> Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de> Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above 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" { extern "C" {
#endif #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 #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()) #define is_monsters(f) (f && fval(f, FFL_NPC) && f==get_monsters())

View file

@ -926,7 +926,7 @@ void spawn_dragons(void)
if (verbosity >= 2) { if (verbosity >= 2) {
log_printf(stdout, "%d %s in %s.\n", u->number, log_printf(stdout, "%d %s in %s.\n", u->number,
LOC(default_locale, 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); name_unit(u);
@ -1001,7 +1001,7 @@ void spawn_undead(void)
if (verbosity >= 2) { if (verbosity >= 2) {
log_printf(stdout, "%d %s in %s.\n", u->number, log_printf(stdout, "%d %s in %s.\n", u->number,
LOC(default_locale, 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));
} }
{ {

View file

@ -215,7 +215,7 @@ const char *silbe3[SIL3] = {
static const char *generic_name(const unit * u) 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); return LOC(u->faction->locale, name);
} }

View file

@ -2179,7 +2179,7 @@ const char *charset)
centre(F, gamedate_season(f->locale), true); centre(F, gamedate_season(f->locale), true);
rnl(F); rnl(F);
sprintf(buf, "%s, %s/%s (%s)", factionname(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); LOC(f->locale, mkname("school", magic_school[f->magiegebiet])), f->email);
centre(F, buf, true); centre(F, buf, true);
if (f_get_alliance(f)) { if (f_get_alliance(f)) {

View file

@ -2161,7 +2161,7 @@ static void eval_race(struct opstack **stack, const void *userdata)
const struct locale *lang = report ? report->locale : default_locale; const struct locale *lang = report ? report->locale : default_locale;
int j = opop(stack).i; int j = opop(stack).i;
const race *r = (const race *)opop(stack).v; 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); size_t len = strlen(c);
variant var; variant var;

View file

@ -1546,7 +1546,7 @@ static int sp_create_irongolem(castorder * co)
ADDMSG(&mage->faction->msgs, ADDMSG(&mage->faction->msgs,
msg_message("magiccreate_effect", "region command unit amount object", msg_message("magiccreate_effect", "region command unit amount object",
mage->region, co->order, mage, number, 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; return cast_level;
} }
@ -1607,7 +1607,7 @@ static int sp_create_stonegolem(castorder * co)
ADDMSG(&mage->faction->msgs, ADDMSG(&mage->faction->msgs,
msg_message("magiccreate_effect", "region command unit amount object", msg_message("magiccreate_effect", "region command unit amount object",
mage->region, co->order, mage, number, 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; return cast_level;
} }
@ -5657,7 +5657,7 @@ int sp_showastral(castorder * co)
} }
icat(u->number); icat(u->number);
scat(" "); 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 "); scat(", Entfernung ");
icat(distance(rl2->data, rt)); icat(distance(rl2->data, rt));
scat(")"); scat(")");

View file

@ -123,11 +123,11 @@ static void out_faction(FILE * file, const struct faction *f)
if (alliances != NULL) { if (alliances != NULL) {
fprintf(file, "%s (%s/%d) (%.3s/%.3s), %d Einh., %d Pers., $%d, %d NMR\n", 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, 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); count_units(f), f->num_total, f->money, turn - f->lastorders);
} else { } else {
fprintf(file, "%s (%.3s/%.3s), %d Einh., %d Pers., $%d, %d NMR\n", 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, magic_school[f->magiegebiet], count_units(f), f->num_total, f->money,
turn - f->lastorders); 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]) { if (i != RC_TEMPLATE && i != RC_CLONE && s->factionrace[i]) {
const race *rc = get_race(i); const race *rc = get_race(i);
if (rc && playerrace(rc)) { 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], LOC(default_locale, "stat_tribe_p"), pcomp(s->factionrace[i],
o->factionrace[i])); o->factionrace[i]));
} }
@ -246,7 +246,7 @@ void report_summary(summary * s, summary * o, bool full)
for (i = 0; i < MAXRACES; i++) { for (i = 0; i < MAXRACES; i++) {
if (s->poprace[i]) { if (s->poprace[i]) {
const race *rc = get_race(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])); 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]) { if (i != RC_TEMPLATE && i != RC_CLONE && s->poprace[i]) {
const race *rc = get_race(i); const race *rc = get_race(i);
if (playerrace(rc)) { 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])); rcomp(s->poprace[i], o->poprace[i]));
} }
} }