forked from github/server
completing the implementation of JSON terrains (WIP).
seeing a crash when trying to allocate a resource for stone in test_json_terrains.
This commit is contained in:
parent
8860244f1c
commit
59e2c12605
|
@ -54,6 +54,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
/* libc includes */
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -179,9 +180,14 @@ static void rt_register(resource_type * rtype)
|
|||
resource_type *rt_get_or_create(const char *name) {
|
||||
resource_type *rtype = rt_find(name);
|
||||
if (!rtype) {
|
||||
rtype = (resource_type *)calloc(sizeof(resource_type), 1);
|
||||
rtype->_name = _strdup(name);
|
||||
rt_register(rtype);
|
||||
rtype = calloc(1, sizeof(resource_type));
|
||||
if (!rtype) {
|
||||
perror("resource_type allocation failed");
|
||||
}
|
||||
else {
|
||||
rtype->_name = _strdup(name);
|
||||
rt_register(rtype);
|
||||
}
|
||||
}
|
||||
return rtype;
|
||||
}
|
||||
|
|
|
@ -185,6 +185,39 @@ static void json_construction(cJSON *json, construction **consp) {
|
|||
*consp = cons;
|
||||
}
|
||||
|
||||
static void json_terrain_production(cJSON *json, terrain_production *prod) {
|
||||
assert(json->type == cJSON_Object);
|
||||
cJSON *child;
|
||||
for (child = json->child; child; child = child->next) {
|
||||
switch (child->type) {
|
||||
case cJSON_String:
|
||||
if (strcmp(child->string, "base") == 0) {
|
||||
prod->base = _strdup(child->valuestring);
|
||||
}
|
||||
else if (strcmp(child->string, "level") == 0) {
|
||||
prod->startlevel = _strdup(child->valuestring);
|
||||
}
|
||||
else if (strcmp(child->string, "div") == 0) {
|
||||
prod->divisor = _strdup(child->valuestring);
|
||||
}
|
||||
else {
|
||||
log_error("terrain_production %s contains unknown attribute %s", json->string, child->string);
|
||||
}
|
||||
break;
|
||||
case cJSON_Number:
|
||||
if (strcmp(child->string, "chance") == 0) {
|
||||
prod->chance = (float)child->valuedouble;
|
||||
}
|
||||
else {
|
||||
log_error("terrain_production %s contains unknown attribute %s", json->string, child->string);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
log_error("terrain_production %s contains unknown attribute %s", json->string, child->string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void json_terrain(cJSON *json, terrain_type *ter) {
|
||||
cJSON *child;
|
||||
if (json->type != cJSON_Object) {
|
||||
|
@ -193,6 +226,26 @@ static void json_terrain(cJSON *json, terrain_type *ter) {
|
|||
}
|
||||
for (child = json->child; child; child = child->next) {
|
||||
switch (child->type) {
|
||||
case cJSON_Object:
|
||||
if (strcmp(child->string, "production") == 0) {
|
||||
cJSON *entry;
|
||||
int n, size = cJSON_GetArraySize(child);
|
||||
ter->production = (terrain_production *)calloc(size + 1, sizeof(const item_type *));
|
||||
ter->production[size].type = 0;
|
||||
for (n = 0, entry = child->child; entry; entry = entry->next, ++n) {
|
||||
ter->production[n].type = rt_get_or_create(entry->string);
|
||||
if (entry->type != cJSON_Object) {
|
||||
log_error("terrain %s contains invalid production %s", json->string, entry->string);
|
||||
}
|
||||
else {
|
||||
json_terrain_production(entry, ter->production + n);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_error("terrain %s contains unknown attribute %s", json->string, child->string);
|
||||
}
|
||||
break;
|
||||
case cJSON_Array:
|
||||
if (strcmp(child->string, "flags") == 0) {
|
||||
const char * flags[] = {
|
||||
|
@ -200,10 +253,29 @@ static void json_terrain(cJSON *json, terrain_type *ter) {
|
|||
};
|
||||
ter->flags = json_flags(child, flags);
|
||||
}
|
||||
else if (strcmp(child->string, "herbs") == 0) {
|
||||
cJSON *entry;
|
||||
int n, size = cJSON_GetArraySize(child);
|
||||
ter->herbs = malloc(sizeof(const item_type *) * (size+1));
|
||||
ter->herbs[size] = 0;
|
||||
for (n = 0, entry = child->child; entry; entry = entry->next) {
|
||||
ter->herbs[n++] = it_get_or_create(rt_get_or_create(entry->valuestring));
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_error("terrain %s contains unknown attribute %s", json->string, child->string);
|
||||
}
|
||||
break;
|
||||
case cJSON_Number:
|
||||
if (strcmp(child->string, "size") == 0) {
|
||||
ter->size = child->valueint;
|
||||
}
|
||||
else if (strcmp(child->string, "road") == 0) {
|
||||
ter->max_road = (short)child->valueint;
|
||||
}
|
||||
else if (strcmp(child->string, "seed") == 0) {
|
||||
ter->distribution = (short)child->valueint;
|
||||
}
|
||||
default:
|
||||
log_error("terrain %s contains unknown attribute %s", json->string, child->string);
|
||||
}
|
||||
|
|
|
@ -389,7 +389,13 @@ static void test_configs(CuTest * tc)
|
|||
|
||||
static void test_terrains(CuTest * tc)
|
||||
{
|
||||
const char * data = "{\"terrains\": { \"plain\" : { \"flags\" : [ \"land\", \"fly\", \"walk\" ] } }}";
|
||||
const char * data = "{\"terrains\": { \"plain\" : { "
|
||||
"\"herbs\": [ \"h0\", \"h1\" ], "
|
||||
"\"production\": { \"stone\": { \"chance\": 0.1, \"base\": \"1d4\", \"div\": \"1d5\", \"level\": \"1d6\" }, \"iron\": {} }, "
|
||||
"\"size\": 4000, "
|
||||
"\"road\": 50, "
|
||||
"\"seed\": 3, "
|
||||
"\"flags\" : [ \"forbidden\", \"arctic\", \"cavalry\", \"sea\", \"forest\", \"land\", \"sail\", \"fly\", \"swim\", \"walk\" ] } }}";
|
||||
const terrain_type *ter;
|
||||
|
||||
cJSON *json = cJSON_Parse(data);
|
||||
|
@ -401,7 +407,19 @@ static void test_terrains(CuTest * tc)
|
|||
json_config(json);
|
||||
ter = get_terrain("plain");
|
||||
CuAssertPtrNotNull(tc, ter);
|
||||
CuAssertIntEquals(tc, ter->flags, LAND_REGION | FLY_INTO | WALK_INTO);
|
||||
CuAssertIntEquals(tc, ARCTIC_REGION | LAND_REGION | SEA_REGION | FOREST_REGION | CAVALRY_REGION | FORBIDDEN_REGION | FLY_INTO | WALK_INTO | SWIM_INTO | SAIL_INTO, ter->flags);
|
||||
CuAssertIntEquals(tc, 4000, ter->size);
|
||||
CuAssertIntEquals(tc, 50, ter->max_road);
|
||||
CuAssertIntEquals(tc, 3, ter->distribution);
|
||||
CuAssertPtrNotNull(tc, ter->herbs);
|
||||
CuAssertPtrEquals(tc, rt_get_or_create("h0"), ter->herbs[0]->rtype);
|
||||
CuAssertPtrEquals(tc, rt_get_or_create("h1"), ter->herbs[1]->rtype);
|
||||
CuAssertPtrEquals(tc, 0, (void *)ter->herbs[2]);
|
||||
CuAssertPtrNotNull(tc, ter->name); // anything named "plain" uses plain_name()
|
||||
CuAssertPtrNotNull(tc, ter->production);
|
||||
CuAssertPtrEquals(tc, rt_get_or_create("stone"), (resource_type *)ter->production[0].type);
|
||||
CuAssertPtrEquals(tc, rt_get_or_create("iron"), (resource_type *)ter->production[1].type);
|
||||
CuAssertPtrEquals(tc, 0, (void *)ter->production[2].type);
|
||||
|
||||
test_cleanup();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue