Merge pull request #666 from ennorehling/hotfix/names

BUG 2298: displaying resources in CR and NR
This commit is contained in:
Enno Rehling 2017-03-06 21:55:35 +01:00 committed by GitHub
commit a25b386f85
20 changed files with 369 additions and 112 deletions

View file

@ -6570,15 +6570,6 @@
</string> </string>
</namespace> </namespace>
<string name="nr_tree">
<text locale="de">Baum</text>
<text locale="en">tree</text>
</string>
<string name="nr_tree_p">
<text locale="de">Bäume</text>
<text locale="en">trees</text>
</string>
<string name="nr_mallorntree"> <string name="nr_mallorntree">
<text locale="de">Mallornbaum</text> <text locale="de">Mallornbaum</text>
<text locale="en">mallorn tree</text> <text locale="en">mallorn tree</text>
@ -6613,11 +6604,21 @@
</string> </string>
<string name="sapling"> <string name="sapling">
<text locale="de">Schößling</text>
<text locale="en">sapling</text>
</string>
<string name="sapling_p">
<text locale="de">Schößlinge</text> <text locale="de">Schößlinge</text>
<text locale="en">saplings</text> <text locale="en">saplings</text>
</string> </string>
<string name="mallornsapling"> <string name="mallornsapling">
<text locale="de">Mallornschößling</text>
<text locale="en">mallorn sapling</text>
</string>
<string name="mallornsapling_p">
<text locale="de">Mallornschößlinge</text> <text locale="de">Mallornschößlinge</text>
<text locale="en">mallorn saplings</text> <text locale="en">mallorn saplings</text>
</string> </string>

View file

@ -6882,6 +6882,7 @@
<text locale="de">"$string"</text> <text locale="de">"$string"</text>
<text locale="en">"$string"</text> <text locale="en">"$string"</text>
</message> </message>
<message name="give_person" section="economy"> <message name="give_person" section="economy">
<type> <type>
<arg name="unit" type="unit"/> <arg name="unit" type="unit"/>
@ -6892,6 +6893,16 @@
<text locale="en">"$unit($unit) transfers $int($amount) person$if($eq($amount,1),"","s") to $unit($target)."</text> <text locale="en">"$unit($unit) transfers $int($amount) person$if($eq($amount,1),"","s") to $unit($target)."</text>
</message> </message>
<message name="receive_person" section="economy">
<type>
<arg name="unit" type="unit"/>
<arg name="amount" type="int"/>
<arg name="target" type="unit"/>
</type>
<text locale="de">"$unit($target) erhält $int($amount) Person$if($eq($amount,1),"","en") von $unit($unit)."</text>
<text locale="en">"$unit($target) receives $int($amount) person$if($eq($amount,1),"","s") from $unit($unit)."</text>
</message>
<message name="give" section="economy"> <message name="give" section="economy">
<type> <type>
<arg name="unit" type="unit"/> <arg name="unit" type="unit"/>
@ -6913,6 +6924,7 @@
<text locale="de">"$unit($target) erhält $int($amount) $resource($resource,$amount) von $unit($unit)."</text> <text locale="de">"$unit($target) erhält $int($amount) $resource($resource,$amount) von $unit($unit)."</text>
<text locale="en">"$unit($target) receives $int($amount) $resource($resource,$amount) from $unit($unit)."</text> <text locale="en">"$unit($target) receives $int($amount) $resource($resource,$amount) from $unit($unit)."</text>
</message> </message>
<message name="give_person_ocean" section="economy"> <message name="give_person_ocean" section="economy">
<type> <type>
<arg name="unit" type="unit"/> <arg name="unit" type="unit"/>

View file

@ -91,10 +91,11 @@ bool opt_cr_absolute_coords = false;
#ifdef TAG_LOCALE #ifdef TAG_LOCALE
static const char *crtag(const char *key) static const char *crtag(const char *key)
{ {
static const struct locale *lang = NULL; /* TODO: those locale lookups are shit, but static kills testing */
if (!lang) const char *result;
lang = get_locale(TAG_LOCALE); const struct locale *lang = get_locale(TAG_LOCALE);
return LOC(lang, key); result = LOC(lang, key);
return result;
} }
#else #else
#define crtag(x) (x) #define crtag(x) (x)
@ -416,6 +417,7 @@ static int cr_resources(variant var, char *buffer, const void *userdata)
char *wp = buffer; char *wp = buffer;
if (rlist != NULL) { if (rlist != NULL) {
const char *name = resourcename(rlist->type, rlist->number != 1); const char *name = resourcename(rlist->type, rlist->number != 1);
assert(name);
wp += wp +=
sprintf(wp, "\"%d %s", rlist->number, translate(name, LOC(f->locale, sprintf(wp, "\"%d %s", rlist->number, translate(name, LOC(f->locale,
name))); name)));
@ -424,6 +426,7 @@ static int cr_resources(variant var, char *buffer, const void *userdata)
if (rlist == NULL) if (rlist == NULL)
break; break;
name = resourcename(rlist->type, rlist->number != 1); name = resourcename(rlist->type, rlist->number != 1);
assert(name);
wp += wp +=
sprintf(wp, ", %d %s", rlist->number, translate(name, sprintf(wp, ", %d %s", rlist->number, translate(name,
LOC(f->locale, name))); LOC(f->locale, name)));
@ -1093,11 +1096,15 @@ 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) const struct locale *loc, int amount, int level)
{ {
buf += sprintf(buf, "RESOURCE %u\n", hashstring(name)); const char * name;
buf += sprintf(buf, "\"%s\";type\n", translate(name, LOC(loc, 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) { if (amount >= 0) {
if (level >= 0) if (level >= 0)
buf += sprintf(buf, "%d;skill\n", level); buf += sprintf(buf, "%d;skill\n", level);
@ -1157,11 +1164,9 @@ cr_borders(const region * r, const faction * f, seen_mode mode, FILE * F)
} }
} }
static void void cr_output_resources(stream *out, const faction * f, const region *r, bool see_unit)
cr_output_resources(FILE * F, report_context * ctx, region *r, bool see_unit)
{ {
char cbuf[BUFFERSIZE], *pos = cbuf; char cbuf[BUFFERSIZE], *pos = cbuf;
faction *f = ctx->f;
resource_report result[MAX_RAWMATERIALS]; resource_report result[MAX_RAWMATERIALS];
int n, size = report_resources(r, result, MAX_RAWMATERIALS, f, see_unit); int n, size = report_resources(r, result, MAX_RAWMATERIALS, f, see_unit);
@ -1169,15 +1174,20 @@ cr_output_resources(FILE * F, report_context * ctx, region *r, bool see_unit)
int trees = rtrees(r, 2); int trees = rtrees(r, 2);
int saplings = rtrees(r, 1); int saplings = rtrees(r, 1);
if (trees > 0) if (trees > 0) {
fprintf(F, "%d;Baeume\n", trees); stream_printf(out, "%d;Baeume\n", trees);
if (saplings > 0) }
fprintf(F, "%d;Schoesslinge\n", saplings); if (saplings > 0) {
if (fval(r, RF_MALLORN) && (trees > 0 || saplings > 0)) stream_printf(out, "%d;Schoesslinge\n", saplings);
fprintf(F, "1;Mallorn\n"); }
if (fval(r, RF_MALLORN) && (trees > 0 || saplings > 0)) {
sputs("1;Mallorn", out);
}
for (n = 0; n < size; ++n) { for (n = 0; n < size; ++n) {
if (result[n].level >= 0 && result[n].number >= 0) { if (result[n].level >= 0 && result[n].number >= 0) {
fprintf(F, "%d;%s\n", result[n].number, crtag(result[n].name)); const char * name = resourcename(result[n].rtype, result[n].number != 1);
assert(name);
stream_printf(out, "%d;%s\n", result[n].number, crtag(name));
} }
} }
#endif #endif
@ -1185,14 +1195,25 @@ cr_output_resources(FILE * F, report_context * ctx, region *r, bool see_unit)
for (n = 0; n < size; ++n) { for (n = 0; n < size; ++n) {
if (result[n].number >= 0) { if (result[n].number >= 0) {
pos = 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); result[n].level);
} }
} }
if (pos != cbuf) if (pos != cbuf) {
fputs(cbuf, F); swrite(cbuf, 1, pos - 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 static void
cr_region_header(FILE * F, int plid, int nx, int ny, int uid) cr_region_header(FILE * F, int plid, int nx, int ny, int uid)
{ {
@ -1357,7 +1378,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r)
/* this writes both some tags (RESOURCECOMPAT) and a block. /* this writes both some tags (RESOURCECOMPAT) and a block.
* must not write any blocks before it */ * 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) { if (r->seen.mode >= seen_unit) {
/* trade */ /* trade */

View file

@ -29,7 +29,8 @@ extern "C" {
int crwritemap(const char *filename); int crwritemap(const char *filename);
void cr_output_unit(struct stream *out, const struct region * r, void cr_output_unit(struct stream *out, const struct region * r,
const struct faction * f, const struct unit * u, seen_mode mode); 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -50,6 +50,83 @@ static void test_cr_unit(CuTest *tc) {
test_cleanup(); test_cleanup();
} }
static void test_cr_resources(CuTest *tc) {
stream strm;
char line[1024];
faction *f;
region *r;
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, "sapling", "Schoessling");
locale_setstring(lang, "sapling_p", "Schoesslinge");
f = test_create_faction(0);
r = test_create_region(0, 0, 0);
r->land->horses = 1;
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, "1;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, "\"Blumen\";type", line);
CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
CuAssertStrEquals(tc, "3;number", line);
mstream_done(&strm);
test_cleanup();
}
static int cr_get_int(stream *strm, const char *match, int def) static int cr_get_int(stream *strm, const char *match, int def)
{ {
char line[1024]; char line[1024];
@ -111,6 +188,7 @@ CuSuite *get_creport_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_cr_unit); SUITE_ADD_TEST(suite, test_cr_unit);
SUITE_ADD_TEST(suite, test_cr_resources);
SUITE_ADD_TEST(suite, test_cr_factionstealth); SUITE_ADD_TEST(suite, test_cr_factionstealth);
return suite; return suite;
} }

View file

@ -2130,7 +2130,7 @@ static void planttrees(unit * u, int raw)
} }
/* Mallornb<6E>ume kann man nur in Mallornregionen z<>chten */ /* Mallornb<6E>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<70>fen */ /* Skill pr<70>fen */
skill = effskill(u, SK_HERBALISM, 0); skill = effskill(u, SK_HERBALISM, 0);
@ -2195,7 +2195,7 @@ static void breedtrees(unit * u, int raw)
} }
/* Mallornb<6E>ume kann man nur in Mallornregionen z<>chten */ /* Mallornb<6E>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<70>fen */ /* Skill pr<70>fen */
skill = effskill(u, SK_HERBALISM, 0); skill = effskill(u, SK_HERBALISM, 0);
@ -2313,7 +2313,7 @@ static void breed_cmd(unit * u, struct order *ord)
default: default:
if (p != P_ANY) { if (p != P_ANY) {
rtype = findresourcetype(s, u->faction->locale); 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); breedtrees(u, m);
break; break;
} }

View file

@ -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) static bool limited_give(const item_type * type)
{ {
/* trade only money 2:1, if at all */ /* 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); cmistake(u, ord, 156, MSG_COMMERCE);
return; 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); u_setfaction(u, u2->faction);
u2->faction->newbies += u->number; u2->faction->newbies += u->number;
} }

View file

@ -83,6 +83,8 @@ static void test_give_unit(CuTest * tc) {
CuAssertPtrEquals(tc, env.f2, env.src->faction); CuAssertPtrEquals(tc, env.f2, env.src->faction);
CuAssertIntEquals(tc, 1, env.f2->newbies); CuAssertIntEquals(tc, 1, env.f2->newbies);
CuAssertPtrEquals(tc, 0, env.f1->units); 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(); test_cleanup();
} }

View file

@ -610,29 +610,22 @@ struct order *ord)
return -1; /* use the mechanism */ return -1; /* use the mechanism */
} }
#define R_MINOTHER R_SILVER const potion_type *oldpotiontype[MAX_POTIONS + 1];
#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];
/*** alte items ***/ /*** alte items ***/
static const char *resourcenames[MAX_RESOURCES] = { static const char *resourcenames[MAX_RESOURCES] = {
"money", "aura", "permaura",
"hp", "peasant",
"sapling", "mallornsapling",
"tree", "mallorntree",
"seed", "mallornseed",
"iron", "stone", "horse", "ao_healing", "iron", "stone", "horse", "ao_healing",
"aots", "roi", "rop", "ao_chastity", "aots", "roi", "rop", "ao_chastity",
"laen", "fairyboot", "aoc", "pegasus", "laen", "fairyboot", "aoc", "pegasus",
"elvenhorse", "charger", "dolphin", "roqf", "trollbelt", "elvenhorse", "charger", "dolphin", "roqf", "trollbelt",
"aurafocus", "sphereofinv", "magicbag", "aurafocus", "sphereofinv", "magicbag",
"magicherbbag", "dreameye", "p2", "seed", "mallornseed", "magicherbbag", "dreameye", "p2"
"money", "aura", "permaura",
"hp", "peasant", "person"
}; };
const resource_type *get_resourcetype(resource_t type) { const resource_type *get_resourcetype(resource_t type) {
@ -966,7 +959,7 @@ static void init_oldpotions(void)
}; };
int p; int p;
for (p = 0; p != MAXPOTIONS; ++p) { for (p = 0; p != MAX_POTIONS; ++p) {
item_type *itype = it_find(potionnames[p]); item_type *itype = it_find(potionnames[p]);
if (itype != NULL) { if (itype != NULL) {
oldpotiontype[p] = itype->rtype->ptype; oldpotiontype[p] = itype->rtype->ptype;
@ -978,25 +971,37 @@ void init_resources(void)
{ {
resource_type *rtype; resource_type *rtype;
rt_get_or_create(resourcenames[R_PERSON]); /* lousy hack */ /* there are resources that are special and must be hard-coded.
* these are not items, but things like trees or hitpoints
rtype = rt_get_or_create(resourcenames[R_PEASANT]); * which can be used in a construction recipe or as a spell ingredient.
rtype->uchange = res_changepeasants; */
/* special resources needed in report_region */
rtype = rt_get_or_create(resourcenames[R_SILVER]); rtype = rt_get_or_create(resourcenames[R_SILVER]);
rtype->flags |= RTF_ITEM | RTF_POOLED; rtype->flags |= RTF_ITEM | RTF_POOLED;
rtype->uchange = res_changeitem; rtype->uchange = res_changeitem;
rtype->itype = it_get_or_create(rtype); rtype->itype = it_get_or_create(rtype);
rtype->itype->give = give_money; rtype->itype->give = give_money;
rtype = rt_get_or_create(resourcenames[R_PERMAURA]); rtype = rt_get_or_create(resourcenames[R_HORSE]);
rtype->uchange = res_changepermaura; rtype->flags |= RTF_ITEM | RTF_LIMITED;
rtype->itype = it_get_or_create(rtype);
rtype->itype->flags |= ITF_ANIMAL | ITF_BIG;
rtype = rt_get_or_create(resourcenames[R_LIFE]); rtype = rt_get_or_create(resourcenames[R_SAPLING]);
rtype->uchange = res_changehp; 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 = rt_get_or_create(resourcenames[R_AURA]);
rtype->uchange = res_changeaura; 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;
/* alte typen registrieren: */ /* alte typen registrieren: */
init_oldpotions(); init_oldpotions();

View file

@ -252,8 +252,26 @@ extern "C" {
variant magres, int prot, unsigned int flags); variant magres, int prot, unsigned int flags);
potion_type *new_potiontype(item_type * itype, int level); 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 { typedef enum {
/* SPECIAL */
R_SILVER,
R_AURA, /* Aura */
R_PERMAURA, /* Permanente Aura */
R_LIFE,
R_PEASANT,
R_SAPLING,
R_MALLORN_SAPLING,
R_TREE,
R_MALLORN_TREE,
/* ITEMS: */ /* ITEMS: */
R_SEED,
R_MALLORN_SEED,
R_IRON, R_IRON,
R_STONE, R_STONE,
R_HORSE, R_HORSE,
@ -277,15 +295,7 @@ extern "C" {
R_SACK_OF_CONSERVATION, R_SACK_OF_CONSERVATION,
R_TACTICCRYSTAL, R_TACTICCRYSTAL,
R_WATER_OF_LIFE, R_WATER_OF_LIFE,
R_SEED,
R_MALLORNSEED,
/* SONSTIGE */ /* SONSTIGE */
R_SILVER,
R_AURA, /* Aura */
R_PERMAURA, /* Permanente Aura */
R_LIFE,
R_PEASANT,
R_PERSON,
MAX_RESOURCES, /* do not use outside item.c ! */ MAX_RESOURCES, /* do not use outside item.c ! */
NORESOURCE = -1 NORESOURCE = -1

View file

@ -117,14 +117,14 @@ void test_findresourcetype(CuTest * tc)
test_setup(); test_setup();
lang = get_or_create_locale("de"); lang = get_or_create_locale("de");
locale_setstring(lang, "horse", "Pferd"); locale_setstring(lang, "log", "Holz");
locale_setstring(lang, "peasant", "Bauer"); locale_setstring(lang, "peasant", "Bauer");
init_resources(); init_resources();
CuAssertPtrNotNull(tc, rt_find("peasant")); CuAssertPtrNotNull(tc, rt_find("peasant"));
CuAssertPtrEquals(tc, 0, rt_find("horse")); CuAssertPtrEquals(tc, 0, rt_find("log"));
itype = test_create_itemtype("horse"); 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)); CuAssertPtrEquals(tc, (void *)rt_find("peasant"), (void *)findresourcetype("Bauer", lang));
test_cleanup(); test_cleanup();
} }
@ -165,8 +165,6 @@ static void test_core_resources(CuTest *tc) {
CuAssertPtrNotNull(tc, rtype->itype->give); CuAssertPtrNotNull(tc, rtype->itype->give);
CuAssertPtrNotNull(tc, rtype = rt_find("peasant")); CuAssertPtrNotNull(tc, rtype = rt_find("peasant"));
CuAssertPtrEquals(tc, 0, rtype->itype); CuAssertPtrEquals(tc, 0, rtype->itype);
CuAssertPtrNotNull(tc, rtype = rt_find("person"));
CuAssertPtrEquals(tc, 0, rtype->itype);
CuAssertPtrNotNull(tc, rtype = rt_find("permaura")); CuAssertPtrNotNull(tc, rtype = rt_find("permaura"));
CuAssertPtrEquals(tc, 0, rtype->itype); CuAssertPtrEquals(tc, 0, rtype->itype);
CuAssertPtrNotNull(tc, rtype = rt_find("hp")); CuAssertPtrNotNull(tc, rtype = rt_find("hp"));

View file

@ -203,6 +203,7 @@ struct rawmaterial_type *rmt_create(struct resource_type *rtype)
rawmaterial_type *rmtype; rawmaterial_type *rmtype;
assert(!rtype->raw); assert(!rtype->raw);
assert(!rtype->itype || rtype->itype->construction);
rmtype = rtype->raw = malloc(sizeof(rawmaterial_type)); rmtype = rtype->raw = malloc(sizeof(rawmaterial_type));
rmtype->rtype = rtype; rmtype->rtype = rtype;
rmtype->terraform = terraform_default; rmtype->terraform = terraform_default;

View file

@ -149,7 +149,7 @@ enter_arena(unit * u, const item_type * itype, int amount, order * ord)
assert(!"not implemented"); 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); int x = get_resource(u, res);
if (x) { if (x) {
if (u2) { if (u2) {

View file

@ -878,7 +878,7 @@ bool see_border(const connection * b, const faction * f, const region * r)
return cs; 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; int n;
bool dh; bool dh;
@ -987,10 +987,10 @@ static void describe(struct stream *out, const region * r, faction * f)
} }
} }
else if (trees == 1) { else if (trees == 1) {
bytes = (int)strlcpy(bufp, LOC(f->locale, "nr_tree"), size); bytes = (int)strlcpy(bufp, LOC(f->locale, "tree"), size);
} }
else { 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) if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER(); WARN_STATIC_BUFFER();
@ -1004,8 +1004,9 @@ static void describe(struct stream *out, const region * r, faction * f)
for (n = 0; n < numresults; ++n) { for (n = 0; n < numresults; ++n) {
if (result[n].number >= 0 && result[n].level >= 0) { 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, bytes = snprintf(bufp, size, ", %d %s/%d", result[n].number,
LOC(f->locale, result[n].name), result[n].level); LOC(f->locale, name), result[n].level);
if (wrptr(&bufp, &size, bytes) != 0) if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER(); WARN_STATIC_BUFFER();
} }
@ -1181,7 +1182,6 @@ static void describe(struct stream *out, const region * r, faction * f)
dh = 1; dh = 1;
} }
} }
newline(out);
*bufp = 0; *bufp = 0;
paragraph(out, buf, 0, 0, 0); paragraph(out, buf, 0, 0, 0);
@ -1999,7 +1999,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; int maxtravel;
char buf[8192]; char buf[8192];
@ -2281,7 +2281,8 @@ report_plaintext(const char *filename, report_context * ctx,
if (r->seen.mode == seen_unit) { if (r->seen.mode == seen_unit) {
anyunits = 1; anyunits = 1;
describe(out, r, f); newline(out);
report_region(out, r, f);
if (markets_module() && r->land) { if (markets_module() && r->land) {
const item_type *lux = r_luxury(r); const item_type *lux = r_luxury(r);
const item_type *herb = r->land->herbtype; const item_type *herb = r->land->herbtype;
@ -2308,20 +2309,22 @@ report_plaintext(const char *filename, report_context * ctx,
} }
guards(out, r, f); guards(out, r, f);
newline(out); newline(out);
write_travelthru(out, r, f); report_travelthru(out, r, f);
} }
else { else {
if (r->seen.mode == seen_far) { if (r->seen.mode == seen_far) {
describe(out, r, f); newline(out);
report_region(out, r, f);
newline(out); newline(out);
guards(out, r, f); guards(out, r, f);
newline(out); newline(out);
write_travelthru(out, r, f); report_travelthru(out, r, f);
} }
else { else {
describe(out, r, f);
newline(out); newline(out);
write_travelthru(out, r, f); report_region(out, r, f);
newline(out);
report_travelthru(out, r, f);
} }
} }
/* Statistik */ /* Statistik */

View file

@ -27,7 +27,8 @@ extern "C" {
void register_nr(void); void register_nr(void);
void report_cleanup(void); void report_cleanup(void);
void write_spaces(struct stream *out, size_t num); 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_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); void nr_spell(struct stream *out, struct spellbook_entry * sbe, const struct locale *lang);

View file

@ -9,6 +9,7 @@
#include <kernel/item.h> #include <kernel/item.h>
#include <kernel/race.h> #include <kernel/race.h>
#include <kernel/region.h> #include <kernel/region.h>
#include <kernel/resources.h>
#include <kernel/ship.h> #include <kernel/ship.h>
#include <kernel/unit.h> #include <kernel/unit.h>
#include <kernel/spell.h> #include <kernel/spell.h>
@ -56,7 +57,92 @@ static void test_write_many_spaces(CuTest *tc) {
mstream_done(&out); mstream_done(&out);
} }
static void test_write_travelthru(CuTest *tc) { 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");
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");
locale_setstring(lang, "see_travel", "durchgereist");
mstream_init(&out);
r = test_create_region(0, 0, 0);
add_resource(r, 1, 100, 10, rt_stone);
r->resources->amount = 135;
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) (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);
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();
}
static void test_report_travelthru(CuTest *tc) {
stream out = { 0 }; stream out = { 0 };
char buf[1024]; char buf[1024];
size_t len; size_t len;
@ -65,7 +151,7 @@ static void test_write_travelthru(CuTest *tc) {
unit *u; unit *u;
struct locale *lang; struct locale *lang;
test_cleanup(); test_setup();
lang = get_or_create_locale("de"); lang = get_or_create_locale("de");
locale_setstring(lang, "travelthru_header", "Durchreise: "); locale_setstring(lang, "travelthru_header", "Durchreise: ");
mstream_init(&out); mstream_init(&out);
@ -77,7 +163,7 @@ static void test_write_travelthru(CuTest *tc) {
unit_setname(u, "Hodor"); unit_setname(u, "Hodor");
unit_setid(u, 1); unit_setid(u, 1);
write_travelthru(&out, r, f); report_travelthru(&out, r, f);
out.api->rewind(out.handle); out.api->rewind(out.handle);
len = out.api->read(out.handle, buf, sizeof(buf)); len = out.api->read(out.handle, buf, sizeof(buf));
CuAssertIntEquals_Msg(tc, "no travelers, no report", 0, (int)len); CuAssertIntEquals_Msg(tc, "no travelers, no report", 0, (int)len);
@ -85,7 +171,7 @@ static void test_write_travelthru(CuTest *tc) {
mstream_init(&out); mstream_init(&out);
travelthru_add(r, u); travelthru_add(r, u);
write_travelthru(&out, r, f); report_travelthru(&out, r, f);
out.api->rewind(out.handle); out.api->rewind(out.handle);
len = out.api->read(out.handle, buf, sizeof(buf)); len = out.api->read(out.handle, buf, sizeof(buf));
buf[len] = '\0'; buf[len] = '\0';
@ -94,7 +180,7 @@ static void test_write_travelthru(CuTest *tc) {
mstream_init(&out); mstream_init(&out);
move_unit(u, r, 0); move_unit(u, r, 0);
write_travelthru(&out, r, f); report_travelthru(&out, r, f);
out.api->rewind(out.handle); out.api->rewind(out.handle);
len = out.api->read(out.handle, buf, sizeof(buf)); len = out.api->read(out.handle, buf, sizeof(buf));
CuAssertIntEquals_Msg(tc, "do not list units that stopped in the region", 0, (int)len); CuAssertIntEquals_Msg(tc, "do not list units that stopped in the region", 0, (int)len);
@ -234,7 +320,8 @@ CuSuite *get_report_suite(void)
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_write_spaces); SUITE_ADD_TEST(suite, test_write_spaces);
SUITE_ADD_TEST(suite, test_write_many_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); SUITE_ADD_TEST(suite, test_write_spell_syntax);
return suite; return suite;
} }

View file

@ -346,11 +346,11 @@ report_items(const unit *u, item * result, int size, const unit * owner,
return n; return n;
} }
static void static void report_resource(resource_report * result, const resource_type *rtype,
report_resource(resource_report * result, const char *name, int number, int number, int level)
int level)
{ {
result->name = name; assert(rtype);
result->rtype = rtype;
result->number = number; result->number = number;
result->level = level; result->level = level;
} }
@ -408,37 +408,38 @@ const faction * viewer, bool see_unit)
int trees = rtrees(r, 2); int trees = rtrees(r, 2);
int saplings = rtrees(r, 1); int saplings = rtrees(r, 1);
bool mallorn = fval(r, RF_MALLORN) != 0; bool mallorn = fval(r, RF_MALLORN) != 0;
const resource_type *rtype;
if (money) { if (money) {
if (n >= size) if (n >= size)
return -1; return -1;
report_resource(result + n, "money", money, -1); report_resource(result + n, get_resourcetype(R_SILVER), money, -1);
++n; ++n;
} }
if (peasants) { if (peasants) {
if (n >= size) if (n >= size)
return -1; return -1;
report_resource(result + n, "peasant", peasants, -1); report_resource(result + n, get_resourcetype(R_PEASANT), peasants, -1);
++n; ++n;
} }
if (horses) { if (horses) {
if (n >= size) if (n >= size)
return -1; return -1;
report_resource(result + n, "horse", horses, -1); report_resource(result + n, get_resourcetype(R_HORSE), horses, -1);
++n; ++n;
} }
if (saplings) { if (saplings) {
if (n >= size) if (n >= size)
return -1; return -1;
report_resource(result + n, mallorn ? "mallornsapling" : "sapling", rtype = get_resourcetype(mallorn ? R_MALLORN_SAPLING : R_SAPLING);
saplings, -1); report_resource(result + n, rtype, saplings, -1);
++n; ++n;
} }
if (trees) { if (trees) {
if (n >= size) if (n >= size)
return -1; return -1;
report_resource(result + n, mallorn ? "mallorn" : "tree", trees, rtype = get_resourcetype(mallorn ? R_MALLORN_TREE : R_TREE);
-1); report_resource(result + n, rtype, trees, -1);
++n; ++n;
} }
} }
@ -448,17 +449,19 @@ const faction * viewer, bool see_unit)
while (res) { while (res) {
int maxskill = 0; int maxskill = 0;
const item_type *itype = resource2item(res->type->rtype); 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; int visible = -1;
if (res->type->visible == NULL) { if (res->type->visible == NULL) {
visible = res->amount; visible = res->amount;
level = res->level + itype->construction->minskill - 1; level = res->level + minskill - 1;
} }
else { else {
const unit *u; const unit *u;
for (u = r->units; visible != res->amount && u != NULL; u = u->next) { for (u = r->units; visible != res->amount && u != NULL; u = u->next) {
if (u->faction == viewer) { if (u->faction == viewer) {
int s = effskill(u, itype->construction->skill, 0); int s = effskill(u, skill, 0);
if (s > maxskill) { if (s > maxskill) {
maxskill = s; maxskill = s;
visible = res->type->visible(res, maxskill); visible = res->type->visible(res, maxskill);
@ -469,7 +472,7 @@ const faction * viewer, bool see_unit)
if (level >= 0 && visible >= 0) { if (level >= 0 && visible >= 0) {
if (n >= size) if (n >= size)
return -1; return -1;
report_resource(result + n, res->type->rtype->_name, visible, level); report_resource(result + n, res->type->rtype, visible, level);
n++; n++;
} }
res = res->next; res = res->next;
@ -2049,7 +2052,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; va_list args;
int result; int result;
char buffer[4096]; char buffer[4096];

View file

@ -107,7 +107,7 @@ extern "C" {
} arg_regions; } arg_regions;
typedef struct resource_report { typedef struct resource_report {
const char *name; const struct resource_type *rtype;
int number; int number;
int level; int level;
} resource_report; } resource_report;

View file

@ -53,10 +53,13 @@ assert_grep_count reports/$CRFILE '^BURG' 1
assert_grep_count reports/$CRFILE '^EINHEIT' 2 assert_grep_count reports/$CRFILE '^EINHEIT' 2
assert_grep_count reports/$CRFILE '^GEGENSTAENDE' 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.nr 'erblickt' 6
assert_grep_count reports/185-heg.cr '"lighthouse";visibility' 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-heg.cr '"neighbour";visibility' 11
assert_grep_count reports/185-6rLo.cr '^EINHEIT' 2 assert_grep_count reports/185-6rLo.cr '^EINHEIT' 2
assert_grep_count reports/185-6rLo.cr '^REGION' 13 assert_grep_count reports/185-6rLo.cr '^REGION' 13
echo "integration tests: PASS" echo "integration tests: PASS"
cleanup #cleanup

View file

@ -16,10 +16,10 @@ while [ ! -d $ROOT/.git ]; do
ROOT=`dirname $ROOT` ROOT=`dirname $ROOT`
done done
set -e #set -e
cd $ROOT/tests cd $ROOT/tests
setup setup
cleanup #cleanup
VALGRIND=`which valgrind` VALGRIND=`which valgrind`
TESTS=../Debug/eressea/test_eressea TESTS=../Debug/eressea/test_eressea
SERVER=../Debug/eressea/eressea SERVER=../Debug/eressea/eressea
@ -34,6 +34,14 @@ $VALGRIND $SERVER -t 184 ../scripts/reports.lua
[ -d reports ] || quit 4 "no reports directory created" [ -d reports ] || quit 4 "no reports directory created"
CRFILE=184-zvto.cr CRFILE=184-zvto.cr
grep -q PARTEI reports/$CRFILE || quit 1 "CR did not contain any factions" grep -q PARTEI reports/$CRFILE || quit 1 "CR did not contain any factions"
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 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 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 BURG reports/$CRFILE || quit 4 "CR did not contain any buildings"