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 9864adc41..018133516 100644 --- a/src/battle.c +++ b/src/battle.c @@ -3126,8 +3126,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 bea3a908d..f5d0f27fd 100644 --- a/src/creport.c +++ b/src/creport.c @@ -751,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? */ @@ -765,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; @@ -778,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) { diff --git a/src/creport.test.c b/src/creport.test.c index d0ce1532d..a56d1d589 100644 --- a/src/creport.test.c +++ b/src/creport.test.c @@ -148,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(); } 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/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 612df1dad..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 { diff --git a/src/reports.c b/src/reports.c index 63e274265..aae3d3031 100644 --- a/src/reports.c +++ b/src/reports.c @@ -500,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); @@ -514,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); } } } @@ -528,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); diff --git a/src/util/variant.c b/src/util/variant.c index c1d42808d..af5d690f4 100644 --- a/src/util/variant.c +++ b/src/util/variant.c @@ -2,6 +2,7 @@ #include "variant.h" #include +#include #include const variant frac_zero = { .sa = { 0, 1 } }; @@ -41,8 +42,13 @@ variant frac_make(int num, int den) int g = gcd(num, den); num /= g; den /= g; - assert(num >= SHRT_MIN && num <= SHRT_MAX); - assert(den >= SHRT_MIN && den <= SHRT_MAX); + if (num < SHRT_MIN || num > SHRT_MAX || den < SHRT_MIN || den > SHRT_MAX) { + int a = abs(num/SHRT_MIN) + 1; + int b = abs(den/SHRT_MIN) + 1; + if (b>a) a = b; + num /= a; + den /= a; + } v.sa[0] = (short)num; v.sa[1] = (short)den; return v; 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)