forked from github/server
code cleanup, reports. report types are now registered (some code I had on my disk since the days I was writing xml reports), and a new mailit format (reports.txt replaces mailit). Also, no more writing of shellscripts from the server, since that's done by an external script now.
This commit is contained in:
parent
cc7a1d15bb
commit
d2a75f15fe
10 changed files with 604 additions and 670 deletions
|
@ -404,37 +404,6 @@ cr_spell(variant var, char * buffer, const void * userdata)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
creport_init(void)
|
||||
{
|
||||
tsf_register("report", &cr_ignore);
|
||||
tsf_register("string", &cr_string);
|
||||
tsf_register("order", &cr_order);
|
||||
tsf_register("spell", &cr_spell);
|
||||
tsf_register("int", &cr_int);
|
||||
tsf_register("unit", &cr_unit);
|
||||
tsf_register("region", &cr_region);
|
||||
tsf_register("faction", &cr_faction);
|
||||
tsf_register("ship", &cr_ship);
|
||||
tsf_register("building", &cr_building);
|
||||
tsf_register("skill", &cr_skill);
|
||||
tsf_register("resource", &cr_resource);
|
||||
tsf_register("race", &cr_race);
|
||||
tsf_register("direction", &cr_int);
|
||||
tsf_register("alliance", &cr_alliance);
|
||||
}
|
||||
|
||||
void
|
||||
creport_cleanup(void)
|
||||
{
|
||||
while (junkyard) {
|
||||
translation * t = junkyard;
|
||||
junkyard = junkyard->next;
|
||||
free(t);
|
||||
}
|
||||
junkyard = 0;
|
||||
}
|
||||
|
||||
/*static int msgno; */
|
||||
|
||||
#define MTMAXHASH 1021
|
||||
|
@ -1071,11 +1040,11 @@ cr_borders(seen_region ** seen, const region * r, const faction * f, int seemode
|
|||
}
|
||||
|
||||
/* main function of the creport. creates the header and traverses all regions */
|
||||
int
|
||||
report_computer(FILE * F, faction * f, struct seen_region ** seen, const faction_list * addresses,
|
||||
const time_t report_time)
|
||||
static int
|
||||
report_computer(FILE * F, report_context * ctx)
|
||||
{
|
||||
int i;
|
||||
faction * f = ctx->f;
|
||||
item * itm;
|
||||
const char * prefix;
|
||||
region * r;
|
||||
|
@ -1090,14 +1059,14 @@ report_computer(FILE * F, faction * f, struct seen_region ** seen, const faction
|
|||
#endif
|
||||
|
||||
/* must call this to get all the neighbour regions */
|
||||
get_seen_interval(seen, &first, &last);
|
||||
get_seen_interval(ctx->seen, &first, &last);
|
||||
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
|
||||
/* initialisations, header and lists */
|
||||
|
||||
fprintf(F, "VERSION %d\n", C_REPORT_VERSION);
|
||||
fprintf(F, "\"%s\";locale\n", locale_name(f->locale));
|
||||
fprintf(F, "%d;noskillpoints\n", 1);
|
||||
fprintf(F, "%ld;date\n", report_time);
|
||||
fprintf(F, "%ld;date\n", ctx->report_time);
|
||||
fprintf(F, "\"%s\";Spiel\n", global.gamename);
|
||||
fprintf(F, "\"%s\";Konfiguration\n", "Standard");
|
||||
fprintf(F, "\"%s\";Koordinaten\n", "Hex");
|
||||
|
@ -1196,7 +1165,7 @@ report_computer(FILE * F, faction * f, struct seen_region ** seen, const faction
|
|||
}
|
||||
}
|
||||
|
||||
cr_find_address(F, f, addresses);
|
||||
cr_find_address(F, f, ctx->addresses);
|
||||
a = a_find(f->attribs, &at_reportspell);
|
||||
while (a) {
|
||||
cr_reportspell(F, (spellid_t)a->data.i, f->locale);
|
||||
|
@ -1234,7 +1203,7 @@ report_computer(FILE * F, faction * f, struct seen_region ** seen, const faction
|
|||
for (r=first;r!=last;r=r->next) {
|
||||
int modifier = 0;
|
||||
const char * tname;
|
||||
const seen_region * sd = find_seen(seen, r);
|
||||
const seen_region * sd = find_seen(ctx->seen, r);
|
||||
|
||||
if (sd==NULL) continue;
|
||||
|
||||
|
@ -1278,7 +1247,7 @@ report_computer(FILE * F, faction * f, struct seen_region ** seen, const faction
|
|||
}
|
||||
}
|
||||
if (sd->mode == see_neighbour) {
|
||||
cr_borders(seen, r, f, sd->mode, F);
|
||||
cr_borders(ctx->seen, r, f, sd->mode, F);
|
||||
} else {
|
||||
#define RESOURCECOMPAT
|
||||
char cbuf[8192], *pos = cbuf;
|
||||
|
@ -1371,7 +1340,7 @@ report_computer(FILE * F, faction * f, struct seen_region ** seen, const faction
|
|||
if (pos!=cbuf) fputs(cbuf, F);
|
||||
}
|
||||
print_curses(F, f, r, TYP_REGION);
|
||||
cr_borders(seen, r, f, sd->mode, F);
|
||||
cr_borders(ctx->seen, r, f, sd->mode, F);
|
||||
if (sd->mode==see_unit && rplane(r)==get_astralplane() && !is_cursed(r->attribs, C_ASTRALBLOCK, 0))
|
||||
{
|
||||
/* Sonderbehandlung Teleport-Ebene */
|
||||
|
@ -1489,3 +1458,36 @@ crwritemap(const char * filename)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
creport_init(void)
|
||||
{
|
||||
tsf_register("report", &cr_ignore);
|
||||
tsf_register("string", &cr_string);
|
||||
tsf_register("order", &cr_order);
|
||||
tsf_register("spell", &cr_spell);
|
||||
tsf_register("int", &cr_int);
|
||||
tsf_register("unit", &cr_unit);
|
||||
tsf_register("region", &cr_region);
|
||||
tsf_register("faction", &cr_faction);
|
||||
tsf_register("ship", &cr_ship);
|
||||
tsf_register("building", &cr_building);
|
||||
tsf_register("skill", &cr_skill);
|
||||
tsf_register("resource", &cr_resource);
|
||||
tsf_register("race", &cr_race);
|
||||
tsf_register("direction", &cr_int);
|
||||
tsf_register("alliance", &cr_alliance);
|
||||
|
||||
register_reporttype("cr", &report_computer, 1<<O_COMPUTER);
|
||||
}
|
||||
|
||||
void
|
||||
creport_cleanup(void)
|
||||
{
|
||||
while (junkyard) {
|
||||
translation * t = junkyard;
|
||||
junkyard = junkyard->next;
|
||||
free(t);
|
||||
}
|
||||
junkyard = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,17 +17,9 @@ extern "C" {
|
|||
|
||||
#include <time.h>
|
||||
|
||||
struct faction_list;
|
||||
struct seen_region;
|
||||
struct faction;
|
||||
extern int report_computer(FILE * F, struct faction * f, struct seen_region ** seen,
|
||||
const struct faction_list * addresses, const time_t report_time);
|
||||
extern void creport_cleanup(void);
|
||||
extern void creport_init(void);
|
||||
|
||||
extern void report_init(void);
|
||||
extern void report_cleanup(void);
|
||||
|
||||
extern int crwritemap(const char * filename);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -835,28 +835,6 @@ forget_cmd(unit * u, order * ord)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
report_donations(void)
|
||||
{
|
||||
region * r;
|
||||
for (r=regions;r;r=r->next) {
|
||||
while (r->donations) {
|
||||
donation * sp = r->donations;
|
||||
if (sp->amount > 0) {
|
||||
struct message * msg = msg_message("donation",
|
||||
"from to amount", sp->f1, sp->f2, sp->amount);
|
||||
r_addmessage(r, sp->f1, msg);
|
||||
r_addmessage(r, sp->f2, msg);
|
||||
msg_release(msg);
|
||||
}
|
||||
r->donations = sp->next;
|
||||
free(sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
add_spende(faction * f1, faction * f2, int amount, region * r)
|
||||
{
|
||||
|
|
|
@ -53,7 +53,6 @@ void produce(void);
|
|||
enum { IC_WORK, IC_ENTERTAIN, IC_TAX, IC_TRADE, IC_TRADETAX, IC_STEAL, IC_MAGIC };
|
||||
void maintain_buildings(boolean crash);
|
||||
extern void add_spende(struct faction * f1, struct faction * f2, int betrag, struct region * r);
|
||||
void report_donations(void);
|
||||
extern void init_economy(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -200,6 +200,9 @@
|
|||
<File
|
||||
RelativePath=".\randenc.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\report.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\creation.c">
|
||||
|
|
|
@ -71,7 +71,6 @@
|
|||
|
||||
/* util includes */
|
||||
#include <util/bsdstring.h>
|
||||
#include <functions.h>
|
||||
#include <goodies.h>
|
||||
#include <base36.h>
|
||||
#include <nrmessage.h>
|
||||
|
@ -113,16 +112,6 @@ strxcpy(char * dst, const char * src) {
|
|||
return s;
|
||||
}
|
||||
|
||||
static const char*
|
||||
MailitPath(void)
|
||||
{
|
||||
static const char * value = NULL;
|
||||
if (value==NULL) {
|
||||
value = get_param(global.parameters, "report.mailit");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int
|
||||
read_datenames(const char *filename)
|
||||
{
|
||||
|
@ -531,26 +520,6 @@ report_spell(FILE * F, spellid_t id, const struct locale * lang)
|
|||
rnl(F);
|
||||
}
|
||||
|
||||
void
|
||||
nmr_warnings(void)
|
||||
|
||||
{
|
||||
faction *f,*fa;
|
||||
#define FRIEND (HELP_GUARD|HELP_MONEY)
|
||||
for(f=factions;f;f=f->next) {
|
||||
if(f->no != MONSTER_FACTION && (turn-f->lastorders) >= 2) {
|
||||
for(fa=factions;fa;fa=fa->next) {
|
||||
if (alliedfaction(NULL, f, fa, FRIEND) && alliedfaction(NULL, fa, f, FRIEND)) {
|
||||
sprintf(buf, "Achtung: %s hat einige Zeit keine "
|
||||
"Züge eingeschickt und könnte dadurch in Kürze aus dem "
|
||||
"Spiel ausscheiden.", factionname(f));
|
||||
addmessage(0, fa, buf, MSG_EVENT, ML_WARN);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sparagraph(strlist ** SP, const char *s, int indent, char mark)
|
||||
{
|
||||
|
@ -1448,8 +1417,9 @@ buildingmaintenance(const building * b, const resource_type * rtype)
|
|||
}
|
||||
|
||||
static int
|
||||
order_template(FILE * F, faction * f)
|
||||
report_template(FILE * F, report_context * ctx)
|
||||
{
|
||||
faction * f = ctx->f;
|
||||
region *r;
|
||||
plane *pl;
|
||||
region *last = lastregion(f);
|
||||
|
@ -1923,28 +1893,27 @@ report_building(FILE *F, const region * r, const building * b, const faction * f
|
|||
rpunit(F, f, u, 6, mode);
|
||||
}
|
||||
|
||||
static int
|
||||
report(FILE *F, faction * f, struct seen_region ** seen, const faction_list * addresses,
|
||||
const char * pzTime)
|
||||
int
|
||||
report_plaintext(FILE *F, report_context * ctx)
|
||||
{
|
||||
int flag = 0;
|
||||
char ch;
|
||||
int dh;
|
||||
int anyunits;
|
||||
const struct region *r;
|
||||
region * last = lastregion(f);
|
||||
faction * f = ctx->f;
|
||||
building *b;
|
||||
ship *sh;
|
||||
unit *u;
|
||||
char pzTime[64];
|
||||
attrib *a;
|
||||
message * m;
|
||||
int wants_stats;
|
||||
int ix;
|
||||
unsigned char op;
|
||||
char buf2[80];
|
||||
ix = Pow(O_STATISTICS);
|
||||
wants_stats = (f->options & ix);
|
||||
region * last = lastregion(f);
|
||||
int ix = Pow(O_STATISTICS);
|
||||
int wants_stats = (f->options & ix);
|
||||
|
||||
strftime(pzTime, 64, "%A, %d. %B %Y, %H:%M", localtime(&ctx->report_time));
|
||||
m = msg_message("nr_header_date", "game date", global.gamename, pzTime);
|
||||
nr_render(m, f->locale, buf, sizeof(buf), f);
|
||||
msg_release(m);
|
||||
|
@ -1964,6 +1933,7 @@ report(FILE *F, faction * f, struct seen_region ** seen, const faction_list * ad
|
|||
buf[0] = 0;
|
||||
dh = 0;
|
||||
for (a=a_find(f->attribs, &at_faction_special); a; a=a->nexttype) {
|
||||
char buf2[80];
|
||||
dh++;
|
||||
if(fspecials[a->data.sa[0]].maxlevel != 100) {
|
||||
sprintf(buf2, "%s (%d)", fspecials[a->data.sa[0]].name, a->data.sa[1]);
|
||||
|
@ -2182,7 +2152,7 @@ report(FILE *F, faction * f, struct seen_region ** seen, const faction_list * ad
|
|||
boolean unit_in_region = false;
|
||||
boolean durchgezogen_in_region = false;
|
||||
int turm_sieht_region = false;
|
||||
seen_region * sd = find_seen(seen, r);
|
||||
seen_region * sd = find_seen(ctx->seen, r);
|
||||
if (sd==NULL) continue;
|
||||
|
||||
switch (sd->mode) {
|
||||
|
@ -2345,60 +2315,12 @@ report(FILE *F, faction * f, struct seen_region ** seen, const faction_list * ad
|
|||
rnl(F);
|
||||
rparagraph(F, LOC(f->locale, "nr_youaredead"), 0, 0);
|
||||
} else {
|
||||
list_address(F, f, addresses);
|
||||
list_address(F, f, ctx->addresses);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE *
|
||||
openbatch(void)
|
||||
{
|
||||
faction *f;
|
||||
FILE * BAT = NULL;
|
||||
|
||||
/* falls und mind. ein internet spieler gefunden wird, schreibe den
|
||||
* header des batch files. ab nun kann BAT verwendet werden, um zu
|
||||
* pruefen, ob netspieler vorhanden sind und ins mailit batch
|
||||
* geschrieben werden darf. */
|
||||
|
||||
for (f = factions; f; f = f->next) {
|
||||
|
||||
/* bei "internet:" verschicken wir die mail per batchfile. für
|
||||
* unix kann man alles in EIN batchfile schreiben, als
|
||||
* sogenanntes "herefile". Konnte der batchfile nicht geoeffnet
|
||||
* werden, schreiben wir die reports einzeln. der BAT file wird
|
||||
* nur gemacht, wenn es auch internet benutzer gibt. */
|
||||
|
||||
if (f->email) {
|
||||
sprintf(buf, "%s/mailit", reportpath());
|
||||
if ((BAT = fopen(buf, "w")) == NULL)
|
||||
log_error(("mailit konnte nicht geöffnet werden!\n"));
|
||||
else
|
||||
fprintf(BAT,
|
||||
"#!/bin/sh\n\n"
|
||||
"# MAILIT shell file, vom Eressea Host generiert\n#\n"
|
||||
"# Verwendung: nohup mailit &\n#\n\n"
|
||||
"PATH=%s\n\n"
|
||||
"chmod 755 *.sh\n"
|
||||
"\n", MailitPath());
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
return BAT;
|
||||
}
|
||||
|
||||
void
|
||||
closebatch(FILE * BAT)
|
||||
{
|
||||
if (BAT) {
|
||||
fputs("\n", BAT);
|
||||
fclose(BAT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
base36conversion(void)
|
||||
{
|
||||
|
@ -2415,249 +2337,6 @@ base36conversion(void)
|
|||
}
|
||||
}
|
||||
|
||||
extern void init_intervals(void);
|
||||
|
||||
static void
|
||||
view_default(struct seen_region ** seen, region *r, faction *f)
|
||||
{
|
||||
direction_t dir;
|
||||
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
||||
region * r2 = rconnect(r, dir);
|
||||
if (r2) {
|
||||
border * b = get_borders(r, r2);
|
||||
while (b) {
|
||||
if (!b->type->transparent(b, f)) break;
|
||||
b = b->next;
|
||||
}
|
||||
if (!b) add_seen(seen, r2, see_neighbour, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
view_neighbours(struct seen_region ** seen, region * r, faction * f)
|
||||
{
|
||||
direction_t dir;
|
||||
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
||||
region * r2 = rconnect(r, dir);
|
||||
if (r2) {
|
||||
border * b = get_borders(r, r2);
|
||||
while (b) {
|
||||
if (!b->type->transparent(b, f)) break;
|
||||
b = b->next;
|
||||
}
|
||||
if (!b) {
|
||||
if (add_seen(seen, r2, see_far, false)) {
|
||||
if (!(fval(r2->terrain, FORBIDDEN_REGION))) {
|
||||
direction_t dir;
|
||||
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
||||
region * r3 = rconnect(r2, dir);
|
||||
if (r3) {
|
||||
border * b = get_borders(r2, r3);
|
||||
while (b) {
|
||||
if (!b->type->transparent(b, f)) break;
|
||||
b = b->next;
|
||||
}
|
||||
if (!b) add_seen(seen, r3, see_neighbour, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recurse_regatta(struct seen_region ** seen, region *center, region *r, faction *f, int maxdist)
|
||||
{
|
||||
direction_t dir;
|
||||
int dist = distance(center, r);
|
||||
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
||||
region * r2 = rconnect(r, dir);
|
||||
if (r2) {
|
||||
int ndist = distance(center, r2);
|
||||
if (ndist>dist && fval(r2->terrain, SEA_REGION)) {
|
||||
border * b = get_borders(r, r2);
|
||||
while (b) {
|
||||
if (!b->type->transparent(b, f)) break;
|
||||
b = b->next;
|
||||
}
|
||||
if (!b) {
|
||||
if (ndist<maxdist) {
|
||||
if (add_seen(seen, r2, see_far, false)) {
|
||||
recurse_regatta(seen, center, r2, f, maxdist);
|
||||
}
|
||||
} else add_seen(seen, r2, see_neighbour, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
view_regatta(struct seen_region ** seen, region * r, faction * f)
|
||||
{
|
||||
unit *u;
|
||||
int skill = 0;
|
||||
for (u=r->units; u; u=u->next) {
|
||||
if (u->faction==f) {
|
||||
int es = effskill(u, SK_OBSERVATION);
|
||||
if (es>skill) skill=es;
|
||||
}
|
||||
}
|
||||
recurse_regatta(seen, r, r, f, skill/2);
|
||||
}
|
||||
|
||||
static void
|
||||
global_report(const char * filename)
|
||||
{
|
||||
FILE * F = fopen(filename, "w");
|
||||
region * r;
|
||||
faction * f;
|
||||
faction * monsters = findfaction(MONSTER_FACTION);
|
||||
faction_list * addresses = NULL;
|
||||
struct seen_region ** seen;
|
||||
|
||||
if (!monsters) return;
|
||||
if (!F) return;
|
||||
|
||||
/* list of all addresses */
|
||||
for (f=factions;f;f=f->next) {
|
||||
faction_list * flist = calloc(1, sizeof(faction_list));
|
||||
flist->data = f;
|
||||
flist->next = addresses;
|
||||
addresses = flist;
|
||||
}
|
||||
|
||||
seen = seen_init();
|
||||
for (r = regions; r; r = r->next) {
|
||||
add_seen(seen, r, see_unit, true);
|
||||
}
|
||||
report_computer(F, monsters, seen, addresses, time(NULL));
|
||||
freelist(addresses);
|
||||
seen_done(seen);
|
||||
fclose(F);
|
||||
}
|
||||
|
||||
region_list *
|
||||
get_regions_distance(region * root, int radius)
|
||||
{
|
||||
region_list * rptr, * rlist = NULL;
|
||||
region_list ** rp = &rlist;
|
||||
add_regionlist(rp, root);
|
||||
fset(root, FL_MARK);
|
||||
while (*rp) {
|
||||
region_list * r = *rp;
|
||||
direction_t d;
|
||||
rp = &r->next;
|
||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
||||
region * rn = rconnect(r->data, d);
|
||||
if (rn!=NULL && !fval(rn, FL_MARK) && distance(rn, root)<=radius) {
|
||||
add_regionlist(rp, rn);
|
||||
fset(rn, FL_MARK);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (rptr=rlist;rptr;rptr=rptr->next) {
|
||||
freset(rptr->data, FL_MARK);
|
||||
}
|
||||
return rlist;
|
||||
}
|
||||
|
||||
static struct seen_region **
|
||||
prepare_report(faction * f)
|
||||
{
|
||||
region * r;
|
||||
region * end = lastregion(f);
|
||||
struct seen_region ** seen = seen_init();
|
||||
|
||||
static const struct building_type * bt_lighthouse = NULL;
|
||||
if (bt_lighthouse==NULL) bt_lighthouse = bt_find("lighthouse");
|
||||
|
||||
for (r = firstregion(f); r != end; r = r->next) {
|
||||
attrib *ru;
|
||||
unit * u;
|
||||
plane * p = rplane(r);
|
||||
unsigned char mode = see_none;
|
||||
boolean dis = false;
|
||||
int light = 0;
|
||||
|
||||
if (p) {
|
||||
watcher * w = p->watchers;
|
||||
while (w) {
|
||||
if (f==w->faction) {
|
||||
mode = w->mode;
|
||||
break;
|
||||
}
|
||||
w = w->next;
|
||||
}
|
||||
}
|
||||
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->faction == f) {
|
||||
if (u->building && u->building->type==bt_lighthouse) {
|
||||
int r = lighthouse_range(u->building, f);
|
||||
if (r>light) light = r;
|
||||
}
|
||||
if (u->race != new_race[RC_SPELL] || u->number == RS_FARVISION) {
|
||||
mode = see_unit;
|
||||
if (fval(u, UFL_DISBELIEVES)) {
|
||||
dis = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (light) {
|
||||
/* we are in a lighthouse. add the others! */
|
||||
region_list * rlist = get_regions_distance(r, light);
|
||||
region_list * rp = rlist;
|
||||
while (rp) {
|
||||
region * rl = rp->data;
|
||||
if (fval(rl->terrain, SEA_REGION)) {
|
||||
direction_t d;
|
||||
add_seen(seen, rl, see_lighthouse, false);
|
||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
||||
region * rn = rconnect(rl, d);
|
||||
if (rn!=NULL) {
|
||||
add_seen(seen, rn, see_neighbour, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
rp = rp->next;
|
||||
}
|
||||
free_regionlist(rlist);
|
||||
}
|
||||
|
||||
if (mode<see_travel && fval(r, RF_TRAVELUNIT)) {
|
||||
for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) {
|
||||
unit * u = (unit*)ru->data.v;
|
||||
if (u->faction == f) {
|
||||
mode = see_travel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == see_none)
|
||||
continue;
|
||||
|
||||
add_seen(seen, r, mode, dis);
|
||||
/* nicht, wenn Verwirrung herrscht: */
|
||||
if (!is_cursed(r->attribs, C_REGCONF, 0)) {
|
||||
void (*view)(struct seen_region **, region * r, faction * f) = view_default;
|
||||
if (p && fval(p, PFL_SEESPECIAL)) {
|
||||
attrib * a = a_find(p->attribs, &at_viewrange);
|
||||
if (a) view = (void (*)(struct seen_region **, region * r, faction * f))a->data.f;
|
||||
}
|
||||
view(seen, r, f);
|
||||
}
|
||||
}
|
||||
return seen;
|
||||
}
|
||||
|
||||
#define FMAXHASH 1021
|
||||
|
||||
struct fsee {
|
||||
|
@ -2676,81 +2355,6 @@ struct fsee {
|
|||
#define REPORT_ZIP (1 << O_COMPRESS)
|
||||
#define REPORT_BZIP2 (1 << O_BZIP2)
|
||||
|
||||
int
|
||||
write_reports(faction * f, time_t ltime)
|
||||
{
|
||||
FILE * F;
|
||||
boolean gotit = false;
|
||||
faction_list * addresses;
|
||||
char zTime[64];
|
||||
struct seen_region ** seen = prepare_report(f);
|
||||
|
||||
strftime(zTime, sizeof(zTime), "%A, %d. %B %Y, %H:%M", localtime(<ime));
|
||||
printf("Reports for %s: \r", factionname(f));
|
||||
fflush(stdout);
|
||||
addresses = get_addresses(f, seen);
|
||||
|
||||
/* NR schreiben: */
|
||||
if (!nonr && (f->options & REPORT_NR)) {
|
||||
fprintf(stdout, "Reports for %s: NR\r", factionname(f));
|
||||
fflush(stdout);
|
||||
|
||||
sprintf(buf, "%s/%d-%s.nr", reportpath(), turn, factionid(f));
|
||||
F = cfopen(buf, "wt");
|
||||
if (F) {
|
||||
int status = report(F, f, seen, addresses, zTime);
|
||||
fclose(F);
|
||||
gotit = true;
|
||||
if (status!=0) {
|
||||
seen_done(seen);
|
||||
return status; /* catch errors */
|
||||
}
|
||||
}
|
||||
}
|
||||
/* CR schreiben: */
|
||||
if (!nocr && (f->options & REPORT_CR || f->age<3)) {
|
||||
fprintf(stdout, "Reports for %s: CR\r", factionname(f));
|
||||
fflush(stdout);
|
||||
|
||||
sprintf(buf, "%s/%d-%s.cr", reportpath(), turn, factionid(f));
|
||||
F = cfopen(buf, "wt");
|
||||
if (F) {
|
||||
int status = report_computer(F, f, seen, addresses, ltime);
|
||||
fclose(F);
|
||||
gotit = true;
|
||||
if (status!=0) {
|
||||
seen_done(seen);
|
||||
return status; /* catch errors */
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ZV schreiben: */
|
||||
if (f->options & REPORT_ZV) {
|
||||
fprintf(stdout, "Reports for %s: ZV\r", factionname(f));
|
||||
fflush(stdout);
|
||||
|
||||
sprintf(buf, "%s/%d-%s.txt", reportpath(), turn, factionid(f));
|
||||
F = cfopen(buf, "wt");
|
||||
if (F) {
|
||||
int status = order_template(F, f);
|
||||
fclose(F);
|
||||
if (status!=0) {
|
||||
seen_done(seen);
|
||||
return status; /* catch errors */
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(stdout, "Reports for %s: DONE\n", factionname(f));
|
||||
|
||||
if (!gotit) {
|
||||
log_warning(("No report for faction %s!\n", factionid(f)));
|
||||
}
|
||||
freelist(addresses);
|
||||
|
||||
seen_done(seen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
init_reports(void)
|
||||
{
|
||||
|
@ -2771,136 +2375,6 @@ init_reports(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
reports(void)
|
||||
{
|
||||
faction *f;
|
||||
FILE *shfp, *BAT;
|
||||
time_t ltime = time(NULL);
|
||||
const char * str;
|
||||
int retval = 0;
|
||||
|
||||
nmr_warnings();
|
||||
report_donations();
|
||||
remove_empty_units();
|
||||
|
||||
BAT = openbatch();
|
||||
for (f = factions; f; f = f->next) {
|
||||
int error = write_reports(f, ltime);
|
||||
if (error) retval = error;
|
||||
if (!nosh && f->email && strlen(f->email) && BAT) {
|
||||
sprintf(buf, "%s/%s.sh", reportpath(), factionid(f));
|
||||
shfp = fopen(buf, "w");
|
||||
fprintf(shfp,"#!/bin/sh\n\nPATH=%s\n\n",MailitPath());
|
||||
fprintf(shfp,"if [ $# -ge 1 ]; then\n");
|
||||
fprintf(shfp,"\taddr=$1\n");
|
||||
fprintf(shfp,"else\n");
|
||||
fprintf(shfp,"\taddr=%s\n", f->email);
|
||||
fprintf(shfp,"fi\n\n");
|
||||
|
||||
fprintf(BAT, "\n\ndate;echo %s\n", f->email);
|
||||
|
||||
if (f->options & REPORT_ZIP) {
|
||||
|
||||
fprintf(BAT, "ls %d-%s.nr %d-%s.txt %d-%s.cr | zip -m -j -9 -@ %d-%s.zip\n",
|
||||
turn, factionid(f),
|
||||
turn, factionid(f),
|
||||
turn, factionid(f),
|
||||
turn, factionid(f));
|
||||
if (f->age == 1) {
|
||||
fprintf(BAT, "zip -j -9 %d-%s.zip %s/%s/%s/welcome.txt\n",
|
||||
turn, factionid(f), resourcepath(), global.welcomepath, locale_name(f->locale));
|
||||
}
|
||||
|
||||
fprintf(shfp, "eresseamail.zipped $addr \"%s %s\" \"%d-%s.zip\" "
|
||||
"%d-%s.zip\n", global.gamename, gamedate_short(f->locale),
|
||||
turn, factionid(f),
|
||||
turn, factionid(f));
|
||||
|
||||
} else if(f->options & REPORT_BZIP2) {
|
||||
|
||||
fprintf(BAT, "bzip2 -9v `ls %d-%s.nr %d-%s.txt %d-%s.cr`\n",
|
||||
turn, factionid(f),
|
||||
turn, factionid(f),
|
||||
turn, factionid(f));
|
||||
|
||||
fprintf(shfp, "eresseamail.bzip2 $addr \"%s %s\"", global.gamename, gamedate_short(f->locale));
|
||||
|
||||
if (!nonr && f->options & REPORT_NR)
|
||||
fprintf(shfp,
|
||||
" \\\n\t\"application/x-bzip2\" \"Report\" %d-%s.nr.bz2",
|
||||
turn,factionid(f));
|
||||
|
||||
if (f->options & (1 << O_ZUGVORLAGE))
|
||||
fprintf(shfp,
|
||||
" \\\n\t\"application/x-bzip2\" \"Zugvorlage\" %d-%s.txt.bz2",
|
||||
turn,factionid(f));
|
||||
|
||||
if (!nocr && (f->options & REPORT_CR || f->age<3))
|
||||
fprintf(shfp,
|
||||
" \\\n\t\"application/x-bzip2\" \"Computer-Report\" %d-%s.cr.bz2",
|
||||
turn, factionid(f));
|
||||
|
||||
if (f->age == 1) {
|
||||
fprintf(shfp,
|
||||
" \\\n\t\"text/plain\" \"Willkommen\" %s/%s/%s/welcome.txt",
|
||||
resourcepath(), global.welcomepath, locale_name(f->locale));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
fprintf(shfp, MAIL " $addr \"%s %s\"", global.gamename, gamedate_short(f->locale));
|
||||
|
||||
if (!nonr && f->options & REPORT_NR)
|
||||
fprintf(shfp,
|
||||
" \\\n\t\"text/plain\" \"Report\" %d-%s.nr",
|
||||
turn, factionid(f));
|
||||
|
||||
if (f->options & (1 << O_ZUGVORLAGE))
|
||||
fprintf(shfp,
|
||||
" \\\n\t\"text/plain\" \"Zugvorlage\" %d-%s.txt",
|
||||
turn, factionid(f));
|
||||
|
||||
if (!nocr && (f->options & REPORT_CR || f->age<3))
|
||||
fprintf(shfp,
|
||||
" \\\n\t\"text/x-eressea-cr\" \"Computer-Report\" %d-%s.cr",
|
||||
turn, factionid(f));
|
||||
|
||||
if (f->age == 1) {
|
||||
fprintf(shfp,
|
||||
" \\\n\t\"text/plain\" \"Willkommen\" %s/%s/%s/welcome.txt",
|
||||
resourcepath(), global.welcomepath, locale_name(f->locale));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fprintf(BAT, ". %s.sh %s\n", factionid(f), f->email);
|
||||
fclose(shfp);
|
||||
}
|
||||
}
|
||||
str = get_param(global.parameters, "globalreport");
|
||||
if (str!=NULL) {
|
||||
sprintf(buf, "%s/%s.%u.cr", reportpath(), str, turn);
|
||||
global_report(buf);
|
||||
}
|
||||
/* schliesst BAT und verschickt Zeitungen und Kommentare */
|
||||
closebatch(BAT);
|
||||
free_seen();
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
report_cleanup(void)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i!=FMAXHASH;++i) {
|
||||
while (fsee[i]) {
|
||||
struct fsee * fs = fsee[i]->nexthash;
|
||||
free(fsee[i]);
|
||||
fsee[i] = fs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unit *
|
||||
can_find(faction * f, faction * f2)
|
||||
|
@ -3737,35 +3211,10 @@ eval_int36(struct opstack ** stack, const void * userdata)
|
|||
unused(userdata);
|
||||
}
|
||||
|
||||
static variant
|
||||
var_copy_string(variant x)
|
||||
{
|
||||
x.v = strdup((const char*)x.v);
|
||||
return x;
|
||||
}
|
||||
|
||||
static void
|
||||
var_free_string(variant x)
|
||||
{
|
||||
free(x.v);
|
||||
}
|
||||
|
||||
static variant
|
||||
var_copy_order(variant x)
|
||||
{
|
||||
x.v = copy_order((order*)x.v);
|
||||
return x;
|
||||
}
|
||||
|
||||
static void
|
||||
var_free_order(variant x)
|
||||
{
|
||||
free_order(x.v);
|
||||
}
|
||||
|
||||
void
|
||||
report_init(void)
|
||||
{
|
||||
/* register functions that turn message contents to readable strings */
|
||||
add_function("alliance", &eval_alliance);
|
||||
add_function("region", &eval_region);
|
||||
add_function("weight", &eval_weight);
|
||||
|
@ -3784,21 +3233,20 @@ report_init(void)
|
|||
add_function("trail", &eval_trail);
|
||||
add_function("spell", &eval_spell);
|
||||
|
||||
register_argtype("alliance", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("building", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("direction", NULL, NULL, VAR_INT);
|
||||
register_argtype("faction", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("race", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("region", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("resource", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("ship", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("skill", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("spell", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("unit", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("int", NULL, NULL, VAR_INT);
|
||||
register_argtype("string", var_free_string, var_copy_string, VAR_VOIDPTR);
|
||||
register_argtype("order", var_free_order, var_copy_order, VAR_VOIDPTR);
|
||||
|
||||
register_function((pf_generic)view_neighbours, "view_neighbours");
|
||||
register_function((pf_generic)view_regatta, "view_regatta");
|
||||
register_reporttype("nr", &report_plaintext, 1<<O_REPORT);
|
||||
register_reporttype("txt", &report_template, 1<<O_ZUGVORLAGE);
|
||||
}
|
||||
|
||||
void
|
||||
report_cleanup(void)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i!=FMAXHASH;++i) {
|
||||
while (fsee[i]) {
|
||||
struct fsee * fs = fsee[i]->nexthash;
|
||||
free(fsee[i]);
|
||||
fsee[i] = fs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
25
src/common/gamecode/report.h
Normal file
25
src/common/gamecode/report.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* vi: set ts=2:
|
||||
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
| | Enno Rehling <enno@eressea-pbem.de>
|
||||
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
||||
| (c) 1998 - 2003 | Henning Peters <faroul@beyond.kn-bremen.de>
|
||||
| | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
|
||||
+-------------------+ Stefan Reich <reich@halbling.de>
|
||||
|
||||
This program may not be used, modified or distributed
|
||||
without prior permission by the authors of Eressea.
|
||||
*/
|
||||
#ifndef H_GC_REPORT
|
||||
#define H_GC_REPORT
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void report_init(void);
|
||||
extern void report_cleanup(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -22,39 +22,44 @@
|
|||
#include "reports.h"
|
||||
|
||||
/* kernel includes */
|
||||
#include "building.h"
|
||||
#include "faction.h"
|
||||
#include "group.h"
|
||||
#include "item.h"
|
||||
#include "karma.h"
|
||||
#include "magic.h"
|
||||
#include "message.h"
|
||||
#include "order.h"
|
||||
#include "plane.h"
|
||||
#include "race.h"
|
||||
#include "region.h"
|
||||
#include "ship.h"
|
||||
#include "skill.h"
|
||||
#include "unit.h"
|
||||
#include <kernel/building.h>
|
||||
#include <kernel/border.h>
|
||||
#include <kernel/terrain.h>
|
||||
#include <kernel/faction.h>
|
||||
#include <kernel/group.h>
|
||||
#include <kernel/item.h>
|
||||
#include <kernel/karma.h>
|
||||
#include <kernel/magic.h>
|
||||
#include <kernel/message.h>
|
||||
#include <kernel/order.h>
|
||||
#include <kernel/plane.h>
|
||||
#include <kernel/race.h>
|
||||
#include <kernel/region.h>
|
||||
#include <kernel/ship.h>
|
||||
#include <kernel/skill.h>
|
||||
#include <kernel/unit.h>
|
||||
#ifdef USE_UGROUPS
|
||||
# include "ugroup.h"
|
||||
# include <kernel/ugroup.h>
|
||||
# include <attributes/ugroup.h>
|
||||
#endif
|
||||
|
||||
/* util includes */
|
||||
#include <util/bsdstring.h>
|
||||
#include <util/base36.h>
|
||||
#include <util/functions.h>
|
||||
#include <util/goodies.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
/* attributes includes */
|
||||
#include <attributes/follow.h>
|
||||
#include <attributes/otherfaction.h>
|
||||
#include <attributes/racename.h>
|
||||
#include <attributes/viewrange.h>
|
||||
|
||||
const char * g_reportdir;
|
||||
|
||||
|
@ -1250,3 +1255,469 @@ add_seen(struct seen_region * seehash[], struct region * r, unsigned char mode,
|
|||
return true;
|
||||
}
|
||||
|
||||
typedef struct report_type {
|
||||
struct report_type * next;
|
||||
report_fun write;
|
||||
const char * extension;
|
||||
int flag;
|
||||
} report_type;
|
||||
|
||||
static report_type * report_types;
|
||||
|
||||
void
|
||||
register_reporttype(const char * extension, report_fun write, int flag)
|
||||
{
|
||||
report_type * type = malloc(sizeof(report_type));
|
||||
type->extension = extension;
|
||||
type->write = write;
|
||||
type->flag = flag;
|
||||
type->next = report_types;
|
||||
report_types = type;
|
||||
}
|
||||
|
||||
static region_list *
|
||||
get_regions_distance(region * root, int radius)
|
||||
{
|
||||
region_list * rptr, * rlist = NULL;
|
||||
region_list ** rp = &rlist;
|
||||
add_regionlist(rp, root);
|
||||
fset(root, FL_MARK);
|
||||
while (*rp) {
|
||||
region_list * r = *rp;
|
||||
direction_t d;
|
||||
rp = &r->next;
|
||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
||||
region * rn = rconnect(r->data, d);
|
||||
if (rn!=NULL && !fval(rn, FL_MARK) && distance(rn, root)<=radius) {
|
||||
add_regionlist(rp, rn);
|
||||
fset(rn, FL_MARK);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (rptr=rlist;rptr;rptr=rptr->next) {
|
||||
freset(rptr->data, FL_MARK);
|
||||
}
|
||||
return rlist;
|
||||
}
|
||||
|
||||
static void
|
||||
view_default(struct seen_region ** seen, region *r, faction *f)
|
||||
{
|
||||
direction_t dir;
|
||||
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
||||
region * r2 = rconnect(r, dir);
|
||||
if (r2) {
|
||||
border * b = get_borders(r, r2);
|
||||
while (b) {
|
||||
if (!b->type->transparent(b, f)) break;
|
||||
b = b->next;
|
||||
}
|
||||
if (!b) add_seen(seen, r2, see_neighbour, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
view_neighbours(struct seen_region ** seen, region * r, faction * f)
|
||||
{
|
||||
direction_t dir;
|
||||
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
||||
region * r2 = rconnect(r, dir);
|
||||
if (r2) {
|
||||
border * b = get_borders(r, r2);
|
||||
while (b) {
|
||||
if (!b->type->transparent(b, f)) break;
|
||||
b = b->next;
|
||||
}
|
||||
if (!b) {
|
||||
if (add_seen(seen, r2, see_far, false)) {
|
||||
if (!(fval(r2->terrain, FORBIDDEN_REGION))) {
|
||||
direction_t dir;
|
||||
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
||||
region * r3 = rconnect(r2, dir);
|
||||
if (r3) {
|
||||
border * b = get_borders(r2, r3);
|
||||
while (b) {
|
||||
if (!b->type->transparent(b, f)) break;
|
||||
b = b->next;
|
||||
}
|
||||
if (!b) add_seen(seen, r3, see_neighbour, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recurse_regatta(struct seen_region ** seen, region *center, region *r, faction *f, int maxdist)
|
||||
{
|
||||
direction_t dir;
|
||||
int dist = distance(center, r);
|
||||
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
||||
region * r2 = rconnect(r, dir);
|
||||
if (r2) {
|
||||
int ndist = distance(center, r2);
|
||||
if (ndist>dist && fval(r2->terrain, SEA_REGION)) {
|
||||
border * b = get_borders(r, r2);
|
||||
while (b) {
|
||||
if (!b->type->transparent(b, f)) break;
|
||||
b = b->next;
|
||||
}
|
||||
if (!b) {
|
||||
if (ndist<maxdist) {
|
||||
if (add_seen(seen, r2, see_far, false)) {
|
||||
recurse_regatta(seen, center, r2, f, maxdist);
|
||||
}
|
||||
} else add_seen(seen, r2, see_neighbour, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
view_regatta(struct seen_region ** seen, region * r, faction * f)
|
||||
{
|
||||
unit *u;
|
||||
int skill = 0;
|
||||
for (u=r->units; u; u=u->next) {
|
||||
if (u->faction==f) {
|
||||
int es = effskill(u, SK_OBSERVATION);
|
||||
if (es>skill) skill=es;
|
||||
}
|
||||
}
|
||||
recurse_regatta(seen, r, r, f, skill/2);
|
||||
}
|
||||
|
||||
static struct seen_region **
|
||||
prepare_report(faction * f)
|
||||
{
|
||||
region * r;
|
||||
region * end = lastregion(f);
|
||||
struct seen_region ** seen = seen_init();
|
||||
|
||||
static const struct building_type * bt_lighthouse = NULL;
|
||||
if (bt_lighthouse==NULL) bt_lighthouse = bt_find("lighthouse");
|
||||
|
||||
for (r = firstregion(f); r != end; r = r->next) {
|
||||
attrib *ru;
|
||||
unit * u;
|
||||
plane * p = rplane(r);
|
||||
unsigned char mode = see_none;
|
||||
boolean dis = false;
|
||||
int light = 0;
|
||||
|
||||
if (p) {
|
||||
watcher * w = p->watchers;
|
||||
while (w) {
|
||||
if (f==w->faction) {
|
||||
mode = w->mode;
|
||||
break;
|
||||
}
|
||||
w = w->next;
|
||||
}
|
||||
}
|
||||
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->faction == f) {
|
||||
if (u->building && u->building->type==bt_lighthouse) {
|
||||
int r = lighthouse_range(u->building, f);
|
||||
if (r>light) light = r;
|
||||
}
|
||||
if (u->race != new_race[RC_SPELL] || u->number == RS_FARVISION) {
|
||||
mode = see_unit;
|
||||
if (fval(u, UFL_DISBELIEVES)) {
|
||||
dis = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (light) {
|
||||
/* we are in a lighthouse. add the others! */
|
||||
region_list * rlist = get_regions_distance(r, light);
|
||||
region_list * rp = rlist;
|
||||
while (rp) {
|
||||
region * rl = rp->data;
|
||||
if (fval(rl->terrain, SEA_REGION)) {
|
||||
direction_t d;
|
||||
add_seen(seen, rl, see_lighthouse, false);
|
||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
||||
region * rn = rconnect(rl, d);
|
||||
if (rn!=NULL) {
|
||||
add_seen(seen, rn, see_neighbour, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
rp = rp->next;
|
||||
}
|
||||
free_regionlist(rlist);
|
||||
}
|
||||
|
||||
if (mode<see_travel && fval(r, RF_TRAVELUNIT)) {
|
||||
for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) {
|
||||
unit * u = (unit*)ru->data.v;
|
||||
if (u->faction == f) {
|
||||
mode = see_travel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == see_none)
|
||||
continue;
|
||||
|
||||
add_seen(seen, r, mode, dis);
|
||||
/* nicht, wenn Verwirrung herrscht: */
|
||||
if (!is_cursed(r->attribs, C_REGCONF, 0)) {
|
||||
void (*view)(struct seen_region **, region * r, faction * f) = view_default;
|
||||
if (p && fval(p, PFL_SEESPECIAL)) {
|
||||
attrib * a = a_find(p->attribs, &at_viewrange);
|
||||
if (a) view = (void (*)(struct seen_region **, region * r, faction * f))a->data.f;
|
||||
}
|
||||
view(seen, r, f);
|
||||
}
|
||||
}
|
||||
return seen;
|
||||
}
|
||||
|
||||
int
|
||||
write_reports(faction * f, time_t ltime)
|
||||
{
|
||||
boolean gotit = false;
|
||||
struct seen_region ** seen = prepare_report(f);
|
||||
faction_list * addresses = get_addresses(f, seen);
|
||||
report_type * rtype = report_types;
|
||||
struct report_context ctx;
|
||||
|
||||
ctx.f = f;
|
||||
ctx.addresses = addresses;
|
||||
ctx.report_time = time(NULL);
|
||||
ctx.seen = seen;
|
||||
ctx.userdata = NULL;
|
||||
|
||||
printf("Reports für %s: ", factionname(f));
|
||||
fflush(stdout);
|
||||
|
||||
for (;rtype!=NULL;rtype=rtype->next) {
|
||||
if (f->options & rtype->flag) {
|
||||
FILE * F;
|
||||
sprintf(buf, "%s/%d-%s.%s", reportpath(), turn, factionid(f), rtype->extension);
|
||||
F = fopen(buf, "wt");
|
||||
if (F!=NULL) {
|
||||
rtype->write(F, &ctx);
|
||||
fclose(F);
|
||||
gotit = true;
|
||||
} else {
|
||||
perror(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("Reports for %s: DONE\n", factionname(f));
|
||||
if (!gotit) {
|
||||
log_warning(("No report for faction %s!\n", factionid(f)));
|
||||
}
|
||||
|
||||
freelist(addresses);
|
||||
seen_done(seen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nmr_warnings(void)
|
||||
{
|
||||
faction *f,*fa;
|
||||
#define FRIEND (HELP_GUARD|HELP_MONEY)
|
||||
for (f=factions;f;f=f->next) {
|
||||
if (f->no != MONSTER_FACTION && (turn-f->lastorders) >= 2) {
|
||||
message * msg = NULL;
|
||||
for (fa=factions;fa;fa=fa->next) {
|
||||
if (alliedfaction(NULL, f, fa, FRIEND) && alliedfaction(NULL, fa, f, FRIEND)) {
|
||||
if (msg==NULL) {
|
||||
sprintf(buf, "Achtung: %s hat einige Zeit keine "
|
||||
"Züge eingeschickt und könnte dadurch in Kürze aus dem "
|
||||
"Spiel ausscheiden.", factionname(f));
|
||||
msg = msg_message("msg_event", "string", buf);
|
||||
}
|
||||
add_message(&fa->msgs, msg);
|
||||
}
|
||||
}
|
||||
if (msg!=NULL) msg_release(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
report_donations(void)
|
||||
{
|
||||
region * r;
|
||||
for (r=regions;r;r=r->next) {
|
||||
while (r->donations) {
|
||||
donation * sp = r->donations;
|
||||
if (sp->amount > 0) {
|
||||
struct message * msg = msg_message("donation",
|
||||
"from to amount", sp->f1, sp->f2, sp->amount);
|
||||
r_addmessage(r, sp->f1, msg);
|
||||
r_addmessage(r, sp->f2, msg);
|
||||
msg_release(msg);
|
||||
}
|
||||
r->donations = sp->next;
|
||||
free(sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char*
|
||||
MailitPath(void)
|
||||
{
|
||||
static const char * value = NULL;
|
||||
if (value==NULL) {
|
||||
value = get_param(global.parameters, "report.mailit");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static void
|
||||
write_script(FILE * F, const faction * f)
|
||||
{
|
||||
report_type * rtype;
|
||||
|
||||
fprintf(F, "faction=%s:email=%s", factionid(f), f->email);
|
||||
if (f->options & (1<<O_BZIP2)) fputs(":compression=bz2", F);
|
||||
else fputs(":compression=zip", F);
|
||||
|
||||
fputs(":reports=", F);
|
||||
buf[0] = 0;
|
||||
for (rtype=report_types;rtype!=NULL;rtype=rtype->next) {
|
||||
if (f->options&rtype->flag) {
|
||||
if (buf[0]) strcat(buf, ",");
|
||||
strcat(buf, rtype->extension);
|
||||
}
|
||||
}
|
||||
fputs(buf, F);
|
||||
fputc('\n', F);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
global_report(const char * filename)
|
||||
{
|
||||
FILE * F = fopen(filename, "w");
|
||||
region * r;
|
||||
faction * f;
|
||||
faction * monsters = findfaction(MONSTER_FACTION);
|
||||
faction_list * addresses = NULL;
|
||||
struct seen_region ** seen;
|
||||
|
||||
if (!monsters) return;
|
||||
if (!F) return;
|
||||
|
||||
/* list of all addresses */
|
||||
for (f=factions;f;f=f->next) {
|
||||
faction_list * flist = calloc(1, sizeof(faction_list));
|
||||
flist->data = f;
|
||||
flist->next = addresses;
|
||||
addresses = flist;
|
||||
}
|
||||
|
||||
seen = seen_init();
|
||||
for (r = regions; r; r = r->next) {
|
||||
add_seen(seen, r, see_unit, true);
|
||||
}
|
||||
report_computer(F, monsters, seen, addresses, time(NULL));
|
||||
freelist(addresses);
|
||||
seen_done(seen);
|
||||
fclose(F);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
reports(void)
|
||||
{
|
||||
faction *f;
|
||||
FILE *mailit;
|
||||
time_t ltime = time(NULL);
|
||||
const char * str;
|
||||
int retval = 0;
|
||||
|
||||
nmr_warnings();
|
||||
report_donations();
|
||||
remove_empty_units();
|
||||
|
||||
sprintf(buf, "%s/reports.txt", reportpath());
|
||||
mailit = fopen(buf, "w");
|
||||
if (mailit == NULL) {
|
||||
log_error(("%s konnte nicht geöffnet werden!\n", buf));
|
||||
}
|
||||
|
||||
for (f = factions; f; f = f->next) {
|
||||
int error = write_reports(f, ltime);
|
||||
if (error) retval = error;
|
||||
if (mailit) write_script(mailit, f);
|
||||
}
|
||||
if (mailit) fclose(mailit);
|
||||
free_seen();
|
||||
str = get_param(global.parameters, "globalreport");
|
||||
#if 0
|
||||
if (str!=NULL) {
|
||||
sprintf(buf, "%s/%s.%u.cr", reportpath(), str, turn);
|
||||
global_report(buf);
|
||||
}
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
static variant
|
||||
var_copy_string(variant x)
|
||||
{
|
||||
x.v = strdup((const char*)x.v);
|
||||
return x;
|
||||
}
|
||||
|
||||
static void
|
||||
var_free_string(variant x)
|
||||
{
|
||||
free(x.v);
|
||||
}
|
||||
|
||||
static variant
|
||||
var_copy_order(variant x)
|
||||
{
|
||||
x.v = copy_order((order*)x.v);
|
||||
return x;
|
||||
}
|
||||
|
||||
static void
|
||||
var_free_order(variant x)
|
||||
{
|
||||
free_order(x.v);
|
||||
}
|
||||
|
||||
void
|
||||
reports_init(void)
|
||||
{
|
||||
/* register datatypes for the different message objects */
|
||||
register_argtype("alliance", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("building", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("direction", NULL, NULL, VAR_INT);
|
||||
register_argtype("faction", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("race", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("region", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("resource", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("ship", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("skill", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("spell", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("unit", NULL, NULL, VAR_VOIDPTR);
|
||||
register_argtype("int", NULL, NULL, VAR_INT);
|
||||
register_argtype("string", var_free_string, var_copy_string, VAR_VOIDPTR);
|
||||
register_argtype("order", var_free_order, var_copy_order, VAR_VOIDPTR);
|
||||
|
||||
/* register alternative visibility functions */
|
||||
register_function((pf_generic)view_neighbours, "view_neighbours");
|
||||
register_function((pf_generic)view_regatta, "view_regatta");
|
||||
}
|
|
@ -86,6 +86,17 @@ extern void seen_done(struct seen_region * seehash[]);
|
|||
extern void free_seen(void);
|
||||
extern void get_seen_interval(struct seen_region ** seen, struct region ** first, struct region ** last);
|
||||
|
||||
typedef struct report_context {
|
||||
struct faction * f;
|
||||
struct faction_list * addresses;
|
||||
struct seen_region ** seen;
|
||||
time_t report_time;
|
||||
void * userdata;
|
||||
} report_context;
|
||||
|
||||
typedef void (*report_fun)(FILE * F, report_context * ctx);
|
||||
extern void register_reporttype(const char * extension, report_fun write, int flag);
|
||||
|
||||
extern void report_item(const struct unit * owner, const struct item * i, const struct faction * viewer, const char ** name, const char ** basename, int * number, boolean singular);
|
||||
extern void report_building(FILE *F, const struct region * r, const struct building * b, const struct faction * f, int mode);
|
||||
extern int bufunit(const struct faction * f, const struct unit * u, int indent, int mode);
|
||||
|
@ -97,6 +108,8 @@ extern const char * reportpath(void);
|
|||
extern struct faction_list * get_addresses(struct faction * f, struct seen_region * seehash[]);
|
||||
extern const char * trailinto(const struct region * r, const struct locale * lang);
|
||||
|
||||
extern void reports_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
|
||||
/* gamecode includes */
|
||||
#include <gamecode/creport.h>
|
||||
#include <gamecode/report.h>
|
||||
#include <gamecode/economy.h>
|
||||
#include <gamecode/items.h>
|
||||
#include <gamecode/laws.h>
|
||||
|
@ -202,6 +203,8 @@ game_init(void)
|
|||
{
|
||||
init_triggers();
|
||||
init_xmas();
|
||||
|
||||
reports_init();
|
||||
report_init();
|
||||
creport_init();
|
||||
|
||||
|
|
Loading…
Reference in a new issue