diff --git a/core/res/terrains.xml b/core/res/terrains.xml index edd8895ab..67238c966 100644 --- a/core/res/terrains.xml +++ b/core/res/terrains.xml @@ -1,8 +1,8 @@ - - - + + + diff --git a/src/kernel/config.c b/src/kernel/config.c index 961e939b5..40a0c0daf 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -53,6 +53,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "terrain.h" #include "unit.h" +#include +#include /* util includes */ #include #include @@ -2926,6 +2928,13 @@ void free_gamedata(void) free_units(); free_regions(); free_borders(); + default_locale = 0; + free_locales(); + free_spells(); + free_buildingtypes(); + free_shiptypes(); + free_races(); + free_spellbooks(); for (i=0;i!=MAXLOCALES;++i) { if (defaults[i]) { diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index cd11c8826..6bb0c6360 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -86,7 +86,30 @@ void json_terrain(cJSON *json, terrain_type *ter) { return; } for (child=json->child;child;child=child->next) { - log_error_n("terrain %s contains unknown attribute %s", json->string, child->string); + switch(child->type) { + case cJSON_Array: + if (strcmp(child->string, "flags")==0) { + cJSON *entry; + const char * flags[] = { + "land", "sea", "forest", "arctic", "cavalry", "forbidden", "sail", "fly", "swim", "walk", 0 + }; + for (entry=child->child;entry;entry=entry->next) { + if (entry->type == cJSON_String) { + int i; + for (i = 0; flags[i]; ++i) { + if (strcmp(flags[i], entry->valuestring)==0) { + ter->flags |= (1<string, child->string); + } + break; + default: + log_error_n("terrain %s contains unknown attribute %s", json->string, child->string); + } } } @@ -120,6 +143,15 @@ void json_ship(cJSON *json, ship_type *st) { case cJSON_Object: if (strcmp(child->string, "construction")==0) { json_construction(child, &st->construction); + } else { + log_error_n("ship %s contains unknown attribute %s", json->string, child->string); + } + break; + case cJSON_Number: + if (strcmp(child->string, "range")==0) { + st->range = child->valueint; + } else { + log_error_n("ship %s contains unknown attribute %s", json->string, child->string); } break; default: diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c index 25312ab6e..5ee6f8af2 100644 --- a/src/kernel/jsonconf.test.c +++ b/src/kernel/jsonconf.test.c @@ -132,7 +132,8 @@ static void test_buildings(CuTest * tc) static void test_terrains(CuTest * tc) { - const char * data = "{\"terrains\": { \"plain\" : {} }}"; + const char * data = "{\"terrains\": { \"plain\" : { \"flags\" : [ \"land\", \"fly\", \"walk\" ] } }}"; + const terrain_type *ter; cJSON *json = cJSON_Parse(data); @@ -141,7 +142,9 @@ static void test_terrains(CuTest * tc) CuAssertPtrEquals(tc, 0, (void *)get_terrain("plain")); json_config(json); - CuAssertPtrNotNull(tc, get_terrain("plain")); + ter = get_terrain("plain"); + CuAssertPtrNotNull(tc, ter); + CuAssertIntEquals(tc, ter->flags, LAND_REGION|FLY_INTO|WALK_INTO); test_cleanup(); } diff --git a/src/kernel/move.c b/src/kernel/move.c index c03516376..d63208041 100644 --- a/src/kernel/move.c +++ b/src/kernel/move.c @@ -654,8 +654,12 @@ int check_ship_allowed(struct ship *sh, const region * r) } } - if (bt_harbour && buildingtype_exists(r, bt_harbour, true)) + if (bt_harbour && buildingtype_exists(r, bt_harbour, true)) { return SA_HARBOUR; + } + if (fval(r->terrain, SEA_REGION)) { + return SA_COAST; + } for (c = 0; sh->type->coasts[c] != NULL; ++c) { if (sh->type->coasts[c] == r->terrain) return SA_COAST; @@ -1729,7 +1733,7 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep) if (storms_enabled) { gamedate date; get_gamedate(turn, &date); - stormyness = storms[date.month] * 5; + stormyness = storms ? storms[date.month] * 5 : 0; } gamecookie = global.cookie; } diff --git a/src/kernel/move.test.c b/src/kernel/move.test.c index 1a8d4d272..6b4eb015b 100644 --- a/src/kernel/move.test.c +++ b/src/kernel/move.test.c @@ -14,25 +14,28 @@ static void test_ship_not_allowed_in_coast(CuTest * tc) { - region *r; + region *r1, *r2; ship * sh; - terrain_type * ttype; - ship_type * stype; + terrain_type *ttype, *otype; + ship_type *stype; const char * names[] = { "derp", "derp_p" }; test_cleanup(); test_create_world(); ttype = test_create_terrain("glacier", LAND_REGION|ARCTIC_REGION|WALK_INTO|SAIL_INTO); + otype = test_create_terrain("ocean", SEA_REGION|SAIL_INTO); stype = test_create_shiptype(names); stype->coasts = (const struct terrain_type **)calloc(2, sizeof(const struct terrain_type *)); - r = test_create_region(0, 0, ttype); + r1 = test_create_region(0, 0, ttype); + r2 = test_create_region(1, 0, otype); sh = test_create_ship(0, stype); - CuAssertIntEquals(tc, SA_NO_COAST, check_ship_allowed(sh, r)); + CuAssertIntEquals(tc, SA_COAST, check_ship_allowed(sh, r2)); + CuAssertIntEquals(tc, SA_NO_COAST, check_ship_allowed(sh, r1)); stype->coasts[0] = ttype; - CuAssertIntEquals(tc, SA_COAST, check_ship_allowed(sh, r)); + CuAssertIntEquals(tc, SA_COAST, check_ship_allowed(sh, r1)); } static void test_ship_allowed_with_harbor(CuTest * tc) diff --git a/src/kernel/terrain.h b/src/kernel/terrain.h index 0b6842fa8..15e0318a9 100644 --- a/src/kernel/terrain.h +++ b/src/kernel/terrain.h @@ -35,7 +35,6 @@ extern "C" { #define FLY_INTO (1<<7) /* man darf hierhin fliegen */ #define SWIM_INTO (1<<8) /* man darf hierhin schwimmen */ #define WALK_INTO (1<<9) /* man darf hierhin laufen */ -#define LARGE_SHIPS (1<<10) /* grosse Schiffe dürfen hinfahren */ typedef struct production_rule { char *name; diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index bc2739b95..63d8a7164 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1975,8 +1975,6 @@ static int parse_terrains(xmlDocPtr doc) terrain->flags |= WALK_INTO; if (xml_bvalue(node, "swim", false)) terrain->flags |= SWIM_INTO; - if (xml_bvalue(node, "shallow", true)) - terrain->flags |= LARGE_SHIPS; if (xml_bvalue(node, "cavalry", false)) terrain->flags |= CAVALRY_REGION; } diff --git a/src/tests.c b/src/tests.c index c95d30fbe..f3dcaf312 100644 --- a/src/tests.c +++ b/src/tests.c @@ -60,13 +60,6 @@ void test_cleanup(void) test_clear_resources(); global.functions.maintenance = NULL; global.functions.wage = NULL; - default_locale = 0; - free_locales(); - free_spells(); - free_buildingtypes(); - free_shiptypes(); - free_races(); - free_spellbooks(); free_gamedata(); } diff --git a/tests/init.lua b/tests/init.lua index 31ddd376f..e75241ead 100644 --- a/tests/init.lua +++ b/tests/init.lua @@ -1,8 +1,8 @@ -- new tests 2014-06-11 --- require "tests.ships" require "tests.settings" require "tests.config" require "tests.locale" require "tests.regions" +require "tests.ships" diff --git a/tests/ships.lua b/tests/ships.lua index f47131ef7..763492d3c 100644 --- a/tests/ships.lua +++ b/tests/ships.lua @@ -6,22 +6,37 @@ function setup() eressea.free_game() eressea.settings.set("nmr.removenewbie", "0") eressea.settings.set("nmr.timeout", "0") - eressea.settings.set("NewbieImmunity", "0") + eressea.settings.set("rules.ships.storms", "0") conf = [[{ "races": { "human" : {}, "insect" : {} }, "ships" : { - "boat" : {}, - "longboat" : {} + "boat" : { + "construction" : { + "maxsize" : 5 + }, + "range" : 3 + } }, "buildings" : { "harbour" : {} }, "terrains" : { - "ocean": {}, - "plain": {} + "ocean": { "flags" : [ "sea", "sail", "fly" ] }, + "plain": { "flags" : [ "land", "walk", "sail", "fly" ] } + }, + "directions" : { + "de" : { + "east" : "OSTEN", + "west" : "WESTEN" + } + }, + "keywords" : { + "de" : { + "move" : "NACH" + } } }]] @@ -35,6 +50,7 @@ function test_sail() local f = faction.create("test@example.com", "human", "de") local u = unit.create(f, r1, 1) u.ship = ship.create(r1, "boat") + u.ship.size = 5 u:set_skill("sailing", 10) u:add_order("NACH O") process_orders()