finally have all the scaffolding to write a test with ships.

configure terrain flags from json.
ships are always allowed to enter SEA regions.
This commit is contained in:
Enno Rehling 2014-06-16 22:19:19 -07:00
parent b40ddaeaa1
commit 33928568cf
11 changed files with 87 additions and 30 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml version="1.0" encoding="ISO-8859-1"?>
<terrains> <terrains>
<!-- defaults: walk="yes" sail="yes" fly="yes" shallow="yes" swim="no" forest="no" sea="no" land="yes" forbidden="no" arctic="no" cavalry="no" --> <!-- defaults: walk="yes" sail="yes" fly="yes" swim="no" forest="no" sea="no" land="yes" forbidden="no" arctic="no" cavalry="no" -->
<terrain name="ocean" size="100" shallow="no" walk="no" swim="yes" land="no" sea="yes" /> <terrain name="ocean" size="100" walk="no" swim="yes" land="no" sea="yes" />
<terrain name="plain" size="10000" road="50" shallow="no" forest="yes" cavalry="yes" seed="3"> <terrain name="plain" size="10000" road="50" forest="yes" cavalry="yes" seed="3">
<herb name="h0" /> <herb name="h0" />
<herb name="h1" /> <herb name="h1" />
<herb name="h2" /> <herb name="h2" />

View File

@ -53,6 +53,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "terrain.h" #include "terrain.h"
#include "unit.h" #include "unit.h"
#include <kernel/spell.h>
#include <kernel/spellbook.h>
/* util includes */ /* util includes */
#include <util/attrib.h> #include <util/attrib.h>
#include <util/base36.h> #include <util/base36.h>
@ -2926,6 +2928,13 @@ void free_gamedata(void)
free_units(); free_units();
free_regions(); free_regions();
free_borders(); free_borders();
default_locale = 0;
free_locales();
free_spells();
free_buildingtypes();
free_shiptypes();
free_races();
free_spellbooks();
for (i=0;i!=MAXLOCALES;++i) { for (i=0;i!=MAXLOCALES;++i) {
if (defaults[i]) { if (defaults[i]) {

View File

@ -86,7 +86,30 @@ void json_terrain(cJSON *json, terrain_type *ter) {
return; return;
} }
for (child=json->child;child;child=child->next) { 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<<i);
}
}
}
}
} else {
log_error_n("terrain %s contains unknown attribute %s", json->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: case cJSON_Object:
if (strcmp(child->string, "construction")==0) { if (strcmp(child->string, "construction")==0) {
json_construction(child, &st->construction); 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; break;
default: default:

View File

@ -132,7 +132,8 @@ static void test_buildings(CuTest * tc)
static void test_terrains(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); cJSON *json = cJSON_Parse(data);
@ -141,7 +142,9 @@ static void test_terrains(CuTest * tc)
CuAssertPtrEquals(tc, 0, (void *)get_terrain("plain")); CuAssertPtrEquals(tc, 0, (void *)get_terrain("plain"));
json_config(json); 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(); test_cleanup();
} }

View File

@ -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; return SA_HARBOUR;
}
if (fval(r->terrain, SEA_REGION)) {
return SA_COAST;
}
for (c = 0; sh->type->coasts[c] != NULL; ++c) { for (c = 0; sh->type->coasts[c] != NULL; ++c) {
if (sh->type->coasts[c] == r->terrain) if (sh->type->coasts[c] == r->terrain)
return SA_COAST; return SA_COAST;
@ -1729,7 +1733,7 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
if (storms_enabled) { if (storms_enabled) {
gamedate date; gamedate date;
get_gamedate(turn, &date); get_gamedate(turn, &date);
stormyness = storms[date.month] * 5; stormyness = storms ? storms[date.month] * 5 : 0;
} }
gamecookie = global.cookie; gamecookie = global.cookie;
} }

View File

@ -14,25 +14,28 @@
static void test_ship_not_allowed_in_coast(CuTest * tc) static void test_ship_not_allowed_in_coast(CuTest * tc)
{ {
region *r; region *r1, *r2;
ship * sh; ship * sh;
terrain_type * ttype; terrain_type *ttype, *otype;
ship_type * stype; ship_type *stype;
const char * names[] = { "derp", "derp_p" }; const char * names[] = { "derp", "derp_p" };
test_cleanup(); test_cleanup();
test_create_world(); test_create_world();
ttype = test_create_terrain("glacier", LAND_REGION|ARCTIC_REGION|WALK_INTO|SAIL_INTO); 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 = test_create_shiptype(names);
stype->coasts = (const struct terrain_type **)calloc(2, sizeof(const struct terrain_type *)); 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); 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; 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) static void test_ship_allowed_with_harbor(CuTest * tc)

View File

@ -35,7 +35,6 @@ extern "C" {
#define FLY_INTO (1<<7) /* man darf hierhin fliegen */ #define FLY_INTO (1<<7) /* man darf hierhin fliegen */
#define SWIM_INTO (1<<8) /* man darf hierhin schwimmen */ #define SWIM_INTO (1<<8) /* man darf hierhin schwimmen */
#define WALK_INTO (1<<9) /* man darf hierhin laufen */ #define WALK_INTO (1<<9) /* man darf hierhin laufen */
#define LARGE_SHIPS (1<<10) /* grosse Schiffe dürfen hinfahren */
typedef struct production_rule { typedef struct production_rule {
char *name; char *name;

View File

@ -1975,8 +1975,6 @@ static int parse_terrains(xmlDocPtr doc)
terrain->flags |= WALK_INTO; terrain->flags |= WALK_INTO;
if (xml_bvalue(node, "swim", false)) if (xml_bvalue(node, "swim", false))
terrain->flags |= SWIM_INTO; terrain->flags |= SWIM_INTO;
if (xml_bvalue(node, "shallow", true))
terrain->flags |= LARGE_SHIPS;
if (xml_bvalue(node, "cavalry", false)) if (xml_bvalue(node, "cavalry", false))
terrain->flags |= CAVALRY_REGION; terrain->flags |= CAVALRY_REGION;
} }

View File

@ -60,13 +60,6 @@ void test_cleanup(void)
test_clear_resources(); test_clear_resources();
global.functions.maintenance = NULL; global.functions.maintenance = NULL;
global.functions.wage = NULL; global.functions.wage = NULL;
default_locale = 0;
free_locales();
free_spells();
free_buildingtypes();
free_shiptypes();
free_races();
free_spellbooks();
free_gamedata(); free_gamedata();
} }

View File

@ -1,8 +1,8 @@
-- new tests 2014-06-11 -- new tests 2014-06-11
-- require "tests.ships"
require "tests.settings" require "tests.settings"
require "tests.config" require "tests.config"
require "tests.locale" require "tests.locale"
require "tests.regions" require "tests.regions"
require "tests.ships"

View File

@ -6,22 +6,37 @@ function setup()
eressea.free_game() eressea.free_game()
eressea.settings.set("nmr.removenewbie", "0") eressea.settings.set("nmr.removenewbie", "0")
eressea.settings.set("nmr.timeout", "0") eressea.settings.set("nmr.timeout", "0")
eressea.settings.set("NewbieImmunity", "0") eressea.settings.set("rules.ships.storms", "0")
conf = [[{ conf = [[{
"races": { "races": {
"human" : {}, "human" : {},
"insect" : {} "insect" : {}
}, },
"ships" : { "ships" : {
"boat" : {}, "boat" : {
"longboat" : {} "construction" : {
"maxsize" : 5
},
"range" : 3
}
}, },
"buildings" : { "buildings" : {
"harbour" : {} "harbour" : {}
}, },
"terrains" : { "terrains" : {
"ocean": {}, "ocean": { "flags" : [ "sea", "sail", "fly" ] },
"plain": {} "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 f = faction.create("test@example.com", "human", "de")
local u = unit.create(f, r1, 1) local u = unit.create(f, r1, 1)
u.ship = ship.create(r1, "boat") u.ship = ship.create(r1, "boat")
u.ship.size = 5
u:set_skill("sailing", 10) u:set_skill("sailing", 10)
u:add_order("NACH O") u:add_order("NACH O")
process_orders() process_orders()