diff --git a/res/core/de/strings.xml b/res/core/de/strings.xml
index 46d5605b1..d318f7d56 100644
--- a/res/core/de/strings.xml
+++ b/res/core/de/strings.xml
@@ -6564,15 +6564,6 @@
-
- Baum
- tree
-
-
- Bäume
- trees
-
-
Mallornbaum
mallorn tree
@@ -6607,11 +6598,21 @@
+ Schößling
+ sapling
+
+
+
Schößlinge
saplings
+ Mallornschößling
+ mallorn sapling
+
+
+
Mallornschößlinge
mallorn saplings
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/attributes/otherfaction.c b/src/attributes/otherfaction.c
index 83c56e767..c9e56fe27 100644
--- a/src/attributes/otherfaction.c
+++ b/src/attributes/otherfaction.c
@@ -57,10 +57,16 @@ attrib_type at_otherfaction = {
"otherfaction", NULL, NULL, NULL, write_of, read_of, NULL, ATF_UNIQUE
};
-struct faction *get_otherfaction(const struct attrib *a)
+faction *get_otherfaction(const unit * u)
{
- faction * f = (faction *)(a->data.v);
- return (f && f->_alive) ? f : NULL;
+ attrib *a = a_find(u->attribs, &at_otherfaction);
+ if (a) {
+ faction * f = (faction *)(a->data.v);
+ if (f && f->_alive) {
+ return f;
+ }
+ }
+ return NULL;
}
struct attrib *make_otherfaction(struct faction *f)
@@ -73,11 +79,8 @@ struct attrib *make_otherfaction(struct faction *f)
faction *visible_faction(const faction * f, const unit * u)
{
if (f == NULL || !alliedunit(u, f, HELP_FSTEALTH)) {
- attrib *a = a_find(u->attribs, &at_otherfaction);
- if (a) {
- faction *fv = get_otherfaction(a);
- if (fv) return fv;
- }
+ faction *fv = get_otherfaction(u);
+ if (fv) return fv;
}
return u->faction;
}
diff --git a/src/attributes/otherfaction.h b/src/attributes/otherfaction.h
index 726d86b0e..8a6471658 100644
--- a/src/attributes/otherfaction.h
+++ b/src/attributes/otherfaction.h
@@ -25,7 +25,7 @@ extern "C" {
struct attrib;
extern struct attrib_type at_otherfaction;
- extern struct faction *get_otherfaction(const struct attrib *a);
+ extern struct faction *get_otherfaction(const struct unit *u);
extern struct attrib *make_otherfaction(struct faction *f);
extern struct faction *visible_faction(const struct faction *f,
const struct unit *u);
diff --git a/src/battle.c b/src/battle.c
index e8eb426e3..fce3d3049 100644
--- a/src/battle.c
+++ b/src/battle.c
@@ -3123,8 +3123,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
int speeded = 0, speed = 1;
int rest;
const group *g = NULL;
- const attrib *a = a_find(u->attribs, &at_otherfaction);
- const faction *stealthfaction = a ? get_otherfaction(a) : NULL;
+ const faction *stealthfaction = get_otherfaction(u);
unsigned int flags = 0;
assert(u->number);
diff --git a/src/creport.c b/src/creport.c
index 99a9ede97..f5d0f27fd 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)
@@ -416,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)));
@@ -424,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)));
@@ -748,8 +751,9 @@ void cr_output_unit(stream *out, const region * r, const faction * f,
const char *pzTmp;
skill *sv;
item result[MAX_INVENTORY];
- const faction *sf;
+ const faction *fother, *fseen;
const char *prefix;
+ bool allied;
assert(u && u->number);
assert(u->region == r); /* TODO: if this holds true, then why did we pass in r? */
@@ -762,10 +766,8 @@ void cr_output_unit(stream *out, const region * r, const faction * f,
if (str) {
stream_printf(out, "\"%s\";Beschr\n", str);
}
- /* print faction information */
- sf = visible_faction(NULL, u);
- if (u->faction == f || omniscient(f)) {
- /* my own faction, full info */
+
+ if (u->faction == f) {
const attrib *a = NULL;
unit *mage;
@@ -775,36 +777,29 @@ void cr_output_unit(stream *out, const region * r, const faction * f,
const group *g = (const group *)a->data.v;
stream_printf(out, "%d;gruppe\n", g->gid);
}
- stream_printf(out, "%d;Partei\n", u->faction->no);
- if (sf && sf != u->faction) {
- stream_printf(out, "%d;Verkleidung\n", sf->no);
- stream_printf(out, "%d;Anderepartei\n", sf->no);
- }
- if (fval(u, UFL_ANON_FACTION)) {
- stream_printf(out, "%d;Parteitarnung\n", (u->flags & UFL_ANON_FACTION) != 0);
- }
mage = get_familiar_mage(u);
if (mage) {
stream_printf(out, "%u;familiarmage\n", mage->no);
}
}
- else {
- if (fval(u, UFL_ANON_FACTION)) {
- /* faction info is hidden */
- stream_printf(out, "%d;Parteitarnung\n", (u->flags & UFL_ANON_FACTION) != 0);
- }
- else {
- /* other unit. show visible faction, not u->faction */
- stream_printf(out, "%d;Partei\n", sf ? sf->no : f->no);
- if (sf == f) {
- stream_printf(out, "1;Verraeter\n");
- }
- if (sf && sf != u->faction) {
- if (alliedunit(u, f, HELP_FSTEALTH)) {
- stream_printf(out, "%d;Anderepartei\n", sf->no);
- }
- }
- }
+
+ fseen = u->faction;
+ fother = get_otherfaction(u);
+ allied = u->faction == f || alliedunit(u, f, HELP_FSTEALTH);
+ if (fother && f != u->faction && !allied) {
+ /* getarnt, keine eigene, und kein HELFE fuer uns: wir sehen den fake */
+ fseen = fother;
+ }
+ stream_printf(out, "%d;Partei\n", fseen->no);
+ if (fother && fother!=fseen) {
+ stream_printf(out, "%d;Anderepartei\n", fother->no);
+ }
+ if (fseen==f && fval(u, UFL_ANON_FACTION)) {
+ sputs("1;Parteitarnung", out);
+ }
+ if (!allied && fother == f) {
+ /* sieht aus wie unsere, ist es aber nicht. */
+ stream_printf(out, "1;Verraeter\n");
}
prefix = raceprefix(u);
if (prefix) {
@@ -1093,11 +1088,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)
{
- buf += sprintf(buf, "RESOURCE %u\n", hashstring(name));
- buf += sprintf(buf, "\"%s\";type\n", translate(name, LOC(loc, name)));
+ 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) {
if (level >= 0)
buf += sprintf(buf, "%d;skill\n", level);
@@ -1157,11 +1156,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 +1166,20 @@ 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", saplings);
+ }
+ if (fval(r, RF_MALLORN) && (trees > 0 || saplings > 0)) {
+ sputs("1;Mallorn", 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));
+ 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
@@ -1185,14 +1187,25 @@ cr_output_resources(FILE * F, report_context * ctx, region *r, bool see_unit)
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);
}
}
- if (pos != cbuf)
- fputs(cbuf, F);
+ if (pos != cbuf) {
+ 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
cr_region_header(FILE * F, int plid, int nx, int ny, int uid)
{
@@ -1357,7 +1370,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..a56d1d589 100644
--- a/src/creport.test.c
+++ b/src/creport.test.c
@@ -50,6 +50,83 @@ 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;
+ 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)
{
char line[1024];
@@ -71,39 +148,44 @@ static void test_cr_factionstealth(CuTest *tc) {
ally *al;
test_setup();
- mstream_init(&strm);
f1 = test_create_faction(0);
f2 = test_create_faction(0);
r = test_create_region(0, 0, 0);
u = test_create_unit(f1, r);
+ mstream_init(&strm);
cr_output_unit(&strm, u->region, f1, u, seen_unit);
CuAssertIntEquals(tc, f1->no, cr_get_int(&strm, ";Partei", -1));
CuAssertIntEquals(tc, -1, cr_get_int(&strm, ";Anderepartei", -1));
CuAssertIntEquals(tc, -1, cr_get_int(&strm, ";Verraeter", -1));
+ mstream_done(&strm);
set_factionstealth(u, f2);
CuAssertPtrNotNull(tc, u->attribs);
+ mstream_init(&strm);
cr_output_unit(&strm, u->region, f1, u, seen_unit);
CuAssertIntEquals(tc, f1->no, cr_get_int(&strm, ";Partei", -1));
CuAssertIntEquals(tc, f2->no, cr_get_int(&strm, ";Anderepartei", -1));
CuAssertIntEquals(tc, -1, cr_get_int(&strm, ";Verraeter", -1));
+ mstream_done(&strm);
+ mstream_init(&strm);
cr_output_unit(&strm, u->region, f2, u, seen_unit);
- CuAssertIntEquals(tc, f1->no, cr_get_int(&strm, ";Partei", -1));
- CuAssertIntEquals(tc, f2->no, cr_get_int(&strm, ";Anderepartei", -1));
+ CuAssertIntEquals(tc, f2->no, cr_get_int(&strm, ";Partei", -1));
+ CuAssertIntEquals(tc, -1, cr_get_int(&strm, ";Anderepartei", -1));
CuAssertIntEquals(tc, 1, cr_get_int(&strm, ";Verraeter", -1));
+ mstream_done(&strm);
al = ally_add(&f1->allies, f2);
al->status = HELP_FSTEALTH;
-
+ mstream_init(&strm);
cr_output_unit(&strm, u->region, f2, u, seen_unit);
CuAssertIntEquals(tc, f1->no, cr_get_int(&strm, ";Partei", -1));
CuAssertIntEquals(tc, f2->no, cr_get_int(&strm, ";Anderepartei", -1));
- CuAssertIntEquals(tc, 1, cr_get_int(&strm, ";Verraeter", -1));
-
+ CuAssertIntEquals(tc, -1, cr_get_int(&strm, ";Verraeter", -1));
mstream_done(&strm);
+
test_cleanup();
}
@@ -111,6 +193,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/economy.c b/src/economy.c
index 2a6fea671..d5ee5a4bf 100644
--- a/src/economy.c
+++ b/src/economy.c
@@ -2120,7 +2120,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);
@@ -2185,7 +2185,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);
@@ -2303,7 +2303,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/give.c b/src/give.c
index 5cd19710e..2de8ccf72 100644
--- a/src/give.c
+++ b/src/give.c
@@ -122,6 +122,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 */
@@ -562,7 +584,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/config.c b/src/kernel/config.c
index b605fddd4..a18fc6494 100644
--- a/src/kernel/config.c
+++ b/src/kernel/config.c
@@ -845,6 +845,7 @@ const char * game_mailcmd(void)
*r++ = (char)toupper(*c);
}
*r = '\0';
+ log_warning("game.mailcmd configuration is not set, using %s from game.name", result);
return result;
}
return param;
diff --git a/src/kernel/faction.c b/src/kernel/faction.c
index 57cd5d3af..139474048 100755
--- a/src/kernel/faction.c
+++ b/src/kernel/faction.c
@@ -449,12 +449,10 @@ void destroyfaction(faction ** fp)
/* units of other factions that were disguised as this faction
* have their disguise replaced by ordinary faction hiding. */
if (rule_stealth_other()) {
- /* TODO: f.alive should be tested for in get_otherfaction */
region *rc;
for (rc = regions; rc; rc = rc->next) {
for (u = rc->units; u; u = u->next) {
- attrib *a = a_find(u->attribs, &at_otherfaction);
- if (a && get_otherfaction(a) == f) {
+ if (u->attribs && get_otherfaction(u) == f) {
a_removeall(&u->attribs, &at_otherfaction);
if (rule_stealth_anon()) {
fset(u, UFL_ANON_FACTION);
diff --git a/src/kernel/item.c b/src/kernel/item.c
index 1197e7ce5..d9a466543 100644
--- a/src/kernel/item.c
+++ b/src/kernel/item.c
@@ -565,29 +565,62 @@ item *i_new(const item_type * itype, int size)
#include "region.h"
-#define R_MINOTHER R_SILVER
-#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
+static int
+give_horses(unit * s, unit * d, const item_type * itype, int n,
+struct order *ord)
+{
+ if (d == NULL) {
+ int use = use_pooled(s, item2resource(itype), GET_SLACK, n);
+ region *r = s->region;
+ if (use < n) {
+ use +=
+ use_pooled(s, item2resource(itype), GET_RESERVE | GET_POOLED_SLACK,
+ n - use);
+ }
+ if (r->land) {
+ rsethorses(r, rhorses(r) + use);
+ }
+ return 0;
+ }
+ return -1; /* use the mechanism */
+}
-const potion_type *oldpotiontype[MAXPOTIONS + 1];
+static int
+give_money(unit * s, unit * d, const item_type * itype, int n,
+struct order *ord)
+{
+ if (d == NULL) {
+ int use = use_pooled(s, item2resource(itype), GET_SLACK, n);
+ region *r = s->region;
+ if (use < n) {
+ use +=
+ use_pooled(s, item2resource(itype), GET_RESERVE | GET_POOLED_SLACK,
+ n - use);
+ }
+ if (r->land) {
+ rsetmoney(r, rmoney(r) + use);
+ }
+ return 0;
+ }
+ return -1; /* use the mechanism */
+}
+
+const potion_type *oldpotiontype[MAX_POTIONS + 1];
/*** alte items ***/
static const char *resourcenames[MAX_RESOURCES] = {
+ "money", "aura", "permaura",
+ "hp", "peasant",
+ "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) {
@@ -694,7 +727,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;
@@ -706,24 +739,36 @@ void init_resources(void)
{
resource_type *rtype;
- rt_get_or_create(resourcenames[R_PERSON]); /* lousy hack */
-
- rtype = rt_get_or_create(resourcenames[R_PEASANT]);
- rtype->uchange = res_changepeasants;
+ /* 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.
+ */
+ /* 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 = rt_get_or_create(resourcenames[R_PERMAURA]);
- rtype->uchange = res_changepermaura;
+ 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;
- rtype = rt_get_or_create(resourcenames[R_LIFE]);
- rtype->uchange = res_changehp;
+ 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;
+ 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: */
init_oldpotions();
diff --git a/src/kernel/item.h b/src/kernel/item.h
index 77fe1a9c2..d647bce8c 100644
--- a/src/kernel/item.h
+++ b/src/kernel/item.h
@@ -243,8 +243,26 @@ 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_SAPLING,
+ R_MALLORN_SAPLING,
+ R_TREE,
+ R_MALLORN_TREE,
/* ITEMS: */
+ R_SEED,
+ R_MALLORN_SEED,
R_IRON,
R_STONE,
R_HORSE,
@@ -268,15 +286,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/kernel/item.test.c b/src/kernel/item.test.c
index e8b8d79e3..c1c64bf62 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();
}
@@ -164,8 +164,6 @@ static void test_core_resources(CuTest *tc) {
CuAssertPtrNotNull(tc, rtype->uchange);
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"));
diff --git a/src/kernel/resources.c b/src/kernel/resources.c
index 10cb2bab6..932147a5f 100644
--- a/src/kernel/resources.c
+++ b/src/kernel/resources.c
@@ -204,6 +204,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/kernel/unit.c b/src/kernel/unit.c
index 4592d0bc7..595accba2 100644
--- a/src/kernel/unit.c
+++ b/src/kernel/unit.c
@@ -1565,9 +1565,11 @@ unit *create_unit(region * r, faction * f, int number, const struct race *urace,
set_group(u, g);
}
}
- a = a_find(creator->attribs, &at_otherfaction);
- if (a) {
- a_add(&u->attribs, make_otherfaction(get_otherfaction(a)));
+ if (creator->attribs) {
+ faction *otherf = get_otherfaction(creator);
+ if (otherf) {
+ a_add(&u->attribs, make_otherfaction(otherf));
+ }
}
a = a_add(&u->attribs, a_new(&at_creator));
diff --git a/src/report.c b/src/report.c
index cf00abbc3..2f8ba7bce 100644
--- a/src/report.c
+++ b/src/report.c
@@ -680,7 +680,6 @@ static void rps_nowrap(struct stream *out, const char *s)
static void
nr_unit(struct stream *out, const faction * f, const unit * u, int indent, seen_mode mode)
{
- attrib *a_otherfaction;
char marker;
int dh;
bool isbattle = (bool)(mode == seen_battle);
@@ -692,16 +691,14 @@ nr_unit(struct stream *out, const faction * f, const unit * u, int indent, seen_
newline(out);
dh = bufunit(f, u, indent, mode, buf, sizeof(buf));
- a_otherfaction = a_find(u->attribs, &at_otherfaction);
-
if (u->faction == f) {
marker = '*';
}
else if (is_allied(u->faction, f)) {
marker = 'o';
}
- else if (a_otherfaction && f != u->faction
- && get_otherfaction(a_otherfaction) == f && !fval(u, UFL_ANON_FACTION)) {
+ else if (u->attribs && f != u->faction
+ && !fval(u, UFL_ANON_FACTION) && get_otherfaction(u) == f) {
marker = '!';
}
else {
@@ -878,7 +875,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;
@@ -987,10 +984,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();
@@ -1004,8 +1001,9 @@ static void describe(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].name), result[n].level);
+ LOC(f->locale, name), result[n].level);
if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER();
}
@@ -1181,7 +1179,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 +1996,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 +2278,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 +2306,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..3c6a09ae1 100644
--- a/src/report.test.c
+++ b/src/report.test.c
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -56,7 +57,92 @@ 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;
+ 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 };
char buf[1024];
size_t len;
@@ -65,7 +151,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 +163,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 +171,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 +180,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 +320,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;
}
diff --git a/src/reports.c b/src/reports.c
index a07b60f4b..aae3d3031 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;
}
}
@@ -448,17 +449,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);
@@ -469,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;
@@ -497,7 +500,6 @@ size_t size)
bufp = STRLCPY(bufp, unitname(u), size);
fv = visible_faction(f, u);
if (!isbattle) {
- attrib *a_otherfaction = a_find(u->attribs, &at_otherfaction);
if (u->faction == f) {
if (fval(u, UFL_GROUP)) {
attrib *a = a_find(u->attribs, &at_group);
@@ -511,11 +513,11 @@ size_t size)
bufp = STRLCPY(bufp, ", ", size);
bufp = STRLCPY(bufp, LOC(f->locale, "anonymous"), size);
}
- else if (a_otherfaction) {
- faction *otherfaction = get_otherfaction(a_otherfaction);
- if (otherfaction) {
+ else if (u->attribs) {
+ faction *otherf = get_otherfaction(u);
+ if (otherf) {
bufp = STRLCPY(bufp, ", ", size);
- bufp = STRLCPY(bufp, factionname(otherfaction), size);
+ bufp = STRLCPY(bufp, factionname(otherf), size);
}
}
}
@@ -525,13 +527,15 @@ size_t size)
bufp = STRLCPY(bufp, LOC(f->locale, "anonymous"), size);
}
else {
- if (a_otherfaction && alliedunit(u, f, HELP_FSTEALTH)) {
- faction *f = get_otherfaction(a_otherfaction);
- int result =
- snprintf(bufp, size, ", %s (%s)", factionname(f),
- factionname(u->faction));
- if (wrptr(&bufp, &size, result) != 0)
- WARN_STATIC_BUFFER();
+ if (u->attribs && alliedunit(u, f, HELP_FSTEALTH)) {
+ faction *otherf = get_otherfaction(u);
+ if (otherf) {
+ int result =
+ snprintf(bufp, size, ", %s (%s)", factionname(otherf),
+ factionname(u->faction));
+ if (wrptr(&bufp, &size, result) != 0)
+ WARN_STATIC_BUFFER();
+ }
}
else {
bufp = STRLCPY(bufp, ", ", size);
@@ -2049,7 +2053,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];
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;
diff --git a/src/util/variant.test.c b/src/util/variant.test.c
index 12299720b..37aa3f77e 100644
--- a/src/util/variant.test.c
+++ b/src/util/variant.test.c
@@ -30,6 +30,16 @@ static void test_fractions(CuTest *tc) {
CuAssertIntEquals(tc, -1, frac_sign(frac_make(-1, 1)));
CuAssertIntEquals(tc, -1, frac_sign(frac_make(1, -1)));
CuAssertIntEquals(tc, 0, frac_sign(frac_make(0, 1)));
+
+ /* we reduce large integers by calculating the gcd */
+ a = frac_make(480000, 3000);
+ CuAssertIntEquals(tc, 160, a.sa[0]);
+ CuAssertIntEquals(tc, 1, a.sa[1]);
+
+ /* if num is too big for a short, and the gcd is 1, we cheat: */
+ a = frac_make(480001, 3000);
+ CuAssertIntEquals(tc, 32000, a.sa[0]);
+ CuAssertIntEquals(tc, 200, a.sa[1]);
}
CuSuite *get_variant_suite(void)
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 2183b17dd..5621e84a9 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,6 +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 "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"