More tests for ships.

ship->owner is now in use, but there's an assert failing in shipspeed() during report writing.
This commit is contained in:
Enno Rehling 2012-05-17 01:14:43 -07:00
parent 94ca9a1f98
commit 9cbdaea27f
7 changed files with 226 additions and 28 deletions

View File

@ -1167,7 +1167,7 @@ static boolean mayenter(region * r, unit * u, building * b)
return false; return false;
} }
static int mayboard(const unit * u, const ship * sh) static int mayboard(const unit * u, ship * sh)
{ {
unit *u2 = shipowner(sh); unit *u2 = shipowner(sh);

View File

@ -2494,7 +2494,7 @@ unit *get_clone_mage(const unit * u)
return NULL; return NULL;
} }
static boolean is_moving_ship(const region * r, const ship * sh) static boolean is_moving_ship(const region * r, ship * sh)
{ {
const unit *u = shipowner(sh); const unit *u = shipowner(sh);

View File

@ -633,7 +633,7 @@ static boolean is_freezing(const unit * u)
#define SA_NO_INSECT -1 #define SA_NO_INSECT -1
#define SA_NO_COAST -2 #define SA_NO_COAST -2
static int ship_allowed(const struct ship *sh, const region * r) static int is_ship_allowed(struct ship *sh, const region * r)
{ {
int c = 0; int c = 0;
static const building_type *bt_harbour = NULL; static const building_type *bt_harbour = NULL;
@ -752,7 +752,7 @@ static void drifting_ships(region * r)
region *rn; region *rn;
dir = (direction_t) ((d + d_offset) % MAXDIRECTIONS); dir = (direction_t) ((d + d_offset) % MAXDIRECTIONS);
rn = rconnect(r, dir); rn = rconnect(r, dir);
if (rn != NULL && fval(rn->terrain, SAIL_INTO) && ship_allowed(sh, rn) > 0) { if (rn != NULL && fval(rn->terrain, SAIL_INTO) && is_ship_allowed(sh, rn) > 0) {
rnext = rn; rnext = rn;
if (!fval(rnext->terrain, SEA_REGION)) if (!fval(rnext->terrain, SEA_REGION))
break; break;
@ -1820,7 +1820,7 @@ sail(unit * u, order * ord, boolean move_on_land, region_list ** routep)
} }
} }
reason = ship_allowed(sh, next_point); reason = is_ship_allowed(sh, next_point);
if (reason<0) { if (reason<0) {
/* for some reason or another, we aren't allowed in there.. */ /* for some reason or another, we aren't allowed in there.. */
if (check_leuchtturm(current_point, NULL) || reason == SA_NO_INSECT) { if (check_leuchtturm(current_point, NULL) || reason == SA_NO_INSECT) {

View File

@ -287,31 +287,37 @@ void getshipweight(const ship * sh, int *sweight, int *scabins)
} }
} }
unit *shipowner(const ship * sh) unit *shipowner(ship * sh)
{ {
unit *u; unit *owner = sh->owner;
unit *first = NULL; if (owner && owner->number<=0) {
unit *u, *first = NULL;
const region *r = sh->region; owner->ship = 0;
freset(owner, UFL_OWNER);
/* Prüfen ob Eigentümer am leben. */ /* Prüfen ob Eigentümer am leben. */
for (u = r->units; u; u = u->next) { for (u = sh->region->units; u; u = u->next) {
if (u->ship == sh) { if (u->ship == sh) {
if (!first && u->number > 0) if (u->number > 0) {
first = u; if (u->faction==owner->faction) {
if (fval(u, UFL_OWNER) && u->number > 0) first = u;
return u; break;
if (u->number == 0) }
freset(u, UFL_OWNER); else if (!first) {
first = u; /* you'll do in an emergency */
}
}
}
}
owner = first;
if (owner) {
fset(owner, UFL_OWNER);
sh->owner = owner;
} }
} }
/* Eigentümer tot oder kein Eigentümer vorhanden. Erste lebende Einheit /* Eigentümer tot oder kein Eigentümer vorhanden. Erste lebende Einheit
* nehmen. */ * nehmen. */
return owner;
if (first)
fset(first, UFL_OWNER);
return first;
} }
void write_ship_reference(const struct ship *sh, struct storage *store) void write_ship_reference(const struct ship *sh, struct storage *store)

View File

@ -96,7 +96,7 @@ extern "C" {
extern void damage_ship(ship * sh, double percent); extern void damage_ship(ship * sh, double percent);
extern struct unit *captain(ship * sh); extern struct unit *captain(ship * sh);
extern struct unit *shipowner(const struct ship *sh); extern struct unit *shipowner(struct ship *sh);
extern const char *shipname(const struct ship *self); extern const char *shipname(const struct ship *self);
extern int shipcapacity(const struct ship *sh); extern int shipcapacity(const struct ship *sh);
extern void getshipweight(const struct ship *sh, int *weight, int *cabins); extern void getshipweight(const struct ship *sh, int *weight, int *cabins);

View File

@ -24,7 +24,7 @@ static void test_register_ship(CuTest * tc)
CuAssertPtrNotNull(tc, st_find("herp")); CuAssertPtrNotNull(tc, st_find("herp"));
} }
static void test_shipowner_goes_to_next(CuTest * tc) static void test_shipowner_goes_to_next_after_death(CuTest * tc)
{ {
struct region *r; struct region *r;
struct ship *sh; struct ship *sh;
@ -58,6 +58,193 @@ static void test_shipowner_goes_to_next(CuTest * tc)
CuAssertPtrEquals(tc, u2, shipowner(sh)); CuAssertPtrEquals(tc, u2, shipowner(sh));
} }
static void test_shipowner_goes_to_other_after_death(CuTest * tc)
{
struct region *r;
struct ship *sh;
struct unit *u, *u2;
struct faction *f;
const struct ship_type *stype;
const struct race *human;
test_cleanup();
test_create_world();
human = rc_find("human");
CuAssertPtrNotNull(tc, human);
stype = st_find("boat");
CuAssertPtrNotNull(tc, stype);
f = test_create_faction(human);
r = findregion(0, 0);
sh = test_create_ship(r, stype);
CuAssertPtrNotNull(tc, sh);
u2 = test_create_unit(f, r);
u = test_create_unit(f, r);
CuAssertPtrNotNull(tc, u);
u_set_ship(u, sh);
u_set_ship(u2, sh);
CuAssertPtrEquals(tc, u, shipowner(sh));
u->number = 0;
CuAssertPtrEquals(tc, u2, shipowner(sh));
}
static void test_shipowner_goes_to_same_faction_after_death(CuTest * tc)
{
struct region *r;
struct ship *sh;
struct unit *u, *u2, *u3;
struct faction *f1, *f2;
const struct ship_type *stype;
const struct race *human;
test_cleanup();
test_create_world();
human = rc_find("human");
CuAssertPtrNotNull(tc, human);
stype = st_find("boat");
CuAssertPtrNotNull(tc, stype);
f1 = test_create_faction(human);
f2 = test_create_faction(human);
r = findregion(0, 0);
sh = test_create_ship(r, stype);
CuAssertPtrNotNull(tc, sh);
u2 = test_create_unit(f2, r);
u3 = test_create_unit(f1, r);
u = test_create_unit(f1, r);
CuAssertPtrNotNull(tc, u);
u_set_ship(u, sh);
u_set_ship(u2, sh);
u_set_ship(u3, sh);
CuAssertPtrEquals(tc, u, shipowner(sh));
CuAssertTrue(tc, fval(u, UFL_OWNER));
u->number = 0;
CuAssertPtrEquals(tc, u3, shipowner(sh));
CuAssertTrue(tc, !fval(u, UFL_OWNER));
CuAssertTrue(tc, fval(u3, UFL_OWNER));
u3->number = 0;
CuAssertPtrEquals(tc, u2, shipowner(sh));
CuAssertTrue(tc, !fval(u3, UFL_OWNER));
CuAssertTrue(tc, fval(u2, UFL_OWNER));
}
static void test_shipowner_goes_to_next_after_leave(CuTest * tc)
{
struct region *r;
struct ship *sh;
struct unit *u, *u2;
struct faction *f;
const struct ship_type *stype;
const struct race *human;
test_cleanup();
test_create_world();
human = rc_find("human");
CuAssertPtrNotNull(tc, human);
stype = st_find("boat");
CuAssertPtrNotNull(tc, stype);
f = test_create_faction(human);
r = findregion(0, 0);
sh = test_create_ship(r, stype);
CuAssertPtrNotNull(tc, sh);
u = test_create_unit(f, r);
u2 = test_create_unit(f, r);
CuAssertPtrNotNull(tc, u);
u_set_ship(u, sh);
u_set_ship(u2, sh);
CuAssertPtrEquals(tc, u, shipowner(sh));
leave_ship(u);
CuAssertPtrEquals(tc, u2, shipowner(sh));
}
static void test_shipowner_goes_to_other_after_leave(CuTest * tc)
{
struct region *r;
struct ship *sh;
struct unit *u, *u2;
struct faction *f;
const struct ship_type *stype;
const struct race *human;
test_cleanup();
test_create_world();
human = rc_find("human");
CuAssertPtrNotNull(tc, human);
stype = st_find("boat");
CuAssertPtrNotNull(tc, stype);
f = test_create_faction(human);
r = findregion(0, 0);
sh = test_create_ship(r, stype);
CuAssertPtrNotNull(tc, sh);
u2 = test_create_unit(f, r);
u = test_create_unit(f, r);
CuAssertPtrNotNull(tc, u);
u_set_ship(u, sh);
u_set_ship(u2, sh);
CuAssertPtrEquals(tc, u, shipowner(sh));
leave_ship(u);
CuAssertPtrEquals(tc, u2, shipowner(sh));
}
static void test_shipowner_goes_to_same_faction_after_leave(CuTest * tc)
{
struct region *r;
struct ship *sh;
struct unit *u, *u2, *u3;
struct faction *f1, *f2;
const struct ship_type *stype;
const struct race *human;
test_cleanup();
test_create_world();
human = rc_find("human");
CuAssertPtrNotNull(tc, human);
stype = st_find("boat");
CuAssertPtrNotNull(tc, stype);
f1 = test_create_faction(human);
f2 = test_create_faction(human);
r = findregion(0, 0);
sh = test_create_ship(r, stype);
CuAssertPtrNotNull(tc, sh);
u2 = test_create_unit(f2, r);
u3 = test_create_unit(f1, r);
u = test_create_unit(f1, r);
CuAssertPtrNotNull(tc, u);
u_set_ship(u, sh);
u_set_ship(u2, sh);
u_set_ship(u3, sh);
CuAssertPtrEquals(tc, u, shipowner(sh));
leave_ship(u);
CuAssertPtrEquals(tc, u3, shipowner(sh));
leave_ship(u3);
CuAssertPtrEquals(tc, u2, shipowner(sh));
leave_ship(u2);
CuAssertPtrEquals(tc, 0, shipowner(sh));
}
static void test_shipowner_resets_when_dead(CuTest * tc) static void test_shipowner_resets_when_dead(CuTest * tc)
{ {
struct region *r; struct region *r;
@ -95,6 +282,11 @@ CuSuite *get_ship_suite(void)
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_register_ship); SUITE_ADD_TEST(suite, test_register_ship);
SUITE_ADD_TEST(suite, test_shipowner_resets_when_dead); SUITE_ADD_TEST(suite, test_shipowner_resets_when_dead);
SUITE_ADD_TEST(suite, test_shipowner_goes_to_next); SUITE_ADD_TEST(suite, test_shipowner_goes_to_next_after_death);
SUITE_ADD_TEST(suite, test_shipowner_goes_to_other_after_death);
SUITE_ADD_TEST(suite, test_shipowner_goes_to_same_faction_after_death);
SUITE_ADD_TEST(suite, test_shipowner_goes_to_next_after_leave);
SUITE_ADD_TEST(suite, test_shipowner_goes_to_other_after_leave);
SUITE_ADD_TEST(suite, test_shipowner_goes_to_same_faction_after_leave);
return suite; return suite;
} }

View File

@ -807,8 +807,8 @@ void leave_ship(unit * u)
} }
} }
} }
sh->owner = owner;
if (owner) { if (owner) {
sh->owner = owner;
fset(owner, UFL_OWNER); fset(owner, UFL_OWNER);
} }
} }