From 6326664b86ee1d80e3252dc0325580d5ca362a2f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 28 Oct 2018 21:48:52 +0100 Subject: [PATCH 1/7] BUG 2505 proof by test. --- scripts/tests/common.lua | 15 +++++++++++++++ scripts/tests/e2/buildings.lua | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index 403db0a46..31881ab7a 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -1058,6 +1058,21 @@ function test_give_silver() assert_equal(10, u:get_item("money")) end +function test_build_castle_one_stage() + local r = region.create(0, 0, 'plain') + local f = faction.create('human') + local u = unit.create(f, r, 2) + + u:add_item('stone', 4) + + u:set_skill('building', 1) + u:add_order('MACHE BURG') + + process_orders() + assert_equal(2, u.building.size) + assert_equal(2, u:get_item('stone')) +end + function test_build_castle() local r = region.create(0, 0, "plain") local f = create_faction('human') diff --git a/scripts/tests/e2/buildings.lua b/scripts/tests/e2/buildings.lua index 02298bd97..eb49f0ee2 100644 --- a/scripts/tests/e2/buildings.lua +++ b/scripts/tests/e2/buildings.lua @@ -29,6 +29,21 @@ function test_castle_names() assert_equal("citadel", b:get_typename(6250)) end +function test_build_castle_one_stage() + local r = region.create(0, 0, 'plain') + local f = faction.create('human') + local u = unit.create(f, r, 2) + + u:add_item('stone', 4) + + u:set_skill('building', 1) + u:add_order('MACHE BURG') + + process_orders() + assert_equal(2, u.building.size) + assert_equal(2, u:get_item('stone')) +end + function test_build_castle_stages() local r = region.create(0,0, "plain") local f = faction.create("human") From f8040e2d9fbee932a98c19ad0bc21ac6fe8d3011 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 29 Oct 2018 18:54:23 +0100 Subject: [PATCH 2/7] unit test to also prove bug 2505 --- src/kernel/build.test.c | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/kernel/build.test.c b/src/kernel/build.test.c index 537f9d860..e76cf89c0 100644 --- a/src/kernel/build.test.c +++ b/src/kernel/build.test.c @@ -52,6 +52,53 @@ static unit * setup_build(build_fixture *bf) { return bf->u; } +static building_type *setup_castle(item_type *it_stone) { + building_type *btype; + building_stage *stage; + construction * cons; + + btype = test_create_buildingtype("castle"); + stage = btype->stages = calloc(1, sizeof(building_stage)); + cons = stage->construction = calloc(1, sizeof(construction)); + cons->materials = calloc(2, sizeof(requirement)); + cons->materials[0].number = 1; + cons->materials[0].rtype = it_stone->rtype; + cons->minskill = 1; + cons->maxsize = 2; + cons->reqsize = 1; + cons->skill = SK_BUILDING; + stage = stage->next = calloc(1, sizeof(building_stage)); + cons = stage->construction = calloc(1, sizeof(construction)); + cons->materials = calloc(2, sizeof(requirement)); + cons->materials[0].number = 1; + cons->materials[0].rtype = it_stone->rtype; + cons->minskill = 1; + cons->maxsize = 8; + cons->reqsize = 1; + cons->skill = SK_BUILDING; + return btype; +} + +static void test_build_building_stages(CuTest *tc) { + building_type *btype; + item_type *it_stone; + unit *u; + + test_setup(); + init_resources(); + it_stone = test_create_itemtype("stone"); + btype = setup_castle(it_stone); + u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0)); + set_level(u, SK_BUILDING, 2); + i_change(&u->items, it_stone, 4); + build_building(u, btype, -1, INT_MAX, NULL); + CuAssertPtrNotNull(tc, u->building); + CuAssertIntEquals(tc, 2, u->building->size); + CuAssertIntEquals(tc, 2, i_get(u->items, it_stone)); + + test_teardown(); +} + static void teardown_build(build_fixture *bf) { free(bf->cons.materials); test_teardown(); @@ -390,6 +437,7 @@ CuSuite *get_build_suite(void) SUITE_ADD_TEST(suite, test_build_with_ring); SUITE_ADD_TEST(suite, test_build_with_potion); SUITE_ADD_TEST(suite, test_build_building_success); + SUITE_ADD_TEST(suite, test_build_building_stages); SUITE_ADD_TEST(suite, test_build_building_with_golem); SUITE_ADD_TEST(suite, test_build_building_no_materials); SUITE_ADD_TEST(suite, test_build_destroy_cmd); From e8ca81bc1a816e5e0500ca91d0e686f9e62b3034 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 29 Oct 2018 19:35:49 +0100 Subject: [PATCH 3/7] BUG 2505: make build code more comlpicated, and fix multi-stage buildings. --- src/kernel/build.c | 51 +++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/src/kernel/build.c b/src/kernel/build.c index 1f96fcda9..8b654c45c 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -527,28 +527,19 @@ int build_skill(unit *u, int basesk, int skill_mod) { * of the first object have already been finished. return the * actual size that could be built. */ -int build(unit * u, const construction * ctype, int completed, int want, int skill_mod) -{ - const construction *con = ctype; - int skills = INT_MAX; /* number of skill points remainig */ - int basesk = 0; +static int build_limited(unit * u, const construction * con, int completed, int want, int basesk, int *skill_total) { + int skills = *skill_total; int made = 0; - if (want <= 0) + if (want <= 0) { return 0; + } if (con == NULL) { return ENOMATERIALS; } if (completed == con->maxsize) { return ECOMPLETE; } - if (con->skill != NOSKILL) { - basesk = effskill(u, con->skill, 0); - if (basesk == 0) - return ENEEDSKILL; - - skills = build_skill(u, basesk, skill_mod); - } for (; want > 0 && skills > 0;) { int err, n; @@ -615,9 +606,27 @@ int build(unit * u, const construction * ctype, int completed, int want, int ski want -= n; completed = completed + n; } - /* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */ - produceexp(u, ctype->skill, (made < u->number) ? made : u->number); + *skill_total = skills; + return made; +} +int build(unit * u, const construction * con, int completed, int want, int skill_mod) +{ + int skills = INT_MAX; /* number of skill points remainig */ + int made, basesk = 0; + + assert(con->skill != NOSKILL); + basesk = effskill(u, con->skill, 0); + if (basesk == 0) { + return ENEEDSKILL; + } + + skills = build_skill(u, basesk, skill_mod); + made = build_limited(u, con, completed, want, basesk, &skills); + /* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */ + if (made > 0) { + produceexp(u, con->skill, (made < u->number) ? made : u->number); + } return made; } @@ -686,7 +695,7 @@ static int build_failure(unit *u, order *ord, const building_type *btype, int wa return err; } -static int build_stages(unit *u, const building_type *btype, int built, int n) { +static int build_stages(unit *u, const building_type *btype, int built, int n, int basesk, int *skill_total) { const building_stage *stage; int made = 0; @@ -706,7 +715,7 @@ static int build_stages(unit *u, const building_type *btype, int built, int n) { want = todo; } } - err = build(u, con, built, want, 0); + err = build_limited(u, con, built, want, basesk, skill_total); if (err < 0) { if (made == 0) { /* could not make any part at all */ @@ -744,10 +753,14 @@ build_building(unit * u, const building_type * btype, int id, int want, order * const char *btname; order *new_order = NULL; const struct locale *lang = u->faction->locale; + int skills, basesk; /* number of skill points remainig */ assert(u->number); assert(btype->stages && btype->stages->construction); - if (effskill(u, SK_BUILDING, 0) == 0) { + + basesk = effskill(u, SK_BUILDING, 0); + skills = build_skill(u, basesk, 0); + if (skills == 0) { cmistake(u, ord, 101, MSG_PRODUCE); return 0; } @@ -837,7 +850,7 @@ build_building(unit * u, const building_type * btype, int id, int want, order * } } - built = build_stages(u, btype, built, n); + built = build_stages(u, btype, built, n, basesk, &skills); if (built < 0) { return build_failure(u, ord, btype, want, built); From 00718424cf83709afbeac334ea8d365c87307943 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 30 Oct 2018 06:02:55 +0100 Subject: [PATCH 4/7] missing limits include --- src/kernel/build.test.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/kernel/build.test.c b/src/kernel/build.test.c index e76cf89c0..9de94e0a4 100644 --- a/src/kernel/build.test.c +++ b/src/kernel/build.test.c @@ -17,8 +17,9 @@ #include #include -#include #include +#include +#include typedef struct build_fixture { faction *f; From a8ff6d2a99515dd7c75908832e19593632176a14 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 30 Oct 2018 20:11:35 +0100 Subject: [PATCH 5/7] gmtool can now select and highlight islands. --- src/gmtool.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/gmtool.h | 2 +- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/gmtool.c b/src/gmtool.c index fdbfd3faa..0ad9bf0ce 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -55,6 +55,7 @@ #include "wormhole.h" #include "teleport.h" +#include #include #include @@ -708,7 +709,7 @@ void highlight_region(region * r, int toggle) } } -void select_coordinate(struct selection *selected, int nx, int ny, int toggle) +void select_coordinate(struct selection *selected, int nx, int ny, bool toggle) { if (toggle) tag_region(selected, nx, ny); @@ -716,7 +717,50 @@ void select_coordinate(struct selection *selected, int nx, int ny, int toggle) untag_region(selected, nx, ny); } -enum { MODE_MARK, MODE_SELECT, MODE_UNMARK, MODE_UNSELECT }; +enum select_t { MODE_MARK, MODE_SELECT, MODE_UNMARK, MODE_UNSELECT }; + +static void select_island(state *st, int selectmode) +{ + region *r; + int nx = st->cursor.x; + int ny = st->cursor.y; + + pnormalize(&nx, &ny, st->cursor.pl); + r = findregion(nx, ny); + if (r && r->land) { + selist *ql, *stack = NULL; + int qi = 0; + + selist_push(&stack, r); + for (ql = stack, qi = 0; ql; selist_advance(&ql, &qi, 1)) { + region *r = (region *)selist_get(ql, qi); + region *rnext[MAXDIRECTIONS]; + int i; + + fset(r, RF_MARK); + if (selectmode & MODE_SELECT) { + select_coordinate(st->selected, r->x, r->y, + selectmode == MODE_SELECT); + } + else { + highlight_region(r, selectmode == MODE_MARK); + } + get_neighbours(r, rnext); + for (i = 0; i != MAXDIRECTIONS; ++i) { + region *rn = rnext[i]; + if (rn && rn->land && !fval(rn, RF_MARK)) { + selist_push(&stack, rn); + } + } + } + + for (ql = stack, qi = 0; ql; selist_advance(&ql, &qi, 1)) { + region *r = (region *)selist_get(ql, qi); + freset(r, RF_MARK); + } + selist_free(stack); + } +} static void select_regions(state * st, int selectmode) { @@ -870,6 +914,11 @@ static void select_regions(state * st, int selectmode) } } } + else if (findmode == 'i') { + sprintf(sbuffer, "%swand: ", status); + statusline(st->wnd_status->handle, sbuffer); + select_island(st, selectmode); + } else if (findmode == 't') { const struct terrain_type *terrain; sprintf(sbuffer, "%sterrain: ", status); diff --git a/src/gmtool.h b/src/gmtool.h index 5a2449c9a..6566db7cb 100644 --- a/src/gmtool.h +++ b/src/gmtool.h @@ -29,7 +29,7 @@ extern "C" { const char *prompt); void highlight_region(struct region *r, int on); - void select_coordinate(struct selection *selected, int x, int y, int on); + void select_coordinate(struct selection *selected, int x, int y, bool on); void run_mapper(void); extern int force_color; From b5b39024f27ed0c1bc04a8afacd9f9f2e1e5541d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 30 Oct 2018 21:01:09 +0100 Subject: [PATCH 6/7] BUG 2506: starting regions have bad resource levels. add some one-off custom code to fix the resource levels of selected regions --- src/gmtool.c | 100 +++++++++++++++++++++++++++++++++++++++++ src/kernel/region.c | 15 ++++++- src/kernel/region.h | 2 + src/kernel/resources.c | 17 ++++--- src/kernel/resources.h | 1 + 5 files changed, 126 insertions(+), 9 deletions(-) diff --git a/src/gmtool.c b/src/gmtool.c index 0ad9bf0ce..757841af6 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -452,7 +453,10 @@ static void paint_info_region(window * wnd, const state * st) line++; umvwprintw(win, line++, 1, "%s, age %d", r->terrain->_name, r->age); if (r->land) { + int iron = region_getresource_level(r, get_resourcetype(R_IRON)); + int stone = region_getresource_level(r, get_resourcetype(R_STONE)); mvwprintw(win, line++, 1, "$:%6d P:%5d", rmoney(r), rpeasants(r)); + mvwprintw(win, line++, 1, "S:%6d I:%5d", stone, iron); mvwprintw(win, line++, 1, "H:%6d %s:%5d", rhorses(r), (r->flags & RF_MALLORN) ? "M" : "T", r->land->trees[1] + r->land->trees[2]); @@ -530,6 +534,33 @@ static void statusline(WINDOW * win, const char *str) wnoutrefresh(win); } +static void reset_resources(region *r, const struct terrain_type *terrain) +{ + int i; + + for (i = 0; terrain->production[i].type; ++i) { + rawmaterial *rm; + const terrain_production *production = terrain->production + i; + const resource_type *rtype = production->type; + + for (rm = r->resources; rm; rm = rm->next) { + if (rm->rtype == rtype) + break; + } + if (rm) { + struct rawmaterial_type *rmt; + set_resource(rm, + dice_rand(production->startlevel), + dice_rand(production->base), + dice_rand(production->divisor)); + rmt = rmt_get(rtype); + if (rmt && rmt->terraform) { + rmt->terraform(rm, r); + } + } + } +} + static void reset_region(region *r) { unit **up = &r->units; bool players = false; @@ -555,6 +586,7 @@ static void reset_region(region *r) { } if (r->land) { init_region(r); + reset_resources(r, r->terrain); } } } @@ -600,6 +632,69 @@ static void terraform_at(coordinate * c, const terrain_type * terrain) } } +static void selection_walk(selection * selected, void(*callback)(region *, void *), void *udata) { + int i; + + for (i = 0; i != MAXTHASH; ++i) { + tag **tp = &selected->tags[i]; + while (*tp) { + region *r; + tag *t = *tp; + int nx = t->coord.x, ny = t->coord.y; + plane *pl = t->coord.pl; + + pnormalize(&nx, &ny, pl); + r = findregion(nx, ny); + if (r != NULL) { + callback(r, udata); + } + tp = &t->nexthash; + } + } +} + +static void reset_levels_cb(region *r, void *udata) { + struct rawmaterial *res; + UNUSED_ARG(udata); + for (res = r->resources; res; res = res->next) { + if (res->level > 3) { + res->level = 1; + } + } +} + +/** + * BUG 2506: reset drained mountains to level 1 + */ +static void +fix_selection(selection * selected) +{ + selection_walk(selected, reset_levels_cb, NULL); +} + +static void +reset_selection(selection * selected) +{ + int i; + + for (i = 0; i != MAXTHASH; ++i) { + tag **tp = &selected->tags[i]; + while (*tp) { + region *r; + tag *t = *tp; + int nx = t->coord.x, ny = t->coord.y; + plane *pl = t->coord.pl; + + pnormalize(&nx, &ny, pl); + r = findregion(nx, ny); + if (r != NULL) { + reset_region(r); + } + tp = &t->nexthash; + } + } +} + static void terraform_selection(selection * selected, const terrain_type * terrain) { @@ -1259,7 +1354,12 @@ static void handlekey(state * st, int c) statusline(st->wnd_status->handle, "tag-"); doupdate(); switch (getch()) { + case 'r': + reset_selection(st->selected); + break; case 'f': + fix_selection(st->selected); + break; case 't': terraform_selection(st->selected, select_terrain(st, NULL)); st->modified = 1; diff --git a/src/kernel/region.c b/src/kernel/region.c index 29f7222e1..04c46989c 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -827,7 +827,7 @@ void free_land(land_region * lr) free(lr); } -void region_setresource(region * r, const resource_type * rtype, int value) +void region_setresource(region * r, const struct resource_type *rtype, int value) { rawmaterial *rm = r->resources; while (rm) { @@ -870,7 +870,18 @@ void region_setresource(region * r, const resource_type * rtype, int value) } } -int region_getresource(const region * r, const resource_type * rtype) +int region_getresource_level(const region * r, const struct resource_type * rtype) +{ + const rawmaterial *rm; + for (rm = r->resources; rm; rm = rm->next) { + if (rm->rtype == rtype) { + return rm->level; + } + } + return -1; +} + +int region_getresource(const region * r, const struct resource_type *rtype) { const rawmaterial *rm; for (rm = r->resources; rm; rm = rm->next) { diff --git a/src/kernel/region.h b/src/kernel/region.h index bf932e9c3..f439bceed 100644 --- a/src/kernel/region.h +++ b/src/kernel/region.h @@ -261,6 +261,8 @@ extern "C" { void region_setname(struct region *self, const char *name); const char *region_getinfo(const struct region *self); void region_setinfo(struct region *self, const char *name); + int region_getresource_level(const struct region * r, + const struct resource_type * rtype); int region_getresource(const struct region *r, const struct resource_type *rtype); void region_setresource(struct region *r, const struct resource_type *rtype, diff --git a/src/kernel/resources.c b/src/kernel/resources.c index 231b763f8..4bb27616d 100644 --- a/src/kernel/resources.c +++ b/src/kernel/resources.c @@ -46,8 +46,6 @@ void update_resources(region * r) } } -extern int dice_rand(const char *s); - static void update_resource(struct rawmaterial *res, double modifier) { double amount = (res->level - res->startlevel) / 100.0 * res->divisor + 1; @@ -59,6 +57,15 @@ static void update_resource(struct rawmaterial *res, double modifier) assert(res->amount > 0); } +void set_resource(struct rawmaterial *rm, int level, int base, int divisor) +{ + rm->level = level; + rm->startlevel = level; + rm->base = base; + rm->amount = base; + rm->divisor = divisor; +} + struct rawmaterial * add_resource(region * r, int level, int base, int divisor, const resource_type * rtype) @@ -67,13 +74,9 @@ const resource_type * rtype) rm->next = r->resources; r->resources = rm; - rm->level = level; - rm->startlevel = level; - rm->base = base; - rm->amount = base; - rm->divisor = divisor; rm->flags = 0; rm->rtype = rtype; + set_resource(rm, level, base, divisor); return rm; } diff --git a/src/kernel/resources.h b/src/kernel/resources.h index 8f291c305..65431bb2c 100644 --- a/src/kernel/resources.h +++ b/src/kernel/resources.h @@ -70,6 +70,7 @@ extern "C" { const struct resource_type *); struct rawmaterial_type *rmt_get(const struct resource_type *); + void set_resource(struct rawmaterial *rm, int level, int base, int divisor); struct rawmaterial *add_resource(struct region *r, int level, int base, int divisor, const struct resource_type *rtype); struct rawmaterial_type *rmt_create(struct resource_type *rtype); From 1a10c0271d8eb7fcfdc63b668dc01cb4e3616bd5 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 4 Nov 2018 09:08:50 +0100 Subject: [PATCH 7/7] Bug 2511: LERNE AUTO fixed, student limit increased --- src/automate.c | 53 ++++++++++++++++++++++++++++++--------------- src/automate.h | 2 +- src/automate.test.c | 29 +++++++++++++++++++------ src/kernel/skills.h | 2 +- 4 files changed, 59 insertions(+), 27 deletions(-) diff --git a/src/automate.c b/src/automate.c index 9a3516c44..e4d7d60ad 100644 --- a/src/automate.c +++ b/src/automate.c @@ -28,33 +28,42 @@ static int cmp_scholars(const void *lhs, const void *rhs) return (int)a->sk - (int)b->sk; } -int autostudy_init(scholar scholars[], int max_scholars, region *r) +int autostudy_init(scholar scholars[], int max_scholars, unit **units) { - unit *u; + unit *unext = NULL, *u = *units; + faction *f = u->faction; int nscholars = 0; - for (u = r->units; u; u = u->next) { + while (u) { keyword_t kwd = init_order(u->thisorder, u->faction->locale); if (kwd == K_AUTOSTUDY) { if (long_order_allowed(u)) { - scholar * st = scholars + nscholars; - skill_t sk = getskill(u->faction->locale); - if (check_student(u, u->thisorder, sk)) { - st->sk = sk; - st->level = effskill_study(u, st->sk); - st->learn = 0; - st->u = u; - if (++nscholars == max_scholars) { - log_fatal("you must increase MAXSCHOLARS"); + if (f == u->faction) { + scholar * st = scholars + nscholars; + skill_t sk = getskill(u->faction->locale); + if (check_student(u, u->thisorder, sk)) { + st->sk = sk; + st->level = effskill_study(u, st->sk); + st->learn = 0; + st->u = u; + if (++nscholars == max_scholars) { + log_fatal("you must increase MAXSCHOLARS"); + } } } + else if (!unext) { + unext = u; + } } else { ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "error_race_nolearn", "race", u_race(u))); } } + u = u->next; } + *units = unext; + scholars[nscholars].u = NULL; if (nscholars > 0) { qsort(scholars, nscholars, sizeof(scholar), cmp_scholars); } @@ -149,15 +158,23 @@ void autostudy_run(scholar scholars[], int nscholars) } } -#define MAXSCHOLARS 128 +#define MAXSCHOLARS 512 void do_autostudy(region *r) { + static int max_scholars; + unit *units = r->units; scholar scholars[MAXSCHOLARS]; - int i, nscholars = autostudy_init(scholars, MAXSCHOLARS, r); - autostudy_run(scholars, nscholars); - for (i = 0; i != nscholars; ++i) { - int days = STUDYDAYS * scholars[i].learn; - learn_skill(scholars[i].u, scholars[i].sk, days); + while (units) { + int i, nscholars = autostudy_init(scholars, MAXSCHOLARS, &units); + if (nscholars > max_scholars) { + stats_count("automate.max_scholars", nscholars - max_scholars); + max_scholars = nscholars; + } + autostudy_run(scholars, nscholars); + for (i = 0; i != nscholars; ++i) { + int days = STUDYDAYS * scholars[i].learn; + learn_skill(scholars[i].u, scholars[i].sk, days); + } } } diff --git a/src/automate.h b/src/automate.h index 61fed6866..314791b8f 100644 --- a/src/automate.h +++ b/src/automate.h @@ -37,7 +37,7 @@ typedef struct scholar { void do_autostudy(struct region *r); -int autostudy_init(scholar scholars[], int max_scholars, struct region *r); +int autostudy_init(scholar scholars[], int max_scholars, struct unit **units); void autostudy_run(scholar scholars[], int nscholars); #endif diff --git a/src/automate.test.c b/src/automate.test.c index 6c87b8656..0caa70f3b 100644 --- a/src/automate.test.c +++ b/src/automate.test.c @@ -17,7 +17,7 @@ static void test_autostudy_init(CuTest *tc) { scholar scholars[4]; - unit *u1, *u2, *u3, *u4; + unit *u1, *u2, *u3, *u4, *u5, *ulist; faction *f; region *r; @@ -35,10 +35,13 @@ static void test_autostudy_init(CuTest *tc) { set_level(u2, SK_ENTERTAINMENT, 2); u3 = test_create_unit(f, r); u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]); - u4 = test_create_unit(test_create_faction(NULL), r); + u4 = test_create_unit(f, r); u4->thisorder = create_order(K_AUTOSTUDY, f->locale, "Dudelidu"); + u5 = test_create_unit(test_create_faction(NULL), r); + u5->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]); scholars[3].u = NULL; - CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, r)); + ulist = r->units; + CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, &ulist)); CuAssertPtrNotNull(tc, test_find_messagetype(u4->faction->msgs, "error77")); CuAssertPtrEquals(tc, u2, scholars[0].u); CuAssertIntEquals(tc, 2, scholars[0].level); @@ -53,12 +56,20 @@ static void test_autostudy_init(CuTest *tc) { CuAssertIntEquals(tc, 0, scholars[2].learn); CuAssertIntEquals(tc, SK_PERCEPTION, scholars[2].sk); CuAssertPtrEquals(tc, NULL, scholars[3].u); + CuAssertPtrEquals(tc, u5, ulist); + CuAssertIntEquals(tc, 1, autostudy_init(scholars, 4, &ulist)); + CuAssertPtrEquals(tc, u5, scholars[0].u); + CuAssertIntEquals(tc, 0, scholars[0].level); + CuAssertIntEquals(tc, 0, scholars[0].learn); + CuAssertIntEquals(tc, SK_PERCEPTION, scholars[0].sk); + CuAssertPtrEquals(tc, NULL, scholars[1].u); + CuAssertPtrEquals(tc, NULL, ulist); test_teardown(); } static void test_autostudy_run(CuTest *tc) { scholar scholars[4]; - unit *u1, *u2, *u3; + unit *u1, *u2, *u3, *ulist; faction *f; region *r; @@ -76,7 +87,9 @@ static void test_autostudy_run(CuTest *tc) { u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]); set_number(u3, 15); scholars[3].u = NULL; - CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, r)); + ulist = r->units; + CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, &ulist)); + CuAssertPtrEquals(tc, NULL, ulist); autostudy_run(scholars, 3); CuAssertIntEquals(tc, 0, scholars[0].learn); CuAssertIntEquals(tc, 20, scholars[1].learn); @@ -86,7 +99,7 @@ static void test_autostudy_run(CuTest *tc) { static void test_autostudy_run_noteachers(CuTest *tc) { scholar scholars[4]; - unit *u1, *u2, *u3; + unit *u1, *u2, *u3, *ulist; faction *f; region *r; @@ -104,7 +117,9 @@ static void test_autostudy_run_noteachers(CuTest *tc) { u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]); set_number(u3, 15); scholars[3].u = NULL; - CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, r)); + ulist = r->units; + CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, &ulist)); + CuAssertPtrEquals(tc, NULL, ulist); autostudy_run(scholars, 3); CuAssertIntEquals(tc, 2, scholars[0].learn); CuAssertIntEquals(tc, 10, scholars[1].learn); diff --git a/src/kernel/skills.h b/src/kernel/skills.h index 94576295c..aa3c62339 100644 --- a/src/kernel/skills.h +++ b/src/kernel/skills.h @@ -26,7 +26,7 @@ extern "C" { #endif typedef struct skill { - skill_t id : 8; + int id : 8; int level : 8; int weeks : 8; int old : 8;