From 7e2364c296004cb644bd8e21a12094320d63467a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 12 Oct 2015 19:40:20 +0200 Subject: [PATCH] test for actual piracy ship movement refactor storm check, run less code when disabled fix ship creation in tests --- src/move.c | 93 +++++++++++++++++++++++------------------------ src/piracy.c | 3 +- src/piracy.test.c | 28 +++++++++++--- src/tests.c | 3 +- 4 files changed, 73 insertions(+), 54 deletions(-) diff --git a/src/move.c b/src/move.c index c71f45c4f..8eaf052ca 100644 --- a/src/move.c +++ b/src/move.c @@ -1847,66 +1847,65 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep) } if (!flying_ship(sh)) { - int stormchance; - int stormyness = 0; + int stormchance = 0; int reason; bool storms_enabled = get_param_int(global.parameters, "rules.ship.storms", 1) != 0; if (storms_enabled) { + int stormyness; gamedate date; get_gamedate(turn, &date); stormyness = storms ? storms[date.month] * 5 : 0; - } - /* storms should be the first thing we do. */ - stormchance = stormyness / shipspeed(sh, u); - if (check_leuchtturm(next_point, NULL)) { - int param = get_param_int(global.parameters, "rules.lighthous.stormchancedevisor", 0); - if (param > 0) { - stormchance /= param; + /* storms should be the first thing we do. */ + stormchance = stormyness / shipspeed(sh, u); + if (check_leuchtturm(next_point, NULL)) { + int param = get_param_int(global.parameters, "rules.lighthous.stormchancedevisor", 0); + if (param > 0) { + stormchance /= param; + } + else { + stormchance = 0; + } } - else { - stormchance = 0; - } - } - if (rng_int() % 10000 < stormchance * sh->type->storm - && fval(current_point->terrain, SEA_REGION)) { - if (!is_cursed(sh->attribs, C_SHIP_NODRIFT, 0)) { - region *rnext = NULL; - bool storm = true; - int d_offset = rng_int() % MAXDIRECTIONS; - direction_t d; - /* Sturm nur, wenn nächste Region Hochsee ist. */ - for (d = 0; d != MAXDIRECTIONS; ++d) { - direction_t dnext = (direction_t)((d + d_offset) % MAXDIRECTIONS); - region *rn = rconnect(current_point, dnext); + if (rng_int() % 10000 < stormchance * sh->type->storm + && fval(current_point->terrain, SEA_REGION)) { + if (!is_cursed(sh->attribs, C_SHIP_NODRIFT, 0)) { + region *rnext = NULL; + bool storm = true; + int d_offset = rng_int() % MAXDIRECTIONS; + direction_t d; + /* Sturm nur, wenn nächste Region Hochsee ist. */ + for (d = 0; d != MAXDIRECTIONS; ++d) { + direction_t dnext = (direction_t)((d + d_offset) % MAXDIRECTIONS); + region *rn = rconnect(current_point, dnext); - if (rn != NULL) { - if (fval(rn->terrain, FORBIDDEN_REGION)) - continue; - if (!fval(rn->terrain, SEA_REGION)) { - storm = false; - break; + if (rn != NULL) { + if (fval(rn->terrain, FORBIDDEN_REGION)) + continue; + if (!fval(rn->terrain, SEA_REGION)) { + storm = false; + break; + } + if (rn != next_point) + rnext = rn; } - if (rn != next_point) - rnext = rn; + } + if (storm && rnext != NULL) { + ADDMSG(&f->msgs, msg_message("storm", "ship region sink", + sh, current_point, sh->damage >= sh->size * DAMAGE_SCALE)); + + /* damage the ship. we handle destruction in the end */ + damage_ship(sh, damage_drift()); + if (sh->damage >= sh->size * DAMAGE_SCALE) + break; + + next_point = rnext; + /* these values need to be updated if next_point changes (due to storms): */ + tnext = next_point->terrain; } } - if (storm && rnext != NULL) { - ADDMSG(&f->msgs, msg_message("storm", "ship region sink", - sh, current_point, sh->damage >= sh->size * DAMAGE_SCALE)); - - /* damage the ship. we handle destruction in the end */ - damage_ship(sh, damage_drift()); - if (sh->damage >= sh->size * DAMAGE_SCALE) - break; - - next_point = rnext; - /* these values need to be updated if next_point changes (due to storms): */ - tnext = next_point->terrain; - } } - } - + } // storms_enabled if (!fval(tthis, SEA_REGION)) { if (!fval(tnext, SEA_REGION)) { if (!move_on_land) { diff --git a/src/piracy.c b/src/piracy.c index 69b8b26b0..ab68e4dae 100644 --- a/src/piracy.c +++ b/src/piracy.c @@ -115,7 +115,7 @@ void piracy_cmd(unit * u, order *ord) { region *r = u->region; ship *sh = u->ship, *sh2; - direction_t dir, target_dir; + direction_t target_dir; struct { const faction *target; int value; @@ -136,6 +136,7 @@ void piracy_cmd(unit * u, order *ord) /* Wenn nicht, sehen wir, ob wir ein Ziel finden. */ if (target_dir == NODIRECTION) { + direction_t dir; /* Einheit ist also Kapitän. Jetzt gucken, in wievielen * Nachbarregionen potentielle Opfer sind. */ diff --git a/src/piracy.test.c b/src/piracy.test.c index 250fc8b10..c521b1be6 100644 --- a/src/piracy.test.c +++ b/src/piracy.test.c @@ -1,6 +1,8 @@ #include #include "piracy.h" +#include +#include #include #include #include @@ -17,34 +19,48 @@ static void setup_piracy(void) { struct locale *lang; terrain_type *t_ocean; + ship_type *st_boat; test_cleanup(); + set_param(&global.parameters, "rules.ship.storms", "0"); lang = get_or_create_locale("de"); locale_setstring(lang, directions[D_EAST], "OSTEN"); init_directions(lang); t_ocean = test_create_terrain("ocean", SAIL_INTO | SEA_REGION); + st_boat = test_create_shiptype("boat"); + st_boat->cargo = 1000; } static void test_piracy_cmd(CuTest * tc) { faction *f; + region *r; unit *u, *u2; order *ord; terrain_type *t_ocean; + ship_type *st_boat; setup_piracy(); t_ocean = get_or_create_terrain("ocean"); + st_boat = st_get_or_create("boat"); u2 = test_create_unit(test_create_faction(0), test_create_region(1, 0, t_ocean)); - u_set_ship(u2, test_create_ship(u2->region, 0)); + u_set_ship(u2, test_create_ship(u2->region, st_boat)); assert(u2); - u = test_create_unit(f = test_create_faction(0), test_create_region(0, 0, t_ocean)); - u_set_ship(u, test_create_ship(u->region, 0)); + u = test_create_unit(f = test_create_faction(0), r = test_create_region(0, 0, t_ocean)); + set_level(u, SK_SAILING, st_boat->sumskill); + u_set_ship(u, test_create_ship(u->region, st_boat)); assert(f && u); f->locale = get_or_create_locale("de"); ord = create_order(K_PIRACY, f->locale, "%s", itoa36(u2->faction->no)); assert(ord); piracy_cmd(u, ord); - CuAssertPtrNotNullMsg(tc, "successful PIRACY", test_find_messagetype(f->msgs, "piratesawvictim")); + CuAssertPtrEquals(tc, 0, u->thisorder); + CuAssertTrue(tc, u->region != r); + CuAssertPtrEquals(tc, u2->region, u->region); + CuAssertPtrEquals(tc, u2->region, u->ship->region); + CuAssertPtrNotNullMsg(tc, "successful PIRACY sets attribute", r->attribs); // FIXME: this is testing implementation, not interface + CuAssertPtrNotNullMsg(tc, "successful PIRACY message", test_find_messagetype(f->msgs, "piratesawvictim")); + CuAssertPtrNotNullMsg(tc, "successful PIRACY movement", test_find_messagetype(f->msgs, "shipsail")); test_cleanup(); } @@ -53,8 +69,10 @@ static void test_piracy_cmd_errors(CuTest * tc) { faction *f; unit *u, *u2; order *ord; + ship_type *st_boat; setup_piracy(); + st_boat = st_get_or_create("boat"); u = test_create_unit(f = test_create_faction(0), test_create_region(0, 0, get_or_create_terrain("ocean"))); f->locale = get_or_create_locale("de"); ord = create_order(K_PIRACY, f->locale, ""); @@ -63,7 +81,7 @@ static void test_piracy_cmd_errors(CuTest * tc) { piracy_cmd(u, ord); CuAssertPtrNotNullMsg(tc, "must be on a ship for PIRACY", test_find_messagetype(f->msgs, "error144")); - u_set_ship(u, test_create_ship(u->region, 0)); + u_set_ship(u, test_create_ship(u->region, st_boat)); u2 = test_create_unit(u->faction, u->region); u_set_ship(u2, u->ship); diff --git a/src/tests.c b/src/tests.c index b8c5f06c1..dce6604ce 100644 --- a/src/tests.c +++ b/src/tests.c @@ -123,7 +123,7 @@ building * test_create_building(region * r, const building_type * btype) ship * test_create_ship(region * r, const ship_type * stype) { - ship * s = new_ship(stype ? stype : st_get_or_create("boat"), r, default_locale); + ship * s = new_ship(stype ? stype : test_create_shiptype("boat"), r, default_locale); s->size = s->type->construction ? s->type->construction->maxsize : 1; return s; } @@ -134,6 +134,7 @@ ship_type * test_create_shiptype(const char * name) stype->cptskill = 1; stype->sumskill = 1; stype->minskill = 1; + stype->range = 2; if (!stype->construction) { stype->construction = calloc(1, sizeof(construction)); stype->construction->maxsize = 5;