diff --git a/critbit b/critbit index 934c2dd94..ee7a32b9b 160000 --- a/critbit +++ b/critbit @@ -1 +1 @@ -Subproject commit 934c2dd94d41da19637a76a1a8b3dfeb7aa8524d +Subproject commit ee7a32b9b8986bf2ea6b287975f9ef0ec997b7a3 diff --git a/src/kernel/equipment.test.c b/src/kernel/equipment.test.c index 851e591d2..f0543ad8c 100644 --- a/src/kernel/equipment.test.c +++ b/src/kernel/equipment.test.c @@ -36,7 +36,7 @@ void test_equipment(CuTest * tc) equipment_setskill(eq, SK_MAGIC, "5"); equipment_addspell(eq, sp, 1); - u = test_create_unit(0, 0); + u = test_create_unit(test_create_faction(0), 0); equip_unit_mask(u, eq, EQUIP_ALL); CuAssertIntEquals(tc, 1, i_get(u->items, it_horses)); CuAssertIntEquals(tc, 5, get_level(u, SK_MAGIC)); diff --git a/src/kernel/item.test.c b/src/kernel/item.test.c index 2d76422ff..1c133b74f 100644 --- a/src/kernel/item.test.c +++ b/src/kernel/item.test.c @@ -64,7 +64,7 @@ void test_change_item(CuTest * tc) test_create_itemtype("iron"); init_resources(); - u = test_create_unit(0, 0); + u = test_create_unit(test_create_faction(0), 0); test_uchange(tc, u, get_resourcetype(R_IRON)); } diff --git a/src/randenc.c b/src/randenc.c index a7227a210..dfa1e998d 100644 --- a/src/randenc.c +++ b/src/randenc.c @@ -958,38 +958,7 @@ static void demon_skillchanges(void) unit *u; for (u = r->units; u; u = u->next) { if (u_race(u) == get_race(RC_DAEMON)) { - skill *sv = u->skills; - int upchance = 15; - int downchance = 10; - - if (fval(u, UFL_HUNGER)) { - /* hungry demons only go down, never up in skill */ - int rule_hunger = config_get_int("hunger.demons.skill", 0) != 0; - if (rule_hunger) { - upchance = 0; - downchance = 15; - } - } - - while (sv != u->skills + u->skill_size) { - int roll = rng_int() % 100; - if (sv->level > 0 && roll < upchance + downchance) { - int weeks = 1 + rng_int() % 3; - if (roll < downchance) { - reduce_skill(u, sv, weeks); - if (sv->level < 1) { - /* demons should never forget below 1 */ - set_level(u, sv->id, 1); - } - } - else { - while (weeks--) { - learn_skill_depr(u, sv->id, 1.0); - } - } - } - ++sv; - } + demon_skillchange(u); } } } diff --git a/src/study.c b/src/study.c index 0cb8df525..a39f2e57b 100644 --- a/src/study.c +++ b/src/study.c @@ -826,7 +826,7 @@ bool learn_skill_depr(unit * u, skill_t sk, double learn_chance) } #endif if (learn_chance < 1.0 && rng_int() % 10000 >= learn_chance * 10000) - if (!chance(learn_chance)) + if (!chance(learn_chance)) // FIXME: this nested if looks as if we are rolling twice! return false; while (sv != u->skills + u->skill_size) { assert(sv->weeks > 0); @@ -865,3 +865,39 @@ void learn_skill(unit *u, skill_t sk, int days) { } sv->weeks -= weeks; } + +/** Talente von Dämonen verschieben sich. +*/ +void demon_skillchange(unit *u) +{ + skill *sv = u->skills; + int upchance = 15; + int downchance = 10; + + if (fval(u, UFL_HUNGER)) { + /* hungry demons only go down, never up in skill */ + int rule_hunger = config_get_int("hunger.demon.skill", 0) != 0; + if (rule_hunger) { + upchance = 0; + downchance = 15; + } + } + + while (sv != u->skills + u->skill_size) { + int roll = rng_int() % 100; + if (sv->level > 0 && roll < upchance + downchance) { + int weeks = 1 + rng_int() % 3; + if (roll < downchance) { + reduce_skill(u, sv, weeks); + if (sv->level < 1) { + /* demons should never forget below 1 */ + set_level(u, sv->id, 1); + } + } + else { + learn_skill(u, sv->id, STUDYDAYS*weeks); + } + } + ++sv; + } +} diff --git a/src/study.h b/src/study.h index 52c384aba..078204a6e 100644 --- a/src/study.h +++ b/src/study.h @@ -47,6 +47,8 @@ extern "C" { void produceexp(struct unit *u, skill_t sk, int n); void produceexp_ex(struct unit *u, skill_t sk, int n, bool(*learn)(struct unit *, skill_t, double)); + void demon_skillchange(struct unit *u); + #define MAXTEACHERS 20 #define TEACHNUMBER 10 typedef struct teaching_info { diff --git a/src/study.test.c b/src/study.test.c index b51e17e68..64db05e26 100644 --- a/src/study.test.c +++ b/src/study.test.c @@ -3,12 +3,13 @@ #include "study.h" #include -#include +#include #include #include #include +#include #include -#include +#include #include #include #include @@ -247,6 +248,19 @@ void test_learn_skill(CuTest *tc) { test_cleanup(); } +void test_demon_skillchanges(CuTest *tc) { + unit * u; + race * rc; + test_cleanup(); + rc = test_create_race("demon"); + CuAssertPtrEquals(tc, rc, get_race(RC_DAEMON)); + u = test_create_unit(test_create_faction(rc), 0); + CuAssertPtrNotNull(tc, u); + set_level(u, SK_CROSSBOW, 1); + demon_skillchange(u); + test_cleanup(); +} + CuSuite *get_study_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -256,6 +270,7 @@ CuSuite *get_study_suite(void) SUITE_ADD_TEST(suite, test_study_with_bad_teacher); SUITE_ADD_TEST(suite, test_produceexp); SUITE_ADD_TEST(suite, test_academy_building); + SUITE_ADD_TEST(suite, test_demon_skillchanges); DISABLE_TEST(suite, test_study_bug_2194); return suite; } diff --git a/src/tests.c b/src/tests.c index f8a0c2a7f..c03680baf 100644 --- a/src/tests.c +++ b/src/tests.c @@ -77,8 +77,9 @@ struct faction *test_create_faction(const struct race *rc) struct unit *test_create_unit(struct faction *f, struct region *r) { const struct race * rc = f ? f->race : 0; - assert(f || !r); - return create_unit(r, f, 1, rc ? rc : rc_get_or_create("human"), 0, 0, 0); + assert(f); + if (!rc) rc = rc_get_or_create("human"); + return create_unit(r, f, 1, rc, 0, 0, 0); } void test_cleanup(void)