Merge pull request #667 from ennorehling/hotfix/config-2301

fix bugs 2301, 2302, 2303
This commit is contained in:
Enno Rehling 2017-03-06 21:57:23 +01:00 committed by GitHub
commit ba8f51b7d4
12 changed files with 86 additions and 72 deletions

View File

@ -57,10 +57,16 @@ attrib_type at_otherfaction = {
"otherfaction", NULL, NULL, NULL, write_of, read_of, NULL, ATF_UNIQUE "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); attrib *a = a_find(u->attribs, &at_otherfaction);
return (f && f->_alive) ? f : NULL; if (a) {
faction * f = (faction *)(a->data.v);
if (f && f->_alive) {
return f;
}
}
return NULL;
} }
struct attrib *make_otherfaction(struct faction *f) 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) faction *visible_faction(const faction * f, const unit * u)
{ {
if (f == NULL || !alliedunit(u, f, HELP_FSTEALTH)) { if (f == NULL || !alliedunit(u, f, HELP_FSTEALTH)) {
attrib *a = a_find(u->attribs, &at_otherfaction); faction *fv = get_otherfaction(u);
if (a) { if (fv) return fv;
faction *fv = get_otherfaction(a);
if (fv) return fv;
}
} }
return u->faction; return u->faction;
} }

View File

@ -25,7 +25,7 @@ extern "C" {
struct attrib; struct attrib;
extern struct attrib_type at_otherfaction; 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 attrib *make_otherfaction(struct faction *f);
extern struct faction *visible_faction(const struct faction *f, extern struct faction *visible_faction(const struct faction *f,
const struct unit *u); const struct unit *u);

View File

@ -3126,8 +3126,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
int speeded = 0, speed = 1; int speeded = 0, speed = 1;
int rest; int rest;
const group *g = NULL; const group *g = NULL;
const attrib *a = a_find(u->attribs, &at_otherfaction); const faction *stealthfaction = get_otherfaction(u);
const faction *stealthfaction = a ? get_otherfaction(a) : NULL;
unsigned int flags = 0; unsigned int flags = 0;
assert(u->number); assert(u->number);

View File

@ -751,8 +751,9 @@ void cr_output_unit(stream *out, const region * r, const faction * f,
const char *pzTmp; const char *pzTmp;
skill *sv; skill *sv;
item result[MAX_INVENTORY]; item result[MAX_INVENTORY];
const faction *sf; const faction *fother, *fseen;
const char *prefix; const char *prefix;
bool allied;
assert(u && u->number); assert(u && u->number);
assert(u->region == r); /* TODO: if this holds true, then why did we pass in r? */ 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) { if (str) {
stream_printf(out, "\"%s\";Beschr\n", str); stream_printf(out, "\"%s\";Beschr\n", str);
} }
/* print faction information */
sf = visible_faction(NULL, u); if (u->faction == f) {
if (u->faction == f || omniscient(f)) {
/* my own faction, full info */
const attrib *a = NULL; const attrib *a = NULL;
unit *mage; 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; const group *g = (const group *)a->data.v;
stream_printf(out, "%d;gruppe\n", g->gid); 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); mage = get_familiar_mage(u);
if (mage) { if (mage) {
stream_printf(out, "%u;familiarmage\n", mage->no); stream_printf(out, "%u;familiarmage\n", mage->no);
} }
} }
else {
if (fval(u, UFL_ANON_FACTION)) { fseen = u->faction;
/* faction info is hidden */ fother = get_otherfaction(u);
stream_printf(out, "%d;Parteitarnung\n", (u->flags & UFL_ANON_FACTION) != 0); allied = u->faction == f || alliedunit(u, f, HELP_FSTEALTH);
} if (fother && f != u->faction && !allied) {
else { /* getarnt, keine eigene, und kein HELFE fuer uns: wir sehen den fake */
/* other unit. show visible faction, not u->faction */ fseen = fother;
stream_printf(out, "%d;Partei\n", sf ? sf->no : f->no); }
if (sf == f) { stream_printf(out, "%d;Partei\n", fseen->no);
stream_printf(out, "1;Verraeter\n"); if (fother && fother!=fseen) {
} stream_printf(out, "%d;Anderepartei\n", fother->no);
if (sf && sf != u->faction) { }
if (alliedunit(u, f, HELP_FSTEALTH)) { if (fseen==f && fval(u, UFL_ANON_FACTION)) {
stream_printf(out, "%d;Anderepartei\n", sf->no); 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); prefix = raceprefix(u);
if (prefix) { if (prefix) {

View File

@ -148,39 +148,44 @@ static void test_cr_factionstealth(CuTest *tc) {
ally *al; ally *al;
test_setup(); test_setup();
mstream_init(&strm);
f1 = test_create_faction(0); f1 = test_create_faction(0);
f2 = test_create_faction(0); f2 = test_create_faction(0);
r = test_create_region(0, 0, 0); r = test_create_region(0, 0, 0);
u = test_create_unit(f1, r); u = test_create_unit(f1, r);
mstream_init(&strm);
cr_output_unit(&strm, u->region, f1, u, seen_unit); cr_output_unit(&strm, u->region, f1, u, seen_unit);
CuAssertIntEquals(tc, f1->no, cr_get_int(&strm, ";Partei", -1)); 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, ";Anderepartei", -1));
CuAssertIntEquals(tc, -1, cr_get_int(&strm, ";Verraeter", -1)); CuAssertIntEquals(tc, -1, cr_get_int(&strm, ";Verraeter", -1));
mstream_done(&strm);
set_factionstealth(u, f2); set_factionstealth(u, f2);
CuAssertPtrNotNull(tc, u->attribs); CuAssertPtrNotNull(tc, u->attribs);
mstream_init(&strm);
cr_output_unit(&strm, u->region, f1, u, seen_unit); cr_output_unit(&strm, u->region, f1, u, seen_unit);
CuAssertIntEquals(tc, f1->no, cr_get_int(&strm, ";Partei", -1)); 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, ";Anderepartei", -1));
CuAssertIntEquals(tc, -1, cr_get_int(&strm, ";Verraeter", -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); 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, ";Partei", -1));
CuAssertIntEquals(tc, f2->no, cr_get_int(&strm, ";Anderepartei", -1)); CuAssertIntEquals(tc, -1, 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);
al = ally_add(&f1->allies, f2); al = ally_add(&f1->allies, f2);
al->status = HELP_FSTEALTH; al->status = HELP_FSTEALTH;
mstream_init(&strm);
cr_output_unit(&strm, u->region, f2, u, seen_unit); cr_output_unit(&strm, u->region, f2, u, seen_unit);
CuAssertIntEquals(tc, f1->no, cr_get_int(&strm, ";Partei", -1)); 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, ";Anderepartei", -1));
CuAssertIntEquals(tc, 1, cr_get_int(&strm, ";Verraeter", -1)); CuAssertIntEquals(tc, -1, cr_get_int(&strm, ";Verraeter", -1));
mstream_done(&strm); mstream_done(&strm);
test_cleanup(); test_cleanup();
} }

View File

@ -845,6 +845,7 @@ const char * game_mailcmd(void)
*r++ = (char)toupper(*c); *r++ = (char)toupper(*c);
} }
*r = '\0'; *r = '\0';
log_warning("game.mailcmd configuration is not set, using %s from game.name", result);
return result; return result;
} }
return param; return param;

View File

@ -449,12 +449,10 @@ void destroyfaction(faction ** fp)
/* units of other factions that were disguised as this faction /* units of other factions that were disguised as this faction
* have their disguise replaced by ordinary faction hiding. */ * have their disguise replaced by ordinary faction hiding. */
if (rule_stealth_other()) { if (rule_stealth_other()) {
/* TODO: f.alive should be tested for in get_otherfaction */
region *rc; region *rc;
for (rc = regions; rc; rc = rc->next) { for (rc = regions; rc; rc = rc->next) {
for (u = rc->units; u; u = u->next) { for (u = rc->units; u; u = u->next) {
attrib *a = a_find(u->attribs, &at_otherfaction); if (u->attribs && get_otherfaction(u) == f) {
if (a && get_otherfaction(a) == f) {
a_removeall(&u->attribs, &at_otherfaction); a_removeall(&u->attribs, &at_otherfaction);
if (rule_stealth_anon()) { if (rule_stealth_anon()) {
fset(u, UFL_ANON_FACTION); fset(u, UFL_ANON_FACTION);

View File

@ -1565,9 +1565,11 @@ unit *create_unit(region * r, faction * f, int number, const struct race *urace,
set_group(u, g); set_group(u, g);
} }
} }
a = a_find(creator->attribs, &at_otherfaction); if (creator->attribs) {
if (a) { faction *otherf = get_otherfaction(creator);
a_add(&u->attribs, make_otherfaction(get_otherfaction(a))); if (otherf) {
a_add(&u->attribs, make_otherfaction(otherf));
}
} }
a = a_add(&u->attribs, a_new(&at_creator)); a = a_add(&u->attribs, a_new(&at_creator));

View File

@ -680,7 +680,6 @@ static void rps_nowrap(struct stream *out, const char *s)
static void static void
nr_unit(struct stream *out, const faction * f, const unit * u, int indent, seen_mode mode) nr_unit(struct stream *out, const faction * f, const unit * u, int indent, seen_mode mode)
{ {
attrib *a_otherfaction;
char marker; char marker;
int dh; int dh;
bool isbattle = (bool)(mode == seen_battle); 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); newline(out);
dh = bufunit(f, u, indent, mode, buf, sizeof(buf)); dh = bufunit(f, u, indent, mode, buf, sizeof(buf));
a_otherfaction = a_find(u->attribs, &at_otherfaction);
if (u->faction == f) { if (u->faction == f) {
marker = '*'; marker = '*';
} }
else if (is_allied(u->faction, f)) { else if (is_allied(u->faction, f)) {
marker = 'o'; marker = 'o';
} }
else if (a_otherfaction && f != u->faction else if (u->attribs && f != u->faction
&& get_otherfaction(a_otherfaction) == f && !fval(u, UFL_ANON_FACTION)) { && !fval(u, UFL_ANON_FACTION) && get_otherfaction(u) == f) {
marker = '!'; marker = '!';
} }
else { else {

View File

@ -500,7 +500,6 @@ size_t size)
bufp = STRLCPY(bufp, unitname(u), size); bufp = STRLCPY(bufp, unitname(u), size);
fv = visible_faction(f, u); fv = visible_faction(f, u);
if (!isbattle) { if (!isbattle) {
attrib *a_otherfaction = a_find(u->attribs, &at_otherfaction);
if (u->faction == f) { if (u->faction == f) {
if (fval(u, UFL_GROUP)) { if (fval(u, UFL_GROUP)) {
attrib *a = a_find(u->attribs, &at_group); attrib *a = a_find(u->attribs, &at_group);
@ -514,11 +513,11 @@ size_t size)
bufp = STRLCPY(bufp, ", ", size); bufp = STRLCPY(bufp, ", ", size);
bufp = STRLCPY(bufp, LOC(f->locale, "anonymous"), size); bufp = STRLCPY(bufp, LOC(f->locale, "anonymous"), size);
} }
else if (a_otherfaction) { else if (u->attribs) {
faction *otherfaction = get_otherfaction(a_otherfaction); faction *otherf = get_otherfaction(u);
if (otherfaction) { if (otherf) {
bufp = STRLCPY(bufp, ", ", size); 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); bufp = STRLCPY(bufp, LOC(f->locale, "anonymous"), size);
} }
else { else {
if (a_otherfaction && alliedunit(u, f, HELP_FSTEALTH)) { if (u->attribs && alliedunit(u, f, HELP_FSTEALTH)) {
faction *f = get_otherfaction(a_otherfaction); faction *otherf = get_otherfaction(u);
int result = if (otherf) {
snprintf(bufp, size, ", %s (%s)", factionname(f), int result =
factionname(u->faction)); snprintf(bufp, size, ", %s (%s)", factionname(otherf),
if (wrptr(&bufp, &size, result) != 0) factionname(u->faction));
WARN_STATIC_BUFFER(); if (wrptr(&bufp, &size, result) != 0)
WARN_STATIC_BUFFER();
}
} }
else { else {
bufp = STRLCPY(bufp, ", ", size); bufp = STRLCPY(bufp, ", ", size);

View File

@ -2,6 +2,7 @@
#include "variant.h" #include "variant.h"
#include <assert.h> #include <assert.h>
#include <stdlib.h>
#include <limits.h> #include <limits.h>
const variant frac_zero = { .sa = { 0, 1 } }; const variant frac_zero = { .sa = { 0, 1 } };
@ -41,8 +42,13 @@ variant frac_make(int num, int den)
int g = gcd(num, den); int g = gcd(num, den);
num /= g; num /= g;
den /= g; den /= g;
assert(num >= SHRT_MIN && num <= SHRT_MAX); if (num < SHRT_MIN || num > SHRT_MAX || den < SHRT_MIN || den > SHRT_MAX) {
assert(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[0] = (short)num;
v.sa[1] = (short)den; v.sa[1] = (short)den;
return v; return v;

View File

@ -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, -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))); 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) CuSuite *get_variant_suite(void)