diff --git a/conf/e2/config.json b/conf/e2/config.json index 1ac8fc195..c8bedf2b3 100644 --- a/conf/e2/config.json +++ b/conf/e2/config.json @@ -1,6 +1,7 @@ { "include": [ - "keywords.json" + "keywords.json", + "e2/terrains.json" ], "settings": { "game.id": 2, diff --git a/conf/e2/config.xml b/conf/e2/config.xml index 367f43c29..cea730405 100644 --- a/conf/e2/config.xml +++ b/conf/e2/config.xml @@ -20,8 +20,6 @@ - - diff --git a/conf/e2/terrains.json b/conf/e2/terrains.json new file mode 100644 index 000000000..709f1b1a4 --- /dev/null +++ b/conf/e2/terrains.json @@ -0,0 +1,296 @@ +{ + "terrains": { + "ocean": { + "size": 100, + "flags": [ "swim", "sea", "sail", "fly" ] + }, + "plain": { + "size": 10000, + "herbs": [ "h0", "h1", "h2", "h3", "h4", "h5" ], + "seed": 3, + "road": 50, + "flags": [ "land", "walk", "sail", "fly" ], + "production": { + "iron": { + "chance": 0.1, + "base": "5d8", + "div": "2d20+10", + "level": "2d4-1" + }, + "stone": { + "chance": 0.15, + "base": "5d8", + "div": "2d30+20", + "level": "1d4" + }, + "laen": { + "chance": 0.01, + "base": "1d4", + "div": "2d20+50", + "level": "1d4" + } + } + }, + "swamp": { + "size": 2000, + "herbs": [ "h6", "h7", "h8" ], + "seed": 2, + "road": 75, + "flags": [ "land", "walk", "sail", "fly" ], + "production": { + "iron": { + "chance": 0.02, + "base": "5d8", + "div": "2d20+10", + "level": "2d4-1" + }, + "stone": { + "chance": 0.02, + "base": "5d8", + "div": "2d30+20", + "level": "1d4" + }, + "laen": { + "chance": 0.02, + "base": "1d4", + "div": "2d20+50", + "level": "1d4" + } + } + }, + "desert": { + "size": 500, + "herbs": [ "h9", "h10", "h11" ], + "seed": 2, + "road": 100, + "flags": [ "land", "walk", "sail", "fly", "cavalry" ], + "production": { + "iron": { + "chance": 0.15, + "base": "5d8", + "div": "2d20+10", + "level": "2d4-1" + }, + "stone": { + "chance": 0.25, + "base": "5d8", + "div": "2d30+20", + "level": "1d4" + }, + "laen": { + "chance": 0.025, + "base": "1d4", + "div": "2d20+50", + "level": "1d4" + } + } + }, + "highland": { + "size": 4000, + "herbs": [ "h12", "h13", "h14" ], + "seed": 2, + "road": 100, + "flags": [ "land", "walk", "sail", "fly", "cavalry" ], + "production": { + "iron": { + "chance": 0.15, + "base": "5d8", + "div": "2d20+10", + "level": "2d4-1" + }, + "stone": { + "chance": 0.25, + "base": "5d8", + "div": "2d30+20", + "level": "1d4" + }, + "laen": { + "chance": 0.025, + "base": "1d4", + "div": "2d20+50", + "level": "1d4" + } + } + }, + "mountain": { + "size": 1000, + "herbs": [ "h15", "h16", "h17" ], + "seed": 2, + "road": 250, + "flags": [ "land", "walk", "sail", "fly" ], + "production": { + "iron": { + "chance": 1.0, + "base": "50", + "div": "50", + "level": "1" + }, + "stone": { + "chance": 1.0, + "base": "100", + "div": "100", + "level": "1" + }, + "laen": { + "chance": 0.05, + "base": "4", + "div": "100", + "level": "1" + } + } + }, + "glacier": { + "size": 100, + "herbs": [ "h15", "h16", "h17" ], + "seed": 2, + "road": 250, + "flags": [ "arctic", "land", "walk", "sail", "fly" ], + "production": { + "iron": { + "chance": 1.0, + "base": "3", + "div": "50", + "level": "1" + }, + "stone": { + "chance": 1.0, + "base": "2", + "div": "100", + "level": "1" + }, + "laen": { + "chance": 0.05, + "base": "4", + "div": "100", + "level": "1" + } + } + }, + "iceberg": { + "size": 100, + "herbs": [ "h18", "h19", "h20" ], + "flags": [ "arctic", "land", "walk", "sail", "fly" ], + "production": { + "iron": { + "chance": 0.9, + "base": "3", + "div": "50", + "level": "1" + }, + "stone": { + "chance": 0.9, + "base": "2", + "div": "100", + "level": "1" + } + } + }, + "iceberg_sleep": { + "size": 100, + "herbs": [ "h18", "h19", "h20" ], + "flags": [ "arctic", "land", "walk", "sail", "fly" ], + "production": { + "iron": { + "chance": 0.9, + "base": "3", + "div": "50", + "level": "1" + }, + "stone": { + "chance": 0.9, + "base": "2", + "div": "100", + "level": "1" + }, + "laen": { + "chance": 0.05, + "base": "4", + "div": "100", + "level": "1" + } + } + }, + "firewall": { + "size": 100, + "road": 250, + "flags": [ "forbidden" ] + }, + "fog": { + "flags": [ "walk", "fly" ] + }, + "thickfog": { + "flags": [ "forbidden" ] + }, + "volcano": { + "size": 500, + "road": 250, + "seed": 1, + "flags": [ "land", "walk", "sail", "fly" ], + "production": { + "iron": { + "chance": 0.5, + "level": 1, + "base": 50, + "div": 50 + }, + "stone": { + "chance": 0.5, + "level": 1, + "base": 100, + "div": 100 + }, + "laen": { + "chance": 0.075, + "level": 1, + "base": 4, + "div": 100 + } + } + }, + "activevolcano": { + "size": 500, + "road": 250, + "flags": [ "land", "walk", "sail", "fly" ], + "production": { + "iron": { + "chance": 0.5, + "level": 1, + "base": 50, + "div": 50 + }, + "stone": { + "chance": 0.5, + "level": 1, + "base": 100, + "div": 100 + }, + "laen": { + "chance": 0.075, + "level": 1, + "base": 4, + "div": 100 + } + } + }, + "hell": { + "flags": [ "land", "walk" ] + }, + "hall1": { + "flags": [ "land", "walk", "sail" ] + }, + "corridor1": { + "flags": [ "land", "walk", "sail" ] + }, + "wall1": { + "flags": [ "forbidden" ] + }, + "default": { + "size": 0, + "herbs": [], + "seed": 0, + "road": 0, + "flags": [ "land", "walk", "sail", "fly" ], + "production": {} + } + } +} diff --git a/conf/e3/config.json b/conf/e3/config.json index 33b0aa52d..d28dda80f 100644 --- a/conf/e3/config.json +++ b/conf/e3/config.json @@ -1,6 +1,7 @@ { "include": [ - "keywords.json" + "keywords.json", + "e3/terrains.json" ], "settings": { "game.id": 3, diff --git a/conf/e3/config.xml b/conf/e3/config.xml index a1dff207a..f1f403ecd 100644 --- a/conf/e3/config.xml +++ b/conf/e3/config.xml @@ -14,7 +14,6 @@ - diff --git a/conf/e3/terrains.json b/conf/e3/terrains.json new file mode 100644 index 000000000..2688312ab --- /dev/null +++ b/conf/e3/terrains.json @@ -0,0 +1,235 @@ +{ + "terrains": { + "ocean": { + "size": 100, + "flags": [ "sea", "swim", "sail", "fly" ] + }, + "plain": { + "size": 4000, + "herbs": [ "h0", "h4" ], + "seed": 3, + "road": 50, + "flags": [ "forest", "cavalry", "land", "walk", "sail", "fly" ], + "production": { + "iron": { + "chance": 0.1, + "level": "2d4-1", + "base": "5d8", + "div": "2d20+10" + }, + "stone": { + "chance": 0.15, + "level": "1d4", + "base": "5d8", + "div": "2d30+20" + }, + "laen": { + "chance": 0.01, + "level": "1d4", + "base": "1d4", + "div": "2d20+50" + } + } + }, + "swamp": { + "size": 1200, + "herbs": [ "h6", "h8" ], + "seed": 2, + "road": 75, + "flags": [ "land", "walk", "sail", "fly" ], + "production": { + "iron": { + "chance": 0.02, + "level": "2d4-1", + "base": "5d8", + "div": "2d20+10" + }, + "stone": { + "chance": 0.02, + "level": "1d4", + "base": "5d8", + "div": "2d30+20" + }, + "laen": { + "chance": 0.02, + "level": "1d4", + "base": "1d4", + "div": "2d20+50" + } + } + }, + "desert": { + "size": 400, + "seed": 2, + "road": 75, + "flags": [ "cavalry", "land", "walk", "sail", "fly" ], + "herbs": [ "h9", "h11" ], + "production": { + "iron": { + "chance": 0.15, + "level": "2d4-1", + "base": "5d8", + "div": "2d20+10" + }, + "stone": { + "chance": 0.25, + "level": "1d4", + "base": "5d8", + "div": "2d30+20" + }, + "laen": { + "chance": 0.025, + "level": "1d4", + "base": "1d4", + "div": "2d20+50" + } + } + }, + "highland": { + "size": 2300, + "seed": 2, + "road": 100, + "flags": [ "cavalry", "land", "walk", "sail", "fly" ], + "herbs": [ "h12", "h14" ], + "production": { + "iron": { + "chance": 0.15, + "level": "2d4-1", + "base": "5d8", + "div": "2d20+10" + }, + "stone": { + "chance": 0.25, + "level": "1d4", + "base": "5d8", + "div": "2d30+20" + }, + "laen": { + "chance": 0.025, + "level": "1d4", + "base": "1d4", + "div": "2d20+50" + } + } + }, + "mountain": { + "size": 600, + "seed": 2, + "road": 250, + "flags": [ "land", "walk", "sail", "fly" ], + "herbs": [ "h15", "h17" ], + "production": { + "iron": { + "chance": 1.0, + "level": "1", + "base": "50", + "div": "50" + }, + "stone": { + "chance": 1.0, + "level": "1", + "base": "100", + "div": "100" + }, + "laen": { + "chance": 0.05, + "level": "1", + "base": "4", + "div": "100" + } + } + }, + "glacier": { + "size": 150, + "seed": 2, + "road": 250, + "flags": [ "arctic", "land", "walk", "sail", "fly" ], + "herbs": [ "h18", "h20" ], + "production": { + "iron": { + "chance": 1.0, + "level": "1", + "base": "3", + "div": "50" + }, + "stone": { + "chance": 1.0, + "level": "1", + "base": "2", + "div": "100" + }, + "laen": { + "chance": 0.05, + "level": "1", + "base": "4", + "div": "100" + } + } + }, + "packice": { + "flags": [ "arctic", "swim", "walk", "sail", "fly" ] + }, + "firewall": { + "flags": [ "forbidden" ] + }, + "volcano": { + "size": 400, + "seed": 1, + "road": 250, + "flags": [ "land", "walk", "sail", "fly" ], + "production": { + "iron": { + "chance": 0.5, + "level": "1", + "base": "50", + "div": "50" + }, + "stone": { + "chance": 0.5, + "level": "1", + "base": "100", + "div": "100" + }, + "laen": { + "chance": 0.075, + "level": "1", + "base": "4", + "div": "100" + } + } + }, + "activevolcano": { + "size": 400, + "road": 250, + "flags": [ "land", "walk", "sail", "fly" ], + "production": { + "iron": { + "chance": 0.5, + "level": "1", + "base": "50", + "div": "50" + }, + "stone": { + "chance": 0.5, + "level": "1", + "base": "100", + "div": "100" + }, + "laen": { + "chance": 0.075, + "level": "1", + "base": "4", + "div": "100" + } + } + }, + "default": { + "size": 0, + "herbs": [], + "seed": 0, + "road": 0, + "flags": [ "land", "walk", "sail", "fly" ], + "production": {} + } + } +} \ No newline at end of file diff --git a/conf/e4/config.json b/conf/e4/config.json index 0f31d8362..b6a0e16ab 100644 --- a/conf/e4/config.json +++ b/conf/e4/config.json @@ -1,6 +1,7 @@ { "include": [ - "keywords.json" + "keywords.json", + "e3/terrains.xml" ], "settings": { "game.id": 4, diff --git a/conf/e4/config.xml b/conf/e4/config.xml index 8e0fad67c..011f19821 100644 --- a/conf/e4/config.xml +++ b/conf/e4/config.xml @@ -14,7 +14,6 @@ - diff --git a/res/core/messages.xml b/res/core/messages.xml index 084ffd20a..43939b2b4 100644 --- a/res/core/messages.xml +++ b/res/core/messages.xml @@ -6425,7 +6425,7 @@ - "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat soetwas nicht." + "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat so etwas nicht." "$unit($unit) in $region($region): '$order($command)' - The unit does not have this." diff --git a/res/core/terrains.xml b/res/core/terrains.xml deleted file mode 100644 index 67238c966..000000000 --- a/res/core/terrains.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/e3a/terrains.xml b/res/e3a/terrains.xml deleted file mode 100644 index 8d9d6f17a..000000000 --- a/res/e3a/terrains.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/eressea/terrains.xml b/res/eressea/terrains.xml deleted file mode 100644 index e506c5dd4..000000000 --- a/res/eressea/terrains.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/res/terrains.xml b/res/terrains.xml deleted file mode 100644 index f5786d42a..000000000 --- a/res/terrains.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/kernel/item.c b/src/kernel/item.c index f801cf226..4aab13112 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -54,6 +54,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* libc includes */ #include +#include #include #include @@ -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; } diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index 7b2297146..b9fe278b5 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -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,29 @@ 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 size = cJSON_GetArraySize(child); + if (size > 0) { + int n; + ter->production = (terrain_production *)calloc(size + 1, sizeof(terrain_production)); + 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,6 +256,32 @@ 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 size = cJSON_GetArraySize(child); + if (size > 0) { + int n; + 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; + } else { log_error("terrain %s contains unknown attribute %s", json->string, child->string); } @@ -702,14 +784,20 @@ static void json_include(cJSON *json) { fclose(F); config = cJSON_Parse(data); free(data); - json_config(config); - cJSON_Delete(config); + if (config) { + json_config(config); + cJSON_Delete(config); + } + else { + log_error("invalid JSON, could not parse %s", child->valuestring); + } } } } void json_config(cJSON *json) { cJSON *child; + assert(json); if (json->type != cJSON_Object) { log_error("config is not a json object: %d", json->type); return; @@ -751,6 +839,7 @@ void json_config(cJSON *json) { } else if (strcmp(child->string, "terrains") == 0) { json_terrains(child); + init_terrains(); } else { log_error("config contains unknown attribute %s", child->string); diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c index c317fc15a..2fd8e3efe 100644 --- a/src/kernel/jsonconf.test.c +++ b/src/kernel/jsonconf.test.c @@ -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,23 @@ 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); + CuAssertDblEquals(tc, 0.1, ter->production[0].chance, 0.01); + CuAssertStrEquals(tc, "1d4", ter->production[0].base); + CuAssertStrEquals(tc, "1d5", ter->production[0].divisor); + CuAssertStrEquals(tc, "1d6", ter->production[0].startlevel); + CuAssertPtrEquals(tc, rt_get_or_create("iron"), (resource_type *)ter->production[1].type); + CuAssertPtrEquals(tc, 0, (void *)ter->production[2].type); test_cleanup(); } diff --git a/src/kernel/region.c b/src/kernel/region.c index 8b82edbea..1b4bf838e 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -1119,14 +1119,19 @@ void terraform_region(region * r, const terrain_type * terrain) } if (oldterrain == NULL || terrain->size != oldterrain->size) { + int horses = 0, trees = 0; + if (terrain->size>0) { + horses = rng_int() % (terrain->size / 50); + trees = terrain->size * (30 + rng_int() % 40) / 1000; + } if (terrain == newterrain(T_PLAIN)) { - rsethorses(r, rng_int() % (terrain->size / 50)); - if (rng_int() % 100 < 40) { - rsettrees(r, 2, terrain->size * (30 + rng_int() % 40) / 1000); + rsethorses(r, horses); + if (chance(0.4)) { + rsettrees(r, 2, trees); } } - else if (chance(0.2)) { - rsettrees(r, 2, terrain->size * (30 + rng_int() % 40) / 1000); + else if (trees>0 && chance(0.2)) { + rsettrees(r, 2, trees); } else { rsettrees(r, 2, 0); @@ -1146,7 +1151,7 @@ void terraform_region(region * r, const terrain_type * terrain) /** ENNO: * ich denke, das das hier nicht sein sollte. - * statt dessen sollte ein attribut an der region sein, das das erledigt, + * statt dessen sollte ein attribut an der region sein, dass das erledigt, * egal ob durch den spell oder anderes angelegt. **/ #include "curse.h" diff --git a/src/kernel/terrain.c b/src/kernel/terrain.c index f27fe1bd0..e72e94bfa 100644 --- a/src/kernel/terrain.c +++ b/src/kernel/terrain.c @@ -59,10 +59,18 @@ static terrain_type *registered_terrains; void free_terrains(void) { while (registered_terrains) { + int n; terrain_type * t = registered_terrains; registered_terrains = t->next; free(t->_name); - free(t->production); + if (t->production) { + for (n = 0; t->production[n].type; ++n) { + free(t->production[n].base); + free(t->production[n].divisor); + free(t->production[n].startlevel); + } + free(t->production); + } free(t); } } diff --git a/src/kernel/terrain.h b/src/kernel/terrain.h index 64b0aa299..945d07794 100644 --- a/src/kernel/terrain.h +++ b/src/kernel/terrain.h @@ -51,9 +51,9 @@ extern "C" { typedef struct terrain_production { const struct resource_type *type; - const char *startlevel; - const char *base; - const char *divisor; + char *startlevel; + char *base; + char *divisor; float chance; } terrain_production; diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 2deb15be7..5d8f081cc 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1883,131 +1883,6 @@ static int parse_races(xmlDocPtr doc) return 0; } -static int parse_terrains(xmlDocPtr doc) -{ - xmlXPathContextPtr xpath; - xmlXPathObjectPtr terrains; - xmlNodeSetPtr nodes; - int i; - - xpath = xmlXPathNewContext(doc); - - /* reading eressea/terrains/terrain */ - terrains = - xmlXPathEvalExpression(BAD_CAST "/eressea/terrains/terrain", xpath); - nodes = terrains->nodesetval; - for (i = 0; i != nodes->nodeNr; ++i) { - xmlNodePtr node = nodes->nodeTab[i]; - terrain_type *terrain; - xmlChar *propValue; - xmlXPathObjectPtr xpathChildren; - xmlNodeSetPtr children; - - propValue = xmlGetProp(node, BAD_CAST "name"); - assert(propValue != NULL); - terrain = get_or_create_terrain((const char *)propValue); - xmlFree(propValue); - - terrain->max_road = (short)xml_ivalue(node, "road", 0); - assert(terrain->max_road >= 0); - terrain->size = xml_ivalue(node, "size", 0); - - if (xml_bvalue(node, "forbidden", false)) - terrain->flags |= FORBIDDEN_REGION; - else { - if (xml_bvalue(node, "fly", true)) - terrain->flags |= FLY_INTO; - if (xml_bvalue(node, "sail", true)) - terrain->flags |= SAIL_INTO; - if (xml_bvalue(node, "walk", true)) - terrain->flags |= WALK_INTO; - if (xml_bvalue(node, "swim", false)) - terrain->flags |= SWIM_INTO; - if (xml_bvalue(node, "cavalry", false)) - terrain->flags |= CAVALRY_REGION; - } - if (xml_bvalue(node, "sea", false)) - terrain->flags |= SEA_REGION; - if (xml_bvalue(node, "arctic", false)) - terrain->flags |= ARCTIC_REGION; - if (xml_bvalue(node, "land", true)) - terrain->flags |= LAND_REGION; - if (xml_bvalue(node, "forest", false)) - terrain->flags |= FOREST_REGION; - - terrain->distribution = (short)xml_ivalue(node, "seed", 0); - - xpath->node = node; - xpathChildren = xmlXPathEvalExpression(BAD_CAST "herb", xpath); - children = xpathChildren->nodesetval; - if (children->nodeNr > 0) { - int k; - - terrain->herbs = malloc((children->nodeNr + 1) * sizeof(item_type *)); - terrain->herbs[children->nodeNr] = NULL; - for (k = 0; k != children->nodeNr; ++k) { - xmlNodePtr nodeHerb = children->nodeTab[k]; - const struct resource_type *rtype; - - propValue = xmlGetProp(nodeHerb, BAD_CAST "name"); - assert(propValue != NULL); - rtype = rt_find((const char *)propValue); - assert(rtype != NULL && rtype->itype != NULL - && fval(rtype->itype, ITF_HERB)); - terrain->herbs[k] = rtype->itype; - xmlFree(propValue); - } - } - xmlXPathFreeObject(xpathChildren); - - xpath->node = node; - xpathChildren = xmlXPathEvalExpression(BAD_CAST "resource", xpath); - children = xpathChildren->nodesetval; - if (children->nodeNr > 0) { - int k; - - terrain->production = - malloc((children->nodeNr + 1) * sizeof(terrain_production)); - terrain->production[children->nodeNr].type = NULL; - for (k = 0; k != children->nodeNr; ++k) { - xmlNodePtr nodeProd = children->nodeTab[k]; - - propValue = xmlGetProp(nodeProd, BAD_CAST "name"); - assert(propValue != NULL); - terrain->production[k].type = rt_find((const char *)propValue); - assert(terrain->production[k].type); - xmlFree(propValue); - - propValue = xmlGetProp(nodeProd, BAD_CAST "level"); - assert(propValue); - terrain->production[k].startlevel = _strdup((const char *)propValue); - xmlFree(propValue); - - propValue = xmlGetProp(nodeProd, BAD_CAST "base"); - assert(propValue); - terrain->production[k].base = _strdup((const char *)propValue); - xmlFree(propValue); - - propValue = xmlGetProp(nodeProd, BAD_CAST "div"); - assert(propValue); - terrain->production[k].divisor = _strdup((const char *)propValue); - xmlFree(propValue); - - terrain->production[k].chance = - (float)xml_fvalue(nodeProd, "chance", 1.0); - } - } - xmlXPathFreeObject(xpathChildren); - - } - xmlXPathFreeObject(terrains); - - xmlXPathFreeContext(xpath); - - init_terrains(); - return 0; -} - static int parse_messages(xmlDocPtr doc) { xmlXPathContextPtr xpath; @@ -2287,7 +2162,6 @@ void register_xmlreader(void) xml_register_callback(parse_resources); xml_register_callback(parse_rules); - xml_register_callback(parse_terrains); /* requires resources */ xml_register_callback(parse_buildings); /* requires resources */ xml_register_callback(parse_ships); /* requires terrains */ xml_register_callback(parse_spells); /* requires resources */ diff --git a/src/move.test.c b/src/move.test.c index 4e2b5f41e..de515be16 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -215,6 +215,31 @@ static void test_walkingcapacity(CuTest *tc) { test_cleanup(); } +static void test_is_guarded(CuTest *tc) { + unit *u1, *u2; + region *r; + race *rc; + + test_cleanup(); + rc = rc_get_or_create("dragon"); + rc->flags |= RCF_UNARMEDGUARD; + r = test_create_region(0, 0, 0); + u1 = test_create_unit(test_create_faction(0), r); + u2 = test_create_unit(test_create_faction(rc), r); + CuAssertPtrEquals(tc, 0, is_guarded(r, u1, GUARD_TRAVELTHRU)); + CuAssertPtrEquals(tc, 0, is_guarded(r, u1, GUARD_PRODUCE)); + CuAssertPtrEquals(tc, 0, is_guarded(r, u1, GUARD_TREES)); + CuAssertPtrEquals(tc, 0, is_guarded(r, u1, GUARD_MINING)); + guard(u2, GUARD_MINING | GUARD_PRODUCE); + CuAssertIntEquals(tc, GUARD_CREWS | GUARD_LANDING | GUARD_TRAVELTHRU | GUARD_TAX | GUARD_PRODUCE | GUARD_RECRUIT, guard_flags(u2)); + CuAssertPtrEquals(tc, 0, is_guarded(r, u1, GUARD_TRAVELTHRU)); + CuAssertPtrEquals(tc, 0, is_guarded(r, u1, GUARD_TREES)); + CuAssertPtrEquals(tc, 0, is_guarded(r, u1, GUARD_MINING)); + CuAssertPtrEquals(tc, u2, is_guarded(r, u1, GUARD_PRODUCE)); + + test_cleanup(); +} + CuSuite *get_move_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -226,5 +251,6 @@ CuSuite *get_move_suite(void) SUITE_ADD_TEST(suite, test_ship_has_harbormaster_contact); SUITE_ADD_TEST(suite, test_ship_has_harbormaster_ally); SUITE_ADD_TEST(suite, test_ship_has_harbormaster_same_faction); + SUITE_ADD_TEST(suite, test_is_guarded); return suite; }