2001-01-25 10:37:55 +01:00
|
|
|
|
/* vi: set ts=2:
|
|
|
|
|
*
|
2001-02-04 14:20:12 +01:00
|
|
|
|
* $Id: report.c,v 1.8 2001/02/04 13:20:12 corwin Exp $
|
2001-01-25 10:37:55 +01:00
|
|
|
|
* Eressea PB(E)M host Copyright (C) 1998-2000
|
|
|
|
|
* Christian Schlittchen (corwin@amber.kn-bremen.de)
|
|
|
|
|
* Katja Zedel (katze@felidae.kn-bremen.de)
|
|
|
|
|
* Henning Peters (faroul@beyond.kn-bremen.de)
|
|
|
|
|
* Enno Rehling (enno@eressea-pbem.de)
|
|
|
|
|
* Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
|
|
|
|
|
*
|
|
|
|
|
* based on:
|
|
|
|
|
*
|
|
|
|
|
* Atlantis v1.0 13 September 1993 Copyright 1993 by Russell Wallace
|
|
|
|
|
* Atlantis v1.7 Copyright 1996 by Alex Schr<EFBFBD>der
|
|
|
|
|
*
|
|
|
|
|
* This program may not be used, modified or distributed without
|
|
|
|
|
* prior permission by the authors of Eressea.
|
|
|
|
|
* This program may not be sold or used commercially without prior written
|
|
|
|
|
* permission from the authors.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define FAST_SEEN 0
|
|
|
|
|
#define INDENT 0
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
#include "eressea.h"
|
|
|
|
|
#include "reports.h"
|
|
|
|
|
|
|
|
|
|
#include "item.h"
|
|
|
|
|
#include "alchemy.h"
|
|
|
|
|
#include "faction.h"
|
|
|
|
|
#include "region.h"
|
|
|
|
|
#include "unit.h"
|
|
|
|
|
#include "skill.h"
|
|
|
|
|
#include "movement.h"
|
|
|
|
|
#include "message.h"
|
|
|
|
|
#include "ship.h"
|
|
|
|
|
#include "building.h"
|
|
|
|
|
#include "economy.h"
|
|
|
|
|
#include "build.h"
|
|
|
|
|
#include "creation.h"
|
|
|
|
|
#include "save.h"
|
|
|
|
|
#include "build.h"
|
|
|
|
|
#include "magic.h"
|
|
|
|
|
#include "race.h"
|
|
|
|
|
#include "monster.h"
|
|
|
|
|
#include "plane.h"
|
|
|
|
|
#include "pool.h"
|
|
|
|
|
#include "teleport.h"
|
|
|
|
|
#include "border.h"
|
|
|
|
|
#include "objtypes.h"
|
|
|
|
|
#include "goodies.h"
|
|
|
|
|
#include "karma.h"
|
|
|
|
|
#include "render.h"
|
|
|
|
|
#ifdef GROUPS
|
|
|
|
|
#include "group.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <modules/score.h>
|
|
|
|
|
|
|
|
|
|
/* util includes */
|
|
|
|
|
#include <base36.h>
|
|
|
|
|
|
|
|
|
|
/* libc includes */
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <limits.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
extern int quiet;
|
|
|
|
|
|
|
|
|
|
boolean nocr = false;
|
|
|
|
|
boolean nonr = false;
|
|
|
|
|
boolean nomer = false;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* -------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
extern int *storms;
|
|
|
|
|
|
|
|
|
|
char **seasonnames;
|
|
|
|
|
char **weeknames;
|
|
|
|
|
char **weeknames2;
|
|
|
|
|
char **monthnames;
|
|
|
|
|
int *season;
|
|
|
|
|
char *agename;
|
|
|
|
|
int seasons;
|
|
|
|
|
extern int weeks_per_month;
|
|
|
|
|
extern int months_per_year;
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
read_datenames(char *filename)
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
FILE *namesFP;
|
|
|
|
|
char line[256];
|
|
|
|
|
int i, l;
|
|
|
|
|
|
|
|
|
|
if( (namesFP=fopen(filename,"r")) == NULL) {
|
|
|
|
|
fprintf(stderr, "Kann Datei '%s' nicht <20>ffnen, Abbruch\n",filename);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fgets(line,255,namesFP);
|
|
|
|
|
l = strlen(line)-1;
|
|
|
|
|
if(line[l] == '\n') line[l] = 0;
|
|
|
|
|
agename = strdup(line);
|
|
|
|
|
|
|
|
|
|
fgets(line,255,namesFP);
|
|
|
|
|
seasons = strtol(line, NULL, 10);
|
|
|
|
|
seasonnames = malloc(sizeof(char *) * seasons);
|
|
|
|
|
|
|
|
|
|
for(i=0;i<seasons;i++) {
|
|
|
|
|
fgets(line,255,namesFP);
|
|
|
|
|
l = strlen(line)-1;
|
|
|
|
|
if(line[l] == '\n') line[l] = 0;
|
|
|
|
|
seasonnames[i] = strdup(line);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fgets(line,255,namesFP);
|
|
|
|
|
weeks_per_month = strtol(line, NULL, 10);
|
|
|
|
|
weeknames = malloc(sizeof(char *) * weeks_per_month);
|
|
|
|
|
weeknames2 = malloc(sizeof(char *) * weeks_per_month);
|
|
|
|
|
|
|
|
|
|
for(i=0;i<weeks_per_month;i++) {
|
|
|
|
|
char * np;
|
|
|
|
|
|
|
|
|
|
fgets(line,255,namesFP);
|
|
|
|
|
l = strlen(line)-1;
|
|
|
|
|
if(line[l] == '\n') line[l] = 0;
|
|
|
|
|
|
|
|
|
|
np = strtok(line,":");
|
|
|
|
|
weeknames[i] = strdup(np);
|
|
|
|
|
np = strtok(NULL,":");
|
|
|
|
|
weeknames2[i] = strdup(np);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fgets(line,255,namesFP);
|
|
|
|
|
months_per_year = strtol(line, NULL, 10);
|
|
|
|
|
monthnames = malloc(sizeof(char *) * months_per_year);
|
|
|
|
|
season = malloc(sizeof(int) * months_per_year);
|
|
|
|
|
storms = malloc(sizeof(int) * months_per_year);
|
|
|
|
|
|
|
|
|
|
for(i=0;i<months_per_year;i++) {
|
|
|
|
|
char * np;
|
|
|
|
|
fgets(line,255,namesFP);
|
|
|
|
|
l = strlen(line)-1;
|
|
|
|
|
if(line[l] == '\n') line[l] = 0;
|
|
|
|
|
|
|
|
|
|
np = strtok(line,":");
|
|
|
|
|
monthnames[i] = strdup(np);
|
|
|
|
|
season[i] = atoi(strtok(NULL,":"));
|
|
|
|
|
storms[i] = atoi(strtok(NULL,":"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fclose(namesFP);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
gamedate(void)
|
|
|
|
|
{
|
|
|
|
|
int year,month,week,r;
|
|
|
|
|
static char buf[256];
|
|
|
|
|
int t = turn - FIRST_TURN;
|
|
|
|
|
|
|
|
|
|
if (t<0) t = turn;
|
|
|
|
|
|
|
|
|
|
year = t/(months_per_year * weeks_per_month) + 1;
|
|
|
|
|
r = t - (year-1) * months_per_year * weeks_per_month;
|
|
|
|
|
month = r/weeks_per_month;
|
|
|
|
|
week = r%weeks_per_month;
|
|
|
|
|
if (turn>=FIRST_TURN) {
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "Wir schreiben %s des Monats %s im Jahre %d %s.",
|
|
|
|
|
weeknames[week],
|
|
|
|
|
monthnames[month],
|
|
|
|
|
year,
|
|
|
|
|
agename);
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(buf, "Wir schreiben %s des Monats %s im Jahre %d %s.",
|
|
|
|
|
weeknames[week],
|
|
|
|
|
monthnames[month],
|
|
|
|
|
year,
|
|
|
|
|
"der alten Zeitrechnung");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
gamedate2(void)
|
|
|
|
|
{
|
|
|
|
|
int year,month,week,r;
|
|
|
|
|
static char buf[256];
|
|
|
|
|
int t = turn - FIRST_TURN;
|
|
|
|
|
|
|
|
|
|
if (t<0) t = turn;
|
|
|
|
|
|
|
|
|
|
year = t/(months_per_year * weeks_per_month) + 1;
|
|
|
|
|
r = t - (year-1) * months_per_year * weeks_per_month;
|
|
|
|
|
month = r/weeks_per_month; /* 0 - months_per_year-1 */
|
|
|
|
|
week = r%weeks_per_month; /* 0 - weeks_per_month-1 */
|
|
|
|
|
if (turn>=FIRST_TURN) {
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "in %s des Monats %s im Jahre %d %s.",
|
|
|
|
|
weeknames2[week],
|
|
|
|
|
monthnames[month],
|
|
|
|
|
year,
|
|
|
|
|
agename);
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(buf, "in %s des Monats %s im Jahre %d %s.",
|
|
|
|
|
weeknames2[week],
|
|
|
|
|
monthnames[month],
|
|
|
|
|
year,
|
|
|
|
|
"der alten Zeitrechnung");
|
|
|
|
|
}
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
gamedate_short(void)
|
|
|
|
|
{
|
|
|
|
|
int year,month,week,r;
|
|
|
|
|
static char buf[256];
|
|
|
|
|
int t = turn - FIRST_TURN;
|
|
|
|
|
|
|
|
|
|
if (t<0) t = turn;
|
|
|
|
|
|
|
|
|
|
year = t/(months_per_year * weeks_per_month) + 1;
|
|
|
|
|
r = t - (year-1) * months_per_year * weeks_per_month;
|
|
|
|
|
month = r/weeks_per_month; /* 0 - months_per_year-1 */
|
|
|
|
|
week = r%weeks_per_month; /* 0 - weeks_per_month-1 */
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%d/%s/%d", week+1, monthnames[month], year);
|
|
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
static void
|
|
|
|
|
rpsnr(FILE * F, const char * s, int offset)
|
|
|
|
|
{
|
|
|
|
|
char inset[REPORTWIDTH];
|
|
|
|
|
const char *l, *x = s;
|
|
|
|
|
char ui=0;
|
|
|
|
|
size_t indent = 0, len;
|
|
|
|
|
|
|
|
|
|
/* Geht nicht: Privatbeschreibungen der Monster enthalten
|
|
|
|
|
* \\r-Koordinaten ! */
|
|
|
|
|
/* assert(!strstr(s, "\\r(") || !"error: regionid not translated"); */
|
|
|
|
|
|
|
|
|
|
len = strlen(s);
|
|
|
|
|
while (*x++ == ' ');
|
|
|
|
|
indent = x - s - 1;
|
|
|
|
|
if (*(x - 1) && indent && *x == ' ') indent += 2;
|
|
|
|
|
if (!indent) indent = offset;
|
|
|
|
|
x = s;
|
|
|
|
|
memset(inset, 32, indent * sizeof(char));
|
|
|
|
|
inset[indent] = 0;
|
|
|
|
|
while (s <= x+len) {
|
|
|
|
|
size_t line = min(len-(s-x), REPORTWIDTH - indent*ui);
|
|
|
|
|
char * br = strchr(s, '\n');
|
|
|
|
|
l = s + line;
|
|
|
|
|
|
|
|
|
|
if(br && br < l) {
|
|
|
|
|
l = br;
|
|
|
|
|
} else {
|
|
|
|
|
if (*l) {
|
|
|
|
|
while (*l!=' ' && l!=s) --l;
|
|
|
|
|
/* wenn nicht gefunden, harte breaks: */
|
|
|
|
|
if (s == l) l = s + REPORTWIDTH - indent;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (*s) {
|
|
|
|
|
#if INDENT
|
|
|
|
|
putc(' ', F);
|
|
|
|
|
#endif
|
|
|
|
|
if (s!=x) {
|
|
|
|
|
fputs(inset, F);
|
|
|
|
|
}
|
|
|
|
|
fwrite(s, sizeof(char), l-s, F);
|
|
|
|
|
putc('\n', F);
|
|
|
|
|
}
|
|
|
|
|
s = l+1; ui=1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static faction *current_faction = NULL;
|
|
|
|
|
|
|
|
|
|
int outi;
|
|
|
|
|
char outbuf[4096];
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
rpc(FILE * F, char c, size_t num)
|
|
|
|
|
{
|
|
|
|
|
while(num > 0) {
|
|
|
|
|
putc(c, F);
|
|
|
|
|
num--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
rnl(FILE * F)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
int rc, vc;
|
|
|
|
|
|
|
|
|
|
i = outi;
|
|
|
|
|
assert(i < 4096);
|
|
|
|
|
while (i && isspace((int)outbuf[i - 1]))
|
|
|
|
|
i--;
|
|
|
|
|
outbuf[i] = 0;
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
rc = 0;
|
|
|
|
|
vc = 0;
|
|
|
|
|
|
|
|
|
|
while (outbuf[i]) {
|
|
|
|
|
switch (outbuf[i]) {
|
|
|
|
|
case ' ':
|
|
|
|
|
vc++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '\t':
|
|
|
|
|
vc = (vc & ~7) + 8;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
/* ER: Tabs in Reports sind Mist. Die versauen die *
|
|
|
|
|
* Anzeige von Einheiten in Burgen und Schiffen. while
|
|
|
|
|
* (rc / 8 != vc / 8) { if ((rc & 7) == 7) putc(' ',
|
|
|
|
|
* F); else putc('\t', F); rc = (rc & ~7) + 8; } */
|
|
|
|
|
while (rc != vc) {
|
|
|
|
|
putc(' ', F);
|
|
|
|
|
rc++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
putc(outbuf[i], F);
|
|
|
|
|
rc++;
|
|
|
|
|
vc++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
assert(i < 4096);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
putc('\n', F);
|
|
|
|
|
outi = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
rps(FILE * F, const char * src)
|
|
|
|
|
{
|
|
|
|
|
char * s;
|
|
|
|
|
|
|
|
|
|
if (strstr(src, "\\r(")) s = replace_global_coords(src, current_faction);
|
|
|
|
|
else s = strcpy(buf, src);
|
|
|
|
|
rpsnr(F, s, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
centre(FILE * F, const char *s, boolean breaking)
|
|
|
|
|
{
|
|
|
|
|
/* Bei Namen die genau 80 Zeichen lang sind, kann es hier Probleme
|
|
|
|
|
* geben. Seltsamerweise wird i dann auf MAXINT oder aehnlich
|
|
|
|
|
* initialisiert. Deswegen keine Strings die laenger als REPORTWIDTH
|
|
|
|
|
* sind! */
|
|
|
|
|
|
|
|
|
|
if (breaking && REPORTWIDTH < strlen(s)) {
|
|
|
|
|
strlist *T, *SP = 0;
|
|
|
|
|
sparagraph(&SP, s, 0, 0);
|
|
|
|
|
T = SP;
|
|
|
|
|
while (SP) {
|
|
|
|
|
centre(F, SP->s, false);
|
|
|
|
|
SP = SP->next;
|
|
|
|
|
}
|
|
|
|
|
freestrlist(T);
|
|
|
|
|
} else {
|
|
|
|
|
rpc(F, ' ', (REPORTWIDTH - strlen(s)+1) / 2);
|
|
|
|
|
fputs(s, F);
|
|
|
|
|
putc('\n', F);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
rparagraph(FILE *F, const char *s, int indent, char mark)
|
|
|
|
|
{
|
|
|
|
|
static char mbuf[BUFSIZE+1];
|
|
|
|
|
/* static size_t bsize = 0; */
|
|
|
|
|
size_t size;
|
|
|
|
|
char inset[REPORTWIDTH];
|
|
|
|
|
|
|
|
|
|
if (indent) {
|
|
|
|
|
memset(inset, ' ', indent);
|
|
|
|
|
inset[indent]=0;
|
|
|
|
|
if (mark)
|
|
|
|
|
inset[indent - 2] = mark;
|
|
|
|
|
} else {
|
|
|
|
|
assert(mark == 0);
|
|
|
|
|
inset[0] = 0;
|
|
|
|
|
}
|
|
|
|
|
inset[indent]=0;
|
|
|
|
|
size = strlen(s)+indent+1;
|
|
|
|
|
if (size==1) return;
|
|
|
|
|
strcpy(mbuf, inset);
|
|
|
|
|
strncpy(mbuf+indent, s, BUFSIZE-indent);
|
|
|
|
|
*(mbuf+size-1)=0;
|
|
|
|
|
rps(F, mbuf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
report_spell(FILE * F, spellid_t id)
|
|
|
|
|
{
|
|
|
|
|
int k, itemanz, res, costtyp;
|
|
|
|
|
int dh = 0;
|
|
|
|
|
spell *sp = find_spellbyid(id);
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, sp->name, true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
strcpy(buf,"Beschreibung:");
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
rparagraph(F, sp->beschreibung, 0, 0);
|
|
|
|
|
rnl(F);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
strcpy(buf, "Art: ");
|
|
|
|
|
if (sp->sptyp & PRECOMBATSPELL) {
|
|
|
|
|
scat("Pr<EFBFBD>kampfzauber");
|
|
|
|
|
} else if (sp->sptyp & COMBATSPELL) {
|
|
|
|
|
scat("Kampfzauber");
|
|
|
|
|
} else if (sp->sptyp & POSTCOMBATSPELL) {
|
|
|
|
|
scat("Postkampfzauber");
|
|
|
|
|
} else {
|
|
|
|
|
scat("Normaler Zauber");
|
|
|
|
|
}
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
|
|
|
|
|
strcpy(buf, "Komponenten:");
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
for (k = 0; k < MAXINGREDIENT; k++) {
|
|
|
|
|
res = sp->komponenten[k][0];
|
|
|
|
|
itemanz = sp->komponenten[k][1];
|
|
|
|
|
costtyp = sp->komponenten[k][2];
|
|
|
|
|
if(itemanz > 0){
|
|
|
|
|
sprintf(buf, " %d %s", itemanz, resname(res, itemanz!=1));
|
|
|
|
|
if (costtyp == SPC_LEVEL || costtyp == SPC_LINEAR )
|
|
|
|
|
scat(" * Stufe");
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
strcpy(buf, "Modifikationen: ");
|
|
|
|
|
if (sp->sptyp & FARCASTING) {
|
|
|
|
|
scat("Fernzauber");
|
|
|
|
|
dh = 1;
|
|
|
|
|
}
|
|
|
|
|
if (sp->sptyp & OCEANCASTABLE) {
|
|
|
|
|
if (dh == 1){
|
|
|
|
|
scat(", ");
|
|
|
|
|
}
|
|
|
|
|
scat("Seezauber");
|
|
|
|
|
dh = 1;
|
|
|
|
|
}
|
|
|
|
|
if (sp->sptyp & ONSHIPCAST) {
|
|
|
|
|
if (dh == 1){
|
|
|
|
|
scat(", ");
|
|
|
|
|
}
|
|
|
|
|
scat("Schiffszauber");
|
|
|
|
|
dh = 1;
|
|
|
|
|
}
|
|
|
|
|
if (sp->sptyp & NOTFAMILIARCAST) {
|
|
|
|
|
if (dh == 1){
|
|
|
|
|
scat(", k");
|
|
|
|
|
} else {
|
|
|
|
|
scat("K");
|
|
|
|
|
}
|
|
|
|
|
scat("ann nicht vom Vertrauten gezaubert werden");
|
|
|
|
|
dh = 1;
|
|
|
|
|
}
|
|
|
|
|
if(dh == 0) scat("Keine");
|
|
|
|
|
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "Stufe: %d", sp->level);
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "Rang: %d", sp->rank);
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
|
|
|
|
strcpy(buf, "Syntax: ");
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
if(!sp->syntax){
|
|
|
|
|
if(sp->sptyp & ISCOMBATSPELL){
|
|
|
|
|
strcpy(buf, "KAMPFZAUBER ");
|
|
|
|
|
}else{
|
|
|
|
|
strcpy(buf, "ZAUBERE ");
|
|
|
|
|
}
|
|
|
|
|
/* Reihenfolge beachten: Erst REGION, dann STUFE! */
|
|
|
|
|
if (sp->sptyp & FARCASTING) {
|
|
|
|
|
scat("[REGION x y] ");
|
|
|
|
|
}
|
|
|
|
|
if (sp->sptyp & SPELLLEVEL) {
|
|
|
|
|
scat("[STUFE n] ");
|
|
|
|
|
}
|
|
|
|
|
scat("\"");
|
|
|
|
|
scat(sp->name);
|
|
|
|
|
scat("\" ");
|
|
|
|
|
if (sp->sptyp & ONETARGET){
|
|
|
|
|
if (sp->sptyp & UNITSPELL) {
|
|
|
|
|
scat("<Einheit-Nr>");
|
|
|
|
|
} else if (sp->sptyp & SHIPSPELL) {
|
|
|
|
|
scat("<Schiff-Nr>");
|
|
|
|
|
} else if (sp->sptyp & BUILDINGSPELL) {
|
|
|
|
|
scat("<Geb<65>ude-Nr>");
|
|
|
|
|
}
|
|
|
|
|
}else {
|
|
|
|
|
if (sp->sptyp & UNITSPELL) {
|
|
|
|
|
scat("<Einheit-Nr> [<Einheit-Nr> ...]");
|
|
|
|
|
} else if (sp->sptyp & SHIPSPELL) {
|
|
|
|
|
scat("<Schiff-Nr> [<Schiff-Nr> ...]");
|
|
|
|
|
} else if (sp->sptyp & BUILDINGSPELL) {
|
|
|
|
|
scat("<Geb<65>ude-Nr> [<Geb<65>ude-Nr> ...]");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
strcpy(buf, sp->syntax);
|
|
|
|
|
}
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nmr_warnings(void)
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
faction *f,*fa;
|
|
|
|
|
|
|
|
|
|
for(f=factions;f;f=f->next) {
|
|
|
|
|
if(f->no != MONSTER_FACTION && (turn-f->lastorders) >= 2) {
|
|
|
|
|
for(fa=factions;fa;fa=fa->next) {
|
|
|
|
|
if(isallied(NULL, f, fa, HELP_GUARD | HELP_MONEY) && isallied(NULL, fa,f,HELP_GUARD | HELP_MONEY)) {
|
|
|
|
|
sprintf(buf, "Achtung: %s hat einige Zeit keine "
|
|
|
|
|
"Z<EFBFBD>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)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/* Die Liste SP wird mit dem String s aufgefuellt, mit indent und einer
|
|
|
|
|
* mark, falls angegeben. SP wurde also auf 0 gesetzt vor dem Aufruf.
|
|
|
|
|
* Vgl. spunit (). */
|
|
|
|
|
|
|
|
|
|
int i, j, width;
|
|
|
|
|
int firstline;
|
|
|
|
|
static char buf[REPORTWIDTH + 1];
|
|
|
|
|
|
|
|
|
|
width = REPORTWIDTH - indent;
|
|
|
|
|
firstline = 1;
|
|
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
j = i;
|
|
|
|
|
while (s[j] && s[j] != ' ')
|
|
|
|
|
j++;
|
|
|
|
|
if (j > width) {
|
|
|
|
|
|
|
|
|
|
/* j zeigt auf das ende der aktuellen zeile, i zeigt auf den anfang der
|
|
|
|
|
* n<EFBFBD>chsten zeile. existiert ein wort am anfang der zeile, welches
|
|
|
|
|
* l<EFBFBD>nger als eine zeile ist, mu<EFBFBD> dieses hier abgetrennt werden. */
|
|
|
|
|
|
|
|
|
|
if (i == 0)
|
|
|
|
|
i = width - 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
i = j + 1;
|
|
|
|
|
}
|
|
|
|
|
while (s[j]);
|
|
|
|
|
|
|
|
|
|
for (j = 0; j != indent; j++)
|
|
|
|
|
buf[j] = ' ';
|
|
|
|
|
|
|
|
|
|
if (firstline && mark)
|
|
|
|
|
buf[indent - 2] = mark;
|
|
|
|
|
|
|
|
|
|
for (j = 0; j != i - 1; j++)
|
|
|
|
|
buf[indent + j] = s[j];
|
|
|
|
|
buf[indent + j] = 0;
|
|
|
|
|
|
|
|
|
|
addstrlist(SP, buf);
|
|
|
|
|
|
|
|
|
|
if (s[i - 1] == 0)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
s += i;
|
|
|
|
|
firstline = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
hat_in_region(item_t it, region * r, faction * f)
|
|
|
|
|
{
|
|
|
|
|
unit *u;
|
|
|
|
|
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->faction == f && get_item(u, it) > 0) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
print_curses(FILE *F, const void * obj, typ_t typ, const attrib *a, int self, int indent)
|
|
|
|
|
{
|
|
|
|
|
for(;a;a=a->next) {
|
|
|
|
|
int dh = 0;
|
|
|
|
|
|
|
|
|
|
if (fval(a->type, ATF_CURSE)) {
|
|
|
|
|
curse *c = (curse *)a->data.v;
|
|
|
|
|
if (c->type->curseinfo)
|
|
|
|
|
dh = c->type->curseinfo(obj, typ, c, self);
|
|
|
|
|
if (dh == 1) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, buf, indent, 0);
|
|
|
|
|
}
|
|
|
|
|
} else if (a->type==&at_effect && self) {
|
|
|
|
|
effect_data * data = (effect_data *)a->data.v;
|
|
|
|
|
sprintf(buf, "Auf der Einheit lieg%s %d Wirkung%s %s.",
|
|
|
|
|
(data->value==1 ? "t" : "en"),
|
|
|
|
|
data->value,
|
|
|
|
|
(data->value==1 ? "" : "en"),
|
|
|
|
|
locale_string(NULL, resourcename(data->type->itype->rtype, 0)));
|
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, buf, indent, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
replace_global_coords(const char *s, faction * f)
|
|
|
|
|
{
|
|
|
|
|
return translate_regions(s, f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
rps_nowrap(FILE * F, const char *s)
|
|
|
|
|
{
|
|
|
|
|
const char *x = s;
|
|
|
|
|
int indent = 0;
|
|
|
|
|
|
|
|
|
|
x = s = replace_global_coords(s, current_faction);
|
|
|
|
|
|
|
|
|
|
while (*x++ == ' ');
|
|
|
|
|
indent = x - s - 1;
|
|
|
|
|
if (*(x - 1) && indent && *x == ' ')
|
|
|
|
|
indent += 2;
|
|
|
|
|
x = s;
|
|
|
|
|
while (*s) {
|
|
|
|
|
if (s == x) {
|
|
|
|
|
x = strchr(x + 1, ' ');
|
|
|
|
|
if (!x)
|
|
|
|
|
x = s + strlen(s);
|
|
|
|
|
}
|
|
|
|
|
rpc(F, *s++, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int rpu = 0;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
rpunit(FILE * F, const faction * f, const unit * u, int indent, int mode)
|
|
|
|
|
{
|
|
|
|
|
strlist *S;
|
|
|
|
|
int dh;
|
|
|
|
|
boolean isbattle = (boolean)(mode == see_battle);
|
|
|
|
|
++rpu;
|
|
|
|
|
|
|
|
|
|
if(u->race == RC_SPELL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
|
|
|
|
|
|
|
|
|
dh = bufunit(f, u, indent, mode);
|
|
|
|
|
rparagraph(F, buf, indent, (char) ((u->faction == f) ? '*' : (dh ? '+' : '-')));
|
|
|
|
|
if(!isbattle){
|
|
|
|
|
print_curses(F, u, TYP_UNIT, u->attribs, (u->faction == f)? 1 : 0, indent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mode==see_unit && u->faction == f && u->botschaften) {
|
|
|
|
|
for (S = u->botschaften; S; S = S->next) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, S->s, indent, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
rp_messages(FILE * F, message * msgs, faction * viewer, int indent, boolean centered, boolean categorized)
|
|
|
|
|
{
|
|
|
|
|
messageclass * category;
|
|
|
|
|
if (!msgs) return;
|
|
|
|
|
for (category=msgclasses; category; category=category->next) {
|
|
|
|
|
int k = 0;
|
|
|
|
|
message * m;
|
|
|
|
|
for (m=msgs; m; m=m->next) {
|
|
|
|
|
boolean debug = viewer->options & want(O_DEBUG);
|
|
|
|
|
if (m->type->section!=category) continue;
|
|
|
|
|
#ifdef MSG_LEVELS
|
|
|
|
|
if (!debug && get_msglevel(viewer->warnings, viewer->msglevels, m->type) < m->level) continue;
|
|
|
|
|
#endif
|
|
|
|
|
/* messagetype * mt = m->type; */
|
|
|
|
|
if (m->receiver==NULL || !viewer || viewer==m->receiver) {
|
|
|
|
|
const char * s = render(m, viewer->locale);
|
|
|
|
|
if (!k && categorized) {
|
|
|
|
|
const char * name;
|
|
|
|
|
char cat_identifier[24];
|
|
|
|
|
|
|
|
|
|
sprintf(cat_identifier, "section_%s", category->name);
|
|
|
|
|
name = locale_string(viewer->locale, cat_identifier);
|
|
|
|
|
if (debug) {
|
|
|
|
|
if (name!=buf) strcpy(buf, name);
|
|
|
|
|
sprintf(buf+strlen(name), " [%s]", cat_identifier);
|
|
|
|
|
name = buf;
|
|
|
|
|
}
|
|
|
|
|
k = 1;
|
|
|
|
|
rnl(F);
|
|
|
|
|
if (centered) centre(F, name, true);
|
|
|
|
|
else {
|
|
|
|
|
if (indent>0) strcpy(buf, " ");
|
|
|
|
|
strcpy(buf+indent, name);
|
|
|
|
|
rpsnr(F, buf, 2);
|
|
|
|
|
}
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
if (indent>0) {
|
|
|
|
|
strcpy(buf, " ");
|
|
|
|
|
strcpy(buf+indent, s);
|
|
|
|
|
s = buf;
|
|
|
|
|
}
|
|
|
|
|
if (debug) {
|
|
|
|
|
int mylevel = get_msglevel(viewer->warnings, viewer->msglevels, m->type);
|
|
|
|
|
int level = msg_level(m);
|
|
|
|
|
if (s!=buf) strcpy(buf, s);
|
|
|
|
|
sprintf(buf+strlen(s), " [%d:%d(%d)]", m->type->hashkey, level, mylevel);
|
|
|
|
|
s = buf;
|
|
|
|
|
}
|
|
|
|
|
rpsnr(F, s, 2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
f_regionid(const region * r, const faction * f)
|
|
|
|
|
{
|
|
|
|
|
static int i = 0;
|
|
|
|
|
static char bufs[4][NAMESIZE + 20];
|
|
|
|
|
char * buf = bufs[(++i)%4];
|
|
|
|
|
plane *pl = NULL;
|
|
|
|
|
|
|
|
|
|
if (!r)
|
|
|
|
|
strcpy(buf, "(Chaos)");
|
|
|
|
|
else {
|
|
|
|
|
pl = getplane(r);
|
|
|
|
|
if(pl && fval(pl,PFL_NOCOORDS)) {
|
|
|
|
|
if (rterrain(r) == T_OCEAN)
|
|
|
|
|
sprintf(buf, "Ozean");
|
|
|
|
|
else
|
|
|
|
|
sprintf(buf, "%s", rname(r, f->locale));
|
|
|
|
|
} else {
|
|
|
|
|
if (rterrain(r) == T_OCEAN)
|
|
|
|
|
sprintf(buf, "Ozean (%d,%d%s%s)", region_x(r,f), region_y(r,f), pl?",":"", pl?pl->name:"");
|
|
|
|
|
else
|
|
|
|
|
sprintf(buf, "%s (%d,%d%s%s)", rname(r, f->locale), region_x(r,f), region_y(r,f), pl?",":"", pl?pl->name:"");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
prices(FILE * F, region * r, faction * f)
|
|
|
|
|
{
|
|
|
|
|
const luxury_type *sale=NULL;
|
|
|
|
|
struct demand * dmd;
|
2001-02-03 14:45:35 +01:00
|
|
|
|
int n = 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
if (r->land==NULL || r->land->demands==NULL) return;
|
|
|
|
|
for (dmd=r->land->demands;dmd;dmd=dmd->next) {
|
|
|
|
|
if (dmd->value==0) sale = dmd->type;
|
2001-02-03 14:45:35 +01:00
|
|
|
|
else if (dmd->value > 0) n++;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
assert(sale!=NULL);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "Auf dem Markt wird f<>r %s %d Silber verlangt.",
|
2001-02-03 14:45:35 +01:00
|
|
|
|
locale_string(f->locale, resourcename(sale->itype->rtype, GR_PLURAL)),
|
|
|
|
|
sale->price);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
if(n > 0) scat(" Geboten wird f<>r ");
|
|
|
|
|
|
|
|
|
|
for (dmd=r->land->demands;dmd;dmd=dmd->next) if(dmd->value > 0) {
|
|
|
|
|
char sbuf[80];
|
|
|
|
|
sprintf(sbuf, "%s %d Silber", locale_string(f->locale,
|
|
|
|
|
resourcename(dmd->type->itype->rtype, GR_PLURAL)),
|
|
|
|
|
dmd->value * dmd->type->price);
|
|
|
|
|
scat(sbuf);
|
|
|
|
|
n--;
|
|
|
|
|
if (n == 0) scat(".");
|
|
|
|
|
else if (n == 1) scat(" und f<>r ");
|
|
|
|
|
else scat(", f<>r ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Schreibe Paragraphen */
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
extern const direction_t back[MAXDIRECTIONS];
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
boolean
|
|
|
|
|
see_border(border * b, faction * f, region * r)
|
|
|
|
|
{
|
|
|
|
|
boolean cs = b->type->fvisible(b, f, r);
|
|
|
|
|
if (!cs) {
|
|
|
|
|
cs = b->type->rvisible(b, r);
|
|
|
|
|
if (!cs) {
|
|
|
|
|
unit * us = r->units;
|
|
|
|
|
while (us && !cs) {
|
|
|
|
|
if (us->faction==f) {
|
|
|
|
|
cs = b->type->uvisible(b, us);
|
|
|
|
|
if (cs) break;
|
|
|
|
|
}
|
|
|
|
|
us=us->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return cs;
|
|
|
|
|
}
|
|
|
|
|
|
2001-02-04 09:42:36 +01:00
|
|
|
|
attrib_type at_roads_override = {
|
|
|
|
|
"roads_override", NULL, NULL, NULL, &a_writestring, &a_readstring
|
|
|
|
|
};
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static void
|
|
|
|
|
describe(FILE * F, region * r, int partial, faction * f)
|
|
|
|
|
{
|
|
|
|
|
char dbuf[512];
|
|
|
|
|
int n;
|
|
|
|
|
boolean dh;
|
|
|
|
|
direction_t d;
|
|
|
|
|
int maxmining = 0, trees;
|
|
|
|
|
unit *u;
|
|
|
|
|
attrib *a;
|
|
|
|
|
const char *tname;
|
|
|
|
|
struct edge {
|
|
|
|
|
struct edge * next;
|
|
|
|
|
char * name;
|
|
|
|
|
boolean transparent;
|
|
|
|
|
boolean block;
|
|
|
|
|
boolean exist[MAXDIRECTIONS];
|
|
|
|
|
direction_t lastd;
|
|
|
|
|
} * edges = NULL, * e;
|
|
|
|
|
boolean see[MAXDIRECTIONS];
|
|
|
|
|
|
|
|
|
|
for (d = 0; d != MAXDIRECTIONS; d++)
|
|
|
|
|
{ /* Nachbarregionen, die gesehen werden, ermitteln */
|
|
|
|
|
region *r2 = rconnect(r, d);
|
|
|
|
|
border *b;
|
|
|
|
|
see[d] = true;
|
|
|
|
|
if (!r2) continue;
|
|
|
|
|
for (b=get_borders(r, r2);b;) {
|
|
|
|
|
struct edge * e = edges;
|
|
|
|
|
boolean transparent = b->type->transparent(b, f);
|
|
|
|
|
const char * name = b->type->name(b, r, f, GF_DETAILED|GF_ARTICLE);
|
|
|
|
|
|
|
|
|
|
if (!transparent) see[d] = false;
|
|
|
|
|
if (!see_border(b, f, r)) {
|
|
|
|
|
b = b->next;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
while (e && (e->transparent != transparent || strcmp(name,e->name))) e = e->next;
|
|
|
|
|
if (!e) {
|
|
|
|
|
e = calloc(sizeof(struct edge), 1);
|
|
|
|
|
e->name = strdup(name);
|
|
|
|
|
e->transparent = transparent;
|
|
|
|
|
e->next = edges;
|
|
|
|
|
edges = e;
|
|
|
|
|
}
|
|
|
|
|
e->lastd=d;
|
|
|
|
|
e->exist[d] = true;
|
|
|
|
|
b = b->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
strcpy(buf, f_regionid(r, f));
|
|
|
|
|
|
|
|
|
|
if (partial == 1) {
|
|
|
|
|
scat(" (durchgereist)");
|
|
|
|
|
}
|
|
|
|
|
#ifdef SEE_FAR
|
|
|
|
|
else if (partial == 3) {
|
|
|
|
|
scat(" (benachbart)");
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
else if (partial == 2) {
|
|
|
|
|
scat(" (vom Turm erblickt)");
|
|
|
|
|
}
|
|
|
|
|
/* Terrain */
|
|
|
|
|
|
|
|
|
|
scat(", ");
|
|
|
|
|
if(is_cursed(r->attribs,C_MAELSTROM, 0))
|
|
|
|
|
tname = "maelstrom";
|
|
|
|
|
else {
|
|
|
|
|
if (r_isforest(r)) tname = "forest";
|
|
|
|
|
else tname = terrain[rterrain(r)].name;
|
|
|
|
|
}
|
|
|
|
|
scat(locale_string(f->locale, tname));
|
|
|
|
|
|
|
|
|
|
/* B<>ume */
|
|
|
|
|
|
|
|
|
|
trees = rtrees(r);
|
|
|
|
|
if (production(r) && trees > 0) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
icat(trees);
|
|
|
|
|
scat(" ");
|
|
|
|
|
if (fval(r, RF_MALLORN)) {
|
|
|
|
|
if (rtrees(r) == 1)
|
|
|
|
|
scat("Mallornbaum");
|
|
|
|
|
else
|
|
|
|
|
scat("Mallornb<EFBFBD>ume");
|
|
|
|
|
}
|
|
|
|
|
else if (rtrees(r) == 1)
|
|
|
|
|
scat("Baum");
|
|
|
|
|
else
|
|
|
|
|
scat("B<EFBFBD>ume");
|
|
|
|
|
}
|
|
|
|
|
/* Eisen */
|
|
|
|
|
|
|
|
|
|
if (partial == 0
|
|
|
|
|
&& f != (faction *) NULL
|
|
|
|
|
&& (rterrain(r) == T_MOUNTAIN || rterrain(r) == T_GLACIER)) {
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->faction == f) {
|
|
|
|
|
int s = eff_skill(u, SK_MINING, r);
|
|
|
|
|
maxmining = max(maxmining, s);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (maxmining >= 4) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
icat(riron(r));
|
|
|
|
|
scat(" Eisen");
|
|
|
|
|
}
|
|
|
|
|
#ifdef NEW_ITEMS
|
|
|
|
|
if (rlaen(r)>=0 && maxmining >= 7)
|
|
|
|
|
#else
|
|
|
|
|
if (rlaen(r)>=0 && maxmining >= itemdata[I_EOG].minskill)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
scat(", ");
|
|
|
|
|
icat(rlaen(r));
|
|
|
|
|
scat(" Laen");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Bauern & Geld */
|
|
|
|
|
|
|
|
|
|
if (rpeasants(r)) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
icat(rpeasants(r));
|
|
|
|
|
|
|
|
|
|
if(fval(r, RF_ORCIFIED)) {
|
|
|
|
|
scat(rpeasants(r)==1?" Ork":" Orks");
|
|
|
|
|
} else {
|
|
|
|
|
scat(rpeasants(r)==1?" Bauer":" Bauern");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rmoney(r) && partial == 0) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
icat(rmoney(r));
|
|
|
|
|
scat(" Silber");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Pferde */
|
|
|
|
|
|
|
|
|
|
if (rhorses(r)) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
icat(rhorses(r));
|
|
|
|
|
scat(" ");
|
|
|
|
|
#ifdef NEW_ITEMS
|
|
|
|
|
scat(locale_string(f->locale, resourcename(oldresourcetype[R_HORSE], (rhorses(r)>1)?GR_PLURAL:0)));
|
|
|
|
|
#else
|
|
|
|
|
scat(itemdata[I_HORSE].name[rhorses(r) > 1]);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
scat(".");
|
|
|
|
|
|
|
|
|
|
if (r->display[0]) {
|
|
|
|
|
scat(" ");
|
|
|
|
|
scat(r->display);
|
|
|
|
|
|
|
|
|
|
n = r->display[strlen(r->display) - 1];
|
|
|
|
|
if (n != '!' && n != '?' && n != '.')
|
|
|
|
|
scat(".");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!is_cursed(r->attribs, C_REGCONF, 0)) {
|
2001-02-04 09:42:36 +01:00
|
|
|
|
attrib *a_do = a_find(r->attribs, &at_roads_override);
|
|
|
|
|
if(a_do) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
scat(" ");
|
2001-02-04 09:42:36 +01:00
|
|
|
|
scat((char *)a_do->data.v);
|
|
|
|
|
} else {
|
|
|
|
|
int nrd = 0;
|
|
|
|
|
|
|
|
|
|
/* Nachbarregionen, die gesehen werden, ermitteln */
|
|
|
|
|
for (d = 0; d != MAXDIRECTIONS; d++)
|
|
|
|
|
if (see[d] && rconnect(r, d)) nrd++;
|
|
|
|
|
|
|
|
|
|
/* Richtungen aufz<66>hlen */
|
|
|
|
|
|
|
|
|
|
dh = false;
|
|
|
|
|
for (d = 0; d != MAXDIRECTIONS; d++) if (see[d]) {
|
|
|
|
|
region * r2 = rconnect(r, d);
|
|
|
|
|
if(!r2) continue;
|
|
|
|
|
nrd--;
|
|
|
|
|
if (dh) {
|
|
|
|
|
if (nrd == 0) scat(" und im ");
|
|
|
|
|
else scat(", im ");
|
|
|
|
|
}
|
|
|
|
|
else scat(" Im ");
|
|
|
|
|
scat(directions[d]);
|
|
|
|
|
scat(" ");
|
|
|
|
|
if (!dh) scat("der Region liegt ");
|
|
|
|
|
sprintf(dbuf, trailinto(r2, f->locale),
|
|
|
|
|
f_regionid(r2, f));
|
|
|
|
|
scat(dbuf);
|
|
|
|
|
dh = true;
|
|
|
|
|
}
|
|
|
|
|
/* Spezielle Richtungen */
|
|
|
|
|
for (a = a_find(r->attribs, &at_direction);a;a = a->nexttype) {
|
|
|
|
|
spec_direction * d = (spec_direction *)(a->data.v);
|
|
|
|
|
scat(" ");
|
|
|
|
|
scat(d->desc);
|
|
|
|
|
scat(" (\"");
|
|
|
|
|
scat(d->keyword);
|
|
|
|
|
scat("\")");
|
|
|
|
|
scat(".");
|
|
|
|
|
dh = 1;
|
|
|
|
|
}
|
|
|
|
|
if (dh) scat(".");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
} else {
|
|
|
|
|
scat(" Gro<72>e Verwirrung bef<65>llt alle Reisenden in dieser Region.");
|
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (r->planep && r->planep->id == 1 &&
|
|
|
|
|
!is_cursed(r->attribs, C_ASTRALBLOCK, 0)) {
|
|
|
|
|
/* Sonderbehandlung Teleport-Ebene */
|
|
|
|
|
regionlist *rl = allinhab_in_range(r_astral_to_standard(r), TP_RADIUS);
|
|
|
|
|
regionlist *rl2;
|
|
|
|
|
|
|
|
|
|
if (rl) {
|
|
|
|
|
strcpy(buf, "Schemen der Regionen ");
|
|
|
|
|
rl2 = rl;
|
|
|
|
|
while(rl2) {
|
|
|
|
|
scat(f_regionid(rl2->region, f));
|
|
|
|
|
rl2 = rl2->next;
|
|
|
|
|
if(rl2) scat(", ");
|
|
|
|
|
}
|
|
|
|
|
scat(" sind erkennbar.");
|
|
|
|
|
free_regionlist(rl);
|
|
|
|
|
/* Schreibe Paragraphen */
|
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
|
|
|
|
|
|
/* Wirkungen permanenter Spr<70>che */
|
|
|
|
|
print_curses(F, r, TYP_REGION, r->attribs, 0, 0);
|
|
|
|
|
|
|
|
|
|
/* Produktionsreduktion */
|
|
|
|
|
a = a_find(r->attribs, &at_reduceproduction);
|
|
|
|
|
if(a) {
|
|
|
|
|
sprintf(buf, "Die Region ist verw<72>stet, der Boden karg.");
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (edges) rnl(F);
|
|
|
|
|
for (e=edges;e;e=e->next) {
|
|
|
|
|
boolean first = true;
|
|
|
|
|
for (d=0;d!=MAXDIRECTIONS;++d) {
|
|
|
|
|
if (!e->exist[d]) continue;
|
|
|
|
|
if (first) strcpy(buf, "Im ");
|
|
|
|
|
else {
|
|
|
|
|
if (e->lastd==d) strcat(buf, " und im ");
|
|
|
|
|
else strcat(buf, ", im ");
|
|
|
|
|
}
|
|
|
|
|
strcat(buf, directions[d]);
|
|
|
|
|
first = false;
|
|
|
|
|
}
|
|
|
|
|
if (!e->transparent) strcat(buf, " versperrt ");
|
|
|
|
|
else strcat(buf, " befindet sich ");
|
|
|
|
|
strcat(buf, e->name);
|
|
|
|
|
if (!e->transparent) strcat(buf, " die Sicht.");
|
|
|
|
|
else strcat(buf, ".");
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
if (edges) {
|
|
|
|
|
while (edges) {
|
|
|
|
|
e = edges->next;
|
|
|
|
|
free(edges->name);
|
|
|
|
|
free(edges);
|
|
|
|
|
edges = e;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern const int wagetable[6][3];
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
statistics(FILE * F, region * r, faction * f)
|
|
|
|
|
{
|
|
|
|
|
unit *u;
|
|
|
|
|
int number, p;
|
|
|
|
|
item *itm, *items = NULL;
|
|
|
|
|
p = rpeasants(r);
|
|
|
|
|
number = 0;
|
|
|
|
|
|
|
|
|
|
/* z<>hlen */
|
|
|
|
|
for (u = r->units; u; u = u->next)
|
|
|
|
|
if (u->faction == f && u->race != RC_SPELL) {
|
|
|
|
|
for (itm=u->items;itm;itm=itm->next) {
|
|
|
|
|
i_change(&items, itm->type, itm->number);
|
|
|
|
|
}
|
|
|
|
|
number += u->number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Ausgabe */
|
|
|
|
|
rnl(F);
|
|
|
|
|
sprintf(buf, "Statistik f<>r %s:", f_regionid(r, f));
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
|
|
|
|
|
/* Region */
|
|
|
|
|
if (landregion(rterrain(r)) && rmoney(r)) {
|
|
|
|
|
sprintf(buf, "Unterhaltung: max. %d Silber", entertainmoney(r));
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
}
|
|
|
|
|
if (production(r) && (!rterrain(r) == T_OCEAN || f->race == RC_AQUARIAN)) {
|
|
|
|
|
sprintf(buf, "Lohn f<>r Arbeit: %d Silber", fwage(r, f, true));
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
}
|
|
|
|
|
if (p) {
|
|
|
|
|
sprintf(buf, "Rekrutieren: max. %d Bauern",
|
|
|
|
|
p / RECRUITFRACTION);
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
|
|
|
|
|
if (gebaeude_vorhanden(r, &bt_caravan)) {
|
|
|
|
|
sprintf(buf, "Luxusg<EFBFBD>ter zum angegebenen Preis: %d",
|
|
|
|
|
(p * 2) / TRADE_FRACTION);
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(buf, "Luxusg<EFBFBD>ter zum angegebenen Preis: %d",
|
|
|
|
|
p / TRADE_FRACTION);
|
|
|
|
|
}
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
}
|
|
|
|
|
/* Info <20>ber Einheiten */
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "Personen: %d", number);
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
for (itm = items; itm; itm=itm->next) {
|
|
|
|
|
sprintf(buf, "%s: %d", locale_string(f->locale, resourcename(itm->type->rtype, GR_PLURAL)), itm->number);
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
}
|
|
|
|
|
while (items) i_free(i_remove(&items, items));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
in_region(region * r, unit * u)
|
|
|
|
|
{
|
|
|
|
|
unit *ru;
|
|
|
|
|
|
|
|
|
|
for (ru = r->units; ru; ru = ru->next) {
|
|
|
|
|
if (u == ru) {
|
|
|
|
|
return (1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return (0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
durchreisende(FILE * F, region * r, faction * f)
|
|
|
|
|
{
|
|
|
|
|
attrib *ru;
|
|
|
|
|
int wieviele;
|
|
|
|
|
int counter;
|
|
|
|
|
|
|
|
|
|
wieviele = counter = 0;
|
|
|
|
|
|
|
|
|
|
/* Wieviele sind aufzulisten? F<>r die Grammatik. */
|
|
|
|
|
|
|
|
|
|
for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) {
|
|
|
|
|
unit * u = (unit*)ru->data.v;
|
|
|
|
|
if (cansee_durchgezogen(f, r, u, 0) > 0 && !in_region(r, u)) {
|
|
|
|
|
if (u->ship && !fval(u, FL_OWNER))
|
|
|
|
|
continue;
|
|
|
|
|
wieviele++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!wieviele)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Auflisten. */
|
|
|
|
|
|
|
|
|
|
buf[0] = 0;
|
|
|
|
|
rnl(F);
|
|
|
|
|
|
|
|
|
|
for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) {
|
|
|
|
|
unit * u = (unit*)ru->data.v;
|
|
|
|
|
if (cansee_durchgezogen(f, r, u, 0) > 0 && !in_region(r, u)) {
|
|
|
|
|
if (u->ship && !fval(u, FL_OWNER))
|
|
|
|
|
continue;
|
|
|
|
|
counter++;
|
|
|
|
|
if (u->ship != (ship *) NULL) {
|
|
|
|
|
if (counter == 1) {
|
|
|
|
|
scat("Die ");
|
|
|
|
|
} else {
|
|
|
|
|
scat("die ");
|
|
|
|
|
}
|
|
|
|
|
scat(shipname(u->ship));
|
|
|
|
|
} else {
|
|
|
|
|
scat(unitname(u));
|
|
|
|
|
}
|
|
|
|
|
if (counter + 1 < wieviele) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
} else if (counter + 1 == wieviele) {
|
|
|
|
|
scat(" und ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (wieviele == 1) {
|
|
|
|
|
scat(" hat die Region durchquert.");
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
} else {
|
|
|
|
|
scat(" haben die Region durchquert.");
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
order_template(FILE * F, faction * f)
|
|
|
|
|
{
|
|
|
|
|
strlist *S2;
|
|
|
|
|
region *r;
|
|
|
|
|
plane *pl;
|
|
|
|
|
unit *u;
|
|
|
|
|
int dh;
|
|
|
|
|
region *last = lastregion(f);
|
|
|
|
|
|
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
|
|
|
|
rps_nowrap(F, "Vorlage f<>r den n<>chsten Zug:");
|
|
|
|
|
rnl(F);
|
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
|
|
|
|
|
2001-02-03 14:45:35 +01:00
|
|
|
|
sprintf(buf, "%s %s \"hier_passwort_eintragen\"", parameters[P_FACTION], factionid(f));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
|
|
|
|
|
dh = (f->options & Pow(O_SILBERPOOL));
|
|
|
|
|
|
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
2001-02-03 14:45:35 +01:00
|
|
|
|
sprintf(buf, "; ECHECK %s-w4 -r%d -v%s", dh ? "-l " : "",
|
|
|
|
|
race[f->race].rekrutieren, ECHECK_VERSION);
|
|
|
|
|
/* -v3.4: ECheck Version 3.4.x */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
|
|
|
|
|
for (r = firstregion(f); r != last; r = r->next) {
|
|
|
|
|
dh = 0;
|
|
|
|
|
for (u = r->units; u; u = u->next)
|
|
|
|
|
if (u->faction == f && u->race != RC_SPELL) {
|
|
|
|
|
if (!dh) {
|
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
|
|
|
|
pl = getplane(r);
|
|
|
|
|
if (pl && fval(pl, PFL_NOCOORDS)) {
|
|
|
|
|
sprintf(buf, "REGION; %s", rname(r, f->locale));
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(buf, "REGION %d,%d ; %s", region_x(r,f),
|
|
|
|
|
region_y(r,f), rname(r, f->locale));
|
|
|
|
|
}
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
sprintf(buf,"; ECheck Lohn %d", fwage(r,f,true));
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
dh = 1;
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%s %s; %s [%d,%d$", parameters[P_UNIT],
|
|
|
|
|
unitid(u), u->name, u->number, get_money(u));
|
|
|
|
|
if (u->building != NULL && fval(u, FL_OWNER)) {
|
|
|
|
|
building * b = u->building;
|
|
|
|
|
int cost = buildingmaintenance(b, R_SILVER);
|
|
|
|
|
|
|
|
|
|
if (cost > 0) {
|
|
|
|
|
scat(",U");
|
|
|
|
|
icat(cost);
|
|
|
|
|
}
|
|
|
|
|
#if TODO
|
|
|
|
|
if (buildingdaten[u->building->typ].spezial != 0) {
|
|
|
|
|
scat("+");
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
} else if (u->ship) {
|
|
|
|
|
if (fval(u, FL_OWNER))
|
|
|
|
|
scat(",S");
|
|
|
|
|
else
|
|
|
|
|
scat(",s");
|
|
|
|
|
scat(shipid(u->ship));
|
|
|
|
|
}
|
|
|
|
|
if (lifestyle(u) == 0)
|
|
|
|
|
scat(",I");
|
|
|
|
|
scat("]");
|
|
|
|
|
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
|
|
|
|
|
for (S2 = u->orders; S2; S2 = S2->next) {
|
|
|
|
|
if(is_persistent(S2->s)) {
|
|
|
|
|
sprintf(buf, " %s", S2->s);
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(u->lastorder[0]) {
|
|
|
|
|
sprintf(buf, " %s", u->lastorder);
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
|
|
|
|
sprintf(buf, parameters[P_NEXT]);
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
alliances(ally * sf)
|
|
|
|
|
{
|
|
|
|
|
int allierte = 0;
|
|
|
|
|
int i=0, h, hh = 0;
|
|
|
|
|
int dh = 0;
|
|
|
|
|
ally * sff;
|
|
|
|
|
for (sff = sf; sff; sff = sff->next) {
|
|
|
|
|
if (sff->status > 0 && sff->status <= HELP_ALL) {
|
|
|
|
|
allierte++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (sf) {
|
|
|
|
|
if (sf->status > 0) {
|
|
|
|
|
i++;
|
|
|
|
|
if (dh) {
|
|
|
|
|
if (i == allierte)
|
|
|
|
|
scat(" und ");
|
|
|
|
|
else
|
|
|
|
|
scat(", ");
|
|
|
|
|
}
|
|
|
|
|
dh = 1;
|
|
|
|
|
hh = 0;
|
|
|
|
|
scat(factionname(sf->faction));
|
|
|
|
|
scat(" (");
|
|
|
|
|
if (sf->status == HELP_ALL) {
|
|
|
|
|
scat("Alles");
|
|
|
|
|
} else
|
|
|
|
|
for (h = 1; h < HELP_ALL; h *= 2) {
|
|
|
|
|
if ((sf->status & h) == h)
|
|
|
|
|
switch (h) {
|
|
|
|
|
case HELP_MONEY:
|
|
|
|
|
scat("Silber");
|
|
|
|
|
hh = 1;
|
|
|
|
|
break;
|
|
|
|
|
case HELP_FIGHT:
|
|
|
|
|
if (hh)
|
|
|
|
|
scat(", ");
|
|
|
|
|
scat("K<EFBFBD>mpfe");
|
|
|
|
|
hh = 1;
|
|
|
|
|
break;
|
|
|
|
|
case HELP_OBSERVE:
|
|
|
|
|
if (hh)
|
|
|
|
|
scat(", ");
|
|
|
|
|
scat("Wahrnehmung");
|
|
|
|
|
hh = 1;
|
|
|
|
|
break;
|
|
|
|
|
case HELP_GIVE:
|
|
|
|
|
if (hh)
|
|
|
|
|
scat(", ");
|
|
|
|
|
scat("Gib");
|
|
|
|
|
hh = 1;
|
|
|
|
|
break;
|
|
|
|
|
case HELP_GUARD:
|
|
|
|
|
if (hh)
|
|
|
|
|
scat(", ");
|
|
|
|
|
scat("Bewache");
|
|
|
|
|
hh = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
scat(")");
|
|
|
|
|
}
|
|
|
|
|
sf = sf->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
allies(FILE * F, faction * f)
|
|
|
|
|
{
|
|
|
|
|
#ifdef GROUPS
|
|
|
|
|
group * g = f->groups;
|
|
|
|
|
#endif
|
|
|
|
|
if (f->allies) {
|
|
|
|
|
if (!f->allies->next) {
|
|
|
|
|
strcpy(buf, "Wir helfen der Partei ");
|
|
|
|
|
} else {
|
|
|
|
|
strcpy(buf, "Wir helfen den Parteien ");
|
|
|
|
|
}
|
|
|
|
|
alliances(f->allies);
|
|
|
|
|
scat(".");
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef GROUPS
|
|
|
|
|
while (g) {
|
|
|
|
|
if (g->allies) {
|
|
|
|
|
if (!g->allies->next) {
|
|
|
|
|
sprintf(buf, "%s hilft der Partei ", g->name);
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(buf, "%s hilft den Parteien ", g->name);
|
|
|
|
|
}
|
|
|
|
|
alliances(g->allies);
|
|
|
|
|
scat(".");
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
g = g->next;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
guards(FILE * F, region * r, faction * see)
|
|
|
|
|
{ /* die Partei see sieht dies; wegen
|
|
|
|
|
* "unbekannte Partei", wenn man es selbst ist... */
|
|
|
|
|
|
|
|
|
|
faction* guardians[512];
|
|
|
|
|
|
|
|
|
|
int nextguard = 0;
|
|
|
|
|
|
|
|
|
|
unit *u;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
boolean tarned = false;
|
|
|
|
|
/* Bewachung */
|
|
|
|
|
|
|
|
|
|
for (u = r->units; u; u = u->next)
|
|
|
|
|
if (getguard(u)) {
|
|
|
|
|
faction *f = u->faction;
|
|
|
|
|
|
|
|
|
|
if (f!=see && fval(u, FL_PARTEITARNUNG)) {
|
|
|
|
|
tarned=true;
|
|
|
|
|
} else {
|
|
|
|
|
for (i=0;i!=nextguard;++i) if (guardians[i]==f) break;
|
|
|
|
|
if (i==nextguard) {
|
|
|
|
|
guardians[nextguard++] = f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!nextguard && !tarned) return;
|
|
|
|
|
|
|
|
|
|
strcpy(buf, "Die Region wird von ");
|
|
|
|
|
|
|
|
|
|
for (i = 0; i!=nextguard+(tarned?1:0); ++i) {
|
|
|
|
|
if (i!=0) {
|
|
|
|
|
if (i == nextguard-(tarned?0:1))
|
|
|
|
|
scat(" und ");
|
|
|
|
|
else
|
|
|
|
|
scat(", ");
|
|
|
|
|
}
|
|
|
|
|
if (i<nextguard) scat(factionname(guardians[i]));
|
|
|
|
|
|
|
|
|
|
else scat("unbekannten Einheiten");
|
|
|
|
|
}
|
|
|
|
|
scat(" bewacht.");
|
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
rpline(FILE * F)
|
|
|
|
|
{
|
|
|
|
|
rpc(F, ' ', 1);
|
|
|
|
|
rpc(F, '-', REPORTWIDTH);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
fcompare(const void *a, const void *b)
|
|
|
|
|
{
|
|
|
|
|
faction * f1 = *(faction**)a;
|
|
|
|
|
faction * f2 = *(faction**)b;
|
|
|
|
|
if (f1->no>f2->no) return 1;
|
|
|
|
|
else if (f1->no<f2->no) return -1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
list_address(FILE * F, faction * uf)
|
|
|
|
|
{
|
|
|
|
|
faction *f;
|
|
|
|
|
void **fp;
|
|
|
|
|
cvector *fcts = malloc(sizeof(cvector));
|
|
|
|
|
|
|
|
|
|
cv_init(fcts);
|
|
|
|
|
for (f = factions; f; f = f->next) {
|
|
|
|
|
if (f->no != MONSTER_FACTION && kann_finden(uf, f) != 0) {
|
|
|
|
|
cv_pushback(fcts, f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
v_sort(fcts->begin, fcts->end, fcompare);
|
|
|
|
|
|
|
|
|
|
centre(F, "Liste aller Adressen", false);
|
|
|
|
|
rnl(F);
|
|
|
|
|
for (fp = fcts->begin; fp != fcts->end; ++fp) {
|
|
|
|
|
f = *fp;
|
|
|
|
|
sprintf(buf, "%s: %s; %s", factionname(f), f->email, f->banner);
|
|
|
|
|
rparagraph(F, buf, 4, '*');
|
|
|
|
|
}
|
|
|
|
|
rnl(F);
|
|
|
|
|
rpline(F);
|
|
|
|
|
free(cv_kill(fcts));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_building(FILE *F, const region * r, const building * b, const faction * f, int mode)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
unit *u;
|
|
|
|
|
attrib * a = a_find(b->attribs, &at_icastle);
|
|
|
|
|
const locale * lang = NULL;
|
|
|
|
|
const building_type * type = b->type;
|
|
|
|
|
|
|
|
|
|
if (f) lang = f->locale;
|
|
|
|
|
|
|
|
|
|
if (a!=NULL) {
|
|
|
|
|
type = ((icastle_data*)a->data.v)->type;
|
|
|
|
|
} else {
|
|
|
|
|
type = b->type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%s, Gr<47><72>e %d, %s", buildingname(b), b->size, buildingtype(b, b->size, lang));
|
|
|
|
|
if (b->size < type->maxsize) {
|
|
|
|
|
scat(" (im Bau)");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (b->besieged > 0 && mode>=see_lighthouse) {
|
|
|
|
|
scat(", belagert von ");
|
|
|
|
|
icat(b->besieged);
|
|
|
|
|
scat(" Personen ");
|
|
|
|
|
if (b->besieged >= b->size * SIEGEFACTOR) {
|
|
|
|
|
scat("(abgeschnitten)");
|
|
|
|
|
} else {
|
|
|
|
|
scat("(unvollst<73>ndig belagert)");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
i = 0;
|
|
|
|
|
if (b->display[0]) {
|
|
|
|
|
scat("; ");
|
|
|
|
|
scat(b->display);
|
|
|
|
|
i = b->display[strlen(b->display) - 1];
|
|
|
|
|
}
|
|
|
|
|
if (i != '!' && i != '?' && i != '.')
|
|
|
|
|
scat(".");
|
|
|
|
|
|
|
|
|
|
rparagraph(F, buf, 2, 0);
|
|
|
|
|
|
|
|
|
|
if (mode<see_lighthouse) return;
|
|
|
|
|
|
|
|
|
|
/* Leere Burgen verursachten sonst segfault! */
|
|
|
|
|
if(buildingowner(r,b) != NULL){
|
|
|
|
|
print_curses(F, b, TYP_BUILDING, b->attribs,
|
|
|
|
|
(buildingowner(r,b)->faction == f)? 1 : 0, 2);
|
|
|
|
|
} else {
|
|
|
|
|
print_curses(F, b, TYP_BUILDING, b->attribs, 0, 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (u = r->units; u; u = u->next)
|
|
|
|
|
if (u->building == b && fval(u, FL_OWNER)) {
|
|
|
|
|
rpunit(F, f, u, 6, mode);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for (u = r->units; u; u = u->next)
|
|
|
|
|
if (u->building == b && !fval(u, FL_OWNER))
|
|
|
|
|
rpunit(F, f, u, 6, mode);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
report(FILE *F, faction * f)
|
|
|
|
|
{
|
|
|
|
|
#ifndef NEW_ITEMS
|
|
|
|
|
potion_t potion;
|
|
|
|
|
#endif
|
|
|
|
|
int flag = 0;
|
|
|
|
|
char ch;
|
|
|
|
|
int dh;
|
|
|
|
|
int anyunits;
|
|
|
|
|
region *r;
|
|
|
|
|
building *b;
|
|
|
|
|
ship *sh;
|
|
|
|
|
unit *u;
|
|
|
|
|
attrib *a;
|
|
|
|
|
int wants_stats;
|
|
|
|
|
int wants_zugvorlage;
|
|
|
|
|
int wants_addresses;
|
|
|
|
|
seen_region * sd;
|
|
|
|
|
int ix;
|
|
|
|
|
unsigned char op;
|
|
|
|
|
char buf2[80];
|
|
|
|
|
ix = Pow(O_STATISTICS);
|
|
|
|
|
wants_stats = (f->options & ix);
|
|
|
|
|
ix = Pow(O_ZUGVORLAGE);
|
|
|
|
|
wants_zugvorlage = (f->options & ix);
|
|
|
|
|
ix = Pow(O_ADRESSEN);
|
|
|
|
|
wants_addresses = (f->options & ix);
|
|
|
|
|
|
|
|
|
|
if (quiet) {
|
|
|
|
|
printf(" NR");
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
printf(" - Schreibe Report\n");
|
|
|
|
|
|
|
|
|
|
centre(F, gamedate(), true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
sprintf(buf, "%s, %s/%s (%s)", factionname(f), race[f->race].name[1],
|
|
|
|
|
neue_gebiete[f->magiegebiet], f->email);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
|
|
|
|
|
buf[0] = 0;
|
|
|
|
|
dh = 0;
|
|
|
|
|
for(a=a_find(f->attribs, &at_faction_special); a; a=a->nexttype) {
|
|
|
|
|
dh++;
|
|
|
|
|
if(fspecials[a->data.sa[0]].levels) {
|
|
|
|
|
sprintf(buf2, "%s (%d)", fspecials[a->data.sa[0]].name, a->data.sa[1]);
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(buf2, "%s", fspecials[a->data.sa[0]].name);
|
|
|
|
|
}
|
|
|
|
|
if(dh > 1) strcat(buf, ", ");
|
|
|
|
|
strcat(buf, buf2);
|
|
|
|
|
}
|
|
|
|
|
if(dh > 0) centre(F, buf, true);
|
|
|
|
|
dh = 0;
|
|
|
|
|
|
|
|
|
|
if(f->karma > 0) {
|
|
|
|
|
sprintf(buf, "Deine Partei hat %d Karma.", f->karma);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (f->age <= 2) {
|
|
|
|
|
rnl(F);
|
2001-02-03 14:45:35 +01:00
|
|
|
|
sprintf(buf, "Dein Passwort lautet \"%s\".", f->passw);
|
|
|
|
|
centre(F, buf, true);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
sprintf(buf, "Bitte denke daran, deine Befehle mit dem Betreff"
|
|
|
|
|
" ERESSEA BEFEHLE an eressea@eressea.amber.kn-bremen.de zu senden."
|
|
|
|
|
" Am besten, du verwendest die Befehlsvorlage am Ende des Reports.");
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
sprintf(buf, "Die ersten beiden Z<>ge mu<6D>t du abgeben, sonst wird deine"
|
|
|
|
|
" Partei sofort wieder gel<65>scht, um Karteileichen zu vermeiden.");
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
sprintf(buf, "Mit der ersten Auswertung bekommst du einen Computerreport, "
|
|
|
|
|
"den du mit vielen der Tools auf http://eressea-pbem.de/download.html "
|
|
|
|
|
"benutzen kannst. Wenn du ihn weiterhin bekommen willst, gib einer "
|
|
|
|
|
"deiner Einheiten den Befehl OPTION COMPUTER");
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
}
|
|
|
|
|
rnl(F);
|
|
|
|
|
if (f->options & want(O_SCORE) && f->age > DISPLAYSCORE) {
|
|
|
|
|
sprintf(buf, "Deine Partei hat diese Woche %d Punkte.", f->score);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
sprintf(buf, "(Durchschnitt f<>r Parteien <20>hnlichen Alters ist %d Punkte)",
|
|
|
|
|
average_score_of_age(f->age, f->age / 24 + 1));
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
}
|
|
|
|
|
if (f->race == RC_HUMAN) {
|
|
|
|
|
sprintf(buf, "Deine Partei besteht aus %d Personen in %d Einheiten, davon sind %d Personen Migranten.",
|
|
|
|
|
count_all(f), f->no_units, count_migrants(f));
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
sprintf(buf, "Maximal kann Deine Partei %d Migranten aufnehmen.",
|
|
|
|
|
count_maxmigrants(f));
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(buf, "Deine Partei besteht aus %d Personen in %d Einheiten.", count_all(f),f->no_units);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (f->age > 1 && f->lastorders != turn) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
if (turn - f->lastorders == 1) {
|
|
|
|
|
centre(F, "Deine Partei hat letzte Runde keinen Zug abgegeben!", true);
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(buf,
|
|
|
|
|
"Deine Partei hat seit %d Runden keinen Zug abgegeben! Wenn du"
|
|
|
|
|
" drei Runden nacheinander keinen Zug abgibst, wird sie"
|
|
|
|
|
" automatisch gel<65>scht.",
|
|
|
|
|
turn - f->lastorders);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
}
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Insekten-Winter-Warnung */
|
|
|
|
|
if(f->race == RC_INSECT) {
|
|
|
|
|
if(season[month(1)] == 0) {
|
|
|
|
|
strcpy(buf, "Es ist Winter, und Insekten k<>nnen nur in W<>sten oder mit "
|
|
|
|
|
"Hilfe des Nestw<74>rme-Tranks Personen rekrutieren.");
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
} else if(season[month(2)] == 0) {
|
|
|
|
|
strcpy(buf, "Es ist Sp<53>therbst, und diese Woche ist die letzte vor dem "
|
|
|
|
|
"Winter, in der Insekten rekrutieren k<>nnen.");
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "Optionen:");
|
|
|
|
|
for (op = 0; op != MAXOPTIONS; op++) {
|
|
|
|
|
if (f->options & (int) pow(2, op)) {
|
|
|
|
|
scat(" ");
|
|
|
|
|
scat(options[op]);
|
|
|
|
|
flag++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (flag > 0) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
}
|
|
|
|
|
/* Der Report soll sp<73>ter einmal durch einen Makroprozessor laufen.
|
|
|
|
|
* (enno) was? wer hat das geschrieben?
|
|
|
|
|
* Momentan ist das wegen der der Mailverschickmimik schwierig. */
|
|
|
|
|
rp_messages(F, f->msgs, f, 0, true, true);
|
|
|
|
|
if(f->battles) {
|
|
|
|
|
struct bmsg * bm;
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, "K<EFBFBD>mpfe", false);
|
|
|
|
|
rnl(F);
|
|
|
|
|
for (bm=f->battles;bm;bm=bm->next) {
|
|
|
|
|
#if HAVE_SNPRINTF
|
|
|
|
|
snprintf(buf, 80, "In %s findet ein Kampf statt:",
|
|
|
|
|
translate_regions(regionid(bm->r), f));
|
|
|
|
|
#else
|
|
|
|
|
sprintf(buf, "In %s findet ein Kampf statt:",
|
|
|
|
|
translate_regions(regionid(bm->r), f));
|
|
|
|
|
buf[80]=0;
|
|
|
|
|
#endif
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
rp_messages(F, bm->msgs, f, 0, true, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
a = a_find(f->attribs, &at_reportspell);
|
|
|
|
|
if (a) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, "Neue Zauber", true);
|
|
|
|
|
while (a) {
|
|
|
|
|
report_spell(F, (spellid_t)a->data.i);
|
|
|
|
|
a = a->nexttype;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef NEW_ITEMS
|
|
|
|
|
ch = 0;
|
|
|
|
|
for (a=a_find(f->attribs, &at_showitem);a;a=a->nexttype) {
|
|
|
|
|
const potion_type * ptype = resource2potion(((const item_type*)a->data.v)->rtype);
|
|
|
|
|
requirement * m;
|
|
|
|
|
if (ptype==NULL) continue;
|
|
|
|
|
m = ptype->itype->construction->materials;
|
|
|
|
|
if (ch==0) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, "Erforschte Tr<54>nke", true);
|
|
|
|
|
ch = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, locale_string(f->locale, resourcename(ptype->itype->rtype, 0)), true);
|
|
|
|
|
sprintf(buf, "Stufe %d", ptype->level);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
sprintf(buf, "Ben<EFBFBD>tigte Kr<4B>uter: ");
|
|
|
|
|
while (m->number) {
|
|
|
|
|
scat(locale_string(f->locale, resourcename(oldresourcetype[m->type], 0)));
|
|
|
|
|
++m;
|
|
|
|
|
if (m->number) scat(", ");
|
|
|
|
|
}
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, ptype->text, true);
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
for (potion = 0; potion != MAXPOTIONS; potion++)
|
|
|
|
|
if (f->showpotion[potion] == 1)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (potion != MAXPOTIONS) {
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, "Erforschte Tr<54>nke", true);
|
|
|
|
|
|
|
|
|
|
for (potion = 0; potion != MAXPOTIONS; ++potion) {
|
|
|
|
|
if (f->showpotion[potion] == 1) {
|
|
|
|
|
int h;
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, potionnames[0][potion], true);
|
|
|
|
|
sprintf(buf, "Stufe %d", potionlevel[potion]);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
sprintf(buf, "Ben<EFBFBD>tigte Kr<4B>uter: ");
|
|
|
|
|
for (h = 0; h < MAXHERBSPERPOTION; h++) {
|
|
|
|
|
if (potionherbs[potion][h] == NOHERB)
|
|
|
|
|
break;
|
|
|
|
|
if (h > 0) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
}
|
|
|
|
|
scat(herbdata[0][potionherbs[potion][h]]);
|
|
|
|
|
}
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, (char *) potiontext[potion], true);
|
|
|
|
|
|
|
|
|
|
/* Nicht nochmal anzeigen! */
|
|
|
|
|
|
|
|
|
|
f->showpotion[potion] = 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, "Aktueller Status", false);
|
|
|
|
|
rnl(F);
|
|
|
|
|
|
|
|
|
|
allies(F, f);
|
|
|
|
|
|
|
|
|
|
rpline(F);
|
|
|
|
|
|
|
|
|
|
anyunits = 0;
|
|
|
|
|
|
|
|
|
|
for (sd = seen; sd!=NULL; sd = sd->next) {
|
|
|
|
|
boolean unit_in_region = false;
|
|
|
|
|
boolean durchgezogen_in_region = false;
|
|
|
|
|
int turm_sieht_region = false;
|
|
|
|
|
|
|
|
|
|
switch (sd->mode) {
|
|
|
|
|
case see_lighthouse:
|
|
|
|
|
turm_sieht_region = true;
|
|
|
|
|
break;
|
|
|
|
|
#ifdef SEE_FAR
|
|
|
|
|
case see_far:
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
case see_travel:
|
|
|
|
|
durchgezogen_in_region = true;
|
|
|
|
|
break;
|
|
|
|
|
case see_unit:
|
|
|
|
|
unit_in_region = true;
|
|
|
|
|
anyunits = true;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
r = sd->r;
|
|
|
|
|
/* Beschreibung */
|
|
|
|
|
|
|
|
|
|
if (unit_in_region) {
|
|
|
|
|
describe(F, r, 0, f);
|
|
|
|
|
if (rterrain(r) != T_OCEAN && rpeasants(r)/TRADE_FRACTION > 0) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
prices(F, r, f);
|
|
|
|
|
}
|
|
|
|
|
guards(F, r, f);
|
|
|
|
|
durchreisende(F, r, f);
|
|
|
|
|
}
|
|
|
|
|
#ifdef SEE_FAR
|
|
|
|
|
else if (sd->mode==see_far) {
|
|
|
|
|
describe(F, r, 3, f);
|
|
|
|
|
guards(F, r, f);
|
|
|
|
|
durchreisende(F, r, f);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
else if (turm_sieht_region) {
|
|
|
|
|
describe(F, r, 2, f);
|
|
|
|
|
durchreisende(F, r, f);
|
|
|
|
|
} else {
|
|
|
|
|
describe(F, r, 1, f);
|
|
|
|
|
durchreisende(F, r, f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Statistik */
|
|
|
|
|
|
|
|
|
|
if (wants_stats && unit_in_region == 1)
|
|
|
|
|
statistics(F, r, f);
|
|
|
|
|
|
|
|
|
|
/* Nachrichten an REGION in der Region */
|
|
|
|
|
|
|
|
|
|
if (unit_in_region || durchgezogen_in_region) {
|
|
|
|
|
rp_messages(F, r->msgs, f, 0, true, true);
|
|
|
|
|
}
|
|
|
|
|
/* Burgen und ihre Einheiten */
|
|
|
|
|
|
|
|
|
|
for (b = rbuildings(r); b; b = b->next) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
report_building(F, r, b, f, sd->mode);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Restliche Einheiten */
|
|
|
|
|
|
|
|
|
|
if (sd->mode>=see_lighthouse) {
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (!u->building && !u->ship) {
|
|
|
|
|
if ((u->faction == f) ||
|
|
|
|
|
(unit_in_region && cansee(f, r, u, 0)) ||
|
|
|
|
|
(durchgezogen_in_region && cansee(f, r, u, -1)) ||
|
|
|
|
|
#ifdef SEE_FAR
|
|
|
|
|
(sd->mode==see_far && cansee(f, r, u, -2)) ||
|
|
|
|
|
#endif
|
|
|
|
|
(turm_sieht_region && cansee(f, r, u, -2)))
|
|
|
|
|
{
|
|
|
|
|
if (dh == 0 && !(rbuildings(r) || r->ships)) {
|
|
|
|
|
dh = 1;
|
|
|
|
|
/* rnl(F); */
|
|
|
|
|
}
|
|
|
|
|
rpunit(F, f, u, 4, sd->mode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Schiffe und ihre Einheiten */
|
|
|
|
|
|
|
|
|
|
for (sh = r->ships; sh; sh = sh->next) {
|
|
|
|
|
int w = 0;
|
|
|
|
|
faction *of = NULL;
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
|
|
|
|
|
|
|
|
|
/* Gewicht feststellen */
|
|
|
|
|
|
|
|
|
|
for (u = r->units; u; u = u->next)
|
|
|
|
|
if (u->ship == sh && fval(u, FL_OWNER)) {
|
|
|
|
|
of = u->faction;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (of == f) {
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->ship == sh) {
|
|
|
|
|
w += weight(u);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sprintf(buf, "%s, %s, (%d/%d)",
|
|
|
|
|
shipname(sh),
|
|
|
|
|
sh->type->name[0],
|
|
|
|
|
(w + 99) / 100, /* +99 weil sonst die Nachkommastellen ignoriert w<>rden */
|
|
|
|
|
shipcapacity(sh) / 100);
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(buf, "%s, %s", shipname(sh), sh->type->name[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(sh->type->construction->improvement==NULL); /* sonst ist construction::size nicht ship_type::maxsize */
|
|
|
|
|
if (sh->size!=sh->type->construction->maxsize) {
|
|
|
|
|
scat(", im Bau (");
|
|
|
|
|
icat(sh->size);
|
|
|
|
|
scat("/");
|
|
|
|
|
icat(sh->type->construction->maxsize);
|
|
|
|
|
scat(")");
|
|
|
|
|
}
|
|
|
|
|
if (sh->damage) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
icat(sh->damage*100/(sh->size*DAMAGE_SCALE));
|
|
|
|
|
scat("% besch<63>digt");
|
|
|
|
|
}
|
|
|
|
|
if (rterrain(r) != T_OCEAN) {
|
|
|
|
|
if (sh->coast != NODIRECTION) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
scat(coasts[sh->coast]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ch = 0;
|
|
|
|
|
if (sh->display[0]) {
|
|
|
|
|
scat("; ");
|
|
|
|
|
scat(sh->display);
|
|
|
|
|
|
|
|
|
|
ch = sh->display[strlen(sh->display) - 1];
|
|
|
|
|
}
|
|
|
|
|
if (ch != '!' && ch != '?' && ch != '.')
|
|
|
|
|
scat(".");
|
|
|
|
|
|
|
|
|
|
rparagraph(F, buf, 2, 0);
|
|
|
|
|
|
|
|
|
|
/* Leere Schiffe verursachten sonst segfault! */
|
|
|
|
|
if(shipowner(r,sh) != NULL){
|
|
|
|
|
print_curses(F, sh, TYP_SHIP, sh->attribs,
|
|
|
|
|
(shipowner(r,sh)->faction == f)? 1 : 0, 2);
|
|
|
|
|
} else {
|
|
|
|
|
print_curses(F, sh, TYP_SHIP, sh->attribs, 0, 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (u = r->units; u; u = u->next)
|
|
|
|
|
if (u->ship == sh && fval(u, FL_OWNER)) {
|
|
|
|
|
rpunit(F, f, u, 6, sd->mode);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for (u = r->units; u; u = u->next)
|
|
|
|
|
if (u->ship == sh && !fval(u, FL_OWNER))
|
|
|
|
|
rpunit(F, f, u, 6, sd->mode);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
|
|
|
|
rpline(F);
|
|
|
|
|
}
|
|
|
|
|
if (f->no != MONSTER_FACTION) {
|
|
|
|
|
if (!anyunits) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, "Ungl<EFBFBD>cklicherweise wurde deine Partei ausgel<65>scht. "
|
|
|
|
|
"Du kannst gerne an einer anderen Stelle wieder "
|
|
|
|
|
"einsteigen. Melde Dich einfach wieder an.", 0, 0);
|
|
|
|
|
} else {
|
|
|
|
|
if (wants_addresses) {
|
|
|
|
|
list_address(F, f);
|
|
|
|
|
}
|
|
|
|
|
if (wants_zugvorlage) {
|
|
|
|
|
order_template(F, f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
puts("* Fehler: mailit konnte nicht ge<67>ffnet werden!");
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
region * r;
|
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
unit * u;
|
|
|
|
|
for (u=r->units;u;u=u->next) {
|
|
|
|
|
if (forbiddenid(u->no)) {
|
|
|
|
|
uunhash(u);
|
|
|
|
|
u->no = newunitid();
|
|
|
|
|
uhash(u);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern void init_intervals(void);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef USE_MERIAN
|
|
|
|
|
|
|
|
|
|
#define xp(r, f) ((region_x((r),(f)))*2 + region_y((r),(f)))
|
|
|
|
|
#define yp(r, f) (region_y((r),(f)))
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
merian(FILE * out, faction * f)
|
|
|
|
|
{
|
|
|
|
|
int x1 = INT_MAX, x2=INT_MIN, y1=INT_MAX, y2=INT_MIN;
|
|
|
|
|
region *left=0, *right=0, *top=0, *bottom=0;
|
|
|
|
|
char ** line;
|
|
|
|
|
char * c;
|
|
|
|
|
int y, xw;
|
|
|
|
|
|
|
|
|
|
seen_region * sd;
|
|
|
|
|
if (!seen) return;
|
|
|
|
|
for (sd = seen; sd!=NULL; sd = sd->next) {
|
|
|
|
|
region * r = sd->r;
|
|
|
|
|
if (r->planeid != 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (!left || xp(r, f)<xp(left, f)) left=r;
|
|
|
|
|
if (!right || xp(r, f)>xp(right, f)) right=r;
|
|
|
|
|
if (!top || yp(r, f)>yp(top, f)) top=r;
|
|
|
|
|
if (!bottom || yp(r, f)<yp(bottom, f)) bottom=r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!left) return; /* Keine normale Region gesehen */
|
|
|
|
|
|
|
|
|
|
x1 = xp(left, f);
|
|
|
|
|
x2 = xp(right, f)+1;
|
|
|
|
|
y1 = yp(bottom, f);
|
|
|
|
|
y2 = yp(top, f)+1;
|
|
|
|
|
|
|
|
|
|
xw = abs(x1); xw = max(xw, x2);
|
|
|
|
|
if (xw>99) xw = 3;
|
|
|
|
|
else if (xw>9) xw = 2;
|
|
|
|
|
else xw = 1;
|
|
|
|
|
|
|
|
|
|
fputs("CR-Version: 42\nMERIAN Version 1.02\nKartenart: Hex(Standard)\n\nLEGENDE\nHochland = H\nGletscher = G\nGebirge = B\nWald = W\nSumpf = S\nOzean = .\nW<EFBFBD>ste = D\nEbene = E\n\n", out);
|
|
|
|
|
|
|
|
|
|
line = (char**)calloc(1, (y2-y1)*sizeof(char*));
|
|
|
|
|
c = (char*)calloc(1, (y2-y1)*((x2-x1)*sizeof(char)+13));
|
|
|
|
|
memset(c, ' ', (y2-y1)*((x2-x1)*sizeof(char)+13));
|
|
|
|
|
{
|
|
|
|
|
int width = 1+x2-x1;
|
|
|
|
|
int lx = region_x(top, f) - (xp(top, f)-x1) / 2;
|
|
|
|
|
int i;
|
|
|
|
|
if ((y2-y1) % 2 ==0) ++lx;
|
|
|
|
|
|
|
|
|
|
fputs(" ", out);
|
|
|
|
|
for (i=0;i!=width;++i) {
|
|
|
|
|
int x = lx+((i+1)/2);
|
|
|
|
|
int o = abs(x1-y2);
|
|
|
|
|
if (i%2 == o % 2)
|
|
|
|
|
fprintf(out, "%c", (x<0)?'-':(x>0)?'+':' ');
|
|
|
|
|
else putc(' ', out);
|
|
|
|
|
}
|
|
|
|
|
putc('\n', out);
|
|
|
|
|
switch (xw) {
|
|
|
|
|
case 3:
|
|
|
|
|
fputs(" ", out);
|
|
|
|
|
for (i=0;i!=width;++i) {
|
|
|
|
|
int x = lx+((i+1)/2);
|
|
|
|
|
int o = abs(x1-y2);
|
|
|
|
|
if (i%2 == o % 2)
|
|
|
|
|
fprintf(out, "%c", (abs(x)/100)?((abs(x)/100)+'0'):' ');
|
|
|
|
|
else putc(' ', out);
|
|
|
|
|
}
|
|
|
|
|
putc('\n', out);
|
|
|
|
|
case 2:
|
|
|
|
|
fputs(" ", out);
|
|
|
|
|
for (i=0;i!=width;++i) {
|
|
|
|
|
int x = lx+((i+1)/2);
|
|
|
|
|
int o = abs(x1-y2);
|
|
|
|
|
if (i%2 == o % 2)
|
|
|
|
|
fprintf(out, "%c", (abs(x)%100)/10?((abs(x)%100)/10+'0'):(abs(x)<100?' ':'0'));
|
|
|
|
|
else putc(' ', out);
|
|
|
|
|
}
|
|
|
|
|
putc('\n', out);
|
|
|
|
|
default:
|
|
|
|
|
fputs(" ", out);
|
|
|
|
|
for (i=0;i!=width;++i) {
|
|
|
|
|
int x = lx+(i/2);
|
|
|
|
|
int o = abs(x1-y2);
|
|
|
|
|
if (i%2 == o % 2)
|
|
|
|
|
fprintf(out, "%c", abs(x)%10+'0');
|
|
|
|
|
else putc(' ', out);
|
|
|
|
|
}
|
|
|
|
|
putc('\n', out);
|
|
|
|
|
}
|
|
|
|
|
fputs(" ", out);
|
|
|
|
|
for (i=0;i!=width;++i) {
|
|
|
|
|
int o = abs(x1-y2);
|
|
|
|
|
if (i%2 == o % 2)
|
|
|
|
|
putc('/', out);
|
|
|
|
|
else putc(' ', out);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
putc('\n', out);
|
|
|
|
|
for (y=y1;y!=y2;++y) {
|
|
|
|
|
line[y-y1] = c + (y-y1)*((x2-x1)*sizeof(char)+13);
|
|
|
|
|
sprintf(line[y-y1], "%4d", y);
|
|
|
|
|
line[y-y1][4] = ' ';
|
|
|
|
|
sprintf(line[y-y1]+7+(x2-x1), "%4d", y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (sd = seen; sd!=NULL; sd = sd->next) {
|
|
|
|
|
region * r = sd->r;
|
|
|
|
|
|
|
|
|
|
if (getplane(r))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
line[yp(r, f)-y1][5+(xp(r, f)-x1)] = ' ';
|
|
|
|
|
line[yp(r, f)-y1][6+(xp(r, f)-x1)] = terrain[rterrain(r)].symbol;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* print header */
|
|
|
|
|
for (y=y1;y!=y2;++y) {
|
|
|
|
|
fputs(line[y2-y-1], out);
|
|
|
|
|
putc('\n', out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
int width = 1+x2-x1;
|
|
|
|
|
int lx = region_x(bottom, f) - (xp(bottom, f)-x1) / 2;
|
|
|
|
|
int i;
|
|
|
|
|
fputs(" ", out);
|
|
|
|
|
for (i=0;i!=width;++i) {
|
|
|
|
|
int o = abs(x1-y1);
|
|
|
|
|
if (i%2 == o % 2)
|
|
|
|
|
putc('/', out);
|
|
|
|
|
else putc(' ', out);
|
|
|
|
|
}
|
|
|
|
|
putc('\n', out);
|
|
|
|
|
fputs(" ", out);
|
|
|
|
|
for (i=0;i!=width;++i) {
|
|
|
|
|
int x = lx+((i+1)/2);
|
|
|
|
|
int o = abs(x1-y1);
|
|
|
|
|
if (i%2 == o % 2)
|
|
|
|
|
fprintf(out, "%c", (x<0)?'-':(x>0)?'+':' ');
|
|
|
|
|
else putc(' ', out);
|
|
|
|
|
}
|
|
|
|
|
putc('\n', out);
|
|
|
|
|
switch (xw) {
|
|
|
|
|
case 3:
|
|
|
|
|
fputs(" ", out);
|
|
|
|
|
for (i=0;i!=width;++i) {
|
|
|
|
|
int x = lx+((i+1)/2);
|
|
|
|
|
int o = abs(x1-y1);
|
|
|
|
|
if (i%2 == o % 2)
|
|
|
|
|
fprintf(out, "%c", (abs(x)/100)?((abs(x)/100)+'0'):' ');
|
|
|
|
|
else putc(' ', out);
|
|
|
|
|
}
|
|
|
|
|
putc('\n', out);
|
|
|
|
|
case 2:
|
|
|
|
|
fputs(" ", out);
|
|
|
|
|
for (i=0;i!=width;++i) {
|
|
|
|
|
int x = lx+((i+1)/2);
|
|
|
|
|
int o = abs(x1-y1);
|
|
|
|
|
if (i%2 == o % 2)
|
|
|
|
|
fprintf(out, "%c", (abs(x)%100)/10?((abs(x)%100)/10+'0'):(abs(x)<100?' ':'0'));
|
|
|
|
|
else putc(' ', out);
|
|
|
|
|
}
|
|
|
|
|
putc('\n', out);
|
|
|
|
|
default:
|
|
|
|
|
fputs(" ", out);
|
|
|
|
|
for (i=0;i!=width;++i) {
|
|
|
|
|
int x = lx+((i+1)/2);
|
|
|
|
|
int o = abs(x1-y1);
|
|
|
|
|
if (i%2 == o % 2)
|
|
|
|
|
fprintf(out, "%c", abs(x)%10+'0');
|
|
|
|
|
else putc(' ', out);
|
|
|
|
|
}
|
|
|
|
|
putc('\n', out);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
free(c);
|
|
|
|
|
free(line);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
seen_region * seen;
|
|
|
|
|
seen_region * reuse;
|
|
|
|
|
seen_region** append;
|
|
|
|
|
seen_region * last;
|
|
|
|
|
|
|
|
|
|
#define MAXSEEHASH 4095
|
|
|
|
|
seen_region * seehash[MAXSEEHASH];
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
seen_done(void)
|
|
|
|
|
{
|
|
|
|
|
while (seen) {
|
|
|
|
|
seen_region * r = seen;
|
|
|
|
|
seen = seen->next;
|
|
|
|
|
free(r);
|
|
|
|
|
}
|
|
|
|
|
while (reuse) {
|
|
|
|
|
seen_region * r = reuse;
|
|
|
|
|
reuse = reuse->next;
|
|
|
|
|
free(r);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if FAST_SEEN
|
|
|
|
|
static void
|
|
|
|
|
init_intervals()
|
|
|
|
|
{
|
|
|
|
|
region * r;
|
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
unit * u;
|
|
|
|
|
attrib * a;
|
|
|
|
|
for (a=a_find(r->attribs, &at_travelunit);a;a=a->nexttype) {
|
|
|
|
|
unit * v = (unit*)a->data.v;
|
|
|
|
|
faction * f = v->faction;
|
|
|
|
|
if (!f) continue;
|
|
|
|
|
if (!f->first)
|
|
|
|
|
{
|
|
|
|
|
assert(!f->last);
|
|
|
|
|
f->first = r;
|
|
|
|
|
}
|
|
|
|
|
f->last = r->next;
|
|
|
|
|
}
|
|
|
|
|
for (a=a_find(r->attribs, &at_lighthouse);a;a=a->nexttype) {
|
|
|
|
|
building * b = (building*)a->data.v;
|
|
|
|
|
region * br = b->region;
|
|
|
|
|
if (!b->region) continue;
|
|
|
|
|
for (u=br->units;u;u=u->next) {
|
|
|
|
|
faction * f = u->faction;
|
|
|
|
|
if (!f->first)
|
|
|
|
|
{
|
|
|
|
|
assert(!f->last);
|
|
|
|
|
f->first = r;
|
|
|
|
|
}
|
|
|
|
|
f->last = r->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (u=r->units;u;u=u->next) {
|
|
|
|
|
faction * f = u->faction;
|
|
|
|
|
if (!f->first)
|
|
|
|
|
{
|
|
|
|
|
assert(!f->last);
|
|
|
|
|
f->first = r;
|
|
|
|
|
}
|
|
|
|
|
f->last = r->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static boolean
|
|
|
|
|
add_seen(region * r, unsigned char mode, boolean dis)
|
|
|
|
|
{
|
|
|
|
|
seen_region * find;
|
|
|
|
|
|
|
|
|
|
int index = abs((r->x & 0xffff) + ((r->y) << 16)) % MAXSEEHASH;
|
|
|
|
|
for (find=seehash[index];find;find=find->nextHash) {
|
|
|
|
|
if (find->r==r) {
|
|
|
|
|
if (find->mode < mode) {
|
|
|
|
|
if (find->mode<=see_neighbour && find->next) {
|
|
|
|
|
find->next->prev = find->prev;
|
|
|
|
|
if (find->prev) find->prev->next = find->next;
|
|
|
|
|
else seen = find->next;
|
|
|
|
|
last->next = find;
|
|
|
|
|
find->prev = last;
|
|
|
|
|
find->next = NULL;
|
|
|
|
|
last = find;
|
|
|
|
|
append = &last->next;
|
|
|
|
|
}
|
|
|
|
|
find->mode = mode;
|
|
|
|
|
find->disbelieves |= dis;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!reuse) reuse = (seen_region*)calloc(1, sizeof(seen_region));
|
|
|
|
|
*append = reuse;
|
|
|
|
|
reuse = reuse->next;
|
|
|
|
|
(*append)->next = NULL;
|
|
|
|
|
(*append)->prev = last;
|
|
|
|
|
if (last) last->next = *append;
|
|
|
|
|
last = *append;
|
|
|
|
|
(*append)->nextHash = seehash[index];
|
|
|
|
|
seehash[index] = *append;
|
|
|
|
|
(*append)->r = r;
|
|
|
|
|
(*append)->mode = mode;
|
|
|
|
|
(*append)->disbelieves = dis;
|
|
|
|
|
append = &(*append)->next;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define DBG_CACHE 1
|
|
|
|
|
#if DBG_CACHE
|
|
|
|
|
int chits = 0;
|
|
|
|
|
int ctries = 0;
|
|
|
|
|
#endif
|
|
|
|
|
static void
|
|
|
|
|
prepare_report(faction * f)
|
|
|
|
|
{
|
|
|
|
|
region * r;
|
|
|
|
|
region * end = lastregion(f);
|
|
|
|
|
|
|
|
|
|
append = &reuse;
|
|
|
|
|
memset(seehash, 0, sizeof(seehash));
|
|
|
|
|
while (*append) append = &(*append)->next;
|
|
|
|
|
*append = seen;
|
|
|
|
|
seen = NULL;
|
|
|
|
|
last = NULL;
|
|
|
|
|
append = &seen;
|
|
|
|
|
for (r = firstregion(f); r != end; r = r->next)
|
|
|
|
|
{
|
|
|
|
|
attrib *ru;
|
|
|
|
|
unit * u;
|
|
|
|
|
unsigned char mode = see_none;
|
|
|
|
|
boolean dis = false;
|
|
|
|
|
#if DBG_CACHE
|
|
|
|
|
++ctries;
|
|
|
|
|
#endif
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->faction == f) {
|
|
|
|
|
if (u->race != RC_SPELL || u->number == RS_FARVISION) {
|
|
|
|
|
mode = see_unit;
|
|
|
|
|
if (fval(u, FL_DISBELIEVES)) {
|
|
|
|
|
dis = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mode==see_none) 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 && rterrain(r) == T_OCEAN) {
|
|
|
|
|
if (check_leuchtturm(r, f)) mode = see_lighthouse;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mode == see_none)
|
|
|
|
|
continue;
|
|
|
|
|
#if DBG_CACHE
|
|
|
|
|
else ++chits;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
add_seen(r, mode, dis);
|
|
|
|
|
/* nicht, wenn Verwirrung herrscht: */
|
|
|
|
|
if (!is_cursed(r->attribs, C_REGCONF, 0)) {
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
#ifdef SEE_FAR
|
|
|
|
|
if (!b) {
|
|
|
|
|
if (add_seen(r2, see_far, false)) {
|
|
|
|
|
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(r3, see_neighbour, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
if (!b) add_seen(r2, see_neighbour, false);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#if DBG_CACHE
|
|
|
|
|
if (!quiet)
|
|
|
|
|
printf(" - cache hits: %.2f%%\n", 100*chits/(double)ctries);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define FMAXHASH 1023
|
|
|
|
|
|
|
|
|
|
struct fsee {
|
|
|
|
|
struct fsee * nexthash;
|
|
|
|
|
faction * f;
|
|
|
|
|
struct see {
|
|
|
|
|
struct see * next;
|
|
|
|
|
faction * seen;
|
|
|
|
|
unit * proof;
|
|
|
|
|
} * see;
|
|
|
|
|
} * fsee[FMAXHASH];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
reports(void)
|
|
|
|
|
{
|
|
|
|
|
faction *f;
|
|
|
|
|
region *r;
|
|
|
|
|
boolean gotit;
|
|
|
|
|
FILE *shfp, *F, *BAT;
|
|
|
|
|
int wants_report, wants_computer_report,
|
|
|
|
|
wants_compressed, wants_bzip2;
|
|
|
|
|
|
|
|
|
|
nmr_warnings();
|
|
|
|
|
#ifdef DMALLOC
|
|
|
|
|
assert(dmalloc_verify ( NULL ));
|
|
|
|
|
#endif
|
2001-02-03 14:45:35 +01:00
|
|
|
|
makedir(reportpath(), 0700);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-01-27 19:15:52 +01:00
|
|
|
|
if (global.data_version<BASE36_VERSION) base36conversion();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* <20>ffnet file BAT (mailit batch file) */
|
|
|
|
|
|
|
|
|
|
BAT = openbatch();
|
|
|
|
|
|
|
|
|
|
wants_report = 1 << O_REPORT;
|
|
|
|
|
wants_computer_report = 1 << O_COMPUTER;
|
|
|
|
|
wants_compressed = 1 << O_COMPRESS;
|
|
|
|
|
wants_bzip2 = 1 << O_BZIP2;
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
invert_list(&r->msgs);
|
|
|
|
|
}
|
|
|
|
|
report_donations();
|
|
|
|
|
#if FAST_SEEN
|
|
|
|
|
init_intervals();
|
|
|
|
|
#endif
|
|
|
|
|
remove_empty_units();
|
|
|
|
|
for (f = factions; f; f = f->next) {
|
|
|
|
|
struct bmsg * b;
|
|
|
|
|
attrib * a = a_find(f->attribs, &at_reportspell);
|
|
|
|
|
for (b = f->battles;b;b=b->next)
|
|
|
|
|
invert_list(&b->msgs);
|
|
|
|
|
invert_list(&f->battles);
|
|
|
|
|
current_faction = f;
|
|
|
|
|
gotit = false;
|
|
|
|
|
|
|
|
|
|
if (quiet) {
|
|
|
|
|
printf("Reports f<>r %s: ", factionname(f));
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
}
|
|
|
|
|
else printf("%s\n", factionname(f));
|
|
|
|
|
prepare_report(f);
|
|
|
|
|
invert_list(&f->msgs);
|
|
|
|
|
if (!nonr && (f->options & wants_report))
|
|
|
|
|
{
|
|
|
|
|
sprintf(buf, "%s/%s.nr", reportpath(), factionid(f));
|
|
|
|
|
F = cfopen(buf, "wt");
|
|
|
|
|
if (F) {
|
|
|
|
|
report(F, f);
|
|
|
|
|
fclose(F);
|
|
|
|
|
gotit = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!nocr && (f->options & wants_computer_report || f->age<3))
|
|
|
|
|
{
|
|
|
|
|
sprintf(buf, "%s/%s.cr", reportpath(), factionid(f));
|
|
|
|
|
F = cfopen(buf, "wt");
|
|
|
|
|
if (F) {
|
|
|
|
|
report_computer(F, f);
|
|
|
|
|
fclose(F);
|
|
|
|
|
gotit = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (f->email && BAT) {
|
2001-02-04 14:20:12 +01:00
|
|
|
|
sprintf(buf, "%s/%s.sh", reportpath(), factionid(f));
|
|
|
|
|
shfp = fopen(buf, "w");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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");
|
2001-02-04 14:20:12 +01:00
|
|
|
|
fprintf(shfp,"\taddr=%s\n", f->email);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fprintf(shfp,"fi\n\n");
|
|
|
|
|
|
2001-02-04 14:20:12 +01:00
|
|
|
|
fprintf(BAT, "\n\ndate;echo %s\n", f->email);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
if (f->options & wants_compressed) {
|
|
|
|
|
|
|
|
|
|
if(f->age == 1) {
|
|
|
|
|
fprintf(BAT, "ls %s.nr %s.cr ../newbie.txt | zip -m -j -9 -@ %s.zip\n",
|
|
|
|
|
factionid(f), factionid(f), factionid(f));
|
|
|
|
|
} else {
|
|
|
|
|
fprintf(BAT, "ls %s.nr %s.cr | zip -m -j -9 -@ %s.zip\n",
|
|
|
|
|
factionid(f), factionid(f), factionid(f));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(shfp, "eresseamail.zipped $addr \"%s %s\" \"%s-%d.zip\" "
|
|
|
|
|
"%s.zip\n", global.gamename, gamedate_short(), factionid(f), turn, factionid(f));
|
|
|
|
|
|
|
|
|
|
} else if(f->options & wants_bzip2) {
|
|
|
|
|
|
|
|
|
|
if (f->age == 1) {
|
|
|
|
|
fprintf(shfp,
|
|
|
|
|
" \\\n\t\"text/plain\" \"Willkommen\" ../newbie.txt");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(BAT, "bzip2 -9v `ls %s.nr %s.cr`\n",
|
|
|
|
|
factionid(f), factionid(f));
|
|
|
|
|
|
|
|
|
|
fprintf(shfp, "eresseamail.bzip2 $addr \"%s %s\"", global.gamename, gamedate_short());
|
|
|
|
|
|
|
|
|
|
if (!nonr && f->options & wants_report)
|
|
|
|
|
fprintf(shfp,
|
|
|
|
|
" \\\n\t\"application/x-bzip2\" \"Report\" %s.nr.bz2",
|
|
|
|
|
factionid(f));
|
|
|
|
|
|
|
|
|
|
if (!nocr && (f->options & wants_computer_report || f->age<3))
|
|
|
|
|
fprintf(shfp,
|
|
|
|
|
" \\\n\t\"application/x-bzip2\" \"Computer-Report\" %s.cr.bz2",
|
|
|
|
|
factionid(f));
|
|
|
|
|
#ifdef USE_MERIAN
|
|
|
|
|
if (!nomer && f->options & wants_merian)
|
|
|
|
|
fprintf(shfp,
|
|
|
|
|
" \\\n\t\"application/x-bzip2\" \"Merian-Karte\" %s.mer.bz2",
|
|
|
|
|
factionid(f));
|
|
|
|
|
#endif
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
fprintf(shfp, MAIL " $addr \"%s %s\"", global.gamename, gamedate_short());
|
|
|
|
|
|
|
|
|
|
if (f->age == 1) {
|
|
|
|
|
fprintf(shfp,
|
|
|
|
|
" \\\n\t\"text/plain\" \"Willkommen\" ../newbie.txt");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!nonr && f->options & wants_report)
|
|
|
|
|
fprintf(shfp,
|
|
|
|
|
" \\\n\t\"text/plain\" \"Report\" %s.nr",
|
|
|
|
|
factionid(f));
|
|
|
|
|
|
|
|
|
|
if (!nocr && (f->options & wants_computer_report || f->age<3))
|
|
|
|
|
fprintf(shfp,
|
|
|
|
|
" \\\n\t\"text/x-eressea-cr\" \"Computer-Report\" %s.cr",
|
|
|
|
|
factionid(f));
|
|
|
|
|
}
|
|
|
|
|
|
2001-02-04 14:20:12 +01:00
|
|
|
|
fprintf(BAT, ". %s.sh %s\n", factionid(f), f->email);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fclose(shfp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!gotit)
|
|
|
|
|
printf("* Fehler: Kein Report f<>r Partei Nr. %s!\n",
|
|
|
|
|
factionid(f));
|
|
|
|
|
while (a) {
|
|
|
|
|
attrib * a_old = a;
|
|
|
|
|
a = a->nexttype;
|
|
|
|
|
a_remove(&f->attribs, a_old);
|
|
|
|
|
}
|
|
|
|
|
if (quiet)
|
|
|
|
|
printf("\n");
|
|
|
|
|
}
|
|
|
|
|
/* schliesst BAT und verschickt Zeitungen und Kommentare */
|
|
|
|
|
current_faction = NULL;
|
|
|
|
|
seen_done();
|
|
|
|
|
closebatch(BAT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
reports_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)
|
|
|
|
|
{
|
|
|
|
|
int key = f->no % FMAXHASH;
|
|
|
|
|
struct fsee * fs = fsee[key];
|
|
|
|
|
struct see * ss;
|
|
|
|
|
if (f==f2) return f->units;
|
|
|
|
|
while (fs && fs->f!=f) fs=fs->nexthash;
|
|
|
|
|
if (!fs) return NULL;
|
|
|
|
|
ss=fs->see;
|
|
|
|
|
while (ss && ss->seen!=f2) ss=ss->next;
|
|
|
|
|
if (ss) {
|
|
|
|
|
assert(ss->proof->faction==f2);
|
|
|
|
|
return ss->proof;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
add_find(faction * f, unit * u)
|
|
|
|
|
{
|
|
|
|
|
/* faction f sees f2 through u */
|
|
|
|
|
faction * f2 = u->faction;
|
|
|
|
|
int key = f->no % FMAXHASH;
|
|
|
|
|
struct fsee ** fp = &fsee[key];
|
|
|
|
|
struct fsee * fs;
|
|
|
|
|
struct see ** sp;
|
|
|
|
|
struct see * ss;
|
|
|
|
|
while (*fp && (*fp)->f!=f) fp=&(*fp)->nexthash;
|
|
|
|
|
if (!*fp) {
|
|
|
|
|
fs = *fp = calloc(sizeof(struct fsee), 1);
|
|
|
|
|
fs->f = f;
|
|
|
|
|
} else fs = *fp;
|
|
|
|
|
sp = &fs->see;
|
|
|
|
|
while (*sp && (*sp)->seen!=f2) sp=&(*sp)->next;
|
|
|
|
|
if (!*sp) {
|
|
|
|
|
ss = *sp = calloc(sizeof(struct see), 1);
|
|
|
|
|
ss->proof = u;
|
|
|
|
|
ss->seen = f2;
|
|
|
|
|
} else ss = *sp;
|
|
|
|
|
ss->proof = u;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
update_find(void)
|
|
|
|
|
{
|
|
|
|
|
region * r;
|
|
|
|
|
static boolean initial = true;
|
|
|
|
|
|
|
|
|
|
if (initial) for (r=regions;r;r=r->next) {
|
|
|
|
|
unit * u;
|
|
|
|
|
for (u=r->units;u;u=u->next) {
|
|
|
|
|
faction * lastf = u->faction;
|
|
|
|
|
unit * u2;
|
|
|
|
|
for (u2=r->units;u2;u2=u2->next) {
|
|
|
|
|
if (u2->faction==lastf || u2->faction==u->faction)
|
|
|
|
|
continue;
|
|
|
|
|
if (seefaction(u->faction, r, u2, 0)) {
|
|
|
|
|
lastf=u2->faction;
|
|
|
|
|
add_find(u->faction, u2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
initial = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boolean
|
|
|
|
|
kann_finden(faction * f1, faction * f2)
|
|
|
|
|
{
|
|
|
|
|
update_find();
|
|
|
|
|
return (boolean)(can_find(f1, f2)!=NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******* summary *******/
|
|
|
|
|
int dropouts[2];
|
|
|
|
|
int * age = NULL;
|
|
|
|
|
|
|
|
|
|
typedef struct summary {
|
|
|
|
|
int waffen;
|
|
|
|
|
int factions;
|
|
|
|
|
int artefakte;
|
|
|
|
|
int ruestungen;
|
|
|
|
|
int schiffe;
|
|
|
|
|
int gebaeude;
|
|
|
|
|
int maxskill;
|
|
|
|
|
int inhabitedregions;
|
|
|
|
|
int peasants;
|
|
|
|
|
int peasantmoney;
|
|
|
|
|
int nunits;
|
|
|
|
|
int playerpop;
|
|
|
|
|
int playermoney;
|
|
|
|
|
int armed_men;
|
|
|
|
|
int poprace[MAXRACES];
|
|
|
|
|
int factionrace[MAXRACES];
|
|
|
|
|
int landregionen;
|
|
|
|
|
int regionen_mit_spielern;
|
|
|
|
|
int landregionen_mit_spielern;
|
|
|
|
|
int orkifizierte_regionen;
|
|
|
|
|
int spielerpferde;
|
|
|
|
|
int pferde;
|
|
|
|
|
} summary;
|
|
|
|
|
|
|
|
|
|
summary *
|
|
|
|
|
make_summary(boolean count_new)
|
|
|
|
|
{
|
|
|
|
|
char sk;
|
|
|
|
|
faction *f;
|
|
|
|
|
region *r;
|
|
|
|
|
unit *u;
|
|
|
|
|
summary * s = calloc(1, sizeof(summary));
|
|
|
|
|
|
|
|
|
|
for (f = factions; f; f = f->next) {
|
|
|
|
|
f->nregions = 0;
|
|
|
|
|
f->nunits = 0;
|
|
|
|
|
f->number = 0;
|
|
|
|
|
f->money = 0;
|
|
|
|
|
if (count_new == true || f->age > 0) s->factions++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Alles z<>hlen */
|
|
|
|
|
|
|
|
|
|
for (r = regions; r; r = r->next) {
|
|
|
|
|
s->pferde += rhorses(r);
|
|
|
|
|
s->schiffe += listlen(r->ships);
|
|
|
|
|
s->gebaeude += listlen(r->buildings);
|
|
|
|
|
if (rterrain(r) != T_OCEAN) {
|
|
|
|
|
s->landregionen++;
|
|
|
|
|
if (r->units) {
|
|
|
|
|
s->landregionen_mit_spielern++;
|
|
|
|
|
}
|
|
|
|
|
if (fval(r, RF_ORCIFIED)) {
|
|
|
|
|
s->orkifizierte_regionen++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (r->units) {
|
|
|
|
|
s->regionen_mit_spielern++;
|
|
|
|
|
}
|
|
|
|
|
if (rpeasants(r) || r->units) {
|
|
|
|
|
s->inhabitedregions++;
|
|
|
|
|
s->peasants += rpeasants(r);
|
|
|
|
|
s->peasantmoney += rmoney(r);
|
|
|
|
|
|
|
|
|
|
/* Einheiten Info. nregions darf nur einmal pro Partei
|
|
|
|
|
* incrementiert werden. */
|
|
|
|
|
|
|
|
|
|
for (u = r->units; u; u = u->next) freset(u->faction, FL_DH);
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
f = u->faction;
|
|
|
|
|
if (u->faction->no != MONSTER_FACTION) {
|
|
|
|
|
s->nunits++;
|
|
|
|
|
s->playerpop += u->number;
|
|
|
|
|
s->spielerpferde += get_item(u, I_HORSE);
|
|
|
|
|
s->playermoney += get_money(u);
|
|
|
|
|
s->armed_men += armedmen(u);
|
|
|
|
|
s->waffen += get_item(u, I_SWORD);
|
|
|
|
|
s->waffen += get_item(u, I_SPEAR);
|
|
|
|
|
s->waffen += get_item(u, I_CATAPULT);
|
|
|
|
|
s->waffen += get_item(u, I_CROSSBOW);
|
|
|
|
|
s->waffen += get_item(u, I_LONGBOW);
|
|
|
|
|
s->waffen += get_item(u, I_RUNESWORD);
|
|
|
|
|
|
|
|
|
|
s->ruestungen += get_item(u, I_CHAIN_MAIL);
|
|
|
|
|
s->ruestungen += get_item(u, I_PLATE_ARMOR);
|
|
|
|
|
|
|
|
|
|
#ifdef COMPATIBILITY
|
|
|
|
|
s->ruestungen += get_item(u, I_CLOAK_OF_INVULNERABILITY);
|
|
|
|
|
|
|
|
|
|
s->artefakte += get_item(u, I_AMULET_OF_DARKNESS);
|
|
|
|
|
s->artefakte += get_item(u, I_AMULET_OF_HEALING);
|
|
|
|
|
s->artefakte += get_item(u, I_CLOAK_OF_INVULNERABILITY);
|
|
|
|
|
s->artefakte += get_item(u, I_SHIELDSTONE);
|
|
|
|
|
s->artefakte += get_item(u, I_STAFF_OF_FIRE);
|
|
|
|
|
s->artefakte += get_item(u, I_STAFF_OF_LIGHTNING);
|
|
|
|
|
s->artefakte += get_item(u, I_WAND_OF_TELEPORTATION);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
s->artefakte += get_item(u, I_AMULET_OF_TRUE_SEEING);
|
|
|
|
|
s->artefakte += get_item(u, I_RING_OF_INVISIBILITY);
|
|
|
|
|
s->artefakte += get_item(u, I_RING_OF_POWER);
|
|
|
|
|
s->artefakte += get_item(u, I_RUNESWORD);
|
|
|
|
|
|
|
|
|
|
s->spielerpferde += get_item(u, I_HORSE);
|
|
|
|
|
|
|
|
|
|
for (sk = 0; sk < MAXSKILLS; sk++) {
|
|
|
|
|
int aktskill;
|
|
|
|
|
aktskill = eff_skill(u, sk, r);
|
|
|
|
|
if (aktskill > s->maxskill) s->maxskill = aktskill;
|
|
|
|
|
}
|
|
|
|
|
if (!fval(f, FL_DH)) {
|
|
|
|
|
f->nregions++;
|
|
|
|
|
fset(f, FL_DH);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f->nunits++;
|
|
|
|
|
f->number += u->number;
|
|
|
|
|
f->money += get_money(u);
|
|
|
|
|
s->poprace[u->race] += u->number;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* jetzt noch parteienweise z<>hlen */
|
|
|
|
|
/* Problem mit Monsterpartei ... */
|
|
|
|
|
for (f = factions; f; f = f->next) if (f->no!=MONSTER_FACTION) {
|
|
|
|
|
if (count_new == true || f->age > 0) s->factionrace[f->race]++;
|
|
|
|
|
}
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
|
pcomp(int i, int j)
|
|
|
|
|
{
|
|
|
|
|
sprintf(buf, "%d (%s%d)", i, (i>=j)?"+":"", i-j);
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
|
rcomp(int i, int j)
|
|
|
|
|
{
|
|
|
|
|
sprintf(buf, "%d (%s%d,%s%d%%)",
|
|
|
|
|
i, (i>=j)?"+":"", i-j, (i>=j)?"+":"",j?((i-j)*100)/j:0);
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
writemonument(void)
|
|
|
|
|
{
|
|
|
|
|
FILE * F;
|
|
|
|
|
region *r;
|
|
|
|
|
building *b;
|
|
|
|
|
building *buildings[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
|
|
|
|
int size[7] = {0,0,0,0,0,0,0};
|
|
|
|
|
int i, j, ra;
|
|
|
|
|
int count = 0;
|
|
|
|
|
unit *owner;
|
|
|
|
|
|
|
|
|
|
for (r = regions; r; r = r->next) {
|
|
|
|
|
for (b = r->buildings; b; b = b->next) {
|
|
|
|
|
if (b->type == &bt_monument && b->display && *b->display) {
|
|
|
|
|
freset(b, FL_DH);
|
|
|
|
|
count++;
|
|
|
|
|
if(b->size > size[6]) {
|
|
|
|
|
for(i=0; i <= 6; i++) if(b->size >= size[i]) {
|
|
|
|
|
for(j=5;j >= i; j--) {
|
|
|
|
|
size[j+1] = size[j];
|
|
|
|
|
buildings[j+1] = buildings[j];
|
|
|
|
|
}
|
|
|
|
|
buildings[i] = b;
|
|
|
|
|
size[i] = b->size;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(i=0; i <= 6; i++) if(buildings[i]) {
|
|
|
|
|
fset(buildings[i], FL_DH);
|
|
|
|
|
}
|
2001-01-28 09:50:46 +01:00
|
|
|
|
{
|
|
|
|
|
char zText[MAX_PATH];
|
|
|
|
|
sprintf(zText, "%s/news-monument", basepath());
|
|
|
|
|
F = cfopen(zText, "w");
|
|
|
|
|
if (!F) return;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fprintf(F, "\n--- maintitle ---\n\n");
|
|
|
|
|
for(i = 0; i<=6; i++) {
|
|
|
|
|
if (buildings[i] != NULL) {
|
|
|
|
|
fprintf(F, "In %s", rname(buildings[i]->region, NULL));
|
|
|
|
|
if ((owner=buildingowner(buildings[i]->region,buildings[i]))!=NULL && !fval(owner,FL_PARTEITARNUNG)) {
|
|
|
|
|
fprintf(F, ", Eigent<6E>mer: %s", factionname(owner->faction));
|
|
|
|
|
}
|
|
|
|
|
fprintf(F, "\n\n");
|
|
|
|
|
report_building(F, buildings[i]->region, buildings[i], findfaction(0), see_neighbour);
|
|
|
|
|
fprintf(F, "\n\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(F, "\n--- newcomer ---\n\n");
|
|
|
|
|
|
|
|
|
|
if(count > 7) {
|
|
|
|
|
ra = rand()%(count-7);
|
|
|
|
|
j = 0;
|
|
|
|
|
for (r = regions; r; r = r->next) {
|
|
|
|
|
for (b = r->buildings; b; b = b->next) {
|
|
|
|
|
if (b->type == &bt_monument && b->display && *b->display && !fval(b, FL_DH)) {
|
|
|
|
|
j++;
|
|
|
|
|
if(j == ra) {
|
|
|
|
|
fprintf(F, "In %s", rname(b->region, NULL));
|
|
|
|
|
if ((owner=buildingowner(b->region,b))!=NULL && !fval(owner,FL_PARTEITARNUNG)) {
|
|
|
|
|
fprintf(F, ", Eigent<6E>mer: %s", factionname(owner->faction));
|
|
|
|
|
}
|
|
|
|
|
fprintf(F, "\n\n");
|
|
|
|
|
report_building(F, b->region, b, findfaction(0), see_neighbour);
|
|
|
|
|
fprintf(F, "\n\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fclose(F);
|
|
|
|
|
|
|
|
|
|
#ifdef OLD_ITEMS
|
2001-01-28 09:50:46 +01:00
|
|
|
|
{
|
|
|
|
|
char zText[MAX_PATH];
|
|
|
|
|
sprintf(zText, "%s/news-silly", basepath());
|
|
|
|
|
F = cfopen(zText, "w");
|
|
|
|
|
if (!F) return;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for (f=factions;f;f=f->next) {
|
|
|
|
|
unit * u;
|
|
|
|
|
int k;
|
|
|
|
|
int count = 0;
|
|
|
|
|
for (u=f->units;u;u=u->nextF) {
|
|
|
|
|
count += get_herb(u, h);
|
|
|
|
|
}
|
|
|
|
|
for (i=0;i!=3;++i) if (count<fjord[i].size) break;
|
|
|
|
|
if (i) {
|
|
|
|
|
for (k=0;k<i-1;++k) fjord[k] = fjord[k+1];
|
|
|
|
|
fjord[i-1].size=count;
|
|
|
|
|
fjord[i-1].f=f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fprintf(F, "\n\nBesitzer der gr<67><72>ten %shaufen:\n", herbdata[0][h]);
|
|
|
|
|
for (i=0;i!=3;++i) {
|
|
|
|
|
fprintf(F, " %s (%d St<53>ck)\n", factionname(fjord[2-i].f), fjord[2-i].size);
|
|
|
|
|
}
|
|
|
|
|
fclose(F);
|
|
|
|
|
#else
|
|
|
|
|
printf("!! news-silly not implemented\n");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-31 00:16:17 +01:00
|
|
|
|
static void
|
|
|
|
|
writeadresses()
|
|
|
|
|
{
|
|
|
|
|
faction *f;
|
|
|
|
|
FILE * F;
|
|
|
|
|
char zText[MAX_PATH];
|
|
|
|
|
sprintf(zText, "%s/adressen", basepath());
|
|
|
|
|
F = cfopen(zText, "w");
|
|
|
|
|
if (!F) return;
|
|
|
|
|
|
|
|
|
|
/* adressen liste */
|
|
|
|
|
|
|
|
|
|
for (f = factions; f; f = f->next) {
|
|
|
|
|
if (f->no != MONSTER_FACTION) {
|
|
|
|
|
fprintf(F, "%s:%s:%s\n", factionname(f), f->email, f->banner);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fclose(F);
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static void
|
|
|
|
|
writeforward(void)
|
|
|
|
|
{
|
|
|
|
|
FILE *forwardFile;
|
|
|
|
|
region *r;
|
|
|
|
|
unit *u;
|
|
|
|
|
|
2001-01-28 09:50:46 +01:00
|
|
|
|
{
|
|
|
|
|
char zText[MAX_PATH];
|
|
|
|
|
sprintf(zText, "%s/aliases", basepath());
|
|
|
|
|
forwardFile = cfopen(zText, "w");
|
|
|
|
|
if (!forwardFile) return;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
for (r = regions; r; r = r->next) {
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->faction->no != MONSTER_FACTION) {
|
|
|
|
|
fprintf(forwardFile,"einheit-%s: %s\n", unitid(u), u->faction->email);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fclose(forwardFile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_summary(summary * s, summary * o, boolean full)
|
|
|
|
|
{
|
2001-01-31 00:16:17 +01:00
|
|
|
|
FILE * F = NULL;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
int i, newplayers = 0;
|
|
|
|
|
faction * f;
|
|
|
|
|
int nmrs[ORDERGAP];
|
|
|
|
|
|
2001-01-28 09:50:46 +01:00
|
|
|
|
{
|
|
|
|
|
char zText[MAX_PATH];
|
|
|
|
|
if (full) {
|
|
|
|
|
sprintf(zText, "%s/parteien.full", basepath());
|
|
|
|
|
} else {
|
2001-02-04 14:20:12 +01:00
|
|
|
|
sprintf(zText, "%s/parteien", basepath());
|
2001-01-28 09:50:46 +01:00
|
|
|
|
}
|
|
|
|
|
F = cfopen(zText, "w");
|
|
|
|
|
if (!F) return;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
printf("Schreibe Zusammenfassung (parteien)...\n");
|
|
|
|
|
fprintf(F, "%s\n%s\n\n", global.gamename, gamedate2());
|
|
|
|
|
fprintf(F, "Auswertung Nr: %d\n", turn);
|
|
|
|
|
fprintf(F, "Parteien: %s\n", pcomp(s->factions, o->factions));
|
|
|
|
|
fprintf(F, "Einheiten: %s\n\n", pcomp(s->nunits, o->nunits));
|
|
|
|
|
fprintf(F, "Spielerpopulation: %s\n",
|
|
|
|
|
pcomp(s->playerpop, o->playerpop));
|
|
|
|
|
fprintf(F, " davon bewaffnet: %s\n",
|
|
|
|
|
pcomp(s->armed_men, o->armed_men));
|
|
|
|
|
|
|
|
|
|
if (full) {
|
|
|
|
|
fprintf(F, "Regionen: %d\n", listlen(regions));
|
|
|
|
|
fprintf(F, "Bewohnte Regionen: %d\n", s->inhabitedregions);
|
|
|
|
|
fprintf(F, "Landregionen: %d\n", s->landregionen);
|
|
|
|
|
fprintf(F, "Spielerregionen: %d\n", s->regionen_mit_spielern);
|
|
|
|
|
fprintf(F, "Landspielerregionen: %d\n", s->landregionen_mit_spielern);
|
|
|
|
|
fprintf(F, "Orkifizierte Regionen: %d\n\n", s->orkifizierte_regionen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i <= RC_AQUARIAN ; i++) if (s->factionrace[i] && !nonplayer_race(i)) {
|
|
|
|
|
fprintf(F, "%14sv<73>lker: %s\n",
|
|
|
|
|
race[i].name[3], pcomp(s->factionrace[i], o->factionrace[i]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(F, "\n");
|
|
|
|
|
|
|
|
|
|
if (full) {
|
|
|
|
|
for (i = 0; i < MAXRACES; i++) if (s->poprace[i]) {
|
|
|
|
|
fprintf(F, "%20s: %s\n",race[i].name[1],
|
|
|
|
|
rcomp(s->poprace[i],o->poprace[i]));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
for (i = 0; i <= RC_AQUARIAN; i++) if (s->poprace[i] && !nonplayer_race(i)) {
|
|
|
|
|
fprintf(F, "%20s: %s\n",race[i].name[1],
|
|
|
|
|
rcomp(s->poprace[i],o->poprace[i]));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (full) {
|
|
|
|
|
fprintf(F, "\nWaffen: %s\n", pcomp(s->waffen,o->waffen));
|
|
|
|
|
fprintf(F, "R<EFBFBD>stungen: %s\n",
|
|
|
|
|
pcomp(s->ruestungen,o->ruestungen));
|
|
|
|
|
fprintf(F, "ungez<EFBFBD>hmte Pferde: %s\n", pcomp(s->pferde, o->pferde));
|
|
|
|
|
fprintf(F, "gez<EFBFBD>hmte Pferde: %s\n",
|
|
|
|
|
pcomp(s->spielerpferde,o->spielerpferde));
|
|
|
|
|
fprintf(F, "Artefakte: %s\n", pcomp(s->artefakte,o->artefakte));
|
|
|
|
|
fprintf(F, "Schiffe: %s\n", pcomp(s->schiffe, o->schiffe));
|
|
|
|
|
fprintf(F, "Geb<EFBFBD>ude: %s\n", pcomp(s->gebaeude, o->gebaeude));
|
|
|
|
|
|
|
|
|
|
fprintf(F, "\nBauernpopulation: %s\n", pcomp(s->peasants,o->peasants));
|
|
|
|
|
|
|
|
|
|
fprintf(F, "Population gesamt: %d\n\n", s->playerpop+s->peasants);
|
|
|
|
|
|
|
|
|
|
fprintf(F, "Reichtum Spieler: $%s\n",
|
|
|
|
|
pcomp(s->playermoney,o->playermoney));
|
|
|
|
|
fprintf(F, "Reichtum Bauern: $%s\n",
|
|
|
|
|
pcomp(s->peasantmoney, o->peasantmoney));
|
|
|
|
|
fprintf(F, "Reichtum gesamt: $%d\n\n", s->playermoney+s->peasantmoney);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(F, "\n\n");
|
|
|
|
|
|
|
|
|
|
for (i = 0; i != ORDERGAP; i++) {
|
|
|
|
|
nmrs[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (f = factions; f; f = f->next) {
|
|
|
|
|
if (f->age <= 1 && turn - f->lastorders == 1) {
|
|
|
|
|
newplayers++;
|
|
|
|
|
} else if (f->no != MONSTER_FACTION) {
|
|
|
|
|
nmrs[min(ORDERGAP-1,turn-f->lastorders)]++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i != ORDERGAP; i++) {
|
|
|
|
|
fprintf(F, "%d %s:\t\t %d\n", i,
|
|
|
|
|
i != 1 ? "NMRs" : "NMR ", nmrs[i]);
|
|
|
|
|
}
|
|
|
|
|
if (age) {
|
|
|
|
|
if (age[2] != 0) {
|
|
|
|
|
fprintf(F, "Erstabgaben:\t %d%%\n", 100 - (dropouts[0] * 100 / age[2]));
|
|
|
|
|
}
|
|
|
|
|
if (age[3] != 0) {
|
|
|
|
|
fprintf(F, "Zweitabgaben:\t %d%%\n", 100 - (dropouts[1] * 100 / age[3]));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fprintf(F, "Neue Spieler:\t %d\n", newplayers);
|
|
|
|
|
|
|
|
|
|
if (factions)
|
|
|
|
|
fprintf(F, "\nParteien:\n\n");
|
|
|
|
|
|
|
|
|
|
for (f = factions; f; f = f->next)
|
|
|
|
|
fprintf(F, "%s (%.3s/%.3s), %d Einh., %d Pers., $%d, %d %s\n",
|
|
|
|
|
factionname(f), race[f->race].name[0], neue_gebiete[f->magiegebiet],
|
|
|
|
|
f->nunits, f->number, f->money,
|
|
|
|
|
turn - f->lastorders,
|
|
|
|
|
turn - f->lastorders != 1 ? "NMRs" : "NMR ");
|
|
|
|
|
|
|
|
|
|
fclose(F);
|
|
|
|
|
|
2001-01-31 00:16:17 +01:00
|
|
|
|
if (full) {
|
|
|
|
|
FILE * F;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#ifdef PLAYER_CSV
|
|
|
|
|
region * r;
|
|
|
|
|
#endif
|
|
|
|
|
printf("Schreibe Liste der Adressen (adressen)...\n");
|
2001-01-31 00:16:17 +01:00
|
|
|
|
writeadresses();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
writeforward();
|
|
|
|
|
|
2001-01-28 09:50:46 +01:00
|
|
|
|
{
|
2001-01-31 00:16:17 +01:00
|
|
|
|
char zText[MAX_PATH];
|
2001-01-28 09:50:46 +01:00
|
|
|
|
sprintf(zText, "%s/datum", basepath());
|
|
|
|
|
F = cfopen(zText, "w");
|
2001-01-31 00:16:17 +01:00
|
|
|
|
if (!F) return;
|
2001-01-28 09:50:46 +01:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
printf("Schreibe Datum (datum)...\n");
|
|
|
|
|
fputs(gamedate2(), F);
|
|
|
|
|
fclose(F);
|
2001-01-31 00:16:17 +01:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#ifdef PLAYER_CSV
|
2001-01-28 09:50:46 +01:00
|
|
|
|
{
|
|
|
|
|
strcpy(zText, "%s/players", basepath());
|
|
|
|
|
F = cfopen(zText, "w");
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (!F) return;
|
|
|
|
|
printf("Schreibe Spielerliste (players)...\n");
|
|
|
|
|
r = findregion(0, 0);
|
|
|
|
|
if (r) for (f=factions;f;f=f->next) {
|
|
|
|
|
fputs("id;name;email;info;age;x;y;nmr;score;race;magic;units;people;money", F);
|
|
|
|
|
fprintf(F, "%s;\"%s\";\"%s\";\"%s\";\"%s\";%d;%d;%d;%d;%d;"
|
|
|
|
|
"\"%s\";\"%s\";"
|
|
|
|
|
"%d;%d;%d\n",
|
|
|
|
|
factionid(f), f->name, f->email, f->banner, f->passw, f->age, region_x(r, f), region_y(r, f), turn-f->lastorders, f->score,
|
|
|
|
|
race[f->race].name[0], neue_gebiete[f->magiegebiet],
|
|
|
|
|
f->nunits, f->number, f->money);
|
|
|
|
|
}
|
|
|
|
|
fclose(F);
|
|
|
|
|
#endif
|
|
|
|
|
writemonument();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/******* end summary ******/
|