diff --git a/src/wormhole.c b/src/wormhole.c index 1ce6686c9..10d1e4b70 100644 --- a/src/wormhole.c +++ b/src/wormhole.c @@ -55,17 +55,15 @@ static int cmp_age(const void *v1, const void *v2) return 0; } -static int wormhole_age(struct attrib *a, void *owner) +void wormhole_transfer(building *b, region *exit) { - building *entry = (building *)owner; - region *exit = (region *)a->data.v; - int maxtransport = entry->size; - region *r = entry->region; + int maxtransport = b->size; + region *r = b->region; unit *u = r->units; - UNUSED_ARG(owner); - for (; u != NULL && maxtransport != 0; u = u->next) { - if (u->building == entry) { + while (u != NULL && maxtransport != 0) { + unit *unext = u->next; + if (u->building == b) { message *m = NULL; if (u->number > maxtransport || has_limited_skills(u)) { m = msg_message("wormhole_requirements", "unit region", u, u->region); @@ -81,11 +79,18 @@ static int wormhole_age(struct attrib *a, void *owner) msg_release(m); } } + u = unext; } - remove_building(&r->buildings, entry); + remove_building(&r->buildings, b); ADDMSG(&r->msgs, msg_message("wormhole_dissolve", "region", r)); +} +static int wormhole_age(struct attrib *a, void *owner) { + building *b = (building *)owner; + region *exit = (region *)a->data.v; + + wormhole_transfer(b, exit); /* age returns 0 if the attribute needs to be removed, !=0 otherwise */ return AT_AGE_KEEP; } diff --git a/src/wormhole.h b/src/wormhole.h index 6c1536874..783b59983 100644 --- a/src/wormhole.h +++ b/src/wormhole.h @@ -22,8 +22,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif - extern void wormholes_update(void); - extern void wormholes_register(void); + struct region; + struct building; + + void wormholes_update(void); + void wormholes_register(void); + void wormhole_transfer(struct building *b, struct region *exit); #ifdef __cplusplus } diff --git a/src/wormhole.test.c b/src/wormhole.test.c index bec4a5ff8..4b6fe2d3c 100644 --- a/src/wormhole.test.c +++ b/src/wormhole.test.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -31,15 +32,13 @@ static void setup_wormholes(void) { static void test_make_wormholes(CuTest *tc) { region *r1, *r2, *match[2]; - terrain_type *t_plain; building_type *btype; test_setup(); setup_wormholes(); - t_plain = test_create_terrain("plain", LAND_REGION); btype = test_create_buildingtype("wormhole"); - match[0] = r1 = test_create_region(0, 0, t_plain); - match[1] = r2 = test_create_region(1, 0, t_plain); + match[0] = r1 = test_create_plain(0, 0); + match[1] = r2 = test_create_plain(1, 0); make_wormholes(match, 2, btype); CuAssertPtrNotNull(tc, r1->buildings); CuAssertPtrNotNull(tc, r1->buildings->attribs); @@ -54,14 +53,12 @@ static void test_make_wormholes(CuTest *tc) { static void test_sort_wormhole_regions(CuTest *tc) { region *r1, *r2, *match[2]; - terrain_type *t_plain; selist *rlist = 0; test_setup(); setup_wormholes(); - t_plain = test_create_terrain("plain", LAND_REGION); - r1 = test_create_region(0, 0, t_plain); - r2 = test_create_region(1, 0, t_plain); + r1 = test_create_plain(0, 0); + r2 = test_create_plain(1, 0); r1->age = 4; r2->age = 2; selist_push(&rlist, r1); @@ -73,10 +70,42 @@ static void test_sort_wormhole_regions(CuTest *tc) { test_teardown(); } +static void test_wormhole_transfer(CuTest *tc) { + region *r1, *r2; + building *b; + unit *u1, *u2; + struct faction *f; + + test_setup(); + setup_wormholes(); + r1 = test_create_plain(0, 0); + r2 = test_create_plain(1, 0); + b = test_create_building(r1, NULL); + b->size = 4; + f = test_create_faction(NULL); + u1 = test_create_unit(f, r1); + u1->number = 2; + u_set_building(u1, b); + u2 = test_create_unit(f, r1); + u2->number = 3; + u_set_building(u2, b); + u1 = test_create_unit(f, r1); + u1->number = 2; + u_set_building(u1, b); + wormhole_transfer(b, r2); + CuAssertPtrEquals(tc, u2, r1->units); + CuAssertPtrEquals(tc, NULL, u2->building); + CuAssertPtrEquals(tc, NULL, u2->next); + CuAssertPtrEquals(tc, r2, u1->region); + CuAssertPtrEquals(tc, u1, r2->units->next); + test_teardown(); +} + CuSuite *get_wormhole_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_sort_wormhole_regions); SUITE_ADD_TEST(suite, test_make_wormholes); + SUITE_ADD_TEST(suite, test_wormhole_transfer); return suite; }