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 */
|
/* libc includes */
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -179,10 +180,15 @@ static void rt_register(resource_type * rtype)
|
||||||
resource_type *rt_get_or_create(const char *name) {
|
resource_type *rt_get_or_create(const char *name) {
|
||||||
resource_type *rtype = rt_find(name);
|
resource_type *rtype = rt_find(name);
|
||||||
if (!rtype) {
|
if (!rtype) {
|
||||||
rtype = (resource_type *)calloc(sizeof(resource_type), 1);
|
rtype = calloc(1, sizeof(resource_type));
|
||||||
|
if (!rtype) {
|
||||||
|
perror("resource_type allocation failed");
|
||||||
|
}
|
||||||
|
else {
|
||||||
rtype->_name = _strdup(name);
|
rtype->_name = _strdup(name);
|
||||||
rt_register(rtype);
|
rt_register(rtype);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return rtype;
|
return rtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -185,6 +185,39 @@ static void json_construction(cJSON *json, construction **consp) {
|
||||||
*consp = cons;
|
*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) {
|
static void json_terrain(cJSON *json, terrain_type *ter) {
|
||||||
cJSON *child;
|
cJSON *child;
|
||||||
if (json->type != cJSON_Object) {
|
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) {
|
for (child = json->child; child; child = child->next) {
|
||||||
switch (child->type) {
|
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:
|
case cJSON_Array:
|
||||||
if (strcmp(child->string, "flags") == 0) {
|
if (strcmp(child->string, "flags") == 0) {
|
||||||
const char * flags[] = {
|
const char * flags[] = {
|
||||||
|
@ -200,10 +253,29 @@ static void json_terrain(cJSON *json, terrain_type *ter) {
|
||||||
};
|
};
|
||||||
ter->flags = json_flags(child, flags);
|
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 {
|
else {
|
||||||
log_error("terrain %s contains unknown attribute %s", json->string, child->string);
|
log_error("terrain %s contains unknown attribute %s", json->string, child->string);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
log_error("terrain %s contains unknown attribute %s", json->string, child->string);
|
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)
|
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;
|
const terrain_type *ter;
|
||||||
|
|
||||||
cJSON *json = cJSON_Parse(data);
|
cJSON *json = cJSON_Parse(data);
|
||||||
|
@ -401,7 +407,19 @@ static void test_terrains(CuTest * tc)
|
||||||
json_config(json);
|
json_config(json);
|
||||||
ter = get_terrain("plain");
|
ter = get_terrain("plain");
|
||||||
CuAssertPtrNotNull(tc, ter);
|
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();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue