diff --git a/res/eressea/races.xml b/res/eressea/races.xml
index 6deefacc9..986e2b85f 100644
--- a/res/eressea/races.xml
+++ b/res/eressea/races.xml
@@ -701,7 +701,7 @@
-
+
diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua
index 3576b7349..eb118c931 100644
--- a/scripts/tests/e2/e2features.lua
+++ b/scripts/tests/e2/e2features.lua
@@ -254,7 +254,7 @@ function test_can_give_person()
end
function test_no_uruk()
- local f1 = faction.create("uruk", "noreply@eressea.de", "de")
+ local f1 = faction.create("uruk")
assert_equal(f1.race, "orc")
end
@@ -349,7 +349,7 @@ end
function test_stonegolems()
local r0 = region.create(0, 0, "plain")
- local f1 = faction.create("stonegolem", "noreply@eressea.de", "de")
+ local f1 = faction.create("stonegolem")
local u1 = unit.create(f1, r0, 1)
local u2 = unit.create(f1, r0, 2)
local c1 = building.create(r0, "castle")
@@ -378,10 +378,29 @@ end
function test_birthdaycake()
r = region.create(0,0, "plain")
- f = faction.create("human", "cake@eressea.de", "de")
+ f = faction.create("human")
u = unit.create(f, r, 1)
u:add_item("birthdaycake", 1)
u:clear_orders()
u:add_order("ZEIGE Geburtstagstorte")
process_orders()
end
+
+function test_demonstealth()
+ local desc, r, f, u
+ r = region.create(0, 0, "plain")
+ f = faction.create("demon")
+ u = unit.create(f, r, 1)
+
+ u:clear_orders()
+ u:add_order("TARNE Zwerg")
+ process_orders()
+ desc = u:show()
+ assert_not_nil(string.find(desc, "Zwerg"))
+
+ u:clear_orders()
+ u:add_order("TARNE Drache")
+ process_orders()
+ desc = u:show()
+ assert_equal(nil, string.find(desc, "Drache"))
+end
diff --git a/src/kernel/config.c b/src/kernel/config.c
index 1d005c9c1..02ed9894d 100644
--- a/src/kernel/config.c
+++ b/src/kernel/config.c
@@ -365,13 +365,26 @@ void init_options_translation(const struct locale * lang) {
}
}
-void init_locale(struct locale *lang)
+void init_races(struct locale *lang)
{
- variant var;
- int i;
const struct race *rc;
void **tokens;
+ tokens = get_translations(lang, UT_RACES);
+ for (rc = races; rc; rc = rc->next) {
+ const char *name;
+ variant var;
+ var.v = (void *)rc;
+ name = locale_string(lang, rc_name_s(rc, NAME_PLURAL), false);
+ if (name) addtoken((struct tnode **)tokens, name, var);
+ name = locale_string(lang, rc_name_s(rc, NAME_SINGULAR), false);
+ if (name) addtoken((struct tnode **)tokens, name, var);
+ }
+}
+
+static void init_magic(struct locale *lang)
+{
+ void **tokens;
tokens = get_translations(lang, UT_MAGIC);
if (tokens) {
const char *str = config_get("rules.magic.playerschools");
@@ -383,7 +396,9 @@ void init_locale(struct locale *lang)
sstr = strdup(str);
tok = strtok(sstr, " ");
while (tok) {
+ variant var;
const char *name;
+ int i;
for (i = 0; i != MAXMAGIETYP; ++i) {
if (strcmp(tok, magic_school[i]) == 0) break;
}
@@ -400,21 +415,14 @@ void init_locale(struct locale *lang)
}
free(sstr);
}
-
+}
+void init_locale(struct locale *lang)
+{
+ init_magic(lang);
init_directions(lang);
init_keywords(lang);
init_skills(lang);
-
- tokens = get_translations(lang, UT_RACES);
- for (rc = races; rc; rc = rc->next) {
- const char *name;
- var.v = (void *)rc;
- name = locale_string(lang, rc_name_s(rc, NAME_PLURAL), false);
- if (name) addtoken((struct tnode **)tokens, name, var);
- name = locale_string(lang, rc_name_s(rc, NAME_SINGULAR), false);
- if (name) addtoken((struct tnode **)tokens, name, var);
- }
-
+ init_races(lang);
init_parameters(lang);
init_options_translation(lang);
diff --git a/src/kernel/config.h b/src/kernel/config.h
index a4378332d..f80214fde 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -56,6 +56,7 @@ extern "C" {
/* returns a value between [0..xpct_2], generated with two dice */
void init_locale(struct locale *lang);
+ void init_races(struct locale *lang);
int forbiddenid(int id);
int newcontainerid(void);
diff --git a/src/kernel/race.c b/src/kernel/race.c
index 8a8cc906e..a2c37d87d 100644
--- a/src/kernel/race.c
+++ b/src/kernel/race.c
@@ -65,7 +65,7 @@ race *races;
int num_races = 0;
static int rc_changes = 1;
-static const char *racenames[MAXRACES] = {
+const char *racenames[MAXRACES] = {
"dwarf", "elf", NULL, "goblin", "human", "troll", "demon", "insect",
"halfling", "cat", "aquarian", "orc", "snotling", "undead", NULL,
"youngdragon", "dragon", "wyrm", "ent", "catdragon", "dracoid",
@@ -168,6 +168,7 @@ const struct race *findrace(const char *s, const struct locale *lang)
const struct race *get_race(race_t rt) {
const char * name;
+ assert(rt >= 0);
assert(rt < MAXRACES);
name = racenames[rt];
if (!name) {
@@ -484,11 +485,9 @@ void rc_set_param(struct race *rc, const char *key, const char *value) {
}
}
-const char* rc_name(const race * rc, name_t n, char *name, size_t size) {
+const char* rc_key(const char *rcname, name_t n, char *name, size_t size)
+{
const char * postfix = 0;
- if (!rc) {
- return NULL;
- }
switch (n) {
case NAME_SINGULAR: postfix = ""; break;
case NAME_PLURAL: postfix = "_p"; break;
@@ -497,12 +496,20 @@ const char* rc_name(const race * rc, name_t n, char *name, size_t size) {
default: assert(!"invalid name_t enum in rc_name_s");
}
if (postfix) {
- snprintf(name, size, "race::%s%s", rc->_name, postfix);
+ snprintf(name, size, "race::%s%s", rcname, postfix);
return name;
}
return NULL;
}
+const char* rc_name(const race * rc, name_t n, char *name, size_t size)
+{
+ if (!rc) {
+ return NULL;
+ }
+ return rc_key(rc->_name, n, name, size);
+}
+
const char *rc_name_s(const race * rc, name_t n)
{
static char name[64]; /* FIXME: static return value */
diff --git a/src/kernel/race.h b/src/kernel/race.h
index fcd78ae19..5c320ea05 100644
--- a/src/kernel/race.h
+++ b/src/kernel/race.h
@@ -50,8 +50,6 @@ extern "C" {
struct rcoption;
struct item_type;
- extern int num_races;
-
typedef enum {
RC_DWARF, /* 0 - Zwerg */
RC_ELF,
@@ -103,6 +101,9 @@ extern "C" {
NORACE = -1
} race_t;
+ extern int num_races;
+ extern const char *racenames[MAXRACES];
+
typedef struct att {
int type;
union {
@@ -180,6 +181,7 @@ extern "C" {
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_key(const char *rcname, name_t n, char *name, size_t size);
const char * rc_name(const race *rc, name_t n, char *name, size_t size);
void rc_set_param(struct race *rc, const char *key, const char *value);
diff --git a/src/kernel/region.c b/src/kernel/region.c
index 2a54a2eaa..0e45c59bb 100644
--- a/src/kernel/region.c
+++ b/src/kernel/region.c
@@ -1505,6 +1505,7 @@ int owner_change(const region * r)
bool is_mourning(const region * r, int in_turn)
{
int change = owner_change(r);
- return (change == in_turn - 1 && r->land->ownership->last_owner && r->land->ownership->owner
- && r->land->ownership->last_owner != r->land->ownership->owner);
+ return (change == in_turn - 1 && r->land &&
+ r->land->ownership->last_owner && r->land->ownership->owner &&
+ r->land->ownership->last_owner != r->land->ownership->owner);
}
diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c
index d8aaae6ec..096da9d62 100644
--- a/src/kernel/unit.test.c
+++ b/src/kernel/unit.test.c
@@ -153,42 +153,37 @@ static void test_unit_name(CuTest *tc) {
static void test_unit_name_from_race(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));
+ test_setup();
+ u = test_create_unit(test_create_faction(test_create_race("human")), test_create_region(0, 0, NULL));
renumber_unit(u, 666);
unit_setname(u, NULL);
- 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");
- CuAssertStrEquals(tc, "Mensch (ii)", unitname(u));
- CuAssertStrEquals(tc, "Mensch", unit_getname(u));
+ CuAssertStrEquals(tc, "human (ii)", unitname(u));
+ CuAssertStrEquals(tc, "human", unit_getname(u));
u->number = 2;
- CuAssertStrEquals(tc, "Menschen (ii)", unitname(u));
- CuAssertStrEquals(tc, "Menschen", unit_getname(u));
+ CuAssertStrEquals(tc, "human_p (ii)", unitname(u));
+ CuAssertStrEquals(tc, "human_p", unit_getname(u));
test_cleanup();
}
static void test_update_monster_name(CuTest *tc) {
unit *u;
- struct locale *lang;
+ race *rc;
- 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");
+ test_setup();
+ rc = test_create_race("human");
+ u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL));
unit_setname(u, "Hodor");
CuAssertTrue(tc, !unit_name_equals_race(u));
- unit_setname(u, "Menschling");
+ unit_setname(u, "humanitarian");
+ CuAssertTrue(tc, !unit_name_equals_race(u));
+
+ unit_setname(u, "huma");
CuAssertTrue(tc, !unit_name_equals_race(u));
unit_setname(u, rc_name_s(u->_race, NAME_SINGULAR));
@@ -197,12 +192,6 @@ static void test_update_monster_name(CuTest *tc) {
unit_setname(u, rc_name_s(u->_race, NAME_PLURAL));
CuAssertTrue(tc, unit_name_equals_race(u));
- unit_setname(u, "Mensch");
- CuAssertTrue(tc, unit_name_equals_race(u));
-
- unit_setname(u, "Menschen");
- CuAssertTrue(tc, unit_name_equals_race(u));
-
test_cleanup();
}
diff --git a/src/laws.c b/src/laws.c
index adf8b9f11..af96a309c 100644
--- a/src/laws.c
+++ b/src/laws.c
@@ -1584,7 +1584,9 @@ int display_cmd(unit * u, struct order *ord)
free(*s);
if (s2) {
char * str = strdup(s2);
- unicode_utf8_trim(str);
+ if (unicode_utf8_trim(str) != 0) {
+ log_info("trimming info: %s", s2);
+ }
if (strlen(str) >= DISPLAYSIZE) {
str[DISPLAYSIZE-1] = 0;
}
@@ -1626,7 +1628,9 @@ static int rename_cmd(unit * u, order * ord, char **s, const char *s2)
/* TODO: Validate to make sure people don't have illegal characters in
* names, phishing-style? () come to mind. */
strlcpy(name, s2, sizeof(name));
- unicode_utf8_trim(name);
+ if (unicode_utf8_trim(name) != 0) {
+ log_info("trimming name: %s", s2);
+ }
free(*s);
*s = strdup(name);
diff --git a/src/monsters.c b/src/monsters.c
index 4edaeedea..21a3583af 100644
--- a/src/monsters.c
+++ b/src/monsters.c
@@ -738,7 +738,7 @@ void plan_monsters(faction * f)
order *long_order = NULL;
/* Ab hier nur noch Befehle für NPC-Einheiten. */
- if (!is_monsters(u->faction))
+ if (u->faction!=f)
continue;
/* Befehle müssen jede Runde neu gegeben werden: */
diff --git a/src/spy.c b/src/spy.c
index 08662ea8e..837bc28ee 100644
--- a/src/spy.c
+++ b/src/spy.c
@@ -247,24 +247,16 @@ int setstealth_cmd(unit * u, struct order *ord)
if (trace) {
/* demons can cloak as other player-races */
if (u_race(u) == get_race(RC_DAEMON)) {
- race_t allowed[] = { RC_DWARF, RC_ELF, RC_ORC, RC_GOBLIN, RC_HUMAN,
- RC_TROLL, RC_DAEMON, RC_INSECT, RC_HALFLING, RC_CAT, RC_AQUARIAN,
- NORACE
- };
- int i;
- for (i = 0; allowed[i] != NORACE; ++i)
- if (get_race(allowed[i]) == trace)
- break;
- if (get_race(allowed[i]) == trace) {
+ if (playerrace(trace)) {
u->irace = trace;
- if (u_race(u)->flags & RCF_SHAPESHIFTANY && get_racename(u->attribs))
+ if (u_race(u)->flags & RCF_SHAPESHIFTANY && get_racename(u->attribs)) {
set_racename(&u->attribs, NULL);
+ }
}
return 0;
}
-
/* Singdrachen koennen sich nur als Drachen tarnen */
- if (u_race(u) == get_race(RC_SONGDRAGON)
+ else if (u_race(u) == get_race(RC_SONGDRAGON)
|| u_race(u) == get_race(RC_BIRTHDAYDRAGON)) {
if (trace == get_race(RC_SONGDRAGON) || trace == get_race(RC_FIREDRAGON)
|| trace == get_race(RC_DRAGON) || trace == get_race(RC_WYRM)) {
diff --git a/src/spy.test.c b/src/spy.test.c
index 190cb09a5..11c8c1ff1 100644
--- a/src/spy.test.c
+++ b/src/spy.test.c
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -130,21 +131,55 @@ static void test_sabotage_other_fail(CuTest *tc) {
static void test_setstealth_cmd(CuTest *tc) {
unit *u;
const struct locale *lang;
-
+
test_setup();
- u = test_create_unit(test_create_faction(0), test_create_region(0,0,0));
+ u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
lang = u->faction->locale;
- u->flags = UFL_ANON_FACTION|UFL_SIEGE;
+ u->flags = UFL_ANON_FACTION | UFL_SIEGE;
u->thisorder = create_order(K_SETSTEALTH, lang, "%s %s",
- LOC(lang, parameters[P_FACTION]),
- LOC(lang, parameters[P_NOT]));
+ LOC(lang, parameters[P_FACTION]),
+ LOC(lang, parameters[P_NOT]));
setstealth_cmd(u, u->thisorder);
CuAssertIntEquals(tc, UFL_SIEGE, u->flags);
free_order(u->thisorder);
u->thisorder = create_order(K_SETSTEALTH, lang, "%s",
- LOC(lang, parameters[P_FACTION]));
+ LOC(lang, parameters[P_FACTION]));
setstealth_cmd(u, u->thisorder);
- CuAssertIntEquals(tc, UFL_SIEGE|UFL_ANON_FACTION, u->flags);
+ CuAssertIntEquals(tc, UFL_SIEGE | UFL_ANON_FACTION, u->flags);
+ test_cleanup();
+}
+
+static void test_setstealth_demon(CuTest *tc) {
+ unit *u;
+ struct locale *lang;
+ struct race *rc;
+
+ test_setup();
+ lang = test_create_locale();
+ rc = test_create_race("demon");
+ u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0));
+ rc = test_create_race("dwarf");
+ init_races(lang);
+ u->thisorder = create_order(K_SETSTEALTH, lang, racename(lang, u, rc));
+ setstealth_cmd(u, u->thisorder);
+ CuAssertPtrEquals(tc, (void *)rc, (void *)u->irace);
+ test_cleanup();
+}
+
+static void test_setstealth_demon_bad(CuTest *tc) {
+ unit *u;
+ struct locale *lang;
+ struct race *rc;
+
+ test_setup();
+ lang = test_create_locale();
+ rc = test_create_race("demon");
+ u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0));
+ rc = test_create_race("smurf");
+ init_races(lang);
+ u->thisorder = create_order(K_SETSTEALTH, lang, racename(lang, u, rc));
+ setstealth_cmd(u, u->thisorder);
+ CuAssertPtrEquals(tc, NULL, (void *)u->irace);
test_cleanup();
}
@@ -180,6 +215,8 @@ CuSuite *get_spy_suite(void)
SUITE_ADD_TEST(suite, test_all_spy_message);
SUITE_ADD_TEST(suite, test_sabotage_self);
SUITE_ADD_TEST(suite, test_setstealth_cmd);
+ SUITE_ADD_TEST(suite, test_setstealth_demon);
+ SUITE_ADD_TEST(suite, test_setstealth_demon_bad);
SUITE_ADD_TEST(suite, test_sabotage_other_fail);
SUITE_ADD_TEST(suite, test_sabotage_other_success);
return suite;
diff --git a/src/tests.c b/src/tests.c
index faa8f6e2e..a9b4878b6 100644
--- a/src/tests.c
+++ b/src/tests.c
@@ -96,8 +96,19 @@ struct locale * test_create_locale(void) {
locale_setstring(loc, "stone_p", "Steine");
locale_setstring(loc, "plain", "Ebene");
locale_setstring(loc, "ocean", "Ozean");
- locale_setstring(loc, "race::human", "Mensch");
- locale_setstring(loc, "race::human_p", "Menschen");
+ for (i = 0; i < MAXRACES; ++i) {
+ if (racenames[i]) {
+ char name[64];
+ rc_key(racenames[i], NAME_PLURAL, name, sizeof(name));
+ if (!locale_getstring(loc, name)) {
+ locale_setstring(loc, name, name + 6);
+ }
+ rc_key(racenames[i], NAME_SINGULAR, name, sizeof(name));
+ if (!locale_getstring(loc, name)) {
+ locale_setstring(loc, name, name + 6);
+ }
+ }
+ }
for (i = 0; i < MAXSKILLS; ++i) {
if (!locale_getstring(loc, mkname("skill", skillnames[i])))
locale_setstring(loc, mkname("skill", skillnames[i]), skillnames[i]);