diff --git a/res/core/ships.xml b/res/core/ships.xml index 6c6821be4..0ce254328 100644 --- a/res/core/ships.xml +++ b/res/core/ships.xml @@ -1,7 +1,6 @@ - @@ -9,7 +8,6 @@ - @@ -17,7 +15,6 @@ - @@ -25,7 +22,6 @@ - @@ -33,7 +29,6 @@ - @@ -48,7 +43,6 @@ - @@ -65,7 +59,6 @@ - diff --git a/res/e3a/ships.xml b/res/e3a/ships.xml index 1174eda8e..b8c5f0197 100644 --- a/res/e3a/ships.xml +++ b/res/e3a/ships.xml @@ -1,7 +1,6 @@ - @@ -17,7 +16,6 @@ - @@ -28,7 +26,6 @@ - @@ -44,7 +41,6 @@ - @@ -61,7 +57,6 @@ - @@ -78,7 +73,6 @@ - @@ -89,7 +83,6 @@ - @@ -98,7 +91,6 @@ - @@ -109,7 +101,6 @@ - @@ -120,7 +111,6 @@ - @@ -133,7 +123,6 @@ - @@ -145,7 +134,6 @@ - diff --git a/res/ships/boat.xml b/res/ships/boat.xml index 28d48392f..91852de92 100644 --- a/res/ships/boat.xml +++ b/res/ships/boat.xml @@ -1,6 +1,5 @@ - diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c index 63c5fe0ff..858c811b9 100644 --- a/src/kernel/jsonconf.test.c +++ b/src/kernel/jsonconf.test.c @@ -458,7 +458,7 @@ static void test_terrains(CuTest * tc) "\"size\": 4000, " "\"road\": 50, " "\"seed\": 3, " - "\"flags\" : [ \"forbidden\", \"arctic\", \"cavalry\", \"sea\", \"forest\", \"land\", \"sail\", \"fly\", \"swim\", \"walk\" ] } }}"; + "\"flags\" : [ \"forbidden\", \"arctic\", \"cavalry\", \"sea\", \"forest\", \"land\", \"fly\", \"swim\", \"walk\" ] } }}"; const terrain_type *ter; cJSON *json = cJSON_Parse(data); @@ -470,7 +470,7 @@ static void test_terrains(CuTest * tc) json_config(json); ter = get_terrain("plain"); CuAssertPtrNotNull(tc, ter); - CuAssertIntEquals(tc, ARCTIC_REGION | LAND_REGION | SEA_REGION | FOREST_REGION | CAVALRY_REGION | FORBIDDEN_REGION | FLY_INTO | WALK_INTO | SWIM_INTO | SAIL_INTO, ter->flags); + CuAssertIntEquals(tc, ARCTIC_REGION | LAND_REGION | SEA_REGION | FOREST_REGION | CAVALRY_REGION | FORBIDDEN_REGION | FLY_INTO | WALK_INTO | SWIM_INTO , ter->flags); CuAssertIntEquals(tc, 4000, ter->size); CuAssertIntEquals(tc, 50, ter->max_road); CuAssertIntEquals(tc, 3, ter->distribution); diff --git a/src/kernel/terrain.h b/src/kernel/terrain.h index 931a74861..3d1491867 100644 --- a/src/kernel/terrain.h +++ b/src/kernel/terrain.h @@ -31,7 +31,6 @@ extern "C" { #define CAVALRY_REGION (1<<4) /* riding in combat is possible */ /* Achtung: SEA_REGION ist nicht das Gegenteil von LAND_REGION. Die zwei schliessen sich nichtmal aus! */ #define FORBIDDEN_REGION (1<<5) /* unpassierbare Blockade-struct region */ -#define SAIL_INTO (1<<6) /* man darf hierhin segeln */ #define FLY_INTO (1<<7) /* man darf hierhin fliegen */ #define SWIM_INTO (1<<8) /* man darf hierhin schwimmen */ #define WALK_INTO (1<<9) /* man darf hierhin laufen */ diff --git a/src/modules/score.c b/src/modules/score.c index 74eb0898b..2fd3cf230 100644 --- a/src/modules/score.c +++ b/src/modules/score.c @@ -167,7 +167,7 @@ void score(void) fprintf(scoreFP, "(%s) ", score); fprintf(scoreFP, "%30.30s (%3.3s) %5s (%3d)\n", f->name, - rc_name_s(f->race, NAME_SINGULAR), + f->race->_name, factionid(f), f->age); } diff --git a/src/monsters.test.c b/src/monsters.test.c index a7a4d9b18..1660800fe 100644 --- a/src/monsters.test.c +++ b/src/monsters.test.c @@ -55,7 +55,7 @@ static void create_monsters(faction **player, faction **monsters, unit **u, unit fset(*monsters, FFL_NOIDLEOUT); assert(fval(*monsters, FFL_NPC) && fval((*monsters)->race, RCF_UNARMEDGUARD) && fval((*monsters)->race, RCF_NPC) && fval(*monsters, FFL_NOIDLEOUT)); - test_create_region(-1, 0, test_create_terrain("ocean", SEA_REGION | SAIL_INTO | SWIM_INTO | FLY_INTO)); + test_create_region(-1, 0, test_create_terrain("ocean", SEA_REGION | SWIM_INTO | FLY_INTO)); test_create_region(1, 0, 0); r = test_create_region(0, 0, 0); diff --git a/src/move.c b/src/move.c index e602b073c..e7ca523b5 100644 --- a/src/move.c +++ b/src/move.c @@ -677,12 +677,6 @@ int check_ship_allowed(struct ship *sh, const region * r) } if (is_freezing(u)) { - unit *captain = ship_owner(sh); - if (captain) { - ADDMSG(&captain->faction->msgs, - msg_message("detectforbidden", "unit region", u, r)); - } - return SA_NO_INSECT; } } @@ -783,9 +777,26 @@ static void msg_to_ship_inmates(ship *sh, unit **firstu, unit **lastu, message * msg_release(msg); } +region * drift_target(ship *sh) { + int d, d_offset = rng_int() % MAXDIRECTIONS; + region *rnext = NULL; + for (d = 0; d != MAXDIRECTIONS; ++d) { + region *rn; + direction_t dir = (direction_t)((d + d_offset) % MAXDIRECTIONS); + rn = rconnect(sh->region, dir); + if (rn != NULL && check_ship_allowed(sh, rn) >= 0) { + rnext = rn; + if (!fval(rnext->terrain, SEA_REGION)) { + // prefer drifting towards non-ocean regions + break; + } + } + } + return rnext; +} + static void drifting_ships(region * r) { - direction_t d; bool drift = config_get_int("rules.ship.drifting", 1) != 0; double damage_drift = config_get_flt("rules.ship.damage_drift", 0.02); @@ -796,7 +807,6 @@ static void drifting_ships(region * r) region *rnext = NULL; region_list *route = NULL; unit *firstu = r->units, *lastu = NULL, *captain; - int d_offset; direction_t dir = 0; double ovl; @@ -831,17 +841,7 @@ static void drifting_ships(region * r) } else { /* Auswahl einer Richtung: Zuerst auf Land, dann * zufällig. Falls unmögliches Resultat: vergiß es. */ - d_offset = rng_int () % MAXDIRECTIONS; - for (d = 0; d != MAXDIRECTIONS; ++d) { - region *rn; - dir = (direction_t)((d + d_offset) % MAXDIRECTIONS); - rn = rconnect(r, dir); - if (rn != NULL && fval(rn->terrain, SAIL_INTO) && check_ship_allowed(sh, rn) > 0) { - rnext = rn; - if (!fval(rnext->terrain, SEA_REGION)) - break; - } - } + rnext = drift_target(sh); } if (rnext != NULL) { @@ -1946,7 +1946,10 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep) 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) { + if (reason == SA_NO_INSECT) { + ADDMSG(&f->msgs, msg_message("detectforbidden", "unit region", u, sh->region)); + } + else if (check_leuchtturm(current_point, NULL)) { ADDMSG(&f->msgs, msg_message("sailnolandingstorm", "ship region", sh, next_point)); } else { diff --git a/src/move.h b/src/move.h index 0417dcec5..9c5893629 100644 --- a/src/move.h +++ b/src/move.h @@ -77,12 +77,13 @@ extern "C" { void move_cmd(struct unit * u, struct order * ord, bool move_on_land); int follow_ship(struct unit * u, struct order * ord); -#define SA_HARBOUR 2 -#define SA_COAST 1 +#define SA_HARBOUR 1 +#define SA_COAST 0 #define SA_NO_INSECT -1 #define SA_NO_COAST -2 int check_ship_allowed(struct ship *sh, const struct region * r); + struct region * drift_target(struct ship *sh); #ifdef __cplusplus } #endif diff --git a/src/move.test.c b/src/move.test.c index 4c0a07bc5..e974a7b69 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -35,8 +35,8 @@ static void test_ship_not_allowed_in_coast(CuTest * tc) ship_type *stype; test_cleanup(); - ttype = test_create_terrain("glacier", LAND_REGION | ARCTIC_REGION | WALK_INTO | SAIL_INTO); - otype = test_create_terrain("ocean", SEA_REGION | SAIL_INTO); + ttype = test_create_terrain("glacier", LAND_REGION | ARCTIC_REGION | WALK_INTO); + otype = test_create_terrain("ocean", SEA_REGION); stype = test_create_shiptype("derp"); free(stype->coasts); stype->coasts = (struct terrain_type **)calloc(2, sizeof(struct terrain_type *)); @@ -69,7 +69,7 @@ static void setup_harbor(move_fixture *mf) { test_cleanup(); - ttype = test_create_terrain("glacier", LAND_REGION | ARCTIC_REGION | WALK_INTO | SAIL_INTO); + ttype = test_create_terrain("glacier", LAND_REGION | ARCTIC_REGION | WALK_INTO); btype = test_create_buildingtype("harbour"); sh = test_create_ship(0, 0); @@ -232,7 +232,7 @@ static void test_ship_trails(CuTest *tc) { region_list *route = 0; test_cleanup(); - otype = test_create_terrain("ocean", SEA_REGION | SAIL_INTO); + otype = test_create_terrain("ocean", SEA_REGION); r1 = test_create_region(0, 0, otype); r2 = test_create_region(1, 0, otype); r3 = test_create_region(2, 0, otype); @@ -298,7 +298,7 @@ void setup_drift (struct drift_fixture *fix) { fix->st_boat->cabins = 20000; fix->u = test_create_unit(fix->f = test_create_faction(0), fix->r=findregion(-1,0)); - assert(fix->r && fix->r->terrain->flags & SAIL_INTO); + assert(fix->r); set_level(fix->u, SK_SAILING, fix->st_boat->sumskill); u_set_ship(fix->u, fix->sh = test_create_ship(fix->u->region, fix->st_boat)); assert(fix->f && fix->u && fix->sh); @@ -498,6 +498,24 @@ static void test_follow_ship_msg(CuTest * tc) { test_cleanup(); } +static void test_drifting_ships(CuTest *tc) { + ship *sh; + region *r1, *r2, *r3; + terrain_type *t_ocean, *t_plain; + ship_type *st_boat; + test_cleanup(); + t_ocean = test_create_terrain("ocean", SEA_REGION); + t_plain = test_create_terrain("plain", LAND_REGION); + r1 = test_create_region(0, 0, t_ocean); + r2 = test_create_region(1, 0, t_ocean); + st_boat = test_create_shiptype("boat"); + sh = test_create_ship(r1, st_boat); + CuAssertPtrEquals(tc, r2, drift_target(sh)); + r3 = test_create_region(-1, 0, t_plain); + CuAssertPtrEquals(tc, r3, drift_target(sh)); + test_cleanup(); +} + CuSuite *get_move_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -521,5 +539,6 @@ CuSuite *get_move_suite(void) SUITE_ADD_TEST(suite, test_ship_ridiculous_overload_no_captain); SUITE_ADD_TEST(suite, test_ship_damage_overload); SUITE_ADD_TEST(suite, test_follow_ship_msg); + SUITE_ADD_TEST(suite, test_drifting_ships); return suite; } diff --git a/src/piracy.c b/src/piracy.c index e8864faa9..05a744cb9 100644 --- a/src/piracy.c +++ b/src/piracy.c @@ -151,7 +151,7 @@ void piracy_cmd(unit * u, order *ord) // TODO this could still result in an illegal movement order (through a wall or whatever) // which will be prevented by move_cmd below if (rc && - ((sh && fval(rc->terrain, SAIL_INTO) && can_takeoff(sh, r, rc)) + ((sh && !fval(rc->terrain, FORBIDDEN_REGION) && can_takeoff(sh, r, rc)) || (canswim(u) && fval(rc->terrain, SWIM_INTO) && fval(rc->terrain, SEA_REGION)))) { for (sh2 = rc->ships; sh2; sh2 = sh2->next) { diff --git a/src/piracy.test.c b/src/piracy.test.c index 419f73073..005ce5857 100644 --- a/src/piracy.test.c +++ b/src/piracy.test.c @@ -26,7 +26,7 @@ static void setup_piracy(void) { lang = get_or_create_locale("de"); locale_setstring(lang, directions[D_EAST], "OSTEN"); init_directions(lang); - test_create_terrain("ocean", SAIL_INTO | SEA_REGION); + test_create_terrain("ocean", SEA_REGION); st_boat = test_create_shiptype("boat"); st_boat->cargo = 1000; } @@ -184,7 +184,7 @@ static void test_piracy_cmd_land_to_land(CuTest * tc) { test_cleanup(); - setup_pirate(&pirate, 0, 0, "boat", &ord, &victim, SAIL_INTO, "boat"); + setup_pirate(&pirate, 0, 0, "boat", &ord, &victim, SEA_REGION, "boat"); set_level(pirate, SK_SAILING, pirate->ship->type->sumskill); r = pirate->region; diff --git a/src/tests.c b/src/tests.c index a0d54a4cc..4e6d98a74 100644 --- a/src/tests.c +++ b/src/tests.c @@ -54,7 +54,7 @@ struct region *test_create_region(int x, int y, const terrain_type *terrain) if (!terrain) { terrain_type *t = get_or_create_terrain("plain"); t->size = 1000; - fset(t, LAND_REGION|CAVALRY_REGION|FOREST_REGION|FLY_INTO|WALK_INTO|SAIL_INTO); + fset(t, LAND_REGION|CAVALRY_REGION|FOREST_REGION|FLY_INTO|WALK_INTO); terraform_region(r, t); } else { @@ -196,9 +196,10 @@ ship_type * test_create_shiptype(const char * name) free(stype->coasts); } stype->coasts = - (terrain_type **)malloc(sizeof(terrain_type *) * 2); - stype->coasts[0] = test_create_terrain("plain", LAND_REGION | FOREST_REGION | WALK_INTO | CAVALRY_REGION | SAIL_INTO | FLY_INTO); - stype->coasts[1] = NULL; + (terrain_type **)malloc(sizeof(terrain_type *) * 3); + stype->coasts[0] = test_create_terrain("plain", LAND_REGION | FOREST_REGION | WALK_INTO | CAVALRY_REGION | FLY_INTO); + stype->coasts[1] = test_create_terrain("ocean", SEA_REGION | SWIM_INTO | FLY_INTO); + stype->coasts[2] = NULL; if (default_locale) { locale_setstring(default_locale, name, name); } @@ -322,10 +323,10 @@ void test_create_world(void) test_create_itemtype("iron"); test_create_itemtype("stone"); - t_plain = test_create_terrain("plain", LAND_REGION | FOREST_REGION | WALK_INTO | CAVALRY_REGION | SAIL_INTO | FLY_INTO); + t_plain = test_create_terrain("plain", LAND_REGION | FOREST_REGION | WALK_INTO | CAVALRY_REGION | FLY_INTO); t_plain->size = 1000; t_plain->max_road = 100; - t_ocean = test_create_terrain("ocean", SEA_REGION | SAIL_INTO | SWIM_INTO | FLY_INTO); + t_ocean = test_create_terrain("ocean", SEA_REGION | SWIM_INTO | FLY_INTO); t_ocean->size = 0; island[0] = test_create_region(0, 0, t_plain);