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