2001-01-25 10:37:55 +01:00
|
|
|
|
/* vi: set ts=2:
|
|
|
|
|
*
|
2001-04-16 16:34:19 +02:00
|
|
|
|
*
|
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)
|
|
|
|
|
*
|
|
|
|
|
* This program may not be used, modified or distributed without
|
|
|
|
|
* prior permission by the authors of Eressea.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define FAST_SEEN 0
|
|
|
|
|
#define INDENT 0
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
2001-02-10 11:40:12 +01:00
|
|
|
|
#include <eressea.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-02-10 11:40:12 +01:00
|
|
|
|
/* modules includes */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include <modules/score.h>
|
2002-09-02 22:36:12 +02:00
|
|
|
|
#ifdef ALLIANCES
|
|
|
|
|
#include <modules/alliance.h>
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-02-10 11:40:12 +01:00
|
|
|
|
/* attributes includes */
|
|
|
|
|
#include <attributes/overrideroads.h>
|
2002-03-29 05:23:51 +01:00
|
|
|
|
#include <attributes/viewrange.h>
|
2001-04-14 14:11:45 +02:00
|
|
|
|
#include <attributes/otherfaction.h>
|
2001-02-28 23:14:59 +01:00
|
|
|
|
#ifdef AT_OPTION
|
|
|
|
|
# include <attributes/option.h>
|
|
|
|
|
#endif
|
2001-02-10 11:40:12 +01:00
|
|
|
|
|
|
|
|
|
/* gamecode includes */
|
|
|
|
|
#include "creation.h"
|
2001-04-26 19:41:06 +02:00
|
|
|
|
#include "creport.h"
|
2001-02-10 11:40:12 +01:00
|
|
|
|
#include "economy.h"
|
|
|
|
|
#include "monster.h"
|
|
|
|
|
#include "laws.h"
|
|
|
|
|
|
|
|
|
|
/* kernel includes */
|
|
|
|
|
#include <alchemy.h>
|
|
|
|
|
#include <border.h>
|
|
|
|
|
#include <build.h>
|
|
|
|
|
#include <building.h>
|
|
|
|
|
#include <faction.h>
|
|
|
|
|
#include <group.h>
|
|
|
|
|
#include <item.h>
|
|
|
|
|
#include <karma.h>
|
|
|
|
|
#include <magic.h>
|
|
|
|
|
#include <message.h>
|
|
|
|
|
#include <movement.h>
|
|
|
|
|
#include <objtypes.h>
|
|
|
|
|
#include <plane.h>
|
|
|
|
|
#include <pool.h>
|
|
|
|
|
#include <race.h>
|
|
|
|
|
#include <region.h>
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#include <render.h>
|
2001-02-10 11:40:12 +01:00
|
|
|
|
#include <reports.h>
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#include <resources.h>
|
2001-02-10 11:40:12 +01:00
|
|
|
|
#include <save.h>
|
|
|
|
|
#include <ship.h>
|
|
|
|
|
#include <skill.h>
|
|
|
|
|
#include <teleport.h>
|
|
|
|
|
#include <unit.h>
|
2001-04-29 21:27:42 +02:00
|
|
|
|
#ifdef USE_UGROUPS
|
|
|
|
|
# include <ugroup.h>
|
|
|
|
|
#endif
|
2001-02-10 11:40:12 +01:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* util includes */
|
2002-03-29 05:23:51 +01:00
|
|
|
|
#include <functions.h>
|
2001-02-10 11:40:12 +01:00
|
|
|
|
#include <goodies.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include <base36.h>
|
2001-02-24 13:50:51 +01:00
|
|
|
|
#include <nrmessage.h>
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
#include <translation.h>
|
2001-02-24 13:50:51 +01:00
|
|
|
|
#include <util/message.h>
|
2001-04-14 14:11:45 +02:00
|
|
|
|
#include <log.h>
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* libc includes */
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdio.h>
|
2001-04-26 19:41:06 +02:00
|
|
|
|
#include <time.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <limits.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
extern int quiet;
|
|
|
|
|
|
|
|
|
|
boolean nocr = false;
|
|
|
|
|
boolean nonr = false;
|
|
|
|
|
boolean nomer = false;
|
2002-02-16 11:37:18 +01:00
|
|
|
|
boolean noreports = false;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* -------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
extern int *storms;
|
|
|
|
|
|
|
|
|
|
char **seasonnames;
|
|
|
|
|
char **weeknames;
|
|
|
|
|
char **weeknames2;
|
|
|
|
|
char **monthnames;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
int *month_season;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
char *agename;
|
|
|
|
|
int seasons;
|
|
|
|
|
extern int weeks_per_month;
|
|
|
|
|
extern int months_per_year;
|
|
|
|
|
|
2001-02-05 17:11:59 +01:00
|
|
|
|
int
|
|
|
|
|
read_datenames(const char *filename)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
FILE *namesFP;
|
|
|
|
|
char line[256];
|
|
|
|
|
int i, l;
|
|
|
|
|
|
|
|
|
|
if( (namesFP=fopen(filename,"r")) == NULL) {
|
2001-04-14 14:11:45 +02:00
|
|
|
|
log_error(("Kann Datei '%s' nicht <20>ffnen, Abbruch\n", filename));
|
2001-02-05 17:11:59 +01:00
|
|
|
|
return -1;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fgets(line,255,namesFP);
|
|
|
|
|
l = strlen(line)-1;
|
|
|
|
|
if(line[l] == '\n') line[l] = 0;
|
2002-07-23 09:23:28 +02:00
|
|
|
|
agename = strdup(mkname("calendar", line));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
fgets(line,255,namesFP);
|
|
|
|
|
seasons = strtol(line, NULL, 10);
|
|
|
|
|
seasonnames = malloc(sizeof(char *) * seasons);
|
|
|
|
|
|
2001-02-05 17:11:59 +01:00
|
|
|
|
for (i=0;i<seasons;i++) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fgets(line,255,namesFP);
|
|
|
|
|
l = strlen(line)-1;
|
|
|
|
|
if(line[l] == '\n') line[l] = 0;
|
2002-07-23 09:23:28 +02:00
|
|
|
|
seasonnames[i] = strdup(mkname("calendar", line));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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,":");
|
2002-07-23 09:23:28 +02:00
|
|
|
|
weeknames[i] = strdup(mkname("calendar", np));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
np = strtok(NULL,":");
|
2002-07-23 09:23:28 +02:00
|
|
|
|
weeknames2[i] = strdup(mkname("calendar", np));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fgets(line,255,namesFP);
|
|
|
|
|
months_per_year = strtol(line, NULL, 10);
|
|
|
|
|
monthnames = malloc(sizeof(char *) * months_per_year);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
month_season = malloc(sizeof(int) * months_per_year);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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,":");
|
2002-07-23 09:23:28 +02:00
|
|
|
|
monthnames[i] = strdup(mkname("calendar", np));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
month_season[i] = atoi(strtok(NULL,":"));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
storms[i] = atoi(strtok(NULL,":"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fclose(namesFP);
|
2001-02-05 17:11:59 +01:00
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
int
|
|
|
|
|
season(int turn)
|
|
|
|
|
{
|
|
|
|
|
int year,month;
|
|
|
|
|
int t = turn - FIRST_TURN;
|
|
|
|
|
|
|
|
|
|
year = t/(months_per_year * weeks_per_month) + 1;
|
|
|
|
|
month = (t - (year-1) * months_per_year * weeks_per_month)/weeks_per_month;
|
|
|
|
|
|
2002-11-10 15:46:21 +01:00
|
|
|
|
assert(month >= 0 && month < months_per_year);
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
return month_season[month];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
static char *
|
2001-04-22 07:36:50 +02:00
|
|
|
|
gamedate(const struct locale * lang)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
int year,month,week,r;
|
|
|
|
|
static char buf[256];
|
|
|
|
|
int t = turn - FIRST_TURN;
|
|
|
|
|
|
|
|
|
|
if (t<0) t = turn;
|
2001-04-22 07:36:50 +02:00
|
|
|
|
assert(lang);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
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;
|
2001-04-22 07:36:50 +02:00
|
|
|
|
sprintf(buf, LOC(lang, "nr_calendar"),
|
2002-07-23 09:23:28 +02:00
|
|
|
|
LOC(lang, weeknames[week]),
|
|
|
|
|
LOC(lang, monthnames[month]),
|
|
|
|
|
LOC(lang, year),
|
|
|
|
|
LOC(lang, agename));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
static char *
|
|
|
|
|
gamedate_season(const struct locale * lang)
|
|
|
|
|
{
|
|
|
|
|
int year,month,week,r;
|
|
|
|
|
static char buf[256];
|
|
|
|
|
int t = turn - FIRST_TURN;
|
|
|
|
|
|
|
|
|
|
if (t<0) t = turn;
|
|
|
|
|
assert(lang);
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
sprintf(buf, LOC(lang, "nr_calendar_season"),
|
2002-07-23 09:23:28 +02:00
|
|
|
|
LOC(lang, weeknames[week]),
|
|
|
|
|
LOC(lang, monthnames[month]),
|
2001-12-10 01:13:39 +01:00
|
|
|
|
year,
|
2002-07-23 09:23:28 +02:00
|
|
|
|
LOC(lang, agename),
|
2001-12-10 01:13:39 +01:00
|
|
|
|
LOC(lang, seasonnames[month_season[month]]));
|
|
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *
|
2002-07-28 13:51:24 +02:00
|
|
|
|
gamedate2(const struct locale * lang)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
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 */
|
2001-04-22 07:36:50 +02:00
|
|
|
|
sprintf(buf, "in %s des Monats %s im Jahre %d %s.",
|
2002-07-28 13:51:24 +02:00
|
|
|
|
LOC(lang, weeknames2[week]),
|
|
|
|
|
LOC(lang, monthnames[month]),
|
|
|
|
|
year,
|
|
|
|
|
LOC(lang, agename));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
static char *
|
2002-07-28 13:51:24 +02:00
|
|
|
|
gamedate_short(const struct locale * lang)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
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 */
|
|
|
|
|
|
2002-07-28 13:51:24 +02:00
|
|
|
|
sprintf(buf, "%d/%s/%d", week+1, LOC(lang, monthnames[month]), year);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
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
|
2001-12-10 01:13:39 +01:00
|
|
|
|
report_spell(FILE * F, spellid_t id, const struct locale * lang)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
int k, itemanz, res, costtyp;
|
|
|
|
|
int dh = 0;
|
|
|
|
|
spell *sp = find_spellbyid(id);
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
2002-05-01 21:08:32 +02:00
|
|
|
|
centre(F, spell_name(sp, lang), true);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rnl(F);
|
|
|
|
|
strcpy(buf,"Beschreibung:");
|
|
|
|
|
rps(F, buf);
|
2002-05-01 21:08:32 +02:00
|
|
|
|
rparagraph(F, spell_info(sp, lang), 0, 0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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){
|
2001-12-10 01:13:39 +01:00
|
|
|
|
sprintf(buf, " %d %s", itemanz, LOC(lang, resname(res, itemanz!=1)));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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("\"");
|
2002-05-01 21:08:32 +02:00
|
|
|
|
scat(spell_name(sp, lang));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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;
|
2002-09-02 22:36:12 +02:00
|
|
|
|
#define FRIEND (HELP_GUARD|HELP_MONEY)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for(f=factions;f;f=f->next) {
|
|
|
|
|
if(f->no != MONSTER_FACTION && (turn-f->lastorders) >= 2) {
|
|
|
|
|
for(fa=factions;fa;fa=fa->next) {
|
2002-09-02 22:36:12 +02:00
|
|
|
|
if (alliedfaction(NULL, f, fa, FRIEND) && alliedfaction(NULL, fa, f, FRIEND)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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
|
2002-05-10 18:49:31 +02:00
|
|
|
|
print_curses(FILE *F, const faction *viewer, const void * obj, typ_t typ, int indent)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2002-05-10 18:09:07 +02:00
|
|
|
|
attrib *a = NULL;
|
|
|
|
|
int self = 0;
|
|
|
|
|
region *r;
|
|
|
|
|
|
|
|
|
|
/* Die Sichtbarkeit eines Zaubers und die Zaubermeldung sind bei
|
|
|
|
|
* Geb<EFBFBD>uden und Schiffen je nach, ob man Besitzer ist, verschieden.
|
|
|
|
|
* Bei Einheiten sieht man Wirkungen auf eigene Einheiten immer.
|
|
|
|
|
* Spezialf<EFBFBD>lle (besonderes Talent, verursachender Magier usw. werde
|
|
|
|
|
* bei jedem curse gesondert behandelt. */
|
|
|
|
|
if (typ == TYP_SHIP){
|
|
|
|
|
ship * sh = (ship*)obj;
|
|
|
|
|
unit * owner;
|
|
|
|
|
a = sh->attribs;
|
|
|
|
|
r = sh->region;
|
|
|
|
|
if((owner = shipowner(r,sh)) != NULL){
|
|
|
|
|
if (owner->faction == viewer){
|
|
|
|
|
self = 2;
|
|
|
|
|
} else { /* steht eine person der Partei auf dem Schiff? */
|
|
|
|
|
unit *u = NULL;
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->ship == sh) {
|
|
|
|
|
self = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (typ == TYP_BUILDING) {
|
|
|
|
|
building * b = (building*)obj;
|
|
|
|
|
unit * owner;
|
|
|
|
|
a = b->attribs;
|
|
|
|
|
r = b->region;
|
|
|
|
|
if((owner = buildingowner(r,b)) != NULL){
|
|
|
|
|
if (owner->faction == viewer){
|
|
|
|
|
self = 2;
|
|
|
|
|
} else { /* steht eine Person der Partei in der Burg? */
|
|
|
|
|
unit *u = NULL;
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->building == b) {
|
|
|
|
|
self = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (typ == TYP_UNIT) {
|
|
|
|
|
unit *u = (unit *)obj;
|
|
|
|
|
a = u->attribs;
|
|
|
|
|
r = u->region;
|
|
|
|
|
if (u->faction == viewer){
|
|
|
|
|
self = 2;
|
|
|
|
|
}
|
|
|
|
|
} else if (typ == TYP_REGION) {
|
|
|
|
|
r = (region *)obj;
|
|
|
|
|
a = r->attribs;
|
|
|
|
|
} else {
|
|
|
|
|
/* fehler */
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for(;a;a=a->next) {
|
|
|
|
|
int dh = 0;
|
|
|
|
|
|
|
|
|
|
if (fval(a->type, ATF_CURSE)) {
|
|
|
|
|
curse *c = (curse *)a->data.v;
|
2002-05-11 21:09:33 +02:00
|
|
|
|
if (c->type->curseinfo) {
|
2002-05-11 22:38:34 +02:00
|
|
|
|
if (c->type->cansee) {
|
2002-05-11 19:08:54 +02:00
|
|
|
|
self = c->type->cansee(viewer, obj, typ, c, self);
|
|
|
|
|
}
|
2002-05-10 18:09:07 +02:00
|
|
|
|
dh = c->type->curseinfo(viewer->locale, obj, typ, c, self);
|
2002-05-11 21:09:33 +02:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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;
|
2001-04-16 16:34:19 +02:00
|
|
|
|
sprintf(buf, "Auf der Einheit lieg%s %d Wirkung%s %s.",
|
2001-01-25 10:37:55 +01:00
|
|
|
|
(data->value==1 ? "t" : "en"),
|
2001-04-16 16:34:19 +02:00
|
|
|
|
data->value,
|
2001-01-25 10:37:55 +01:00
|
|
|
|
(data->value==1 ? "" : "en"),
|
2001-05-27 12:11:36 +02:00
|
|
|
|
LOC(default_locale, resourcename(data->type->itype->rtype, 0)));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, buf, indent, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
char *
|
2001-12-10 01:13:39 +01:00
|
|
|
|
replace_global_coords(const char *s, const faction * f)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
rpunit(FILE * F, const faction * f, const unit * u, int indent, int mode)
|
|
|
|
|
{
|
2001-12-10 01:13:39 +01:00
|
|
|
|
attrib *a_otherfaction;
|
|
|
|
|
char marker;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
strlist *S;
|
|
|
|
|
int dh;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
faction *fv;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
boolean isbattle = (boolean)(mode == see_battle);
|
2001-04-29 21:27:42 +02:00
|
|
|
|
#ifdef USE_UGROUPS
|
2001-04-28 17:39:13 +02:00
|
|
|
|
ugroup *ug = findugroup(u);
|
2001-04-29 21:27:42 +02:00
|
|
|
|
#endif
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if(u->race == new_race[RC_SPELL]) return;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-04-29 21:27:42 +02:00
|
|
|
|
#ifdef USE_UGROUPS
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if(u->faction != f && (isbattle || ug)) {
|
2001-04-28 17:39:13 +02:00
|
|
|
|
if(is_ugroupleader(u, ug)) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
dh = bufunit_ugroupleader(f, u, indent, mode);
|
|
|
|
|
} else {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2001-04-29 21:27:42 +02:00
|
|
|
|
} else
|
|
|
|
|
#endif
|
|
|
|
|
{
|
2001-04-28 17:39:13 +02:00
|
|
|
|
rnl(F);
|
|
|
|
|
dh = bufunit(f, u, indent, mode);
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
|
|
|
|
a_otherfaction = a_find(u->attribs, &at_otherfaction);
|
|
|
|
|
fv = visible_faction(f,u);
|
|
|
|
|
|
|
|
|
|
if(u->faction == f) {
|
|
|
|
|
marker = '*';
|
|
|
|
|
} else {
|
2002-03-24 10:40:50 +01:00
|
|
|
|
if(a_otherfaction && f != u->faction && get_otherfaction(a_otherfaction) == f
|
2001-12-10 01:13:39 +01:00
|
|
|
|
&& !fval(u, FL_PARTEITARNUNG)) {
|
|
|
|
|
marker = '!';
|
|
|
|
|
} else {
|
|
|
|
|
if(dh && !fval(u, FL_PARTEITARNUNG)) {
|
|
|
|
|
marker = '+';
|
|
|
|
|
} else {
|
|
|
|
|
marker = '-';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rparagraph(F, buf, indent, marker);
|
2001-04-28 17:39:13 +02:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if(!isbattle){
|
2001-04-29 21:27:42 +02:00
|
|
|
|
#ifdef USE_UGROUPS
|
2001-04-28 17:39:13 +02:00
|
|
|
|
if(ug) {
|
|
|
|
|
int i;
|
|
|
|
|
for(i=0; i<ug->members; i++) {
|
2002-05-10 18:49:31 +02:00
|
|
|
|
print_curses(F, f, ug->unit_array[i], TYP_UNIT, indent);
|
2001-04-28 17:39:13 +02:00
|
|
|
|
}
|
2001-05-18 09:06:47 +02:00
|
|
|
|
} else
|
2001-04-29 21:27:42 +02:00
|
|
|
|
#endif /* USE_UGROUPS */
|
2002-05-10 18:09:07 +02:00
|
|
|
|
print_curses(F, f, u, TYP_UNIT, indent);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2001-04-29 21:27:42 +02:00
|
|
|
|
#ifdef USE_UGROUPS
|
2001-04-28 17:39:13 +02:00
|
|
|
|
if(ug) {
|
|
|
|
|
int i;
|
|
|
|
|
for(i=0; i<ug->members; i++) {
|
|
|
|
|
if (mode==see_unit && ug->unit_array[i]->faction == f && ug->unit_array[i]->botschaften) {
|
|
|
|
|
for (S = ug->unit_array[i]->botschaften; S; S = S->next) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, S->s, indent, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-04-29 21:27:42 +02:00
|
|
|
|
} else
|
|
|
|
|
#endif
|
2001-04-28 17:39:13 +02:00
|
|
|
|
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);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2001-02-24 13:50:51 +01:00
|
|
|
|
rp_messages(FILE * F, message_list * msgs, faction * viewer, int indent, boolean centered, boolean categorized)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
messageclass * category;
|
|
|
|
|
if (!msgs) return;
|
|
|
|
|
for (category=msgclasses; category; category=category->next) {
|
|
|
|
|
int k = 0;
|
2001-02-24 13:50:51 +01:00
|
|
|
|
struct mlist * m = msgs->begin;
|
|
|
|
|
while (m) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
boolean debug = viewer->options & want(O_DEBUG);
|
|
|
|
|
#ifdef MSG_LEVELS
|
|
|
|
|
if (!debug && get_msglevel(viewer->warnings, viewer->msglevels, m->type) < m->level) continue;
|
|
|
|
|
#endif
|
|
|
|
|
/* messagetype * mt = m->type; */
|
2001-05-20 12:44:37 +02:00
|
|
|
|
if (strcmp(nr_section(m->msg), category->name)==0)
|
2001-02-28 23:14:59 +01:00
|
|
|
|
{
|
2001-12-10 01:13:39 +01:00
|
|
|
|
char lbuf[8192], *s = lbuf;
|
|
|
|
|
nr_render(m->msg, viewer->locale, s, sizeof(lbuf), viewer);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (!k && categorized) {
|
|
|
|
|
const char * name;
|
|
|
|
|
char cat_identifier[24];
|
|
|
|
|
|
|
|
|
|
sprintf(cat_identifier, "section_%s", category->name);
|
2001-04-22 07:36:50 +02:00
|
|
|
|
name = LOC(viewer->locale, cat_identifier);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (debug) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (name!=lbuf) strcpy(lbuf, name);
|
|
|
|
|
sprintf(lbuf+strlen(name), " [%s]", cat_identifier);
|
|
|
|
|
name = lbuf;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
k = 1;
|
|
|
|
|
rnl(F);
|
|
|
|
|
if (centered) centre(F, name, true);
|
|
|
|
|
else {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (indent>0) strcpy(lbuf, " ");
|
|
|
|
|
strcpy(lbuf+indent, name);
|
|
|
|
|
rpsnr(F, lbuf, 2);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
if (indent>0) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
strcpy(lbuf, " ");
|
|
|
|
|
strcpy(lbuf+indent, s);
|
|
|
|
|
s = lbuf;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-02-28 23:14:59 +01:00
|
|
|
|
#ifdef MSG_LEVELS
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (debug) {
|
|
|
|
|
int mylevel = get_msglevel(viewer->warnings, viewer->msglevels, m->type);
|
|
|
|
|
int level = msg_level(m);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (s!=lbuf) strcpy(lbuf, s);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
sprintf(buf+strlen(s), " [%d:%d(%d)]", m->type->hashkey, level, mylevel);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
s = lbuf;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-02-28 23:14:59 +01:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rpsnr(F, s, 2);
|
|
|
|
|
}
|
2001-02-24 13:50:51 +01:00
|
|
|
|
m=m->next;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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)) {
|
2001-04-16 16:34:19 +02:00
|
|
|
|
sprintf(buf, "%s", rname(r, f->locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} else {
|
2001-04-16 16:34:19 +02:00
|
|
|
|
sprintf(buf, "%s (%d,%d%s%s)", rname(r, f->locale), region_x(r,f), region_y(r,f), pl?",":"", pl?pl->name:"");
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2002-04-07 02:44:01 +02:00
|
|
|
|
prices(FILE * F, const region * r, const faction * f)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
const luxury_type *sale=NULL;
|
|
|
|
|
struct demand * dmd;
|
2002-07-23 09:23:28 +02:00
|
|
|
|
message * m;
|
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);
|
|
|
|
|
|
2002-07-23 09:23:28 +02:00
|
|
|
|
m = msg_message("nr_market_sale", "product price",
|
|
|
|
|
sale->itype->rtype, sale->price);
|
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
|
|
|
|
msg_release(m);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-07-23 09:23:28 +02:00
|
|
|
|
if(n > 0) {
|
|
|
|
|
scat(" ");
|
|
|
|
|
scat(LOC(f->locale, "nr_trade_intro"));
|
|
|
|
|
scat(" ");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-07-23 09:23:28 +02:00
|
|
|
|
for (dmd=r->land->demands;dmd;dmd=dmd->next) if(dmd->value > 0) {
|
|
|
|
|
char sbuf[80];
|
|
|
|
|
m = msg_message("nr_market_price", "product price",
|
|
|
|
|
dmd->type->itype->rtype, dmd->value * dmd->type->price);
|
|
|
|
|
nr_render(m, f->locale, sbuf, sizeof(sbuf), f);
|
|
|
|
|
msg_release(m);
|
|
|
|
|
scat(sbuf);
|
|
|
|
|
n--;
|
|
|
|
|
if (n == 0) scat(LOC(f->locale, "nr_trade_end"));
|
|
|
|
|
else if (n == 1) {
|
|
|
|
|
scat(" ");
|
|
|
|
|
scat(LOC(f->locale, "nr_trade_final"));
|
|
|
|
|
scat(" ");
|
|
|
|
|
} else {
|
|
|
|
|
scat(LOC(f->locale, "nr_trade_next"));
|
|
|
|
|
scat(" ");
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
/* Schreibe Paragraphen */
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
extern const direction_t back[MAXDIRECTIONS];
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
boolean
|
2002-04-07 02:44:01 +02:00
|
|
|
|
see_border(const border * b, const faction * f, const region * r)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
boolean cs = b->type->fvisible(b, f, r);
|
|
|
|
|
if (!cs) {
|
|
|
|
|
cs = b->type->rvisible(b, r);
|
|
|
|
|
if (!cs) {
|
2002-04-07 02:44:01 +02:00
|
|
|
|
const unit * us = r->units;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
while (us && !cs) {
|
|
|
|
|
if (us->faction==f) {
|
|
|
|
|
cs = b->type->uvisible(b, us);
|
|
|
|
|
if (cs) break;
|
|
|
|
|
}
|
|
|
|
|
us=us->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return cs;
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
const char *
|
2002-09-02 22:36:12 +02:00
|
|
|
|
trailinto(const region * r, const struct locale * lang)
|
2001-12-10 01:13:39 +01:00
|
|
|
|
{
|
|
|
|
|
char ref[32];
|
|
|
|
|
const char * s;
|
|
|
|
|
if (r) {
|
|
|
|
|
terrain_t t = r->terrain;
|
|
|
|
|
if (is_cursed(r->attribs, C_MAELSTROM, 0)) {
|
|
|
|
|
/* das kostet. evtl. w<>re ein FL_CURSED gut? */
|
|
|
|
|
s = locale_string(lang, "maelstrom_trail");
|
|
|
|
|
}
|
|
|
|
|
else if (terrain[t].trailname==NULL) {
|
|
|
|
|
strcat(strcpy(ref, terrain[t].name), "_trail");
|
|
|
|
|
s = locale_string(lang, ref);
|
|
|
|
|
}
|
|
|
|
|
else s = locale_string(lang, terrain[t].trailname(r));
|
|
|
|
|
if (s && *s) {
|
|
|
|
|
if (strstr(s, "%s")) return s;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return "%s";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
eval_trail(struct opstack ** stack, const void * userdata) /* (int, int) -> int */
|
|
|
|
|
{
|
|
|
|
|
const struct faction * f = (const struct faction *)userdata;
|
2002-09-02 22:36:12 +02:00
|
|
|
|
const struct locale * lang = opop(stack, const struct locale*);
|
|
|
|
|
const struct region * r = opop(stack, const struct region*);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
const char * trail = trailinto(r, lang);
|
|
|
|
|
const char * rn = regionname(r, f);
|
|
|
|
|
char * x = balloc(strlen(trail)+strlen(rn));
|
|
|
|
|
sprintf(x, trail, rn);
|
|
|
|
|
opush(stack, x);
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static void
|
2002-04-07 02:44:01 +02:00
|
|
|
|
describe(FILE * F, const region * r, int partial, faction * f)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
char dbuf[512];
|
|
|
|
|
int n;
|
|
|
|
|
boolean dh;
|
|
|
|
|
direction_t d;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
int trees;
|
2001-12-15 13:26:04 +01:00
|
|
|
|
#if GROWING_TREES
|
2001-12-10 01:13:39 +01:00
|
|
|
|
int ytrees;
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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)");
|
|
|
|
|
}
|
|
|
|
|
else if (partial == 3) {
|
|
|
|
|
scat(" (benachbart)");
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
}
|
2001-04-22 07:36:50 +02:00
|
|
|
|
scat(LOC(f->locale, tname));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* B<>ume */
|
|
|
|
|
|
2001-12-15 13:26:04 +01:00
|
|
|
|
#if GROWING_TREES
|
2001-12-10 01:13:39 +01:00
|
|
|
|
trees = rtrees(r,2);
|
|
|
|
|
ytrees = rtrees(r,1);
|
|
|
|
|
if (production(r)) {
|
|
|
|
|
if(trees > 0 || ytrees > 0) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
icat(trees);
|
|
|
|
|
scat("/");
|
|
|
|
|
icat(ytrees);
|
|
|
|
|
scat(" ");
|
|
|
|
|
if (fval(r, RF_MALLORN)) {
|
|
|
|
|
if (trees == 1)
|
2002-07-23 09:23:28 +02:00
|
|
|
|
scat(LOC(f->locale, "nr_mallorntree"));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
else
|
2002-07-23 09:23:28 +02:00
|
|
|
|
scat(LOC(f->locale, "nr_mallorntree_p"));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
}
|
|
|
|
|
else if (trees == 1)
|
2002-07-23 09:23:28 +02:00
|
|
|
|
scat(LOC(f->locale, "nr_tree"));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
else
|
2002-07-23 09:23:28 +02:00
|
|
|
|
scat(LOC(f->locale, "nr_tree_p"));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
2001-01-25 10:37:55 +01:00
|
|
|
|
trees = rtrees(r);
|
|
|
|
|
if (production(r) && trees > 0) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
icat(trees);
|
|
|
|
|
scat(" ");
|
|
|
|
|
if (fval(r, RF_MALLORN)) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (trees == 1)
|
2002-07-23 09:23:28 +02:00
|
|
|
|
scat(LOC(f->locale, "nr_mallorntree"));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
else
|
2002-07-23 09:23:28 +02:00
|
|
|
|
scat(LOC(f->locale, "nr_mallorntree_p"));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
else if (trees == 1)
|
2002-07-23 09:23:28 +02:00
|
|
|
|
scat(LOC(f->locale, "nr_tree"));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
else
|
2002-07-23 09:23:28 +02:00
|
|
|
|
scat(LOC(f->locale, "nr_tree_p"));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-03-31 19:20:08 +02:00
|
|
|
|
/* iron & stone */
|
2001-12-15 13:26:04 +01:00
|
|
|
|
#if NEW_RESOURCEGROWTH
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (partial == 0 && f != (faction *) NULL) {
|
|
|
|
|
struct rawmaterial * res;
|
|
|
|
|
for (res=r->resources;res;res=res->next) {
|
|
|
|
|
int level = -1;
|
|
|
|
|
int visible = -1;
|
|
|
|
|
int maxskill = 0;
|
|
|
|
|
const item_type * itype = resource2item(res->type->rtype);
|
|
|
|
|
if (res->type->visible==NULL) {
|
|
|
|
|
visible = res->amount;
|
|
|
|
|
level = res->level + itype->construction->minskill - 1;
|
|
|
|
|
} else {
|
|
|
|
|
const unit * u;
|
|
|
|
|
for (u=r->units; visible!=res->amount && u!=NULL; u=u->next) {
|
|
|
|
|
if (u->faction == f) {
|
|
|
|
|
int s = eff_skill(u, itype->construction->skill, r);
|
|
|
|
|
if (s>maxskill) {
|
|
|
|
|
if (s>=itype->construction->minskill) {
|
|
|
|
|
level = res->level + itype->construction->minskill - 1;
|
|
|
|
|
}
|
|
|
|
|
maxskill = s;
|
|
|
|
|
visible = res->type->visible(res, maxskill);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-03-31 19:20:08 +02:00
|
|
|
|
if (level>=0 && visible >= 0) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
char * pos = buf+strlen(buf);
|
2002-03-31 19:20:08 +02:00
|
|
|
|
snprintf(pos, sizeof(buf)-(pos-buf), ", %d %s/%d",
|
|
|
|
|
visible, LOC(f->locale, res->type->name), res->level + itype->construction->minskill - 1);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
if (partial == 0 && f != (faction *) NULL) {
|
|
|
|
|
int maxmining = 0;
|
|
|
|
|
const unit * u;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->faction == f) {
|
|
|
|
|
int s = eff_skill(u, SK_MINING, r);
|
|
|
|
|
maxmining = max(maxmining, s);
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (riron(r) > 0 && maxmining >= 4) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
scat(", ");
|
|
|
|
|
icat(riron(r));
|
|
|
|
|
scat(" Eisen");
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (rlaen(r)>=0 && maxmining >= 7) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
scat(", ");
|
|
|
|
|
icat(rlaen(r));
|
|
|
|
|
scat(" Laen");
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-03-31 19:20:08 +02:00
|
|
|
|
/* peasants & silver */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (rpeasants(r)) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
icat(rpeasants(r));
|
|
|
|
|
|
|
|
|
|
if(fval(r, RF_ORCIFIED)) {
|
2002-07-23 09:23:28 +02:00
|
|
|
|
scat(" ");
|
|
|
|
|
scat(LOC(f->locale, rpeasants(r)==1?"rc_orc":"rc_orc_p"));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} else {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
scat(" ");
|
|
|
|
|
scat(LOC(f->locale, resourcename(oldresourcetype[R_PEASANTS], rpeasants(r)!=1)));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rmoney(r) && partial == 0) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
icat(rmoney(r));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
scat(" ");
|
|
|
|
|
scat(LOC(f->locale, resourcename(oldresourcetype[R_SILVER], rmoney(r)!=1)));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Pferde */
|
|
|
|
|
|
|
|
|
|
if (rhorses(r)) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
icat(rhorses(r));
|
|
|
|
|
scat(" ");
|
|
|
|
|
#ifdef NEW_ITEMS
|
2001-04-22 07:36:50 +02:00
|
|
|
|
scat(LOC(f->locale, resourcename(oldresourcetype[R_HORSE], (rhorses(r)>1)?GR_PLURAL:0)));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#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-10 11:40:12 +01:00
|
|
|
|
attrib *a_do = a_find(r->attribs, &at_overrideroads);
|
2001-02-04 09:42:36 +01:00
|
|
|
|
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;
|
2001-04-16 16:34:19 +02:00
|
|
|
|
|
2001-02-04 09:42:36 +01:00
|
|
|
|
/* Nachbarregionen, die gesehen werden, ermitteln */
|
|
|
|
|
for (d = 0; d != MAXDIRECTIONS; d++)
|
|
|
|
|
if (see[d] && rconnect(r, d)) nrd++;
|
2001-04-16 16:34:19 +02:00
|
|
|
|
|
2001-02-04 09:42:36 +01:00
|
|
|
|
/* Richtungen aufz<66>hlen */
|
2001-04-16 16:34:19 +02:00
|
|
|
|
|
2001-02-04 09:42:36 +01:00
|
|
|
|
dh = false;
|
|
|
|
|
for (d = 0; d != MAXDIRECTIONS; d++) if (see[d]) {
|
|
|
|
|
region * r2 = rconnect(r, d);
|
|
|
|
|
if(!r2) continue;
|
|
|
|
|
nrd--;
|
|
|
|
|
if (dh) {
|
2002-07-23 09:23:28 +02:00
|
|
|
|
if (nrd == 0) {
|
|
|
|
|
scat(" ");
|
|
|
|
|
scat(LOC(f->locale, "nr_nb_final"));
|
|
|
|
|
} else {
|
|
|
|
|
scat(LOC(f->locale, "nr_nb_next"));
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
scat(LOC(f->locale, directions[d]));
|
|
|
|
|
scat(" ");
|
|
|
|
|
sprintf(dbuf, trailinto(r2, f->locale),
|
|
|
|
|
f_regionid(r2, f));
|
|
|
|
|
scat(dbuf);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
scat(" ");
|
|
|
|
|
MSG(("nr_vicinitystart", "dir region", d, r2), dbuf, sizeof(dbuf), f->locale, f);
|
|
|
|
|
scat(dbuf);
|
|
|
|
|
dh = true;
|
2001-02-04 09:42:36 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* 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);
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (partial==0 && r->planep && r->planep->id == 1 &&
|
2001-01-25 10:37:55 +01:00
|
|
|
|
!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 */
|
2002-05-10 18:09:07 +02:00
|
|
|
|
print_curses(F, f, r, TYP_REGION,0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* 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 ");
|
|
|
|
|
}
|
2001-04-22 07:36:50 +02:00
|
|
|
|
strcat(buf, LOC(f->locale, directions[d]));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2002-04-07 02:44:01 +02:00
|
|
|
|
statistics(FILE * F, const region * r, const faction * f)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2002-04-07 02:44:01 +02:00
|
|
|
|
const unit *u;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
int number, p;
|
|
|
|
|
item *itm, *items = NULL;
|
|
|
|
|
p = rpeasants(r);
|
|
|
|
|
number = 0;
|
|
|
|
|
|
|
|
|
|
/* z<>hlen */
|
|
|
|
|
for (u = r->units; u; u = u->next)
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (u->faction == f && u->race != new_race[RC_SPELL]) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (production(r) && (!rterrain(r) == T_OCEAN || f->race == new_race[RC_AQUARIAN])) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
|
|
|
|
|
2002-03-27 22:49:27 +01:00
|
|
|
|
if (buildingtype_exists(r, bt_find("caravan"))) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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) {
|
2001-04-22 07:36:50 +02:00
|
|
|
|
sprintf(buf, "%s: %d", LOC(f->locale, resourcename(itm->type->rtype, GR_PLURAL)), itm->number);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rps(F, buf);
|
|
|
|
|
}
|
|
|
|
|
while (items) i_free(i_remove(&items, items));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2002-04-07 02:44:01 +02:00
|
|
|
|
durchreisende(FILE * F, const region * r, const faction * f)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
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;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (cansee_durchgezogen(f, r, u, 0) > 0 && r!=u->region) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (cansee_durchgezogen(f, r, u, 0) > 0 && r!=u->region) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
rps_nowrap(F, LOC(f->locale, "nr_template"));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rnl(F);
|
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
|
|
|
|
|
2002-07-23 09:23:28 +02:00
|
|
|
|
sprintf(buf, "%s %s \"%s\"", LOC(f->locale, "ERESSEA"), factionid(f), LOC(f->locale, "enterpasswd"));
|
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 " : "",
|
2001-12-10 01:13:39 +01:00
|
|
|
|
f->race->recruitcost, ECHECK_VERSION);
|
2001-02-03 14:45:35 +01:00
|
|
|
|
/* -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)
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (u->faction == f && u->race != new_race[RC_SPELL]) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (!dh) {
|
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
|
|
|
|
pl = getplane(r);
|
|
|
|
|
if (pl && fval(pl, PFL_NOCOORDS)) {
|
2001-04-22 07:36:50 +02:00
|
|
|
|
sprintf(buf, "%s; %s", LOC(f->locale, parameters[P_REGION]), rname(r, f->locale));
|
2001-02-13 00:44:30 +01:00
|
|
|
|
} else if (pl && pl->id != 0) {
|
2001-04-22 07:36:50 +02:00
|
|
|
|
sprintf(buf, "%s %d,%d,%d ; %s", LOC(f->locale, parameters[P_REGION]), region_x(r,f),
|
2001-02-11 20:56:49 +01:00
|
|
|
|
region_y(r,f), pl->id, rname(r, f->locale));
|
2001-02-13 00:44:30 +01:00
|
|
|
|
} else {
|
2001-04-22 07:36:50 +02:00
|
|
|
|
sprintf(buf, "%s %d,%d ; %s", LOC(f->locale, parameters[P_REGION]), region_x(r,f),
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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;
|
|
|
|
|
|
2001-04-22 07:36:50 +02:00
|
|
|
|
sprintf(buf, "%s %s; %s [%d,%d$", LOC(u->faction->locale, parameters[P_UNIT]),
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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) {
|
2001-04-16 16:34:19 +02:00
|
|
|
|
if(is_persistent(S2->s, u->faction->locale)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
sprintf(buf, " %s", S2->s);
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-01 08:58:45 +02:00
|
|
|
|
/* If the lastorder begins with an @ it should have
|
|
|
|
|
* been printed in the loop before. */
|
|
|
|
|
if(u->lastorder[0] != 0 && u->lastorder[0] != '@') {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
sprintf(buf, " %s", u->lastorder);
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
2001-04-22 07:36:50 +02:00
|
|
|
|
sprintf(buf, LOC(f->locale, parameters[P_NEXT]));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2002-12-14 16:49:18 +01:00
|
|
|
|
show_allies(const faction * f, const ally * allies)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
int allierte = 0;
|
|
|
|
|
int i=0, h, hh = 0;
|
|
|
|
|
int dh = 0;
|
2002-12-14 16:49:18 +01:00
|
|
|
|
const ally * sf;
|
|
|
|
|
for (sf = allies; sf; sf = sf->next) {
|
|
|
|
|
int mode = alliedgroup(NULL, f, sf->faction, sf, HELP_ALL);
|
|
|
|
|
#ifdef ALLIANCES
|
|
|
|
|
if (f->alliance!=sf->faction->alliance) continue;
|
|
|
|
|
#endif
|
|
|
|
|
if (mode > 0) ++allierte;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-12-14 16:49:18 +01:00
|
|
|
|
for (sf = allies; sf; sf = sf->next) {
|
|
|
|
|
int mode = alliedgroup(NULL, f, sf->faction, sf, HELP_ALL);
|
|
|
|
|
#ifdef ALLIANCES
|
|
|
|
|
if (f->alliance!=sf->faction->alliance) continue;
|
|
|
|
|
#endif
|
|
|
|
|
if (mode <= 0) continue;
|
|
|
|
|
i++;
|
|
|
|
|
if (dh) {
|
|
|
|
|
if (i == allierte)
|
|
|
|
|
scat(" und ");
|
|
|
|
|
else
|
|
|
|
|
scat(", ");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2002-12-14 16:49:18 +01:00
|
|
|
|
dh = 1;
|
|
|
|
|
hh = 0;
|
|
|
|
|
scat(factionname(sf->faction));
|
|
|
|
|
scat(" (");
|
|
|
|
|
if (mode == HELP_ALL) {
|
|
|
|
|
scat("Alles");
|
|
|
|
|
} else
|
|
|
|
|
for (h = 1; h < HELP_ALL; h *= 2) {
|
|
|
|
|
if ((mode & 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;
|
|
|
|
|
break;
|
|
|
|
|
case HELP_FSTEALTH:
|
|
|
|
|
if (hh)
|
|
|
|
|
scat(", ");
|
|
|
|
|
scat("Parteitarnung");
|
|
|
|
|
hh = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
scat(")");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
allies(FILE * F, faction * f)
|
|
|
|
|
{
|
|
|
|
|
group * g = f->groups;
|
|
|
|
|
if (f->allies) {
|
|
|
|
|
if (!f->allies->next) {
|
|
|
|
|
strcpy(buf, "Wir helfen der Partei ");
|
|
|
|
|
} else {
|
|
|
|
|
strcpy(buf, "Wir helfen den Parteien ");
|
|
|
|
|
}
|
2002-12-14 16:04:20 +01:00
|
|
|
|
show_allies(f, f->allies);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
scat(".");
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
2002-12-14 16:04:20 +01:00
|
|
|
|
show_allies(f, g->allies);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
scat(".");
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
g = g->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2002-04-07 02:44:01 +02:00
|
|
|
|
guards(FILE * F, const region * r, const faction * see)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{ /* 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)) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
faction *f = u->faction;
|
|
|
|
|
faction *fv = visible_faction(see, u);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if(fv != f && see != fv) {
|
|
|
|
|
f = fv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (f != see && fval(u, FL_PARTEITARNUNG)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2001-12-10 01:13:39 +01:00
|
|
|
|
list_address(FILE * F, const faction * uf, const faction_list * seenfactions)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2001-12-10 01:13:39 +01:00
|
|
|
|
const faction_list *flist = seenfactions;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-04-22 07:36:50 +02:00
|
|
|
|
centre(F, LOC(uf->locale, "nr_addresses"), false);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rnl(F);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
|
|
|
|
while (flist!=NULL) {
|
|
|
|
|
const faction * f = flist->data;
|
|
|
|
|
if (f->no!=MONSTER_FACTION) {
|
|
|
|
|
sprintf(buf, "%s: %s; %s", factionname(f), f->email, f->banner);
|
2002-10-08 08:46:03 +02:00
|
|
|
|
rparagraph(F, buf, 4, (char)(ALLIED(uf, f)?'+':'*'));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
}
|
|
|
|
|
flist = flist->next;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
rnl(F);
|
|
|
|
|
rpline(F);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
2002-09-02 22:36:12 +02:00
|
|
|
|
const struct locale * lang = NULL;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-22 07:36:50 +02:00
|
|
|
|
sprintf(buf, "%s, %s %d, %s", buildingname(b), LOC(f->locale, "nr_size"),
|
2001-12-10 01:13:39 +01:00
|
|
|
|
b->size, LOC(lang, buildingtype(b, b->size)));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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;
|
|
|
|
|
|
2002-05-10 18:09:07 +02:00
|
|
|
|
print_curses(F, f, b, TYP_BUILDING, 4);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
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
|
2001-12-10 01:13:39 +01:00
|
|
|
|
report(FILE *F, faction * f, const faction_list * addresses,
|
|
|
|
|
const char * pzTime)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
#ifndef NEW_ITEMS
|
|
|
|
|
potion_t potion;
|
|
|
|
|
#endif
|
|
|
|
|
int flag = 0;
|
|
|
|
|
char ch;
|
|
|
|
|
int dh;
|
|
|
|
|
int anyunits;
|
2002-04-07 02:44:01 +02:00
|
|
|
|
const struct region *r;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
building *b;
|
|
|
|
|
ship *sh;
|
|
|
|
|
unit *u;
|
|
|
|
|
attrib *a;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
message * m;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
int wants_stats;
|
|
|
|
|
int wants_zugvorlage;
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
if (quiet) {
|
|
|
|
|
printf(" NR");
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
printf(" - Schreibe Report\n");
|
|
|
|
|
|
2002-07-23 09:23:28 +02:00
|
|
|
|
m = msg_message("nr_header_date", "game date", global.gamename, pzTime);
|
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
|
|
|
|
msg_release(m);
|
2001-04-26 19:41:06 +02:00
|
|
|
|
centre(F, buf, true);
|
2002-07-23 09:23:28 +02:00
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
centre(F, gamedate_season(f->locale), true);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rnl(F);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
sprintf(buf, "%s, %s/%s (%s)", factionname(f),
|
|
|
|
|
LOC(f->locale, rc_name(f->race, 1)), neue_gebiete[f->magiegebiet],
|
|
|
|
|
f->email);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
centre(F, buf, true);
|
2002-09-02 22:36:12 +02:00
|
|
|
|
#ifdef ALLIANCES
|
|
|
|
|
if (f->alliance!=NULL) {
|
|
|
|
|
centre(F, alliancename(f->alliance), true);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
buf[0] = 0;
|
|
|
|
|
dh = 0;
|
|
|
|
|
for(a=a_find(f->attribs, &at_faction_special); a; a=a->nexttype) {
|
|
|
|
|
dh++;
|
2001-04-08 19:36:50 +02:00
|
|
|
|
if(fspecials[a->data.sa[0]].maxlevel != 100) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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) {
|
2002-03-09 16:16:35 +01:00
|
|
|
|
if (f->age <= 1) {
|
2002-04-20 14:41:49 +02:00
|
|
|
|
ADDMSG(&f->msgs, msg_message("changepasswd",
|
|
|
|
|
"value", gc_add(strdup(f->passw))));
|
2002-03-09 16:16:35 +01:00
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
RENDER(f, buf, sizeof(buf), ("newbie_password", "password", f->passw));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, buf, true);
|
2002-04-21 19:22:48 +02:00
|
|
|
|
rnl(F);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
centre(F, LOC(f->locale, "newbie_info_1"), true);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rnl(F);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
centre(F, LOC(f->locale, "newbie_info_2"), true);
|
|
|
|
|
if ((f->options & want(O_COMPUTER)) == 0) {
|
2001-12-16 11:16:58 +01:00
|
|
|
|
f->options |= want(O_COMPUTER);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, LOC(f->locale, "newbie_info_3"), true);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
rnl(F);
|
|
|
|
|
if (f->options & want(O_SCORE) && f->age > DISPLAYSCORE) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
RENDER(f, buf, sizeof(buf), ("nr_score", "score average", f->score, average_score_of_age(f->age, f->age / 24 + 1)));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
m = msg_message("nr_population", "population units", count_all(f), f->no_units);
|
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
|
|
|
|
msg_release(m);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
if (f->race == new_race[RC_HUMAN]) {
|
|
|
|
|
int maxmig = count_maxmigrants(f);
|
|
|
|
|
sprintf(buf, "Deine Partei hat %d Migranten und kann maximal %d Migranten aufnehmen.",
|
|
|
|
|
count_migrants(f), maxmig);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (f->age > 1 && f->lastorders != turn) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
if (turn - f->lastorders == 1) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
centre(F, LOC(f->locale, "nr_nmr"), true);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} 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 */
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if(f->race == new_race[RC_INSECT]) {
|
|
|
|
|
if(month_season[month(1)] == 0) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
} else if(month_season[month(2)] == 0) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-22 07:36:50 +02:00
|
|
|
|
sprintf(buf, "%s:", LOC(f->locale, "nr_options"));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for (op = 0; op != MAXOPTIONS; op++) {
|
|
|
|
|
if (f->options & (int) pow(2, op)) {
|
|
|
|
|
scat(" ");
|
2001-04-22 07:36:50 +02:00
|
|
|
|
scat(LOC(f->locale, options[op]));
|
2001-02-28 23:14:59 +01:00
|
|
|
|
#ifdef AT_OPTION
|
2001-02-28 19:25:25 +01:00
|
|
|
|
if(op == O_NEWS) {
|
|
|
|
|
attrib *a = a_find(f->attribs, &at_option_news);
|
|
|
|
|
if(!a) {
|
|
|
|
|
/* Zur Altlastenbeseitigung */
|
|
|
|
|
f->options = f->options & ~op;
|
|
|
|
|
} else {
|
|
|
|
|
int sec = a->data.i;
|
|
|
|
|
int i;
|
|
|
|
|
scat("(");
|
|
|
|
|
for(i=1; sec != 0; i *= 2) {
|
|
|
|
|
if(sec & i) {
|
|
|
|
|
icat(i);
|
|
|
|
|
sec = sec & ~i;
|
|
|
|
|
if(sec) scat(",");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
scat(")");
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-02-28 23:14:59 +01:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
2001-04-22 07:36:50 +02:00
|
|
|
|
centre(F, LOC(f->locale, "section_battle"), false);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rnl(F);
|
|
|
|
|
for (bm=f->battles;bm;bm=bm->next) {
|
2001-02-05 17:11:59 +01:00
|
|
|
|
#ifdef HAVE_SNPRINTF
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
2001-04-22 07:36:50 +02:00
|
|
|
|
centre(F, LOC(f->locale, "section_newspells"), true);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
while (a) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
report_spell(F, (spellid_t)a->data.i, f->locale);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
a = a->nexttype;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
2001-04-22 07:36:50 +02:00
|
|
|
|
centre(F, LOC(f->locale, "section_newpotions"), true);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
ch = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
2001-04-22 07:36:50 +02:00
|
|
|
|
centre(F, LOC(f->locale, resourcename(ptype->itype->rtype, 0)), true);
|
|
|
|
|
sprintf(buf, "%s %d", LOC(f->locale, "nr_level"), ptype->level);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
2001-04-22 07:36:50 +02:00
|
|
|
|
sprintf(buf, "%s: ", LOC(f->locale, "nr_herbsrequired"));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
while (m->number) {
|
2001-04-22 07:36:50 +02:00
|
|
|
|
scat(LOC(f->locale, resourcename(oldresourcetype[m->type], 0)));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
++m;
|
|
|
|
|
if (m->number) scat(", ");
|
|
|
|
|
}
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, ptype->text, true);
|
|
|
|
|
}
|
|
|
|
|
rnl(F);
|
2001-04-22 07:36:50 +02:00
|
|
|
|
centre(F, LOC(f->locale, "nr_alliances"), false);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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;
|
|
|
|
|
case see_far:
|
|
|
|
|
break;
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
else if (sd->mode==see_far) {
|
|
|
|
|
describe(F, r, 3, f);
|
|
|
|
|
guards(F, r, f);
|
|
|
|
|
durchreisende(F, r, f);
|
|
|
|
|
}
|
|
|
|
|
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) {
|
2001-05-20 09:46:13 +02:00
|
|
|
|
message_list * mlist = r_getmessages(r, f);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rp_messages(F, r->msgs, f, 0, true, true);
|
2001-05-20 09:46:13 +02:00
|
|
|
|
if (mlist) rp_messages(F, mlist, f, 0, true, true);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
/* 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)) ||
|
|
|
|
|
(sd->mode==see_far && cansee(f, r, u, -2)) ||
|
|
|
|
|
(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),
|
2001-04-22 07:36:50 +02:00
|
|
|
|
LOC(f->locale, sh->type->name[0]),
|
2001-01-25 10:37:55 +01:00
|
|
|
|
(w + 99) / 100, /* +99 weil sonst die Nachkommastellen ignoriert w<>rden */
|
|
|
|
|
shipcapacity(sh) / 100);
|
|
|
|
|
} else {
|
2001-05-18 09:06:47 +02:00
|
|
|
|
sprintf(buf, "%s, %s", shipname(sh),
|
2001-04-22 07:36:50 +02:00
|
|
|
|
LOC(f->locale, sh->type->name[0]));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(sh->type->construction->improvement==NULL); /* sonst ist construction::size nicht ship_type::maxsize */
|
|
|
|
|
if (sh->size!=sh->type->construction->maxsize) {
|
2001-05-18 09:06:47 +02:00
|
|
|
|
sprintf(buf+strlen(buf), ", %s (%d/%d)",
|
|
|
|
|
LOC(f->locale, "nr_undercons"), sh->size,
|
2001-04-22 07:36:50 +02:00
|
|
|
|
sh->type->construction->maxsize);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
if (sh->damage) {
|
2001-05-18 09:06:47 +02:00
|
|
|
|
sprintf(buf+strlen(buf), ", %d%% %s",
|
2001-04-22 07:36:50 +02:00
|
|
|
|
sh->damage*100/(sh->size*DAMAGE_SCALE),
|
|
|
|
|
LOC(f->locale, "nr_damaged"));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
if (rterrain(r) != T_OCEAN) {
|
|
|
|
|
if (sh->coast != NODIRECTION) {
|
|
|
|
|
scat(", ");
|
2001-04-22 07:36:50 +02:00
|
|
|
|
scat(LOC(f->locale, coasts[sh->coast]));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
|
2002-05-10 18:09:07 +02:00
|
|
|
|
print_curses(F,f,sh,TYP_SHIP,4);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
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);
|
2001-04-22 07:36:50 +02:00
|
|
|
|
rparagraph(F, LOC(f->locale, "nr_youaredead"), 0, 0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} else {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
list_address(F, f, addresses);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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 * last;
|
|
|
|
|
|
|
|
|
|
#define MAXSEEHASH 4095
|
|
|
|
|
seen_region * seehash[MAXSEEHASH];
|
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
static void
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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
|
2001-04-16 16:34:19 +02:00
|
|
|
|
static void
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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
|
|
|
|
|
|
2002-04-07 02:44:01 +02:00
|
|
|
|
seen_region *
|
|
|
|
|
find_seen(const region * r)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
int index = abs((r->x & 0xffff) + ((r->y) << 16)) % MAXSEEHASH;
|
2002-04-07 02:44:01 +02:00
|
|
|
|
seen_region * find=seehash[index];
|
|
|
|
|
while (find) {
|
|
|
|
|
if (find->r==r) return find;
|
|
|
|
|
find=find->nextHash;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2002-05-05 10:46:27 +02:00
|
|
|
|
seen_region * last;
|
2002-04-07 02:44:01 +02:00
|
|
|
|
static boolean
|
|
|
|
|
add_seen(const struct region * r, unsigned char mode, boolean dis)
|
|
|
|
|
{
|
|
|
|
|
seen_region * find = find_seen(r);
|
2002-04-14 09:57:26 +02:00
|
|
|
|
if (find==NULL) {
|
2002-05-05 10:46:27 +02:00
|
|
|
|
seen_region * insert = NULL;
|
2002-04-07 02:44:01 +02:00
|
|
|
|
int index = abs((r->x & 0xffff) + ((r->y) << 16)) % MAXSEEHASH;
|
2002-04-14 09:57:26 +02:00
|
|
|
|
if (!reuse) reuse = (seen_region*)calloc(1, sizeof(struct seen_region));
|
2002-05-04 01:27:45 +02:00
|
|
|
|
find = reuse;
|
2002-04-07 02:44:01 +02:00
|
|
|
|
reuse = reuse->next;
|
|
|
|
|
find->nextHash = seehash[index];
|
|
|
|
|
seehash[index] = find;
|
|
|
|
|
find->r = r;
|
2002-05-04 01:27:45 +02:00
|
|
|
|
|
2002-05-05 10:46:27 +02:00
|
|
|
|
/* first attempt: try to put it between previous insertion point and
|
|
|
|
|
* last region known so far. It's quite likely to be here. */
|
|
|
|
|
if (last) {
|
|
|
|
|
for (insert=last;insert->next;insert=insert->next) {
|
|
|
|
|
region * rl;
|
2002-05-04 01:27:45 +02:00
|
|
|
|
seen_region * inext = insert->next;
|
2002-05-05 10:46:27 +02:00
|
|
|
|
for (rl=insert->r->next;rl && rl!=inext->r;rl=rl->next) {
|
2002-05-04 01:27:45 +02:00
|
|
|
|
if (rl==r) break;
|
|
|
|
|
}
|
|
|
|
|
if (rl==r) break;
|
|
|
|
|
}
|
2002-05-05 10:46:27 +02:00
|
|
|
|
/* if we did not find it, and mode is not see_neighbour, it *still*
|
|
|
|
|
* belongs at the end. otherwise, search more: */
|
|
|
|
|
if (insert->next==NULL && mode==see_neighbour) {
|
|
|
|
|
const region * rl = NULL;
|
|
|
|
|
seen_region * sprev;
|
|
|
|
|
for(sprev=seen;sprev!=last;sprev=sprev->next) {
|
|
|
|
|
seen_region * snext = sprev->next;
|
|
|
|
|
for (rl=sprev->r->next;rl!=snext->r;rl=rl->next) {
|
|
|
|
|
if (rl==r) break;
|
|
|
|
|
}
|
|
|
|
|
if (rl==r) break;
|
|
|
|
|
}
|
|
|
|
|
/* search it after the insertion point, all the way to the end */
|
|
|
|
|
if (rl==r) insert = sprev;
|
|
|
|
|
else {
|
|
|
|
|
for (rl=insert->r->next;rl;rl=rl->next) {
|
|
|
|
|
if (rl==r) break;
|
|
|
|
|
}
|
|
|
|
|
if (rl!=r) insert=NULL; /* in front */
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-05-04 01:27:45 +02:00
|
|
|
|
}
|
2002-05-05 10:46:27 +02:00
|
|
|
|
if (mode!=see_neighbour) last=find;
|
2002-05-04 01:27:45 +02:00
|
|
|
|
find->prev = insert;
|
|
|
|
|
if (insert!=0) {
|
|
|
|
|
find->next = insert->next;
|
|
|
|
|
insert->next = find;
|
|
|
|
|
} else {
|
|
|
|
|
find->next = seen;
|
|
|
|
|
seen = find;
|
|
|
|
|
}
|
2002-04-14 09:57:26 +02:00
|
|
|
|
} else if (find->mode >= mode) {
|
|
|
|
|
return false;
|
2002-04-07 02:44:01 +02:00
|
|
|
|
}
|
|
|
|
|
find->mode = mode;
|
|
|
|
|
find->disbelieves |= dis;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define DBG_CACHE 1
|
|
|
|
|
#if DBG_CACHE
|
|
|
|
|
int chits = 0;
|
|
|
|
|
int ctries = 0;
|
|
|
|
|
#endif
|
2002-03-29 05:23:51 +01:00
|
|
|
|
static void
|
|
|
|
|
view_default(region *r, faction *f)
|
|
|
|
|
{
|
|
|
|
|
direction_t dir;
|
|
|
|
|
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
|
|
|
|
region * r2 = rconnect(r, dir);
|
|
|
|
|
if (r2) {
|
|
|
|
|
border * b = get_borders(r, r2);
|
2002-04-07 02:44:01 +02:00
|
|
|
|
while (b) {
|
|
|
|
|
if (!b->type->transparent(b, f)) break;
|
|
|
|
|
b = b->next;
|
|
|
|
|
}
|
2002-03-29 05:23:51 +01:00
|
|
|
|
if (!b) add_seen(r2, see_neighbour, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
view_neighbours(region * r, faction * f)
|
|
|
|
|
{
|
|
|
|
|
direction_t dir;
|
|
|
|
|
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
|
|
|
|
region * r2 = rconnect(r, dir);
|
|
|
|
|
if (r2) {
|
|
|
|
|
border * b = get_borders(r, r2);
|
|
|
|
|
while (b) {
|
|
|
|
|
if (!b->type->transparent(b, f)) break;
|
|
|
|
|
b = b->next;
|
|
|
|
|
}
|
|
|
|
|
if (!b) {
|
|
|
|
|
if (add_seen(r2, see_far, false)) {
|
2002-03-29 09:57:06 +01:00
|
|
|
|
if (!(terrain[rterrain(r2)].flags & FORBIDDEN_LAND)) {
|
|
|
|
|
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);
|
2002-03-29 05:23:51 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
recurse_regatta(region *center, region *r, faction *f, int maxdist)
|
|
|
|
|
{
|
|
|
|
|
direction_t dir;
|
|
|
|
|
int dist = distance(center, r);
|
|
|
|
|
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
|
|
|
|
region * r2 = rconnect(r, dir);
|
|
|
|
|
if (r2) {
|
|
|
|
|
int ndist = distance(center, r2);
|
2002-03-29 09:57:06 +01:00
|
|
|
|
if (ndist>dist && r2->terrain==T_OCEAN) {
|
2002-03-29 05:23:51 +01:00
|
|
|
|
border * b = get_borders(r, r2);
|
|
|
|
|
while (b) {
|
|
|
|
|
if (!b->type->transparent(b, f)) break;
|
|
|
|
|
b = b->next;
|
|
|
|
|
}
|
|
|
|
|
if (!b) {
|
|
|
|
|
if (ndist<maxdist) {
|
|
|
|
|
if (add_seen(r2, see_far, false)) {
|
|
|
|
|
recurse_regatta(center, r2, f, maxdist);
|
|
|
|
|
}
|
|
|
|
|
} else add_seen(r2, see_neighbour, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
view_regatta(region * r, faction * f)
|
|
|
|
|
{
|
|
|
|
|
unit *u;
|
|
|
|
|
int skill = 0;
|
|
|
|
|
for (u=r->units; u; u=u->next) {
|
|
|
|
|
if (u->faction==f) {
|
|
|
|
|
int es = effskill(u, SK_OBSERVATION);
|
|
|
|
|
if (es>skill) skill=es;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
recurse_regatta(r, r, f, skill/2);
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static void
|
|
|
|
|
prepare_report(faction * f)
|
|
|
|
|
{
|
|
|
|
|
region * r;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
region * end = lastregion(f);
|
2002-05-04 01:27:45 +02:00
|
|
|
|
seen_region ** append = &reuse;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
while (*append) append = &(*append)->next;
|
|
|
|
|
*append = seen;
|
2002-05-04 01:27:45 +02:00
|
|
|
|
memset(seehash, 0, sizeof(seehash));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
seen = NULL;
|
|
|
|
|
last = NULL;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
for (r = firstregion(f); r != end; r = r->next) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
attrib *ru;
|
|
|
|
|
unit * u;
|
2002-02-18 22:41:11 +01:00
|
|
|
|
plane * p = rplane(r);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
unsigned char mode = see_none;
|
|
|
|
|
boolean dis = false;
|
|
|
|
|
#if DBG_CACHE
|
|
|
|
|
++ctries;
|
|
|
|
|
#endif
|
2002-02-18 22:41:11 +01:00
|
|
|
|
if (p) {
|
|
|
|
|
watcher * w = p->watchers;
|
|
|
|
|
while (w) {
|
|
|
|
|
if (f==w->faction) {
|
|
|
|
|
mode = w->mode;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
w = w->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (mode<see_unit) for (u = r->units; u; u = u->next) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (u->faction == f) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (u->race != new_race[RC_SPELL] || u->number == RS_FARVISION) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
mode = see_unit;
|
|
|
|
|
if (fval(u, FL_DISBELIEVES)) {
|
|
|
|
|
dis = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-02-18 22:41:11 +01:00
|
|
|
|
if (mode<see_travel) for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
unit * u = (unit*)ru->data.v;
|
|
|
|
|
if (u->faction == f) {
|
|
|
|
|
mode = see_travel;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-02-18 22:41:11 +01:00
|
|
|
|
if (mode<see_lighthouse && rterrain(r) == T_OCEAN) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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)) {
|
2002-03-29 05:23:51 +01:00
|
|
|
|
void (*view)(region * r, faction * f) = view_default;
|
|
|
|
|
if (p && fval(p, PFL_SEESPECIAL)) {
|
|
|
|
|
attrib * a = a_find(p->attribs, &at_viewrange);
|
|
|
|
|
if (a) view = (void (*)(region * r, faction * f))a->data.f;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2002-03-29 05:23:51 +01:00
|
|
|
|
view(r, f);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#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;
|
|
|
|
|
boolean gotit;
|
|
|
|
|
FILE *shfp, *F, *BAT;
|
|
|
|
|
int wants_report, wants_computer_report,
|
|
|
|
|
wants_compressed, wants_bzip2;
|
2001-04-26 19:41:06 +02:00
|
|
|
|
time_t ltime = time(NULL);
|
2001-04-29 20:23:40 +02:00
|
|
|
|
char pzTime[64];
|
|
|
|
|
|
|
|
|
|
#ifdef _GNU_SOURCE
|
|
|
|
|
strftime(pzTime, 64, "%A, %-e. %B %Y, %-k:%M", localtime(<ime));
|
|
|
|
|
#else
|
2001-05-18 09:06:47 +02:00
|
|
|
|
strftime(pzTime, 64, "%A, %d. %B %Y, %H:%M", localtime(<ime));
|
2001-04-29 20:23:40 +02:00
|
|
|
|
#endif
|
2001-05-18 09:06:47 +02:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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");
|
|
|
|
|
|
|
|
|
|
report_donations();
|
|
|
|
|
#if FAST_SEEN
|
|
|
|
|
init_intervals();
|
|
|
|
|
#endif
|
|
|
|
|
remove_empty_units();
|
* möglichen Exploit beseitigt:
GIB xyz EINHEIT
GIB 0 ALLES SILBER
--> ALLE Befehle der übergebenen Einheit werden gelöscht.
* neue Funktion (convenience): ucansee(f, u1, u2)
liefert u1, wenn cansee(f,u1), sonst u2
* neue mistakes eingefügt uns übersetzt
* message bugfix:
u->htisorder kann gelöscht werden (z.b. NACH). Daher muss ein pointer auf
einen befehl in einer message immer auf den u->order Eintrag zeigen, damit er
zeit der auswertung noch existiert.
findorder(u, u->thisorder) tut das. Ist an mehreren Stellen nicht benutzt
worden. assert eingebaut, das das prüft.
* RESERVE_DONATIONS
Gegenstände, die von einer anderen Partei übergeben wurden, werden nicht
reserviert.
* TWOPASS_GIVE:
GIB Befehle werden zuerst an fremde Einheiten, danach in einem zweiten
Durchlauf an eigene Einheiten, ausgeführt.
* msg_message
An einigen messages ausprobiert, ob man die gleiche Message mehreren
Parteien einhängen kann - klappt, spart Speicher.
Allerdings fehlt dazu ein ordentliches memory-management (refcounter)
2001-05-10 07:50:52 +02:00
|
|
|
|
log_printf("Report timestamp - %s\n", pzTime);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for (f = factions; f; f = f->next) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
faction_list * addresses;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
attrib * a = a_find(f->attribs, &at_reportspell);
|
|
|
|
|
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);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
addresses = get_addresses(f, seen);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (!nonr && (f->options & wants_report))
|
|
|
|
|
{
|
2002-01-31 23:52:40 +01:00
|
|
|
|
sprintf(buf, "%s/%d-%s.nr", reportpath(), turn, factionid(f));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
F = cfopen(buf, "wt");
|
|
|
|
|
if (F) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
report(F, f, addresses, pzTime);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fclose(F);
|
|
|
|
|
gotit = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!nocr && (f->options & wants_computer_report || f->age<3))
|
|
|
|
|
{
|
2002-01-31 23:52:40 +01:00
|
|
|
|
sprintf(buf, "%s/%d-%s.cr", reportpath(), turn, factionid(f));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
F = cfopen(buf, "wt");
|
|
|
|
|
if (F) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
report_computer(F, f, seen, addresses, ltime);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fclose(F);
|
|
|
|
|
gotit = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-01-20 13:53:35 +01:00
|
|
|
|
if (f->no > 0 && 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
|
|
|
|
|
2001-02-04 14:47:25 +01:00
|
|
|
|
if (f->no > 0 && f->options & wants_compressed) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
if(f->age == 1) {
|
2002-02-04 18:59:40 +01:00
|
|
|
|
fprintf(BAT, "ls %d-%s.nr %d-%s.cr | zip -m -j -9 -@ %d-%s.zip\n",
|
|
|
|
|
turn, factionid(f), turn, factionid(f), turn, factionid(f));
|
2002-01-31 23:52:40 +01:00
|
|
|
|
fprintf(BAT, "zip -j -9 %d-%s.zip ../res/%s/%s/welcome.txt\n", turn, factionid(f), global.welcomepath, locale_name(f->locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} else {
|
2002-01-31 23:52:40 +01:00
|
|
|
|
fprintf(BAT, "ls %d-%s.nr %d-%s.cr | zip -m -j -9 -@ %d-%s.zip\n",
|
2002-02-02 15:51:40 +01:00
|
|
|
|
turn, factionid(f), turn, factionid(f), turn, factionid(f));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-02-03 12:55:49 +01:00
|
|
|
|
fprintf(shfp, "eresseamail.zipped $addr \"%s %s\" \"%d-%s.zip\" "
|
2002-07-28 13:51:24 +02:00
|
|
|
|
"%d-%s.zip\n", global.gamename, gamedate_short(f->locale), turn, factionid(f), turn, factionid(f));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
} else if(f->options & wants_bzip2) {
|
|
|
|
|
|
|
|
|
|
if (f->age == 1) {
|
|
|
|
|
fprintf(shfp,
|
2001-12-16 11:11:29 +01:00
|
|
|
|
" \\\n\t\"text/plain\" \"Willkommen\" ../res/%s/%s/welcome.txt", global.welcomepath, locale_name(f->locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-02-02 15:51:40 +01:00
|
|
|
|
fprintf(BAT, "bzip2 -9v `ls %d-%s.nr %d-%s.cr`\n",
|
2002-01-31 23:52:40 +01:00
|
|
|
|
turn, factionid(f), turn, factionid(f));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-07-28 13:51:24 +02:00
|
|
|
|
fprintf(shfp, "eresseamail.bzip2 $addr \"%s %s\"", global.gamename, gamedate_short(f->locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
if (!nonr && f->options & wants_report)
|
|
|
|
|
fprintf(shfp,
|
2002-02-03 13:01:41 +01:00
|
|
|
|
" \\\n\t\"application/x-bzip2\" \"Report\" %d-%s.nr.bz2",
|
|
|
|
|
turn,factionid(f));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
if (!nocr && (f->options & wants_computer_report || f->age<3))
|
|
|
|
|
fprintf(shfp,
|
2002-01-31 23:52:40 +01:00
|
|
|
|
" \\\n\t\"application/x-bzip2\" \"Computer-Report\" %d-%s.cr.bz2",
|
|
|
|
|
turn, factionid(f));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#ifdef USE_MERIAN
|
|
|
|
|
if (!nomer && f->options & wants_merian)
|
|
|
|
|
fprintf(shfp,
|
2002-01-31 23:52:40 +01:00
|
|
|
|
" \\\n\t\"application/x-bzip2\" \"Merian-Karte\" %d-%s.mer.bz2",
|
|
|
|
|
turn, factionid(f));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#endif
|
|
|
|
|
} else {
|
|
|
|
|
|
2002-07-28 13:51:24 +02:00
|
|
|
|
fprintf(shfp, MAIL " $addr \"%s %s\"", global.gamename, gamedate_short(f->locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
if (f->age == 1) {
|
|
|
|
|
fprintf(shfp,
|
2001-12-16 11:11:29 +01:00
|
|
|
|
" \\\n\t\"text/plain\" \"Willkommen\" ../res/%s/%s/welcome.txt", global.welcomepath, locale_name(f->locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!nonr && f->options & wants_report)
|
|
|
|
|
fprintf(shfp,
|
2002-02-04 19:15:09 +01:00
|
|
|
|
" \\\n\t\"text/plain\" \"Report\" %d-%s.nr",
|
2002-01-31 23:52:40 +01:00
|
|
|
|
turn, factionid(f));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
if (!nocr && (f->options & wants_computer_report || f->age<3))
|
|
|
|
|
fprintf(shfp,
|
2002-01-31 23:52:40 +01:00
|
|
|
|
" \\\n\t\"text/x-eressea-cr\" \"Computer-Report\" %d-%s.cr",
|
|
|
|
|
turn, factionid(f));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
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");
|
2001-12-10 01:13:39 +01:00
|
|
|
|
freelist(addresses);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
/* schliesst BAT und verschickt Zeitungen und Kommentare */
|
|
|
|
|
current_faction = NULL;
|
|
|
|
|
seen_done();
|
|
|
|
|
closebatch(BAT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
report_cleanup(void)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
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) {
|
2001-04-22 20:14:07 +02:00
|
|
|
|
/* bei TARNE PARTEI yxz muss die Partei von unit proof nicht
|
|
|
|
|
* wirklich Partei f2 sein! */
|
|
|
|
|
/* assert(ss->proof->faction==f2); */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return ss->proof;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
static void
|
2001-04-14 14:11:45 +02:00
|
|
|
|
add_find(faction * f, unit * u, faction *f2)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
/* faction f sees f2 through u */
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
static void
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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)) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
faction *fv = visible_faction(u->faction, u2);
|
|
|
|
|
lastf = fv;
|
|
|
|
|
add_find(u->faction, u2, fv);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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 {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
int waffen;
|
|
|
|
|
int factions;
|
|
|
|
|
int artefakte;
|
|
|
|
|
int ruestungen;
|
|
|
|
|
int schiffe;
|
|
|
|
|
int gebaeude;
|
|
|
|
|
int maxskill;
|
|
|
|
|
int inhabitedregions;
|
|
|
|
|
int peasants;
|
|
|
|
|
int nunits;
|
|
|
|
|
int playerpop;
|
|
|
|
|
double playermoney;
|
|
|
|
|
double peasantmoney;
|
|
|
|
|
int armed_men;
|
|
|
|
|
int poprace[MAXRACES];
|
|
|
|
|
int factionrace[MAXRACES];
|
|
|
|
|
int landregionen;
|
|
|
|
|
int regionen_mit_spielern;
|
|
|
|
|
int landregionen_mit_spielern;
|
|
|
|
|
int orkifizierte_regionen;
|
|
|
|
|
int inactive_volcanos;
|
|
|
|
|
int active_volcanos;
|
|
|
|
|
int spielerpferde;
|
|
|
|
|
int pferde;
|
|
|
|
|
struct language {
|
|
|
|
|
struct language * next;
|
|
|
|
|
int number;
|
|
|
|
|
const struct locale * locale;
|
|
|
|
|
} * languages;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} 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) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
const struct locale * lang = f->locale;
|
|
|
|
|
struct language * plang = s->languages;
|
|
|
|
|
while (plang && plang->locale != lang) plang=plang->next;
|
|
|
|
|
if (!plang) {
|
2002-01-20 12:35:06 +01:00
|
|
|
|
plang = calloc(sizeof(struct language), 1);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
plang->next = s->languages;
|
|
|
|
|
s->languages = plang;
|
|
|
|
|
plang->locale = lang;
|
|
|
|
|
}
|
|
|
|
|
++plang->number;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
f->nregions = 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++;
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (rterrain(r) == T_VOLCANO) {
|
|
|
|
|
s->inactive_volcanos++;
|
|
|
|
|
} else if(rterrain(r) == T_VOLCANO_SMOKING) {
|
|
|
|
|
s->active_volcanos++;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
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);
|
2002-05-05 18:59:25 +02:00
|
|
|
|
s->artefakte += get_item(u, I_SPHERE_OF_INVISIBILITY);
|
|
|
|
|
s->artefakte += get_item(u, I_SACK_OF_CONSERVATION);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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->number += u->number;
|
|
|
|
|
f->money += get_money(u);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
s->poprace[old_race(u->race)] += u->number;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* jetzt noch parteienweise z<>hlen */
|
|
|
|
|
/* Problem mit Monsterpartei ... */
|
|
|
|
|
for (f = factions; f; f = f->next) if (f->no!=MONSTER_FACTION) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (count_new == true || f->age > 0) s->factionrace[old_race(f->race)]++;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *
|
2001-12-10 01:13:39 +01:00
|
|
|
|
pcomp(double i, double j)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2001-12-10 01:13:39 +01:00
|
|
|
|
sprintf(buf, "%.0f (%s%.0f)", i, (i>=j)?"+":"", i-j);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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) {
|
2002-03-27 22:49:27 +01:00
|
|
|
|
if (b->type == bt_find("monument") && b->display && *b->display) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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) {
|
2002-03-27 22:49:27 +01:00
|
|
|
|
if (b->type == bt_find("monument") && b->display && *b->display && !fval(b, FL_DH)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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
|
2001-02-10 14:20:33 +01:00
|
|
|
|
writeadresses(void)
|
2001-01-31 00:16:17 +01:00
|
|
|
|
{
|
|
|
|
|
faction *f;
|
2001-02-28 19:25:25 +01:00
|
|
|
|
FILE *F;
|
2001-01-31 00:16:17 +01:00
|
|
|
|
char zText[MAX_PATH];
|
|
|
|
|
sprintf(zText, "%s/adressen", basepath());
|
|
|
|
|
F = cfopen(zText, "w");
|
|
|
|
|
if (!F) return;
|
|
|
|
|
|
|
|
|
|
for (f = factions; f; f = f->next) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (f->no != MONSTER_FACTION && playerrace(f->race)) {
|
2001-01-31 00:16:17 +01:00
|
|
|
|
fprintf(F, "%s:%s:%s\n", factionname(f), f->email, f->banner);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fclose(F);
|
|
|
|
|
}
|
|
|
|
|
|
2001-02-28 19:25:25 +01:00
|
|
|
|
static void
|
|
|
|
|
writenewssubscriptions(void)
|
|
|
|
|
{
|
|
|
|
|
char zText[MAX_PATH];
|
|
|
|
|
FILE *F;
|
|
|
|
|
|
|
|
|
|
sprintf(zText, "%s/news-subscriptions", basepath());
|
|
|
|
|
F = cfopen(zText, "w");
|
|
|
|
|
if (!F) return;
|
2001-02-28 23:14:59 +01:00
|
|
|
|
#ifdef AT_OPTION
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
{
|
|
|
|
|
faction *f;
|
|
|
|
|
for(f=factions; f; f=f->next) {
|
|
|
|
|
attrib *a = a_find(f->attribs, &at_option_news);
|
|
|
|
|
if(!a) {
|
|
|
|
|
fprintf(F, "%s:0\n", f->email);
|
|
|
|
|
} else {
|
|
|
|
|
fprintf(F, "%s:%d\n", f->email, a->data.i);
|
|
|
|
|
}
|
2001-02-28 19:25:25 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-02-28 23:14:59 +01:00
|
|
|
|
#endif
|
2001-02-28 19:25:25 +01:00
|
|
|
|
fclose(F);
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static void
|
|
|
|
|
writeforward(void)
|
|
|
|
|
{
|
|
|
|
|
FILE *forwardFile;
|
|
|
|
|
region *r;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
faction *f;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
for (f = factions; f; f = f->next) {
|
|
|
|
|
if (f->no != MONSTER_FACTION) {
|
|
|
|
|
fprintf(forwardFile,"partei-%s: %s\n", factionid(f), f->email);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2002-05-11 23:37:04 +02:00
|
|
|
|
static void
|
|
|
|
|
writeturn(void)
|
|
|
|
|
{
|
|
|
|
|
char zText[MAX_PATH];
|
|
|
|
|
FILE *f;
|
|
|
|
|
|
|
|
|
|
sprintf(zText, "%s/datum", basepath());
|
|
|
|
|
f = cfopen(zText, "w");
|
|
|
|
|
if (!f) return;
|
2002-07-29 09:35:37 +02:00
|
|
|
|
fputs(gamedate2(default_locale), f);
|
2002-05-11 23:37:04 +02:00
|
|
|
|
fclose(f);
|
|
|
|
|
sprintf(zText, "%s/turn", basepath());
|
|
|
|
|
f = cfopen(zText, "w");
|
|
|
|
|
if (!f) return;
|
|
|
|
|
fprintf(f,"%d",turn);
|
|
|
|
|
fclose(f);
|
|
|
|
|
}
|
|
|
|
|
|
2002-02-18 17:19:50 +01:00
|
|
|
|
static void
|
|
|
|
|
out_faction(FILE *file, faction *f)
|
|
|
|
|
{
|
|
|
|
|
fprintf(file, "%s (%.3s/%.3s), %d Einh., %d Pers., $%d, %d %s\n",
|
|
|
|
|
factionname(f), LOC(default_locale, rc_name(f->race, 0)),
|
2002-03-31 10:46:36 +02:00
|
|
|
|
neue_gebiete[f->magiegebiet], f->no_units, f->number, f->money,
|
2002-02-18 17:19:50 +01:00
|
|
|
|
turn - f->lastorders, turn - f->lastorders != 1 ? "NMRs" : "NMR ");
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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;
|
2002-03-03 11:51:24 +01:00
|
|
|
|
int nmrs[NMRTIMEOUT+1];
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
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");
|
2002-07-29 09:35:37 +02:00
|
|
|
|
fprintf(F, "%s\n%s\n\n", global.gamename, gamedate2(default_locale));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
fprintf(F, "Auswertung Nr: %d\n\n", turn);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fprintf(F, "Parteien: %s\n", pcomp(s->factions, o->factions));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
fprintf(F, "Einheiten: %s\n", pcomp(s->nunits, o->nunits));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
fprintf(F, "Orkifizierte Regionen: %d\n", s->orkifizierte_regionen);
|
|
|
|
|
fprintf(F, "Inaktive Vulkane: %d\n", s->inactive_volcanos);
|
|
|
|
|
fprintf(F, "Aktive Vulkane: %d\n\n", s->active_volcanos);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-03-24 12:22:44 +01:00
|
|
|
|
for (i = 0; i < MAXRACES; i++) if (s->factionrace[i] && playerrace(new_race[i])
|
|
|
|
|
&& i != RC_TEMPLATE && i != RC_CLONE) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fprintf(F, "%14sv<73>lker: %s\n",
|
2001-12-10 01:13:39 +01:00
|
|
|
|
LOC(default_locale, rc_name(new_race[i], 3)), pcomp(s->factionrace[i], o->factionrace[i]));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if(full) {
|
|
|
|
|
fprintf(F, "\n");
|
|
|
|
|
{
|
|
|
|
|
struct language * plang = s->languages;
|
|
|
|
|
while (plang!=NULL) {
|
|
|
|
|
struct language * olang = o->languages;
|
|
|
|
|
int nold = 0;
|
|
|
|
|
while (olang && olang->locale!=plang->locale) olang=olang->next;
|
|
|
|
|
if (olang) nold = olang->number;
|
|
|
|
|
fprintf(F, "Sprache %12s: %s\n", locale_name(plang->locale),
|
|
|
|
|
rcomp(plang->number, nold));
|
|
|
|
|
plang=plang->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
fprintf(F, "\n");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (full) {
|
|
|
|
|
for (i = 0; i < MAXRACES; i++) if (s->poprace[i]) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
fprintf(F, "%20s: %s\n", LOC(default_locale, rc_name(new_race[i], 1)),
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rcomp(s->poprace[i],o->poprace[i]));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2002-03-24 12:22:44 +01:00
|
|
|
|
for (i = 0; i < MAXRACES; i++) if (s->poprace[i] && playerrace(new_race[i])
|
|
|
|
|
&& i != RC_TEMPLATE && i != RC_CLONE) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
fprintf(F, "%20s: %s\n", LOC(default_locale, rc_name(new_race[i], 1)),
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
fprintf(F, "Reichtum Spieler: %s Silber\n",
|
2001-01-25 10:37:55 +01:00
|
|
|
|
pcomp(s->playermoney,o->playermoney));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
fprintf(F, "Reichtum Bauern: %s Silber\n",
|
2001-01-25 10:37:55 +01:00
|
|
|
|
pcomp(s->peasantmoney, o->peasantmoney));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
fprintf(F, "Reichtum gesamt: %s Silber\n\n",
|
|
|
|
|
pcomp(s->playermoney+s->peasantmoney, o->playermoney+o->peasantmoney));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(F, "\n\n");
|
|
|
|
|
|
2002-03-03 11:51:24 +01:00
|
|
|
|
for (i = 0; i != NMRTIMEOUT+1; ++i) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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) {
|
2002-03-03 11:51:24 +01:00
|
|
|
|
nmrs[min(NMRTIMEOUT,turn-f->lastorders)]++;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-03-03 11:51:24 +01:00
|
|
|
|
for (i = 0; i != NMRTIMEOUT+1; ++i) {
|
|
|
|
|
if(i == NMRTIMEOUT) {
|
2002-02-18 17:19:50 +01:00
|
|
|
|
fprintf(F, "+ NMRs:\t\t %d\n", nmrs[i]);
|
|
|
|
|
} else {
|
|
|
|
|
fprintf(F, "%d %s:\t\t %d\n", i,
|
|
|
|
|
i != 1 ? "NMRs" : "NMR ", nmrs[i]);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
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");
|
|
|
|
|
|
2002-02-18 17:19:50 +01:00
|
|
|
|
for (f = factions; f; f = f->next) {
|
|
|
|
|
out_faction(F, f);
|
|
|
|
|
}
|
|
|
|
|
|
2002-03-03 13:53:05 +01:00
|
|
|
|
#if NMRTIMEOUT
|
|
|
|
|
if (full) {
|
2002-02-18 17:19:50 +01:00
|
|
|
|
fprintf(F, "\n\nFactions with NMRs:\n");
|
2002-03-03 11:51:24 +01:00
|
|
|
|
for (i = NMRTIMEOUT; i > 0; --i) {
|
2002-02-18 17:19:50 +01:00
|
|
|
|
for(f=factions; f; f=f->next) {
|
2002-03-03 11:51:24 +01:00
|
|
|
|
if(i == NMRTIMEOUT) {
|
2002-02-18 17:19:50 +01:00
|
|
|
|
if(turn - f->lastorders >= i) {
|
|
|
|
|
out_faction(F, f);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if(turn - f->lastorders == i) {
|
|
|
|
|
out_faction(F, f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-03-03 13:53:05 +01:00
|
|
|
|
#endif
|
2002-07-23 09:23:28 +02:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fclose(F);
|
|
|
|
|
|
2001-01-31 00:16:17 +01:00
|
|
|
|
if (full) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#ifdef PLAYER_CSV
|
2002-05-11 23:37:04 +02:00
|
|
|
|
FILE *F;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
region * r;
|
|
|
|
|
#endif
|
|
|
|
|
printf("Schreibe Liste der Adressen (adressen)...\n");
|
2001-01-31 00:16:17 +01:00
|
|
|
|
writeadresses();
|
2001-02-28 19:25:25 +01:00
|
|
|
|
writenewssubscriptions();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
writeforward();
|
|
|
|
|
|
2002-05-11 23:37:04 +02:00
|
|
|
|
printf("writing date & turn\n");
|
|
|
|
|
writeturn();
|
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);
|
2002-03-31 10:46:36 +02:00
|
|
|
|
fputs("id;name;email;info;age;x;y;nmr;score;race;magic;units;people;money", F);
|
|
|
|
|
if (r) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fputs("id;name;email;info;age;x;y;nmr;score;race;magic;units;people;money", F);
|
2002-03-31 10:46:36 +02:00
|
|
|
|
for (f=factions;f;f=f->next) {
|
|
|
|
|
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,
|
|
|
|
|
f->race->name[0], neue_gebiete[f->magiegebiet],
|
|
|
|
|
f->no_units, f->number, f->money);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
fclose(F);
|
|
|
|
|
#endif
|
|
|
|
|
writemonument();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/******* end summary ******/
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
eval_unit(struct opstack ** stack, const void * userdata) /* unit -> string */
|
|
|
|
|
{
|
|
|
|
|
const struct unit * u = opop(stack, const struct unit *);
|
|
|
|
|
const char * c = u?unitname(u):"nobody";
|
|
|
|
|
size_t len = strlen(c);
|
|
|
|
|
opush(stack, strcpy(balloc(len+1), c));
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
static void
|
|
|
|
|
eval_unitname(struct opstack ** stack, const void * userdata) /* unit -> string */
|
|
|
|
|
{
|
|
|
|
|
const struct unit * u = opop(stack, const struct unit *);
|
|
|
|
|
const char * c = u?u->name:"nobody";
|
|
|
|
|
size_t len = strlen(c);
|
|
|
|
|
opush(stack, strcpy(balloc(len+1), c));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
eval_unitid(struct opstack ** stack, const void * userdata) /* unit -> int */
|
|
|
|
|
{
|
|
|
|
|
const struct unit * u = opop(stack, const struct unit *);
|
|
|
|
|
const char * c = u?u->name:"nobody";
|
|
|
|
|
size_t len = strlen(c);
|
|
|
|
|
opush(stack, strcpy(balloc(len+1), c));
|
|
|
|
|
}
|
|
|
|
|
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
static void
|
|
|
|
|
eval_faction(struct opstack ** stack, const void * userdata) /* faction -> string */
|
|
|
|
|
{
|
|
|
|
|
const struct faction * f = opop(stack, const struct faction *);
|
|
|
|
|
const char * c = factionname(f);
|
|
|
|
|
size_t len = strlen(c);
|
|
|
|
|
opush(stack, strcpy(balloc(len+1), c));
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-02 22:36:12 +02:00
|
|
|
|
#ifdef ALLIANCES
|
|
|
|
|
static void
|
|
|
|
|
eval_alliance(struct opstack ** stack, const void * userdata) /* faction -> string */
|
|
|
|
|
{
|
|
|
|
|
const struct alliance * al = opop(stack, const struct alliance *);
|
|
|
|
|
const char * c = alliancename(al);
|
|
|
|
|
if (c!=NULL) {
|
|
|
|
|
size_t len = strlen(c);
|
|
|
|
|
opush(stack, strcpy(balloc(len+1), c));
|
|
|
|
|
}
|
|
|
|
|
else opush(stack, NULL);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
static void
|
|
|
|
|
eval_region(struct opstack ** stack, const void * userdata) /* region -> string */
|
|
|
|
|
{
|
|
|
|
|
const struct faction * f = (const struct faction *)userdata;
|
|
|
|
|
const struct region * r = opop(stack, const struct region *);
|
|
|
|
|
const char * c = regionname(r, f);
|
|
|
|
|
size_t len = strlen(c);
|
|
|
|
|
opush(stack, strcpy(balloc(len+1), c));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
eval_ship(struct opstack ** stack, const void * userdata) /* ship -> string */
|
|
|
|
|
{
|
|
|
|
|
const struct ship * u = opop(stack, const struct ship *);
|
|
|
|
|
const char * c = u?shipname(u):"nobody";
|
|
|
|
|
size_t len = strlen(c);
|
|
|
|
|
opush(stack, strcpy(balloc(len+1), c));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
eval_building(struct opstack ** stack, const void * userdata) /* building -> string */
|
|
|
|
|
{
|
|
|
|
|
const struct building * u = opop(stack, const struct building *);
|
|
|
|
|
const char * c = u?buildingname(u):"nobody";
|
|
|
|
|
size_t len = strlen(c);
|
|
|
|
|
opush(stack, strcpy(balloc(len+1), c));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
eval_resource(struct opstack ** stack, const void * userdata)
|
|
|
|
|
{
|
|
|
|
|
const faction * report = (const faction*)userdata;
|
|
|
|
|
int j = opop(stack, int);
|
|
|
|
|
struct resource_type * res = opop(stack, struct resource_type *);
|
2001-04-16 16:34:19 +02:00
|
|
|
|
|
2001-04-22 07:36:50 +02:00
|
|
|
|
const char * c = LOC(report->locale, resourcename(res, j!=1));
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
opush(stack, strcpy(balloc(strlen(c)+1), c));
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
static void
|
|
|
|
|
eval_race(struct opstack ** stack, const void * userdata)
|
|
|
|
|
{
|
|
|
|
|
const faction * report = (const faction*)userdata;
|
|
|
|
|
int j = opop(stack, int);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
const race * r = opop(stack, const race *);
|
2001-04-16 16:34:19 +02:00
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
const char * c = LOC(report->locale, rc_name(r, j!=1));
|
2001-04-16 16:34:19 +02:00
|
|
|
|
opush(stack, strcpy(balloc(strlen(c)+1), c));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
eval_direction(struct opstack ** stack, const void * userdata)
|
|
|
|
|
{
|
|
|
|
|
const faction * report = (const faction*)userdata;
|
|
|
|
|
int i = opop(stack, int);
|
|
|
|
|
|
2001-04-22 07:36:50 +02:00
|
|
|
|
const char * c = LOC(report->locale, directions[i]);
|
2001-04-16 16:34:19 +02:00
|
|
|
|
opush(stack, strcpy(balloc(strlen(c)+1), c));
|
|
|
|
|
}
|
|
|
|
|
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
static void
|
|
|
|
|
eval_skill(struct opstack ** stack, const void * userdata)
|
|
|
|
|
{
|
|
|
|
|
const faction * report = (const faction*)userdata;
|
2002-02-23 12:27:19 +01:00
|
|
|
|
skill_t sk = (skill_t)opop(stack, int);
|
2001-04-16 16:34:19 +02:00
|
|
|
|
const char * c = skillname(sk, report->locale);
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
opush(stack, strcpy(balloc(strlen(c)+1), c));
|
2001-05-20 09:23:54 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
eval_int36(struct opstack ** stack, const void * userdata)
|
|
|
|
|
{
|
|
|
|
|
int i = opop(stack, int);
|
|
|
|
|
const char * c = itoa36(i);
|
|
|
|
|
opush(stack, strcpy(balloc(strlen(c)+1), c));
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
unused(userdata);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_init(void)
|
|
|
|
|
{
|
2002-09-02 22:36:12 +02:00
|
|
|
|
#ifdef ALLIANCES
|
|
|
|
|
add_function("alliance", &eval_alliance);
|
|
|
|
|
#endif
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
add_function("region", &eval_region);
|
|
|
|
|
add_function("resource", &eval_resource);
|
2001-04-16 16:34:19 +02:00
|
|
|
|
add_function("race", &eval_race);
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
add_function("faction", &eval_faction);
|
|
|
|
|
add_function("ship", &eval_ship);
|
|
|
|
|
add_function("unit", &eval_unit);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
add_function("unit.name", &eval_unitname);
|
|
|
|
|
add_function("unit.id", &eval_unitid);
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
add_function("building", &eval_building);
|
|
|
|
|
add_function("skill", &eval_skill);
|
2001-04-16 16:34:19 +02:00
|
|
|
|
add_function("direction", &eval_direction);
|
2001-05-20 09:23:54 +02:00
|
|
|
|
add_function("int36", &eval_int36);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
add_function("trail", &eval_trail);
|
2002-03-29 05:23:51 +01:00
|
|
|
|
register_function((pf_generic)view_neighbours, "view_neighbours");
|
|
|
|
|
register_function((pf_generic)view_regatta, "view_regatta");
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
}
|