diff --git a/src/kernel/move.c b/src/kernel/move.c index b7c30a677..8b3572f6d 100644 --- a/src/kernel/move.c +++ b/src/kernel/move.c @@ -621,12 +621,7 @@ static bool is_freezing(const unit * u) return true; } -#define SA_HARBOUR 1 -#define SA_COAST 1 -#define SA_NO_INSECT -1 -#define SA_NO_COAST -2 - -static bool is_ship_allowed(struct ship *sh, const region * r) +int check_ship_allowed(struct ship *sh, const region * r) { int c = 0; static const building_type *bt_harbour = NULL; @@ -634,7 +629,7 @@ static bool is_ship_allowed(struct ship *sh, const region * r) if (bt_harbour == NULL) bt_harbour = bt_find("harbour"); - if (r_insectstalled(r)) { + if (sh->region && r_insectstalled(r)) { /* insekten dürfen nicht hier rein. haben wir welche? */ unit *u; @@ -654,7 +649,7 @@ static bool is_ship_allowed(struct ship *sh, const region * r) } } - if (buildingtype_exists(r, bt_harbour, true)) + if (bt_harbour && buildingtype_exists(r, bt_harbour, true)) return SA_HARBOUR; for (c = 0; sh->type->coasts[c] != NULL; ++c) { if (sh->type->coasts[c] == r->terrain) @@ -746,7 +741,7 @@ static void drifting_ships(region * r) region *rn; dir = (direction_t) ((d + d_offset) % MAXDIRECTIONS); rn = rconnect(r, dir); - if (rn != NULL && fval(rn->terrain, SAIL_INTO) && is_ship_allowed(sh, rn) > 0) { + if (rn != NULL && fval(rn->terrain, SAIL_INTO) && check_ship_allowed(sh, rn) > 0) { rnext = rn; if (!fval(rnext->terrain, SEA_REGION)) break; @@ -1809,7 +1804,7 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep) } } - reason = is_ship_allowed(sh, next_point); + reason = check_ship_allowed(sh, next_point); if (reason<0) { /* for some reason or another, we aren't allowed in there.. */ if (check_leuchtturm(current_point, NULL) || reason == SA_NO_INSECT) { diff --git a/src/kernel/move.h b/src/kernel/move.h index 80744ce9f..c76c362c1 100644 --- a/src/kernel/move.h +++ b/src/kernel/move.h @@ -66,7 +66,13 @@ extern "C" { const struct building_type *bt); extern struct attrib_type at_speedup; + +#define SA_HARBOUR 2 +#define SA_COAST 1 +#define SA_NO_INSECT -1 +#define SA_NO_COAST -2 + extern int check_ship_allowed(struct ship *sh, const struct region * r); #ifdef __cplusplus } #endif diff --git a/src/kernel/move_test.c b/src/kernel/move_test.c index 172012e4d..3183d9a59 100644 --- a/src/kernel/move_test.c +++ b/src/kernel/move_test.c @@ -4,12 +4,57 @@ #include #include #include +#include +#include #include #include #include +static void test_ship_not_allowed_in_coast(CuTest * tc) +{ + region *r; + ship * sh; + terrain_type * ttype; + ship_type * stype; + char * names[] = { "derp", "derp_p" }; + + test_cleanup(); + test_create_world(); + + ttype = test_create_terrain("glacier", LAND_REGION|ARCTIC_REGION|WALK_INTO|SAIL_INTO); + stype = test_create_shiptype(names); + stype->coasts = (const struct terrain_type **)calloc(2, sizeof(const struct terrain_type *)); + + r = test_create_region(0, 0, ttype); + sh = test_create_ship(0, stype); + + CuAssertIntEquals(tc, SA_NO_COAST, check_ship_allowed(sh, r)); + stype->coasts[0] = ttype; + CuAssertIntEquals(tc, SA_COAST, check_ship_allowed(sh, r)); +} + +static void test_ship_allowed_with_harbor(CuTest * tc) +{ + region *r; + ship * sh; + terrain_type * ttype; + building_type * btype; + + test_cleanup(); + test_create_world(); + + ttype = test_create_terrain("glacier", LAND_REGION|ARCTIC_REGION|WALK_INTO|SAIL_INTO); + btype = test_create_buildingtype("harbour"); + + r = test_create_region(0, 0, ttype); + sh = test_create_ship(0, 0); + + test_create_building(r, btype); + CuAssertIntEquals(tc, SA_HARBOUR, check_ship_allowed(sh, r)); +} + static void test_building_type_exists(CuTest * tc) { region *r; @@ -35,5 +80,7 @@ CuSuite *get_move_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_building_type_exists); + SUITE_ADD_TEST(suite, test_ship_not_allowed_in_coast); + SUITE_ADD_TEST(suite, test_ship_allowed_with_harbor); return suite; } diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 141bd4ba9..96745c59e 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -171,7 +171,6 @@ ship *new_ship(const ship_type * stype, region * r, const struct locale *lang) const char *sname = 0; assert(stype); - assert(r); sh->no = newcontainerid(); sh->coast = NODIRECTION; sh->type = stype; @@ -188,7 +187,9 @@ ship *new_ship(const ship_type * stype, region * r, const struct locale *lang) slprintf(buffer, sizeof(buffer), "%s %s", sname, shipid(sh)); sh->name = strdup(buffer); shash(sh); - addlist(&r->ships, sh); + if (r) { + addlist(&r->ships, sh); + } return sh; } diff --git a/src/tests.c b/src/tests.c index a0c5dcd94..dd05c7d93 100644 --- a/src/tests.c +++ b/src/tests.c @@ -138,6 +138,26 @@ ship * test_create_ship(region * r, const ship_type * stype) return s; } +ship_type * test_create_shiptype(const char ** names) +{ + ship_type * stype = (ship_type*)calloc(sizeof(ship_type), 1); + stype->name[0] = strdup(names[0]); + stype->name[1] = strdup(names[1]); + locale_setstring(default_locale, names[0], names[0]); + st_register(stype); + return stype; +} + +building_type * test_create_buildingtype(const char * name) +{ + building_type * btype = (building_type*)calloc(sizeof(building_type), 1); + btype->flags = BTF_NAMECHANGE; + btype->_name = strdup(name); + locale_setstring(default_locale, name, name); + bt_register(btype); + return btype; +} + item_type * test_create_itemtype(const char ** names) { resource_type * rtype; item_type * itype; @@ -160,16 +180,14 @@ void test_create_world(void) terrain_type *t_plain, *t_ocean; region *island[2]; int i; - building_type *btype; - ship_type *stype; item_type * itype; - const char * horses[2] = { "horse", "horse_p" }; + const char * names[] = { "horse", "horse_p", "boat", "boat_p" }; make_locale("de"); init_resources(); assert(!olditemtype[I_HORSE]); - itype = test_create_itemtype(horses); + itype = test_create_itemtype(names); olditemtype[I_HORSE] = itype; t_plain = test_create_terrain("plain", LAND_REGION | FOREST_REGION | WALK_INTO | CAVALRY_REGION); @@ -192,17 +210,8 @@ void test_create_world(void) test_create_race("human"); - btype = (building_type*)calloc(sizeof(building_type), 1); - btype->flags = BTF_NAMECHANGE; - btype->_name = strdup("castle"); - locale_setstring(default_locale, "castle", "castle"); - bt_register(btype); - - stype = (ship_type*)calloc(sizeof(ship_type), 1); - stype->name[0] = strdup("boat"); - stype->name[1] = strdup("boat_p"); - locale_setstring(default_locale, "boat", "boat"); - st_register(stype); + test_create_buildingtype("castle"); + test_create_shiptype(names+2); } int main(int argc, char ** argv) { diff --git a/src/tests.h b/src/tests.h index 2ea13633e..15aa7a230 100644 --- a/src/tests.h +++ b/src/tests.h @@ -39,6 +39,9 @@ extern "C" { struct building * test_create_building(struct region * r, const struct building_type * btype); struct ship * test_create_ship(struct region * r, const struct ship_type * stype); struct item_type * test_create_itemtype(const char ** names); + struct ship_type *test_create_shiptype(const char **names); + struct building_type *test_create_buildingtype(const char *name); + int RunAllTests(void); #ifdef __cplusplus