From caa8159428ef17f0b2d0b668a0d00ada291b6c32 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 09:52:17 +0100 Subject: [PATCH 01/15] eliminate duplicate string definition --- res/core/de/strings.xml | 9 --------- src/report.c | 4 ++-- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/res/core/de/strings.xml b/res/core/de/strings.xml index 26e8cc862..5dc649aa1 100644 --- a/res/core/de/strings.xml +++ b/res/core/de/strings.xml @@ -6570,15 +6570,6 @@ - - Baum - tree - - - Bäume - trees - - Mallornbaum mallorn tree diff --git a/src/report.c b/src/report.c index cf00abbc3..6af46ba07 100644 --- a/src/report.c +++ b/src/report.c @@ -987,10 +987,10 @@ static void describe(struct stream *out, const region * r, faction * f) } } else if (trees == 1) { - bytes = (int)strlcpy(bufp, LOC(f->locale, "nr_tree"), size); + bytes = (int)strlcpy(bufp, LOC(f->locale, "tree"), size); } else { - bytes = (int)strlcpy(bufp, LOC(f->locale, "nr_tree_p"), size); + bytes = (int)strlcpy(bufp, LOC(f->locale, "tree_p"), size); } if (wrptr(&bufp, &size, bytes) != 0) WARN_STATIC_BUFFER(); From 614978a3433bf9250212b705784ca3996977ee58 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 10:26:39 +0100 Subject: [PATCH 02/15] add a breaking test for the CR. trees and peasants are not reported correctly. --- tests/write-reports.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/write-reports.sh b/tests/write-reports.sh index 2183b17dd..6581066f0 100755 --- a/tests/write-reports.sh +++ b/tests/write-reports.sh @@ -16,10 +16,10 @@ while [ ! -d $ROOT/.git ]; do ROOT=`dirname $ROOT` done -set -e +#set -e cd $ROOT/tests setup -cleanup +#cleanup VALGRIND=`which valgrind` TESTS=../Debug/eressea/test_eressea SERVER=../Debug/eressea/eressea @@ -34,10 +34,14 @@ $VALGRIND $SERVER -t 184 ../scripts/reports.lua [ -d reports ] || quit 4 "no reports directory created" CRFILE=184-zvto.cr grep -q PARTEI reports/$CRFILE || quit 1 "CR did not contain any factions" +grep -q -E '"B.ume";type"' reports/$CRFILE || \ + quit 1 "CR did not contain trees" +grep -q '"Bauern";type"' reports/$CRFILE || \ + quit 1 "CR did not contain peasants" grep -q REGION reports/$CRFILE || quit 2 "CR did not contain any regions" grep -q SCHIFF reports/$CRFILE || quit 3 "CR did not contain any ships" grep -q BURG reports/$CRFILE || quit 4 "CR did not contain any buildings" grep -q EINHEIT reports/$CRFILE || quit 5 "CR did not contain any units" grep -q GEGENSTAENDE reports/$CRFILE || quit 6 "CR did not contain any items" echo "integration tests: PASS" -cleanup +#cleanup From 5675ef6091ffc7bb08a1cfff25e9c0f07595d9ed Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 11:10:59 +0100 Subject: [PATCH 03/15] clean and extend the enum of resources. --- src/economy.c | 6 +++--- src/kernel/item.c | 22 +++++++++++++--------- src/kernel/item.h | 27 +++++++++++++++++++-------- src/modules/arena.c | 2 +- 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/economy.c b/src/economy.c index a3b300788..248344e47 100644 --- a/src/economy.c +++ b/src/economy.c @@ -2130,7 +2130,7 @@ static void planttrees(unit * u, int raw) } /* Mallornb�ume kann man nur in Mallornregionen z�chten */ - rtype = get_resourcetype(fval(r, RF_MALLORN) ? R_MALLORNSEED : R_SEED); + rtype = get_resourcetype(fval(r, RF_MALLORN) ? R_MALLORN_SEED : R_SEED); /* Skill pr�fen */ skill = effskill(u, SK_HERBALISM, 0); @@ -2195,7 +2195,7 @@ static void breedtrees(unit * u, int raw) } /* Mallornb�ume kann man nur in Mallornregionen z�chten */ - rtype = get_resourcetype(fval(r, RF_MALLORN) ? R_MALLORNSEED : R_SEED); + rtype = get_resourcetype(fval(r, RF_MALLORN) ? R_MALLORN_SEED : R_SEED); /* Skill pr�fen */ skill = effskill(u, SK_HERBALISM, 0); @@ -2313,7 +2313,7 @@ static void breed_cmd(unit * u, struct order *ord) default: if (p != P_ANY) { rtype = findresourcetype(s, u->faction->locale); - if (rtype == get_resourcetype(R_SEED) || rtype == get_resourcetype(R_MALLORNSEED)) { + if (rtype == get_resourcetype(R_SEED) || rtype == get_resourcetype(R_MALLORN_SEED)) { breedtrees(u, m); break; } diff --git a/src/kernel/item.c b/src/kernel/item.c index 6e64c147f..58e3326a2 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -614,25 +614,24 @@ struct order *ord) #define R_MINHERB R_PLAIN_1 #define R_MINPOTION R_FAST #define R_MINITEM R_IRON -#define MAXITEMS MAX_ITEMS -#define MAXRESOURCES MAX_RESOURCES -#define MAXHERBS MAX_HERBS -#define MAXPOTIONS MAX_POTIONS #define MAXHERBSPERPOTION 6 -const potion_type *oldpotiontype[MAXPOTIONS + 1]; +const potion_type *oldpotiontype[MAX_POTIONS + 1]; /*** alte items ***/ static const char *resourcenames[MAX_RESOURCES] = { + "money", "aura", "permaura", + "hp", "peasant", "person", + "sapling", "mallornsapling", + "tree", "mallorntree", + "seed", "mallornseed", "iron", "stone", "horse", "ao_healing", "aots", "roi", "rop", "ao_chastity", "laen", "fairyboot", "aoc", "pegasus", "elvenhorse", "charger", "dolphin", "roqf", "trollbelt", "aurafocus", "sphereofinv", "magicbag", - "magicherbbag", "dreameye", "p2", "seed", "mallornseed", - "money", "aura", "permaura", - "hp", "peasant", "person" + "magicherbbag", "dreameye", "p2" }; const resource_type *get_resourcetype(resource_t type) { @@ -966,7 +965,7 @@ static void init_oldpotions(void) }; int p; - for (p = 0; p != MAXPOTIONS; ++p) { + for (p = 0; p != MAX_POTIONS; ++p) { item_type *itype = it_find(potionnames[p]); if (itype != NULL) { oldpotiontype[p] = itype->rtype->ptype; @@ -978,6 +977,11 @@ void init_resources(void) { resource_type *rtype; + /* there are resources that are special and must be hard-coded. + * these are not items, but things like trees or hitpoints + * which can be used in a construction recipe or as a spell ingredient. + */ + rt_get_or_create(resourcenames[R_PERSON]); /* lousy hack */ rtype = rt_get_or_create(resourcenames[R_PEASANT]); diff --git a/src/kernel/item.h b/src/kernel/item.h index c1ac38517..c08c676be 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -252,8 +252,27 @@ extern "C" { variant magres, int prot, unsigned int flags); potion_type *new_potiontype(item_type * itype, int level); + + /* these constants are used with get_resourcetype. + * The order of the enum is not important for stored data. + * The resourcenames array must be updated to match. + */ + typedef enum { + /* SPECIAL */ + R_SILVER, + R_AURA, /* Aura */ + R_PERMAURA, /* Permanente Aura */ + R_LIFE, + R_PEASANT, + R_PERSON, + R_SAPLING, + R_MALLORN_SAPLING, + R_TREE, + R_MALLORN_TREE, /* ITEMS: */ + R_SEED, + R_MALLORN_SEED, R_IRON, R_STONE, R_HORSE, @@ -277,15 +296,7 @@ extern "C" { R_SACK_OF_CONSERVATION, R_TACTICCRYSTAL, R_WATER_OF_LIFE, - R_SEED, - R_MALLORNSEED, /* SONSTIGE */ - R_SILVER, - R_AURA, /* Aura */ - R_PERMAURA, /* Permanente Aura */ - R_LIFE, - R_PEASANT, - R_PERSON, MAX_RESOURCES, /* do not use outside item.c ! */ NORESOURCE = -1 diff --git a/src/modules/arena.c b/src/modules/arena.c index fbc3f0673..aada12234 100644 --- a/src/modules/arena.c +++ b/src/modules/arena.c @@ -149,7 +149,7 @@ enter_arena(unit * u, const item_type * itype, int amount, order * ord) assert(!"not implemented"); /* - for (res=0;res!=MAXRESOURCES;++res) if (res!=R_SILVER && res!=R_ARENA_GATE && (is_item(res) || is_herb(res) || is_potion(res))) { + for (res=0;res!=MAX_RESOURCES;++res) if (res!=R_SILVER && res!=R_ARENA_GATE && (is_item(res) || is_herb(res) || is_potion(res))) { int x = get_resource(u, res); if (x) { if (u2) { From aa662e65d20bc80d819aff09dd3b01007473723d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 11:25:17 +0100 Subject: [PATCH 04/15] eliminate R_PERSON hack. --- res/core/messages.xml | 12 ++++++++++++ src/give.c | 24 +++++++++++++++++++++++- src/give.test.c | 2 ++ src/kernel/item.c | 4 +--- src/kernel/item.h | 1 - src/kernel/item.test.c | 2 -- 6 files changed, 38 insertions(+), 7 deletions(-) diff --git a/res/core/messages.xml b/res/core/messages.xml index e312fcc7c..32d8e35a6 100644 --- a/res/core/messages.xml +++ b/res/core/messages.xml @@ -6882,6 +6882,7 @@ "$string" "$string" + @@ -6892,6 +6893,16 @@ "$unit($unit) transfers $int($amount) person$if($eq($amount,1),"","s") to $unit($target)." + + + + + + + "$unit($target) erhält $int($amount) Person$if($eq($amount,1),"","en") von $unit($unit)." + "$unit($target) receives $int($amount) person$if($eq($amount,1),"","s") from $unit($unit)." + + @@ -6913,6 +6924,7 @@ "$unit($target) erhält $int($amount) $resource($resource,$amount) von $unit($unit)." "$unit($target) receives $int($amount) $resource($resource,$amount) from $unit($unit)." + diff --git a/src/give.c b/src/give.c index 5abb950a6..eeb641665 100644 --- a/src/give.c +++ b/src/give.c @@ -121,6 +121,28 @@ const resource_type * rtype, struct order *ord, int error) } } +static void add_give_person(unit * u, unit * u2, int given, + struct order *ord, int error) +{ + assert(u2); + if (error) { + cmistake(u, ord, error, MSG_COMMERCE); + } + else if (u2->faction != u->faction) { + message *msg; + + msg = msg_message("give_person", "unit target resource amount", + u, u2, given); + add_message(&u->faction->msgs, msg); + msg_release(msg); + + msg = msg_message("receive_person", "unit target resource amount", + u, u2, given); + add_message(&u2->faction->msgs, msg); + msg_release(msg); + } +} + static bool limited_give(const item_type * type) { /* trade only money 2:1, if at all */ @@ -531,7 +553,7 @@ void give_unit(unit * u, unit * u2, order * ord) cmistake(u, ord, 156, MSG_COMMERCE); return; } - add_give(u, u2, u->number, u->number, get_resourcetype(R_PERSON), ord, 0); + add_give_person(u, u2, u->number, ord, 0); u_setfaction(u, u2->faction); u2->faction->newbies += u->number; } diff --git a/src/give.test.c b/src/give.test.c index fbb71cf3c..33f70fb90 100644 --- a/src/give.test.c +++ b/src/give.test.c @@ -83,6 +83,8 @@ static void test_give_unit(CuTest * tc) { CuAssertPtrEquals(tc, env.f2, env.src->faction); CuAssertIntEquals(tc, 1, env.f2->newbies); CuAssertPtrEquals(tc, 0, env.f1->units); + CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "give_person")); + CuAssertPtrNotNull(tc, test_find_messagetype(env.f2->msgs, "receive_person")); test_cleanup(); } diff --git a/src/kernel/item.c b/src/kernel/item.c index 58e3326a2..6c96cb0b0 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -622,7 +622,7 @@ const potion_type *oldpotiontype[MAX_POTIONS + 1]; static const char *resourcenames[MAX_RESOURCES] = { "money", "aura", "permaura", - "hp", "peasant", "person", + "hp", "peasant", "sapling", "mallornsapling", "tree", "mallorntree", "seed", "mallornseed", @@ -982,8 +982,6 @@ void init_resources(void) * which can be used in a construction recipe or as a spell ingredient. */ - rt_get_or_create(resourcenames[R_PERSON]); /* lousy hack */ - rtype = rt_get_or_create(resourcenames[R_PEASANT]); rtype->uchange = res_changepeasants; diff --git a/src/kernel/item.h b/src/kernel/item.h index c08c676be..bb114c8ac 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -265,7 +265,6 @@ extern "C" { R_PERMAURA, /* Permanente Aura */ R_LIFE, R_PEASANT, - R_PERSON, R_SAPLING, R_MALLORN_SAPLING, R_TREE, diff --git a/src/kernel/item.test.c b/src/kernel/item.test.c index 52e7d9917..c824d082a 100644 --- a/src/kernel/item.test.c +++ b/src/kernel/item.test.c @@ -165,8 +165,6 @@ static void test_core_resources(CuTest *tc) { CuAssertPtrNotNull(tc, rtype->itype->give); CuAssertPtrNotNull(tc, rtype = rt_find("peasant")); CuAssertPtrEquals(tc, 0, rtype->itype); - CuAssertPtrNotNull(tc, rtype = rt_find("person")); - CuAssertPtrEquals(tc, 0, rtype->itype); CuAssertPtrNotNull(tc, rtype = rt_find("permaura")); CuAssertPtrEquals(tc, 0, rtype->itype); CuAssertPtrNotNull(tc, rtype = rt_find("hp")); From 6a8762540970158af26dee391df74a1b13328cdd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 15:26:04 +0100 Subject: [PATCH 05/15] refactor cr_output_resources for easy testing. Write a (failing) test that checks first resource is silver. --- src/creport.c | 38 +++++++++++++++++++++++++------------- src/creport.h | 3 ++- src/creport.test.c | 27 +++++++++++++++++++++++++++ src/kernel/item.c | 10 +++++----- src/reports.c | 3 ++- 5 files changed, 61 insertions(+), 20 deletions(-) diff --git a/src/creport.c b/src/creport.c index 99a9ede97..aa4fd2f98 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1157,11 +1157,9 @@ cr_borders(const region * r, const faction * f, seen_mode mode, FILE * F) } } -static void -cr_output_resources(FILE * F, report_context * ctx, region *r, bool see_unit) +void cr_output_resources(stream *out, const faction * f, const region *r, bool see_unit) { char cbuf[BUFFERSIZE], *pos = cbuf; - faction *f = ctx->f; resource_report result[MAX_RAWMATERIALS]; int n, size = report_resources(r, result, MAX_RAWMATERIALS, f, see_unit); @@ -1169,15 +1167,18 @@ cr_output_resources(FILE * F, report_context * ctx, region *r, bool see_unit) int trees = rtrees(r, 2); int saplings = rtrees(r, 1); - if (trees > 0) - fprintf(F, "%d;Baeume\n", trees); - if (saplings > 0) - fprintf(F, "%d;Schoesslinge\n", saplings); - if (fval(r, RF_MALLORN) && (trees > 0 || saplings > 0)) - fprintf(F, "1;Mallorn\n"); + if (trees > 0) { + stream_printf(out, "%d;Baeume\n", trees); + } + if (saplings > 0) { + stream_printf(out, "%d;Schoesslinge\n", trees); + } + if (fval(r, RF_MALLORN) && (trees > 0 || saplings > 0)) { + sputs("1;Mallorn\n", out); + } for (n = 0; n < size; ++n) { if (result[n].level >= 0 && result[n].number >= 0) { - fprintf(F, "%d;%s\n", result[n].number, crtag(result[n].name)); + stream_printf(out, "%d;%s\n", result[n].number, crtag(result[n].name)); } } #endif @@ -1189,10 +1190,21 @@ cr_output_resources(FILE * F, report_context * ctx, region *r, bool see_unit) result[n].level); } } - if (pos != cbuf) - fputs(cbuf, F); + if (pos != cbuf) { + sputs(cbuf, out); + } } +static void cr_output_resources_compat(FILE *F, report_context * ctx, + region *r, bool see_unit) +{ + /* TODO: eliminate this function */ + stream strm; + fstream_init(&strm, F); + cr_output_resources(&strm, ctx->f, r, see_unit); +} + + static void cr_region_header(FILE * F, int plid, int nx, int ny, int uid) { @@ -1357,7 +1369,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r) /* this writes both some tags (RESOURCECOMPAT) and a block. * must not write any blocks before it */ - cr_output_resources(F, ctx, r, r->seen.mode >= seen_unit); + cr_output_resources_compat(F, ctx, r, r->seen.mode >= seen_unit); if (r->seen.mode >= seen_unit) { /* trade */ diff --git a/src/creport.h b/src/creport.h index fc2517859..435bb637f 100644 --- a/src/creport.h +++ b/src/creport.h @@ -29,7 +29,8 @@ extern "C" { int crwritemap(const char *filename); void cr_output_unit(struct stream *out, const struct region * r, const struct faction * f, const struct unit * u, seen_mode mode); - + void cr_output_resources(struct stream *out, const struct faction * f, + const struct region *r, bool see_unit); #ifdef __cplusplus } #endif diff --git a/src/creport.test.c b/src/creport.test.c index 14f40268c..254a73cbb 100644 --- a/src/creport.test.c +++ b/src/creport.test.c @@ -50,6 +50,32 @@ static void test_cr_unit(CuTest *tc) { test_cleanup(); } +static void test_cr_resources(CuTest *tc) { + stream strm; + char line[1024]; + faction *f; + region *r; + + test_cleanup(); + f = test_create_faction(0); + r = test_create_region(0, 0, 0); + r->land->horses = 100; + r->land->peasants = 200; + r->land->money = 300; + + mstream_init(&strm); + cr_output_resources(&strm, f, r, false); + strm.api->rewind(strm.handle); + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9)); + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertStrEquals(tc, "\"Silber\";type", line); + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertStrEquals(tc, "300;number", line); + mstream_done(&strm); + test_cleanup(); +} + static int cr_get_int(stream *strm, const char *match, int def) { char line[1024]; @@ -111,6 +137,7 @@ CuSuite *get_creport_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_cr_unit); + SUITE_ADD_TEST(suite, test_cr_resources); SUITE_ADD_TEST(suite, test_cr_factionstealth); return suite; } diff --git a/src/kernel/item.c b/src/kernel/item.c index 6c96cb0b0..476387075 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -982,23 +982,23 @@ void init_resources(void) * which can be used in a construction recipe or as a spell ingredient. */ - rtype = rt_get_or_create(resourcenames[R_PEASANT]); - rtype->uchange = res_changepeasants; - rtype = rt_get_or_create(resourcenames[R_SILVER]); rtype->flags |= RTF_ITEM | RTF_POOLED; rtype->uchange = res_changeitem; rtype->itype = it_get_or_create(rtype); rtype->itype->give = give_money; + rtype = rt_get_or_create(resourcenames[R_AURA]); + rtype->uchange = res_changeaura; + rtype = rt_get_or_create(resourcenames[R_PERMAURA]); rtype->uchange = res_changepermaura; rtype = rt_get_or_create(resourcenames[R_LIFE]); rtype->uchange = res_changehp; - rtype = rt_get_or_create(resourcenames[R_AURA]); - rtype->uchange = res_changeaura; + rtype = rt_get_or_create(resourcenames[R_PEASANT]); + rtype->uchange = res_changepeasants; /* alte typen registrieren: */ init_oldpotions(); diff --git a/src/reports.c b/src/reports.c index a07b60f4b..74b800a90 100644 --- a/src/reports.c +++ b/src/reports.c @@ -2049,7 +2049,8 @@ static void log_orders(const struct message *msg) } } -int stream_printf(struct stream * out, const char *format, ...) { +int stream_printf(struct stream * out, const char *format, ...) +{ va_list args; int result; char buffer[4096]; From 83f170541b23ab2826280a31fd422f1f0725397a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 15:51:04 +0100 Subject: [PATCH 06/15] short unit-test for resources in the CR. now complains because Bauern!=Bauer. TODO: crtag is shit. --- src/creport.c | 12 ++++++----- src/creport.test.c | 52 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/src/creport.c b/src/creport.c index aa4fd2f98..c766ae872 100644 --- a/src/creport.c +++ b/src/creport.c @@ -91,10 +91,11 @@ bool opt_cr_absolute_coords = false; #ifdef TAG_LOCALE static const char *crtag(const char *key) { - static const struct locale *lang = NULL; - if (!lang) - lang = get_locale(TAG_LOCALE); - return LOC(lang, key); + /* TODO: those locale lookups are shit, but static kills testing */ + const char *result; + const struct locale *lang = get_locale(TAG_LOCALE); + result = LOC(lang, key); + return result; } #else #define crtag(x) (x) @@ -1096,6 +1097,7 @@ static void cr_reportspell(FILE * F, spell * sp, int level, const struct locale static char *cr_output_resource(char *buf, const char *name, const struct locale *loc, int amount, int level) { + assert(name); buf += sprintf(buf, "RESOURCE %u\n", hashstring(name)); buf += sprintf(buf, "\"%s\";type\n", translate(name, LOC(loc, name))); if (amount >= 0) { @@ -1171,7 +1173,7 @@ void cr_output_resources(stream *out, const faction * f, const region *r, bool s stream_printf(out, "%d;Baeume\n", trees); } if (saplings > 0) { - stream_printf(out, "%d;Schoesslinge\n", trees); + stream_printf(out, "%d;Schoesslinge\n", saplings); } if (fval(r, RF_MALLORN) && (trees > 0 || saplings > 0)) { sputs("1;Mallorn\n", out); diff --git a/src/creport.test.c b/src/creport.test.c index 254a73cbb..8819aab9b 100644 --- a/src/creport.test.c +++ b/src/creport.test.c @@ -55,23 +55,73 @@ static void test_cr_resources(CuTest *tc) { char line[1024]; faction *f; region *r; + struct locale *lang; + + test_setup(); + lang = get_or_create_locale("de"); /* CR tags are translated from this */ + locale_setstring(lang, "money", "Silber"); + locale_setstring(lang, "money_p", "Silber"); + locale_setstring(lang, "horse", "Pferd"); + locale_setstring(lang, "horse_p", "Pferde"); + locale_setstring(lang, "peasant", "Bauer"); + locale_setstring(lang, "peasant_p", "Bauern"); + locale_setstring(lang, "tree", "Baum"); + locale_setstring(lang, "tree_p", "B?ume"); + locale_setstring(lang, "sapling", "Schoessling"); + locale_setstring(lang, "sapling_p", "Schoesslinge"); - test_cleanup(); f = test_create_faction(0); r = test_create_region(0, 0, 0); r->land->horses = 100; r->land->peasants = 200; r->land->money = 300; + rsettrees(r, 0, 1); + rsettrees(r, 1, 2); + rsettrees(r, 2, 3); mstream_init(&strm); cr_output_resources(&strm, f, r, false); strm.api->rewind(strm.handle); + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertStrEquals(tc, "3;Baeume", line); + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertStrEquals(tc, "2;Schoesslinge", line); + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9)); CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); CuAssertStrEquals(tc, "\"Silber\";type", line); CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); CuAssertStrEquals(tc, "300;number", line); + + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9)); + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertStrEquals(tc, "\"Bauern\";type", line); + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertStrEquals(tc, "200;number", line); + + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9)); + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertStrEquals(tc, "\"Pferde\";type", line); + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertStrEquals(tc, "300;number", line); + + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9)); + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertStrEquals(tc, "\"Schoesslinge\";type", line); + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertStrEquals(tc, "2;number", line); + + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9)); + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertStrEquals(tc, "\"B?ume\";type", line); + CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); + CuAssertStrEquals(tc, "3;number", line); + mstream_done(&strm); test_cleanup(); } From 45862a06d04dbc2990c484e8951c9bdc457fb075 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 16:55:11 +0100 Subject: [PATCH 07/15] Add a good test for the NR. TODO: make it fail. --- src/creport.test.c | 6 ++--- src/kernel/item.c | 16 +++++------- src/kernel/item.test.c | 8 +++--- src/report.c | 20 ++++++++------- src/report.h | 3 ++- src/report.test.c | 58 +++++++++++++++++++++++++++++++++++++----- 6 files changed, 79 insertions(+), 32 deletions(-) diff --git a/src/creport.test.c b/src/creport.test.c index 8819aab9b..b329e2d22 100644 --- a/src/creport.test.c +++ b/src/creport.test.c @@ -65,8 +65,8 @@ static void test_cr_resources(CuTest *tc) { locale_setstring(lang, "horse_p", "Pferde"); locale_setstring(lang, "peasant", "Bauer"); locale_setstring(lang, "peasant_p", "Bauern"); - locale_setstring(lang, "tree", "Baum"); - locale_setstring(lang, "tree_p", "B?ume"); + locale_setstring(lang, "tree", "Blume"); + locale_setstring(lang, "tree_p", "Blumen"); locale_setstring(lang, "sapling", "Schoessling"); locale_setstring(lang, "sapling_p", "Schoesslinge"); @@ -118,7 +118,7 @@ static void test_cr_resources(CuTest *tc) { CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9)); CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); - CuAssertStrEquals(tc, "\"B?ume\";type", line); + CuAssertStrEquals(tc, "\"Blumen\";type", line); CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); CuAssertStrEquals(tc, "3;number", line); diff --git a/src/kernel/item.c b/src/kernel/item.c index 476387075..1fb90d456 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -610,12 +610,6 @@ struct order *ord) return -1; /* use the mechanism */ } -#define R_MINOTHER R_SILVER -#define R_MINHERB R_PLAIN_1 -#define R_MINPOTION R_FAST -#define R_MINITEM R_IRON -#define MAXHERBSPERPOTION 6 - const potion_type *oldpotiontype[MAX_POTIONS + 1]; /*** alte items ***/ @@ -982,21 +976,25 @@ void init_resources(void) * which can be used in a construction recipe or as a spell ingredient. */ + /* special resources needed in report_region */ rtype = rt_get_or_create(resourcenames[R_SILVER]); rtype->flags |= RTF_ITEM | RTF_POOLED; rtype->uchange = res_changeitem; rtype->itype = it_get_or_create(rtype); rtype->itype->give = give_money; + rtype = rt_get_or_create(resourcenames[R_HORSE]); + rtype->flags |= RTF_ITEM | RTF_LIMITED; + rtype->itype = it_get_or_create(rtype); + rtype->itype->flags |= ITF_ANIMAL | ITF_BIG; + + /* "special" spell components */ rtype = rt_get_or_create(resourcenames[R_AURA]); rtype->uchange = res_changeaura; - rtype = rt_get_or_create(resourcenames[R_PERMAURA]); rtype->uchange = res_changepermaura; - rtype = rt_get_or_create(resourcenames[R_LIFE]); rtype->uchange = res_changehp; - rtype = rt_get_or_create(resourcenames[R_PEASANT]); rtype->uchange = res_changepeasants; diff --git a/src/kernel/item.test.c b/src/kernel/item.test.c index c824d082a..6e3615797 100644 --- a/src/kernel/item.test.c +++ b/src/kernel/item.test.c @@ -117,14 +117,14 @@ void test_findresourcetype(CuTest * tc) test_setup(); lang = get_or_create_locale("de"); - locale_setstring(lang, "horse", "Pferd"); + locale_setstring(lang, "log", "Holz"); locale_setstring(lang, "peasant", "Bauer"); init_resources(); CuAssertPtrNotNull(tc, rt_find("peasant")); - CuAssertPtrEquals(tc, 0, rt_find("horse")); - itype = test_create_itemtype("horse"); + CuAssertPtrEquals(tc, 0, rt_find("log")); + itype = test_create_itemtype("log"); - CuAssertPtrEquals(tc, (void*)itype->rtype, (void*)findresourcetype("Pferd", lang)); + CuAssertPtrEquals(tc, (void*)itype->rtype, (void*)findresourcetype("Holz", lang)); CuAssertPtrEquals(tc, (void *)rt_find("peasant"), (void *)findresourcetype("Bauer", lang)); test_cleanup(); } diff --git a/src/report.c b/src/report.c index 6af46ba07..6e8d811bc 100644 --- a/src/report.c +++ b/src/report.c @@ -878,7 +878,7 @@ bool see_border(const connection * b, const faction * f, const region * r) return cs; } -static void describe(struct stream *out, const region * r, faction * f) +void report_region(struct stream *out, const region * r, faction * f) { int n; bool dh; @@ -1181,7 +1181,6 @@ static void describe(struct stream *out, const region * r, faction * f) dh = 1; } } - newline(out); *bufp = 0; paragraph(out, buf, 0, 0, 0); @@ -1999,7 +1998,7 @@ static void cb_write_travelthru(region *r, unit *u, void *cbdata) { } } -void write_travelthru(struct stream *out, region *r, const faction *f) +void report_travelthru(struct stream *out, region *r, const faction *f) { int maxtravel; char buf[8192]; @@ -2281,7 +2280,8 @@ report_plaintext(const char *filename, report_context * ctx, if (r->seen.mode == seen_unit) { anyunits = 1; - describe(out, r, f); + newline(out); + report_region(out, r, f); if (markets_module() && r->land) { const item_type *lux = r_luxury(r); const item_type *herb = r->land->herbtype; @@ -2308,20 +2308,22 @@ report_plaintext(const char *filename, report_context * ctx, } guards(out, r, f); newline(out); - write_travelthru(out, r, f); + report_travelthru(out, r, f); } else { if (r->seen.mode == seen_far) { - describe(out, r, f); + newline(out); + report_region(out, r, f); newline(out); guards(out, r, f); newline(out); - write_travelthru(out, r, f); + report_travelthru(out, r, f); } else { - describe(out, r, f); newline(out); - write_travelthru(out, r, f); + report_region(out, r, f); + newline(out); + report_travelthru(out, r, f); } } /* Statistik */ diff --git a/src/report.h b/src/report.h index 84a6c66d4..45c620562 100644 --- a/src/report.h +++ b/src/report.h @@ -27,7 +27,8 @@ extern "C" { void register_nr(void); void report_cleanup(void); void write_spaces(struct stream *out, size_t num); - void write_travelthru(struct stream *out, struct region * r, const struct faction * f); + void report_travelthru(struct stream *out, struct region * r, const struct faction * f); + void report_region(struct stream *out, const struct region * r, struct faction * f); void nr_spell_syntax(struct stream *out, struct spellbook_entry * sbe, const struct locale *lang); void nr_spell(struct stream *out, struct spellbook_entry * sbe, const struct locale *lang); diff --git a/src/report.test.c b/src/report.test.c index aa3c52695..5b1a8c058 100644 --- a/src/report.test.c +++ b/src/report.test.c @@ -56,7 +56,52 @@ static void test_write_many_spaces(CuTest *tc) { mstream_done(&out); } -static void test_write_travelthru(CuTest *tc) { +static void test_report_region(CuTest *tc) { + char buf[1024]; + region *r; + faction *f; + stream out = { 0 }; + size_t len; + struct locale *lang; + + test_setup(); + init_resources(); + lang = get_or_create_locale("de"); /* CR tags are translated from this */ + locale_setstring(lang, "money", "Silber"); + locale_setstring(lang, "money_p", "Silber"); + locale_setstring(lang, "horse", "Pferd"); + locale_setstring(lang, "horse_p", "Pferde"); + locale_setstring(lang, "peasant", "Bauer"); + locale_setstring(lang, "peasant_p", "Bauern"); + locale_setstring(lang, "tree", "Blume"); + locale_setstring(lang, "tree_p", "Blumen"); + locale_setstring(lang, "stone", "Stein"); + locale_setstring(lang, "stone_p", "Steine"); + locale_setstring(lang, "sapling", "Schoessling"); + locale_setstring(lang, "sapling_p", "Schoesslinge"); + locale_setstring(lang, "plain", "Ebene"); + + mstream_init(&out); + r = test_create_region(0, 0, 0); + r->land->peasants = 100; + r->land->horses = 200; + rsettrees(r, 0, 1); + rsettrees(r, 1, 2); + rsettrees(r, 2, 3); + region_setname(r, "Hodor"); + f = test_create_faction(0); + f->locale = lang; + + report_region(&out, r, f); + out.api->rewind(out.handle); + len = out.api->read(out.handle, buf, sizeof(buf)); + buf[len] = '\0'; + CuAssertStrEquals(tc, "Hodor (0,0), Ebene, 3/2 Blumen, 100 Bauern, 200 Pferde.\n", buf); + mstream_done(&out); + test_cleanup(); +} + +static void test_report_travelthru(CuTest *tc) { stream out = { 0 }; char buf[1024]; size_t len; @@ -65,7 +110,7 @@ static void test_write_travelthru(CuTest *tc) { unit *u; struct locale *lang; - test_cleanup(); + test_setup(); lang = get_or_create_locale("de"); locale_setstring(lang, "travelthru_header", "Durchreise: "); mstream_init(&out); @@ -77,7 +122,7 @@ static void test_write_travelthru(CuTest *tc) { unit_setname(u, "Hodor"); unit_setid(u, 1); - write_travelthru(&out, r, f); + report_travelthru(&out, r, f); out.api->rewind(out.handle); len = out.api->read(out.handle, buf, sizeof(buf)); CuAssertIntEquals_Msg(tc, "no travelers, no report", 0, (int)len); @@ -85,7 +130,7 @@ static void test_write_travelthru(CuTest *tc) { mstream_init(&out); travelthru_add(r, u); - write_travelthru(&out, r, f); + report_travelthru(&out, r, f); out.api->rewind(out.handle); len = out.api->read(out.handle, buf, sizeof(buf)); buf[len] = '\0'; @@ -94,7 +139,7 @@ static void test_write_travelthru(CuTest *tc) { mstream_init(&out); move_unit(u, r, 0); - write_travelthru(&out, r, f); + report_travelthru(&out, r, f); out.api->rewind(out.handle); len = out.api->read(out.handle, buf, sizeof(buf)); CuAssertIntEquals_Msg(tc, "do not list units that stopped in the region", 0, (int)len); @@ -234,7 +279,8 @@ CuSuite *get_report_suite(void) CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_write_spaces); SUITE_ADD_TEST(suite, test_write_many_spaces); - SUITE_ADD_TEST(suite, test_write_travelthru); + SUITE_ADD_TEST(suite, test_report_travelthru); + SUITE_ADD_TEST(suite, test_report_region); SUITE_ADD_TEST(suite, test_write_spell_syntax); return suite; } From 52dd11a28f0dda31f80c2c07197dae631b313ca6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 17:18:17 +0100 Subject: [PATCH 08/15] create a failing test for stones in the NR. --- src/kernel/resources.c | 1 + src/report.test.c | 34 +++++++++++++++++++++++++++++++--- src/reports.c | 8 +++++--- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/kernel/resources.c b/src/kernel/resources.c index ae93d542a..a3f86aac6 100644 --- a/src/kernel/resources.c +++ b/src/kernel/resources.c @@ -203,6 +203,7 @@ struct rawmaterial_type *rmt_create(struct resource_type *rtype) rawmaterial_type *rmtype; assert(!rtype->raw); + assert(!rtype->itype || rtype->itype->construction); rmtype = rtype->raw = malloc(sizeof(rawmaterial_type)); rmtype->rtype = rtype; rmtype->terraform = terraform_default; diff --git a/src/report.test.c b/src/report.test.c index 5b1a8c058..92bfe3d9e 100644 --- a/src/report.test.c +++ b/src/report.test.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -60,12 +61,22 @@ static void test_report_region(CuTest *tc) { char buf[1024]; region *r; faction *f; + unit *u; stream out = { 0 }; size_t len; struct locale *lang; + struct resource_type *rt_stone; + construction *cons; test_setup(); init_resources(); + rt_stone = rt_get_or_create("stone"); + rt_stone->itype = it_get_or_create(rt_stone); + cons = rt_stone->itype->construction = calloc(1, sizeof(construction)); + cons->minskill = 1; + cons->skill = SK_QUARRYING; + rmt_create(rt_stone); + lang = get_or_create_locale("de"); /* CR tags are translated from this */ locale_setstring(lang, "money", "Silber"); locale_setstring(lang, "money_p", "Silber"); @@ -80,23 +91,40 @@ static void test_report_region(CuTest *tc) { locale_setstring(lang, "sapling", "Schoessling"); locale_setstring(lang, "sapling_p", "Schoesslinge"); locale_setstring(lang, "plain", "Ebene"); + locale_setstring(lang, "see_travel", "durchgereist"); mstream_init(&out); r = test_create_region(0, 0, 0); - r->land->peasants = 100; - r->land->horses = 200; + add_resource(r, 1, 100, 10, rt_stone); + CuAssertIntEquals(tc, 135, r->resources->amount); + CuAssertIntEquals(tc, 1, r->resources->level); + r->land->peasants = 5; + r->land->horses = 7; + r->land->money = 2; rsettrees(r, 0, 1); rsettrees(r, 1, 2); rsettrees(r, 2, 3); region_setname(r, "Hodor"); f = test_create_faction(0); f->locale = lang; + u = test_create_unit(f, r); + set_level(u, SK_QUARRYING, 1); + r->seen.mode = seen_travel; report_region(&out, r, f); out.api->rewind(out.handle); len = out.api->read(out.handle, buf, sizeof(buf)); buf[len] = '\0'; - CuAssertStrEquals(tc, "Hodor (0,0), Ebene, 3/2 Blumen, 100 Bauern, 200 Pferde.\n", buf); + CuAssertStrEquals(tc, "Hodor (0,0) (durchgereist), Ebene, 3/2 Blumen, 5 Bauern, 2 Silber, 7 Pferde.\n", buf); + + r->seen.mode = seen_unit; + out.api->rewind(out.handle); + report_region(&out, r, f); + out.api->rewind(out.handle); + len = out.api->read(out.handle, buf, sizeof(buf)); + buf[len] = '\0'; + CuAssertStrEquals(tc, "Hodor (0,0), Ebene, 3/2 Blumen, 135 Steine/1, 5 Bauern, 2 Silber, 7 Pferde.\n", buf); + mstream_done(&out); test_cleanup(); } diff --git a/src/reports.c b/src/reports.c index 74b800a90..737e4fc48 100644 --- a/src/reports.c +++ b/src/reports.c @@ -448,17 +448,19 @@ const faction * viewer, bool see_unit) while (res) { int maxskill = 0; const item_type *itype = resource2item(res->type->rtype); - int level = res->level + itype->construction->minskill - 1; + int minskill = itype->construction->minskill; + skill_t skill = itype->construction->skill; + int level = res->level + minskill - 1; int visible = -1; if (res->type->visible == NULL) { visible = res->amount; - level = res->level + itype->construction->minskill - 1; + level = res->level + minskill - 1; } else { const unit *u; for (u = r->units; visible != res->amount && u != NULL; u = u->next) { if (u->faction == viewer) { - int s = effskill(u, itype->construction->skill, 0); + int s = effskill(u, skill, 0); if (s > maxskill) { maxskill = s; visible = res->type->visible(res, maxskill); From d6ce1d9cfeeda100e10c9ac3cb429ac874a7786e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 17:26:00 +0100 Subject: [PATCH 09/15] Add a test for singular resources. --- src/report.test.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/report.test.c b/src/report.test.c index 92bfe3d9e..0bfea3c69 100644 --- a/src/report.test.c +++ b/src/report.test.c @@ -125,6 +125,19 @@ static void test_report_region(CuTest *tc) { buf[len] = '\0'; CuAssertStrEquals(tc, "Hodor (0,0), Ebene, 3/2 Blumen, 135 Steine/1, 5 Bauern, 2 Silber, 7 Pferde.\n", buf); + r->resources->amount = 1; + r->land->peasants = 1; + r->land->horses = 1; + r->land->money = 1; + + r->seen.mode = seen_unit; + out.api->rewind(out.handle); + report_region(&out, r, f); + out.api->rewind(out.handle); + len = out.api->read(out.handle, buf, sizeof(buf)); + buf[len] = '\0'; + CuAssertStrEquals(tc, "Hodor (0,0), Ebene, 3/2 Blumen, 1 Stein/1, 1 Bauer, 1 Silber, 1 Pferd.\n", buf); + mstream_done(&out); test_cleanup(); } From 0379a17350b778040b318657282408f996657494 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 17:42:57 +0100 Subject: [PATCH 10/15] make report_resource return an rtype, not a name. --- src/creport.c | 12 ++++++------ src/creport.test.c | 1 + src/kernel/item.c | 5 +++++ src/report.c | 2 +- src/reports.c | 25 +++++++++++++------------ src/reports.h | 2 +- 6 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/creport.c b/src/creport.c index c766ae872..ee7abcc87 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1094,12 +1094,12 @@ static void cr_reportspell(FILE * F, spell * sp, int level, const struct locale } } -static char *cr_output_resource(char *buf, const char *name, +static char *cr_output_resource(char *buf, const resource_type *rtype, const struct locale *loc, int amount, int level) { - assert(name); - buf += sprintf(buf, "RESOURCE %u\n", hashstring(name)); - buf += sprintf(buf, "\"%s\";type\n", translate(name, LOC(loc, name))); + assert(rtype); + buf += sprintf(buf, "RESOURCE %u\n", hashstring(rtype->_name)); + buf += sprintf(buf, "\"%s\";type\n", translate(rtype->_name, LOC(loc, rtype->_name))); if (amount >= 0) { if (level >= 0) buf += sprintf(buf, "%d;skill\n", level); @@ -1180,7 +1180,7 @@ void cr_output_resources(stream *out, const faction * f, const region *r, bool s } for (n = 0; n < size; ++n) { if (result[n].level >= 0 && result[n].number >= 0) { - stream_printf(out, "%d;%s\n", result[n].number, crtag(result[n].name)); +/* stream_printf(out, "%d;%s\n", result[n].number, crtag(result[n].name)); */ } } #endif @@ -1188,7 +1188,7 @@ void cr_output_resources(stream *out, const faction * f, const region *r, bool s for (n = 0; n < size; ++n) { if (result[n].number >= 0) { pos = - cr_output_resource(pos, result[n].name, f->locale, result[n].number, + cr_output_resource(pos, result[n].rtype, f->locale, result[n].number, result[n].level); } } diff --git a/src/creport.test.c b/src/creport.test.c index b329e2d22..aff170b01 100644 --- a/src/creport.test.c +++ b/src/creport.test.c @@ -58,6 +58,7 @@ static void test_cr_resources(CuTest *tc) { struct locale *lang; test_setup(); + init_resources(); lang = get_or_create_locale("de"); /* CR tags are translated from this */ locale_setstring(lang, "money", "Silber"); locale_setstring(lang, "money_p", "Silber"); diff --git a/src/kernel/item.c b/src/kernel/item.c index 1fb90d456..48ea7a690 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -988,6 +988,11 @@ void init_resources(void) rtype->itype = it_get_or_create(rtype); rtype->itype->flags |= ITF_ANIMAL | ITF_BIG; + rtype = rt_get_or_create(resourcenames[R_SAPLING]); + rtype = rt_get_or_create(resourcenames[R_TREE]); + rtype = rt_get_or_create(resourcenames[R_MALLORN_SAPLING]); + rtype = rt_get_or_create(resourcenames[R_MALLORN_TREE]); + /* "special" spell components */ rtype = rt_get_or_create(resourcenames[R_AURA]); rtype->uchange = res_changeaura; diff --git a/src/report.c b/src/report.c index 6e8d811bc..43a7ab514 100644 --- a/src/report.c +++ b/src/report.c @@ -1005,7 +1005,7 @@ void report_region(struct stream *out, const region * r, faction * f) for (n = 0; n < numresults; ++n) { if (result[n].number >= 0 && result[n].level >= 0) { bytes = snprintf(bufp, size, ", %d %s/%d", result[n].number, - LOC(f->locale, result[n].name), result[n].level); + LOC(f->locale, result[n].rtype->_name), result[n].level); if (wrptr(&bufp, &size, bytes) != 0) WARN_STATIC_BUFFER(); } diff --git a/src/reports.c b/src/reports.c index 737e4fc48..63e274265 100644 --- a/src/reports.c +++ b/src/reports.c @@ -346,11 +346,11 @@ report_items(const unit *u, item * result, int size, const unit * owner, return n; } -static void -report_resource(resource_report * result, const char *name, int number, -int level) +static void report_resource(resource_report * result, const resource_type *rtype, + int number, int level) { - result->name = name; + assert(rtype); + result->rtype = rtype; result->number = number; result->level = level; } @@ -408,37 +408,38 @@ const faction * viewer, bool see_unit) int trees = rtrees(r, 2); int saplings = rtrees(r, 1); bool mallorn = fval(r, RF_MALLORN) != 0; + const resource_type *rtype; if (money) { if (n >= size) return -1; - report_resource(result + n, "money", money, -1); + report_resource(result + n, get_resourcetype(R_SILVER), money, -1); ++n; } if (peasants) { if (n >= size) return -1; - report_resource(result + n, "peasant", peasants, -1); + report_resource(result + n, get_resourcetype(R_PEASANT), peasants, -1); ++n; } if (horses) { if (n >= size) return -1; - report_resource(result + n, "horse", horses, -1); + report_resource(result + n, get_resourcetype(R_HORSE), horses, -1); ++n; } if (saplings) { if (n >= size) return -1; - report_resource(result + n, mallorn ? "mallornsapling" : "sapling", - saplings, -1); + rtype = get_resourcetype(mallorn ? R_MALLORN_SAPLING : R_SAPLING); + report_resource(result + n, rtype, saplings, -1); ++n; } if (trees) { if (n >= size) return -1; - report_resource(result + n, mallorn ? "mallorn" : "tree", trees, - -1); + rtype = get_resourcetype(mallorn ? R_MALLORN_TREE : R_TREE); + report_resource(result + n, rtype, trees, -1); ++n; } } @@ -471,7 +472,7 @@ const faction * viewer, bool see_unit) if (level >= 0 && visible >= 0) { if (n >= size) return -1; - report_resource(result + n, res->type->rtype->_name, visible, level); + report_resource(result + n, res->type->rtype, visible, level); n++; } res = res->next; diff --git a/src/reports.h b/src/reports.h index 855234376..6ce14e775 100644 --- a/src/reports.h +++ b/src/reports.h @@ -107,7 +107,7 @@ extern "C" { } arg_regions; typedef struct resource_report { - const char *name; + const struct resource_type *rtype; int number; int level; } resource_report; From 8d7f9663912b83134b391f97a909ec742da45699 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 18:23:24 +0100 Subject: [PATCH 11/15] BUG 2298: fix CR output. always use the plural form. --- src/creport.c | 7 +++++-- src/creport.test.c | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/creport.c b/src/creport.c index ee7abcc87..b9088f020 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1097,9 +1097,11 @@ static void cr_reportspell(FILE * F, spell * sp, int level, const struct locale static char *cr_output_resource(char *buf, const resource_type *rtype, const struct locale *loc, int amount, int level) { + const char * name; assert(rtype); + name = resourcename(rtype, 1); buf += sprintf(buf, "RESOURCE %u\n", hashstring(rtype->_name)); - buf += sprintf(buf, "\"%s\";type\n", translate(rtype->_name, LOC(loc, rtype->_name))); + buf += sprintf(buf, "\"%s\";type\n", translate(name, LOC(loc, rtype->_name))); if (amount >= 0) { if (level >= 0) buf += sprintf(buf, "%d;skill\n", level); @@ -1180,7 +1182,8 @@ void cr_output_resources(stream *out, const faction * f, const region *r, bool s } for (n = 0; n < size; ++n) { if (result[n].level >= 0 && result[n].number >= 0) { -/* stream_printf(out, "%d;%s\n", result[n].number, crtag(result[n].name)); */ + const char * name = resourcename(result[n].rtype, result[n].number != 1); + stream_printf(out, "%d;%s\n", result[n].number, crtag(name)); } } #endif diff --git a/src/creport.test.c b/src/creport.test.c index aff170b01..d0ce1532d 100644 --- a/src/creport.test.c +++ b/src/creport.test.c @@ -73,7 +73,7 @@ static void test_cr_resources(CuTest *tc) { f = test_create_faction(0); r = test_create_region(0, 0, 0); - r->land->horses = 100; + r->land->horses = 1; r->land->peasants = 200; r->land->money = 300; rsettrees(r, 0, 1); @@ -107,7 +107,7 @@ static void test_cr_resources(CuTest *tc) { CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); CuAssertStrEquals(tc, "\"Pferde\";type", line); CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); - CuAssertStrEquals(tc, "300;number", line); + CuAssertStrEquals(tc, "1;number", line); CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line))); CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9)); From f699c32f0e76ddb46f5a237920153f6445be1dab Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 18:25:15 +0100 Subject: [PATCH 12/15] BUG 2298: fix NR display. always use correct singular or plural form. --- src/report.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/report.c b/src/report.c index 43a7ab514..612df1dad 100644 --- a/src/report.c +++ b/src/report.c @@ -1004,8 +1004,9 @@ void report_region(struct stream *out, const region * r, faction * f) for (n = 0; n < numresults; ++n) { if (result[n].number >= 0 && result[n].level >= 0) { + const char * name = resourcename(result[n].rtype, result[n].number!=1); bytes = snprintf(bufp, size, ", %d %s/%d", result[n].number, - LOC(f->locale, result[n].rtype->_name), result[n].level); + LOC(f->locale, name), result[n].level); if (wrptr(&bufp, &size, bytes) != 0) WARN_STATIC_BUFFER(); } From dbe5980577bf92554877ed4da1860561621f6b8e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 18:47:49 +0100 Subject: [PATCH 13/15] CR is missing saplings? --- src/creport.c | 4 ++++ tests/run-turn.sh | 5 ++++- tests/write-reports.sh | 14 +++++++++----- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/creport.c b/src/creport.c index b9088f020..706f622de 100644 --- a/src/creport.c +++ b/src/creport.c @@ -417,6 +417,7 @@ static int cr_resources(variant var, char *buffer, const void *userdata) char *wp = buffer; if (rlist != NULL) { const char *name = resourcename(rlist->type, rlist->number != 1); + assert(name); wp += sprintf(wp, "\"%d %s", rlist->number, translate(name, LOC(f->locale, name))); @@ -425,6 +426,7 @@ static int cr_resources(variant var, char *buffer, const void *userdata) if (rlist == NULL) break; name = resourcename(rlist->type, rlist->number != 1); + assert(name); wp += sprintf(wp, ", %d %s", rlist->number, translate(name, LOC(f->locale, name))); @@ -1100,6 +1102,7 @@ static char *cr_output_resource(char *buf, const resource_type *rtype, const char * name; assert(rtype); name = resourcename(rtype, 1); + assert(name); buf += sprintf(buf, "RESOURCE %u\n", hashstring(rtype->_name)); buf += sprintf(buf, "\"%s\";type\n", translate(name, LOC(loc, rtype->_name))); if (amount >= 0) { @@ -1183,6 +1186,7 @@ void cr_output_resources(stream *out, const faction * f, const region *r, bool s for (n = 0; n < size; ++n) { if (result[n].level >= 0 && result[n].number >= 0) { const char * name = resourcename(result[n].rtype, result[n].number != 1); + assert(name); stream_printf(out, "%d;%s\n", result[n].number, crtag(name)); } } diff --git a/tests/run-turn.sh b/tests/run-turn.sh index 519ed8bd8..9297278c3 100755 --- a/tests/run-turn.sh +++ b/tests/run-turn.sh @@ -53,10 +53,13 @@ assert_grep_count reports/$CRFILE '^BURG' 1 assert_grep_count reports/$CRFILE '^EINHEIT' 2 assert_grep_count reports/$CRFILE '^GEGENSTAENDE' 2 +assert_grep_count reports/185-heg.cr ';Baeume' 4 +assert_grep_count reports/185-heg.cr '"B.ume";type' 4 +assert_grep_count reports/185-heg.cr '"Pferde";type' 6 assert_grep_count reports/185-heg.nr 'erblickt' 6 assert_grep_count reports/185-heg.cr '"lighthouse";visibility' 6 assert_grep_count reports/185-heg.cr '"neighbour";visibility' 11 assert_grep_count reports/185-6rLo.cr '^EINHEIT' 2 assert_grep_count reports/185-6rLo.cr '^REGION' 13 echo "integration tests: PASS" -cleanup +#cleanup diff --git a/tests/write-reports.sh b/tests/write-reports.sh index 6581066f0..5621e84a9 100755 --- a/tests/write-reports.sh +++ b/tests/write-reports.sh @@ -34,14 +34,18 @@ $VALGRIND $SERVER -t 184 ../scripts/reports.lua [ -d reports ] || quit 4 "no reports directory created" CRFILE=184-zvto.cr grep -q PARTEI reports/$CRFILE || quit 1 "CR did not contain any factions" -grep -q -E '"B.ume";type"' reports/$CRFILE || \ - quit 1 "CR did not contain trees" -grep -q '"Bauern";type"' reports/$CRFILE || \ - quit 1 "CR did not contain peasants" +grep -q -E '"B.ume";type' reports/$CRFILE || \ + quit 1 "regions did not contain trees" +grep -q -E '"Silber";type' reports/$CRFILE || \ + quit 1 "regions did not contain silver" +grep -q '"Bauern";type' reports/$CRFILE || \ + quit 1 "regions did not contain peasants" +grep -q '"Sch..linge";type' reports/$CRFILE || \ + quit 1 "regions did not contain saplings" grep -q REGION reports/$CRFILE || quit 2 "CR did not contain any regions" grep -q SCHIFF reports/$CRFILE || quit 3 "CR did not contain any ships" grep -q BURG reports/$CRFILE || quit 4 "CR did not contain any buildings" grep -q EINHEIT reports/$CRFILE || quit 5 "CR did not contain any units" grep -q GEGENSTAENDE reports/$CRFILE || quit 6 "CR did not contain any items" echo "integration tests: PASS" -#cleanup +cleanup From cdb65dfd36dce5365a2ad45a02f3f0fec82b0d6b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 18:57:28 +0100 Subject: [PATCH 14/15] Turns out: We did not have a singular form of sapling. --- res/core/de/strings.xml | 10 ++++++++++ src/creport.c | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/res/core/de/strings.xml b/res/core/de/strings.xml index 5dc649aa1..d69c0919f 100644 --- a/res/core/de/strings.xml +++ b/res/core/de/strings.xml @@ -6604,11 +6604,21 @@ + Schößling + sapling + + + Schößlinge saplings + Mallornschößling + mallorn sapling + + + Mallornschößlinge mallorn saplings diff --git a/src/creport.c b/src/creport.c index b9088f020..bb2d68d1d 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1178,7 +1178,7 @@ void cr_output_resources(stream *out, const faction * f, const region *r, bool s stream_printf(out, "%d;Schoesslinge\n", saplings); } if (fval(r, RF_MALLORN) && (trees > 0 || saplings > 0)) { - sputs("1;Mallorn\n", out); + sputs("1;Mallorn", out); } for (n = 0; n < size; ++n) { if (result[n].level >= 0 && result[n].number >= 0) { @@ -1196,7 +1196,7 @@ void cr_output_resources(stream *out, const faction * f, const region *r, bool s } } if (pos != cbuf) { - sputs(cbuf, out); + swrite(cbuf, 1, pos - cbuf, out); } } From e233ed434447d1a076756c3bdee68eb093fffe60 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 5 Mar 2017 19:23:47 +0100 Subject: [PATCH 15/15] eliminate source of randomness from test --- src/report.test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/report.test.c b/src/report.test.c index 0bfea3c69..3c6a09ae1 100644 --- a/src/report.test.c +++ b/src/report.test.c @@ -96,7 +96,7 @@ static void test_report_region(CuTest *tc) { mstream_init(&out); r = test_create_region(0, 0, 0); add_resource(r, 1, 100, 10, rt_stone); - CuAssertIntEquals(tc, 135, r->resources->amount); + r->resources->amount = 135; CuAssertIntEquals(tc, 1, r->resources->level); r->land->peasants = 5; r->land->horses = 7;