diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index 93f805ebc..4050ead55 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -27,7 +27,7 @@ region.test.c # resources.test.c save.test.c ship.test.c -# skills.test.c +skills.test.c spellbook.test.c spell.test.c # terrain.test.c diff --git a/src/kernel/skills.test.c b/src/kernel/skills.test.c new file mode 100644 index 000000000..d624c2a84 --- /dev/null +++ b/src/kernel/skills.test.c @@ -0,0 +1,36 @@ +#ifdef _MSC_VER +#include +#endif +#include "skills.h" + +#include "unit.h" + +#include +#include + +static void test_skills(CuTest * tc) +{ + unit *u; + + test_setup(); + u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0)); + CuAssertPtrEquals(tc, NULL, u->skills); + CuAssertIntEquals(tc, 0, u->skill_size); + CuAssertIntEquals(tc, 0, get_level(u, SK_CROSSBOW)); + set_level(u, SK_CROSSBOW, 1); + CuAssertPtrNotNull(tc, u->skills); + CuAssertIntEquals(tc, 1, u->skill_size); + CuAssertIntEquals(tc, 1, get_level(u, SK_CROSSBOW)); + set_level(u, SK_CROSSBOW, 0); + CuAssertPtrEquals(tc, NULL, u->skills); + CuAssertIntEquals(tc, 0, u->skill_size); + test_teardown(); +} + +CuSuite *get_skills_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_skills); + return suite; +} + diff --git a/src/kernel/unit.c b/src/kernel/unit.c index fb07d782e..40e67ebae 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1198,8 +1198,13 @@ void remove_skill(unit * u, skill_t sk) for (i = 0; i != u->skill_size; ++i) { sv = u->skills + i; if (sv->id == sk) { - memmove(sv, sv + 1, (u->skill_size - i - 1) * sizeof(skill)); - --u->skill_size; + if (u->skill_size - i - 1 > 0) { + memmove(sv, sv + 1, (u->skill_size - i - 1) * sizeof(skill)); + } + if (--u->skill_size == 0) { + free(u->skills); + u->skills = NULL; + } return; } } diff --git a/src/laws.c b/src/laws.c index dbb99adc1..324c4f27d 100644 --- a/src/laws.c +++ b/src/laws.c @@ -161,10 +161,33 @@ static bool RemoveNMRNewbie(void) return value != 0; } +static void dumbeffect(unit *u) { + int effect = get_effect(u, oldpotiontype[P_FOOL]); + if (effect > 0) { /* Trank "Dumpfbackenbrot" */ + skill *sv = u->skills, *sb = NULL; + while (sv != u->skills + u->skill_size) { + if (sb == NULL || skill_compare(sv, sb) > 0) { + sb = sv; + } + ++sv; + } + /* bestes Talent raussuchen */ + if (sb != NULL) { + int weeks = u->number; + if (weeks > effect) weeks = effect; + reduce_skill(u, sb, weeks); + ADDMSG(&u->faction->msgs, msg_message("dumbeffect", + "unit weeks skill", u, weeks, (skill_t)sb->id)); + } /* sonst Glück gehabt: wer nix weiss, kann nix vergessen... */ + change_effect(u, oldpotiontype[P_FOOL], -effect); + } +} + static void age_unit(region * r, unit * u) { const race *rc = u_race(u); + dumbeffect(u); ++u->age; if (u->number > 0 && rc->age_unit) { rc->age_unit(u); @@ -198,26 +221,6 @@ static void live(region * r) /* IUW: age_unit() kann u loeschen, u->next ist dann * undefiniert, also muessen wir hier schon das nächste * Element bestimmen */ - - int effect = get_effect(u, oldpotiontype[P_FOOL]); - if (effect > 0) { /* Trank "Dumpfbackenbrot" */ - skill *sv = u->skills, *sb = NULL; - while (sv != u->skills + u->skill_size) { - if (sb == NULL || skill_compare(sv, sb) > 0) { - sb = sv; - } - ++sv; - } - /* bestes Talent raussuchen */ - if (sb != NULL) { - int weeks = u->number; - if (weeks > effect) weeks = effect; - reduce_skill(u, sb, weeks); - ADDMSG(&u->faction->msgs, msg_message("dumbeffect", - "unit weeks skill", u, weeks, (skill_t)sb->id)); - } /* sonst Glück gehabt: wer nix weiss, kann nix vergessen... */ - change_effect(u, oldpotiontype[P_FOOL], -effect); - } age_unit(r, u); if (*up == u) up = &u->next; diff --git a/src/test_eressea.c b/src/test_eressea.c index fe3458d1e..c299fc09c 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -92,33 +92,34 @@ int RunAllTests(int argc, char *argv[]) /* items */ ADD_SUITE(xerewards); /* kernel */ + ADD_SUITE(academy); + ADD_SUITE(alchemy); ADD_SUITE(alliance); + ADD_SUITE(ally); + ADD_SUITE(building); ADD_SUITE(command); ADD_SUITE(db); - ADD_SUITE(plane); - ADD_SUITE(unit); ADD_SUITE(faction); ADD_SUITE(group); ADD_SUITE(build); - ADD_SUITE(pool); ADD_SUITE(curse); ADD_SUITE(equipment); ADD_SUITE(familiar); ADD_SUITE(item); ADD_SUITE(magic); - ADD_SUITE(academy); - ADD_SUITE(alchemy); + ADD_SUITE(magicresistance); + ADD_SUITE(messages); + ADD_SUITE(plane); + ADD_SUITE(pool); ADD_SUITE(reports); ADD_SUITE(region); ADD_SUITE(save); ADD_SUITE(ship); + ADD_SUITE(skills); ADD_SUITE(spellbook); - ADD_SUITE(building); ADD_SUITE(spell); ADD_SUITE(spells); - ADD_SUITE(magicresistance); - ADD_SUITE(ally); - ADD_SUITE(messages); + ADD_SUITE(unit); /* gamecode */ ADD_SUITE(battle); ADD_SUITE(calendar);