diff --git a/scripts/tests/e2/ships.lua b/scripts/tests/e2/ships.lua index 3208f0a0d..27e4d9b26 100644 --- a/scripts/tests/e2/ships.lua +++ b/scripts/tests/e2/ships.lua @@ -75,3 +75,92 @@ function test_speedy_ship_fast() process_orders() assert_equal(8, u1.region.x) end + +function test_ship_convoy_capacity() + local r1 = region.create(1, 0, 'ocean') + local r2 = region.create(2, 0, 'ocean') + local f = faction.create("human") + local u = unit.create(f, r1, 1) + + u:add_order('NACH O') + u:set_skill('sailing', 2, true) + u:add_item('jewel', 40) + u.ship = ship.create(r1, 'boat') + assert_equal(1, u.ship.number) + process_orders() + u:clear_orders() + assert_equal(r2, u.region) + + u:add_order('NACH W') + u:add_item('jewel', 1) + u:set_skill('sailing', 2, true) + process_orders() + u:clear_orders() + assert_equal(r2, u.region) -- too heavy + + u:add_order('NACH W') + u:add_item('jewel', 39) + u.name = 'Xolgrim' + u.ship.number = 2 + u.number = 2 + u:set_skill('sailing', 2, true) + process_orders() + u:clear_orders() + assert_equal(r1, u.region) -- double capacity + + u:add_order('NACH O') + u.ship.number = 2 + u.name = 'Bolgrim' + u:add_item('jewel', 1) -- too heavy again + u:set_skill('sailing', 2, true) + process_orders() + u:clear_orders() + assert_equal(r1, u.region) +end + +function test_ship_convoy_crew() + local r1 = region.create(1, 0, 'ocean') + local r2 = region.create(2, 0, 'ocean') + local f = faction.create("human") + local u = unit.create(f, r1, 1) + u.ship = ship.create(r1, 'boat') + u.ship.number = 2 + + u:set_skill('sailing', 4, true) + u:add_order('NACH O') + process_orders() + u:clear_orders() + assert_equal(r1, u.region) -- not enough captains + + u.number = 2 + u:set_skill('sailing', 2, true) + u:add_order('NACH O') + process_orders() + u:clear_orders() + assert_equal(r2, u.region) +end + +function test_ship_convoy_skill() + local r1 = region.create(1, 0, 'ocean') + local r2 = region.create(2, 0, 'ocean') + local r3 = region.create(3, 0, 'ocean') + local f = faction.create("human") + local u = unit.create(f, r1, 1) + + u:set_skill('sailing', 2, true) + u.ship = ship.create(r1, 'boat') + assert_equal(1, u.ship.number) + u:add_order('NACH O') + process_orders() + assert_equal(r2, u.region) + + u.ship.number = 2 + u:set_skill('sailing', 2, true) + process_orders() + assert_equal(r2, u.region) + + u.number = 2 + u:set_skill('sailing', 2, true) + process_orders() + assert_equal(r3, u.region) +end diff --git a/src/bind_ship.c b/src/bind_ship.c index d335d996d..6711b0370 100644 --- a/src/bind_ship.c +++ b/src/bind_ship.c @@ -38,39 +38,55 @@ int tolua_shiplist_next(lua_State * L) return 0; /* no more values to return */ } +static int tolua_ship_get_number(lua_State * L) +{ + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + lua_pushinteger(L, sh->number); + return 1; +} + +static int tolua_ship_set_number(lua_State * L) +{ + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + int n = (int)tolua_tonumber(L, 2, 0); + sh->number = n; + sh->size += sh->type->construction->maxsize; + return 0; +} + static int tolua_ship_get_id(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - lua_pushinteger(L, self->no); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + lua_pushinteger(L, sh->no); return 1; } static int tolua_ship_get_name(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - tolua_pushstring(L, ship_getname(self)); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + tolua_pushstring(L, ship_getname(sh)); return 1; } static int tolua_ship_get_size(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - lua_pushinteger(L, self->size); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + lua_pushinteger(L, sh->size); return 1; } static int tolua_ship_get_display(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - tolua_pushstring(L, self->display); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + tolua_pushstring(L, sh->display); return 1; } static int tolua_ship_get_region(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - if (self) { - tolua_pushusertype(L, self->region, TOLUA_CAST "region"); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + if (sh) { + tolua_pushusertype(L, sh->region, TOLUA_CAST "region"); return 1; } return 0; @@ -78,43 +94,43 @@ static int tolua_ship_get_region(lua_State * L) static int tolua_ship_set_region(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); region *r = (region *)tolua_tousertype(L, 2, NULL); - if (self) { - move_ship(self, self->region, r, NULL); + if (sh) { + move_ship(sh, sh->region, r, NULL); } return 0; } static int tolua_ship_set_name(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - ship_setname(self, tolua_tostring(L, 2, NULL)); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + ship_setname(sh, tolua_tostring(L, 2, NULL)); return 0; } static int tolua_ship_set_size(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - self->size = lua_tointeger(L, 2); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + sh->size = lua_tointeger(L, 2); return 0; } static int tolua_ship_set_display(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - free(self->display); - self->display = str_strdup(tolua_tostring(L, 2, NULL)); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + free(sh->display); + sh->display = str_strdup(tolua_tostring(L, 2, NULL)); return 0; } static int tolua_ship_get_units(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); unit **unit_ptr = (unit **)lua_newuserdata(L, sizeof(unit *)); - unit *u = self->region->units; + unit *u = sh->region->units; - while (u && u->ship != self) + while (u && u->ship != sh) u = u->next; luaL_getmetatable(L, TOLUA_CAST "unit"); lua_setmetatable(L, -2); @@ -147,42 +163,42 @@ static int tolua_ship_create(lua_State * L) static int tolua_ship_tostring(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - lua_pushstring(L, shipname(self)); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + lua_pushstring(L, shipname(sh)); return 1; } static int tolua_ship_get_flags(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - lua_pushinteger(L, self->flags); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + lua_pushinteger(L, sh->flags); return 1; } static int tolua_ship_set_flags(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - self->flags = (int)lua_tointeger(L, 2); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + sh->flags = (int)lua_tointeger(L, 2); return 0; } static int tolua_ship_set_coast(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); if (lua_isnil(L, 2)) { - self->coast = NODIRECTION; + sh->coast = NODIRECTION; } else if (lua_isnumber(L, 2)) { - self->coast = (direction_t)lua_tointeger(L, 2); + sh->coast = (direction_t)lua_tointeger(L, 2); } return 0; } static int tolua_ship_get_coast(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - if (self->coast) { - lua_pushinteger(L, self->coast); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + if (sh->coast) { + lua_pushinteger(L, sh->coast); return 1; } return 0; @@ -190,30 +206,30 @@ static int tolua_ship_get_coast(lua_State * L) static int tolua_ship_get_type(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - tolua_pushstring(L, self->type->_name); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + tolua_pushstring(L, sh->type->_name); return 1; } static int tolua_ship_get_damage(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - lua_pushinteger(L, self->damage); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + lua_pushinteger(L, sh->damage); return 1; } static int tolua_ship_set_damage(lua_State * L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); - self->damage = (int)lua_tointeger(L, 2); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); + sh->damage = (int)lua_tointeger(L, 2); return 0; } static int tolua_ship_get_curse(lua_State *L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); const char *name = tolua_tostring(L, 2, NULL); - if (self->attribs) { - curse * c = get_curse(self->attribs, ct_find(name)); + if (sh->attribs) { + curse * c = get_curse(sh->attribs, ct_find(name)); if (c) { lua_pushnumber(L, curse_geteffect(c)); return 1; @@ -223,9 +239,9 @@ static int tolua_ship_get_curse(lua_State *L) { } static int tolua_ship_has_attrib(lua_State *L) { - ship *self = (ship *)tolua_tousertype(L, 1, NULL); + ship *sh = (ship *)tolua_tousertype(L, 1, NULL); const char *name = tolua_tostring(L, 2, NULL); - attrib * a = a_find(self->attribs, at_find(name)); + attrib * a = a_find(sh->attribs, at_find(name)); lua_pushboolean(L, a != NULL); return 1; } @@ -243,6 +259,7 @@ void tolua_ship_open(lua_State * L) { tolua_function(L, TOLUA_CAST "__tostring", tolua_ship_tostring); tolua_variable(L, TOLUA_CAST "id", tolua_ship_get_id, NULL); + tolua_variable(L, TOLUA_CAST "number", tolua_ship_get_number, tolua_ship_set_number); tolua_variable(L, TOLUA_CAST "name", tolua_ship_get_name, tolua_ship_set_name); tolua_variable(L, TOLUA_CAST "size", tolua_ship_get_size, diff --git a/src/bind_unit.c b/src/bind_unit.c index 45b4d7d0a..28e24e85b 100644 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -884,9 +884,19 @@ static int tolua_unit_create(lua_State * L) const char *rcname = tolua_tostring(L, 4, NULL); const race *rc; - assert(f && r); + if (!r) { + log_warning("unit.create: arg(2) is not a region"); + return 0; + } + if (!f) { + log_warning("unit.create: arg(1) is not a faction"); + return 0; + } rc = rcname ? rc_find(rcname) : f->race; - assert(rc); + if (!rc) { + log_warning("unit.create: unknown race %s", rcname); + return 0; + } u = create_unit(r, f, num, rc, 0, NULL, NULL); tolua_pushusertype(L, u, TOLUA_CAST "unit"); return 1; diff --git a/src/creport.c b/src/creport.c index 72bca8c70..4a5188108 100644 --- a/src/creport.c +++ b/src/creport.c @@ -515,7 +515,9 @@ static void report_crtypes(FILE * F, const struct locale *lang) fputc('\"', F); fputs(crescape(nrt_string(kmt->mtype, lang), buffer, sizeof(buffer)), F); fputs("\";text\n", F); - fprintf(F, "\"%s\";section\n", kmt->mtype->section); + if (kmt->mtype->section) { + fprintf(F, "\"%s\";section\n", kmt->mtype->section); + } } while (mtypehash[i]) { kmt = mtypehash[i]; @@ -695,6 +697,7 @@ static void cr_output_ship(struct stream *out, const ship *sh, const unit *u, stream_printf(out, "\"%s\";Beschr\n", sh->display); stream_printf(out, "\"%s\";Typ\n", translate(sh->type->_name, LOC(f->locale, sh->type->_name))); + stream_printf(out, "%d;Anzahl\n", sh->number); stream_printf(out, "%d;Groesse\n", sh->size); if (sh->damage) { int percent = @@ -710,7 +713,7 @@ static void cr_output_ship(struct stream *out, const ship *sh, const unit *u, /* calculate cargo */ if (u && (u->faction == f || omniscient(f))) { int n = 0, p = 0; - int mweight = shipcapacity(sh); + int mweight = ship_capacity(sh); getshipweight(sh, &n, &p); stream_printf(out, "%d;capacity\n", mweight); diff --git a/src/kernel/save.c b/src/kernel/save.c index 2774f3401..a65dda7e1 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1283,6 +1283,7 @@ void write_ship(gamedata *data, const ship *sh) WRITE_STR(store, (const char *)sh->name); WRITE_STR(store, sh->display ? (const char *)sh->display : ""); WRITE_TOK(store, sh->type->_name); + assert(sh->number > 0); WRITE_INT(store, sh->number); WRITE_INT(store, sh->size); WRITE_INT(store, sh->damage); diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 6d458843e..67b98d37c 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -181,6 +181,7 @@ ship *new_ship(const ship_type * stype, region * r, const struct locale *lang) sh->coast = NODIRECTION; sh->type = stype; sh->region = r; + sh->number = 1; if (lang) { sname = LOC(lang, stype->_name); @@ -275,13 +276,13 @@ static int ShipSpeedBonus(const unit * u) } if (bonus > 0) { int skl = effskill(u, SK_SAILING, NULL); - int minsk = (sh->type->cptskill + 1) / 2; + int minsk = (ship_captain_minskill(sh) + 1) / 2; return (skl - minsk) / bonus; } else if (sh->type->flags & SFL_SPEEDY) { int base = 3; int speed = 0; - int minsk = sh->type->cptskill * base; + int minsk = ship_captain_minskill(sh) * base; int skl = effskill(u, SK_SAILING, NULL); while (skl >= minsk) { ++speed; @@ -292,21 +293,8 @@ static int ShipSpeedBonus(const unit * u) return 0; } -int crew_skill(const ship *sh) { - int n = 0; - unit *u; - - n = 0; - - for (u = sh->region->units; u; u = u->next) { - if (u->ship == sh) { - int es = effskill(u, SK_SAILING, NULL); - if (es >= sh->type->minskill) { - n += es * u->number; - } - } - } - return n; +int ship_captain_minskill(const ship *sh) { + return sh->type->cptskill; } int shipspeed(const ship * sh, const unit * u) @@ -323,8 +311,9 @@ int shipspeed(const ship * sh, const unit * u) assert(sh->type->construction); k = sh->type->range; - if (sh->size != sh->type->construction->maxsize) + if (!ship_finished(sh)) { return 0; + } if (sh->attribs) { if (curse_active(get_curse(sh->attribs, &ct_stormwind))) { @@ -343,7 +332,7 @@ int shipspeed(const ship * sh, const unit * u) bonus = ShipSpeedBonus(u); if (bonus > 0 && sh->type->range_max > sh->type->range) { - int crew = crew_skill(sh); + int crew = crew_skill(sh, NULL); int crew_bonus = (crew / sh->type->sumskill / 2) - 1; if (crew_bonus > 0) { int sbonus = sh->type->range_max - sh->type->range; @@ -385,17 +374,68 @@ const char *shipname(const ship * sh) return write_shipname(sh, ibuf, sizeof(idbuf[0])); } -int shipcapacity(const ship * sh) +bool ship_finished(const ship *sh) { - int i = sh->type->cargo; - - if (sh->type->construction && sh->size < sh->number * sh->type->construction->maxsize) - return 0; - - if (sh->damage) { - i = (int)ceil(i * (1.0 - sh->damage / sh->size / (double)DAMAGE_SCALE)); + if (sh->type->construction) { + return (sh->size >= sh->number * sh->type->construction->maxsize); } - return i; + return true; +} + +int enoughsailors(const ship * sh, int crew_skill) +{ + return crew_skill >= sh->type->sumskill * sh->number; +} + +int crew_skill(const ship *sh, int *o_captains) { + int n = 0, captains = 0; + unit *u; + + for (u = sh->region->units; u; u = u->next) { + if (u->ship == sh) { + int es = effskill(u, SK_SAILING, NULL); + if (es >= sh->type->cptskill) { + captains += u->number; + } + if (es >= sh->type->minskill) { + n += es * u->number; + } + } + } + if (o_captains) { + *o_captains = captains; + } + return n; +} + +bool ship_crewed(const ship *sh) +{ + int num_caps, crew = crew_skill(sh, &num_caps); + return num_caps >= sh->number && enoughsailors(sh, crew); +} + +int ship_capacity(const ship * sh) +{ + if (ship_finished(sh)) { + int i = sh->type->cargo * sh->number; + if (sh->damage) { + i = (int)ceil(i * (1.0 - sh->damage / sh->size / (double)DAMAGE_SCALE)); + } + return i; + } + return 0; +} + +int ship_cabins(const ship * sh) +{ + if (ship_finished(sh)) { + int i = sh->type->cabins * sh->number; + if (sh->damage) { + i = (int)ceil(i * (1.0 - sh->damage / sh->size / (double)DAMAGE_SCALE)); + } + return i; + } + return 0; } void getshipweight(const ship * sh, int *sweight, int *scabins) diff --git a/src/kernel/ship.h b/src/kernel/ship.h index 6c4e0bf95..b82a69140 100644 --- a/src/kernel/ship.h +++ b/src/kernel/ship.h @@ -90,8 +90,10 @@ extern "C" { struct unit *ship_owner(const struct ship *sh); void ship_update_owner(struct ship * sh); - extern const char *shipname(const struct ship *self); - extern int shipcapacity(const struct ship *sh); + const char *shipname(const struct ship *self); + int ship_capacity(const struct ship *sh); + int ship_cabins(const struct ship *sh); + bool ship_finished(const struct ship *sh); extern void getshipweight(const struct ship *sh, int *weight, int *cabins); extern ship *new_ship(const struct ship_type *stype, struct region *r, @@ -114,7 +116,10 @@ extern "C" { const char *ship_getname(const struct ship *sh); void ship_setname(struct ship *self, const char *name); int shipspeed(const struct ship *sh, const struct unit *u); - int crew_skill(const struct ship *sh); + + bool ship_crewed(const struct ship *sh); + int crew_skill(const struct ship *sh, int *num_captains); + int ship_captain_minskill(const struct ship *sh); int ship_damage_percent(const struct ship *sh); #ifdef __cplusplus diff --git a/src/kernel/ship.test.c b/src/kernel/ship.test.c index 062e7cd20..18d8a1754 100644 --- a/src/kernel/ship.test.c +++ b/src/kernel/ship.test.c @@ -641,21 +641,21 @@ static void test_crew_skill(CuTest *tc) { CuAssertIntEquals(tc, 1, stype->minskill); r = test_create_ocean(0, 0); sh = test_create_ship(r, stype); - CuAssertIntEquals(tc, 0, crew_skill(sh)); + CuAssertIntEquals(tc, 0, crew_skill(sh, NULL)); u = test_create_unit(test_create_faction(NULL), r); set_level(u, SK_SAILING, 1); - CuAssertIntEquals(tc, 0, crew_skill(sh)); + CuAssertIntEquals(tc, 0, crew_skill(sh, NULL)); u_set_ship(u, sh); set_level(u, SK_SAILING, 1); - CuAssertIntEquals(tc, 1, crew_skill(sh)); + CuAssertIntEquals(tc, 1, crew_skill(sh, NULL)); set_number(u, 10); - CuAssertIntEquals(tc, 10, crew_skill(sh)); + CuAssertIntEquals(tc, 10, crew_skill(sh, NULL)); stype->minskill = 2; - CuAssertIntEquals(tc, 0, crew_skill(sh)); + CuAssertIntEquals(tc, 0, crew_skill(sh, NULL)); set_level(u, SK_SAILING, 2); - CuAssertIntEquals(tc, 20, crew_skill(sh)); + CuAssertIntEquals(tc, 20, crew_skill(sh, NULL)); set_level(u, SK_SAILING, 3); - CuAssertIntEquals(tc, 30, crew_skill(sh)); + CuAssertIntEquals(tc, 30, crew_skill(sh, NULL)); test_teardown(); } diff --git a/src/laws.c b/src/laws.c index 50d364660..61262b75d 100644 --- a/src/laws.c +++ b/src/laws.c @@ -1094,8 +1094,8 @@ int enter_ship(unit * u, struct order *ord, int id, bool report) } if (CheckOverload()) { int sweight, scabins; - int mweight = shipcapacity(sh); - int mcabins = sh->type->cabins; + int mweight = ship_capacity(sh); + int mcabins = ship_cabins(sh); if (mweight > 0) { getshipweight(sh, &sweight, &scabins); @@ -2598,7 +2598,7 @@ void sinkships(struct region * r) if (!sh->type->construction || sh->size >= sh->type->construction->maxsize) { if (fval(r->terrain, SEA_REGION)) { - if (!enoughsailors(sh, crew_skill(sh))) { + if (!ship_crewed(sh)) { /* ship is at sea, but not enough people to control it */ double dmg = config_get_flt("rules.ship.damage.nocrewocean", 0.3); damage_ship(sh, dmg); diff --git a/src/move.c b/src/move.c index a5438eb3d..484ee993f 100644 --- a/src/move.c +++ b/src/move.c @@ -470,13 +470,13 @@ static bool cansail(const region * r, ship * sh) { UNUSED_ARG(r); - if (sh->type->construction && sh->size != sh->type->construction->maxsize) { + if (!ship_finished(sh)) { return false; } else { int n = 0, p = 0; - int mweight = shipcapacity(sh); - int mcabins = sh->type->cabins; + int mweight = ship_capacity(sh); + int mcabins = ship_cabins(sh); getshipweight(sh, &n, &p); @@ -492,12 +492,12 @@ static double overload(const region * r, ship * sh) { UNUSED_ARG(r); - if (sh->type->construction && sh->size != sh->type->construction->maxsize) { + if (!ship_finished(sh)) { return DBL_MAX; } else { int n = 0, p = 0; - int mcabins = sh->type->cabins; + int mcabins = sh->type->cabins * sh->number; double ovl; getshipweight(sh, &n, &p); @@ -509,11 +509,6 @@ static double overload(const region * r, ship * sh) } } -int enoughsailors(const ship * sh, int crew_skill) -{ - return crew_skill >= sh->type->sumskill; -} - /* ------------------------------------------------------------- */ static ship *do_maelstrom(region * r, unit * u) @@ -808,7 +803,7 @@ static void drifting_ships(region * r) ship *sh = *shp; region *rnext = NULL; region_list *route = NULL; - unit *firstu = r->units, *lastu = NULL, *captain; + unit *firstu = r->units, *lastu = NULL; direction_t dir = NODIRECTION; double ovl; @@ -822,16 +817,10 @@ static void drifting_ships(region * r) continue; } - /* Kapitaen bestimmen */ - captain = ship_owner(sh); - if (captain && effskill(captain, SK_SAILING, r) < sh->type->cptskill) - captain = NULL; - /* Kapitaen da? Beschaedigt? Genuegend Matrosen? * Genuegend leicht? Dann ist alles OK. */ - if (captain && sh->size == sh->type->construction->maxsize - && enoughsailors(sh, crew_skill(sh)) && cansail(r, sh)) { + if (ship_finished(sh) && ship_crewed(sh) && cansail(r, sh)) { shp = &sh->next; continue; } @@ -1639,19 +1628,17 @@ static bool ship_ready(const region * r, unit * u, order * ord) cmistake(u, ord, 146, MSG_MOVE); return false; } - if (effskill(u, SK_SAILING, r) < u->ship->type->cptskill) { + if (effskill(u, SK_SAILING, r) < ship_captain_minskill(u->ship)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, - "error_captain_skill_low", "value ship", u->ship->type->cptskill, + "error_captain_skill_low", "value ship", ship_captain_minskill(u->ship), u->ship)); return false; } - if (u->ship->type->construction) { - if (u->ship->size != u->ship->type->construction->maxsize) { - cmistake(u, ord, 15, MSG_MOVE); - return false; - } + if (!ship_finished(u->ship)) { + cmistake(u, ord, 15, MSG_MOVE); + return false; } - if (!enoughsailors(u->ship, crew_skill(u->ship))) { + if (!ship_crewed(u->ship)) { cmistake(u, ord, 1, MSG_MOVE); return false; } diff --git a/src/move.h b/src/move.h index cbf154694..4362091b2 100644 --- a/src/move.h +++ b/src/move.h @@ -53,7 +53,6 @@ extern "C" { int personcapacity(const struct unit *u); void movement(void); - void run_to(struct unit *u, struct region *to); int enoughsailors(const struct ship *sh, int sumskill); bool canswim(struct unit *u); bool canfly(struct unit *u); diff --git a/src/report.c b/src/report.c index c69ddcdab..63886096e 100644 --- a/src/report.c +++ b/src/report.c @@ -1728,7 +1728,7 @@ nr_ship(struct stream *out, const region *r, const ship * sh, const faction * f, n = (n + 99) / 100; /* 1 Silber = 1 GE */ sbs_printf(&sbs, "%s, %s, (%d/%d)", shipname(sh), - LOC(f->locale, sh->type->_name), n, shipcapacity(sh) / 100); + LOC(f->locale, sh->type->_name), n, ship_capacity(sh) / 100); } else { sbs_printf(&sbs, "%s, %s", shipname(sh), LOC(f->locale, sh->type->_name));