forked from github/server
more strictly define what it means to be the owner of the show, and when it is transferred.
mostly copied from building_owner. test coverage is a wonderful thing.
This commit is contained in:
parent
0c2531f259
commit
b95f7ec139
|
@ -500,7 +500,6 @@ static building *deleted_buildings;
|
||||||
void remove_building(building ** blist, building * b)
|
void remove_building(building ** blist, building * b)
|
||||||
{
|
{
|
||||||
unit *u;
|
unit *u;
|
||||||
direction_t d;
|
|
||||||
static const struct building_type *bt_caravan, *bt_dam, *bt_tunnel;
|
static const struct building_type *bt_caravan, *bt_dam, *bt_tunnel;
|
||||||
static boolean init = false;
|
static boolean init = false;
|
||||||
|
|
||||||
|
@ -527,15 +526,19 @@ void remove_building(building ** blist, building * b)
|
||||||
* gebaute Straße zur Hälfte vernichtet */
|
* gebaute Straße zur Hälfte vernichtet */
|
||||||
if (b->type == bt_caravan || b->type == bt_dam || b->type == bt_tunnel) {
|
if (b->type == bt_caravan || b->type == bt_dam || b->type == bt_tunnel) {
|
||||||
region *r = b->region;
|
region *r = b->region;
|
||||||
for (d = 0; d != MAXDIRECTIONS; ++d)
|
int d;
|
||||||
if (rroad(r, d) > 0) {
|
for (d = 0; d != MAXDIRECTIONS; ++d) {
|
||||||
rsetroad(r, d, rroad(r, d) / 2);
|
direction_t dir = (direction_t)d;
|
||||||
|
if (rroad(r, dir) > 0) {
|
||||||
|
rsetroad(r, dir, rroad(r, dir) / 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stattdessen nur aus Liste entfernen, aber im Speicher halten. */
|
/* Stattdessen nur aus Liste entfernen, aber im Speicher halten. */
|
||||||
while (*blist && *blist != b)
|
while (*blist && *blist != b) {
|
||||||
blist = &(*blist)->next;
|
blist = &(*blist)->next;
|
||||||
|
}
|
||||||
*blist = b->next;
|
*blist = b->next;
|
||||||
b->region = NULL;
|
b->region = NULL;
|
||||||
b->next = deleted_buildings;
|
b->next = deleted_buildings;
|
||||||
|
@ -630,7 +633,7 @@ void building_set_owner(struct building *b, struct unit * owner)
|
||||||
b->_owner = owner;
|
b->_owner = owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unit *building_owner_ex(const building * bld, const faction * last_owner)
|
static unit *building_owner_ex(const building * bld, const struct faction * last_owner)
|
||||||
{
|
{
|
||||||
unit *u, *heir = 0;
|
unit *u, *heir = 0;
|
||||||
|
|
||||||
|
|
|
@ -291,20 +291,18 @@ void ship_set_owner(ship * sh, unit * u) {
|
||||||
sh->_owner = u;
|
sh->_owner = u;
|
||||||
}
|
}
|
||||||
|
|
||||||
unit *ship_owner(const ship * sh)
|
static unit * ship_owner_ex(const ship * sh, const struct faction * last_owner)
|
||||||
{
|
{
|
||||||
unit *owner = sh->_owner;
|
|
||||||
if (owner && (owner->ship!=sh || owner->number<=0)) {
|
|
||||||
unit *u, *heir = 0;
|
unit *u, *heir = 0;
|
||||||
|
|
||||||
owner->ship = 0;
|
/* Eigentümer tot oder kein Eigentümer vorhanden. Erste lebende Einheit
|
||||||
/* Prüfen ob Eigentümer am leben. */
|
* nehmen. */
|
||||||
for (u = sh->region->units; u; u = u->next) {
|
for (u = sh->region->units; u; u = u->next) {
|
||||||
if (u->ship == sh) {
|
if (u->ship == sh) {
|
||||||
if (u->number > 0) {
|
if (u->number > 0) {
|
||||||
if (u->faction==owner->faction) {
|
if (heir && last_owner && heir->faction!=last_owner && u->faction==last_owner) {
|
||||||
heir = u;
|
heir = u;
|
||||||
break;
|
break; /* we found someone from the same faction who is not dead. let's take this guy */
|
||||||
}
|
}
|
||||||
else if (!heir) {
|
else if (!heir) {
|
||||||
heir = u; /* you'll do in an emergency */
|
heir = u; /* you'll do in an emergency */
|
||||||
|
@ -312,10 +310,21 @@ unit *ship_owner(const ship * sh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
owner = heir;
|
return heir;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ship_update_owner(ship * sh) {
|
||||||
|
unit * owner = sh->_owner;
|
||||||
|
sh->_owner = ship_owner_ex(sh, owner?owner->faction:0);
|
||||||
|
}
|
||||||
|
|
||||||
|
unit *ship_owner(const ship * sh)
|
||||||
|
{
|
||||||
|
unit *owner = sh->_owner;
|
||||||
|
if (!owner || (owner->ship!=sh || owner->number<=0)) {
|
||||||
|
unit * heir = ship_owner_ex(sh, owner?owner->faction:0);
|
||||||
|
return (heir && heir->number>0) ? heir : 0;
|
||||||
}
|
}
|
||||||
/* Eigentümer tot oder kein Eigentümer vorhanden. Erste lebende Einheit
|
|
||||||
* nehmen. */
|
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,8 @@ extern "C" {
|
||||||
extern void damage_ship(struct ship * sh, double percent);
|
extern void damage_ship(struct ship * sh, double percent);
|
||||||
extern void ship_set_owner(struct ship * sh, struct unit * u);
|
extern void ship_set_owner(struct ship * sh, struct unit * u);
|
||||||
extern struct unit *ship_owner(const struct ship *sh);
|
extern struct unit *ship_owner(const struct ship *sh);
|
||||||
|
extern void ship_update_owner(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);
|
||||||
|
|
|
@ -54,7 +54,7 @@ static void test_ship_set_owner(CuTest * tc)
|
||||||
CuAssertPtrEquals(tc, u2, ship_owner(sh));
|
CuAssertPtrEquals(tc, u2, ship_owner(sh));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_shipowner_goes_to_next_after_death(CuTest * tc)
|
static void test_shipowner_goes_to_next_when_empty(CuTest * tc)
|
||||||
{
|
{
|
||||||
struct region *r;
|
struct region *r;
|
||||||
struct ship *sh;
|
struct ship *sh;
|
||||||
|
@ -88,7 +88,7 @@ static void test_shipowner_goes_to_next_after_death(CuTest * tc)
|
||||||
CuAssertPtrEquals(tc, u2, ship_owner(sh));
|
CuAssertPtrEquals(tc, u2, ship_owner(sh));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_shipowner_goes_to_other_after_death(CuTest * tc)
|
static void test_shipowner_goes_to_other_when_empty(CuTest * tc)
|
||||||
{
|
{
|
||||||
struct region *r;
|
struct region *r;
|
||||||
struct ship *sh;
|
struct ship *sh;
|
||||||
|
@ -122,7 +122,7 @@ static void test_shipowner_goes_to_other_after_death(CuTest * tc)
|
||||||
CuAssertPtrEquals(tc, u2, ship_owner(sh));
|
CuAssertPtrEquals(tc, u2, ship_owner(sh));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_shipowner_goes_to_same_faction_after_death(CuTest * tc)
|
static void test_shipowner_goes_to_same_faction_when_empty(CuTest * tc)
|
||||||
{
|
{
|
||||||
struct region *r;
|
struct region *r;
|
||||||
struct ship *sh;
|
struct ship *sh;
|
||||||
|
@ -270,7 +270,7 @@ static void test_shipowner_goes_to_same_faction_after_leave(CuTest * tc)
|
||||||
CuAssertPtrEquals(tc, 0, ship_owner(sh));
|
CuAssertPtrEquals(tc, 0, ship_owner(sh));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_shipowner_resets_when_dead(CuTest * tc)
|
static void test_shipowner_resets_when_empty(CuTest * tc)
|
||||||
{
|
{
|
||||||
struct region *r;
|
struct region *r;
|
||||||
struct ship *sh;
|
struct ship *sh;
|
||||||
|
@ -300,6 +300,49 @@ static void test_shipowner_resets_when_dead(CuTest * tc)
|
||||||
CuAssertPtrEquals(tc, u, ship_owner(sh));
|
CuAssertPtrEquals(tc, u, ship_owner(sh));
|
||||||
u->number = 0;
|
u->number = 0;
|
||||||
CuAssertPtrEquals(tc, 0, ship_owner(sh));
|
CuAssertPtrEquals(tc, 0, ship_owner(sh));
|
||||||
|
u->number = 1;
|
||||||
|
CuAssertPtrEquals(tc, u, ship_owner(sh));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_shipowner_goes_to_empty_unit_after_leave(CuTest * tc)
|
||||||
|
{
|
||||||
|
struct region *r;
|
||||||
|
struct ship *sh;
|
||||||
|
struct unit *u1, *u2, *u3;
|
||||||
|
struct faction *f1;
|
||||||
|
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);
|
||||||
|
r = findregion(0, 0);
|
||||||
|
|
||||||
|
sh = test_create_ship(r, stype);
|
||||||
|
CuAssertPtrNotNull(tc, sh);
|
||||||
|
|
||||||
|
u1 = test_create_unit(f1, r);
|
||||||
|
u2 = test_create_unit(f1, r);
|
||||||
|
u3 = test_create_unit(f1, r);
|
||||||
|
u_set_ship(u1, sh);
|
||||||
|
u_set_ship(u2, sh);
|
||||||
|
u_set_ship(u3, sh);
|
||||||
|
|
||||||
|
CuAssertPtrEquals(tc, u1, ship_owner(sh));
|
||||||
|
u2->number = 0;
|
||||||
|
leave_ship(u1);
|
||||||
|
CuAssertPtrEquals(tc, u3, ship_owner(sh));
|
||||||
|
leave_ship(u3);
|
||||||
|
CuAssertPtrEquals(tc, 0, ship_owner(sh));
|
||||||
|
u2->number = 1;
|
||||||
|
CuAssertPtrEquals(tc, u2, ship_owner(sh));
|
||||||
}
|
}
|
||||||
|
|
||||||
CuSuite *get_ship_suite(void)
|
CuSuite *get_ship_suite(void)
|
||||||
|
@ -307,12 +350,13 @@ 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_ship_set_owner);
|
SUITE_ADD_TEST(suite, test_ship_set_owner);
|
||||||
SUITE_ADD_TEST(suite, test_shipowner_resets_when_dead);
|
SUITE_ADD_TEST(suite, test_shipowner_resets_when_empty);
|
||||||
SUITE_ADD_TEST(suite, test_shipowner_goes_to_next_after_death);
|
SUITE_ADD_TEST(suite, test_shipowner_goes_to_next_when_empty);
|
||||||
SUITE_ADD_TEST(suite, test_shipowner_goes_to_other_after_death);
|
SUITE_ADD_TEST(suite, test_shipowner_goes_to_other_when_empty);
|
||||||
SUITE_ADD_TEST(suite, test_shipowner_goes_to_same_faction_after_death);
|
SUITE_ADD_TEST(suite, test_shipowner_goes_to_same_faction_when_empty);
|
||||||
SUITE_ADD_TEST(suite, test_shipowner_goes_to_next_after_leave);
|
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_other_after_leave);
|
||||||
SUITE_ADD_TEST(suite, test_shipowner_goes_to_same_faction_after_leave);
|
SUITE_ADD_TEST(suite, test_shipowner_goes_to_same_faction_after_leave);
|
||||||
|
SUITE_ADD_TEST(suite, test_shipowner_goes_to_empty_unit_after_leave);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -798,6 +798,7 @@ void leave_ship(unit * u)
|
||||||
|
|
||||||
u->ship = 0;
|
u->ship = 0;
|
||||||
if (sh->_owner==u) {
|
if (sh->_owner==u) {
|
||||||
|
ship_update_owner(sh);
|
||||||
sh->_owner = ship_owner(sh);
|
sh->_owner = ship_owner(sh);
|
||||||
}
|
}
|
||||||
set_leftship(u, sh);
|
set_leftship(u, sh);
|
||||||
|
|
Loading…
Reference in New Issue