diff --git a/res/core/de/strings.xml b/res/core/de/strings.xml
index cc252c343..cd408f9ea 100644
--- a/res/core/de/strings.xml
+++ b/res/core/de/strings.xml
@@ -4754,6 +4754,11 @@
Der Landstrich kann über Jahre hinaus von den Folgen einer
solchen Dürre betroffen sein.
+ This powerful ritual opens a gate to the elemental plane of
+ fire. A great drought comes over the land. Farmers, animals and
+ plants of the region are fighting for survival, but only half of
+ all living things will be able to survive a drought like this.
+ The region will suffer the consequences of such a drought for years to come.
diff --git a/src/move.c b/src/move.c
index fd6bf2933..32d325304 100644
--- a/src/move.c
+++ b/src/move.c
@@ -696,10 +696,14 @@ int check_ship_allowed(struct ship *sh, const region * r)
}
if (bt_harbour && buildingtype_exists(r, bt_harbour, true)) {
- unit* hafenmeister = NULL;
- hafenmeister = owner_buildingtyp(r, bt_harbour);
- if ((sh->_owner->faction == hafenmeister->faction) || (ucontact(sh->_owner, hafenmeister)) || (alliedunit(sh->_owner, hafenmeister->faction, HELP_GUARD)))
+ unit* harbourmaster = NULL;
+ harbourmaster = owner_buildingtyp(r, bt_harbour);
+ if (!harbourmaster || !sh->_owner) {
return SA_HARBOUR;
+ }
+ else if ((sh->_owner->faction == harbourmaster->faction) || (ucontact(harbourmaster, sh->_owner)) || (alliedunit(harbourmaster, sh->_owner->faction, HELP_GUARD))) {
+ return SA_HARBOUR;
+ }
}
if (fval(r->terrain, SEA_REGION)) {
return SA_COAST;
@@ -2060,7 +2064,7 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
* Inland zu segeln versuchte */
if (sh != NULL && fval(sh, SF_MOVED)) {
- unit *hafenmeister;
+ unit *harbourmaster;
/* nachdem alle Richtungen abgearbeitet wurden, und alle Einheiten
* transferiert wurden, kann der aktuelle Befehl gelöscht werden. */
cycle_route(ord, u, step);
@@ -2089,25 +2093,25 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
/* Hafengebühren ? */
- hafenmeister = owner_buildingtyp(current_point, bt_find("harbour"));
- if (sh && hafenmeister != NULL) {
+ harbourmaster = owner_buildingtyp(current_point, bt_find("harbour"));
+ if (sh && harbourmaster != NULL) {
item *itm;
unit *u2;
item *trans = NULL;
for (u2 = current_point->units; u2; u2 = u2->next) {
- if (u2->ship == sh && !alliedunit(hafenmeister, u->faction, HELP_GUARD)) {
+ if (u2->ship == sh && !alliedunit(harbourmaster, u->faction, HELP_GUARD)) {
- if (effskill(hafenmeister, SK_PERCEPTION) > effskill(u2, SK_STEALTH)) {
+ if (effskill(harbourmaster, SK_PERCEPTION) > effskill(u2, SK_STEALTH)) {
for (itm = u2->items; itm; itm = itm->next) {
const luxury_type *ltype = resource2luxury(itm->type->rtype);
if (ltype != NULL && itm->number > 0) {
- int st = itm->number * effskill(hafenmeister, SK_TRADE) / 50;
+ int st = itm->number * effskill(harbourmaster, SK_TRADE) / 50;
st = _min(itm->number, st);
if (st > 0) {
i_change(&u2->items, itm->type, -st);
- i_change(&hafenmeister->items, itm->type, st);
+ i_change(&harbourmaster->items, itm->type, st);
i_add(&trans, i_new(itm->type, st));
}
}
@@ -2117,10 +2121,10 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
}
if (trans) {
message *msg =
- msg_message("harbor_trade", "unit items ship", hafenmeister, trans,
+ msg_message("harbor_trade", "unit items ship", harbourmaster, trans,
u->ship);
add_message(&u->faction->msgs, msg);
- add_message(&hafenmeister->faction->msgs, msg);
+ add_message(&harbourmaster->faction->msgs, msg);
msg_release(msg);
while (trans)
i_remove(&trans, trans);
diff --git a/src/move.test.c b/src/move.test.c
index 90307586a..83c7c7066 100644
--- a/src/move.test.c
+++ b/src/move.test.c
@@ -3,10 +3,13 @@
#include
#include "move.h"
+#include
#include
+#include
#include
#include
#include
+#include
#include
@@ -15,77 +18,165 @@
static void test_ship_not_allowed_in_coast(CuTest * tc)
{
- region *r1, *r2;
- ship * sh;
- terrain_type *ttype, *otype;
- ship_type *stype;
+ region *r1, *r2;
+ ship * sh;
+ terrain_type *ttype, *otype;
+ ship_type *stype;
- test_cleanup();
- test_create_world();
+ test_cleanup();
+ test_create_world();
- ttype = test_create_terrain("glacier", LAND_REGION|ARCTIC_REGION|WALK_INTO|SAIL_INTO);
- otype = test_create_terrain("ocean", SEA_REGION|SAIL_INTO);
- stype = test_create_shiptype("derp");
- stype->coasts = (const struct terrain_type **)calloc(2, sizeof(const struct terrain_type *));
+ ttype = test_create_terrain("glacier", LAND_REGION | ARCTIC_REGION | WALK_INTO | SAIL_INTO);
+ otype = test_create_terrain("ocean", SEA_REGION | SAIL_INTO);
+ stype = test_create_shiptype("derp");
+ stype->coasts = (const struct terrain_type **)calloc(2, sizeof(const struct terrain_type *));
- r1 = test_create_region(0, 0, ttype);
- r2 = test_create_region(1, 0, otype);
- sh = test_create_ship(0, stype);
+ r1 = test_create_region(0, 0, ttype);
+ r2 = test_create_region(1, 0, otype);
+ sh = test_create_ship(0, stype);
- CuAssertIntEquals(tc, SA_COAST, check_ship_allowed(sh, r2));
- CuAssertIntEquals(tc, SA_NO_COAST, check_ship_allowed(sh, r1));
- stype->coasts[0] = ttype;
- CuAssertIntEquals(tc, SA_COAST, check_ship_allowed(sh, r1));
+ CuAssertIntEquals(tc, SA_COAST, check_ship_allowed(sh, r2));
+ CuAssertIntEquals(tc, SA_NO_COAST, check_ship_allowed(sh, r1));
+ stype->coasts[0] = ttype;
+ CuAssertIntEquals(tc, SA_COAST, check_ship_allowed(sh, r1));
}
-static void test_ship_allowed_with_harbor(CuTest * tc)
+typedef struct move_fixture {
+ region *r;
+ ship *sh;
+ building * b;
+ unit *u;
+} move_fixture;
+
+static void setup_harbor(move_fixture *mf) {
+ region *r;
+ ship * sh;
+ terrain_type * ttype;
+ building_type * btype;
+ building * b;
+ unit *u;
+
+ test_cleanup();
+ test_create_world();
+
+ ttype = test_create_terrain("glacier", LAND_REGION | ARCTIC_REGION | WALK_INTO | SAIL_INTO);
+ btype = test_create_buildingtype("harbour");
+
+ sh = test_create_ship(0, 0);
+ r = test_create_region(0, 0, ttype);
+
+ b = test_create_building(r, btype);
+ b->flags |= BLD_WORKING;
+
+ u = test_create_unit(test_create_faction(0), r);
+ u->ship = sh;
+ ship_set_owner(u);
+
+ mf->r = r;
+ mf->u = u;
+ mf->sh = sh;
+ mf->b = b;
+}
+
+static void test_ship_allowed_without_harbormaster(CuTest * tc)
{
- region *r;
- ship * sh;
- terrain_type * ttype;
- building_type * btype;
- building * b;
+ move_fixture mf;
- test_cleanup();
- test_create_world();
+ setup_harbor(&mf);
- ttype = test_create_terrain("glacier", LAND_REGION|ARCTIC_REGION|WALK_INTO|SAIL_INTO);
- btype = test_create_buildingtype("harbour");
+ CuAssertIntEquals(tc, SA_HARBOUR, check_ship_allowed(mf.sh, mf.r));
+}
- r = test_create_region(0, 0, ttype);
- sh = test_create_ship(0, 0);
+static void test_ship_blocked_by_harbormaster(CuTest * tc) {
+ unit *u;
+ move_fixture mf;
- b = test_create_building(r, btype);
- b->flags |= BLD_WORKING;
- CuAssertIntEquals(tc, SA_HARBOUR, check_ship_allowed(sh, r));
+ setup_harbor(&mf);
+
+ u = test_create_unit(test_create_faction(0), mf.r);
+ u->building = mf.b;
+ building_set_owner(u);
+
+ CuAssertIntEquals_Msg(tc, "harbor master must contact ship", SA_NO_COAST, check_ship_allowed(mf.sh, mf.r));
+ test_cleanup();
+}
+
+static void test_ship_has_harbormaster_contact(CuTest * tc) {
+ unit *u;
+ move_fixture mf;
+
+ setup_harbor(&mf);
+
+ u = test_create_unit(test_create_faction(0), mf.r);
+ u->building = mf.b;
+ building_set_owner(u);
+ usetcontact(mf.b->_owner, mf.sh->_owner);
+
+ CuAssertIntEquals(tc, SA_HARBOUR, check_ship_allowed(mf.sh, mf.r));
+ test_cleanup();
+}
+
+static void test_ship_has_harbormaster_same_faction(CuTest * tc) {
+ unit *u;
+ move_fixture mf;
+
+ setup_harbor(&mf);
+
+ u = test_create_unit(mf.u->faction, mf.r);
+ u->building = mf.b;
+ building_set_owner(u);
+
+ CuAssertIntEquals(tc, SA_HARBOUR, check_ship_allowed(mf.sh, mf.r));
+ test_cleanup();
+}
+
+static void test_ship_has_harbormaster_ally(CuTest * tc) {
+ unit *u;
+ move_fixture mf;
+ ally *al;
+
+ setup_harbor(&mf);
+
+ u = test_create_unit(test_create_faction(0), mf.r);
+ u->building = mf.b;
+ building_set_owner(u);
+ al = ally_add(&u->faction->allies, mf.u->faction);
+ al->status = HELP_GUARD;
+
+ CuAssertIntEquals(tc, SA_HARBOUR, check_ship_allowed(mf.sh, mf.r));
+ test_cleanup();
}
static void test_building_type_exists(CuTest * tc)
{
- region *r;
- building *b;
- building_type *btype, *btype2;
+ region *r;
+ building *b;
+ building_type *btype, *btype2;
- test_cleanup();
- test_create_world();
+ test_cleanup();
+ test_create_world();
- btype2 = bt_get_or_create("lighthouse");
- btype = bt_get_or_create("castle");
+ btype2 = bt_get_or_create("lighthouse");
+ btype = bt_get_or_create("castle");
- r = findregion(-1, 0);
- b = new_building(btype, r, default_locale);
+ r = findregion(-1, 0);
+ b = new_building(btype, r, default_locale);
- CuAssertPtrNotNull(tc, b);
- CuAssertTrue(tc, !buildingtype_exists(r, NULL, false));
- CuAssertTrue(tc, buildingtype_exists(r, btype, false));
- CuAssertTrue(tc, !buildingtype_exists(r, btype2, false));
+ CuAssertPtrNotNull(tc, b);
+ CuAssertTrue(tc, !buildingtype_exists(r, NULL, false));
+ CuAssertTrue(tc, buildingtype_exists(r, btype, false));
+ CuAssertTrue(tc, !buildingtype_exists(r, btype2, false));
}
CuSuite *get_move_suite(void)
{
- CuSuite *suite = CuSuiteNew();
- SUITE_ADD_TEST(suite, test_building_type_exists);
- SUITE_ADD_TEST(suite, test_ship_not_allowed_in_coast);
- SUITE_ADD_TEST(suite, test_ship_allowed_with_harbor);
- return suite;
+ CuSuite *suite = CuSuiteNew();
+ SUITE_ADD_TEST(suite, test_building_type_exists);
+ SUITE_ADD_TEST(suite, test_ship_not_allowed_in_coast);
+ SUITE_ADD_TEST(suite, test_ship_allowed_without_harbormaster);
+ SUITE_ADD_TEST(suite, test_ship_blocked_by_harbormaster);
+ SUITE_ADD_TEST(suite, test_ship_has_harbormaster_contact);
+ SUITE_ADD_TEST(suite, test_ship_has_harbormaster_ally);
+ SUITE_ADD_TEST(suite, test_ship_has_harbormaster_same_faction);
+ return suite;
}