diff --git a/src/guard.c b/src/guard.c index ee26e467b..4b0c63e22 100644 --- a/src/guard.c +++ b/src/guard.c @@ -128,7 +128,7 @@ bool is_guard(const struct unit * u) unit *is_guarded(region * r, unit * u) { unit *u2; - int noguards = 1; + bool noguards = true; if (!fval(r, RF_GUARDED)) { return NULL; @@ -140,7 +140,7 @@ unit *is_guarded(region * r, unit * u) for (u2 = r->units; u2; u2 = u2->next) { if (is_guardian_r(u2)) { - noguards = 0; + noguards = false; if (is_guardian_u(u2, u)) { /* u2 is our guard. stop processing (we might have to go further next time) */ return u2; diff --git a/src/study.c b/src/study.c index 1dd4da8b8..f3372334a 100644 --- a/src/study.c +++ b/src/study.c @@ -53,6 +53,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include + /* libc includes */ #include #include @@ -216,24 +218,11 @@ teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk, n = _min(n, nteaching); if (n != 0) { - int index = 0; - if (teach == NULL) { a = a_add(&student->attribs, a_new(&at_learning)); teach = (teaching_info *)a->data.v; } - else { - while (teach->teachers[index] && index != MAXTEACHERS) - ++index; - } - if (index < MAXTEACHERS) - teach->teachers[index++] = teacher; - if (index < MAXTEACHERS) { - teach->teachers[index] = NULL; - } - else { - log_error("MAXTEACHERS=%d is too low for student %s, teacher %s", MAXTEACHERS, unitname(student), unitname(teacher)); - } + ql_push(&teach->teachers, teacher); teach->value += n; if (student->building && teacher->building == student->building) { @@ -717,7 +706,7 @@ int study_cmd(unit * u, order * ord) a = a_add(&u->attribs, a_new(&at_learning)); teach = (teaching_info *)a->data.v; assert(teach); - teach->teachers[0] = 0; + teach->teachers = NULL; } if (money > 0) { use_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, money); @@ -766,9 +755,9 @@ int study_cmd(unit * u, order * ord) learn_skill(u, sk, days); if (a != NULL) { - int index = 0; - while (teach->teachers[index] && index != MAXTEACHERS) { - unit *teacher = teach->teachers[index++]; + ql_iter qli = qli_init(&teach->teachers); + while (qli_more(qli)) { + unit *teacher = (unit *)qli_next(&qli); if (teacher->faction != u->faction) { bool feedback = alliedunit(u, teacher->faction, HELP_GUARD); if (feedback) { diff --git a/src/study.h b/src/study.h index 20903583a..8067bc9bd 100644 --- a/src/study.h +++ b/src/study.h @@ -27,6 +27,7 @@ extern "C" { #endif struct unit; + struct quicklist; int teach_cmd(struct unit *u, struct order *ord); int study_cmd(struct unit *u, struct order *ord); @@ -45,10 +46,9 @@ extern "C" { void demon_skillchange(struct unit *u); -#define MAXTEACHERS 32 #define TEACHNUMBER 10 typedef struct teaching_info { - struct unit *teachers[MAXTEACHERS]; + struct quicklist *teachers; int value; } teaching_info; diff --git a/src/study.test.c b/src/study.test.c index 47976930d..4c1e5f171 100644 --- a/src/study.test.c +++ b/src/study.test.c @@ -2,6 +2,7 @@ #include "study.h" +#include #include #include #include @@ -10,15 +11,18 @@ #include #include #include +#include #include #include #include #include #include +#include +#include + #include -#include #define MAXLOG 4 typedef struct log_entry { @@ -483,6 +487,7 @@ static void test_teach_one_to_many(CuTest *tc) { static void test_teach_many_to_one(CuTest *tc) { unit *u, *u1, *u2; + test_setup(); init_resources(); u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); @@ -505,6 +510,47 @@ static void test_teach_many_to_one(CuTest *tc) { test_cleanup(); } +static void test_teach_message(CuTest *tc) { + unit *u, *u1, *u2; + attrib *a; + ally *al; + teaching_info *teach; + + test_setup(); + init_resources(); + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + scale_number(u, 20); + u->thisorder = create_order(K_STUDY, u->faction->locale, "CROSSBOW"); + u1 = test_create_unit(test_create_faction(0), u->region); + set_level(u1, SK_CROSSBOW, TEACHDIFFERENCE); + u1->thisorder = create_order(K_TEACH, u->faction->locale, itoa36(u->no)); + u2 = test_create_unit(test_create_faction(0), u->region); + al = ally_add(&u->faction->allies, u2->faction); + al->status = HELP_GUARD; + set_level(u2, SK_CROSSBOW, TEACHDIFFERENCE); + u2->thisorder = create_order(K_TEACH, u->faction->locale, itoa36(u->no)); + CuAssertTrue(tc, !alliedunit(u, u1->faction, HELP_GUARD)); + CuAssertTrue(tc, alliedunit(u, u2->faction, HELP_GUARD)); + teach_cmd(u1, u1->thisorder); + teach_cmd(u2, u2->thisorder); + a = a_find(u->attribs, &at_learning); + CuAssertPtrNotNull(tc, a); + CuAssertPtrNotNull(tc, a->data.v); + teach = (teaching_info *)a->data.v; + CuAssertPtrNotNull(tc, teach->teachers); + CuAssertIntEquals(tc, 600, teach->value); + CuAssertIntEquals(tc, 2, ql_length(teach->teachers)); + CuAssertPtrEquals(tc, u1, ql_get(teach->teachers, 0)); + CuAssertPtrEquals(tc, u2, ql_get(teach->teachers, 1)); + study_cmd(u, u->thisorder); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(u1->faction->msgs, "teach_teacher")); + CuAssertPtrNotNull(tc, test_find_messagetype(u2->faction->msgs, "teach_teacher")); + CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "teach_student")); + a = a_find(u->attribs, &at_learning); + CuAssertPtrEquals(tc, NULL, a); + test_cleanup(); +} + static void test_teach_many_to_many(CuTest *tc) { unit *s1, *s2, *t1, *t2; region *r; @@ -554,6 +600,7 @@ CuSuite *get_study_suite(void) SUITE_ADD_TEST(suite, test_teach_one_to_many); SUITE_ADD_TEST(suite, test_teach_many_to_one); SUITE_ADD_TEST(suite, test_teach_many_to_many); + SUITE_ADD_TEST(suite, test_teach_message); SUITE_ADD_TEST(suite, test_teach_two_skills); SUITE_ADD_TEST(suite, test_learn_skill_single); SUITE_ADD_TEST(suite, test_learn_skill_multi);