From 9cf03d081efc0ad6f8e1177db88cd5f0bcd30fad Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 27 Jun 2014 07:57:48 -0700 Subject: [PATCH 1/3] missing compilation unit --- se/tests.vpj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/se/tests.vpj b/se/tests.vpj index 1c885c9f7..61729ef53 100644 --- a/se/tests.vpj +++ b/se/tests.vpj @@ -3,7 +3,7 @@ Version="10.0" VendorName="SlickEdit" TemplateName="GNU C/C++" - WorkingDir="." + WorkingDir=".." BuildSystem="vsbuild"> + @@ -283,7 +284,6 @@ Name="Other Files" Filters=""> - From 34ce9a05730d67b95a31e01f44e63293277a5889 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 28 Jun 2014 10:37:40 -0700 Subject: [PATCH 2/3] JSON configuration can read strings, with test. --- src/kernel/jsonconf.c | 32 ++++++++++++++++++++++++++++++++ src/kernel/jsonconf.test.c | 18 ++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index 415684e1b..52f34a754 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -329,6 +329,35 @@ void json_ships(cJSON *json) { } } +void json_locale(cJSON *json, struct locale *lang) { + cJSON *child; + if (json->type!=cJSON_Object) { + log_error_n("strings is not a json object: %d", json->type); + return; + } + for (child=json->child;child;child=child->next) { + if (child->type==cJSON_String) { + locale_setstring(lang, child->string, child->valuestring); + } + } +} + +void json_strings(cJSON *json) { + cJSON *child; + if (json->type!=cJSON_Object) { + log_error_n("strings is not a json object: %d", json->type); + return; + } + for (child=json->child;child;child=child->next) { + if ((child->type==cJSON_Object)) { + struct locale *lang = get_or_create_locale(child->string); + json_locale(child, lang); + } else { + log_error_n("strings for locale `%s` are not a json object: %d", child->string, child->type); + } + } +} + static void json_direction(cJSON *json, struct locale *lang) { cJSON *child; if (json->type!=cJSON_Object) { @@ -476,6 +505,9 @@ void json_config(cJSON *json) { else if (strcmp(child->string, "ships")==0) { json_ships(child); } + else if (strcmp(child->string, "strings")==0) { + json_strings(child); + } else if (strcmp(child->string, "directions")==0) { json_directions(child); } diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c index 52a4746f0..7dba7e145 100644 --- a/src/kernel/jsonconf.test.c +++ b/src/kernel/jsonconf.test.c @@ -262,6 +262,23 @@ static void test_keywords(CuTest * tc) test_cleanup(); } +static void test_strings(CuTest * tc) +{ + const char * data = "{\"strings\": { \"de\" : { \"move\" : \"NACH\", \"study\" : \"LERNEN\" }}}"; + const struct locale * lang; + + cJSON *json = cJSON_Parse(data); + CuAssertPtrNotNull(tc, json); + + test_cleanup(); + lang = get_or_create_locale("de"); + CuAssertPtrNotNull(tc, lang); + CuAssertPtrEquals(tc, NULL, (void *)locale_string(lang, "move")); + json_config(json); + CuAssertStrEquals(tc, "NACH", locale_string(lang, "move")); + CuAssertStrEquals(tc, "LERNEN", locale_string(lang, "study")); +} + CuSuite *get_jsonconf_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -273,6 +290,7 @@ CuSuite *get_jsonconf_suite(void) SUITE_ADD_TEST(suite, test_buildings); SUITE_ADD_TEST(suite, test_terrains); SUITE_ADD_TEST(suite, test_races); + SUITE_ADD_TEST(suite, test_strings); SUITE_ADD_TEST(suite, test_flags); return suite; } From 89e7a7826f1cb52cbdc163dc72b116ff46361e03 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 28 Jun 2014 16:19:46 -0700 Subject: [PATCH 3/3] added some tests for building buildings. --- se/tests.vpj | 4 ++ src/economy.c | 3 +- src/kernel/CMakeLists.txt | 1 + src/kernel/build.c | 46 ++++++++++++----------- src/kernel/build.test.c | 78 +++++++++++++++++++++++++++++++++++++++ src/kernel/building.h | 4 +- src/test_eressea.c | 2 + src/tests.c | 21 ++++++++--- 8 files changed, 128 insertions(+), 31 deletions(-) create mode 100644 src/kernel/build.test.c diff --git a/se/tests.vpj b/se/tests.vpj index 61729ef53..9f4e1362e 100644 --- a/se/tests.vpj +++ b/se/tests.vpj @@ -244,6 +244,7 @@ + @@ -283,12 +284,15 @@ + + + diff --git a/src/economy.c b/src/economy.c index 9d8586a4c..f906a2310 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1792,7 +1792,8 @@ int make_cmd(unit * u, struct order *ord) if (pl && fval(pl, PFL_NOBUILD)) { cmistake(u, ord, 94, MSG_PRODUCE); } else { - build_building(u, btype, m, ord); + int id = getid(); + build_building(u, btype, id, m, ord); } } else if (itype != NULL) { create_item(u, itype, m); diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index f6b940ef2..9840a241f 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -1,6 +1,7 @@ project(kernel C) SET(_TEST_FILES +build.test.c config.test.c ship.test.c spell.test.c diff --git a/src/kernel/build.c b/src/kernel/build.c index 86b390755..04014db4b 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -424,7 +424,7 @@ int build(unit * u, const construction * ctype, int completed, int want) if (want <= 0) return 0; if (type == NULL) - return 0; + return ENOMATERIALS; if (type->improvement == NULL && completed == type->maxsize) return ECOMPLETE; if (type->btype != NULL) { @@ -616,7 +616,7 @@ message *msg_materials_required(unit * u, order * ord, if (multi <= 0 || multi == INT_MAX) multi = 1; - for (c = 0; ctype->materials[c].number; ++c) { + for (c = 0; ctype && ctype->materials[c].number; ++c) { resource *res = malloc(sizeof(resource)); res->number = multi * ctype->materials[c].number / ctype->reqsize; res->type = ctype->materials[c].rtype; @@ -646,11 +646,11 @@ int maxbuild(const unit * u, const construction * cons) /** old build routines */ -void -build_building(unit * u, const building_type * btype, int want, order * ord) +int +build_building(unit * u, const building_type * btype, int id, int want, order * ord) { region *r = u->region; - int n = want, built = 0, id; + int n = want, built = 0; building *b = NULL; /* einmalige Korrektur */ const char *btname; @@ -659,9 +659,10 @@ build_building(unit * u, const building_type * btype, int want, order * ord) static int rule_other = -1; assert(u->number); + assert(btype->construction); if (eff_skill(u, SK_BUILDING, r) == 0) { cmistake(u, ord, 101, MSG_PRODUCE); - return; + return 0; } /* Falls eine Nummer angegeben worden ist, und ein Gebaeude mit der @@ -670,7 +671,6 @@ build_building(unit * u, const building_type * btype, int want, order * ord) * baut man an der eigenen burg weiter. */ /* Wenn die angegebene Nummer falsch ist, KEINE Burg bauen! */ - id = getid(); if (id > 0) { /* eine Nummer angegeben, keine neue Burg bauen */ b = findbuilding(id); if (!b || b->region != u->region) { /* eine Burg mit dieser Nummer gibt es hier nicht */ @@ -680,7 +680,7 @@ build_building(unit * u, const building_type * btype, int want, order * ord) } else { /* keine neue Burg anfangen wenn eine Nummer angegeben war */ cmistake(u, ord, 6, MSG_PRODUCE); - return; + return 0; } } } else if (u->building && u->building->type == btype) { @@ -693,27 +693,27 @@ build_building(unit * u, const building_type * btype, int want, order * ord) if (fval(btype, BTF_UNIQUE) && buildingtype_exists(r, btype, false)) { /* only one of these per region */ cmistake(u, ord, 93, MSG_PRODUCE); - return; + return 0; } if (besieged(u)) { /* units under siege can not build */ cmistake(u, ord, 60, MSG_PRODUCE); - return; + return 0; } if (btype->flags & BTF_NOBUILD) { /* special building, cannot be built */ cmistake(u, ord, 221, MSG_PRODUCE); - return; + return 0; } - if (r->terrain->max_road <= 0) { + if ((r->terrain->flags & LAND_REGION) == 0) { /* special terrain, cannot build */ cmistake(u, ord, 221, MSG_PRODUCE); - return; + return 0; } if (btype->flags & BTF_ONEPERTURN) { if (b && fval(b, BLD_EXPANDED)) { cmistake(u, ord, 318, MSG_PRODUCE); - return; + return 0; } n = 1; } @@ -726,7 +726,7 @@ build_building(unit * u, const building_type * btype, int want, order * ord) unit *owner = building_owner(b); if (!owner || owner->faction != u->faction) { cmistake(u, ord, 1222, MSG_PRODUCE); - return; + return 0; } } } @@ -754,18 +754,20 @@ build_building(unit * u, const building_type * btype, int want, order * ord) case ECOMPLETE: /* the building is already complete */ cmistake(u, ord, 4, MSG_PRODUCE); - return; + break; case ENOMATERIALS: - ADDMSG(&u->faction->msgs, msg_materials_required(u, ord, + ADDMSG(&u->faction->msgs, msg_materials_required(u, ord, btype->construction, want)); - return; + break; case ELOWSKILL: case ENEEDSKILL: /* no skill, or not enough skill points to build */ cmistake(u, ord, 50, MSG_PRODUCE); - return; + break; + } + if (built<=0) { + return built; } - /* at this point, the building size is increased. */ if (b == NULL) { /* build a new building */ @@ -784,7 +786,6 @@ build_building(unit * u, const building_type * btype, int want, order * ord) a->data.i = u->faction->alliance->id; } #endif - } btname = LOC(lang, btype->_name); @@ -817,13 +818,14 @@ build_building(unit * u, const building_type * btype, int want, order * ord) free_order(new_order); } - b->size += built; + b->size += built; fset(b, BLD_EXPANDED); update_lighthouse(b); ADDMSG(&u->faction->msgs, msg_message("buildbuilding", "building unit size", b, u, built)); + return built; } static void build_ship(unit * u, ship * sh, int want) diff --git a/src/kernel/build.test.c b/src/kernel/build.test.c new file mode 100644 index 000000000..2f40b3a96 --- /dev/null +++ b/src/kernel/build.test.c @@ -0,0 +1,78 @@ +#include +#include "types.h" +#include "build.h" +#include "order.h" +#include "unit.h" +#include "building.h" +#include "faction.h" +#include "region.h" +#include "race.h" +#include "item.h" +#include +#include +#include + +#include + +static void test_build_building_no_materials(CuTest *tc) { + unit *u; + region *r; + faction *f; + race *rc; + const building_type *btype; + + test_cleanup(); + test_create_world(); + + rc = test_create_race("human"); + r = findregion(0, 0); + f = test_create_faction(rc); + assert(rc && f && r); + u = test_create_unit(f, r); + btype = bt_find("castle"); + assert(u && btype); + set_level(u, SK_BUILDING, 1); + CuAssertIntEquals(tc, ENOMATERIALS, build_building(u, btype, 0, 4, 0)); + CuAssertPtrEquals(tc, 0, r->buildings); + CuAssertPtrEquals(tc, 0, u->building); +} + +static void test_build_building_success(CuTest *tc) { + unit *u; + region *r; + faction *f; + race *rc; + const building_type *btype; + const resource_type *rtype; + + test_cleanup(); + test_create_world(); + + rc = test_create_race("human"); + rtype = get_resourcetype(R_STONE); + btype = bt_find("castle"); + assert(btype && rc && rtype && rtype->itype); +// TODO: assert(btype->construction); + r = findregion(0, 0); + assert(!r->buildings); + f = test_create_faction(rc); + assert(r && f); + u = test_create_unit(f, r); + assert(u); + i_change(&u->items, rtype->itype, 1); + set_level(u, SK_BUILDING, 1); + CuAssertIntEquals(tc, 1, build_building(u, btype, 0, 4, 0)); + CuAssertPtrNotNull(tc, r->buildings); + CuAssertPtrEquals(tc, r->buildings, u->building); + CuAssertIntEquals(tc, 1, u->building->size); + CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype)); +} + +CuSuite *get_build_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_build_building_success); + SUITE_ADD_TEST(suite, test_build_building_no_materials); + return suite; +} + diff --git a/src/kernel/building.h b/src/kernel/building.h index b0b4df798..ccf631e5f 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -125,8 +125,8 @@ extern "C" { extern int buildingcapacity(const struct building *b); extern struct building *new_building(const struct building_type *typ, struct region *r, const struct locale *lang); - void build_building(struct unit *u, const struct building_type *typ, int size, - struct order *ord); + int build_building(struct unit *u, const struct building_type *typ, + int id, int size, struct order *ord); /* Alte Gebäudetypen: */ diff --git a/src/test_eressea.c b/src/test_eressea.c index b887f0e59..00508bb9c 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -16,6 +16,7 @@ CuSuite *get_item_suite(void); CuSuite *get_magic_suite(void); CuSuite *get_move_suite(void); CuSuite *get_pool_suite(void); +CuSuite *get_build_suite(void); CuSuite *get_reports_suite(void); CuSuite *get_ship_suite(void); CuSuite *get_spellbook_suite(void); @@ -52,6 +53,7 @@ int RunAllTests(void) CuSuiteAddSuite(suite, get_functions_suite()); CuSuiteAddSuite(suite, get_umlaut_suite()); /* kernel */ + CuSuiteAddSuite(suite, get_build_suite()); CuSuiteAddSuite(suite, get_pool_suite()); CuSuiteAddSuite(suite, get_curse_suite()); CuSuiteAddSuite(suite, get_equipment_suite()); diff --git a/src/tests.c b/src/tests.c index 84c1595aa..a7edc4a4f 100644 --- a/src/tests.c +++ b/src/tests.c @@ -102,12 +102,20 @@ ship_type * test_create_shiptype(const char ** names) building_type * test_create_buildingtype(const char * name) { - building_type * btype = (building_type*)calloc(sizeof(building_type), 1); - btype->flags = BTF_NAMECHANGE; - btype->_name = _strdup(name); - locale_setstring(default_locale, name, name); - bt_register(btype); - return btype; + building_type *btype = (building_type *)calloc(sizeof(building_type), 1); + btype->flags = BTF_NAMECHANGE; + btype->_name = _strdup(name); + btype->construction = (construction *)calloc(sizeof(construction), 1); + btype->construction->skill = SK_BUILDING; + btype->construction->maxsize = -1; + btype->construction->minskill = 1; + btype->construction->reqsize = 1; + btype->construction->materials = (requirement *)calloc(sizeof(requirement), 1); + btype->construction->materials->number = 1; + btype->construction->materials->rtype = get_resourcetype(R_STONE); + locale_setstring(default_locale, name, name); + bt_register(btype); + return btype; } item_type * test_create_itemtype(const char ** names) { @@ -143,6 +151,7 @@ void test_create_world(void) t_plain = test_create_terrain("plain", LAND_REGION | FOREST_REGION | WALK_INTO | CAVALRY_REGION); t_plain->size = 1000; + t_plain->max_road = 100; t_ocean = test_create_terrain("ocean", SEA_REGION | SAIL_INTO | SWIM_INTO); t_ocean->size = 0;