add a list of valid coasts to ship definition in JSON.

fix endless loop in error-line counting.
This commit is contained in:
Enno Rehling 2014-06-17 21:33:42 -07:00
parent 6788d552cd
commit 8166519d30
4 changed files with 35 additions and 10 deletions

View File

@ -36,9 +36,8 @@ int config_parse(const char *json)
int line; int line;
char buffer[10]; char buffer[10];
const char *xp = json, *lp, *ep = cJSON_GetErrorPtr(); const char *xp = json, *lp, *ep = cJSON_GetErrorPtr();
for (line=0;xp && xp<ep;++line) { for (line=0,lp=xp;xp && xp<ep;++line,lp=xp+1) {
lp = xp; xp = strchr(lp, '\n');
xp = strchr(xp, '\n');
} }
xp = (ep > json + 10) ? ep - 10 : json; xp = (ep > json + 10) ? ep - 10 : json;
strncpy(buffer, xp, sizeof(buffer)); strncpy(buffer, xp, sizeof(buffer));

View File

@ -140,12 +140,13 @@ void json_building(cJSON *json, building_type *bt) {
} }
void json_ship(cJSON *json, ship_type *st) { void json_ship(cJSON *json, ship_type *st) {
cJSON *child; cJSON *child, *iter;
if (json->type!=cJSON_Object) { if (json->type!=cJSON_Object) {
log_error_n("ship %s is not a json object: %d", json->string, json->type); log_error_n("ship %s is not a json object: %d", json->string, json->type);
return; return;
} }
for (child=json->child;child;child=child->next) { for (child=json->child;child;child=child->next) {
int i;
switch(child->type) { switch(child->type) {
case cJSON_Object: case cJSON_Object:
if (strcmp(child->string, "construction")==0) { if (strcmp(child->string, "construction")==0) {
@ -154,6 +155,19 @@ void json_ship(cJSON *json, ship_type *st) {
log_error_n("ship %s contains unknown attribute %s", json->string, child->string); log_error_n("ship %s contains unknown attribute %s", json->string, child->string);
} }
break; break;
case cJSON_Array:
st->coasts = (const terrain_type **)
malloc(sizeof(terrain_type *) * (1+cJSON_GetArraySize(child)));
for (i=0,iter=child->child;iter;iter=iter->next) {
if (iter->type==cJSON_String) {
terrain_type *ter = get_or_create_terrain(iter->valuestring);
if (ter) {
st->coasts[i++] = ter;
}
}
}
st->coasts[i] = 0;
break;
case cJSON_Number: case cJSON_Number:
if (strcmp(child->string, "range")==0) { if (strcmp(child->string, "range")==0) {
st->range = child->valueint; st->range = child->valueint;

View File

@ -85,11 +85,13 @@ static void test_races(CuTest * tc)
static void test_ships(CuTest * tc) static void test_ships(CuTest * tc)
{ {
const char * data = "{\"ships\": { \"boat\" : { " const char * data = "{\"ships\": { \"boat\" : { "
"\"construction\" : { \"maxsize\" : 20, \"reqsize\" : 10, \"minskill\" : 1 }" "\"construction\" : { \"maxsize\" : 20, \"reqsize\" : 10, \"minskill\" : 1 },"
"\"coasts\" : [ \"plain\" ]"
"}}}"; "}}}";
cJSON *json = cJSON_Parse(data); cJSON *json = cJSON_Parse(data);
const struct ship_type *st; const ship_type *st;
const terrain_type *ter;
test_cleanup(); test_cleanup();
@ -104,6 +106,14 @@ static void test_ships(CuTest * tc)
CuAssertIntEquals(tc, 10, st->construction->reqsize); CuAssertIntEquals(tc, 10, st->construction->reqsize);
CuAssertIntEquals(tc, 20, st->construction->maxsize); CuAssertIntEquals(tc, 20, st->construction->maxsize);
CuAssertIntEquals(tc, 1, st->construction->minskill); CuAssertIntEquals(tc, 1, st->construction->minskill);
ter = get_terrain("plain");
CuAssertPtrNotNull(tc, ter);
CuAssertPtrNotNull(tc, st->coasts);
CuAssertPtrEquals(tc, (void *)ter, (void *)st->coasts[0]);
CuAssertPtrEquals(tc, 0, (void *)st->coasts[1]);
test_cleanup(); test_cleanup();
} }

View File

@ -660,11 +660,13 @@ int check_ship_allowed(struct ship *sh, const region * r)
if (fval(r->terrain, SEA_REGION)) { if (fval(r->terrain, SEA_REGION)) {
return SA_COAST; return SA_COAST;
} }
if (sh->type->coasts) {
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;
} }
}
}
return SA_NO_COAST; return SA_NO_COAST;
} }