diff --git a/res/eressea/races.xml b/res/eressea/races.xml
index 9063fbe1d..71eacc458 100644
--- a/res/eressea/races.xml
+++ b/res/eressea/races.xml
@@ -689,7 +689,7 @@
-
+
@@ -840,7 +840,10 @@
-
+
diff --git a/src/attributes/racename.c b/src/attributes/racename.c
index 138355e3c..901630731 100644
--- a/src/attributes/racename.c
+++ b/src/attributes/racename.c
@@ -24,17 +24,20 @@ const char *get_racename(attrib * alist)
void set_racename(attrib ** palist, const char *name)
{
attrib *a = a_find(*palist, &at_racename);
- if (!a && name) {
+
+ if (a) {
+ if (name) {
+ if (strcmp(a->data.v, name) != 0) {
+ free(a->data.v);
+ a->data.v = str_strdup(name);
+ }
+ }
+ else {
+ a_remove(palist, a);
+ }
+ }
+ else if (name) {
a = a_add(palist, a_new(&at_racename));
a->data.v = str_strdup(name);
}
- else if (a && !name) {
- a_remove(palist, a);
- }
- else if (a) {
- if (strcmp(a->data.v, name) != 0) {
- free(a->data.v);
- a->data.v = str_strdup(name);
- }
- }
}
diff --git a/src/creport.c b/src/creport.c
index 7773cdea4..4f92fe132 100644
--- a/src/creport.c
+++ b/src/creport.c
@@ -798,18 +798,15 @@ void cr_output_unit(stream *out, const faction * f,
pzTmp = get_racename(u->attribs);
if (pzTmp) {
- char buffer[64];
- const char *key = rc_key(pzTmp, NAME_PLURAL, buffer, sizeof(buffer));
- const char *pzRace = locale_string(lang, key, false);
- if (pzRace) {
- /* ex: "Ritter von Go */
- pzTmp = pzRace;
+ const race *irace = rc_find(pzTmp);
+ if (irace) {
+ const char *pzRace = rc_name_s(irace, NAME_PLURAL);
+ stream_printf(out, "\"%s\";Typ\n",
+ translate(pzRace, LOC(lang, pzRace)));
}
- pzRace = translate(key, pzTmp);
- if (!pzRace) {
- pzRace = pzTmp;
+ else {
+ stream_printf(out, "\"%s\";Typ\n", pzTmp);
}
- stream_printf(out, "\"%s\";Typ\n", pzRace);
}
else {
const race *irace = u_irace(u);
diff --git a/src/creport.test.c b/src/creport.test.c
index 53b2e9d93..a17fca6de 100644
--- a/src/creport.test.c
+++ b/src/creport.test.c
@@ -299,15 +299,27 @@ static void test_cr_hiderace(CuTest *tc) {
/* when we use racename, nobody can tell it's not the real deal */
u->irace = NULL;
- set_racename(&u->attribs, "Zwerge");
+ set_racename(&u->attribs, "human");
mstream_init(&strm);
cr_output_unit(&strm, f1, u, seen_unit);
- CuAssertTrue(tc, cr_find_string(&strm, ";Typ", "Zwerge"));
+ CuAssertTrue(tc, cr_find_string(&strm, ";Typ", "Menschen"));
CuAssertTrue(tc, cr_find_string(&strm, ";wahrerTyp", NULL));
mstream_done(&strm);
mstream_init(&strm);
cr_output_unit(&strm, f2, u, seen_unit);
- CuAssertTrue(tc, cr_find_string(&strm, ";Typ", "Zwerge"));
+ CuAssertTrue(tc, cr_find_string(&strm, ";Typ", "Menschen"));
+ CuAssertTrue(tc, cr_find_string(&strm, ";wahrerTyp", NULL));
+ mstream_done(&strm);
+
+ set_racename(&u->attribs, "Ritter von Go");
+ mstream_init(&strm);
+ cr_output_unit(&strm, f1, u, seen_unit);
+ CuAssertTrue(tc, cr_find_string(&strm, ";Typ", "Ritter von Go"));
+ CuAssertTrue(tc, cr_find_string(&strm, ";wahrerTyp", NULL));
+ mstream_done(&strm);
+ mstream_init(&strm);
+ cr_output_unit(&strm, f2, u, seen_unit);
+ CuAssertTrue(tc, cr_find_string(&strm, ";Typ", "Ritter von Go"));
CuAssertTrue(tc, cr_find_string(&strm, ";wahrerTyp", NULL));
mstream_done(&strm);
diff --git a/src/kernel/race.h b/src/kernel/race.h
index 4cd7fd3b7..8918437e1 100644
--- a/src/kernel/race.h
+++ b/src/kernel/race.h
@@ -207,7 +207,6 @@ extern "C" {
#define RCF_NOHEAL (1<<16) /* Einheit kann nicht geheilt werden */
#define RCF_NOWEAPONS (1<<17) /* Einheit kann keine Waffen benutzen */
#define RCF_SHAPESHIFT (1<<18) /* Kann TARNE RASSE benutzen. */
-#define RCF_SHAPESHIFTANY (1<<19) /* Kann TARNE RASSE "string" benutzen. */
#define RCF_UNDEAD (1<<20) /* Undead. */
#define RCF_DRAGON (1<<21) /* Drachenart (fuer Zauber) */
#define RCF_COASTAL (1<<22) /* kann in Landregionen an der Kueste sein */
diff --git a/src/reports.c b/src/reports.c
index c690aa345..2553920d1 100644
--- a/src/reports.c
+++ b/src/reports.c
@@ -698,7 +698,7 @@ void bufunit(const faction * f, const unit * u, const faction *fv,
if (pzTmp) {
const char *name = locale_string(lang, mkname("race", pzTmp), false);
sbs_strcat(sbp, name ? name : pzTmp);
- if (u->faction == f && fval(u_race(u), RCF_SHAPESHIFTANY)) {
+ if (u->faction == f) {
sbs_strcat(sbp, " (");
sbs_strcat(sbp, racename(lang, u, u_race(u)));
sbs_strcat(sbp, ")");
diff --git a/src/spy.c b/src/spy.c
index c4752ff72..8fcfa31e2 100644
--- a/src/spy.c
+++ b/src/spy.c
@@ -195,6 +195,39 @@ void set_factionstealth(unit *u, faction *f) {
a->data.v = f;
}
+static void stealth_race(unit *u, const char *s) {
+ const race *trace;
+
+ trace = findrace(s, u->faction->locale);
+ if (trace) {
+ /* demons can cloak as other player-races */
+ if (u_race(u) == get_race(RC_DAEMON)) {
+ if (playerrace(trace)) {
+ u->irace = trace;
+ }
+ }
+ /* Singdrachen können sich nur als Drachen tarnen */
+ 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)) {
+ u->irace = trace;
+ }
+ }
+
+ /* Schablonen können sich als alles mögliche tarnen */
+ if (u_race(u)->flags & RCF_SHAPESHIFT) {
+ u->irace = trace;
+ set_racename(&u->attribs, NULL);
+ }
+ }
+ else {
+ if (u_race(u)->flags & RCF_SHAPESHIFT) {
+ set_racename(&u->attribs, s);
+ }
+ }
+}
+
int setstealth_cmd(unit * u, struct order *ord)
{
char token[64];
@@ -207,111 +240,70 @@ int setstealth_cmd(unit * u, struct order *ord)
if (s == NULL || *s == 0) {
u_seteffstealth(u, -1);
- return 0;
}
-
- if (isdigit(*(const unsigned char *)s)) {
+ else if (isdigit(*(const unsigned char *)s)) {
/* Tarnungslevel setzen */
int level = atoi((const char *)s);
if (level > effskill(u, SK_STEALTH, NULL)) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_lowstealth", ""));
- return 0;
}
- u_seteffstealth(u, level);
- return 0;
- }
-
- if (skill_enabled(SK_STEALTH)) { /* hack! E3 erlaubt keine Tarnung */
- const race *trace;
-
- trace = findrace(s, u->faction->locale);
- if (trace) {
- /* demons can cloak as other player-races */
- if (u_race(u) == get_race(RC_DAEMON)) {
- if (playerrace(trace)) {
- u->irace = trace;
- 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 */
- 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)) {
- u->irace = trace;
- if (u_race(u)->flags & RCF_SHAPESHIFTANY && get_racename(u->attribs))
- set_racename(&u->attribs, NULL);
- }
- return 0;
- }
-
- /* Daemomen und Illusionsparteien koennen sich als andere race tarnen */
- if (u_race(u)->flags & RCF_SHAPESHIFT) {
- if (playerrace(trace)) {
- u->irace = trace;
- if ((u_race(u)->flags & RCF_SHAPESHIFTANY) && get_racename(u->attribs))
- set_racename(&u->attribs, NULL);
- }
- }
- return 0;
+ else {
+ u_seteffstealth(u, level);
}
}
-
- switch (findparam(s, u->faction->locale)) {
- case P_FACTION:
- /* TARNE PARTEI [NICHT|NUMMER abcd] */
- s = gettoken(token, sizeof(token));
- if (rule_stealth_anon()) {
- if (!s || *s == 0) {
- u->flags |= UFL_ANON_FACTION;
- break;
- }
- else if (findparam(s, u->faction->locale) == P_NOT) {
- u->flags &= ~UFL_ANON_FACTION;
- break;
- }
- }
- if (rule_stealth_other()) {
- if (get_keyword(s, u->faction->locale) == K_NUMBER) {
- int nr = -1;
-
- s = gettoken(token, sizeof(token));
- if (s) {
- nr = atoi36(s);
- }
- if (!s || *s == 0 || nr == u->faction->no) {
- a_removeall(&u->attribs, &at_otherfaction);
+ else {
+ switch (findparam(s, u->faction->locale)) {
+ case P_FACTION:
+ /* TARNE PARTEI [NICHT|NUMMER abcd] */
+ s = gettoken(token, sizeof(token));
+ if (rule_stealth_anon()) {
+ if (!s || *s == 0) {
+ u->flags |= UFL_ANON_FACTION;
break;
}
- else {
- struct faction *f = findfaction(nr);
- if (f == NULL || !can_set_factionstealth(u, f)) {
- cmistake(u, ord, 66, MSG_EVENT);
+ else if (findparam(s, u->faction->locale) == P_NOT) {
+ u->flags &= ~UFL_ANON_FACTION;
+ break;
+ }
+ }
+ if (rule_stealth_other()) {
+ if (get_keyword(s, u->faction->locale) == K_NUMBER) {
+ int nr = -1;
+
+ s = gettoken(token, sizeof(token));
+ if (s) {
+ nr = atoi36(s);
+ }
+ if (!s || *s == 0 || nr == u->faction->no) {
+ a_removeall(&u->attribs, &at_otherfaction);
break;
}
else {
- set_factionstealth(u, f);
- break;
+ struct faction *f = findfaction(nr);
+ if (f == NULL || !can_set_factionstealth(u, f)) {
+ cmistake(u, ord, 66, MSG_EVENT);
+ break;
+ }
+ else {
+ set_factionstealth(u, f);
+ break;
+ }
}
}
}
- }
- cmistake(u, ord, 289, MSG_EVENT);
- break;
- case P_ANY:
- case P_NOT:
- /* TARNE ALLES (was nicht so alles geht?) */
- u_seteffstealth(u, -1);
- break;
- default:
- if (u_race(u)->flags & RCF_SHAPESHIFTANY) {
- set_racename(&u->attribs, s);
- }
- else {
cmistake(u, ord, 289, MSG_EVENT);
+ break;
+
+ case P_ANY:
+ case P_NOT:
+ /* TARNE ALLES (was nicht so alles geht?) */
+ u_seteffstealth(u, -1);
+ break;
+
+ default:
+ if (skill_enabled(SK_STEALTH)) { /* hack! E3 erlaubt keine Tarnung */
+ stealth_race(u, s);
+ }
}
}
return 0;