diff --git a/res/core/messages.xml b/res/core/messages.xml
index 8231edec3..3e16e8301 100644
--- a/res/core/messages.xml
+++ b/res/core/messages.xml
@@ -3269,19 +3269,21 @@
+
- "Die $ship($ship) in $region($region) entdeckt ein Opfer im $direction($dir)."
- "The $ship($ship) in $region($region) made $direction($dir) a target."
+ "$if($isnull($ship),"$unit($unit)","Die $ship($ship)") in $region($region) entdeckt ein Opfer im $direction($dir)."
+ "$if($isnull($ship),"$unit($unit)","The $ship($ship)") in $region($region) made $direction($dir) a target."
+
- "Die $ship($ship) in $region($region) kann keine Schiffe aufbringen."
- "The $ship($ship) could not capture other ships in $region($region)."
+ "$if($isnull($ship),"$unit($unit)","Die $ship($ship)") in $region($region) kann keine Schiffe aufbringen."
+ "$if($isnull($ship),"$unit($unit)","The $ship($ship)") could not capture other ships in $region($region)."
diff --git a/src/piracy.c b/src/piracy.c
index 312af6c4b..e8864faa9 100644
--- a/src/piracy.c
+++ b/src/piracy.c
@@ -148,7 +148,11 @@ void piracy_cmd(unit * u, order *ord)
region *rc = rconnect(r, dir);
aff[dir].value = 0;
aff[dir].target = 0;
- if (rc && fval(rc->terrain, SAIL_INTO) && can_takeoff(sh, r, rc)) {
+ // 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))
+ || (canswim(u) && fval(rc->terrain, SWIM_INTO) && fval(rc->terrain, SEA_REGION)))) {
for (sh2 = rc->ships; sh2; sh2 = sh2->next) {
unit *cap = ship_owner(sh2);
@@ -188,13 +192,13 @@ void piracy_cmd(unit * u, order *ord)
/* Wenn kein Ziel gefunden, entsprechende Meldung generieren */
if (target_dir == NODIRECTION) {
ADDMSG(&u->faction->msgs, msg_message("piratenovictim",
- "ship region", sh, r));
+ "ship unit region", sh, u, r));
return;
}
/* Meldung generieren */
ADDMSG(&u->faction->msgs, msg_message("piratesawvictim",
- "ship region dir", sh, r, target_dir));
+ "ship unit region dir", sh, u, r, target_dir));
/* Befehl konstruieren */
set_order(&u->thisorder, create_order(K_MOVE, u->faction->locale, "%s",
diff --git a/src/piracy.test.c b/src/piracy.test.c
index 188ea1fed..bf4b664fb 100644
--- a/src/piracy.test.c
+++ b/src/piracy.test.c
@@ -31,6 +31,45 @@ static void setup_piracy(void) {
st_boat->cargo = 1000;
}
+static void setup_pirate(unit **pirate, int p_r_flags, int p_rc_flags, const char *p_shiptype,
+ order **ord, unit **victim, int v_r_flags, const char *v_shiptype) {
+ terrain_type *vterrain;
+ ship_type *st_boat = NULL;
+ race *rc;
+ faction *f;
+
+ setup_piracy();
+ vterrain = get_or_create_terrain("terrain1");
+ fset(vterrain, v_r_flags);
+ *victim = test_create_unit(test_create_faction(0), test_create_region(1, 0, vterrain));
+ assert(*victim);
+
+ if (v_shiptype) {
+ st_boat = st_get_or_create(v_shiptype);
+ u_set_ship(*victim, test_create_ship((*victim)->region, st_boat));
+ st_boat->coasts = (struct terrain_type **)calloc(2, sizeof(struct terrain_type *));
+ st_boat->coasts[0] = vterrain;
+ st_boat->coasts[1] = 0;
+ }
+
+ *pirate = create_unit(test_create_region(0, 0, get_or_create_terrain("terrain2")), f = test_create_faction(0), 1, rc = rc_get_or_create("pirate"), 0, 0, 0);
+ fset(rc, p_rc_flags);
+ assert(f && *pirate);
+
+ if (p_shiptype) {
+ st_boat = st_get_or_create(p_shiptype);
+ u_set_ship(*pirate, test_create_ship((*pirate)->region, st_boat));
+ st_boat->coasts = (struct terrain_type **)calloc(2, sizeof(struct terrain_type *));
+ st_boat->coasts[0] = vterrain;
+ st_boat->coasts[1] = 0;
+ }
+
+ f->locale = get_or_create_locale("de");
+ *ord = create_order(K_PIRACY, f->locale, "%s", itoa36((*victim)->faction->no));
+ assert(*ord);
+
+}
+
static void test_piracy_cmd(CuTest * tc) {
faction *f;
region *r;
@@ -39,6 +78,8 @@ static void test_piracy_cmd(CuTest * tc) {
terrain_type *t_ocean;
ship_type *st_boat;
+ test_cleanup();
+
setup_piracy();
t_ocean = get_or_create_terrain("ocean");
st_boat = st_get_or_create("boat");
@@ -73,6 +114,8 @@ static void test_piracy_cmd_errors(CuTest * tc) {
order *ord;
ship_type *st_boat;
+ test_cleanup();
+
setup_piracy();
st_boat = st_get_or_create("boat");
r = test_create_race("pirates");
@@ -112,11 +155,76 @@ static void test_piracy_cmd_errors(CuTest * tc) {
test_cleanup();
}
+static void test_piracy_cmd_walking(CuTest * tc) {
+ unit *pirate, *victim;
+ order *ord;
+ region *r;
+
+ test_cleanup();
+
+ setup_pirate(&pirate, 0, 0, NULL, &ord, &victim, SWIM_INTO | SEA_REGION, "boat");
+ /* fset(rc, RCF_SWIM); */
+ r = pirate->region;
+
+ piracy_cmd(pirate, ord);
+ CuAssertPtrEquals(tc, 0, pirate->thisorder);
+ CuAssertTrue(tc, pirate->region == r);
+ CuAssertPtrNotNullMsg(tc, "successful PIRACY message", test_find_messagetype(pirate->faction->msgs, "error144"));
+ free_order(ord);
+
+ test_cleanup();
+}
+
+static void test_piracy_cmd_land_to_land(CuTest * tc) {
+ unit *pirate, *victim;
+ order *ord;
+ region *r;
+
+ test_cleanup();
+
+ setup_pirate(&pirate, 0, 0, "boat", &ord, &victim, SAIL_INTO, "boat");
+ set_level(pirate, SK_SAILING, pirate->ship->type->sumskill);
+ r = pirate->region;
+
+ piracy_cmd(pirate, ord);
+ CuAssertPtrEquals(tc, 0, pirate->thisorder);
+ CuAssertTrue(tc, "no piracy from land to adjacent land region", pirate->region == r);
+ /* TODO check message
+ CuAssertPtrNotNullMsg(tc, "successful PIRACY movement", test_find_messagetype(pirate->faction->msgs, "travel"));
+ */
+ free_order(ord);
+
+ test_cleanup();
+}
+
+static void test_piracy_cmd_swimmer(CuTest * tc) {
+ unit *pirate, *victim;
+ order *ord;
+ region *r;
+
+ test_cleanup();
+
+ setup_pirate(&pirate, 0, RCF_SWIM, NULL, &ord, &victim, SWIM_INTO | SEA_REGION, "boat");
+ r = pirate->region;
+
+ piracy_cmd(pirate, ord);
+ CuAssertPtrEquals(tc, 0, pirate->thisorder);
+ CuAssertTrue(tc, pirate->region != r);
+ CuAssertPtrEquals(tc, victim->region, pirate->region);
+ CuAssertPtrNotNullMsg(tc, "successful PIRACY message", test_find_messagetype(pirate->faction->msgs, "piratesawvictim"));
+ CuAssertPtrNotNullMsg(tc, "successful PIRACY movement", test_find_messagetype(pirate->faction->msgs, "travel"));
+ free_order(ord);
+
+ test_cleanup();
+}
CuSuite *get_piracy_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_piracy_cmd_errors);
SUITE_ADD_TEST(suite, test_piracy_cmd);
+ SUITE_ADD_TEST(suite, test_piracy_cmd_walking);
+ DISABLE_TEST(suite, test_piracy_cmd_land_to_land);
+ SUITE_ADD_TEST(suite, test_piracy_cmd_swimmer);
return suite;
}