diff --git a/src/common/kernel/move.c b/src/common/kernel/move.c index 7d2952cd4..e16bfc6c1 100644 --- a/src/common/kernel/move.c +++ b/src/common/kernel/move.c @@ -707,7 +707,9 @@ flying_ship(const ship * sh) static void set_coast(ship * sh, region * r, region * rnext) { - if (!fval(rnext->terrain, SEA_REGION) && !flying_ship(sh)) { + if (sh->type->flags & SFL_NOCOAST) { + sh->coast = NODIRECTION; + } else if (!fval(rnext->terrain, SEA_REGION) && !flying_ship(sh)) { sh->coast = reldirection(rnext, r); assert(fval(r->terrain, SEA_REGION)); } else { @@ -1777,7 +1779,7 @@ sail(unit * u, order * ord, boolean move_on_land, region_list **routep) for (d=0;d!=MAXDIRECTIONS;++d) { region * rc = rconnect(next_point, d); - if (!fval(rc->terrain, SEA_REGION)) break; + if (rc==NULL || !fval(rc->terrain, SEA_REGION)) break; } if (d == MAXDIRECTIONS) { /* Schiff kann nicht aufs offene Meer */ diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index cd4430847..c450d00c3 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -1548,6 +1548,9 @@ readgame(const char * filename, int mode, int backup) /* Attribute rekursiv einlesen */ sh->coast = (direction_t)store->r_int(store); + if (sh->type->flags & SFL_NOCOAST) { + sh->coast = NODIRECTION; + } a_read(store, &sh->attribs); } @@ -1759,6 +1762,7 @@ writegame(const char *filename, int mode) store->w_tok(store, sh->type->name[0]); store->w_int(store, sh->size); store->w_int(store, sh->damage); + assert((sh->type->flags & SFL_NOCOAST)==0 || sh->coast == NODIRECTION); store->w_int(store, sh->coast); store->w_brk(store); a_write(store, sh->attribs); diff --git a/src/common/kernel/ship.h b/src/common/kernel/ship.h index e51b77a3e..73f4503fe 100644 --- a/src/common/kernel/ship.h +++ b/src/common/kernel/ship.h @@ -25,6 +25,7 @@ extern "C" { /* ship_type::flags */ #define SFL_OPENSEA 0x01 #define SFL_FLY 0x02 +#define SFL_NOCOAST 0x04 typedef struct ship_type { const char * name[2]; diff --git a/src/common/kernel/xmlreader.c b/src/common/kernel/xmlreader.c index 6561696aa..01d4d3960 100644 --- a/src/common/kernel/xmlreader.c +++ b/src/common/kernel/xmlreader.c @@ -533,6 +533,7 @@ parse_ships(xmlDocPtr doc) st->combat = xml_ivalue(node, "combat", 0); st->cptskill = xml_ivalue(node, "cptskill", 0); st->damage = xml_fvalue(node, "damage", 0.0); + if (xml_bvalue(node, "nocoast", false)) st->flags |= SFL_NOCOAST; if (xml_bvalue(node, "fly", false)) st->flags |= SFL_FLY; if (xml_bvalue(node, "opensea", false)) st->flags |= SFL_OPENSEA; st->fishing = xml_ivalue(node, "fishing", 0); diff --git a/src/eressea/tolua/bindings.c b/src/eressea/tolua/bindings.c index 49a690d62..3a0148124 100644 --- a/src/eressea/tolua/bindings.c +++ b/src/eressea/tolua/bindings.c @@ -562,10 +562,32 @@ tolua_write_reports(lua_State* L) return 1; } +static void +reset_game(void) +{ + region * r; + faction * f; + for (r=regions;r;r=r->next) { + unit * u; + building * b; + r->flags &= RF_SAVEMASK; + for (u=r->units;u;u=u->next) { + u->flags &= UFL_SAVEMASK; + } + for (b=r->buildings;b;b=b->next) { + b->flags &= BLD_SAVEMASK; + } + } + for (f=factions;f;f=f->next) { + f->flags &= FFL_SAVEMASK; + } +} + static int tolua_process_orders(lua_State* L) { ++turn; + reset_game(); processorders(); return 0; } diff --git a/src/res/e3a/ships.xml b/src/res/e3a/ships.xml index a5270bd1a..9092c3d51 100644 --- a/src/res/e3a/ships.xml +++ b/src/res/e3a/ships.xml @@ -1,6 +1,6 @@ - + diff --git a/src/scripts/tests.lua b/src/scripts/tests.lua index 34acf5c85..7d081d4ae 100644 --- a/src/scripts/tests.lua +++ b/src/scripts/tests.lua @@ -630,7 +630,7 @@ local function two_units(r, f1, f2) return u1, u2 end -function two_factions() +local function two_factions() local f1 = faction.create("noreply@eressea.de", "human", "de") f1.id = 1 local f2 = faction.create("noreply@eressea.de", "orc", "de") @@ -638,6 +638,27 @@ function two_factions() return f1, f2 end +function test_canoe() + free_game() + local f = faction.create("noreply@eressea.de", "human", "de") + local src = region.create(0, 0, "ocean") + local land = region.create(1, 0, "plain") + region.create(2, 0, "ocean") + local dst = region.create(3, 0, "ocean") + local sh = ship.create(src, "canoe") + local u1, u2 = two_units(src, f, f) + u1.ship = sh + u2.ship = sh + u1:set_skill("sailing", 10) + u1:clear_orders() + u1:add_order("NACH O O O") + process_orders() + assert(u2.region.id==land.id) + u1:add_order("NACH O O O") + process_orders() + assert(u2.region.id==dst.id) +end + function test_control() free_game() local u1, u2 = two_units(region.create(0, 0, "plain"), two_factions()) @@ -707,16 +728,15 @@ tests = { ["work"] = test_work, ["morale"] = test_morale, ["owners"] = test_owners, + ["canoe"] = test_canoe, ["market"] = test_market } mytests = { - ["morale"] = test_morale, - ["control"] = test_control, - ["taxes"] = test_taxes, + ["canoe"] = test_canoe, ["owners"] = test_owners } fail = 0 -for k, v in pairs(tests) do +for k, v in pairs(mytests) do local status, err = pcall(v) if not status then fail = fail + 1