diff --git a/res/e3a/races.xml b/res/e3a/races.xml index 2fa889160..e2fea2acb 100644 --- a/res/e3a/races.xml +++ b/res/e3a/races.xml @@ -400,8 +400,8 @@ - - + + @@ -425,8 +425,8 @@ - - + + @@ -565,8 +565,8 @@ - - + + @@ -597,8 +597,8 @@ - - + + @@ -655,14 +655,14 @@ - - + + - - + + @@ -694,8 +694,8 @@ - - + + @@ -703,9 +703,9 @@ - + @@ -736,8 +736,8 @@ - - + + @@ -754,8 +754,8 @@ - - + + @@ -771,8 +771,8 @@ - - + + @@ -787,8 +787,8 @@ - - + + @@ -801,8 +801,8 @@ - - + + @@ -816,8 +816,8 @@ - - + + @@ -830,13 +830,13 @@ - - + + - - + + diff --git a/res/eressea/races.xml b/res/eressea/races.xml index 1acffa872..bf9eeb18c 100644 --- a/res/eressea/races.xml +++ b/res/eressea/races.xml @@ -298,8 +298,8 @@ - - + + @@ -328,8 +328,8 @@ - - + + @@ -507,8 +507,8 @@ - - + + @@ -578,8 +578,8 @@ - + regaura="1.000000" weight="100" capacity="540" speed="1.000000" hp="20" damage="0d0" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="10" fly="yes" walk="yes" teach="no" invinciblenonmagic="yes"> + @@ -652,14 +652,14 @@ - - + + - - + + @@ -696,13 +696,13 @@ - - + + - - + + @@ -711,8 +711,8 @@ - - + + @@ -721,8 +721,8 @@ - - + + @@ -732,8 +732,8 @@ - - + + @@ -983,8 +983,8 @@ - - + + @@ -1000,8 +1000,8 @@ - - + + @@ -1016,8 +1016,8 @@ - - + + @@ -1031,8 +1031,8 @@ - - + + @@ -1044,8 +1044,8 @@ - - + + @@ -1058,8 +1058,8 @@ - - + + @@ -1071,12 +1071,12 @@ - - + + - - + + @@ -1202,8 +1202,8 @@ - - + + diff --git a/res/races/dragon.xml b/res/races/dragon.xml index 7625b914f..58acc5f57 100644 --- a/res/races/dragon.xml +++ b/res/races/dragon.xml @@ -2,10 +2,10 @@ - + diff --git a/res/races/wyrm.xml b/res/races/wyrm.xml index c69ca2953..96a9d2e3c 100644 --- a/res/races/wyrm.xml +++ b/res/races/wyrm.xml @@ -4,9 +4,9 @@ - + diff --git a/res/races/youngdragon.xml b/res/races/youngdragon.xml index bbfdb5a9f..30797fb7d 100644 --- a/res/races/youngdragon.xml +++ b/res/races/youngdragon.xml @@ -3,9 +3,9 @@ - + diff --git a/res/races/zombie.xml b/res/races/zombie.xml index fdfe97d8e..01407b29a 100644 --- a/res/races/zombie.xml +++ b/res/races/zombie.xml @@ -4,9 +4,9 @@ hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="no" walk="yes" shapeshift="no" giveperson="no" giveunit="no" getitem="no" equipment="yes" scarepeasants="yes" - cansteal="no" unarmedguard="yes" absorbpeasants="yes" noheal="yes" + cansteal="no" unarmedguard="yes" noheal="yes" undead="yes" resistpierce="yes"> - + diff --git a/scripts/tests/e2/undead.lua b/scripts/tests/e2/undead.lua index e1b153f25..28d2c20c1 100644 --- a/scripts/tests/e2/undead.lua +++ b/scripts/tests/e2/undead.lua @@ -60,3 +60,14 @@ function test_clones_dont_give_person() process_orders() assert_equal(2, u1.number) end + +-- bug 2504 +function test_skeleton_cannot_learn() + local r = region.create(0, 0, "plain") + local f = faction.create("elf") + local u = unit.create(f, r, 2) + u.race = "skeleton" + u:add_order("LERNE Wahrnehmung") + process_orders() + assert_equal(0, u:get_skill('perception')) +end diff --git a/src/exparse.c b/src/exparse.c index 0814f7cdc..4160b32ba 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -993,12 +993,19 @@ static int nfamiliars; static void start_races(parseinfo *pi, const XML_Char *el, const XML_Char **attr) { race *rc = (race *)pi->object; const char *flag_names[] = { - "playerrace", "killpeasants", "scarepeasants", "!cansteal", - "moverandom", "cannotmove", "learn", "fly", "swim", "walk", - "!learn", "!teach", "horse", "desert", "illusionary", - "absorbpeasants", "noheal", "noweapons", "shapeshift", + "playerrace", "", "", "!cansteal", + "", "cannotmove", "", "fly", "swim", "walk", + "!learn", "!teach","horse", "desert", "illusionary", + "", "noheal", "noweapons", "shapeshift", "shapeshiftany", "undead", "dragon", "coastal", "unarmedguard", - "cansail", "invisible", "shipspeed", "moveattack", "migrants", NULL }; + "cansail", "invisible", "shipspeed", "", "migrants", NULL }; + const char *ai_flag_names[] = { + "", "killpeasants", "scarepeasants", "", + "moverandom", "", "learn", "", "", "", + "", "", "", "", "", + "absorbpeasants", "", "", "", + "", "", "", "", "", + "", "", "", "moveattack", "", NULL }; const char *bflag_names[] = { "equipment", "noblock", "resistpierce", "resistcut", "resistbash", "invinciblenonmagic", "noattack", NULL }; @@ -1106,7 +1113,7 @@ static void start_races(parseinfo *pi, const XML_Char *el, const XML_Char **attr else if (xml_strequal(key, "scare")) { rc_set_param(rc, "scare", val); } - else if (!handle_flag(&flags, attr + i, flag_names)) { + else if (!handle_flag(&flags, attr + i, ai_flag_names)) { handle_bad_input(pi, el, key); } } diff --git a/src/kernel/race.h b/src/kernel/race.h index f2b96c153..dd169272a 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -208,7 +208,7 @@ extern "C" { #define RCF_NOSTEAL (1<<3) /* this race has high stealth, but is not allowed to steal */ #define RCF_MOVERANDOM (1<<4) #define RCF_CANNOTMOVE (1<<5) -#define RCF_LEARN (1<<6) /* Lernt automatisch wenn struct faction == 0 */ +#define RCF_AI_LEARN (1<<6) /* Lernt automatisch wenn struct faction == 0 */ #define RCF_FLY (1<<7) /* kann fliegen */ #define RCF_SWIM (1<<8) /* kann schwimmen */ #define RCF_WALK (1<<9) /* kann ueber Land gehen */ diff --git a/src/monsters.c b/src/monsters.c index afa8070e5..290cbdb87 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -826,7 +826,7 @@ void plan_monsters(faction * f) long_order = create_order(K_PIRACY, f->locale, NULL); } else { - if (rc->flags & RCF_LEARN) { + if (rc->flags & RCF_AI_LEARN) { long_order = monster_learn(u); } } diff --git a/src/study.c b/src/study.c index 6130d340a..7e5ca9812 100644 --- a/src/study.c +++ b/src/study.c @@ -527,12 +527,13 @@ static void msg_teachers(struct selist *teachers, struct unit *u, skill_t sk) { bool check_student(const struct unit *u, struct order *ord, skill_t sk) { int err = 0; + const race *rc = u_race(u); if (sk < 0) { err = 77; } /* Hack: Talente mit Malus -99 koennen nicht gelernt werden */ - else if (u_race(u)->bonus[sk] == -99) { + else if (rc->bonus[sk] == -99) { err = 771; } else { diff --git a/src/study.test.c b/src/study.test.c index 446b442bb..b57c921f4 100644 --- a/src/study.test.c +++ b/src/study.test.c @@ -59,6 +59,8 @@ typedef struct { static void setup_study(void) { test_setup(); + mt_create_error(77); + mt_create_error(771); mt_create_error(178); mt_create_error(65); mt_create_va(mt_new("teach_asgood", NULL), @@ -148,6 +150,32 @@ static void test_study_with_bad_teacher(CuTest *tc) { test_teardown(); } +static void test_check_student(CuTest *tc) { + unit *u; + race *rc; + + setup_study(); + u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0)); + u->thisorder = create_order(K_STUDY, u->faction->locale, skillnames[SK_CROSSBOW]); + CuAssertTrue(tc, check_student(u, u->thisorder, SK_CROSSBOW)); + CuAssertPtrEquals(tc, NULL, u->faction->msgs); + + rc = test_create_race("skeleton"); + rc->flags |= RCF_NOLEARN; + u_setrace(u, rc); + CuAssertTrue(tc, !check_student(u, u->thisorder, SK_CROSSBOW)); + CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error_race_nolearn")); + test_clear_messages(u->faction); + rc->flags -= RCF_NOLEARN; + + rc->bonus[SK_CROSSBOW] = -99; + CuAssertTrue(tc, !check_student(u, u->thisorder, SK_CROSSBOW)); + CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error771")); + test_clear_messages(u->faction); + + test_teardown(); +} + static void test_study_bug_2194(CuTest *tc) { unit *u, *u1, *u2; struct locale * loc; @@ -158,7 +186,7 @@ static void test_study_bug_2194(CuTest *tc) { init_resources(); loc = test_create_locale(); setup_locale(loc); - u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); + u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0)); scale_number(u, 2); set_level(u, SK_CROSSBOW, TEACHDIFFERENCE); u->faction->locale = loc; @@ -742,5 +770,6 @@ CuSuite *get_study_suite(void) SUITE_ADD_TEST(suite, test_academy_bonus); SUITE_ADD_TEST(suite, test_demon_skillchanges); SUITE_ADD_TEST(suite, test_study_bug_2194); + SUITE_ADD_TEST(suite, test_check_student); return suite; }