From 599b4a83114d5f6c3e77574582261211b0427ee4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 8 Apr 2017 22:07:12 +0200 Subject: [PATCH 01/12] BUG 2318: disable ponnuki --- scripts/eressea/e2/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/eressea/e2/init.lua b/scripts/eressea/e2/init.lua index 722078741..9407b2390 100644 --- a/scripts/eressea/e2/init.lua +++ b/scripts/eressea/e2/init.lua @@ -9,7 +9,7 @@ return { require('eressea.wedding'), require('eressea.embassy'), require('eressea.tunnels'), - require('eressea.ponnuki'), +-- require('eressea.ponnuki'), require('eressea.astral'), -- require('eressea.locales'), require('eressea.jsreport'), From aebc7d4cac56969f0d03586dfb951badd14ab6bf Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 9 Apr 2017 13:40:42 +0200 Subject: [PATCH 03/12] BUG 2138: Ponnuki is dead, long live Ponnuki https://bugs.eressea.de/view.php?id=2318 --- scripts/eressea/ponnuki.lua | 23 ++++++++++++++++------- src/kernel/config.c | 2 +- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/scripts/eressea/ponnuki.lua b/scripts/eressea/ponnuki.lua index 96bb0b5f1..29f882ab5 100644 --- a/scripts/eressea/ponnuki.lua +++ b/scripts/eressea/ponnuki.lua @@ -14,8 +14,10 @@ local function ponnuki_brain(u) u:add_notice("Eine Botschaft von " .. tostring(u) .. ": " ..jokes[i]) local d = math.random(6) local r = u.region:next(d-1) - u:clear_orders() - u:add_order("NACH " .. directions[d]) + if r.terrain == 'glacier' then + u:clear_orders() + u:add_order("NACH " .. directions[d]) + end end function ponnuki.init() @@ -26,11 +28,18 @@ function ponnuki.init() local home = get_region(-67, -5) local f = get_faction(666) if home and f then - u = unit.create(f, home, 1, "illusion") - u.id = atoi36("ponn") - u.name = "Ponnuki" - u.info = "Go, Ponnuki, Go!" - u:set_racename("Ritter von Go") + if home.terrain~="glacier" then + home.terrain="glacier" + home.name = 'Magrathea' + end + u = unit.create(f, home, 1, "template") + if u then + u.id = atoi36("ponn") + u.name = "Ponnuki" + u.info = "Go, Ponnuki, Go!" + u.race_name = "Ritter von Go" + print(u:show()) + end else eressea.log.error("Ponnuki cannot find Magrathea") end diff --git a/src/kernel/config.c b/src/kernel/config.c index a18fc6494..bf61c8f02 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -123,7 +123,7 @@ const char *parameters[MAXPARAMS] = { "TEMP", "FLIEHE", "GEBAEUDE", - "GIB", /* F�r HELFE */ + "GIB", /* HELFE GIB */ "KAEMPFE", "DURCHREISE", "BEWACHE", From 51c2df62caa1d272f11a3b40dccb0572a7174f3f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 16 Apr 2017 15:52:34 +0200 Subject: [PATCH 04/12] fixing new coverity scan defects 167039 Dereference after null check 167038 Unchecked return value --- src/kernel/region.c | 5 +++-- src/laws.c | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) 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/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); From b06e93db7a5cec57b440f04b3fbc3b1045ab8d40 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Apr 2017 16:50:15 +0200 Subject: [PATCH 05/12] BUG 2317: wyrms in E2 didn't move --- res/eressea/races.xml | 2 +- src/monsters.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/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: */ From 635ec6d6c6a631e05b7f18fff730207ebecc3d6e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Apr 2017 20:11:44 +0200 Subject: [PATCH 06/12] Fix a crash in TARNE this was complicated to test, and I had to rewrite how races and their names are registered by test_create_locale. --- src/kernel/config.c | 38 ++++++++++++++++++------------- src/kernel/config.h | 1 + src/kernel/race.c | 19 +++++++++++----- src/kernel/race.h | 6 +++-- src/kernel/unit.test.c | 39 +++++++++++++------------------- src/spy.c | 2 +- src/spy.test.c | 51 ++++++++++++++++++++++++++++++++++++------ src/tests.c | 15 +++++++++++-- 8 files changed, 114 insertions(+), 57 deletions(-) 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/unit.test.c b/src/kernel/unit.test.c index d8aaae6ec..23668fd5f 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -153,23 +153,18 @@ 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(); } @@ -177,18 +172,20 @@ static void test_unit_name_from_race(CuTest *tc) { 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"); + lang = test_create_locale(); + 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 +194,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/spy.c b/src/spy.c index 08662ea8e..10f467ad9 100644 --- a/src/spy.c +++ b/src/spy.c @@ -255,7 +255,7 @@ int setstealth_cmd(unit * u, struct order *ord) for (i = 0; allowed[i] != NORACE; ++i) if (get_race(allowed[i]) == trace) break; - if (get_race(allowed[i]) == trace) { + if (allowed[i]!=NORACE && get_race(allowed[i]) == trace) { u->irace = trace; if (u_race(u)->flags & RCF_SHAPESHIFTANY && get_racename(u->attribs)) set_racename(&u->attribs, NULL); 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]); From 9fcab4ccb82a4e33c52e02c42f1a6aa0e1d1b8dc Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Apr 2017 20:18:37 +0200 Subject: [PATCH 07/12] do not hard-code list of allowed races for demons. --- src/spy.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/spy.c b/src/spy.c index 10f467ad9..391313aa3 100644 --- a/src/spy.c +++ b/src/spy.c @@ -247,15 +247,7 @@ 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 (allowed[i]!=NORACE && get_race(allowed[i]) == trace) { + if (playerrace(trace)) { u->irace = trace; if (u_race(u)->flags & RCF_SHAPESHIFTANY && get_racename(u->attribs)) set_racename(&u->attribs, NULL); From 055fdceff9a7c1fa8a6c5795e28621f4f220ca35 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Apr 2017 20:44:55 +0200 Subject: [PATCH 08/12] fix gcc build --- src/kernel/unit.test.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index 23668fd5f..096da9d62 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -171,12 +171,10 @@ static void test_unit_name_from_race(CuTest *tc) { static void test_update_monster_name(CuTest *tc) { unit *u; - struct locale *lang; race *rc; test_setup(); rc = test_create_race("human"); - lang = test_create_locale(); u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL)); unit_setname(u, "Hodor"); From 7e4f55a1ac28c2e66ebed517a789e75bb94082a0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 22 Apr 2017 13:53:06 +0200 Subject: [PATCH 09/12] enable ponnuki --- cJSON | 2 +- iniparser | 2 +- scripts/eressea/e2/init.lua | 2 +- storage | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cJSON b/cJSON index 43c04ad61..22a4fc9be 160000 --- a/cJSON +++ b/cJSON @@ -1 +1 @@ -Subproject commit 43c04ad61258ec3d54a2167eb3a43915bd003ab1 +Subproject commit 22a4fc9be31f0426e622f5bc9ebd7a1550845001 diff --git a/iniparser b/iniparser index ecf956b98..22741d9ce 160000 --- a/iniparser +++ b/iniparser @@ -1 +1 @@ -Subproject commit ecf956b9808c28c2db52e6b73930f57876dbb258 +Subproject commit 22741d9ce9d19bf7b5f5a219b6ed0925259a4d1b diff --git a/scripts/eressea/e2/init.lua b/scripts/eressea/e2/init.lua index 9407b2390..722078741 100644 --- a/scripts/eressea/e2/init.lua +++ b/scripts/eressea/e2/init.lua @@ -9,7 +9,7 @@ return { require('eressea.wedding'), require('eressea.embassy'), require('eressea.tunnels'), --- require('eressea.ponnuki'), + require('eressea.ponnuki'), require('eressea.astral'), -- require('eressea.locales'), require('eressea.jsreport'), diff --git a/storage b/storage index 2117191d4..d807ef5ce 160000 --- a/storage +++ b/storage @@ -1 +1 @@ -Subproject commit 2117191d4ad75e1eb14809878bc71d15b20a5d86 +Subproject commit d807ef5ce64b3425b31fb440e0b93a4d233f517a From 758af589e528e1617095f085744a1ff8703ab1c9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 22 Apr 2017 18:01:49 +0200 Subject: [PATCH 10/12] remove cmake as a submodule --- .gitmodules | 3 --- cmake | 1 - 2 files changed, 4 deletions(-) delete mode 160000 cmake diff --git a/.gitmodules b/.gitmodules index 7dff5ab6a..4d903c57f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "lunit"] path = lunit url = https://github.com/ennorehling/lunit.git -[submodule "cmake"] - path = cmake - url = https://github.com/ennorehling/cmake.git [submodule "dlmalloc"] path = dlmalloc url = https://github.com/ennorehling/dlmalloc.git diff --git a/cmake b/cmake deleted file mode 160000 index f1fb3943a..000000000 --- a/cmake +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f1fb3943ace59994d90d71a891b80033dc2700a2 From e938350acd3dd561466a8185216c953124ef7243 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 22 Apr 2017 18:07:09 +0200 Subject: [PATCH 11/12] add cmake as part of main project --- CMakeLists.txt | 24 ++++- cmake/Modules/FindLua.cmake | 172 ++++++++++++++++++++++++++++++++ cmake/Modules/FindSQLite3.cmake | 63 ++++++++++++ cmake/Modules/FindToLua.cmake | 71 +++++++++++++ cmake/Modules/MSVC.cmake | 19 ++++ s/build | 2 +- s/cmake-init | 6 +- 7 files changed, 348 insertions(+), 9 deletions(-) create mode 100644 cmake/Modules/FindLua.cmake create mode 100644 cmake/Modules/FindSQLite3.cmake create mode 100644 cmake/Modules/FindToLua.cmake create mode 100644 cmake/Modules/MSVC.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 405b86a03..d9ac81e80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,17 +1,29 @@ -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 2.8) +project (eressea-server C) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/" ${CMAKE_MODULE_PATH}) + if (WIN32) FILE(TO_CMAKE_PATH "${CMAKE_MODULE_PATH}" CMAKE_MODULE_PATH ) FILE(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH ) endif(WIN32) -project (eressea-server C) +if (MSVC) +include(MSVC) +endif (MSVC) -enable_testing() -find_package (LibXml2) find_package (SQLite3) find_package (Curses) -find_package (Lua REQUIRED) +find_package (LibXml2) find_package (ToLua REQUIRED) +if (TOLUA_FOUND) +if (${TOLUA_VERSION_STRING} VERSION_GREATER "5.2") +find_package (Lua 5.2 REQUIRED) +elseif (${TOLUA_VERSION_STRING} VERSION_GREATER "5.1") +find_package (Lua 5.1 REQUIRED) +endif() +endif(TOLUA_FOUND) + +enable_testing() add_subdirectory (cJSON) add_subdirectory (storage) @@ -19,8 +31,10 @@ add_subdirectory (iniparser) add_subdirectory (clibs) add_subdirectory (process) add_subdirectory (src eressea) + install(DIRECTORY res conf DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.xml") install(DIRECTORY res conf DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.json") install(DIRECTORY scripts DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.lua") install(DIRECTORY lunit DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.lua") install(DIRECTORY share DESTINATION ${CMAKE_INSTALL_PREFIX}) + diff --git a/cmake/Modules/FindLua.cmake b/cmake/Modules/FindLua.cmake new file mode 100644 index 000000000..898ccbfd6 --- /dev/null +++ b/cmake/Modules/FindLua.cmake @@ -0,0 +1,172 @@ +#.rst: +# FindLua +# ------- +# +# +# +# Locate Lua library This module defines +# +# :: +# +# LUA_FOUND - if false, do not try to link to Lua +# LUA_LIBRARIES - both lua and lualib +# LUA_INCLUDE_DIR - where to find lua.h +# LUA_VERSION_STRING - the version of Lua found +# LUA_VERSION_MAJOR - the major version of Lua +# LUA_VERSION_MINOR - the minor version of Lua +# LUA_VERSION_PATCH - the patch version of Lua +# +# +# +# Note that the expected include convention is +# +# :: +# +# #include "lua.h" +# +# and not +# +# :: +# +# #include +# +# This is because, the lua location is not standardized and may exist in +# locations other than lua/ + +#============================================================================= +# Copyright 2007-2009 Kitware, Inc. +# Copyright 2013 Rolf Eike Beer +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +unset(_lua_include_subdirs) +unset(_lua_library_names) + +# this is a function only to have all the variables inside go away automatically +function(set_lua_version_vars) + set(LUA_VERSIONS5 5.3 5.2 5.1 5.0) + + if (Lua_FIND_VERSION_EXACT) + if (Lua_FIND_VERSION_COUNT GREATER 1) + set(lua_append_versions ${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR}) + endif () + elseif (Lua_FIND_VERSION) + # once there is a different major version supported this should become a loop + if (NOT Lua_FIND_VERSION_MAJOR GREATER 5) + if (Lua_FIND_VERSION_COUNT EQUAL 1) + set(lua_append_versions ${LUA_VERSIONS5}) + else () + foreach (subver IN LISTS LUA_VERSIONS5) + if (NOT subver VERSION_LESS ${Lua_FIND_VERSION}) + list(APPEND lua_append_versions ${subver}) + endif () + endforeach () + endif () + endif () + else () + # once there is a different major version supported this should become a loop + set(lua_append_versions ${LUA_VERSIONS5}) + endif () + + foreach (ver IN LISTS lua_append_versions) + string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _ver "${ver}") + list(APPEND _lua_include_subdirs + include/lua${CMAKE_MATCH_1}${CMAKE_MATCH_2} + include/lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2} + include/lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2} + ) + list(APPEND _lua_library_names + lua${CMAKE_MATCH_1}${CMAKE_MATCH_2} + lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2} + lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2} + lua.${CMAKE_MATCH_1}.${CMAKE_MATCH_2} + ) + endforeach () + + set(_lua_include_subdirs "${_lua_include_subdirs}" PARENT_SCOPE) + set(_lua_library_names "${_lua_library_names}" PARENT_SCOPE) +endfunction(set_lua_version_vars) + +set_lua_version_vars() + +find_path(LUA_INCLUDE_DIR lua.h + HINTS + ENV LUA_DIR + PATH_SUFFIXES ${_lua_include_subdirs} include/lua include + PATHS + ~/Library/Frameworks + /Library/Frameworks + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) +unset(_lua_include_subdirs) + +find_library(LUA_LIBRARY + NAMES ${_lua_library_names} lua + HINTS + ENV LUA_DIR + PATH_SUFFIXES lib + PATHS + ~/Library/Frameworks + /Library/Frameworks + /sw + /opt/local + /opt/csw + /opt +) +unset(_lua_library_names) + +if (LUA_LIBRARY) + # include the math library for Unix + if (UNIX AND NOT APPLE AND NOT BEOS) + find_library(LUA_MATH_LIBRARY m) + set(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}") + # For Windows and Mac, don't need to explicitly include the math library + else () + set(LUA_LIBRARIES "${LUA_LIBRARY}") + endif () +endif () + +if (LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h") + # At least 5.[012] have different ways to express the version + # so all of them need to be tested. Lua 5.2 defines LUA_VERSION + # and LUA_RELEASE as joined by the C preprocessor, so avoid those. + file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_strings + REGEX "^#define[ \t]+LUA_(RELEASE[ \t]+\"Lua [0-9]|VERSION([ \t]+\"Lua [0-9]|_[MR])).*") + + string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MAJOR ";${lua_version_strings};") + if (LUA_VERSION_MAJOR MATCHES "^[0-9]+$") + string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MINOR ";${lua_version_strings};") + string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_PATCH ";${lua_version_strings};") + set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}") + else () + string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};") + if (NOT LUA_VERSION_STRING MATCHES "^[0-9.]+$") + string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};") + endif () + string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" LUA_VERSION_MAJOR "${LUA_VERSION_STRING}") + string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" LUA_VERSION_MINOR "${LUA_VERSION_STRING}") + string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" LUA_VERSION_PATCH "${LUA_VERSION_STRING}") + endif () + + unset(lua_version_strings) +endif() + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if +# all listed variables are TRUE +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua + REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR + VERSION_VAR LUA_VERSION_STRING) + +mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY LUA_MATH_LIBRARY) diff --git a/cmake/Modules/FindSQLite3.cmake b/cmake/Modules/FindSQLite3.cmake new file mode 100644 index 000000000..910b05cea --- /dev/null +++ b/cmake/Modules/FindSQLite3.cmake @@ -0,0 +1,63 @@ +# - Try to find the SQLite3 library +# Once done this will define +# +# SQLITE3_FOUND - System has SQLite3 +# SQLITE3_INCLUDE_DIR - The SQLite3 include directory +# SQLITE3_LIBRARIES - The libraries needed to use SQLite3 +# SQLITE3_DEFINITIONS - Compiler switches required for using SQLite3 +# SQLITE3_EXECUTABLE - The SQLite3 command line shell +# SQLITE3_VERSION_STRING - the version of SQLite3 found (since CMake 2.8.8) + +#============================================================================= +# Copyright 2006-2009 Kitware, Inc. +# Copyright 2006 Alexander Neundorf +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# use pkg-config to get the directories and then use these values +# in the find_path() and find_library() calls +find_package(PkgConfig QUIET) +PKG_CHECK_MODULES(PC_SQLITE QUIET sqlite3) +set(SQLITE3_DEFINITIONS ${PC_SQLITE_CFLAGS_OTHER}) + +find_path(SQLITE3_INCLUDE_DIR NAMES sqlite3.h + HINTS + ${PC_SQLITE_INCLUDEDIR} + ${PC_SQLITE_INCLUDE_DIRS} + ) + +find_library(SQLITE3_LIBRARIES NAMES sqlite3 + HINTS + ${PC_SQLITE_LIBDIR} + ${PC_SQLITE_LIBRARY_DIRS} + ) + +find_program(SQLITE3_EXECUTABLE sqlite3) + +if(PC_SQLITE_VERSION) + set(SQLITE3_VERSION_STRING ${PC_SQLITE_VERSION}) +elseif(SQLITE3_INCLUDE_DIR AND EXISTS "${SQLITE3_INCLUDE_DIR}/sqlite3.h") + file(STRINGS "${SQLITE3_INCLUDE_DIR}/sqlite3.h" sqlite3_version_str + REGEX "^#define[\t ]+SQLITE_VERSION[\t ]+\".*\"") + + string(REGEX REPLACE "^#define[\t ]+SQLITE_VERSION[\t ]+\"([^\"]*)\".*" "\\1" + SQLITE3_VERSION_STRING "${sqlite3_version_str}") + unset(sqlite3_version_str) +endif() + +# handle the QUIETLY and REQUIRED arguments and set SQLITE3_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SQLite3 + REQUIRED_VARS SQLITE3_LIBRARIES SQLITE3_INCLUDE_DIR + VERSION_VAR SQLITE3_VERSION_STRING) + +mark_as_advanced(SQLITE3_INCLUDE_DIR SQLITE3_LIBRARIES SQLITE3_EXECUTABLE) diff --git a/cmake/Modules/FindToLua.cmake b/cmake/Modules/FindToLua.cmake new file mode 100644 index 000000000..52c721112 --- /dev/null +++ b/cmake/Modules/FindToLua.cmake @@ -0,0 +1,71 @@ +# - Try to find the ToLua library +# Once done this will define +# +# TOLUA_FOUND - System has ToLua +# TOLUA_INCLUDE_DIR - The ToLua include directory +# TOLUA_LIBRARIES - The libraries needed to use ToLua +# TOLUA_DEFINITIONS - Compiler switches required for using ToLua +# TOLUA_EXECUTABLE - The ToLua command line shell +# TOLUA_VERSION_STRING - the version of ToLua found (since CMake 2.8.8) + +#============================================================================= +# Copyright 2006-2009 Kitware, Inc. +# Copyright 2006 Alexander Neundorf +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# use pkg-config to get the directories and then use these values +# in the find_path() and find_library() calls +find_package(PkgConfig QUIET) +PKG_CHECK_MODULES(PC_TOLUA QUIET ToLua) +set(TOLUA_DEFINITIONS ${PC_TOLUA_CFLAGS_OTHER}) + +find_path(TOLUA_INCLUDE_DIR NAMES tolua.h + HINTS + ${PC_TOLUA_DIR}/include + ${PC_TOLUA_INCLUDEDIR} + ${PC_TOLUA_INCLUDE_DIRS} + ) +find_library(TOLUA_LIBRARY NAMES tolua + HINTS + ${PC_TOLUA_DIR}/lib + ${PC_TOLUA_LIBDIR} + ${PC_TOLUA_LIBRARY_DIRS} + ) +find_program(TOLUA_EXECUTABLE tolua + HINTS + ${PC_TOLUA_DIR}/bin + ${PC_TOLUA_LIBDIR} + ${PC_TOLUA_LIBRARY_DIRS} +) + +SET( TOLUA_LIBRARIES "${TOLUA_LIBRARY}" CACHE STRING "ToLua Libraries") + +if(PC_TOLUA_VERSION) + set(TOLUA_VERSION_STRING ${PC_TOLUA_VERSION}) +elseif(TOLUA_INCLUDE_DIR AND EXISTS "${TOLUA_INCLUDE_DIR}/tolua.h") + file(STRINGS "${TOLUA_INCLUDE_DIR}/tolua.h" tolua_version_str + REGEX "^#define[\t ]+TOLUA_VERSION[\t ]+\".*\"") + + string(REGEX REPLACE "^#define[\t ]+TOLUA_VERSION[\t ]+\"tolua ([^\"]*)\".*" "\\1" + TOLUA_VERSION_STRING "${tolua_version_str}") + unset(tolua_version_str) +endif() + +# handle the QUIETLY and REQUIRED arguments and set TOLUA_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ToLua + REQUIRED_VARS TOLUA_LIBRARY TOLUA_INCLUDE_DIR TOLUA_EXECUTABLE + VERSION_VAR TOLUA_VERSION_STRING) + +mark_as_advanced(TOLUA_INCLUDE_DIR TOLUA_LIBRARIES TOLUA_EXECUTABLE) + diff --git a/cmake/Modules/MSVC.cmake b/cmake/Modules/MSVC.cmake new file mode 100644 index 000000000..d32822627 --- /dev/null +++ b/cmake/Modules/MSVC.cmake @@ -0,0 +1,19 @@ +MACRO (MSVC_CRT_SECURE_NO_WARNINGS) + IF (MSVC) + FOREACH (target ${ARGN}) + SET_TARGET_PROPERTIES (${target} PROPERTIES + COMPILE_DEFINITIONS _CRT_SECURE_NO_WARNINGS + ) + ENDFOREACH (target) + ENDIF (MSVC) +ENDMACRO (MSVC_CRT_SECURE_NO_WARNINGS) + +MACRO (MSVC_SET_WARNING_LEVEL level) + IF (MSVC) + IF(CMAKE_C_FLAGS MATCHES "/W[0-4]") + STRING(REGEX REPLACE "/W[0-4]" "/W${level}" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + ELSE() + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W${level}") + ENDIF() + ENDIF(MSVC) +ENDMACRO (MSVC_SET_WARNING_LEVEL) diff --git a/s/build b/s/build index 4ee259573..818cb0268 100755 --- a/s/build +++ b/s/build @@ -33,7 +33,7 @@ fi echo "build eressea" cd $ROOT/$BUILD BRANCH=$(git status -s -b | head -1 | cut -d\ -f 2 | sed 's/\..*//') -if [ "$BRANCH"=="master" ] ; then +if [ "$BRANCH" = "master" ] ; then VERSION=$(git describe --match 'v*.*.*' --tags | sed 's/^v//') cmake -DERESSEA_VERSION="$VERSION" .. else diff --git a/s/cmake-init b/s/cmake-init index 1ce7eccd3..9d529a433 100755 --- a/s/cmake-init +++ b/s/cmake-init @@ -10,6 +10,7 @@ ROOT=$(git rev-parse --show-toplevel) MACHINE=`$CC -dumpmachine` [ -z $MACHINE ] && MACHINE=`uname -m` BIN_DIR="$ROOT/build-$MACHINE-$CC-$BUILD" +rm -rf $BIN_DIR mkdir -p $BIN_DIR rm -f $BUILD ln -sf $BIN_DIR $BUILD @@ -29,12 +30,11 @@ if [ -d $HOME/usr ]; then fi DEST=$(dirname $ROOT)/server -ARGS=" -DCMAKE_MODULE_PATH=$ROOT/cmake/Modules \ - -DCMAKE_BUILD_TYPE=$BUILD \ +ARGS=" -DCMAKE_BUILD_TYPE=$BUILD \ -DCMAKE_LIBRARY_PATH=$LIBRARY_PATH \ - -DCMAKE_INCLUDE_PATH=$INCLUDE_PATH \ -DCMAKE_PREFIX_PATH=$PREFIX_PATH \ -DCMAKE_INSTALL_PREFIX=$DEST" +# -DCMAKE_INCLUDE_PATH=$INCLUDE_PATH git submodule update --init From e53054302293ad7cfe39464c30095fbbb467e7fd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 22 Apr 2017 18:33:47 +0200 Subject: [PATCH 12/12] demon stealth: cloak as other race. added a Lua test. get_race oob fix (potential crash). --- scripts/tests/e2/e2features.lua | 19 +++++++++++++++++++ src/kernel/race.c | 2 +- src/spy.c | 15 +++++++-------- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index 2f8764119..5b2caf61c 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -404,3 +404,22 @@ function test_birthdaycake() 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@eressea.de", "demon", "de") + 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/race.c b/src/kernel/race.c index d159fd6d8..077e03b28 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -166,7 +166,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 < MAXRACES); + assert(rt>=0 && rt < MAXRACES); name = racenames[rt]; if (!name) { return NULL; diff --git a/src/spy.c b/src/spy.c index c9667f7ee..12a30848d 100644 --- a/src/spy.c +++ b/src/spy.c @@ -254,19 +254,18 @@ int setstealth_cmd(unit * u, struct order *ord) NORACE }; int i; - for (i = 0; allowed[i] != NORACE; ++i) - if (get_race(allowed[i]) == trace) + for (i = 0; allowed[i] != NORACE; ++i) { + if (get_race(allowed[i]) == trace) { + u->irace = trace; + if (u_race(u)->flags & RCF_SHAPESHIFTANY && get_racename(u->attribs)) + set_racename(&u->attribs, NULL); break; - if (get_race(allowed[i]) == 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 */ - 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)) {