diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0ff92bf2d..cf96cfbc2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -188,6 +188,7 @@ set(TESTS_SRC tests.c academy.test.c alchemy.test.c + automate.test.c battle.test.c creport.test.c direction.test.c diff --git a/src/automate.c b/src/automate.c index 0855ff0e3..c1d4b384b 100644 --- a/src/automate.c +++ b/src/automate.c @@ -13,14 +13,6 @@ #include -typedef struct student { - unit *u; - skill_t sk; - int level; -} student; - -#define MAXSTUDENTS 128 - int cmp_students(const void *lhs, const void *rhs) { const student *a = (const student *)lhs; const student *b = (const student *)rhs; @@ -32,16 +24,16 @@ int cmp_students(const void *lhs, const void *rhs) { return (int)a->sk - (int)b->sk; } -void do_autostudy(region *r) { +int autostudy_init(student students[], int max_students, region *r) +{ unit *u; int nstudents = 0; - student students[MAXSTUDENTS]; for (u = r->units; u; u = u->next) { keyword_t kwd = getkeyword(u->thisorder); if (kwd == K_AUTOSTUDY) { student * st = students + nstudents; - if (++nstudents == MAXSTUDENTS) { + if (++nstudents == max_students) { log_fatal("you must increase MAXSTUDENTS"); } st->u = u; @@ -50,10 +42,18 @@ void do_autostudy(region *r) { st->level = effskill_study(u, st->sk); } } + return nstudents; +} + +#define MAXSTUDENTS 128 + +void do_autostudy(region *r) { + student students[MAXSTUDENTS]; + int nstudents = autostudy_init(students, MAXSTUDENTS, r); + if (nstudents > 0) { - int i, taught = 0; + int i; skill_t sk = NOSKILL; - student *teacher = NULL, *student = NULL; qsort(students, nstudents, sizeof(student), cmp_students); for (i = 0; i != nstudents; ++i) { diff --git a/src/automate.h b/src/automate.h index ded8f938b..49b052f56 100644 --- a/src/automate.h +++ b/src/automate.h @@ -21,8 +21,20 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifndef H_GC_AUTOMATE #define H_GC_AUTOMATE +#include "skill.h" + struct region; +struct unit; + +typedef struct student { + struct unit *u; + skill_t sk; + int level; + int learn; +} student; void do_autostudy(struct region *r); +int autostudy_init(student students[], int max_students, struct region *r); + #endif diff --git a/src/automate.test.c b/src/automate.test.c new file mode 100644 index 000000000..d8dc8ed74 --- /dev/null +++ b/src/automate.test.c @@ -0,0 +1,38 @@ +#ifdef _MSC_VER +#include +#endif + +#include "automate.h" + +#include "kernel/faction.h" +#include "kernel/order.h" +#include "kernel/region.h" +#include "kernel/unit.h" + +#include "tests.h" + +#include + +static void test_autostudy(CuTest *tc) { + student students[4]; + unit *u1, *u2; + faction *f; + region *r; + + test_setup(); + r = test_create_plain(0, 0); + f = test_create_faction(NULL); + u1 = test_create_unit(f, r); + u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]); + u2 = test_create_unit(f, r); + u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]); + CuAssertIntEquals(tc, 2, autostudy_init(students, 4, r)); + test_teardown(); +} + +CuSuite *get_automate_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_autostudy); + return suite; +} diff --git a/src/kernel/order.c b/src/kernel/order.c index ac2573758..342f45577 100644 --- a/src/kernel/order.c +++ b/src/kernel/order.c @@ -84,7 +84,7 @@ char* get_command(const order *ord, const struct locale *lang, char *sbuffer, si sbs_strcat(&sbs, str); if (ord->id < 0) { skill_t sk = (skill_t)(100+ord->id); - assert(kwd == K_STUDY && sk != SK_MAGIC && sk < MAXSKILLS); + assert((kwd == K_STUDY || kwd == K_AUTOSTUDY) && sk != SK_MAGIC && sk < MAXSKILLS); str = skillname(sk, lang); if (str) { if (strchr(str, ' ') == NULL) { diff --git a/src/kernel/order.test.c b/src/kernel/order.test.c index 3a2f44c56..d1f8b4176 100644 --- a/src/kernel/order.test.c +++ b/src/kernel/order.test.c @@ -113,6 +113,30 @@ static void test_parse_make(CuTest *tc) { test_teardown(); } +static void test_parse_autostudy(CuTest *tc) { + char cmd[32]; + order *ord; + struct locale * lang; + + test_setup(); + lang = get_or_create_locale("en"); + locale_setstring(lang, mkname("skill", skillnames[SK_ENTERTAINMENT]), "Entertainment"); + locale_setstring(lang, keyword(K_STUDY), "STUDY"); + locale_setstring(lang, keyword(K_AUTOSTUDY), "AUTOSTUDY"); + locale_setstring(lang, parameters[P_AUTO], "AUTO"); + init_locale(lang); + + ord = parse_order("STUDY AUTO Entertainment", lang); + CuAssertPtrNotNull(tc, ord); + CuAssertIntEquals(tc, K_AUTOSTUDY, getkeyword(ord)); + CuAssertStrEquals(tc, "AUTOSTUDY Entertainment", get_command(ord, lang, cmd, sizeof(cmd))); + + CuAssertIntEquals(tc, K_AUTOSTUDY, init_order(ord, lang)); + CuAssertStrEquals(tc, "Entertainment", getstrtoken()); + free_order(ord); + test_teardown(); +} + static void test_parse_make_temp(CuTest *tc) { char cmd[32]; order *ord; @@ -130,7 +154,7 @@ static void test_parse_make_temp(CuTest *tc) { CuAssertIntEquals(tc, K_MAKETEMP, getkeyword(ord)); CuAssertStrEquals(tc, "MAKETEMP herp", get_command(ord, lang, cmd, sizeof(cmd))); - CuAssertIntEquals(tc, K_MAKETEMP, init_order_depr(ord)); + CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord, lang)); CuAssertStrEquals(tc, "herp", getstrtoken()); free_order(ord); test_teardown(); @@ -153,7 +177,7 @@ static void test_parse_maketemp(CuTest *tc) { CuAssertPtrNotNull(tc, ord); CuAssertStrEquals(tc, "MAKETEMP herp", get_command(ord, lang, cmd, sizeof(cmd))); CuAssertIntEquals(tc, K_MAKETEMP, getkeyword(ord)); - CuAssertIntEquals(tc, K_MAKETEMP, init_order_depr(ord)); + CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord, lang)); CuAssertStrEquals(tc, "herp", getstrtoken()); free_order(ord); test_teardown(); @@ -167,7 +191,7 @@ static void test_init_order(CuTest *tc) { lang = get_or_create_locale("en"); ord = create_order(K_MAKETEMP, lang, "hurr durr"); - CuAssertIntEquals(tc, K_MAKETEMP, init_order_depr(ord)); + CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord, lang)); CuAssertStrEquals(tc, "hurr", getstrtoken()); CuAssertStrEquals(tc, "durr", getstrtoken()); free_order(ord); @@ -548,6 +572,7 @@ CuSuite *get_order_suite(void) SUITE_ADD_TEST(suite, test_study_order_quoted); SUITE_ADD_TEST(suite, test_parse_order); SUITE_ADD_TEST(suite, test_parse_make); + SUITE_ADD_TEST(suite, test_parse_autostudy); SUITE_ADD_TEST(suite, test_parse_make_temp); SUITE_ADD_TEST(suite, test_parse_maketemp); SUITE_ADD_TEST(suite, test_init_order); diff --git a/src/study.c b/src/study.c index 6df5b5eaf..217fe9505 100644 --- a/src/study.c +++ b/src/study.c @@ -343,7 +343,7 @@ int teach_cmd(unit * teacher, struct order *ord) init_order(student->thisorder, student->faction->locale); sk = getskill(student->faction->locale); if (sk != NOSKILL - && effskill_study(teacher, sk) - TEACHDIFFERENCE >= effskill(student, sk)) { + && effskill_study(teacher, sk) - TEACHDIFFERENCE >= effskill(student, sk, NULL)) { teaching -= teach_unit(teacher, student, teaching, sk, true, &academy_students); } } @@ -432,7 +432,7 @@ int teach_cmd(unit * teacher, struct order *ord) continue; } - if (effskill_study(student, sk, NULL) > effskill_study(teacher, sk) + if (effskill_study(student, sk) > effskill_study(teacher, sk) - TEACHDIFFERENCE) { if (feedback) { ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "teach_asgood", diff --git a/src/test_eressea.c b/src/test_eressea.c index c299fc09c..5684a8ad4 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -93,7 +93,6 @@ int RunAllTests(int argc, char *argv[]) ADD_SUITE(xerewards); /* kernel */ ADD_SUITE(academy); - ADD_SUITE(alchemy); ADD_SUITE(alliance); ADD_SUITE(ally); ADD_SUITE(building); @@ -121,6 +120,8 @@ int RunAllTests(int argc, char *argv[]) ADD_SUITE(spells); ADD_SUITE(unit); /* gamecode */ + ADD_SUITE(alchemy); + ADD_SUITE(automate); ADD_SUITE(battle); ADD_SUITE(calendar); ADD_SUITE(creport);