diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index 8e5eef9ca..1848025bf 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -15,6 +15,7 @@ pool_test.c reports_test.c spellbook_test.c curse_test.c +jsonconf_test.c ) SET(_FILES @@ -56,6 +57,7 @@ teleport.c terrain.c unit.c xmlreader.c +jsonconf.c ) FOREACH(_FILE ${_FILES}) diff --git a/src/kernel/building.c b/src/kernel/building.c index 4cb556e3e..140c25eeb 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -154,6 +154,20 @@ void bt_register(building_type * type) ql_push(&buildingtypes, (void *)type); } +building_type *bt_get_or_create(const char *name) +{ + if (name != NULL) { + building_type *btype = bt_find(name); + if (btype == NULL) { + btype = calloc(sizeof(building_type), 1); + btype->_name = _strdup(name); + bt_register(btype); + } + return btype; + } + return NULL; +} + int buildingcapacity(const building * b) { if (b->type->capacity >= 0) { diff --git a/src/kernel/building.h b/src/kernel/building.h index c91fa01df..122bb45a2 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -73,10 +73,11 @@ extern "C" { extern struct quicklist *buildingtypes; - extern building_type *bt_find(const char *name); - extern void register_buildings(void); - extern void bt_register(struct building_type *type); - extern int bt_effsize(const struct building_type *btype, + building_type *bt_find(const char *name); + building_type *bt_get_or_create(const char *name); + void register_buildings(void); + void bt_register(struct building_type *type); + int bt_effsize(const struct building_type *btype, const struct building *b, int bsize); /* buildingt => building_type diff --git a/src/kernel/equipment_test.c b/src/kernel/equipment_test.c index a526c5abc..4c2268178 100644 --- a/src/kernel/equipment_test.c +++ b/src/kernel/equipment_test.c @@ -23,6 +23,7 @@ void test_equipment(CuTest * tc) sc_mage * mage; test_cleanup(); + test_create_race("human"); skill_enabled[SK_MAGIC] = 1; it_horses = test_create_itemtype(names); CuAssertPtrNotNull(tc, it_horses); diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c new file mode 100644 index 000000000..16e0fa28a --- /dev/null +++ b/src/kernel/jsonconf.c @@ -0,0 +1,147 @@ +/* vi: set ts=2: ++-------------------+ +| | Enno Rehling +| Eressea PBEM host | Christian Schlittchen +| (c) 1998 - 2004 | Katja Zedel +| | Henning Peters ++-------------------+ + +This program may not be used, modified or distributed +without prior permission by the authors of Eressea. +*/ + +#include +#include +#include "jsonconf.h" + +/* kernel includes */ +#include "building.h" +#include "equipment.h" +#include "item.h" +#include "message.h" +#include "race.h" +#include "region.h" +#include "resources.h" +#include "ship.h" +#include "terrain.h" +#include "skill.h" +#include "spell.h" +#include "spellbook.h" +#include "calendar.h" + +/* util includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* external libraries */ +#include + +/* libc includes */ +#include +#include +#include +#include + +void json_race(cJSON *json, race *rc) { + cJSON *child; + if (json->type!=cJSON_Object) { + log_error("race %s is not a json object: %d\n", json->string, json->type); + return; + } + for (child=json->child;child;child=child->next) { + switch(child->type) { + case cJSON_String: + if (strcmp(child->string, "damage")==0) { + rc->def_damage = _strdup(child->valuestring); + } + break; + case cJSON_Number: + if (strcmp(child->string, "magres")==0) { + rc->magres = (float)child->valuedouble; + } + else if (strcmp(child->string, "maxaura")==0) { + rc->maxaura = (float)child->valuedouble; + } + else if (strcmp(child->string, "regaura")==0) { + rc->regaura = (float)child->valuedouble; + } + else if (strcmp(child->string, "speed")==0) { + rc->speed = (float)child->valuedouble; + } + else if (strcmp(child->string, "recruitcost")==0) { + rc->recruitcost = child->valueint; + } + else if (strcmp(child->string, "maintenance")==0) { + rc->maintenance = child->valueint; + } + else if (strcmp(child->string, "weight")==0) { + rc->weight = child->valueint; + } + else if (strcmp(child->string, "capacity")==0) { + rc->capacity = child->valueint; + } + else if (strcmp(child->string, "hp")==0) { + rc->hitpoints = child->valueint; + } + else if (strcmp(child->string, "ac")==0) { + rc->armor = child->valueint; + } + // TODO: studyspeed (orcs only) + break; + case cJSON_True: { + const char *flags[] = { + "playerrace", "killpeasants", "scarepeasants", + "cansteal", "moverandom", "cannotmove", + "learn", "fly", "swim", "walk", "nolearn", + "noteach", "horse", "desert", + "illusionary", "absorbpeasants", "noheal", + "noweapons", "shapeshift", "", "undead", "dragon", + "coastal", "", "cansail", 0 + }; + int i; + for(i=0;flags[i];++i) { + const char * flag = flags[i]; + if (*flag && strcmp(child->string, flag)==0) { + rc->flags |= (1<type!=cJSON_Object) { + log_error("races is not a json object: %d\n", json->type); + return; + } + for (child=json->child;child;child=child->next) { + race * rc = rc_find(child->string); + if (!rc) { + rc = rc_add(rc_new((const char *)child->string)); + json_race(child, rc); + } + } +} + +void json_config(cJSON *json) { + cJSON *child; + if (json->type!=cJSON_Object) { + log_error("config is not a json object: %d\n", json->type); + return; + } + child = cJSON_GetObjectItem(json, "races"); + if (child && child->type==cJSON_Object) { + json_races(child); + } +} diff --git a/src/kernel/jsonconf.h b/src/kernel/jsonconf.h new file mode 100644 index 000000000..9d0f1467e --- /dev/null +++ b/src/kernel/jsonconf.h @@ -0,0 +1,25 @@ +/* vi: set ts=2: ++-------------------+ +| | Enno Rehling +| Eressea PBEM host | Christian Schlittchen +| (c) 1998 - 2007 | Katja Zedel +| | Henning Peters ++-------------------+ + +This program may not be used, modified or distributed +without prior permission by the authors of Eressea. +*/ + +#ifndef H_JSONCONF_H +#define H_JSONCONF_H +#ifdef __cplusplus +extern "C" { +#endif + + struct cJSON; + void json_config(struct cJSON *str); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/kernel/jsonconf_test.c b/src/kernel/jsonconf_test.c new file mode 100644 index 000000000..9056d3a24 --- /dev/null +++ b/src/kernel/jsonconf_test.c @@ -0,0 +1,78 @@ +#include +#include "types.h" +#include "jsonconf.h" +#include "race.h" +#include +#include +#include +#include + +static void test_flag(CuTest *tc, const char *name, int flag) { + char data[1024]; + const struct race *rc; + cJSON *json; + sprintf(data, "{\"races\" : { \"orc\": { \"%s\" : true }}}", name); + + json = cJSON_Parse(data); + free_races(); + json_config(json); + rc = rc_find("orc"); + CuAssertPtrNotNull(tc, rc); + CuAssertIntEquals(tc, flag, rc->flags); +} + +static void test_flags(CuTest *tc) { + test_flag(tc, "playerrace", RCF_PLAYERRACE); + test_flag(tc, "scarepeasants", RCF_SCAREPEASANTS); + test_flag(tc, "cansteal", RCF_CANSTEAL); + test_flag(tc, "noheal", RCF_NOHEAL); + test_flag(tc, "undead", RCF_UNDEAD); + test_flag(tc, "dragon", RCF_DRAGON); + test_flag(tc, "fly", RCF_FLY); +} + +static void test_races(CuTest * tc) +{ + const char * data = "{\"races\": { \"orc\" : { " + "\"damage\" : \"1d4\"," + "\"magres\" : 1.0," + "\"maxaura\" : 2.0," + "\"regaura\" : 3.0," + "\"speed\" : 4.0," + "\"recruitcost\" : 1," + "\"maintenance\" : 2," + "\"weight\" : 3," + "\"capacity\" : 4," + "\"hp\" : 5," + "\"ac\" : 6" + "}}}"; + cJSON *json = cJSON_Parse(data); + const struct race *rc; + test_cleanup(); + + CuAssertPtrEquals(tc, 0, races); + json_config(json); + + CuAssertPtrNotNull(tc, races); + rc = rc_find("orc"); + CuAssertPtrNotNull(tc, rc); + CuAssertStrEquals(tc, "1d4", rc->def_damage); + CuAssertDblEquals(tc, 1.0, rc->magres, 0.0); + CuAssertDblEquals(tc, 2.0, rc->maxaura, 0.0); + CuAssertDblEquals(tc, 3.0, rc->regaura, 0.0); + CuAssertDblEquals(tc, 4.0, rc->speed, 0.0); + CuAssertIntEquals(tc, 1, rc->recruitcost); + CuAssertIntEquals(tc, 2, rc->maintenance); + CuAssertIntEquals(tc, 3, rc->weight); + CuAssertIntEquals(tc, 4, rc->capacity); + CuAssertIntEquals(tc, 5, rc->hitpoints); + CuAssertIntEquals(tc, 6, rc->armor); +} + +CuSuite *get_jsonconf_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_races); + SUITE_ADD_TEST(suite, test_flags); + return suite; +} diff --git a/src/kernel/magic_test.c b/src/kernel/magic_test.c index 910eb27c4..044375d1d 100644 --- a/src/kernel/magic_test.c +++ b/src/kernel/magic_test.c @@ -25,7 +25,8 @@ void test_updatespells(CuTest * tc) spellbook *book = 0; test_cleanup(); - + test_create_race("human"); + f = test_create_faction(0); sp = create_spell("testspell", 0); CuAssertPtrNotNull(tc, sp); diff --git a/src/kernel/race.c b/src/kernel/race.c index 43df15f21..5fafd159f 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -98,6 +98,14 @@ void racelist_insert(struct race_list **rl, const struct race *r) *rl = rl2; } +void free_races(void) { + while (races) { + race * rc = races->next; + free(races); + races =rc; + } +} + race *rc_new(const char *zName) { char zBuffer[80]; diff --git a/src/kernel/race.h b/src/kernel/race.h index c6f511d44..ba9ae94ab 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -115,6 +115,7 @@ extern "C" { extern struct race *rc_new(const char *zName); extern int rc_specialdamage(const race *, const race *, const struct weapon_type *); + void free_races(void); /* Flags */ #define RCF_PLAYERRACE (1<<0) /* can be played by a player. */ diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index d2d88471c..540f36ee0 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -51,20 +51,6 @@ without prior permission by the authors of Eressea. #include #include -static building_type *bt_get_or_create(const char *name) -{ - if (name != NULL) { - building_type *btype = bt_find(name); - if (btype == NULL) { - btype = calloc(sizeof(building_type), 1); - btype->_name = _strdup(name); - bt_register(btype); - } - return btype; - } - return NULL; -} - static void xml_readtext(xmlNodePtr node, struct locale **lang, xmlChar ** text) { xmlChar *propValue = xmlGetProp(node, BAD_CAST "locale"); diff --git a/src/test_eressea.c b/src/test_eressea.c index 412e1e99b..5c4b815fe 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -3,6 +3,7 @@ #include CuSuite *get_tests_suite(void); +CuSuite *get_jsonconf_suite(void); CuSuite *get_json_suite(void); CuSuite *get_economy_suite(void); CuSuite *get_laws_suite(void); @@ -36,6 +37,7 @@ int RunAllTests(void) /* self-test */ CuSuiteAddSuite(suite, get_tests_suite()); CuSuiteAddSuite(suite, get_json_suite()); + CuSuiteAddSuite(suite, get_jsonconf_suite()); /* util */ CuSuiteAddSuite(suite, get_base36_suite()); CuSuiteAddSuite(suite, get_bsdstring_suite()); diff --git a/src/tests.c b/src/tests.c index 28baa367a..d4dcc7263 100644 --- a/src/tests.c +++ b/src/tests.c @@ -63,6 +63,7 @@ void test_cleanup(void) default_locale = 0; free_locales(); free_spells(); + free_races(); free_spellbooks(); free_gamedata(); }