From ff33af3c6577775a1e0369bc8e543041da4b30cf Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 17 May 2012 15:23:15 -0700 Subject: [PATCH] ship and building owners encapsulated in accessors tests added --- src/bindings/bind_unit.c | 24 +-- src/gamecode/economy.c | 4 +- src/gamecode/laws_test.c | 5 +- src/gamecode/market_test.c | 3 +- src/gamecode/randenc.c | 3 +- src/kernel.vcxproj | 1 + src/kernel.vcxproj.filters | 3 + src/kernel/battle_test.c | 9 +- src/kernel/build.c | 24 +-- src/kernel/building.c | 58 +++---- src/kernel/building.h | 1 + src/kernel/building_test.c | 324 +++++++++++++++++++++++++++++++++++++ src/kernel/ship.c | 26 +-- src/kernel/ship.h | 4 +- src/kernel/ship_test.c | 5 +- src/kernel/unit.c | 43 ++--- src/tests.c | 2 + 17 files changed, 425 insertions(+), 114 deletions(-) create mode 100644 src/kernel/building_test.c diff --git a/src/bindings/bind_unit.c b/src/bindings/bind_unit.c index 139740237..3b0198d2c 100644 --- a/src/bindings/bind_unit.c +++ b/src/bindings/bind_unit.c @@ -614,20 +614,20 @@ static int tolua_unit_get_building(lua_State * L) return 1; } -static void unit_setbuilding(unit * u, building * b) -{ - leave(u, true); - if (b && u->region != b->region) { - move_unit(u, b->region, NULL); - } - u->building = b; -} - static int tolua_unit_set_building(lua_State * L) { - unit *self = (unit *) tolua_tousertype(L, 1, 0); - if (self->faction) { - unit_setbuilding(self, (building *) tolua_tousertype(L, 2, 0)); + unit *u = (unit *) tolua_tousertype(L, 1, 0); + if (u->faction) { + building * b = (building *) tolua_tousertype(L, 2, 0); + if (b!=u->building) { + leave(u, true); + if (b) { + if (u->region != b->region) { + move_unit(u, b->region, NULL); + } + u_set_building(u, b); + } + } } return 0; } diff --git a/src/gamecode/economy.c b/src/gamecode/economy.c index 32c7e1182..6b99573a8 100644 --- a/src/gamecode/economy.c +++ b/src/gamecode/economy.c @@ -639,10 +639,8 @@ static void give_control(unit * u, unit * u2) } } if (u->ship) { - u->ship->owner = u2; + ship_set_owner(u->ship, u2); } - freset(u, UFL_OWNER); - fset(u2, UFL_OWNER); } int give_control_cmd(unit * u, order * ord) diff --git a/src/gamecode/laws_test.c b/src/gamecode/laws_test.c index 02af945dc..e8fbd1895 100644 --- a/src/gamecode/laws_test.c +++ b/src/gamecode/laws_test.c @@ -53,7 +53,7 @@ static void test_rename_building(CuTest * tc) b = new_building(btype, r, default_locale); f = test_create_faction(rc_find("human")); u = test_create_unit(f, r); - u->building = b; + u_set_building(u, b); fset(u, UFL_OWNER); rename_building(u, NULL, b, "Villa Nagel"); @@ -77,8 +77,7 @@ static void test_rename_building_twice(CuTest * tc) b = new_building(btype, r, default_locale); f = test_create_faction(rc_find("human")); u = test_create_unit(f, r); - u->building = b; - fset(u, UFL_OWNER); + u_set_building(u, b); rename_building(u, NULL, b, "Villa Nagel"); CuAssertStrEquals(tc, "Villa Nagel", b->name); diff --git a/src/gamecode/market_test.c b/src/gamecode/market_test.c index d60c71982..c60876995 100644 --- a/src/gamecode/market_test.c +++ b/src/gamecode/market_test.c @@ -61,8 +61,7 @@ static void market_curse(CuTest * tc) f = addfaction("nobody@eressea.de", NULL, rc, default_locale, 0); u = create_unit(r, f, 1, f->race, 0, 0, 0); - u->building = b; - u->flags |= UFL_OWNER; + u_set_building(u, b); do_markets(); diff --git a/src/gamecode/randenc.c b/src/gamecode/randenc.c index a84f792b5..b0f422f0b 100644 --- a/src/gamecode/randenc.c +++ b/src/gamecode/randenc.c @@ -911,8 +911,9 @@ static void move_iceberg(region * r) while (rc->units) { building *b = rc->units->building; u = rc->units; + u->building = 0; /* prevent leaving in move_unit */ move_unit(rc->units, r, NULL); - u->building = b; /* move_unit macht ein leave() */ + u_set_building(u, b); /* undo leave-prevention */ } /* Beschädigte Schiffe können sinken */ diff --git a/src/kernel.vcxproj b/src/kernel.vcxproj index c998520ac..240cc1a6d 100644 --- a/src/kernel.vcxproj +++ b/src/kernel.vcxproj @@ -94,6 +94,7 @@ + diff --git a/src/kernel.vcxproj.filters b/src/kernel.vcxproj.filters index 0239a0193..8c6cdcdf1 100644 --- a/src/kernel.vcxproj.filters +++ b/src/kernel.vcxproj.filters @@ -304,6 +304,9 @@ kernel + + kernel + diff --git a/src/kernel/battle_test.c b/src/kernel/battle_test.c index ceac668c7..c86a7f0b8 100644 --- a/src/kernel/battle_test.c +++ b/src/kernel/battle_test.c @@ -77,7 +77,7 @@ static void test_defenders_get_building_bonus(CuTest * tc) du = test_create_unit(test_create_faction(rc_find("human")), r); au = test_create_unit(test_create_faction(rc_find("human")), r); - du->building = bld; + u_set_building(du, bld); b = make_battle(r); ds = make_side(b, du->faction, 0, 0, 0); @@ -119,8 +119,7 @@ static void test_attackers_get_no_building_bonus(CuTest * tc) bld->size = 10; au = test_create_unit(test_create_faction(rc_find("human")), r); - au->building = bld; - + u_set_building(au, bld); b = make_battle(r); as = make_side(b, au->faction, 0, 0, 0); @@ -151,9 +150,9 @@ static void test_building_bonus_respects_size(CuTest * tc) f = test_create_faction(rc_find("human")); au = test_create_unit(f, r); scale_number(au, 9); - au->building = bld; + u_set_building(au, bld); du = test_create_unit(f, r); - du->building = bld; + u_set_building(du, bld); scale_number(du, 2); b = make_battle(r); diff --git a/src/kernel/build.c b/src/kernel/build.c index a3ab10b8c..fcda6483f 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -360,14 +360,13 @@ int destroy_cmd(unit * u, struct order *ord) return 0; } - if (!fval(u, UFL_OWNER)) { - cmistake(u, ord, 138, MSG_PRODUCE); - return 0; - } - if (u->building) { building *b = u->building; + if (u!=building_owner(b)) { + cmistake(u, ord, 138, MSG_PRODUCE); + return 0; + } if (fval(b->type, BTF_INDESTRUCTIBLE)) { cmistake(u, ord, 138, MSG_PRODUCE); return 0; @@ -377,8 +376,8 @@ int destroy_cmd(unit * u, struct order *ord) /* all units leave the building */ for (u2 = r->units; u2; u2 = u2->next) { if (u2->building == b) { - u2->building = 0; freset(u2, UFL_OWNER); + leave_building(u2); } } ADDMSG(&u->faction->msgs, msg_message("destroy", "building unit", b, u)); @@ -393,6 +392,10 @@ int destroy_cmd(unit * u, struct order *ord) } else if (u->ship) { sh = u->ship; + if (u!=ship_owner(sh)) { + cmistake(u, ord, 138, MSG_PRODUCE); + return 0; + } if (fval(r->terrain, SEA_REGION)) { cmistake(u, ord, 14, MSG_EVENT); return 0; @@ -970,8 +973,8 @@ build_building(unit * u, const building_type * btype, int want, order * ord) /* Die Einheit befindet sich automatisch im Inneren der neuen Burg. */ if (leave(u, false)) { - u->building = b; - fset(u, UFL_OWNER); + u_set_building(u, b); + assert(building_owner(b)==u); } #ifdef WDW_PYRAMID if (b->type == bt_find("pyramid") && f_get_alliance(u->faction) != NULL) { @@ -1297,11 +1300,8 @@ static boolean enter_building(unit * u, order * ord, int id, boolean report) } if (leave(u, false)) { - if (building_owner(b) == 0) { - fset(u, UFL_OWNER); - } fset(u, UFL_ENTER); - u->building = b; + u_set_building(u, b); return true; } return false; diff --git a/src/kernel/building.c b/src/kernel/building.c index f36636047..1295d47b1 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -145,8 +145,9 @@ building_type *bt_find(const char *name) void bt_register(building_type * type) { - if (type->init) + if (type->init) { type->init(type); + } ql_push(&buildingtypes, (void *)type); } @@ -616,43 +617,44 @@ const char *buildingname(const building * b) void building_set_owner(struct building *b, struct unit * owner) { - unit * u; - assert(b && owner && owner->building==b); - - for (u = b->region->units; u; u = u->next) { - if (u->building == b) { - freset(owner, UFL_OWNER); - } + if (b->_owner && b->_owner!=owner) { + freset(b->_owner, UFL_OWNER); } + b->_owner = owner; fset(owner, UFL_OWNER); } -unit *building_owner(const building * b) +unit *building_owner(const building * bld) { - unit *u = NULL; - unit *first = NULL; - region *r = b->region; - /* Prüfen ob Eigentümer am leben. */ + unit *owner = bld->_owner; + if (owner && (owner->building!=bld || owner->number<=0)) { + unit *u, *heir = 0; - for (u = r->units; u; u = u->next) { - if (u->building == b) { - if (!first && u->number > 0) - first = u; - if (fval(u, UFL_OWNER) && u->number > 0) - return u; - if (u->number == 0) + /* Eigentümer tot oder kein Eigentümer vorhanden. Erste lebende Einheit + * nehmen. */ + for (u = bld->region->units; u; u = u->next) { + if (u->building == bld) { + if (u->number > 0) { + if (u->faction==owner->faction) { + heir = u; + break; + } + else if (!heir) { + heir = u; /* you'll do in an emergency */ + } + } freset(u, UFL_OWNER); + } + } + freset(owner, UFL_OWNER); + owner->building = 0; + owner = heir; + if (owner) { + fset(owner, UFL_OWNER); } } - - /* Eigentümer tot oder kein Eigentümer vorhanden. Erste lebende Einheit - * nehmen. */ - - if (first) { - fset(first, UFL_OWNER); - } - return first; + return owner; } const char *building_getname(const building * self) diff --git a/src/kernel/building.h b/src/kernel/building.h index 7fdbfaf1e..bacf91d93 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -104,6 +104,7 @@ extern "C" { const struct building_type *type; struct region *region; + struct unit *_owner; /* you should always use building_owner(), never this naked pointer */ char *name; char *display; struct attrib *attribs; diff --git a/src/kernel/building_test.c b/src/kernel/building_test.c new file mode 100644 index 000000000..0e09aa1c8 --- /dev/null +++ b/src/kernel/building_test.c @@ -0,0 +1,324 @@ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static void test_register_building(CuTest * tc) +{ + building_type *btype; + + test_cleanup(); + + btype = (building_type *)calloc(sizeof(building_type), 1); + btype->_name = strdup("herp"); + bt_register(btype); + + CuAssertPtrNotNull(tc, bt_find("herp")); +} + +static void test_building_set_owner(CuTest * tc) +{ + struct region *r; + struct building *bld; + struct unit *u1, *u2; + struct faction *f; + const struct building_type *btype; + const struct race *human; + + test_cleanup(); + test_create_world(); + + human = rc_find("human"); + btype = bt_find("castle"); + f = test_create_faction(human); + r = findregion(0, 0); + + bld = test_create_building(r, btype); + u1 = test_create_unit(f, r); + u_set_building(u1, bld); + CuAssertPtrEquals(tc, u1, building_owner(bld)); + + u2 = test_create_unit(f, r); + u_set_building(u2, bld); + CuAssertPtrEquals(tc, u1, building_owner(bld)); + building_set_owner(bld, u2); + CuAssertPtrEquals(tc, u2, building_owner(bld)); +} + +static void test_buildingowner_goes_to_next_after_death(CuTest * tc) +{ + struct region *r; + struct building *bld; + struct unit *u, *u2; + struct faction *f; + const struct building_type *btype; + const struct race *human; + + test_cleanup(); + test_create_world(); + + human = rc_find("human"); + CuAssertPtrNotNull(tc, human); + + btype = bt_find("castle"); + CuAssertPtrNotNull(tc, btype); + + f = test_create_faction(human); + r = findregion(0, 0); + + bld = test_create_building(r, btype); + CuAssertPtrNotNull(tc, bld); + + u = test_create_unit(f, r); + u2 = test_create_unit(f, r); + CuAssertPtrNotNull(tc, u); + u_set_building(u, bld); + u_set_building(u2, bld); + CuAssertPtrEquals(tc, u, building_owner(bld)); + u->number = 0; + CuAssertPtrEquals(tc, u2, building_owner(bld)); +} + +static void test_buildingowner_goes_to_other_after_death(CuTest * tc) +{ + struct region *r; + struct building *bld; + struct unit *u, *u2; + struct faction *f; + const struct building_type *btype; + const struct race *human; + + test_cleanup(); + test_create_world(); + + human = rc_find("human"); + CuAssertPtrNotNull(tc, human); + + btype = bt_find("castle"); + CuAssertPtrNotNull(tc, btype); + + f = test_create_faction(human); + r = findregion(0, 0); + + bld = test_create_building(r, btype); + CuAssertPtrNotNull(tc, bld); + + u2 = test_create_unit(f, r); + u = test_create_unit(f, r); + CuAssertPtrNotNull(tc, u); + u_set_building(u, bld); + CuAssertPtrEquals(tc, u, building_owner(bld)); + u_set_building(u2, bld); + CuAssertPtrEquals(tc, u, building_owner(bld)); + u->number = 0; + CuAssertPtrEquals(tc, u2, building_owner(bld)); +} + +static void test_buildingowner_goes_to_same_faction_after_death(CuTest * tc) +{ + struct region *r; + struct building *bld; + struct unit *u, *u2, *u3; + struct faction *f1, *f2; + const struct building_type *btype; + const struct race *human; + + test_cleanup(); + test_create_world(); + + human = rc_find("human"); + CuAssertPtrNotNull(tc, human); + + btype = bt_find("castle"); + CuAssertPtrNotNull(tc, btype); + + f1 = test_create_faction(human); + f2 = test_create_faction(human); + r = findregion(0, 0); + + bld = test_create_building(r, btype); + CuAssertPtrNotNull(tc, bld); + + u2 = test_create_unit(f2, r); + u3 = test_create_unit(f1, r); + u = test_create_unit(f1, r); + CuAssertPtrNotNull(tc, u); + u_set_building(u, bld); + u_set_building(u2, bld); + u_set_building(u3, bld); + CuAssertPtrEquals(tc, u, building_owner(bld)); + CuAssertTrue(tc, fval(u, UFL_OWNER)); + u->number = 0; + CuAssertPtrEquals(tc, u3, building_owner(bld)); + CuAssertTrue(tc, !fval(u, UFL_OWNER)); + CuAssertTrue(tc, fval(u3, UFL_OWNER)); + u3->number = 0; + CuAssertPtrEquals(tc, u2, building_owner(bld)); + CuAssertTrue(tc, !fval(u3, UFL_OWNER)); + CuAssertTrue(tc, fval(u2, UFL_OWNER)); +} + +static void test_buildingowner_goes_to_next_after_leave(CuTest * tc) +{ + struct region *r; + struct building *bld; + struct unit *u, *u2; + struct faction *f; + const struct building_type *btype; + const struct race *human; + + test_cleanup(); + test_create_world(); + + human = rc_find("human"); + CuAssertPtrNotNull(tc, human); + + btype = bt_find("castle"); + CuAssertPtrNotNull(tc, btype); + + f = test_create_faction(human); + r = findregion(0, 0); + + bld = test_create_building(r, btype); + CuAssertPtrNotNull(tc, bld); + + u = test_create_unit(f, r); + u2 = test_create_unit(f, r); + CuAssertPtrNotNull(tc, u); + u_set_building(u, bld); + u_set_building(u2, bld); + CuAssertPtrEquals(tc, u, building_owner(bld)); + leave_building(u); + CuAssertPtrEquals(tc, u2, building_owner(bld)); +} + +static void test_buildingowner_goes_to_other_after_leave(CuTest * tc) +{ + struct region *r; + struct building *bld; + struct unit *u, *u2; + struct faction *f; + const struct building_type *btype; + const struct race *human; + + test_cleanup(); + test_create_world(); + + human = rc_find("human"); + CuAssertPtrNotNull(tc, human); + + btype = bt_find("castle"); + CuAssertPtrNotNull(tc, btype); + + f = test_create_faction(human); + r = findregion(0, 0); + + bld = test_create_building(r, btype); + CuAssertPtrNotNull(tc, bld); + + u2 = test_create_unit(f, r); + u = test_create_unit(f, r); + CuAssertPtrNotNull(tc, u); + u_set_building(u, bld); + u_set_building(u2, bld); + CuAssertPtrEquals(tc, u, building_owner(bld)); + leave_building(u); + CuAssertPtrEquals(tc, u2, building_owner(bld)); +} + +static void test_buildingowner_goes_to_same_faction_after_leave(CuTest * tc) +{ + struct region *r; + struct building *bld; + struct unit *u, *u2, *u3; + struct faction *f1, *f2; + const struct building_type *btype; + const struct race *human; + + test_cleanup(); + test_create_world(); + + human = rc_find("human"); + CuAssertPtrNotNull(tc, human); + + btype = bt_find("castle"); + CuAssertPtrNotNull(tc, btype); + + f1 = test_create_faction(human); + f2 = test_create_faction(human); + r = findregion(0, 0); + + bld = test_create_building(r, btype); + CuAssertPtrNotNull(tc, bld); + + u2 = test_create_unit(f2, r); + u3 = test_create_unit(f1, r); + u = test_create_unit(f1, r); + CuAssertPtrNotNull(tc, u); + u_set_building(u, bld); + u_set_building(u2, bld); + u_set_building(u3, bld); + CuAssertPtrEquals(tc, u, building_owner(bld)); + leave_building(u); + CuAssertPtrEquals(tc, u3, building_owner(bld)); + leave_building(u3); + CuAssertPtrEquals(tc, u2, building_owner(bld)); + leave_building(u2); + CuAssertPtrEquals(tc, 0, building_owner(bld)); +} + +static void test_buildingowner_resets_when_dead(CuTest * tc) +{ + struct region *r; + struct building *bld; + struct unit *u; + struct faction *f; + const struct building_type *btype; + const struct race *human; + + test_cleanup(); + test_create_world(); + + human = rc_find("human"); + CuAssertPtrNotNull(tc, human); + + btype = bt_find("castle"); + CuAssertPtrNotNull(tc, btype); + + f = test_create_faction(human); + r = findregion(0, 0); + + bld = test_create_building(r, btype); + CuAssertPtrNotNull(tc, bld); + + u = test_create_unit(f, r); + CuAssertPtrNotNull(tc, u); + u_set_building(u, bld); + CuAssertPtrEquals(tc, u, building_owner(bld)); + u->number = 0; + CuAssertPtrEquals(tc, 0, building_owner(bld)); +} + +CuSuite *get_building_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_register_building); + SUITE_ADD_TEST(suite, test_building_set_owner); + SUITE_ADD_TEST(suite, test_buildingowner_resets_when_dead); + SUITE_ADD_TEST(suite, test_buildingowner_goes_to_next_after_death); + SUITE_ADD_TEST(suite, test_buildingowner_goes_to_other_after_death); + SUITE_ADD_TEST(suite, test_buildingowner_goes_to_same_faction_after_death); + SUITE_ADD_TEST(suite, test_buildingowner_goes_to_next_after_leave); + SUITE_ADD_TEST(suite, test_buildingowner_goes_to_other_after_leave); + SUITE_ADD_TEST(suite, test_buildingowner_goes_to_same_faction_after_leave); + return suite; +} diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 966074a27..2d15bb52c 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -278,39 +278,39 @@ void getshipweight(const ship * sh, int *sweight, int *scabins) void ship_set_owner(ship * sh, unit * u) { assert(u->ship==sh); - if (sh->owner && sh->owner!=u) { - freset(sh->owner, UFL_OWNER); + if (sh->_owner && sh->_owner!=u) { + freset(sh->_owner, UFL_OWNER); } - sh->owner = u; + sh->_owner = u; fset(u, UFL_OWNER); } -unit *ship_owner(ship * sh) +unit *ship_owner(const ship * sh) { - unit *owner = sh->owner; - if (owner && owner->number<=0) { - unit *u, *first = NULL; + unit *owner = sh->_owner; + if (owner && (owner->ship!=sh || owner->number<=0)) { + unit *u, *heir = 0; owner->ship = 0; - freset(owner, UFL_OWNER); /* Prüfen ob Eigentümer am leben. */ for (u = sh->region->units; u; u = u->next) { if (u->ship == sh) { if (u->number > 0) { if (u->faction==owner->faction) { - first = u; + heir = u; break; } - else if (!first) { - first = u; /* you'll do in an emergency */ + else if (!heir) { + heir = u; /* you'll do in an emergency */ } } + freset(u, UFL_OWNER); } } - owner = first; + freset(owner, UFL_OWNER); + owner = heir; if (owner) { fset(owner, UFL_OWNER); - sh->owner = owner; } } /* Eigentümer tot oder kein Eigentümer vorhanden. Erste lebende Einheit diff --git a/src/kernel/ship.h b/src/kernel/ship.h index aedbff63c..b4e95a302 100644 --- a/src/kernel/ship.h +++ b/src/kernel/ship.h @@ -81,7 +81,7 @@ extern "C" { typedef struct ship { struct ship *next; struct ship *nexthash; - struct unit * owner; + struct unit * _owner; /* never use directly, always use ship_owner() */ int no; struct region *region; char *name; @@ -96,7 +96,7 @@ extern "C" { extern void damage_ship(struct ship * sh, double percent); extern void ship_set_owner(struct ship * sh, struct unit * u); - extern struct unit *ship_owner(struct ship *sh); + extern struct unit *ship_owner(const struct ship *sh); extern const char *shipname(const struct ship *self); extern int shipcapacity(const struct ship *sh); extern void getshipweight(const struct ship *sh, int *weight, int *cabins); diff --git a/src/kernel/ship_test.c b/src/kernel/ship_test.c index 9eb6641a3..8e69a6bd4 100644 --- a/src/kernel/ship_test.c +++ b/src/kernel/ship_test.c @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -43,8 +44,10 @@ static void test_ship_set_owner(CuTest * tc) sh = test_create_ship(r, stype); u1 = test_create_unit(f, r); - u2 = test_create_unit(f, r); u_set_ship(u1, sh); + CuAssertPtrEquals(tc, u1, ship_owner(sh)); + + u2 = test_create_unit(f, r); u_set_ship(u2, sh); CuAssertPtrEquals(tc, u1, ship_owner(sh)); ship_set_owner(sh, u2); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 07f80c410..3b1fdcf3b 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -778,17 +778,17 @@ void u_set_building(unit * u, building * b) { assert(b && !u->building); /* you must leave first */ u->building = b; + if (b && !b->_owner) { + building_set_owner(b, u); + } } void u_set_ship(unit * u, ship * sh) { assert(!u->ship); /* you must leave_ship */ - if (sh) { - u->ship = sh; - if (!sh->owner) { - sh->owner = u; - fset(u, UFL_OWNER); - } + u->ship = sh; + if (sh && !sh->_owner) { + ship_set_owner(sh, u); } } @@ -798,37 +798,14 @@ void leave_ship(unit * u) if (!sh) return; u->ship = 0; set_leftship(u, sh); - - if (fval(u, UFL_OWNER)) { - unit *u2, *owner = NULL; - freset(u, UFL_OWNER); - - for (u2 = u->region->units; u2; u2 = u2->next) { - if (u2->ship == sh) { - if (u2->faction == u->faction) { - owner = u2; - break; - } else if (!owner) { - owner = u2; - } - } - } - sh->owner = owner; - if (owner) { - fset(owner, UFL_OWNER); - } - } - assert(sh->owner!=u); } void leave_building(unit * u) { struct building *b = u->building; - if (!b) - return; - u->building = NULL; - if (fval(u, UFL_OWNER)) { + u->building = NULL; + if (b && fval(u, UFL_OWNER)) { unit *u2, *owner = NULL; freset(u, UFL_OWNER); @@ -1521,7 +1498,9 @@ unit *create_unit(region * r, faction * f, int number, const struct race *urace, /* erbt Gebäude/Schiff */ if (creator->region == r) { - u->building = creator->building; + if (creator->building) { + u_set_building(u, creator->building); + } if (creator->ship && fval(u->race, RCF_CANSAIL)) { u_set_ship(u, creator->ship); } diff --git a/src/tests.c b/src/tests.c index e55f31825..5219f9983 100644 --- a/src/tests.c +++ b/src/tests.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,7 @@ int RunAllTests(void) CuSuiteAddSuite(suite, get_move_suite()); CuSuiteAddSuite(suite, get_reports_suite()); CuSuiteAddSuite(suite, get_ship_suite()); + CuSuiteAddSuite(suite, get_building_suite()); CuSuiteAddSuite(suite, get_spell_suite()); CuSuiteAddSuite(suite, get_laws_suite()); CuSuiteAddSuite(suite, get_battle_suite());