diff --git a/scripts/tests/e2/init.lua b/scripts/tests/e2/init.lua index 28d7ebc9b..0f377a991 100644 --- a/scripts/tests/e2/init.lua +++ b/scripts/tests/e2/init.lua @@ -1,6 +1,6 @@ +require 'tests.e2.movement' require 'tests.e2.carts' require 'tests.e2.quit' -require 'tests.e2.movement' require 'tests.e2.astral' require 'tests.e2.spells' require 'tests.e2.e2features' diff --git a/scripts/tests/e2/movement.lua b/scripts/tests/e2/movement.lua index 2d8d6b7a7..aa42857f3 100644 --- a/scripts/tests/e2/movement.lua +++ b/scripts/tests/e2/movement.lua @@ -5,11 +5,40 @@ module("tests.e2.movement", package.seeall, lunit.testcase) function setup() eressea.free_game() eressea.settings.set("rules.food.flags", "4") + eressea.settings.set("rules.ship.damage.nocrewocean", "0") + eressea.settings.set("rules.ship.damage.nocrew", "0") + eressea.settings.set("rules.ship.drifting", "0") + eressea.settings.set("rules.ship.storms", "0") eressea.settings.set("nmr.timeout", "0") eressea.settings.set("NewbieImmunity", "0") end function test_piracy() + local r = region.create(0, 0, "plain") + local r2 = region.create(1, 0, "ocean") + local r3 = region.create(-1, 0, "ocean") + local f = faction.create("human", "pirate@eressea.de", "de") + local f2 = faction.create("human", "elf@eressea.de", "de") + local u1 = unit.create(f, r2, 1) + local u2 = unit.create(f2, r3, 1) + + u1.ship = ship.create(r2, "longboat") + u2.ship = ship.create(r3, "longboat") + u1:set_skill("sailing", 10) + u2:set_skill("sailing", 10) + + u1:clear_orders() + u1:add_order("PIRATERIE") + u2:clear_orders() + u2:add_order("NACH o") + + process_orders() + + assert_equal(r, u2.region) -- Nach Osten + assert_equal(r, u1.region) -- Entern! +end + +function test_piracy_to_land() local r = region.create(0, 0, "plain") local r2 = region.create(1, 0, "plain") local r3 = region.create(-1, 0, "ocean") @@ -30,10 +59,8 @@ function test_piracy() process_orders() - if r2~=u1.region then - write_reports() - end - assert_equal(r2, u1.region) -- should pass, but fails!!! + assert_equal(r, u2.region) -- Nach Osten + assert_equal(r2, u1.region) -- bewegt sich nicht end function test_dolphin_on_land() diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 56551e0f2..87194834b 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -407,22 +407,19 @@ int crew_skill(const ship *sh) { } bool ship_crewed(const ship *sh) { - unit *u; + unit *u, *cap = ship_owner(sh); int capskill = -1, sumskill = 0; for (u = sh->region->units; u; u = u->next) { if (u->ship == sh) { int es = effskill(u, SK_SAILING, NULL); - if (capskill < 0) { - if (u->number >= sh->number) { + if (es > 0) { + if (u == cap && u->number >= sh->number) { capskill = es; } - else { - capskill = 0; + if (es >= sh->type->minskill) { + sumskill += es * u->number; } } - if (es >= sh->type->minskill) { - sumskill += es * u->number; - } } } return (capskill >= ship_captain_minskill(sh)) && (sumskill >= sh->type->sumskill * sh->number); diff --git a/src/kernel/ship.test.c b/src/kernel/ship.test.c index 062e7cd20..174762182 100644 --- a/src/kernel/ship.test.c +++ b/src/kernel/ship.test.c @@ -30,6 +30,58 @@ static void test_register_ship(CuTest * tc) test_teardown(); } +static void test_ship_crewed(CuTest * tc) +{ + struct region *r; + struct faction *f; + struct ship *sh; + struct unit *u1, *u2; + struct ship_type *stype; + + test_setup(); + f = test_create_faction(NULL); + r = test_create_ocean(0, 0); + stype = test_create_shiptype("longboat"); + stype->cptskill = 2; + stype->sumskill = 4; + sh = test_create_ship(r, stype); + CuAssertTrue(tc, !ship_crewed(sh)); + u1 = test_create_unit(f, r); + set_level(u1, SK_SAILING, 4); + u_set_ship(u1, sh); + CuAssertTrue(tc, ship_crewed(sh)); + u2 = test_create_unit(f, r); + set_level(u1, SK_SAILING, 2); + set_level(u2, SK_SAILING, 2); + u_set_ship(u2, sh); + CuAssertTrue(tc, ship_crewed(sh)); + set_level(u1, SK_SAILING, 1); + set_level(u2, SK_SAILING, 2); + CuAssertTrue(tc, !ship_crewed(sh)); + set_level(u1, SK_SAILING, 2); + set_level(u2, SK_SAILING, 1); + CuAssertTrue(tc, !ship_crewed(sh)); + set_level(u1, SK_SAILING, 3); + set_level(u2, SK_SAILING, 1); + CuAssertTrue(tc, ship_crewed(sh)); + stype->minskill = 2; + CuAssertTrue(tc, !ship_crewed(sh)); + set_level(u1, SK_SAILING, 2); + set_level(u2, SK_SAILING, 2); + CuAssertTrue(tc, ship_crewed(sh)); + sh->number = 2; + CuAssertTrue(tc, !ship_crewed(sh)); + set_level(u1, SK_SAILING, 4); + set_level(u2, SK_SAILING, 4); + CuAssertTrue(tc, !ship_crewed(sh)); + u1->number = 2; + set_level(u1, SK_SAILING, 2); + set_level(u2, SK_SAILING, 4); + CuAssertTrue(tc, ship_crewed(sh)); + + test_teardown(); +} + static void test_ship_set_owner(CuTest * tc) { struct region *r; @@ -665,6 +717,7 @@ CuSuite *get_ship_suite(void) SUITE_ADD_TEST(suite, test_register_ship); SUITE_ADD_TEST(suite, test_stype_defaults); SUITE_ADD_TEST(suite, test_ship_set_owner); + SUITE_ADD_TEST(suite, test_ship_crewed); SUITE_ADD_TEST(suite, test_shipowner_resets_when_empty); SUITE_ADD_TEST(suite, test_shipowner_goes_to_next_when_empty); SUITE_ADD_TEST(suite, test_shipowner_goes_to_other_when_empty); diff --git a/src/move.c b/src/move.c index 18cb5098d..0fc6f6411 100644 --- a/src/move.c +++ b/src/move.c @@ -696,18 +696,17 @@ int check_ship_allowed(struct ship *sh, const region * r) return SA_NO_COAST; } -static void set_coast(ship * sh, region * r, region * rnext) +static enum direction_t set_coast(ship * sh, region * r, region * rnext) { if (sh->type->flags & SFL_NOCOAST) { - sh->coast = NODIRECTION; + return sh->coast = NODIRECTION; } else if (!fval(rnext->terrain, SEA_REGION) && !flying_ship(sh)) { - sh->coast = reldirection(rnext, r); - assert(fval(r->terrain, SEA_REGION)); - } - else { - sh->coast = NODIRECTION; + if (fval(r->terrain, SEA_REGION)) { + return sh->coast = reldirection(rnext, r); + } } + return sh->coast = NODIRECTION; } static double overload_start(void) { @@ -1923,7 +1922,6 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting) replace_order(&u->orders, ord, norder); free_order(norder); } - set_order(&u->thisorder, NULL); set_coast(sh, last_point, current_point); if (is_cursed(sh->attribs, &ct_flyingship)) {