an experiment to have deterministic sort order for known factions in the report.

This commit is contained in:
Enno Rehling 2014-08-24 23:36:06 +02:00
parent a3037950ff
commit e87b1cf372
6 changed files with 149 additions and 106 deletions

View File

@ -176,6 +176,9 @@
<string name="wall1"> <string name="wall1">
<text locale="en">Wall</text> <text locale="en">Wall</text>
</string> </string>
<string name="wall1_trail">
<text locale="de">a solid wall</text>
</string>
<string name="hall1_trail"> <string name="hall1_trail">
<text locale="en">the %s</text> <text locale="en">the %s</text>
</string> </string>

View File

@ -3606,7 +3606,7 @@
<arg name="weeks" type="int"/> <arg name="weeks" type="int"/>
<arg name="skill" type="skill"/> <arg name="skill" type="skill"/>
</type> </type>
<text locale="de">"$unit($unit) vergißt durch Dumpfbackenbrot $int($weeks) Wochen des Talentes $skill($skill)."</text> <text locale="de">"$unit($unit) vergisst durch Dumpfbackenbrot $int($weeks) Wochen des Talentes $skill($skill)."</text>
<text locale="fr">"$unit($unit) eats a Dumpfbackenbrot and forgets $int($weeks) weeks worth of $skill($skill)."</text> <text locale="fr">"$unit($unit) eats a Dumpfbackenbrot and forgets $int($weeks) weeks worth of $skill($skill)."</text>
<text locale="en">"$unit($unit) eats a Dumpfbackenbrot and forgets $int($weeks) weeks worth of $skill($skill)."</text> <text locale="en">"$unit($unit) eats a Dumpfbackenbrot and forgets $int($weeks) weeks worth of $skill($skill)."</text>
</message> </message>
@ -3699,7 +3699,7 @@
<arg name="unit" type="unit"/> <arg name="unit" type="unit"/>
<arg name="skill" type="skill"/> <arg name="skill" type="skill"/>
</type> </type>
<text locale="de">"$unit($unit) vergißt $skill($skill)."</text> <text locale="de">"$unit($unit) vergisst $skill($skill)."</text>
<text locale="fr">"$unit($unit) forgets $skill($skill)."</text> <text locale="fr">"$unit($unit) forgets $skill($skill)."</text>
<text locale="en">"$unit($unit) forgets $skill($skill)."</text> <text locale="en">"$unit($unit) forgets $skill($skill)."</text>
</message> </message>

View File

@ -1048,6 +1048,23 @@ void transfer_seen(quicklist ** dst, quicklist ** src)
*src = NULL; *src = NULL;
} }
int cmp_faction(const void *lhs, const void *rhs) {
const faction *lhf = (const faction *)lhs;
const faction *rhf = (const faction *)rhs;
if (lhf->no == rhf->no) return 0;
if (lhf->no > rhf->no) return 1;
return -1;
}
static void add_seen_faction_i(struct quicklist **flist, faction *f) {
ql_set_insert_ex(flist, f, cmp_faction);
}
void add_seen_faction(faction *self, faction *seen) {
add_seen_faction_i(&self->seen_factions, seen);
}
static void get_addresses(report_context * ctx) static void get_addresses(report_context * ctx)
{ {
/* "TODO: travelthru" */ /* "TODO: travelthru" */
@ -1065,7 +1082,7 @@ static void get_addresses(report_context * ctx)
quicklist *ql = ctx->f->alliance->members; quicklist *ql = ctx->f->alliance->members;
int qi; int qi;
for (qi = 0; ql; ql_advance(&ql, &qi, 1)) { for (qi = 0; ql; ql_advance(&ql, &qi, 1)) {
ql_set_insert(&flist, ql_get(ql, qi)); add_seen_faction_i(&flist, (faction *)ql_get(ql, qi));
} }
} }
@ -1084,7 +1101,7 @@ static void get_addresses(report_context * ctx)
if (lastf != sf) { if (lastf != sf) {
if (u->building || u->ship || (stealthmod > INT_MIN if (u->building || u->ship || (stealthmod > INT_MIN
&& cansee(ctx->f, r, u, stealthmod))) { && cansee(ctx->f, r, u, stealthmod))) {
ql_set_insert(&flist, sf); add_seen_faction_i(&flist, sf);
lastf = sf; lastf = sf;
} }
} }
@ -1101,7 +1118,7 @@ static void get_addresses(report_context * ctx)
unit *u2 = (unit *)a->data.v; unit *u2 = (unit *)a->data.v;
if (u2->faction == ctx->f) { if (u2->faction == ctx->f) {
if (cansee_unit(u2, u, stealthmod)) { if (cansee_unit(u2, u, stealthmod)) {
ql_set_insert(&flist, sf); add_seen_faction_i(&flist, sf);
lastf = sf; lastf = sf;
break; break;
} }
@ -1120,7 +1137,7 @@ static void get_addresses(report_context * ctx)
bool ballied = sf && sf != ctx->f && sf != lastf bool ballied = sf && sf != ctx->f && sf != lastf
&& !fval(u, UFL_ANON_FACTION) && cansee(ctx->f, r, u, stealthmod); && !fval(u, UFL_ANON_FACTION) && cansee(ctx->f, r, u, stealthmod);
if (ballied || ALLIED(ctx->f, sf)) { if (ballied || ALLIED(ctx->f, sf)) {
ql_set_insert(&flist, sf); add_seen_faction_i(&flist, sf);
lastf = sf; lastf = sf;
} }
} }
@ -1133,7 +1150,7 @@ static void get_addresses(report_context * ctx)
faction *f2; faction *f2;
for (f2 = factions; f2; f2 = f2->next) { for (f2 = factions; f2; f2 = f2->next) {
if (f2->alliance == ctx->f->alliance) { if (f2->alliance == ctx->f->alliance) {
ql_set_insert(&flist, f2); add_seen_faction_i(&flist, f2);
} }
} }
} }

View File

@ -1,7 +1,7 @@
/* /*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de> Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de> Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@ -26,129 +26,130 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
extern "C" { extern "C" {
#endif #endif
/* Alter, ab dem der Score angezeigt werden soll: */ /* Alter, ab dem der Score angezeigt werden soll: */
#define DISPLAYSCORE 12 #define DISPLAYSCORE 12
/* Breite einer Reportzeile: */ /* Breite einer Reportzeile: */
#define REPORTWIDTH 78 #define REPORTWIDTH 78
extern const char *directions[]; extern const char *directions[];
extern const char *coasts[]; extern const char *coasts[];
extern bool nonr; extern const char *combatstatus[];
extern bool nocr; extern bool nonr;
extern bool noreports; extern bool nocr;
extern bool noreports;
/* kann_finden speedups */ /* kann_finden speedups */
extern bool kann_finden(struct faction *f1, struct faction *f2); bool kann_finden(struct faction *f1, struct faction *f2);
extern struct unit *can_find(struct faction *, struct faction *); struct unit *can_find(struct faction *, struct faction *);
/* funktionen zum schreiben eines reports */ /* funktionen zum schreiben eines reports */
void sparagraph(struct strlist **SP, const char *s, int indent, char mark); void sparagraph(struct strlist **SP, const char *s, int indent, char mark);
void lparagraph(struct strlist **SP, char *s, int indent, char mark); void lparagraph(struct strlist **SP, char *s, int indent, char mark);
const char *hp_status(const struct unit *u); const char *hp_status(const struct unit *u);
extern size_t spskill(char *pbuf, size_t siz, const struct locale *lang, const struct unit *u, struct skill *sv, int *dh, int days); /* mapper */ size_t spskill(char *pbuf, size_t siz, const struct locale *lang, const struct unit *u, struct skill *sv, int *dh, int days); /* mapper */
extern void spunit(struct strlist **SP, const struct faction *f, void spunit(struct strlist **SP, const struct faction *f,
const struct unit *u, int indent, int mode); const struct unit *u, int indent, int mode);
extern int reports(void); int reports(void);
extern int write_reports(struct faction *f, time_t ltime); int write_reports(struct faction *f, time_t ltime);
extern int init_reports(void); int init_reports(void);
extern void reorder_units(struct region * r); void reorder_units(struct region * r);
extern const struct unit *ucansee(const struct faction *f, const struct unit *ucansee(const struct faction *f,
const struct unit *u, const struct unit *x); const struct unit *u, const struct unit *x);
enum { enum {
see_none, see_none,
see_neighbour, see_neighbour,
see_lighthouse, see_lighthouse,
see_travel, see_travel,
see_far, see_far,
see_unit, see_unit,
see_battle see_battle
}; };
extern int stealth_modifier(int seen_mode); int stealth_modifier(int seen_mode);
typedef struct seen_region { typedef struct seen_region {
struct seen_region *nextHash; struct seen_region *nextHash;
struct seen_region *next; struct seen_region *next;
struct region *r; struct region *r;
unsigned char mode; unsigned char mode;
bool disbelieves; bool disbelieves;
} seen_region; } seen_region;
extern struct seen_region *find_seen(struct seen_region *seehash[], struct seen_region *find_seen(struct seen_region *seehash[],
const struct region *r); const struct region *r);
extern bool add_seen(struct seen_region *seehash[], struct region *r, bool add_seen(struct seen_region *seehash[], struct region *r,
unsigned char mode, bool dis); unsigned char mode, bool dis);
extern struct seen_region **seen_init(void); struct seen_region **seen_init(void);
extern void seen_done(struct seen_region *seehash[]); void seen_done(struct seen_region *seehash[]);
extern void free_seen(void); void free_seen(void);
extern void link_seen(seen_region * seehash[], const struct region *first, void link_seen(seen_region * seehash[], const struct region *first,
const struct region *last); const struct region *last);
extern const char *visibility[]; const char *visibility[];
typedef struct report_context { typedef struct report_context {
struct faction *f; struct faction *f;
struct quicklist *addresses; struct quicklist *addresses;
struct seen_region **seen; struct seen_region **seen;
struct region *first, *last; struct region *first, *last;
void *userdata; void *userdata;
time_t report_time; time_t report_time;
} report_context; } report_context;
typedef int (*report_fun) (const char *filename, report_context * ctx, typedef int(*report_fun) (const char *filename, report_context * ctx,
const char *charset); const char *charset);
extern void register_reporttype(const char *extension, report_fun write, void register_reporttype(const char *extension, report_fun write,
int flag); int flag);
extern int bufunit(const struct faction *f, const struct unit *u, int indent, int bufunit(const struct faction *f, const struct unit *u, int indent,
int mode, char *buf, size_t size); int mode, char *buf, size_t size);
extern const char *trailinto(const struct region *r, const char *trailinto(const struct region *r,
const struct locale *lang); const struct locale *lang);
extern const char *report_kampfstatus(const struct unit *u, const char *report_kampfstatus(const struct unit *u,
const struct locale *lang); const struct locale *lang);
extern void register_reports(void); void register_reports(void);
extern int update_nmrs(void); int update_nmrs(void);
extern int *nmrs; int *nmrs;
extern struct message *msg_curse(const struct curse *c, const void *obj, struct message *msg_curse(const struct curse *c, const void *obj,
objtype_t typ, int slef); objtype_t typ, int slef);
typedef struct arg_regions { typedef struct arg_regions {
int nregions; int nregions;
struct region **regions; struct region **regions;
} arg_regions; } arg_regions;
typedef struct resource_report { typedef struct resource_report {
const char *name; const char *name;
int number; int number;
int level; int level;
} resource_report; } resource_report;
int report_resources(const struct seen_region *sr, int report_resources(const struct seen_region *sr,
struct resource_report *result, int size, const struct faction *viewer); struct resource_report *result, int size, const struct faction *viewer);
int report_items(const struct item *items, struct item *result, int size, int report_items(const struct item *items, struct item *result, int size,
const struct unit *owner, const struct faction *viewer); const struct unit *owner, const struct faction *viewer);
void report_item(const struct unit *owner, const struct item *i, void report_item(const struct unit *owner, const struct item *i,
const struct faction *viewer, const char **name, const char **basename, const struct faction *viewer, const char **name, const char **basename,
int *number, bool singular); int *number, bool singular);
void report_building(const struct building *b, const char **btype, void report_building(const struct building *b, const char **btype,
const char **billusion); const char **billusion);
void report_race(const struct unit *u, const char **rcname, void report_race(const struct unit *u, const char **rcname,
const char **rcillusion); const char **rcillusion);
void add_seen_faction(struct faction *self, struct faction *seen);
#define ACTION_RESET 0x01 /* reset the one-time-flag FFL_SELECT (on first pass) */ #define ACTION_RESET 0x01 /* reset the one-time-flag FFL_SELECT (on first pass) */
#define ACTION_CANSEE 0x02 /* to people who can see the actor */ #define ACTION_CANSEE 0x02 /* to people who can see the actor */
#define ACTION_CANNOTSEE 0x04 /* to people who can not see the actor */ #define ACTION_CANNOTSEE 0x04 /* to people who can not see the actor */
extern int report_action(struct region *r, struct unit *actor, int report_action(struct region *r, struct unit *actor,
struct message *msg, int flags); struct message *msg, int flags);
extern size_t f_regionid(const struct region *r, const struct faction *f, size_t f_regionid(const struct region *r, const struct faction *f,
char *buffer, size_t size); char *buffer, size_t size);
extern const char *combatstatus[];
#define GR_PLURAL 0x01 /* grammar: plural */ #define GR_PLURAL 0x01 /* grammar: plural */
#define MAX_INVENTORY 128 /* maimum number of different items in an inventory */ #define MAX_INVENTORY 128 /* maimum number of different items in an inventory */
#define MAX_RAWMATERIALS 8 /* maximum kinds of raw materials in a regions */ #define MAX_RAWMATERIALS 8 /* maximum kinds of raw materials in a regions */

View File

@ -1,11 +1,15 @@
#include <platform.h> #include <platform.h>
#include <kernel/building.h> #include <kernel/building.h>
#include <kernel/faction.h>
#include <kernel/race.h>
#include <kernel/reports.h> #include <kernel/reports.h>
#include <kernel/region.h> #include <kernel/region.h>
#include <kernel/ship.h> #include <kernel/ship.h>
#include <kernel/unit.h> #include <kernel/unit.h>
#include <quicklist.h>
#include <CuTest.h> #include <CuTest.h>
#include <tests.h> #include <tests.h>
@ -76,10 +80,28 @@ static void test_regionid(CuTest * tc) {
CuAssertIntEquals(tc, 0x7d, buffer[11]); CuAssertIntEquals(tc, 0x7d, buffer[11]);
} }
static void test_seen_faction(CuTest *tc) {
faction *f1, *f2;
race *rc = test_create_race("human");
f1 = test_create_faction(rc);
f2 = test_create_faction(rc);
add_seen_faction(f1, f2);
CuAssertPtrEquals(tc, f2, ql_get(f1->seen_factions, 0));
CuAssertIntEquals(tc, 1, ql_length(f1->seen_factions));
add_seen_faction(f1, f2);
CuAssertIntEquals(tc, 1, ql_length(f1->seen_factions));
add_seen_faction(f1, f1);
CuAssertIntEquals(tc, 2, ql_length(f1->seen_factions));
f2 = (faction *)ql_get(f1->seen_factions, 1);
f1 = (faction *)ql_get(f1->seen_factions, 0);
CuAssertTrue(tc, f1->no<f2->no);
}
CuSuite *get_reports_suite(void) CuSuite *get_reports_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_reorder_units); SUITE_ADD_TEST(suite, test_reorder_units);
SUITE_ADD_TEST(suite, test_seen_faction);
SUITE_ADD_TEST(suite, test_regionid); SUITE_ADD_TEST(suite, test_regionid);
return suite; return suite;
} }

View File

@ -76,7 +76,7 @@ void spy_message(int spy, const unit * u, const unit * target)
/* true faction */ /* true faction */
ADDMSG(&u->faction->msgs, msg_message("spyreport_faction", ADDMSG(&u->faction->msgs, msg_message("spyreport_faction",
"target faction", target, target->faction)); "target faction", target, target->faction));
ql_set_insert(&u->faction->seen_factions, target->faction); add_seen_faction(u->faction, target->faction);
} }
} }
if (spy > 0) { if (spy > 0) {