diff --git a/res/translations/messages.de.po b/res/translations/messages.de.po index 776a1e207..759f41ed1 100644 --- a/res/translations/messages.de.po +++ b/res/translations/messages.de.po @@ -2768,6 +2768,12 @@ msgstr "\"$unit($unit) verspeiste $int($amount) Bauern.\"" msgid "error320" msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit kann nicht bewachen, da sie versucht zu fliehen.\"" +msgid "error321" +msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit gehört nicht zu unserer Partei.\"" + +msgid "error322" +msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit ist bereits auf einem Schiff.\"" + msgid "dissolve_units_2" msgstr "\"$unit($unit) in $region($region): $int($number) $race($race,$number) $if($eq($number,1),\"wurde zum Baum\", \"wurden zu Bäumen\").\"" diff --git a/scripts/tests/e2/ships.lua b/scripts/tests/e2/ships.lua index a50182c0d..1e101b5b2 100644 --- a/scripts/tests/e2/ships.lua +++ b/scripts/tests/e2/ships.lua @@ -190,3 +190,38 @@ function test_give_ship_merge() assert_equal(1, u1.ship.number) assert_equal(2, u2.ship.number) end + +function test_give_ship_max() + local r = region.create(1, 0, 'plain') + local f = faction.create("human") + local u1 = unit.create(f, r, 1) + local u2 = unit.create(f, r, 1) + local sh = ship.create(r, 'boat') + sh.number = 3 + sh.damage = 9 + sh.size = 12 + u1.ship = sh + u1:add_order("GIB " .. itoa36(u2.id) .. " 4 SCHIFF") + process_orders() + assert_equal(1, u1.ship.number) + assert_equal(3, u1.ship.damage) + assert_equal(4, u1.ship.size) + assert_equal(2, u2.ship.number) + assert_equal(6, u2.ship.damage) + assert_equal(8, u2.ship.size) +end + +function test_give_ship_self_only() + local r = region.create(1, 0, 'plain') + local f1 = faction.create("human") + local f2 = faction.create("human") + local u1 = unit.create(f1, r, 1) + local u2 = unit.create(f2, r, 1) + local sh = ship.create(r, 'boat') + sh.number = 2 + u1.ship = sh + u1:add_order("GIB " .. itoa36(u2.id) .. " 1 SCHIFF") + process_orders() + assert_equal(2, u1.ship.number) + assert_equal(nil, u2.ship) +end diff --git a/src/bind_ship.c b/src/bind_ship.c index 6711b0370..71b6ae4f4 100644 --- a/src/bind_ship.c +++ b/src/bind_ship.c @@ -49,8 +49,7 @@ 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; + scale_ship(sh, n); return 0; } diff --git a/src/give.c b/src/give.c index 036a7ae04..52b017448 100644 --- a/src/give.c +++ b/src/give.c @@ -293,8 +293,40 @@ bool rule_transfermen(void) return rule != 0; } -message * give_ship(unit *u, unit *u2, int n, order *ord) { +static void transfer_ships(ship *s1, ship *s2, int n) +{ + assert(n < s1->number); + s2->damage += s1->damage * n / s1->number; + s2->size += s1->size * n / s1->number; + s2->number += n; + scale_ship(s1, s1->number - n); +} + +message * give_ship(unit *u, unit *u2, int n, order *ord) +{ assert(u->ship); + assert(n > 0 && n < u->ship->number); + if (u->faction != u2->faction) { + return msg_error(u, ord, 321); + } + if (u2->ship) { + if (u2->ship->type != u->ship->type) { + return msg_error(u, ord, 322); + } + transfer_ships(u->ship, u2->ship, n); + } + else{ + if (fval(u_race(u2), RCF_CANSAIL)) { + ship * sh = new_ship(u->ship->type, u->region, u->faction->locale); + scale_ship(sh, 0); + u_set_ship(u2, sh); + transfer_ships(u->ship, sh, n); + } + else { + return msg_error(u, ord, 233); + } + + } if (u->ship->number < n) { n = u->ship->number; } @@ -661,18 +693,7 @@ static void give_all_items(unit *u, unit *u2, order *ord) { } else { param_t p = findparam(s, u->faction->locale); - if (p == P_SHIP) { - if (u->ship) { - message * msg = give_ship(u, u2, u->ship->number, ord); - if (msg) { - ADDMSG(&u->faction->msgs, msg); - } - } - else { - cmistake(u, ord, 144, MSG_COMMERCE); - } - } - else if (p == P_PERSON) { + if (p == P_PERSON) { if (!(u_race(u)->ec_flags & ECF_GIVEPERSON)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "race_noregroup", "race", u_race(u))); @@ -838,7 +859,11 @@ void give_cmd(unit * u, order * ord) p = findparam(s, u->faction->locale); if (p == P_SHIP) { if (u->ship) { - message * msg = give_ship(u, u2, n, ord); + message * msg; + if (n >= u->ship->number) { + n = u->ship->number - 1; + } + msg = give_ship(u, u2, n, ord); if (msg) { ADDMSG(&u->faction->msgs, msg); } diff --git a/src/kernel/build.c b/src/kernel/build.c index 3a73f8fd5..447db8662 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -932,8 +932,7 @@ static void build_ship(unit * u, ship * sh, int want) msg_message("buildship", "ship unit size", sh, u, n)); } -void -create_ship(unit * u, const struct ship_type *newtype, int want, +void create_ship(unit * u, const struct ship_type *newtype, int want, order * ord) { ship *sh; diff --git a/src/kernel/ship.c b/src/kernel/ship.c index ca2da27b9..1e38257d9 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -424,6 +424,13 @@ bool ship_crewed(const ship *sh) { return (capskill >= ship_captain_minskill(sh)) && (sumskill >= sh->type->sumskill * sh->number); } +void scale_ship(ship *sh, int n) +{ + sh->size = sh->size * n / sh->number; + sh->damage = sh->damage * n / sh->number; + sh->number = n; +} + int ship_capacity(const ship * sh) { if (ship_finished(sh)) { diff --git a/src/kernel/ship.h b/src/kernel/ship.h index 34230f55b..a9a678848 100644 --- a/src/kernel/ship.h +++ b/src/kernel/ship.h @@ -122,6 +122,7 @@ extern "C" { int ship_captain_minskill(const struct ship *sh); int ship_damage_percent(const struct ship *sh); + void scale_ship(struct ship *sh, int n); #ifdef __cplusplus } #endif