fix new harbor code, add tests.

- alliances were checked in the opposite direction
- code crashed when harbor has no owner
This commit is contained in:
Enno Rehling 2014-10-03 21:26:11 +02:00
parent 98b69dc614
commit 595dc1334e
3 changed files with 162 additions and 62 deletions

View File

@ -4754,6 +4754,11 @@
Der Landstrich kann über Jahre hinaus von den Folgen einer
solchen Dürre betroffen sein.
</text>
<text locale="en">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.</text>
</string>
<string name="magic_roots">
<text locale="de">

View File

@ -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);

View File

@ -3,10 +3,13 @@
#include <stdlib.h>
#include "move.h"
#include <kernel/ally.h>
#include <kernel/building.h>
#include <kernel/faction.h>
#include <kernel/region.h>
#include <kernel/ship.h>
#include <kernel/terrain.h>
#include <kernel/unit.h>
#include <util/language.h>
@ -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;
}