BUG 2303: allied units are not traitors.

had to rewrite the creport code for this, it is probably less efficient now than ever, but at least it works.
This commit is contained in:
Enno Rehling 2017-03-06 21:35:48 +01:00
parent 4b246863c0
commit 05bb109a09
8 changed files with 56 additions and 64 deletions

View File

@ -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)
{
attrib *a = a_find(u->attribs, &at_otherfaction);
if (a) {
faction * f = (faction *)(a->data.v);
return (f && f->_alive) ? f : NULL;
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);
faction *fv = get_otherfaction(u);
if (fv) return fv;
}
}
return u->faction;
}

View File

@ -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);

View File

@ -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);

View File

@ -748,8 +748,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 +763,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,37 +774,30 @@ 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);
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;
}
else {
/* other unit. show visible faction, not u->faction */
stream_printf(out, "%d;Partei\n", sf ? sf->no : f->no);
if (alliedunit(u, f, HELP_FSTEALTH)) {
if (sf && sf != u->faction) {
stream_printf(out, "%d;Anderepartei\n", sf->no);
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);
}
else if (sf == f) {
if (!allied && fother == f) {
/* sieht aus wie unsere, ist es aber nicht. */
stream_printf(out, "1;Verraeter\n");
}
}
}
prefix = raceprefix(u);
if (prefix) {
prefix = mkname("prefix", prefix);

View File

@ -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);

View File

@ -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));

View File

@ -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 {

View File

@ -497,7 +497,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 +510,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,14 +524,16 @@ 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);
if (u->attribs && alliedunit(u, f, HELP_FSTEALTH)) {
faction *otherf = get_otherfaction(u);
if (otherf) {
int result =
snprintf(bufp, size, ", %s (%s)", factionname(f),
snprintf(bufp, size, ", %s (%s)", factionname(otherf),
factionname(u->faction));
if (wrptr(&bufp, &size, result) != 0)
WARN_STATIC_BUFFER();
}
}
else {
bufp = STRLCPY(bufp, ", ", size);
bufp = STRLCPY(bufp, factionname(fv), size);