From d12fe2dbed54221983cbe62fad4638021a275d0c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 17 May 2012 00:13:30 -0700 Subject: [PATCH] begin making shipowner use ship->owner. fix a broken test caused by locale_string returning null. --- src/bindings/bind_ship.c | 2 +- src/bindings/bind_unit.c | 2 +- src/gamecode/creport.c | 2 +- src/gamecode/give.c | 4 +-- src/gamecode/laws.c | 74 ++++++-------------------------------- src/gamecode/laws_test.c | 12 +++---- src/gamecode/report.c | 2 +- src/gamecode/spy.c | 3 +- src/kernel.vcxproj | 1 + src/kernel.vcxproj.filters | 3 ++ src/kernel/build.c | 48 +++++++++++-------------- src/kernel/build.h | 4 +-- src/kernel/building.c | 2 +- src/kernel/building.h | 2 +- src/kernel/curse.c | 2 +- src/kernel/curse.h | 7 ++-- src/kernel/magic.h | 2 +- src/kernel/move.c | 4 +-- src/kernel/move_test.c | 5 ++- src/kernel/objtypes.h | 4 +-- src/kernel/reports.c | 2 +- src/kernel/reports.h | 3 +- src/kernel/save.c | 9 +++-- src/kernel/ship.c | 15 +++++--- src/kernel/ship.h | 5 +-- src/kernel/ship_test.c | 63 ++++++++++++++++++++++++++++++++ src/kernel/types.h | 1 - src/kernel/unit.c | 33 ++++++++++++----- src/kernel/unit.h | 5 +-- src/kernel/xmlreader.c | 2 +- src/modules/xecmd.c | 7 ++-- src/tests.c | 11 ++++++ src/tests.h | 2 +- 33 files changed, 193 insertions(+), 150 deletions(-) create mode 100644 src/kernel/ship_test.c diff --git a/src/bindings/bind_ship.c b/src/bindings/bind_ship.c index a72dec778..d5319dfe0 100644 --- a/src/bindings/bind_ship.c +++ b/src/bindings/bind_ship.c @@ -109,7 +109,7 @@ static int tolua_ship_create(lua_State * L) if (sname) { const ship_type *stype = st_find(sname); if (stype) { - ship *sh = new_ship(stype, default_locale, r); + ship *sh = new_ship(stype, r, default_locale); sh->size = stype->construction->maxsize; tolua_pushusertype(L, (void *)sh, TOLUA_CAST "ship"); return 1; diff --git a/src/bindings/bind_unit.c b/src/bindings/bind_unit.c index 1760d414a..139740237 100644 --- a/src/bindings/bind_unit.c +++ b/src/bindings/bind_unit.c @@ -645,7 +645,7 @@ static void unit_setship(unit * u, ship * s) if (s && u->region != s->region) { move_unit(u, s->region, NULL); } - u->ship = s; + u_set_ship(u, s); } static int tolua_unit_set_ship(lua_State * L) diff --git a/src/gamecode/creport.c b/src/gamecode/creport.c index 1e50f99a4..9d67f2def 100644 --- a/src/gamecode/creport.c +++ b/src/gamecode/creport.c @@ -173,7 +173,7 @@ static void print_items(FILE * F, item * items, const struct locale *lang) } static void -cr_output_curses(FILE * F, const faction * viewer, const void *obj, typ_t typ) +cr_output_curses(FILE * F, const faction * viewer, const void *obj, objtype_t typ) { boolean header = false; attrib *a = NULL; diff --git a/src/gamecode/give.c b/src/gamecode/give.c index bee31ab33..755b97c26 100644 --- a/src/gamecode/give.c +++ b/src/gamecode/give.c @@ -311,9 +311,9 @@ void give_men(int n, unit * u, unit * u2, struct order *ord) /* Einheiten von Schiffen können nicht NACH in von * Nicht-alliierten bewachten Regionen ausführen */ sh = leftship(u); - if (sh) + if (sh) { set_leftship(u2, sh); - + } transfermen(u, u2, n); if (u->faction != u2->faction) { u2->faction->newbies += n; diff --git a/src/gamecode/laws.c b/src/gamecode/laws.c index 47205e098..ee13b8257 100644 --- a/src/gamecode/laws.c +++ b/src/gamecode/laws.c @@ -1617,11 +1617,14 @@ static int display_cmd(unit * u, struct order *ord) boolean renamed_building(const building * b) { const struct locale *lang = locales; + size_t len = strlen(b->name); for (; lang; lang = nextlocale(lang)) { const char *bdname = LOC(lang, b->type->_name); - size_t bdlen = strlen(bdname); - if (strlen(b->name) >= bdlen && strncmp(b->name, bdname, bdlen) == 0) { - return false; + if (bdname) { + size_t bdlen = strlen(bdname); + if (len >= bdlen && strncmp(b->name, bdname, bdlen) == 0) { + return false; + } } } return true; @@ -2926,64 +2929,6 @@ static void reorder(void) } } -#if 0 -/* Aus Gebäude weisen, VERBANNE */ -static void evict(void) -{ - region *r; - strlist *S; - unit *u; - - for (r = regions; r; r = r->next) { - for (u = r->units; u; u = u->next) { - for (S = u->orders; S; S = S->next) - if (get_keyword(ord) == K_EVICT) { - int id; - unit *u2; - /* Nur der Kapitän bzw Burgherr kann jemanden rausschmeißen */ - if (!fval(u, UFL_OWNER)) { - /* Die Einheit ist nicht der Eigentümer */ - cmistake(u, ord, 49, MSG_EVENT); - continue; - } - init_tokens(ord); - skip_token(); - id = getid(); - u2 = findunit(id); - - if (u2 == NULL) { - /* Einheit nicht gefunden */ - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, - "feedback_unit_not_found", "")); - continue; - } - - if (u->building) { - /* in der selben Burg? */ - if (u->building != u2->building) { - /* nicht in Burg */ - cmistake(u, ord, 33, MSG_EVENT); - continue; - } - leave_building(u2); - /* meldung an beide */ - } - - if (u->ship) { - if (u->ship != u2->ship) { - /* nicht an Bord */ - cmistake(u, ord, 32, MSG_EVENT); - continue; - } - leave_ship(u2); - /* meldung an beide */ - } - } - } - } -} -#endif - static int renumber_cmd(unit * u, order * ord) { const char *s; @@ -3422,8 +3367,9 @@ static void new_units(void) a_add(&u2->attribs, a_new(&at_alias))->data.i = alias; sh = leftship(u); - if (sh) + if (sh) { set_leftship(u2, sh); + } setstatus(u2, u->status); ordp = &makeord->next; @@ -4109,12 +4055,12 @@ void process(void) static void enter_1(region * r) { - do_misc(r, false); + do_misc(r, 0); } static void enter_2(region * r) { - do_misc(r, true); + do_misc(r, 1); } static void maintain_buildings_1(region * r) diff --git a/src/gamecode/laws_test.c b/src/gamecode/laws_test.c index 367a9c629..02af945dc 100644 --- a/src/gamecode/laws_test.c +++ b/src/gamecode/laws_test.c @@ -100,8 +100,8 @@ static void test_fishing_feeds_2_people(CuTest * tc) CuAssertStrEquals(tc, "ocean", r->terrain->_name); /* test_create_world needs coverage */ f = test_create_faction(rc_find("human")); u = test_create_unit(f, r); - sh = new_ship(st_find("boat"), NULL, r); - u->ship = sh; + sh = new_ship(st_find("boat"), r, 0); + u_set_ship(u, sh); i_change(&u->items, it_find("money"), 42); scale_number(u, 1); @@ -140,8 +140,8 @@ static void test_fishing_does_not_give_goblins_money(CuTest * tc) CuAssertStrEquals(tc, "ocean", r->terrain->_name); /* test_create_world needs coverage */ f = test_create_faction(rc_find("human")); u = test_create_unit(f, r); - sh = new_ship(st_find("boat"), NULL, r); - u->ship = sh; + sh = new_ship(st_find("boat"), r, 0); + u_set_ship(u, sh); i_change(&u->items, it_find("money"), 42); global.functions.maintenance = not_so_hungry; @@ -165,8 +165,8 @@ static void test_fishing_gets_reset(CuTest * tc) CuAssertStrEquals(tc, "ocean", r->terrain->_name); /* test_create_world needs coverage */ f = test_create_faction(rc_find("human")); u = test_create_unit(f, r); - sh = new_ship(st_find("boat"), NULL, r); - u->ship = sh; + sh = new_ship(st_find("boat"), r, 0); + u_set_ship(u, sh); i_change(&u->items, it_find("money"), 42); scale_number(u, 1); diff --git a/src/gamecode/report.c b/src/gamecode/report.c index e0ec3cd34..b1a58770c 100644 --- a/src/gamecode/report.c +++ b/src/gamecode/report.c @@ -576,7 +576,7 @@ int hat_in_region(item_t it, region * r, faction * f) } static void -nr_curses(FILE * F, const faction * viewer, const void *obj, typ_t typ, +nr_curses(FILE * F, const faction * viewer, const void *obj, objtype_t typ, int indent) { attrib *a = NULL; diff --git a/src/gamecode/spy.c b/src/gamecode/spy.c index 8341825a0..d8e608b59 100644 --- a/src/gamecode/spy.c +++ b/src/gamecode/spy.c @@ -443,8 +443,7 @@ static void sink_ship(region * r, ship * sh, const char *name, unit * saboteur) } else { msg = msg_message("sink_saved_msg", "region unit", safety, u); } - set_leftship(u, u->ship); - u->ship = 0; + leave_ship(u); if (r != safety) { setguard(u, GUARD_NONE); } diff --git a/src/kernel.vcxproj b/src/kernel.vcxproj index 01d47c948..97cda449a 100644 --- a/src/kernel.vcxproj +++ b/src/kernel.vcxproj @@ -119,6 +119,7 @@ + diff --git a/src/kernel.vcxproj.filters b/src/kernel.vcxproj.filters index 5d877a81e..9e2d9b3af 100644 --- a/src/kernel.vcxproj.filters +++ b/src/kernel.vcxproj.filters @@ -298,6 +298,9 @@ kernel + + kernel + diff --git a/src/kernel/build.c b/src/kernel/build.c index c7b3ef7dc..d2ca8c155 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -112,29 +112,27 @@ static int slipthru(const region * r, const unit * u, const building * b) return 1; } -boolean can_contact(const region * r, const unit * u, const unit * u2) +int can_contact(const region * r, const unit * u, const unit * u2) { /* hier geht es nur um die belagerung von burgen */ - if (u->building == u2->building) - return true; + if (u->building == u2->building) { + return 1; + } /* unit u is trying to contact u2 - unasked for contact. wenn u oder u2 * nicht in einer burg ist, oder die burg nicht belagert ist, ist * slipthru () == 1. ansonsten ist es nur 1, wenn man die belagerer */ - if (slipthru(u->region, u, u->building) - && slipthru(u->region, u2, u2->building)) - return true; + if (slipthru(u->region, u, u->building) && slipthru(u->region, u2, u2->building)) { + return 1; + } - if (alliedunit(u, u2->faction, HELP_GIVE)) - return true; - - return false; + return (alliedunit(u, u2->faction, HELP_GIVE)); } -static void contact_cmd(unit * u, order * ord, boolean tries) +static void contact_cmd(unit * u, order * ord, int final) { /* unit u kontaktiert unit u2. Dies setzt den contact einfach auf 1 - * ein richtiger toggle ist (noch?) nicht noetig. die region als @@ -150,7 +148,7 @@ static void contact_cmd(unit * u, order * ord, boolean tries) if (u2 != NULL) { if (!can_contact(r, u, u2)) { - if (tries) + if (final) cmistake(u, u->thisorder, 23, MSG_EVENT); return; } @@ -405,8 +403,7 @@ int destroy_cmd(unit * u, struct order *ord) /* all units leave the ship */ for (u2 = r->units; u2; u2 = u2->next) { if (u2->ship == sh) { - u2->ship = 0; - freset(u2, UFL_OWNER); + leave_ship(u2); } } ADDMSG(&u->faction->msgs, msg_message("shipdestroy", @@ -1092,12 +1089,11 @@ create_ship(region * r, unit * u, const struct ship_type *newtype, int want, else want = msize; - sh = new_ship(newtype, u->faction->locale, r); + sh = new_ship(newtype, r, u->faction->locale); if (leave(u, false)) { if (fval(u->race, RCF_CANSAIL)) { - u->ship = sh; - fset(u, UFL_OWNER); + u_set_ship(u, sh); } } new_order = @@ -1256,11 +1252,7 @@ static boolean enter_ship(unit * u, struct order *ord, int id, boolean report) } if (leave(u, false)) { - u->ship = sh; - - if (shipowner(sh) == NULL) { - fset(u, UFL_OWNER); - } + u_set_ship(u, sh); fset(u, UFL_ENTER); } return true; @@ -1315,7 +1307,7 @@ static boolean enter_building(unit * u, order * ord, int id, boolean report) return false; } -void do_misc(region * r, boolean lasttry) +void do_misc(region * r, int is_final_attempt) { unit **uptr, *uc; @@ -1324,7 +1316,7 @@ void do_misc(region * r, boolean lasttry) for (ord = uc->orders; ord; ord = ord->next) { keyword_t kwd = get_keyword(ord); if (kwd == K_CONTACT) { - contact_cmd(uc, ord, lasttry); + contact_cmd(uc, ord, is_final_attempt); } } } @@ -1352,7 +1344,7 @@ void do_misc(region * r, boolean lasttry) case P_GEBAEUDE: if (u->building && u->building->no == id) break; - if (enter_building(u, ord, id, lasttry)) { + if (enter_building(u, ord, id, is_final_attempt)) { unit *ub; for (ub = u; ub; ub = ub->next) { if (ub->building == u->building) { @@ -1365,7 +1357,7 @@ void do_misc(region * r, boolean lasttry) case P_SHIP: if (u->ship && u->ship->no == id) break; - if (enter_ship(u, ord, id, lasttry)) { + if (enter_ship(u, ord, id, is_final_attempt)) { unit *ub; ulast = u; for (ub = u; ub; ub = ub->next) { @@ -1377,9 +1369,9 @@ void do_misc(region * r, boolean lasttry) break; default: - if (lasttry) + if (is_final_attempt) { cmistake(u, ord, 79, MSG_MOVE); - + } } if (ulast != NULL) { /* Wenn wir hier angekommen sind, war der Befehl diff --git a/src/kernel/build.h b/src/kernel/build.h index 710f103f3..5407034bf 100644 --- a/src/kernel/build.h +++ b/src/kernel/build.h @@ -64,7 +64,7 @@ extern "C" { extern int destroy_cmd(struct unit *u, struct order *ord); extern int leave_cmd(struct unit *u, struct order *ord); - extern boolean can_contact(const struct region *r, const struct unit *u, + extern int can_contact(const struct region *r, const struct unit *u, const struct unit *u2); void do_siege(struct region *r); @@ -76,7 +76,7 @@ extern "C" { struct building *getbuilding(const struct region *r); struct ship *getship(const struct region *r); - void do_misc(struct region *r, boolean tries); + void do_misc(struct region *r, int is_final_attempt); void reportevent(struct region *r, char *s); diff --git a/src/kernel/building.c b/src/kernel/building.c index f7ac73f00..9bac38157 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -554,7 +554,7 @@ extern struct attrib_type at_icastle; /** returns the building's build stage (NOT size in people). * only makes sense for castles or similar buildings with multiple * stages */ -int buildingeffsize(const building * b, boolean img) +int buildingeffsize(const building * b, int img) { const struct building_type *btype = NULL; diff --git a/src/kernel/building.h b/src/kernel/building.h index 8055e3731..135b8a80b 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -128,7 +128,7 @@ extern "C" { /* Alte Gebäudetypen: */ /* old functions, still in build.c: */ - int buildingeffsize(const building * b, boolean img); + int buildingeffsize(const building * b, int imaginary); void bhash(struct building *b); void bunhash(struct building *b); int buildingcapacity(const struct building *b); diff --git a/src/kernel/curse.c b/src/kernel/curse.c index 89b689e36..ce18998b6 100644 --- a/src/kernel/curse.c +++ b/src/kernel/curse.c @@ -754,7 +754,7 @@ const char *oldcursename(int id) } /* ------------------------------------------------------------- */ -message *cinfo_simple(const void *obj, typ_t typ, const struct curse * c, +message *cinfo_simple(const void *obj, objtype_t typ, const struct curse * c, int self) { struct message *msg; diff --git a/src/kernel/curse.h b/src/kernel/curse.h index b9af001e0..ee2f7899e 100644 --- a/src/kernel/curse.h +++ b/src/kernel/curse.h @@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define CURSE_H #include +#include "objtypes.h" #ifdef __cplusplus extern "C" { @@ -208,13 +209,13 @@ extern "C" { int typ; unsigned int flags; unsigned int mergeflags; - struct message *(*curseinfo) (const void *, typ_t, const struct curse *, + struct message *(*curseinfo) (const void *, objtype_t, const struct curse *, int); void (*change_vigour) (curse *, double); int (*read) (struct storage * store, curse * c, void *target); int (*write) (struct storage * store, const struct curse * c, const void *target); - int (*cansee) (const struct faction *, const void *, typ_t, + int (*cansee) (const struct faction *, const void *, objtype_t, const struct curse *, int); int (*age) (curse *); } curse_type; @@ -315,7 +316,7 @@ extern "C" { /*** COMPATIBILITY MACROS. DO NOT USE FOR NEW CODE, REPLACE IN OLD CODE: */ extern const char *oldcursename(int id); - extern struct message *cinfo_simple(const void *obj, typ_t typ, + extern struct message *cinfo_simple(const void *obj, objtype_t typ, const struct curse *c, int self); #define is_cursed(a, id, id2) \ diff --git a/src/kernel/magic.h b/src/kernel/magic.h index 621992991..931ccf8f6 100644 --- a/src/kernel/magic.h +++ b/src/kernel/magic.h @@ -45,7 +45,7 @@ extern "C" { * erst in verify_targets wird dann global gesucht, da in den meisten * Fällen das Zielobjekt lokal sein dürfte */ -/* siehe auch typ_t in objtypes.h */ +/* siehe auch objtype_t in objtypes.h */ typedef enum { SPP_REGION, /* "r" : findregion(x,y) -> *region */ SPP_UNIT, /* - : atoi36() -> int */ diff --git a/src/kernel/move.c b/src/kernel/move.c index a3c1fffaf..bf62587d7 100644 --- a/src/kernel/move.c +++ b/src/kernel/move.c @@ -603,10 +603,10 @@ ship *move_ship(ship * sh, region * from, region * to, region_list * route) if (route != NULL) mark_travelthru(u, from, route, NULL); if (from != to) { - u->ship = NULL; /* damit move_unit() kein leave() macht */ + u->ship = 0; /* temporary trick -- do not use u_set_ship here */ move_unit(u, to, ulist); ulist = &u->next; - u->ship = sh; + u->ship = sh; /* undo the trick -- do not use u_set_ship here */ } if (route && eff_skill(u, SK_SAILING, from) >= 1) { produceexp(u, SK_SAILING, u->number); diff --git a/src/kernel/move_test.c b/src/kernel/move_test.c index ce2a1f221..38e899aaf 100644 --- a/src/kernel/move_test.c +++ b/src/kernel/move_test.c @@ -1,3 +1,6 @@ +#include +#include + #include #include #include @@ -12,7 +15,7 @@ static void building_type_exists(CuTest * tc) region *r; building *b; building_type *btype; - building_type *btype2 = calloc(1, sizeof(building_type)); + building_type *btype2 = (building_type *)calloc(1, sizeof(building_type)); test_cleanup(); test_create_world(); diff --git a/src/kernel/objtypes.h b/src/kernel/objtypes.h index b676697f3..293158ecb 100644 --- a/src/kernel/objtypes.h +++ b/src/kernel/objtypes.h @@ -22,7 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif - enum { + typedef enum { TYP_UNIT, TYP_REGION, TYP_BUILDING, @@ -31,7 +31,7 @@ extern "C" { TYP_ACTION, TYP_TRIGGER, TYP_TIMEOUT - }; + } objtype_t; #ifdef __cplusplus } diff --git a/src/kernel/reports.c b/src/kernel/reports.c index aefcdae66..461833ef3 100644 --- a/src/kernel/reports.c +++ b/src/kernel/reports.c @@ -975,7 +975,7 @@ spunit(struct strlist **SP, const struct faction *f, const unit * u, int indent, (char)((u->faction == f) ? '*' : (dh ? '+' : '-'))); } -struct message *msg_curse(const struct curse *c, const void *obj, typ_t typ, +struct message *msg_curse(const struct curse *c, const void *obj, objtype_t typ, int self) { if (c->type->curseinfo) { diff --git a/src/kernel/reports.h b/src/kernel/reports.h index 632c3df86..b1de0f3dc 100644 --- a/src/kernel/reports.h +++ b/src/kernel/reports.h @@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define H_KRNL_REPORTS #include +#include "objtypes.h" #ifdef __cplusplus extern "C" { @@ -117,7 +118,7 @@ extern "C" { extern int *nmrs; extern struct message *msg_curse(const struct curse *c, const void *obj, - typ_t typ, int slef); + objtype_t typ, int slef); typedef struct arg_regions { int nregions; diff --git a/src/kernel/save.c b/src/kernel/save.c index 8f14c944c..d039e62b9 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -796,9 +796,12 @@ unit *read_unit(struct storage *store) u->building = findbuilding(n); n = store->r_id(store); - if (n > 0) - u->ship = findship(n); - + if (n > 0) { + ship * sh = findship(n); + if (sh) { + u_set_ship(u, sh); + } + } setstatus(u, store->r_int(store)); u->flags = store->r_int(store); u->flags &= UFL_SAVEMASK; diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 1721174e2..22311b919 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -174,7 +174,7 @@ unit *captain(ship * sh) /* Alte Schiffstypen: */ static ship *deleted_ships; -ship *new_ship(const ship_type * stype, const struct locale *lang, region * r) +ship *new_ship(const ship_type * stype, region * r, const struct locale *lang) { static char buffer[7 + IDSIZE + 1]; ship *sh = (ship *) calloc(1, sizeof(ship)); @@ -289,6 +289,7 @@ void getshipweight(const ship * sh, int *sweight, int *scabins) unit *shipowner(const ship * sh) { +#ifndef NDEBUG unit *u; unit *first = NULL; @@ -300,7 +301,7 @@ unit *shipowner(const ship * sh) if (!first && u->number > 0) first = u; if (fval(u, UFL_OWNER) && u->number > 0) - return u; + break; if (u->number == 0) freset(u, UFL_OWNER); } @@ -309,9 +310,13 @@ unit *shipowner(const ship * sh) /* Eigentümer tot oder kein Eigentümer vorhanden. Erste lebende Einheit * nehmen. */ - if (first) - fset(first, UFL_OWNER); - return first; + if (first && !u) { + u = first; + fset(u, UFL_OWNER); + } + assert(u==sh->owner); +#endif + return sh->owner; } void write_ship_reference(const struct ship *sh, struct storage *store) diff --git a/src/kernel/ship.h b/src/kernel/ship.h index 12e501d80..4a33ac701 100644 --- a/src/kernel/ship.h +++ b/src/kernel/ship.h @@ -81,6 +81,7 @@ extern "C" { typedef struct ship { struct ship *next; struct ship *nexthash; + struct unit * owner; int no; struct region *region; char *name; @@ -100,8 +101,8 @@ extern "C" { extern int shipcapacity(const struct ship *sh); extern void getshipweight(const struct ship *sh, int *weight, int *cabins); - extern ship *new_ship(const struct ship_type *stype, - const struct locale *lang, struct region *r); + extern ship *new_ship(const struct ship_type *stype, struct region *r, + const struct locale *lang); extern const char *write_shipname(const struct ship *sh, char *buffer, size_t size); extern struct ship *findship(int n); diff --git a/src/kernel/ship_test.c b/src/kernel/ship_test.c new file mode 100644 index 000000000..eee901b05 --- /dev/null +++ b/src/kernel/ship_test.c @@ -0,0 +1,63 @@ +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static void test_register_ship(CuTest * tc) +{ + ship_type *stype; + + test_cleanup(); + + stype = (ship_type *)calloc(sizeof(ship_type), 1); + stype->name[0] = strdup("herp"); + st_register(stype); + + CuAssertPtrNotNull(tc, st_find("herp")); +} + +static void test_shipowner(CuTest * tc) +{ + struct region *r; + struct ship * sh; + struct unit * u; + 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); + CuAssertPtrNotNull(tc, u); + u_set_ship(u, sh); + CuAssertPtrEquals(tc, u, shipowner(sh)); +} + +CuSuite *get_ship_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_register_ship); + SUITE_ADD_TEST(suite, test_shipowner); + return suite; +} diff --git a/src/kernel/types.h b/src/kernel/types.h index 2b2772564..ae53a79bd 100644 --- a/src/kernel/types.h +++ b/src/kernel/types.h @@ -31,7 +31,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include typedef short terrain_t; -typedef short typ_t; typedef short item_t; struct attrib; diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 7344c4589..2cc272539 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -774,12 +774,23 @@ ship *leftship(const unit * u) return NULL; } +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); + } + } +} + void leave_ship(unit * u) { struct ship *sh = u->ship; - if (sh == NULL) - return; - u->ship = NULL; + if (!sh) return; + u->ship = 0; set_leftship(u, sh); if (fval(u, UFL_OWNER)) { @@ -791,12 +802,15 @@ void leave_ship(unit * u) if (u2->faction == u->faction) { owner = u2; break; - } else if (owner == NULL) + } else if (!owner) { owner = u2; + } } } - if (owner != NULL) + if (owner) { + sh->owner = owner; fset(owner, UFL_OWNER); + } } } @@ -849,10 +863,11 @@ boolean leave(unit * u, boolean force) return false; } } - if (u->building) + if (u->building) { leave_building(u); - else if (u->ship) + } else if (u->ship) { leave_ship(u); + } return true; } @@ -1493,8 +1508,8 @@ 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->ship != NULL && fval(u->race, RCF_CANSAIL)) { - u->ship = creator->ship; + if (creator->ship && fval(u->race, RCF_CANSAIL)) { + u_set_ship(u, creator->ship); } } diff --git a/src/kernel/unit.h b/src/kernel/unit.h index ab5ace449..0470ee7a7 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -182,8 +182,9 @@ extern "C" { extern boolean leave(struct unit *u, boolean force); extern boolean can_leave(struct unit *u); - extern void leave_ship(unit * u); - extern void leave_building(unit * u); + extern void u_set_ship(struct unit * u, struct ship * sh); + extern void leave_ship(struct unit * u); + extern void leave_building(struct unit * u); extern void set_leftship(struct unit *u, struct ship *sh); extern struct ship *leftship(const struct unit *); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index c1ed36b76..8e488b115 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -534,7 +534,7 @@ static int parse_ships(xmlDocPtr doc) for (i = 0; i != nodes->nodeNr; ++i) { xmlNodePtr child, node = nodes->nodeTab[i]; xmlChar *propValue; - ship_type *st = calloc(sizeof(ship_type), 1); + ship_type *st = (ship_type *)calloc(sizeof(ship_type), 1); xmlXPathObjectPtr result; int k, c; diff --git a/src/modules/xecmd.c b/src/modules/xecmd.c index 67ebeb094..e45c611cd 100644 --- a/src/modules/xecmd.c +++ b/src/modules/xecmd.c @@ -75,12 +75,11 @@ static void xe_giveballon(unit * u, struct order *ord) return; } - sh = new_ship(st_find("balloon"), u2->faction->locale, u2->region); + sh = new_ship(st_find("balloon"), u2->region, u2->faction->locale); sh->size = 5; ship_setname(sh, "Xontormia-Ballon"); - leave(u2, false); - u2->ship = sh; - fset(u2, UFL_OWNER); + leave(u2, true); + u_set_ship(u2, sh); } int xecmd(unit * u, order * ord) diff --git a/src/tests.c b/src/tests.c index 914e23512..229904c9a 100644 --- a/src/tests.c +++ b/src/tests.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,7 @@ int RunAllTests(void) CuSuiteAddSuite(suite, get_curse_suite()); CuSuiteAddSuite(suite, get_market_suite()); CuSuiteAddSuite(suite, get_move_suite()); + CuSuiteAddSuite(suite, get_ship_suite()); CuSuiteAddSuite(suite, get_spell_suite()); CuSuiteAddSuite(suite, get_laws_suite()); CuSuiteAddSuite(suite, get_battle_suite()); @@ -117,6 +119,13 @@ building * test_create_building(region * r, const building_type * btype) return b; } +ship * test_create_ship(region * r, const ship_type * stype) +{ + ship * s = new_ship(stype, r, default_locale); + s->size = stype->construction?stype->construction->maxsize:1; + return s; +} + item_type * test_create_itemtype(const char ** names) { resource_type * rtype; item_type * itype; @@ -171,10 +180,12 @@ void test_create_world(void) btype = (building_type*)calloc(sizeof(building_type), 1); btype->flags = BTF_NAMECHANGE; btype->_name = strdup("castle"); + locale_setstring(default_locale, "castle", "castle"); bt_register(btype); stype = (ship_type*)calloc(sizeof(ship_type), 1); stype->name[0] = strdup("boat"); stype->name[1] = strdup("boat_p"); + locale_setstring(default_locale, "boat", "boat"); st_register(stype); } diff --git a/src/tests.h b/src/tests.h index 2a3c4f625..c35922c7c 100644 --- a/src/tests.h +++ b/src/tests.h @@ -15,7 +15,7 @@ extern "C" { struct unit *test_create_unit(struct faction *f, struct region *r); void test_create_world(void); struct building * test_create_building(struct region * r, const struct building_type * btype); - + struct ship * test_create_ship(struct region * r, const struct ship_type * stype); int RunAllTests(void); #else #define RunAllTests() 0