2001-01-25 10:37:55 +01:00
|
|
|
|
/* vi: set ts=2:
|
|
|
|
|
*
|
2001-04-16 16:34:19 +02:00
|
|
|
|
*
|
2003-07-29 11:48:03 +02:00
|
|
|
|
* Eressea PB(E)M host Copyright (C) 1998-2003
|
2001-01-25 10:37:55 +01:00
|
|
|
|
* 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 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>
|
|
|
|
|
|
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 */
|
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 */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
#include <kernel/alchemy.h>
|
2004-06-27 18:56:01 +02:00
|
|
|
|
#include <kernel/alliance.h>
|
2004-06-21 18:45:27 +02:00
|
|
|
|
#include <kernel/border.h>
|
|
|
|
|
#include <kernel/build.h>
|
|
|
|
|
#include <kernel/building.h>
|
|
|
|
|
#include <kernel/faction.h>
|
|
|
|
|
#include <kernel/group.h>
|
|
|
|
|
#include <kernel/item.h>
|
|
|
|
|
#include <kernel/karma.h>
|
|
|
|
|
#include <kernel/message.h>
|
|
|
|
|
#include <kernel/movement.h>
|
|
|
|
|
#include <kernel/objtypes.h>
|
|
|
|
|
#include <kernel/order.h>
|
|
|
|
|
#include <kernel/plane.h>
|
|
|
|
|
#include <kernel/pool.h>
|
|
|
|
|
#include <kernel/race.h>
|
|
|
|
|
#include <kernel/region.h>
|
|
|
|
|
#include <kernel/render.h>
|
|
|
|
|
#include <kernel/reports.h>
|
|
|
|
|
#include <kernel/resources.h>
|
|
|
|
|
#include <kernel/save.h>
|
|
|
|
|
#include <kernel/ship.h>
|
|
|
|
|
#include <kernel/skill.h>
|
|
|
|
|
#include <kernel/teleport.h>
|
|
|
|
|
#include <kernel/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>
|
2005-04-27 15:06:35 +02:00
|
|
|
|
#include <errno.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#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>
|
|
|
|
|
|
2005-04-27 14:18:05 +02:00
|
|
|
|
#ifdef HAVE_STAT
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
extern int quiet;
|
2004-04-22 00:09:39 +02:00
|
|
|
|
extern int *storms;
|
|
|
|
|
extern int weeks_per_month;
|
|
|
|
|
extern int months_per_year;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
boolean nocr = false;
|
|
|
|
|
boolean nonr = false;
|
2005-04-30 16:00:02 +02:00
|
|
|
|
boolean nosh = false;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
boolean nomer = false;
|
2002-02-16 11:37:18 +01:00
|
|
|
|
boolean noreports = false;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
2004-05-04 21:24:03 +02:00
|
|
|
|
static const char*
|
2004-05-04 21:34:35 +02:00
|
|
|
|
MailitPath(void)
|
2004-05-04 21:24:03 +02:00
|
|
|
|
{
|
|
|
|
|
static const char * value = NULL;
|
|
|
|
|
if (value==NULL) {
|
|
|
|
|
value = get_param(global.parameters, "report.mailit");
|
|
|
|
|
}
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
2004-04-10 22:25:40 +02:00
|
|
|
|
int t = turn - FirstTurn();
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
|
|
|
|
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];
|
2004-04-10 22:25:40 +02:00
|
|
|
|
int t = turn - FirstTurn();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
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];
|
2004-04-10 22:25:40 +02:00
|
|
|
|
int t = turn - FirstTurn();
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
|
|
|
|
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];
|
2004-04-10 22:25:40 +02:00
|
|
|
|
int t = turn - FirstTurn();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
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];
|
2004-04-10 22:25:40 +02:00
|
|
|
|
int t = turn - FirstTurn();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2005-01-19 21:33:13 +01:00
|
|
|
|
rpsnr(F, src, 0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2004-01-19 00:57:43 +01:00
|
|
|
|
int k, itemanz, costtyp;
|
|
|
|
|
resource_t res;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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){
|
2005-02-05 23:52:59 +01:00
|
|
|
|
if (sp->sptyp & SPELLLEVEL) {
|
|
|
|
|
sprintf(buf, " %d %s", itemanz, LOC(lang, resname(res, itemanz!=1)));
|
|
|
|
|
if (costtyp == SPC_LEVEL || costtyp == SPC_LINEAR ) {
|
|
|
|
|
scat(" * Stufe");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2005-02-12 14:42:15 +01:00
|
|
|
|
if (costtyp == SPC_LEVEL || costtyp == SPC_LINEAR ) {
|
|
|
|
|
itemanz *= sp->level;
|
|
|
|
|
}
|
2005-02-05 23:52:59 +01:00
|
|
|
|
sprintf(buf, " %d %s", itemanz, LOC(lang, resname(res, itemanz!=1)));
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * owner = shipowner(sh);
|
2002-05-10 18:09:07 +02:00
|
|
|
|
a = sh->attribs;
|
|
|
|
|
r = sh->region;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if((owner) != NULL){
|
2002-05-10 18:09:07 +02:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
rps_nowrap(FILE * F, const char *s)
|
|
|
|
|
{
|
|
|
|
|
const char *x = s;
|
|
|
|
|
int indent = 0;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
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
|
2003-07-29 11:48:03 +02:00
|
|
|
|
&& !fval(u, UFL_PARTEITARNUNG)) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
marker = '!';
|
|
|
|
|
} else {
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if(dh && !fval(u, UFL_PARTEITARNUNG)) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-04-22 00:09:39 +02:00
|
|
|
|
static void
|
|
|
|
|
rp_battles(FILE * F, faction * f)
|
|
|
|
|
{
|
|
|
|
|
if (f->battles!=NULL) {
|
|
|
|
|
struct bmsg * bm;
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, LOC(f->locale, "section_battle"), false);
|
|
|
|
|
rnl(F);
|
|
|
|
|
for (bm=f->battles;bm;bm=bm->next) {
|
|
|
|
|
RENDER(f, buf, 80, ("battle::header", "region", bm->r));
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
rp_messages(F, bm->msgs, f, 0, true, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
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)) {
|
2004-09-12 11:55:47 +02:00
|
|
|
|
strncpy(buf, rname(r, f->locale), NAMESIZE);
|
|
|
|
|
buf[NAMESIZE]=0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} else {
|
2004-09-12 11:55:47 +02:00
|
|
|
|
strncpy(buf, rname(r, f->locale), NAMESIZE);
|
|
|
|
|
buf[NAMESIZE]=0;
|
|
|
|
|
sprintf(buf+strlen(buf), " (%d,%d%s%s)", region_x(r,f), region_y(r,f), pl?",":"", pl?pl->name:"");
|
2001-04-16 16:34:19 +02:00
|
|
|
|
}
|
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);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
2004-05-22 01:02:19 +02:00
|
|
|
|
const char * rn = f_regionid(r, f);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
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(".");
|
|
|
|
|
|
2005-04-23 11:47:03 +02:00
|
|
|
|
if (r->display && r->display[0]) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
scat(" ");
|
|
|
|
|
scat(r->display);
|
|
|
|
|
|
|
|
|
|
n = r->display[strlen(r->display) - 1];
|
|
|
|
|
if (n != '!' && n != '?' && n != '.')
|
|
|
|
|
scat(".");
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-18 18:40:21 +01:00
|
|
|
|
{
|
|
|
|
|
const unit * u = region_owner(r);
|
|
|
|
|
if (u) {
|
|
|
|
|
scat(" Die Region ist im Besitz von ");
|
|
|
|
|
scat(factionname(u->faction));
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2004-05-25 10:53:59 +02:00
|
|
|
|
if (partial==0 && rplane(r) == get_astralplane() &&
|
2001-01-25 10:37:55 +01:00
|
|
|
|
!is_cursed(r->attribs, C_ASTRALBLOCK, 0)) {
|
|
|
|
|
/* Sonderbehandlung Teleport-Ebene */
|
2004-05-25 10:53:59 +02:00
|
|
|
|
region_list *rl = astralregions(r, inhabitable);
|
2004-02-21 13:18:29 +01:00
|
|
|
|
region_list *rl2;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
if (rl) {
|
|
|
|
|
strcpy(buf, "Schemen der Regionen ");
|
|
|
|
|
rl2 = rl;
|
|
|
|
|
while(rl2) {
|
2004-02-21 13:18:29 +01:00
|
|
|
|
scat(f_regionid(rl2->data, f));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-05-13 19:51:22 +02:00
|
|
|
|
static 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
|
|
|
|
{
|
2005-04-10 18:11:20 +02:00
|
|
|
|
const unit *u;
|
|
|
|
|
int number, p;
|
|
|
|
|
message * m;
|
|
|
|
|
item *itm, *items = NULL;
|
|
|
|
|
p = rpeasants(r);
|
|
|
|
|
number = 0;
|
|
|
|
|
|
|
|
|
|
/* z<>hlen */
|
|
|
|
|
for (u = r->units; u; u = u->next)
|
|
|
|
|
if (u->faction == f && u->race != new_race[RC_SPELL]) {
|
|
|
|
|
for (itm=u->items;itm;itm=itm->next) {
|
|
|
|
|
i_change(&items, itm->type, itm->number);
|
|
|
|
|
}
|
|
|
|
|
number += u->number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Ausgabe */
|
|
|
|
|
rnl(F);
|
|
|
|
|
m = msg_message("nr_stat_header", "region", r);
|
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
msg_release(m);
|
|
|
|
|
rnl(F);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-04-10 18:11:20 +02:00
|
|
|
|
/* Region */
|
|
|
|
|
if (landregion(rterrain(r)) && rmoney(r)) {
|
2005-04-11 21:10:38 +02:00
|
|
|
|
m = msg_message("nr_stat_maxentertainment", "max", entertainmoney(r));
|
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
msg_release(m);
|
2005-04-10 18:11:20 +02:00
|
|
|
|
}
|
|
|
|
|
if (production(r) && (!rterrain(r) == T_OCEAN || f->race == new_race[RC_AQUARIAN])) {
|
2005-04-11 21:10:38 +02:00
|
|
|
|
m = msg_message("nr_stat_salary", "max", fwage(r, f, true));
|
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
msg_release(m);
|
2005-04-10 18:11:20 +02:00
|
|
|
|
}
|
|
|
|
|
if (p) {
|
2005-04-11 21:10:38 +02:00
|
|
|
|
m = msg_message("nr_stat_recruits", "max", p / RECRUITFRACTION);
|
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
msg_release(m);
|
|
|
|
|
|
|
|
|
|
if (!TradeDisabled()) {
|
|
|
|
|
if (buildingtype_exists(r, bt_find("caravan"))) {
|
|
|
|
|
m = msg_message("nr_stat_luxuries", "max",
|
|
|
|
|
(p * 2) / TRADE_FRACTION);
|
|
|
|
|
} else {
|
|
|
|
|
m = msg_message("nr_stat_luxuries", "max",
|
|
|
|
|
p / TRADE_FRACTION);
|
|
|
|
|
}
|
2005-04-10 18:11:20 +02:00
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
msg_release(m);
|
2005-04-11 21:10:38 +02:00
|
|
|
|
}
|
2005-04-10 18:11:20 +02:00
|
|
|
|
}
|
|
|
|
|
/* Info <20>ber Einheiten */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-04-11 21:10:38 +02:00
|
|
|
|
m = msg_message("nr_stat_people", "max", number);
|
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
msg_release(m);
|
|
|
|
|
|
|
|
|
|
for (itm = items; itm; itm=itm->next) {
|
|
|
|
|
sprintf(buf, "%s: %d",
|
|
|
|
|
LOC(f->locale, resourcename(itm->type->rtype, GR_PLURAL)),
|
|
|
|
|
itm->number);
|
|
|
|
|
rps(F, buf);
|
|
|
|
|
}
|
|
|
|
|
while (items) i_free(i_remove(&items, items));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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) {
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (u->ship && !fval(u, UFL_OWNER))
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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) {
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (u->ship && !fval(u, UFL_OWNER))
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-16 13:15:47 +02:00
|
|
|
|
static int
|
|
|
|
|
buildingmaintenance(const building * b, const resource_type * rtype)
|
|
|
|
|
{
|
|
|
|
|
const building_type * bt = b->type;
|
|
|
|
|
int c, cost=0;
|
|
|
|
|
static boolean init = false;
|
|
|
|
|
static const curse_type * nocost_ct;
|
|
|
|
|
if (!init) { init = true; nocost_ct = ct_find("nocost"); }
|
|
|
|
|
if (curse_active(get_curse(b->attribs, nocost_ct))) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
for (c=0;bt->maintenance && bt->maintenance[c].number;++c) {
|
|
|
|
|
const maintenance * m = bt->maintenance + c;
|
|
|
|
|
if (m->rtype==rtype) {
|
|
|
|
|
if (fval(m, MTF_VARIABLE))
|
|
|
|
|
cost += (b->size * m->number);
|
|
|
|
|
else
|
|
|
|
|
cost += m->number;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return cost;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-24 23:49:51 +02:00
|
|
|
|
static int
|
2001-01-25 10:37:55 +01:00
|
|
|
|
order_template(FILE * F, faction * f)
|
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
region *r;
|
|
|
|
|
plane *pl;
|
2005-04-27 15:30:12 +02:00
|
|
|
|
region *last = lastregion(f);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
|
|
|
|
rps_nowrap(F, LOC(f->locale, "nr_template"));
|
|
|
|
|
rnl(F);
|
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
sprintf(buf, "%s %s \"%s\"", LOC(f->locale, "ERESSEA"), factionid(f), LOC(f->locale, "enterpasswd"));
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
|
|
|
|
sprintf(buf, "; ECHECK %s-w4 -r%d -v%s", (f->options & Pow(O_SILBERPOOL)) ? "-l " : "",
|
|
|
|
|
f->race->recruitcost, ECHECK_VERSION);
|
|
|
|
|
/* -v3.4: ECheck Version 3.4.x */
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-04-27 15:30:12 +02:00
|
|
|
|
for (r = firstregion(f); r != last; r = r->next) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit *u;
|
|
|
|
|
|
|
|
|
|
int dh = 0;
|
|
|
|
|
for (u = r->units; u; u = u->next)
|
|
|
|
|
if (u->faction == f && u->race != new_race[RC_SPELL]) {
|
|
|
|
|
order * ord;
|
|
|
|
|
if (!dh) {
|
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
|
|
|
|
pl = getplane(r);
|
|
|
|
|
if (pl && fval(pl, PFL_NOCOORDS)) {
|
|
|
|
|
sprintf(buf, "%s; %s", LOC(f->locale, parameters[P_REGION]), rname(r, f->locale));
|
|
|
|
|
} else if (pl && pl->id != 0) {
|
|
|
|
|
sprintf(buf, "%s %d,%d,%d ; %s", LOC(f->locale, parameters[P_REGION]), region_x(r,f),
|
|
|
|
|
region_y(r,f), pl->id, rname(r, f->locale));
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(buf, "%s %d,%d ; %s", LOC(f->locale, parameters[P_REGION]), region_x(r,f),
|
|
|
|
|
region_y(r,f), rname(r, f->locale));
|
|
|
|
|
}
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
sprintf(buf,"; ECheck Lohn %d", fwage(r,f,true));
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
dh = 1;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
sprintf(buf, "%s %s; %s [%d,%d$", LOC(u->faction->locale, parameters[P_UNIT]),
|
|
|
|
|
unitid(u), u->name, u->number, get_money(u));
|
|
|
|
|
if (u->building != NULL && fval(u, UFL_OWNER)) {
|
|
|
|
|
building * b = u->building;
|
|
|
|
|
int cost = buildingmaintenance(b, r_silver);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (cost > 0) {
|
|
|
|
|
scat(",U");
|
|
|
|
|
icat(cost);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#if TODO
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (buildingdaten[u->building->typ].spezial != 0) {
|
|
|
|
|
scat("+");
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#endif
|
2004-06-21 18:45:27 +02:00
|
|
|
|
} else if (u->ship) {
|
|
|
|
|
if (fval(u, UFL_OWNER))
|
|
|
|
|
scat(",S");
|
|
|
|
|
else
|
|
|
|
|
scat(",s");
|
|
|
|
|
scat(shipid(u->ship));
|
|
|
|
|
}
|
|
|
|
|
if (lifestyle(u) == 0)
|
|
|
|
|
scat(",I");
|
|
|
|
|
scat("]");
|
|
|
|
|
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
|
2005-05-01 13:32:24 +02:00
|
|
|
|
#ifndef LASTORDER
|
|
|
|
|
for (ord = u->old_orders; ord; ord = ord->next) {
|
|
|
|
|
/* this new order will replace the old defaults */
|
|
|
|
|
strcpy(buf, " ");
|
|
|
|
|
write_order(ord, u->faction->locale, buf+2, sizeof(buf)-2);
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2004-06-21 18:45:27 +02:00
|
|
|
|
for (ord = u->orders; ord; ord = ord->next) {
|
|
|
|
|
if (is_persistent(ord)) {
|
|
|
|
|
strcpy(buf, " ");
|
|
|
|
|
write_order(ord, u->faction->locale, buf+2, sizeof(buf)-2);
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
/* If the lastorder begins with an @ it should have
|
|
|
|
|
* been printed in the loop before. */
|
2005-04-30 19:07:46 +02:00
|
|
|
|
#ifdef LASTORDER
|
2004-06-21 18:45:27 +02:00
|
|
|
|
if (u->lastorder && !is_persistent(u->lastorder)) {
|
|
|
|
|
strcpy(buf, " ");
|
|
|
|
|
write_order(u->lastorder, u->faction->locale, buf+2, sizeof(buf)-2);
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
2005-04-30 19:07:46 +02:00
|
|
|
|
#endif
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
|
|
|
|
sprintf(buf, LOC(f->locale, parameters[P_NEXT]));
|
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
2005-04-24 23:49:51 +02:00
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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) {
|
2003-01-12 10:33:20 +01:00
|
|
|
|
int mode = alliedgroup(NULL, f, sf->faction, sf, HELP_ALL);
|
2002-12-14 16:49:18 +01:00
|
|
|
|
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) {
|
2003-01-12 10:33:20 +01:00
|
|
|
|
int mode = alliedgroup(NULL, f, sf->faction, sf, HELP_ALL);
|
2002-12-14 16:49:18 +01:00
|
|
|
|
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(" (");
|
2004-08-21 03:55:56 +02:00
|
|
|
|
if ((mode & HELP_ALL) == HELP_ALL) {
|
2002-12-14 16:49:18 +01:00
|
|
|
|
scat("Alles");
|
|
|
|
|
} else
|
|
|
|
|
for (h = 1; h < HELP_ALL; h *= 2) {
|
|
|
|
|
if ((mode & h) == h)
|
|
|
|
|
switch (h) {
|
2002-12-18 01:34:19 +01:00
|
|
|
|
case HELP_TRAVEL:
|
|
|
|
|
scat("Durchreise");
|
|
|
|
|
hh = 1;
|
|
|
|
|
break;
|
2002-12-14 16:49:18 +01:00
|
|
|
|
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
|
2002-12-18 18:40:21 +01:00
|
|
|
|
allies(FILE * F, const faction * f)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2002-12-18 18:40:21 +01:00
|
|
|
|
const group * g = f->groups;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-18 18:40:21 +01:00
|
|
|
|
#ifdef REGIONOWNERS
|
|
|
|
|
static void
|
|
|
|
|
enemies(FILE * F, const faction * f)
|
|
|
|
|
{
|
|
|
|
|
faction_list * flist = f->enemies;
|
|
|
|
|
if (flist!=NULL) {
|
|
|
|
|
strcpy(buf, "Wir liegen im Krieg mit ");
|
|
|
|
|
for (;flist!=NULL;flist = flist->next) {
|
|
|
|
|
const faction * enemy = flist->data;
|
|
|
|
|
scat(factionname(enemy));
|
|
|
|
|
if (flist->next) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
} else {
|
|
|
|
|
scat(".");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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
|
2004-05-04 21:24:03 +02:00
|
|
|
|
* "unbekannte Partei", wenn man es selbst ist... */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-05-04 21:24:03 +02:00
|
|
|
|
faction* guardians[512];
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-05-04 21:24:03 +02:00
|
|
|
|
int nextguard = 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-05-04 21:24:03 +02:00
|
|
|
|
unit *u;
|
|
|
|
|
int i;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-05-04 21:24:03 +02:00
|
|
|
|
boolean tarned = false;
|
|
|
|
|
/* Bewachung */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-12-18 18:40:21 +01:00
|
|
|
|
for (u = r->units; u; u = u->next) {
|
2004-05-04 21:24:03 +02:00
|
|
|
|
if (getguard(u)) {
|
|
|
|
|
faction *f = u->faction;
|
|
|
|
|
faction *fv = visible_faction(see, u);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-05-04 21:24:03 +02:00
|
|
|
|
if(fv != f && see != fv) {
|
|
|
|
|
f = fv;
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2004-05-04 21:24:03 +02:00
|
|
|
|
if (f != see && fval(u, UFL_PARTEITARNUNG)) {
|
|
|
|
|
tarned=true;
|
|
|
|
|
} else {
|
|
|
|
|
for (i=0;i!=nextguard;++i) if (guardians[i]==f) break;
|
|
|
|
|
if (i==nextguard) {
|
|
|
|
|
guardians[nextguard++] = f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-12-18 18:40:21 +01:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-12-18 18:40:21 +01:00
|
|
|
|
if (nextguard || tarned) {
|
|
|
|
|
strcpy(buf, "Die Region wird von ");
|
|
|
|
|
} else {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2004-05-04 21:24:03 +02:00
|
|
|
|
|
|
|
|
|
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");
|
2002-12-18 18:40:21 +01:00
|
|
|
|
}
|
2004-05-04 21:24:03 +02:00
|
|
|
|
scat(" bewacht.");
|
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, buf, 0, 0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)?'+':'*'));
|
2003-06-22 10:38:55 +02:00
|
|
|
|
#ifdef SHORTPWDS
|
|
|
|
|
if (f->shortpwds) {
|
|
|
|
|
shortpwd * spwd = f->shortpwds;
|
|
|
|
|
while (spwd) {
|
|
|
|
|
if (spwd->used) {
|
|
|
|
|
sprintf(buf, "Vertretung: %s", spwd->email);
|
|
|
|
|
rparagraph(F, buf, 6, '-');
|
|
|
|
|
}
|
|
|
|
|
spwd=spwd->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
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;
|
2005-04-23 11:47:03 +02:00
|
|
|
|
if (b->display && b->display[0]) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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)
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (u->building == b && fval(u, UFL_OWNER)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rpunit(F, f, u, 6, mode);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for (u = r->units; u; u = u->next)
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (u->building == b && !fval(u, UFL_OWNER))
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rpunit(F, f, u, 6, mode);
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-24 23:49:51 +02:00
|
|
|
|
static int
|
2005-04-27 23:03:08 +02:00
|
|
|
|
report(FILE *F, faction * f, struct seen_region ** seen, const faction_list * addresses,
|
2001-12-10 01:13:39 +01:00
|
|
|
|
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;
|
2005-04-27 15:30:12 +02:00
|
|
|
|
region * last = lastregion(f);
|
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 ix;
|
|
|
|
|
unsigned char op;
|
|
|
|
|
char buf2[80];
|
|
|
|
|
ix = Pow(O_STATISTICS);
|
|
|
|
|
wants_stats = (f->options & ix);
|
|
|
|
|
|
2005-04-25 18:31:36 +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),
|
2004-07-03 10:55:41 +02:00
|
|
|
|
LOC(f->locale, rc_name(f->race, 1)),
|
|
|
|
|
LOC(f->locale, mkname("school", neue_gebiete[f->magiegebiet])),
|
2001-12-10 01:13:39 +01:00
|
|
|
|
f->email);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
centre(F, buf, true);
|
2002-09-02 22:36:12 +02:00
|
|
|
|
if (f->alliance!=NULL) {
|
|
|
|
|
centre(F, alliancename(f->alliance), true);
|
|
|
|
|
}
|
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;
|
|
|
|
|
|
2004-12-22 01:53:12 +01:00
|
|
|
|
if (f->karma > 0) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
|
|
|
|
}
|
2004-12-22 01:56:27 +01:00
|
|
|
|
#ifdef HEROES
|
2004-10-19 00:03:32 +02:00
|
|
|
|
{
|
|
|
|
|
int maxh = maxheroes(f);
|
|
|
|
|
if (maxh) {
|
|
|
|
|
sprintf(buf, "Deine Partei hat %d Helden und kann maximal %d Helden ernennen.",
|
|
|
|
|
countheroes(f), maxh);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-12-20 11:09:59 +01:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-12-22 01:53:12 +01:00
|
|
|
|
if (f->items!=NULL) {
|
|
|
|
|
item * iclaim = f->items;
|
|
|
|
|
char * edit = buf;
|
|
|
|
|
strcpy(edit, LOC(f->locale, "claimable"));
|
|
|
|
|
edit += strlen(edit);
|
|
|
|
|
while (iclaim!=NULL) {
|
|
|
|
|
sprintf(edit, "%d %s", iclaim->number,
|
|
|
|
|
LOC(f->locale, resourcename(iclaim->type->rtype, iclaim->number)));
|
|
|
|
|
iclaim = iclaim->next;
|
|
|
|
|
if (iclaim!=NULL) {
|
|
|
|
|
strcat(edit, ", ");
|
|
|
|
|
}
|
|
|
|
|
edit += strlen(edit);
|
|
|
|
|
}
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
2004-04-22 00:09:39 +02:00
|
|
|
|
rp_battles(F, f);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
2003-03-14 20:50:54 +01:00
|
|
|
|
const char * description = NULL;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
requirement * m;
|
2003-05-28 18:24:28 +02:00
|
|
|
|
if (ptype!=NULL) {
|
|
|
|
|
const char * pname = resourcename(ptype->itype->rtype, 0);
|
|
|
|
|
m = ptype->itype->construction->materials;
|
|
|
|
|
if (ch==0) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, LOC(f->locale, "section_newpotions"), true);
|
|
|
|
|
ch = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, LOC(f->locale, pname), true);
|
|
|
|
|
sprintf(buf, "%s %d", LOC(f->locale, "nr_level"), ptype->level);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
sprintf(buf, "%s: ", LOC(f->locale, "nr_herbsrequired"));
|
|
|
|
|
while (m->number) {
|
|
|
|
|
scat(LOC(f->locale, resourcename(oldresourcetype[m->type], 0)));
|
|
|
|
|
++m;
|
|
|
|
|
if (m->number) scat(", ");
|
|
|
|
|
}
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
2004-08-07 09:42:22 +02:00
|
|
|
|
description = ptype->text;
|
|
|
|
|
if (description==NULL || f->locale!=find_locale("de")) {
|
2004-09-23 01:17:15 +02:00
|
|
|
|
const char * potiontext = mkname("potion", pname);
|
2004-08-07 09:42:22 +02:00
|
|
|
|
description = LOC(f->locale, potiontext);
|
|
|
|
|
if (strcmp(description, potiontext)==0) {
|
|
|
|
|
/* string not found */
|
|
|
|
|
description = ptype->text;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-05-28 18:24:28 +02:00
|
|
|
|
centre(F, description, true);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
|
2002-12-18 18:40:21 +01:00
|
|
|
|
#ifdef REGIONOWNERS
|
|
|
|
|
enemies(F, f);
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
allies(F, f);
|
|
|
|
|
|
|
|
|
|
rpline(F);
|
|
|
|
|
|
|
|
|
|
anyunits = 0;
|
|
|
|
|
|
2005-04-27 15:30:12 +02:00
|
|
|
|
for (r=firstregion(f);r!=last;r=r->next) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
boolean unit_in_region = false;
|
|
|
|
|
boolean durchgezogen_in_region = false;
|
|
|
|
|
int turm_sieht_region = false;
|
2005-04-27 23:03:08 +02:00
|
|
|
|
seen_region * sd = find_seen(seen, r);
|
2004-01-19 00:57:43 +01:00
|
|
|
|
if (sd==NULL) continue;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
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);
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (!TradeDisabled() && rterrain(r) != T_OCEAN && rpeasants(r)/TRADE_FRACTION > 0) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rnl(F);
|
|
|
|
|
prices(F, r, f);
|
|
|
|
|
}
|
|
|
|
|
guards(F, r, f);
|
|
|
|
|
durchreisende(F, r, f);
|
|
|
|
|
}
|
2002-12-18 18:40:21 +01:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* 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) {
|
|
|
|
|
faction *of = NULL;
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
|
|
|
|
|
|
|
|
|
/* Gewicht feststellen */
|
|
|
|
|
|
2005-04-17 18:02:13 +02:00
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->ship == sh && fval(u, UFL_OWNER)) {
|
|
|
|
|
of = u->faction;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (of == f) {
|
|
|
|
|
int n = 0, p = 0;
|
|
|
|
|
getshipweight(sh, &n, &p);
|
2005-04-17 20:25:11 +02:00
|
|
|
|
n = (n+99) / 100; /* 1 Silber = 1 GE */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-04-17 18:02:13 +02:00
|
|
|
|
sprintf(buf, "%s, %s, (%d/%d)", shipname(sh),
|
2005-04-17 20:25:11 +02:00
|
|
|
|
LOC(f->locale, sh->type->name[0]), n, shipcapacity(sh) / 100);
|
2005-04-17 18:02:13 +02:00
|
|
|
|
} else {
|
|
|
|
|
sprintf(buf, "%s, %s", shipname(sh), LOC(f->locale, sh->type->name[0]));
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-04-17 18:02:13 +02:00
|
|
|
|
assert(sh->type->construction->improvement==NULL); /* sonst ist construction::size nicht ship_type::maxsize */
|
|
|
|
|
if (sh->size!=sh->type->construction->maxsize) {
|
|
|
|
|
sprintf(buf+strlen(buf), ", %s (%d/%d)",
|
|
|
|
|
LOC(f->locale, "nr_undercons"), sh->size,
|
|
|
|
|
sh->type->construction->maxsize);
|
|
|
|
|
}
|
|
|
|
|
if (sh->damage) {
|
|
|
|
|
sprintf(buf+strlen(buf), ", %d%% %s",
|
|
|
|
|
sh->damage*100/(sh->size*DAMAGE_SCALE),
|
|
|
|
|
LOC(f->locale, "nr_damaged"));
|
|
|
|
|
}
|
|
|
|
|
if (rterrain(r) != T_OCEAN) {
|
|
|
|
|
if (sh->coast != NODIRECTION) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
scat(LOC(f->locale, coasts[sh->coast]));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ch = 0;
|
2005-04-23 11:47:03 +02:00
|
|
|
|
if (sh->display && sh->display[0]) {
|
2005-04-17 18:02:13 +02:00
|
|
|
|
scat("; ");
|
|
|
|
|
scat(sh->display);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-04-17 18:02:13 +02:00
|
|
|
|
ch = sh->display[strlen(sh->display) - 1];
|
|
|
|
|
}
|
|
|
|
|
if (ch != '!' && ch != '?' && ch != '.')
|
|
|
|
|
scat(".");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-04-17 18:02:13 +02:00
|
|
|
|
rparagraph(F, buf, 2, 0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-04-17 18:02:13 +02:00
|
|
|
|
print_curses(F,f,sh,TYP_SHIP,4);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-04-17 18:02:13 +02:00
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->ship == sh && fval(u, UFL_OWNER)) {
|
|
|
|
|
rpunit(F, f, u, 6, sd->mode);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->ship == sh && !fval(u, UFL_OWNER)) {
|
|
|
|
|
rpunit(F, f, u, 6, sd->mode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
|
|
|
|
rpline(F);
|
|
|
|
|
}
|
|
|
|
|
if (f->no != MONSTER_FACTION) {
|
|
|
|
|
if (!anyunits) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, LOC(f->locale, "nr_youaredead"), 0, 0);
|
|
|
|
|
} else {
|
|
|
|
|
list_address(F, f, addresses);
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-04-24 23:49:51 +02:00
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FILE *
|
|
|
|
|
openbatch(void)
|
|
|
|
|
{
|
2004-05-04 21:24:03 +02:00
|
|
|
|
faction *f;
|
|
|
|
|
FILE * BAT = NULL;
|
|
|
|
|
|
|
|
|
|
/* falls und mind. ein internet spieler gefunden wird, schreibe den
|
|
|
|
|
* header des batch files. ab nun kann BAT verwendet werden, um zu
|
|
|
|
|
* pruefen, ob netspieler vorhanden sind und ins mailit batch
|
|
|
|
|
* geschrieben werden darf. */
|
|
|
|
|
|
|
|
|
|
for (f = factions; f; f = f->next) {
|
|
|
|
|
|
|
|
|
|
/* bei "internet:" verschicken wir die mail per batchfile. f<>r
|
|
|
|
|
* unix kann man alles in EIN batchfile schreiben, als
|
|
|
|
|
* sogenanntes "herefile". Konnte der batchfile nicht geoeffnet
|
|
|
|
|
* werden, schreiben wir die reports einzeln. der BAT file wird
|
|
|
|
|
* nur gemacht, wenn es auch internet benutzer gibt. */
|
|
|
|
|
|
|
|
|
|
if (f->email) {
|
|
|
|
|
sprintf(buf, "%s/mailit", reportpath());
|
|
|
|
|
if ((BAT = fopen(buf, "w")) == NULL)
|
|
|
|
|
log_error(("mailit konnte nicht ge<67>ffnet werden!\n"));
|
|
|
|
|
else
|
|
|
|
|
fprintf(BAT,
|
|
|
|
|
"#!/bin/sh\n\n"
|
|
|
|
|
"# MAILIT shell file, vom Eressea Host generiert\n#\n"
|
|
|
|
|
"# Verwendung: nohup mailit &\n#\n\n"
|
|
|
|
|
"PATH=%s\n\n"
|
|
|
|
|
"chmod 755 *.sh\n"
|
|
|
|
|
"\n", MailitPath());
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-05-04 21:24:03 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return BAT;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
closebatch(FILE * BAT)
|
|
|
|
|
{
|
2004-05-04 21:24:03 +02:00
|
|
|
|
if (BAT) {
|
|
|
|
|
fputs("\n", BAT);
|
|
|
|
|
fclose(BAT);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2004-04-22 00:09:39 +02:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
2005-04-27 23:03:08 +02:00
|
|
|
|
static void
|
|
|
|
|
view_default(struct seen_region ** seen, region *r, faction *f)
|
2002-03-29 05:23:51 +01:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
2005-04-27 23:03:08 +02:00
|
|
|
|
if (!b) add_seen(seen, r2, see_neighbour, false);
|
2002-03-29 05:23:51 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2005-04-27 23:03:08 +02:00
|
|
|
|
view_neighbours(struct seen_region ** seen, region * r, faction * f)
|
2002-03-29 05:23:51 +01:00
|
|
|
|
{
|
|
|
|
|
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) {
|
2005-04-27 23:03:08 +02:00
|
|
|
|
if (add_seen(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;
|
|
|
|
|
}
|
2005-04-27 23:03:08 +02:00
|
|
|
|
if (!b) add_seen(seen, r3, see_neighbour, false);
|
2002-03-29 05:23:51 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2005-04-27 23:03:08 +02:00
|
|
|
|
recurse_regatta(struct seen_region ** seen, region *center, region *r, faction *f, int maxdist)
|
2002-03-29 05:23:51 +01:00
|
|
|
|
{
|
|
|
|
|
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) {
|
2005-04-27 23:03:08 +02:00
|
|
|
|
if (add_seen(seen, r2, see_far, false)) {
|
|
|
|
|
recurse_regatta(seen, center, r2, f, maxdist);
|
2002-03-29 05:23:51 +01:00
|
|
|
|
}
|
2005-04-27 23:03:08 +02:00
|
|
|
|
} else add_seen(seen, r2, see_neighbour, false);
|
2002-03-29 05:23:51 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2005-04-27 23:03:08 +02:00
|
|
|
|
view_regatta(struct seen_region ** seen, region * r, faction * f)
|
2002-03-29 05:23:51 +01:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-04-27 23:03:08 +02:00
|
|
|
|
recurse_regatta(seen, r, r, f, skill/2);
|
2002-03-29 05:23:51 +01:00
|
|
|
|
}
|
|
|
|
|
|
2005-01-07 02:14:09 +01:00
|
|
|
|
static void
|
|
|
|
|
global_report(const char * filename)
|
|
|
|
|
{
|
|
|
|
|
FILE * F = fopen(filename, "w");
|
|
|
|
|
region * r;
|
|
|
|
|
faction * f;
|
|
|
|
|
faction * monsters = findfaction(MONSTER_FACTION);
|
|
|
|
|
faction_list * addresses = NULL;
|
2005-04-27 23:03:08 +02:00
|
|
|
|
struct seen_region ** seen;
|
2005-01-07 02:14:09 +01:00
|
|
|
|
|
|
|
|
|
if (!monsters) return;
|
|
|
|
|
if (!F) return;
|
|
|
|
|
|
2005-04-27 23:03:08 +02:00
|
|
|
|
/* list of all addresses */
|
2005-01-07 02:14:09 +01:00
|
|
|
|
for (f=factions;f;f=f->next) {
|
|
|
|
|
faction_list * flist = calloc(1, sizeof(faction_list));
|
|
|
|
|
flist->data = f;
|
|
|
|
|
flist->next = addresses;
|
|
|
|
|
addresses = flist;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-27 23:03:08 +02:00
|
|
|
|
seen = seen_init();
|
|
|
|
|
for (r = regions; r; r = r->next) {
|
|
|
|
|
add_seen(seen, r, see_unit, true);
|
|
|
|
|
}
|
|
|
|
|
report_computer(F, monsters, seen, addresses, time(NULL));
|
|
|
|
|
seen_done(seen);
|
|
|
|
|
|
2005-01-07 02:14:09 +01:00
|
|
|
|
fclose(F);
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-27 23:03:08 +02:00
|
|
|
|
region_list *
|
|
|
|
|
get_regions_distance(region * root, int radius)
|
|
|
|
|
{
|
|
|
|
|
region_list * rptr, * rlist = NULL;
|
|
|
|
|
region_list ** rp = &rlist;
|
|
|
|
|
add_regionlist(rp, root);
|
|
|
|
|
fset(root, FL_MARK);
|
|
|
|
|
while (*rp) {
|
|
|
|
|
region_list * r = *rp;
|
|
|
|
|
direction_t d;
|
|
|
|
|
rp = &r->next;
|
|
|
|
|
for (d=0;d!=MAXDIRECTIONS;++d) {
|
|
|
|
|
region * rn = rconnect(r->data, d);
|
2005-04-28 00:29:11 +02:00
|
|
|
|
if (rn!=NULL && !fval(rn, FL_MARK) && distance(rn, root)<=radius) {
|
2005-04-27 23:03:08 +02:00
|
|
|
|
add_regionlist(rp, rn);
|
|
|
|
|
fset(rn, FL_MARK);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (rptr=rlist;rptr;rptr=rptr->next) {
|
|
|
|
|
freset(rptr->data, FL_MARK);
|
|
|
|
|
}
|
|
|
|
|
return rlist;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct seen_region **
|
2001-01-25 10:37:55 +01:00
|
|
|
|
prepare_report(faction * f)
|
|
|
|
|
{
|
2004-02-21 13:19:50 +01:00
|
|
|
|
region * r;
|
2005-04-27 15:30:12 +02:00
|
|
|
|
region * end = lastregion(f);
|
2005-04-27 23:03:08 +02:00
|
|
|
|
struct seen_region ** seen = seen_init();
|
|
|
|
|
|
|
|
|
|
static const struct building_type * bt_lighthouse = NULL;
|
|
|
|
|
if (bt_lighthouse==NULL) bt_lighthouse = bt_find("lighthouse");
|
|
|
|
|
|
2005-04-27 15:30:12 +02: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;
|
2005-04-27 23:03:08 +02:00
|
|
|
|
int light = 0;
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-04-27 23:03:08 +02:00
|
|
|
|
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->faction == f) {
|
|
|
|
|
if (u->building && u->building->type==bt_lighthouse) {
|
|
|
|
|
int r = lighthouse_range(u->building, f);
|
|
|
|
|
if (r>light) light = r;
|
|
|
|
|
}
|
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;
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (fval(u, UFL_DISBELIEVES)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
dis = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-27 23:03:08 +02:00
|
|
|
|
if (light) {
|
|
|
|
|
/* we are in a lighthouse. add the others! */
|
|
|
|
|
region_list * rlist = get_regions_distance(r, light);
|
|
|
|
|
region_list * rp = rlist;
|
|
|
|
|
while (rp) {
|
|
|
|
|
region * r = rp->data;
|
|
|
|
|
if (rterrain(r) == T_OCEAN) {
|
|
|
|
|
add_seen(seen, r, see_lighthouse, false);
|
|
|
|
|
}
|
|
|
|
|
rp = rp->next;
|
|
|
|
|
}
|
|
|
|
|
free_regionlist(rlist);
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mode == see_none)
|
|
|
|
|
continue;
|
|
|
|
|
|
2005-04-27 23:03:08 +02:00
|
|
|
|
add_seen(seen, r, mode, dis);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* nicht, wenn Verwirrung herrscht: */
|
|
|
|
|
if (!is_cursed(r->attribs, C_REGCONF, 0)) {
|
2005-04-27 23:03:08 +02:00
|
|
|
|
void (*view)(struct seen_region **, region * r, faction * f) = view_default;
|
2002-03-29 05:23:51 +01:00
|
|
|
|
if (p && fval(p, PFL_SEESPECIAL)) {
|
|
|
|
|
attrib * a = a_find(p->attribs, &at_viewrange);
|
2005-04-27 23:03:08 +02:00
|
|
|
|
if (a) view = (void (*)(struct seen_region **, region * r, faction * f))a->data.f;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2005-04-27 23:03:08 +02:00
|
|
|
|
view(seen, r, f);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2005-04-27 23:03:08 +02:00
|
|
|
|
return seen;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2004-05-26 08:42:58 +02:00
|
|
|
|
#define FMAXHASH 1021
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
struct fsee {
|
|
|
|
|
struct fsee * nexthash;
|
|
|
|
|
faction * f;
|
|
|
|
|
struct see {
|
|
|
|
|
struct see * next;
|
|
|
|
|
faction * seen;
|
|
|
|
|
unit * proof;
|
|
|
|
|
} * see;
|
|
|
|
|
} * fsee[FMAXHASH];
|
|
|
|
|
|
2005-04-27 14:18:05 +02:00
|
|
|
|
#define REPORT_NR (1 << O_REPORT)
|
|
|
|
|
#define REPORT_CR (1 << O_COMPUTER)
|
|
|
|
|
#define REPORT_ZV (1 << O_ZUGVORLAGE)
|
|
|
|
|
#define REPORT_ZIP (1 << O_COMPRESS)
|
|
|
|
|
#define REPORT_BZIP2 (1 << O_BZIP2)
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
write_reports(faction * f, time_t ltime)
|
|
|
|
|
{
|
|
|
|
|
FILE * F;
|
|
|
|
|
boolean gotit = false;
|
|
|
|
|
faction_list * addresses;
|
|
|
|
|
char zTime[64];
|
2005-04-27 23:03:08 +02:00
|
|
|
|
struct seen_region ** seen = prepare_report(f);
|
2005-04-27 14:18:05 +02:00
|
|
|
|
|
|
|
|
|
strftime(zTime, sizeof(zTime), "%A, %d. %B %Y, %H:%M", localtime(<ime));
|
2005-04-27 15:30:12 +02:00
|
|
|
|
printf("Reports for %s: \r", factionname(f));
|
2005-04-27 14:18:05 +02:00
|
|
|
|
fflush(stdout);
|
2005-04-27 23:03:08 +02:00
|
|
|
|
addresses = get_addresses(f, seen);
|
2005-04-27 14:18:05 +02:00
|
|
|
|
|
|
|
|
|
/* NR schreiben: */
|
|
|
|
|
if (!nonr && (f->options & REPORT_NR)) {
|
2005-04-27 15:30:12 +02:00
|
|
|
|
fprintf(stdout, "Reports for %s: NR\r", factionname(f));
|
2005-04-27 14:18:05 +02:00
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%s/%d-%s.nr", reportpath(), turn, factionid(f));
|
|
|
|
|
F = cfopen(buf, "wt");
|
|
|
|
|
if (F) {
|
2005-04-27 23:03:08 +02:00
|
|
|
|
int status = report(F, f, seen, addresses, zTime);
|
2005-04-27 14:18:05 +02:00
|
|
|
|
fclose(F);
|
|
|
|
|
gotit = true;
|
2005-04-27 23:03:08 +02:00
|
|
|
|
if (status!=0) {
|
|
|
|
|
seen_done(seen);
|
|
|
|
|
return status; /* catch errors */
|
|
|
|
|
}
|
2005-04-27 14:18:05 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* CR schreiben: */
|
|
|
|
|
if (!nocr && (f->options & REPORT_CR || f->age<3)) {
|
2005-04-27 15:30:12 +02:00
|
|
|
|
fprintf(stdout, "Reports for %s: CR\r", factionname(f));
|
2005-04-27 14:18:05 +02:00
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%s/%d-%s.cr", reportpath(), turn, factionid(f));
|
|
|
|
|
F = cfopen(buf, "wt");
|
|
|
|
|
if (F) {
|
2005-04-27 23:03:08 +02:00
|
|
|
|
int status = report_computer(F, f, seen, addresses, ltime);
|
2005-04-27 14:18:05 +02:00
|
|
|
|
fclose(F);
|
|
|
|
|
gotit = true;
|
2005-04-27 23:03:08 +02:00
|
|
|
|
if (status!=0) {
|
|
|
|
|
seen_done(seen);
|
|
|
|
|
return status; /* catch errors */
|
|
|
|
|
}
|
2005-04-27 14:18:05 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* ZV schreiben: */
|
|
|
|
|
if (f->options & REPORT_ZV) {
|
2005-04-27 15:30:12 +02:00
|
|
|
|
fprintf(stdout, "Reports for %s: ZV\r", factionname(f));
|
2005-04-27 14:18:05 +02:00
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%s/%d-%s.txt", reportpath(), turn, factionid(f));
|
|
|
|
|
F = cfopen(buf, "wt");
|
|
|
|
|
if (F) {
|
|
|
|
|
int status = order_template(F, f);
|
|
|
|
|
fclose(F);
|
2005-04-27 23:03:08 +02:00
|
|
|
|
if (status!=0) {
|
|
|
|
|
seen_done(seen);
|
|
|
|
|
return status; /* catch errors */
|
|
|
|
|
}
|
2005-04-27 14:18:05 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2005-04-27 15:30:12 +02:00
|
|
|
|
fprintf(stdout, "Reports for %s: DONE\n", factionname(f));
|
2005-04-27 14:18:05 +02:00
|
|
|
|
|
|
|
|
|
if (!gotit) {
|
2005-04-27 15:30:12 +02:00
|
|
|
|
log_error(("No report for faction %s!\n", factionid(f)));
|
2005-04-27 14:18:05 +02:00
|
|
|
|
}
|
|
|
|
|
freelist(addresses);
|
|
|
|
|
|
2005-04-27 23:03:08 +02:00
|
|
|
|
seen_done(seen);
|
2005-04-27 14:18:05 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-27 15:30:12 +02:00
|
|
|
|
int
|
|
|
|
|
init_reports(void)
|
|
|
|
|
{
|
|
|
|
|
update_intervals();
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_STAT
|
|
|
|
|
{
|
|
|
|
|
stat_type st;
|
|
|
|
|
if (stat(reportpath(), &st)==0) return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if (makedir(reportpath(), 0700)!=0) {
|
|
|
|
|
if (errno!=EEXIST) {
|
|
|
|
|
perror("could not create reportpath");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-24 23:49:51 +02:00
|
|
|
|
int
|
2001-01-25 10:37:55 +01:00
|
|
|
|
reports(void)
|
|
|
|
|
{
|
2005-04-30 15:21:20 +02:00
|
|
|
|
faction *f;
|
|
|
|
|
FILE *shfp, *BAT;
|
|
|
|
|
time_t ltime = time(NULL);
|
2005-01-07 02:14:09 +01:00
|
|
|
|
const char * str;
|
2005-04-27 14:18:05 +02:00
|
|
|
|
int retval = 0;
|
2001-05-18 09:06:47 +02:00
|
|
|
|
|
2005-04-27 15:30:12 +02:00
|
|
|
|
nmr_warnings();
|
2005-04-30 15:21:20 +02:00
|
|
|
|
report_donations();
|
|
|
|
|
remove_empty_units();
|
2005-04-27 15:30:12 +02:00
|
|
|
|
|
|
|
|
|
BAT = openbatch();
|
|
|
|
|
for (f = factions; f; f = f->next) {
|
2005-04-30 15:21:20 +02:00
|
|
|
|
if (f->no != MONSTER_FACTION) {
|
|
|
|
|
int error = write_reports(f, ltime);
|
|
|
|
|
if (error) retval = error;
|
2005-04-30 16:00:02 +02:00
|
|
|
|
if (!nosh && f->email && BAT) {
|
2005-04-30 15:21:20 +02:00
|
|
|
|
sprintf(buf, "%s/%s.sh", reportpath(), factionid(f));
|
|
|
|
|
shfp = fopen(buf, "w");
|
|
|
|
|
fprintf(shfp,"#!/bin/sh\n\nPATH=%s\n\n",MailitPath());
|
|
|
|
|
fprintf(shfp,"if [ $# -ge 1 ]; then\n");
|
|
|
|
|
fprintf(shfp,"\taddr=$1\n");
|
|
|
|
|
fprintf(shfp,"else\n");
|
|
|
|
|
fprintf(shfp,"\taddr=%s\n", f->email);
|
|
|
|
|
fprintf(shfp,"fi\n\n");
|
|
|
|
|
|
|
|
|
|
fprintf(BAT, "\n\ndate;echo %s\n", f->email);
|
|
|
|
|
|
|
|
|
|
if (f->options & REPORT_ZIP) {
|
|
|
|
|
|
2005-04-30 16:00:02 +02:00
|
|
|
|
fprintf(BAT, "ls %d-%s.nr %d-%s.txt %d-%s.cr | zip -m -j -9 -@ %d-%s.zip\n",
|
|
|
|
|
turn, factionid(f),
|
|
|
|
|
turn, factionid(f),
|
|
|
|
|
turn, factionid(f),
|
|
|
|
|
turn, factionid(f));
|
|
|
|
|
if (f->age == 1) {
|
|
|
|
|
fprintf(BAT, "zip -j -9 %d-%s.zip %s/%s/%s/welcome.txt\n",
|
|
|
|
|
turn, factionid(f), resourcepath(), global.welcomepath, locale_name(f->locale));
|
2005-04-30 15:21:20 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(shfp, "eresseamail.zipped $addr \"%s %s\" \"%d-%s.zip\" "
|
|
|
|
|
"%d-%s.zip\n", global.gamename, gamedate_short(f->locale),
|
|
|
|
|
turn, factionid(f),
|
|
|
|
|
turn, factionid(f));
|
|
|
|
|
|
|
|
|
|
} else if(f->options & REPORT_BZIP2) {
|
|
|
|
|
|
|
|
|
|
if (f->age == 1) {
|
|
|
|
|
fprintf(shfp,
|
2005-04-30 16:00:02 +02:00
|
|
|
|
" \\\n\t\"text/plain\" \"Willkommen\" %s/%s/%s/welcome.txt",
|
|
|
|
|
resourcepath(), global.welcomepath, locale_name(f->locale));
|
2005-04-30 15:21:20 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(BAT, "bzip2 -9v `ls %d-%s.nr %d-%s.txt %d-%s.cr`\n",
|
|
|
|
|
turn, factionid(f),
|
|
|
|
|
turn, factionid(f),
|
|
|
|
|
turn, factionid(f));
|
|
|
|
|
|
|
|
|
|
fprintf(shfp, "eresseamail.bzip2 $addr \"%s %s\"", global.gamename, gamedate_short(f->locale));
|
|
|
|
|
|
|
|
|
|
if (!nonr && f->options & REPORT_NR)
|
|
|
|
|
fprintf(shfp,
|
|
|
|
|
" \\\n\t\"application/x-bzip2\" \"Report\" %d-%s.nr.bz2",
|
|
|
|
|
turn,factionid(f));
|
|
|
|
|
|
|
|
|
|
if (f->options & (1 << O_ZUGVORLAGE))
|
|
|
|
|
fprintf(shfp,
|
|
|
|
|
" \\\n\t\"application/x-bzip2\" \"Zugvorlage\" %d-%s.txt.bz2",
|
|
|
|
|
turn,factionid(f));
|
|
|
|
|
|
|
|
|
|
if (!nocr && (f->options & REPORT_CR || f->age<3))
|
|
|
|
|
fprintf(shfp,
|
|
|
|
|
" \\\n\t\"application/x-bzip2\" \"Computer-Report\" %d-%s.cr.bz2",
|
|
|
|
|
turn, factionid(f));
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
fprintf(shfp, MAIL " $addr \"%s %s\"", global.gamename, gamedate_short(f->locale));
|
|
|
|
|
|
|
|
|
|
if (f->age == 1) {
|
|
|
|
|
fprintf(shfp,
|
2005-04-30 16:00:02 +02:00
|
|
|
|
" \\\n\t\"text/plain\" \"Willkommen\" %s/%s/%s/welcome.txt",
|
|
|
|
|
resourcepath(), global.welcomepath, locale_name(f->locale));
|
2005-04-30 15:21:20 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!nonr && f->options & REPORT_NR)
|
|
|
|
|
fprintf(shfp,
|
|
|
|
|
" \\\n\t\"text/plain\" \"Report\" %d-%s.nr",
|
|
|
|
|
turn, factionid(f));
|
|
|
|
|
|
|
|
|
|
if (f->options & (1 << O_ZUGVORLAGE))
|
|
|
|
|
fprintf(shfp,
|
|
|
|
|
" \\\n\t\"text/plain\" \"Zugvorlage\" %d-%s.txt",
|
|
|
|
|
turn, factionid(f));
|
|
|
|
|
|
|
|
|
|
if (!nocr && (f->options & REPORT_CR || f->age<3))
|
|
|
|
|
fprintf(shfp,
|
|
|
|
|
" \\\n\t\"text/x-eressea-cr\" \"Computer-Report\" %d-%s.cr",
|
|
|
|
|
turn, factionid(f));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(BAT, ". %s.sh %s\n", factionid(f), f->email);
|
|
|
|
|
fclose(shfp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-01-07 02:14:09 +01:00
|
|
|
|
str = get_param(global.parameters, "globalreport");
|
|
|
|
|
if (str!=NULL) {
|
|
|
|
|
sprintf(buf, "%s/%s.%u.cr", reportpath(), str, turn);
|
|
|
|
|
global_report(buf);
|
|
|
|
|
}
|
|
|
|
|
/* schliesst BAT und verschickt Zeitungen und Kommentare */
|
|
|
|
|
closebatch(BAT);
|
2005-04-27 23:03:08 +02:00
|
|
|
|
free_seen();
|
2005-04-27 14:18:05 +02:00
|
|
|
|
return retval;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
2004-09-12 11:28:43 +02:00
|
|
|
|
int heroes;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
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 *
|
2005-04-24 23:49:51 +02:00
|
|
|
|
make_summary(void)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
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;
|
2005-03-06 14:47:23 +01:00
|
|
|
|
f->num_total = 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
f->money = 0;
|
2005-04-24 23:49:51 +02:00
|
|
|
|
if (f->alive && f->units) {
|
|
|
|
|
s->factions++;
|
|
|
|
|
/* Problem mit Monsterpartei ... */
|
|
|
|
|
if (f->no!=MONSTER_FACTION) {
|
|
|
|
|
s->factionrace[old_race(f->race)]++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* 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) {
|
2004-02-16 20:59:26 +01:00
|
|
|
|
skill * sv;
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
s->nunits++;
|
|
|
|
|
s->playerpop += u->number;
|
2004-09-12 11:28:43 +02:00
|
|
|
|
if (u->flags & UFL_HERO) {
|
|
|
|
|
s->heroes += u->number;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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);
|
|
|
|
|
|
2004-02-16 20:59:26 +01:00
|
|
|
|
for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) {
|
|
|
|
|
skill_t sk = sv->id;
|
|
|
|
|
int aktskill = eff_skill(u, sk, r);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (aktskill > s->maxskill) s->maxskill = aktskill;
|
|
|
|
|
}
|
|
|
|
|
if (!fval(f, FL_DH)) {
|
|
|
|
|
f->nregions++;
|
|
|
|
|
fset(f, FL_DH);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-06 14:47:23 +01:00
|
|
|
|
f->num_total += u->number;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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));
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if ((owner=buildingowner(buildings[i]->region,buildings[i]))!=NULL && !fval(owner,UFL_PARTEITARNUNG)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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));
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if ((owner=buildingowner(b->region,b))!=NULL && !fval(owner,UFL_PARTEITARNUNG)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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)
|
|
|
|
|
{
|
2004-06-27 18:56:01 +02:00
|
|
|
|
if (alliances!=NULL) {
|
|
|
|
|
fprintf(file, "%s (%s/%d) (%.3s/%.3s), %d Einh., %d Pers., $%d, %d %s\n",
|
|
|
|
|
f->name, itoa36(f->no), f->alliance?f->alliance->id:0,
|
|
|
|
|
LOC(default_locale, rc_name(f->race, 0)), neue_gebiete[f->magiegebiet],
|
2005-03-06 14:47:23 +01:00
|
|
|
|
f->no_units, f->num_total, f->money, turn - f->lastorders,
|
2004-06-27 18:56:01 +02:00
|
|
|
|
turn - f->lastorders != 1 ? "NMRs" : "NMR ");
|
|
|
|
|
} else {
|
|
|
|
|
fprintf(file, "%s (%.3s/%.3s), %d Einh., %d Pers., $%d, %d %s\n",
|
|
|
|
|
factionname(f), LOC(default_locale, rc_name(f->race, 0)),
|
2005-03-06 14:47:23 +01:00
|
|
|
|
neue_gebiete[f->magiegebiet], f->no_units, f->num_total, f->money,
|
2004-06-27 18:56:01 +02:00
|
|
|
|
turn - f->lastorders, turn - f->lastorders != 1 ? "NMRs" : "NMR ");
|
|
|
|
|
}
|
2002-02-18 17:19:50 +01:00
|
|
|
|
}
|
|
|
|
|
|
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;
|
2003-07-29 11:48:03 +02:00
|
|
|
|
int * nmrs = malloc(sizeof(int)*(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));
|
2004-09-12 11:28:43 +02:00
|
|
|
|
#ifdef HEROES
|
|
|
|
|
fprintf(F, " Helden: %s\n", pcomp(s->heroes, o->heroes));
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-09-12 11:28:43 +02:00
|
|
|
|
if (full) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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");
|
|
|
|
|
|
2004-01-04 19:14:20 +01:00
|
|
|
|
for (i = 0; i <= NMRTimeout(); ++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) {
|
2004-01-04 19:14:20 +01:00
|
|
|
|
int nmr = turn-f->lastorders;
|
|
|
|
|
if (nmr<0 || nmr>NMRTimeout()) {
|
|
|
|
|
log_error(("faction %s has %d NMRS\n", factionid(f), nmr));
|
|
|
|
|
nmr = max(0, nmr);
|
|
|
|
|
nmr = min(nmr, NMRTimeout());
|
|
|
|
|
}
|
|
|
|
|
nmrs[nmr]++;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-01-04 19:14:20 +01:00
|
|
|
|
for (i = 0; i <= NMRTimeout(); ++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);
|
|
|
|
|
|
2004-07-14 09:12:36 +02:00
|
|
|
|
if (full) {
|
|
|
|
|
if (factions)
|
|
|
|
|
fprintf(F, "\nParteien:\n\n");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-07-14 09:12:36 +02:00
|
|
|
|
for (f = factions; f; f = f->next) {
|
|
|
|
|
out_faction(F, f);
|
|
|
|
|
}
|
2002-02-18 17:19:50 +01:00
|
|
|
|
|
2004-07-14 09:12:36 +02:00
|
|
|
|
if (NMRTimeout() && full) {
|
|
|
|
|
fprintf(F, "\n\nFactions with NMRs:\n");
|
|
|
|
|
for (i = NMRTimeout(); i > 0; --i) {
|
|
|
|
|
for(f=factions; f; f=f->next) {
|
|
|
|
|
if(i == NMRTimeout()) {
|
|
|
|
|
if(turn - f->lastorders >= i) {
|
|
|
|
|
out_faction(F, f);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if(turn - f->lastorders == i) {
|
|
|
|
|
out_faction(F, f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-07-23 09:23:28 +02:00
|
|
|
|
|
2004-07-14 09:12:36 +02:00
|
|
|
|
fclose(F);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-01-31 00:16:17 +01:00
|
|
|
|
if (full) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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
|
|
|
|
writemonument();
|
|
|
|
|
}
|
2003-07-29 11:48:03 +02:00
|
|
|
|
free(nmrs);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
/******* 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));
|
|
|
|
|
}
|
|
|
|
|
|
2004-04-20 00:52:36 +02:00
|
|
|
|
static void
|
|
|
|
|
eval_spell(struct opstack ** stack, const void * userdata) /* unit -> string */
|
|
|
|
|
{
|
|
|
|
|
const struct faction * f = (const struct faction *)userdata;
|
|
|
|
|
const struct spell * sp = opop(stack, const struct spell *);
|
|
|
|
|
const char * c = sp?spell_name(sp, f->locale):"an unknown spell";
|
|
|
|
|
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
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
- 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));
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
static void
|
|
|
|
|
eval_order(struct opstack ** stack, const void * userdata) /* order -> string */
|
|
|
|
|
{
|
|
|
|
|
const faction * report = (const faction*)userdata;
|
|
|
|
|
struct order * ord = opop(stack, struct order *);
|
|
|
|
|
static char buf[256];
|
|
|
|
|
write_order(ord, report->locale, buf, sizeof(buf));
|
|
|
|
|
opush(stack, strcpy(balloc(strlen(buf)+1), buf));
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
static void
|
|
|
|
|
eval_direction(struct opstack ** stack, const void * userdata)
|
|
|
|
|
{
|
|
|
|
|
const faction * report = (const faction*)userdata;
|
|
|
|
|
int i = opop(stack, int);
|
2004-01-19 00:52:57 +01:00
|
|
|
|
const char * c;
|
|
|
|
|
if (i>=0) {
|
|
|
|
|
c = LOC(report->locale, directions[i]);
|
|
|
|
|
} else {
|
|
|
|
|
c = LOC(report->locale, "unknown_direction");
|
|
|
|
|
}
|
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
|
|
|
|
add_function("alliance", &eval_alliance);
|
- 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);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
add_function("order", &eval_order);
|
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);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
add_function("spell", &eval_spell);
|
|
|
|
|
|
|
|
|
|
register_argtype("string", free, (void*(*)(void*))strdup);
|
2005-04-30 19:07:46 +02:00
|
|
|
|
register_argtype("order", (void(*)(void*))free_order, (void*(*)(void*))duplicate_order);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
register_function((pf_generic)view_neighbours, "view_neighbours");
|
2002-03-29 05:23:51 +01:00
|
|
|
|
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
|
|
|
|
}
|