2001-01-25 10:37:55 +01:00
|
|
|
|
/* vi: set ts=2:
|
|
|
|
|
*
|
2001-04-16 16:34:19 +02:00
|
|
|
|
*
|
2006-04-17 01:16:19 +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
|
2007-06-20 02:34:02 +02:00
|
|
|
|
#define ECHECK_VERSION "4.01"
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
#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>
|
2005-10-23 13:27:55 +02:00
|
|
|
|
#include <attributes/alliance.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>
|
|
|
|
|
#include <kernel/border.h>
|
|
|
|
|
#include <kernel/build.h>
|
|
|
|
|
#include <kernel/building.h>
|
2005-06-04 15:22:31 +02:00
|
|
|
|
#include <kernel/calendar.h>
|
2004-06-21 18:45:27 +02:00
|
|
|
|
#include <kernel/faction.h>
|
|
|
|
|
#include <kernel/group.h>
|
|
|
|
|
#include <kernel/item.h>
|
|
|
|
|
#include <kernel/karma.h>
|
|
|
|
|
#include <kernel/message.h>
|
2007-08-19 19:30:40 +02:00
|
|
|
|
#include <kernel/move.h>
|
2004-06-21 18:45:27 +02:00
|
|
|
|
#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>
|
2005-10-25 14:38:01 +02:00
|
|
|
|
#include <kernel/terrain.h>
|
|
|
|
|
#include <kernel/terrainid.h>
|
2004-06-21 18:45:27 +02:00
|
|
|
|
#include <kernel/unit.h>
|
2005-10-23 13:27:55 +02:00
|
|
|
|
#include <kernel/alliance.h>
|
2001-02-10 11:40:12 +01:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* util includes */
|
2007-06-20 02:34:02 +02:00
|
|
|
|
#include <util/attrib.h>
|
|
|
|
|
#include <util/base36.h>
|
2005-06-17 21:12:55 +02:00
|
|
|
|
#include <util/bsdstring.h>
|
2006-02-19 23:43:56 +01:00
|
|
|
|
#include <util/goodies.h>
|
2007-06-20 02:34:02 +02:00
|
|
|
|
#include <util/lists.h>
|
|
|
|
|
#include <util/log.h>
|
2001-02-24 13:50:51 +01:00
|
|
|
|
#include <util/message.h>
|
2007-06-20 02:34:02 +02:00
|
|
|
|
#include <util/nrmessage.h>
|
2006-02-19 23:43:56 +01:00
|
|
|
|
#include <util/rng.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
|
|
|
|
|
2007-08-19 19:30:40 +02:00
|
|
|
|
#include <libxml/encoding.h>
|
|
|
|
|
|
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>
|
2007-06-20 02:34:02 +02:00
|
|
|
|
#include <stddef.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#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
|
|
|
|
|
2005-05-05 02:12:54 +02:00
|
|
|
|
static size_t
|
2005-05-07 00:30:19 +02:00
|
|
|
|
strxcpy(char * dst, const char * src) {
|
2005-05-05 02:12:54 +02:00
|
|
|
|
size_t s = 0;
|
|
|
|
|
while ((*dst++ = *src++)!=0) ++s;
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
static char *
|
|
|
|
|
gamedate_season(const struct locale * lang)
|
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
static char buf[256];
|
2005-06-05 15:34:08 +02:00
|
|
|
|
gamedate gd;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2005-06-05 15:34:08 +02:00
|
|
|
|
get_gamedate(turn, &gd);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2007-07-17 17:33:48 +02:00
|
|
|
|
sprintf(buf, (const char *)LOC(lang, "nr_calendar_season"),
|
2006-04-17 01:16:19 +02:00
|
|
|
|
LOC(lang, weeknames[gd.week]),
|
|
|
|
|
LOC(lang, monthnames[gd.month]),
|
|
|
|
|
gd.year,
|
|
|
|
|
LOC(lang, agename),
|
|
|
|
|
LOC(lang, seasonnames[gd.season]));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
return buf;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
void
|
|
|
|
|
rpc(FILE * F, char c, size_t num)
|
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
while(num > 0) {
|
|
|
|
|
putc(c, F);
|
|
|
|
|
num--;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
rnl(FILE * F)
|
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
fputc('\n', F);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
centre(FILE * F, const char *s, boolean breaking)
|
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
/* 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);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2006-02-05 11:47:28 +01:00
|
|
|
|
rparagraph(FILE *F, const char *str, ptrdiff_t indent, int hanging_indent, char mark)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2006-01-29 15:05:28 +01:00
|
|
|
|
static const char * spaces = " ";
|
2006-01-29 23:14:43 +01:00
|
|
|
|
size_t length = REPORTWIDTH;
|
|
|
|
|
const char * end, * begin;
|
|
|
|
|
|
|
|
|
|
/* find out if there's a mark + indent already encoded in the string. */
|
|
|
|
|
if (!mark) {
|
|
|
|
|
const char * x = str;
|
|
|
|
|
while (*x == ' ') ++x;
|
|
|
|
|
indent += x - str;
|
|
|
|
|
if (x[0] && indent && x[1]==' ') {
|
|
|
|
|
indent += 2;
|
|
|
|
|
mark = x[0];
|
|
|
|
|
str = x + 2;
|
|
|
|
|
hanging_indent -= 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
begin = end = str;
|
2006-01-27 00:05:40 +01:00
|
|
|
|
|
2006-01-29 23:14:43 +01:00
|
|
|
|
while (*begin) {
|
|
|
|
|
const char * last_space = begin;
|
2006-01-27 00:05:40 +01:00
|
|
|
|
|
|
|
|
|
if (mark && indent>=2) {
|
|
|
|
|
fwrite(spaces, sizeof(char), indent-2, F);
|
|
|
|
|
fputc(mark, F);
|
|
|
|
|
fputc(' ', F);
|
|
|
|
|
mark = 0;
|
2006-01-29 23:14:43 +01:00
|
|
|
|
} else if (begin==str) {
|
2006-01-27 00:05:40 +01:00
|
|
|
|
fwrite(spaces, sizeof(char), indent, F);
|
2006-01-29 23:14:43 +01:00
|
|
|
|
} else {
|
|
|
|
|
fwrite(spaces, sizeof(char), indent+ hanging_indent, F);
|
2006-01-27 00:05:40 +01:00
|
|
|
|
}
|
2006-01-30 00:17:38 +01:00
|
|
|
|
while (*end && end<=begin+length-indent) {
|
2006-01-27 00:05:40 +01:00
|
|
|
|
if (*end==' ') {
|
|
|
|
|
last_space = end;
|
|
|
|
|
}
|
|
|
|
|
++end;
|
|
|
|
|
}
|
2006-01-27 00:56:33 +01:00
|
|
|
|
if (*end==0) last_space = end;
|
2006-01-29 23:14:43 +01:00
|
|
|
|
if (last_space==begin) {
|
2006-01-27 00:05:40 +01:00
|
|
|
|
/* there was no space in this line. clip it */
|
|
|
|
|
last_space = end;
|
|
|
|
|
}
|
2006-01-29 23:14:43 +01:00
|
|
|
|
fwrite(begin, sizeof(char), last_space-begin, F);
|
|
|
|
|
begin = last_space;
|
|
|
|
|
while (*begin==' ') {
|
|
|
|
|
++begin;
|
2006-01-27 00:05:40 +01:00
|
|
|
|
}
|
2006-01-29 23:14:43 +01:00
|
|
|
|
if (begin>end) begin = end;
|
2006-01-27 00:05:40 +01:00
|
|
|
|
fputc('\n', F);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2006-04-17 01:16:19 +02:00
|
|
|
|
report_spell(FILE * F, spell *sp, const struct locale * lang)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2006-01-29 15:05:28 +01:00
|
|
|
|
int k, itemanz, costtyp;
|
|
|
|
|
int dh = 0;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char buf[4096];
|
2005-05-05 02:12:54 +02:00
|
|
|
|
char * bufp;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-20 22:24:09 +01:00
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, spell_name(sp, lang), true);
|
|
|
|
|
rnl(F);
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rparagraph(F, LOC(lang, "nr_spell_description"), 0, 0, 0);
|
2006-02-20 22:24:09 +01:00
|
|
|
|
rparagraph(F, spell_info(sp, lang), 2, 0, 0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-01-29 23:14:43 +01:00
|
|
|
|
bufp = buf;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, LOC(lang, "nr_spell_type"), sizeof(buf)-(bufp-buf));
|
2006-01-29 23:14:43 +01:00
|
|
|
|
*bufp++ = ' ';
|
2006-02-20 22:24:09 +01:00
|
|
|
|
if (sp->sptyp & PRECOMBATSPELL) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, LOC(lang, "sptype_precombat"), sizeof(buf)-(bufp-buf));
|
2006-02-20 22:24:09 +01:00
|
|
|
|
} else if (sp->sptyp & COMBATSPELL) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, LOC(lang, "sptype_combat"), sizeof(buf)-(bufp-buf));
|
2006-02-20 22:24:09 +01:00
|
|
|
|
} else if (sp->sptyp & POSTCOMBATSPELL) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, LOC(lang, "sptype_postcombat"), sizeof(buf)-(bufp-buf));
|
2006-02-20 22:24:09 +01:00
|
|
|
|
} else {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, LOC(lang, "sptype_normal"), sizeof(buf)-(bufp-buf));
|
2006-02-20 22:24:09 +01:00
|
|
|
|
}
|
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-01-29 23:14:43 +01:00
|
|
|
|
sprintf(buf, "%s %d", LOC(lang, "nr_spell_level"), sp->level);
|
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%s %d", LOC(lang, "nr_spell_rank"), sp->rank);
|
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rparagraph(F, LOC(lang, "nr_spell_components"), 0, 0, 0);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
for (k = 0; sp->components[k].type; ++k) {
|
|
|
|
|
const resource_type * rtype = sp->components[k].type;
|
|
|
|
|
itemanz = sp->components[k].amount;
|
|
|
|
|
costtyp = sp->components[k].cost;
|
|
|
|
|
if (itemanz > 0){
|
2005-02-05 23:52:59 +01:00
|
|
|
|
if (sp->sptyp & SPELLLEVEL) {
|
2005-10-25 22:44:18 +02:00
|
|
|
|
bufp = buf + sprintf(buf, " %d %s", itemanz, LOC(lang, resourcename(rtype, itemanz!=1)));
|
2005-02-05 23:52:59 +01:00
|
|
|
|
if (costtyp == SPC_LEVEL || costtyp == SPC_LINEAR ) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += sprintf(bufp, " * %s", LOC(lang, "nr_level"));
|
2005-02-05 23:52:59 +01:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2005-02-12 14:42:15 +01:00
|
|
|
|
if (costtyp == SPC_LEVEL || costtyp == SPC_LINEAR ) {
|
|
|
|
|
itemanz *= sp->level;
|
|
|
|
|
}
|
2006-01-29 23:14:43 +01:00
|
|
|
|
sprintf(buf, "%d %s", itemanz, LOC(lang, resourcename(rtype, itemanz!=1)));
|
2005-02-05 23:52:59 +01:00
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
rparagraph(F, buf, 2, 2, '-');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp = buf + strlcpy(buf, LOC(lang, "nr_spell_modifiers"), sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if (sp->sptyp & FARCASTING) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, " Fernzauber", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
dh = 1;
|
|
|
|
|
}
|
|
|
|
|
if (sp->sptyp & OCEANCASTABLE) {
|
|
|
|
|
if (dh == 1) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, ",", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, " Seezauber", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
dh = 1;
|
|
|
|
|
}
|
|
|
|
|
if (sp->sptyp & ONSHIPCAST) {
|
|
|
|
|
if (dh == 1){
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, ",", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, " Schiffszauber", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
dh = 1;
|
|
|
|
|
}
|
|
|
|
|
if (sp->sptyp & NOTFAMILIARCAST) {
|
|
|
|
|
if (dh == 1){
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, ", k", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
} else {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, " K", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, "ann nicht vom Vertrauten gezaubert werden", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
dh = 1;
|
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
if (dh == 0) bufp += strlcpy(bufp, " Keine", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
rparagraph(F, LOC(lang, "nr_spell_syntax"), 0, 0, 0);
|
2005-05-05 02:12:54 +02:00
|
|
|
|
if (!sp->syntax) {
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if (sp->sptyp & ISCOMBATSPELL) {
|
|
|
|
|
bufp = buf + strxcpy(buf, LOC(lang, keywords[K_COMBAT]));
|
|
|
|
|
} else {
|
|
|
|
|
bufp = buf + strxcpy(buf, LOC(lang, keywords[K_CAST]));
|
|
|
|
|
}
|
|
|
|
|
/* Reihenfolge beachten: Erst REGION, dann STUFE! */
|
|
|
|
|
if (sp->sptyp & FARCASTING) {
|
2006-01-29 23:14:43 +01:00
|
|
|
|
bufp += snprintf(bufp, sizeof(buf)-(bufp-buf), " [%s x y]", LOC(lang, parameters[P_REGION]));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
if (sp->sptyp & SPELLLEVEL) {
|
2006-01-29 23:14:43 +01:00
|
|
|
|
bufp += snprintf(bufp, sizeof(buf)-(bufp-buf), " [%s n]", LOC(lang, parameters[P_LEVEL]));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
bufp += strxcpy(bufp, " \"");
|
|
|
|
|
bufp += strxcpy(bufp, spell_name(sp, lang));
|
|
|
|
|
bufp += strxcpy(bufp, "\" ");
|
|
|
|
|
if (sp->sptyp & ONETARGET){
|
|
|
|
|
if (sp->sptyp & UNITSPELL) {
|
|
|
|
|
bufp += strxcpy(bufp, "<Einheit-Nr>");
|
|
|
|
|
} else if (sp->sptyp & SHIPSPELL) {
|
|
|
|
|
bufp += strxcpy(bufp, "<Schiff-Nr>");
|
|
|
|
|
} else if (sp->sptyp & BUILDINGSPELL) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strxcpy(bufp, "<Gebaeude-Nr>");
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (sp->sptyp & UNITSPELL) {
|
|
|
|
|
bufp += strxcpy(bufp, "<Einheit-Nr> [<Einheit-Nr> ...]");
|
|
|
|
|
} else if (sp->sptyp & SHIPSPELL) {
|
|
|
|
|
bufp += strxcpy(bufp, "<Schiff-Nr> [<Schiff-Nr> ...]");
|
|
|
|
|
} else if (sp->sptyp & BUILDINGSPELL) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strxcpy(bufp, "<Gebaeude-Nr> [<Gebaeude-Nr> ...]");
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rparagraph(F, buf, 2, 0, 0);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
} else {
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rparagraph(F, sp->syntax, 2, 0, 0);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rnl(F);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
sparagraph(strlist ** SP, const char *s, int indent, char mark)
|
|
|
|
|
{
|
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
/* 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 (). */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
int i, j, width;
|
|
|
|
|
int firstline;
|
|
|
|
|
static char buf[REPORTWIDTH + 1];
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
width = REPORTWIDTH - indent;
|
|
|
|
|
firstline = 1;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
for (;;) {
|
|
|
|
|
i = 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
do {
|
|
|
|
|
j = i;
|
|
|
|
|
while (s[j] && s[j] != ' ')
|
|
|
|
|
j++;
|
|
|
|
|
if (j > width) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
/* 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
|
2007-08-19 19:30:40 +02:00
|
|
|
|
* l<EFBFBD>nger als eine zeile ist, muss dieses hier abgetrennt werden. */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if (i == 0)
|
|
|
|
|
i = width - 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
i = j + 1;
|
|
|
|
|
}
|
|
|
|
|
while (s[j]);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
for (j = 0; j != indent; j++)
|
|
|
|
|
buf[j] = ' ';
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if (firstline && mark)
|
|
|
|
|
buf[indent - 2] = mark;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
for (j = 0; j != i - 1; j++)
|
|
|
|
|
buf[indent + j] = s[j];
|
|
|
|
|
buf[indent + j] = 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
addstrlist(SP, buf);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if (s[i - 1] == 0)
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
s += i;
|
|
|
|
|
firstline = 0;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
hat_in_region(item_t it, region * r, faction * f)
|
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
unit *u;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->faction == f && get_item(u, it) > 0) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
attrib *a = NULL;
|
|
|
|
|
int self = 0;
|
|
|
|
|
region *r;
|
|
|
|
|
|
|
|
|
|
/* Die Sichtbarkeit eines Zaubers und die Zaubermeldung sind bei
|
|
|
|
|
* Geb<EFBFBD>uden und Schiffen je nach, ob man Besitzer ist, verschieden.
|
|
|
|
|
* Bei Einheiten sieht man Wirkungen auf eigene Einheiten immer.
|
|
|
|
|
* Spezialf<EFBFBD>lle (besonderes Talent, verursachender Magier usw. werde
|
|
|
|
|
* bei jedem curse gesondert behandelt. */
|
|
|
|
|
if (typ == TYP_SHIP){
|
|
|
|
|
ship * sh = (ship*)obj;
|
|
|
|
|
unit * owner = shipowner(sh);
|
|
|
|
|
a = sh->attribs;
|
|
|
|
|
r = sh->region;
|
2007-02-04 14:30:06 +01:00
|
|
|
|
if (owner) {
|
2006-04-17 01:16:19 +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;
|
2007-03-07 23:38:04 +01:00
|
|
|
|
if ((owner = buildingowner(r,b)) != NULL){
|
2006-04-17 01:16:19 +02:00
|
|
|
|
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 */
|
|
|
|
|
}
|
|
|
|
|
|
2007-08-19 19:30:40 +02:00
|
|
|
|
for (;a;a=a->next) {
|
|
|
|
|
char buf[4096];
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
|
|
|
|
if (fval(a->type, ATF_CURSE)) {
|
|
|
|
|
curse *c = (curse *)a->data.v;
|
2007-03-09 22:30:00 +01:00
|
|
|
|
message * msg;
|
|
|
|
|
|
|
|
|
|
if (c->type->cansee) {
|
|
|
|
|
self = c->type->cansee(viewer, obj, typ, c, self);
|
|
|
|
|
}
|
|
|
|
|
msg = msg_curse(c, obj, typ, self);
|
|
|
|
|
|
|
|
|
|
if (msg) {
|
2006-04-17 01:16:19 +02:00
|
|
|
|
rnl(F);
|
2007-03-10 00:38:13 +01:00
|
|
|
|
nr_render(msg, viewer->locale, buf, sizeof(buf), viewer);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
rparagraph(F, buf, indent, 2, 0);
|
2007-03-09 22:30:00 +01:00
|
|
|
|
msg_release(msg);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
} else if (a->type==&at_effect && self) {
|
|
|
|
|
effect_data * data = (effect_data *)a->data.v;
|
2006-07-24 22:49:58 +02:00
|
|
|
|
if (data->value>0) {
|
|
|
|
|
sprintf(buf, "Auf der Einheit lieg%s %d Wirkung%s %s.",
|
2006-04-17 01:16:19 +02:00
|
|
|
|
(data->value==1 ? "t" : "en"),
|
|
|
|
|
data->value,
|
|
|
|
|
(data->value==1 ? "" : "en"),
|
|
|
|
|
LOC(default_locale, resourcename(data->type->itype->rtype, 0)));
|
2006-07-24 22:49:58 +02:00
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, buf, indent, 2, 0);
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
rps_nowrap(FILE * F, const char *s)
|
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
const char *x = s;
|
|
|
|
|
size_t 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);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
rpunit(FILE * F, const faction * f, const unit * u, int indent, int mode)
|
|
|
|
|
{
|
2006-02-20 22:24:09 +01:00
|
|
|
|
attrib *a_otherfaction;
|
|
|
|
|
char marker;
|
|
|
|
|
int dh;
|
|
|
|
|
boolean isbattle = (boolean)(mode == see_battle);
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char buf[8192];
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-02-20 22:24:09 +01:00
|
|
|
|
if (u->race == new_race[RC_SPELL]) return;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2006-02-20 22:24:09 +01:00
|
|
|
|
{
|
|
|
|
|
rnl(F);
|
2007-08-19 19:30:40 +02:00
|
|
|
|
dh = bufunit(f, u, indent, mode, buf, sizeof(buf));
|
2006-02-20 22:24:09 +01:00
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2006-02-20 22:24:09 +01:00
|
|
|
|
a_otherfaction = a_find(u->attribs, &at_otherfaction);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2006-02-20 22:24:09 +01:00
|
|
|
|
if (u->faction == f) {
|
|
|
|
|
marker = '*';
|
|
|
|
|
} else {
|
|
|
|
|
if (a_otherfaction && f != u->faction && get_otherfaction(a_otherfaction) == f
|
|
|
|
|
&& !fval(u, UFL_PARTEITARNUNG)) {
|
|
|
|
|
marker = '!';
|
|
|
|
|
} else {
|
|
|
|
|
if (dh && !fval(u, UFL_PARTEITARNUNG)) {
|
|
|
|
|
marker = '+';
|
|
|
|
|
} else {
|
|
|
|
|
marker = '-';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-04-28 17:39:13 +02:00
|
|
|
|
|
2006-02-20 22:24:09 +01:00
|
|
|
|
rparagraph(F, buf, indent, 0, marker);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-20 22:24:09 +01:00
|
|
|
|
if (!isbattle) {
|
|
|
|
|
print_curses(F, f, u, TYP_UNIT, indent);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rp_messages(FILE * F, message_list * msgs, faction * viewer, int indent, boolean categorized)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
nrsection * section;
|
|
|
|
|
if (!msgs) return;
|
|
|
|
|
for (section = sections; section; section=section->next) {
|
|
|
|
|
int k = 0;
|
|
|
|
|
struct mlist * m = msgs->begin;
|
|
|
|
|
while (m) {
|
|
|
|
|
/* messagetype * mt = m->type; */
|
|
|
|
|
if (strcmp(nr_section(m->msg), section->name)==0) {
|
|
|
|
|
char lbuf[8192];
|
2005-06-17 21:12:55 +02:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if (!k && categorized) {
|
|
|
|
|
const char * section_title;
|
|
|
|
|
char cat_identifier[24];
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rnl(F);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
sprintf(cat_identifier, "section_%s", section->name);
|
|
|
|
|
section_title = LOC(viewer->locale, cat_identifier);
|
|
|
|
|
centre(F, section_title, true);
|
|
|
|
|
rnl(F);
|
2006-01-29 23:14:43 +01:00
|
|
|
|
k = 1;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
2006-01-29 23:14:43 +01:00
|
|
|
|
nr_render(m->msg, viewer->locale, lbuf, sizeof(lbuf), viewer);
|
|
|
|
|
rparagraph(F, lbuf, indent, 2, 0);
|
2006-04-17 01:16:19 +02: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) {
|
2005-06-19 12:22:51 +02:00
|
|
|
|
struct bmsg * bm = f->battles;
|
2004-04-22 00:09:39 +02:00
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, LOC(f->locale, "section_battle"), false);
|
|
|
|
|
rnl(F);
|
2005-06-11 10:09:55 +02:00
|
|
|
|
|
2005-06-19 12:22:51 +02:00
|
|
|
|
while (bm) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char buf[80];
|
|
|
|
|
RENDER(f, buf, sizeof(buf), ("battle::header", "region", bm->r));
|
2004-04-22 00:09:39 +02:00
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rp_messages(F, bm->msgs, f, 0, false);
|
2005-06-19 12:22:51 +02:00
|
|
|
|
bm = bm->next;
|
2004-04-22 00:09:39 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
const luxury_type *sale=NULL;
|
|
|
|
|
struct demand * dmd;
|
|
|
|
|
message * m;
|
|
|
|
|
int n = 0;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char buf[4096];
|
2006-04-17 01:16:19 +02: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;
|
|
|
|
|
else if (dmd->value > 0) n++;
|
|
|
|
|
}
|
|
|
|
|
assert(sale!=NULL);
|
|
|
|
|
|
|
|
|
|
m = msg_message("nr_market_sale", "product price",
|
|
|
|
|
sale->itype->rtype, sale->price);
|
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
2005-05-05 02:12:54 +02:00
|
|
|
|
msg_release(m);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if (n > 0) {
|
2005-05-05 02:12:54 +02:00
|
|
|
|
char * bufp = buf + strlen(buf);
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, " ", sizeof(buf)-(bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, LOC(f->locale, "nr_trade_intro"), sizeof(buf)-(bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, " ", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
|
|
|
|
for (dmd=r->land->demands;dmd;dmd=dmd->next) if(dmd->value > 0) {
|
|
|
|
|
m = msg_message("nr_market_price", "product price",
|
|
|
|
|
dmd->type->itype->rtype, dmd->value * dmd->type->price);
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += nr_render(m, f->locale, bufp, sizeof(buf)-(bufp-buf), f);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
msg_release(m);
|
|
|
|
|
n--;
|
2005-05-05 02:12:54 +02:00
|
|
|
|
if (n == 0) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, LOC(f->locale, "nr_trade_end"), sizeof(buf)-(bufp-buf));
|
2005-05-05 02:12:54 +02:00
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
else if (n == 1) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, " ", sizeof(buf)-(bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, LOC(f->locale, "nr_trade_final"), sizeof(buf)-(bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, " ", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
} else {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, LOC(f->locale, "nr_trade_next"), sizeof(buf)-(bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, " ", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Schreibe Paragraphen */
|
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
boolean cs = b->type->fvisible(b, f, r);
|
|
|
|
|
if (!cs) {
|
|
|
|
|
cs = b->type->rvisible(b, r);
|
|
|
|
|
if (!cs) {
|
|
|
|
|
const unit * us = r->units;
|
|
|
|
|
while (us && !cs) {
|
|
|
|
|
if (us->faction==f) {
|
|
|
|
|
cs = b->type->uvisible(b, us);
|
|
|
|
|
if (cs) break;
|
|
|
|
|
}
|
|
|
|
|
us=us->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return cs;
|
2001-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
|
|
|
|
{
|
2006-01-29 15:05:28 +01:00
|
|
|
|
int n;
|
|
|
|
|
boolean dh;
|
|
|
|
|
direction_t d;
|
|
|
|
|
int trees;
|
2006-02-10 23:24:20 +01:00
|
|
|
|
int saplings;
|
2006-01-29 15:05:28 +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];
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char buf[8192];
|
2005-05-05 02:12:54 +02:00
|
|
|
|
char * bufp = buf;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
for (d = 0; d != MAXDIRECTIONS; d++) {
|
2005-05-05 02:12:54 +02:00
|
|
|
|
/* Nachbarregionen, die gesehen werden, ermitteln */
|
2006-01-29 15:05:28 +01:00
|
|
|
|
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);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
bufp += f_regionid(r, f, bufp, sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
if (partial == 1) {
|
|
|
|
|
bufp += strxcpy(bufp, " (durchgereist)");
|
|
|
|
|
}
|
|
|
|
|
else if (partial == 3) {
|
|
|
|
|
bufp += strxcpy(bufp, " (benachbart)");
|
|
|
|
|
}
|
|
|
|
|
else if (partial == 2) {
|
|
|
|
|
bufp += strxcpy(bufp, " (vom Turm erblickt)");
|
|
|
|
|
}
|
|
|
|
|
/* Terrain */
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
bufp += strxcpy(bufp, ", ");
|
2007-03-04 23:27:32 +01:00
|
|
|
|
|
|
|
|
|
tname = terrain_name(r);
|
2006-01-29 15:05:28 +01:00
|
|
|
|
bufp += strxcpy(bufp, LOC(f->locale, tname));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2007-08-19 19:30:40 +02:00
|
|
|
|
/* Trees */
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
trees = rtrees(r,2);
|
2006-02-10 23:24:20 +01:00
|
|
|
|
saplings = rtrees(r,1);
|
2006-01-29 15:05:28 +01:00
|
|
|
|
if (production(r)) {
|
2006-02-10 23:24:20 +01:00
|
|
|
|
if (trees > 0 || saplings > 0) {
|
|
|
|
|
bufp += sprintf(bufp, ", %d/%d ", trees, saplings);
|
2006-01-29 15:05:28 +01:00
|
|
|
|
if (fval(r, RF_MALLORN)) {
|
|
|
|
|
if (trees == 1) {
|
|
|
|
|
bufp += strxcpy(bufp, LOC(f->locale, "nr_mallorntree"));
|
|
|
|
|
} else {
|
|
|
|
|
bufp += strxcpy(bufp, LOC(f->locale, "nr_mallorntree_p"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (trees == 1) {
|
|
|
|
|
bufp += strxcpy(bufp, LOC(f->locale, "nr_tree"));
|
|
|
|
|
} else {
|
|
|
|
|
bufp += strxcpy(bufp, LOC(f->locale, "nr_tree_p"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
/* iron & stone */
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (level>=0 && visible >= 0) {
|
2006-04-17 01:16:19 +02:00
|
|
|
|
bufp += snprintf(bufp, sizeof(buf)-(bufp-buf), ", %d %s/%d",
|
|
|
|
|
visible, LOC(f->locale, res->type->name),
|
2006-01-29 15:05:28 +01:00
|
|
|
|
res->level + itype->construction->minskill - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
/* peasants & silver */
|
|
|
|
|
if (rpeasants(r)) {
|
2005-10-29 16:12:46 +02:00
|
|
|
|
int n = rpeasants(r);
|
2006-01-29 15:05:28 +01:00
|
|
|
|
bufp += sprintf(bufp, ", %d", n);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
if(fval(r, RF_ORCIFIED)) {
|
|
|
|
|
strcpy(bufp++, " ");
|
|
|
|
|
bufp += strxcpy(bufp, LOC(f->locale, n==1?"rc_orc":"rc_orc_p"));
|
|
|
|
|
} else {
|
|
|
|
|
strcpy(bufp++, " ");
|
|
|
|
|
bufp += strxcpy(bufp, LOC(f->locale, n==1?"peasant":"peasant_p"));
|
|
|
|
|
}
|
2007-02-01 23:13:22 +01:00
|
|
|
|
}
|
|
|
|
|
if (rmoney(r) && partial == 0) {
|
|
|
|
|
bufp += sprintf(bufp, ", %d ", rmoney(r));
|
|
|
|
|
bufp += strxcpy(bufp, LOC(f->locale, resourcename(oldresourcetype[R_SILVER], rmoney(r)!=1)));
|
2006-01-29 15:05:28 +01:00
|
|
|
|
}
|
|
|
|
|
/* Pferde */
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
if (rhorses(r)) {
|
|
|
|
|
bufp += sprintf(bufp, ", %d ", rhorses(r));
|
|
|
|
|
bufp += strxcpy(bufp, LOC(f->locale, resourcename(oldresourcetype[R_HORSE], (rhorses(r)>1)?GR_PLURAL:0)));
|
|
|
|
|
}
|
|
|
|
|
strcpy(bufp++, ".");
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
if (r->display && r->display[0]) {
|
|
|
|
|
strcpy(bufp++, " ");
|
|
|
|
|
bufp += strxcpy(bufp, r->display);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
n = r->display[strlen(r->display) - 1];
|
|
|
|
|
if (n != '!' && n != '?' && n != '.') {
|
|
|
|
|
strcpy(bufp++, ".");
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2002-12-18 18:40:21 +01:00
|
|
|
|
{
|
2005-11-20 13:58:59 +01:00
|
|
|
|
const faction * owner = region_owner(r);
|
|
|
|
|
if (owner!=NULL) {
|
2005-05-07 00:30:19 +02:00
|
|
|
|
bufp += strxcpy(bufp, " Die Region ist im Besitz von ");
|
2005-11-20 13:58:59 +01:00
|
|
|
|
bufp += strxcpy(bufp, factionname(owner));
|
2005-05-05 02:12:54 +02:00
|
|
|
|
strcpy(bufp++, ".");
|
2002-12-18 18:40:21 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2007-08-19 19:30:40 +02:00
|
|
|
|
a = a_find(r->attribs, &at_overrideroads);
|
|
|
|
|
if (a) {
|
|
|
|
|
strcpy(bufp++, " ");
|
|
|
|
|
bufp += strxcpy(bufp, (char *)a->data.v);
|
|
|
|
|
} else {
|
|
|
|
|
int nrd = 0;
|
|
|
|
|
|
|
|
|
|
/* Nachbarregionen, die gesehen werden, ermitteln */
|
|
|
|
|
for (d = 0; d != MAXDIRECTIONS; d++)
|
|
|
|
|
if (see[d] && rconnect(r, d)) nrd++;
|
|
|
|
|
|
|
|
|
|
/* list directions */
|
|
|
|
|
|
|
|
|
|
dh = false;
|
|
|
|
|
for (d = 0; d != MAXDIRECTIONS; d++) if (see[d]) {
|
|
|
|
|
region * r2 = rconnect(r, d);
|
|
|
|
|
if(!r2) continue;
|
|
|
|
|
nrd--;
|
|
|
|
|
if (dh) {
|
|
|
|
|
char regname[4096];
|
|
|
|
|
if (nrd == 0) {
|
2006-04-17 01:16:19 +02:00
|
|
|
|
strcpy(bufp++, " ");
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strxcpy(bufp, LOC(f->locale, "nr_nb_final"));
|
|
|
|
|
} else {
|
|
|
|
|
bufp += strxcpy(bufp, LOC(f->locale, "nr_nb_next"));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strxcpy(bufp, LOC(f->locale, directions[d]));
|
|
|
|
|
strcpy(bufp++, " ");
|
|
|
|
|
f_regionid(r2, f, regname, sizeof(regname));
|
|
|
|
|
bufp += sprintf(bufp, trailinto(r2, f->locale),
|
|
|
|
|
regname);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
else {
|
2006-04-17 01:16:19 +02:00
|
|
|
|
strcpy(bufp++, " ");
|
2007-08-19 19:30:40 +02:00
|
|
|
|
MSG(("nr_vicinitystart", "dir region", d, r2), bufp, sizeof(buf)-(bufp-buf), f->locale, f);
|
|
|
|
|
bufp += strlen(bufp);
|
|
|
|
|
dh = true;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
/* Spezielle Richtungen */
|
|
|
|
|
for (a = a_find(r->attribs, &at_direction);a && a->type==&at_direction;a=a->next) {
|
|
|
|
|
spec_direction * d = (spec_direction *)(a->data.v);
|
2007-08-19 22:40:42 +02:00
|
|
|
|
bufp += strlcpy(bufp, " ", sizeof(buf) - (bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, LOC(f->locale, d->desc), sizeof(buf) - (bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, " (\"", sizeof(buf) - (bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, LOC(f->locale, d->keyword), sizeof(buf) - (bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, "\")", sizeof(buf) - (bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, ".", sizeof(buf) - (bufp-buf));
|
2007-08-19 19:30:40 +02:00
|
|
|
|
dh = 1;
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
2005-05-05 02:12:54 +02:00
|
|
|
|
rnl(F);
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if (partial==0 && rplane(r) == get_astralplane() &&
|
|
|
|
|
!is_cursed(r->attribs, C_ASTRALBLOCK, 0)) {
|
|
|
|
|
/* Sonderbehandlung Teleport-Ebene */
|
|
|
|
|
region_list *rl = astralregions(r, inhabitable);
|
|
|
|
|
region_list *rl2;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if (rl) {
|
2006-01-27 00:56:33 +01:00
|
|
|
|
/* TODO: Avoid buffer overflows */
|
|
|
|
|
char * c = buf;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
c += strxcpy(c, "Schemen der Regionen ");
|
|
|
|
|
rl2 = rl;
|
|
|
|
|
while (rl2) {
|
2006-01-27 00:56:33 +01:00
|
|
|
|
c += f_regionid(rl2->data, f, c, sizeof(buf)-(c-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
rl2 = rl2->next;
|
2006-01-27 00:56:33 +01:00
|
|
|
|
if (rl2) {
|
|
|
|
|
c += strxcpy(c, ", ");
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
strcpy(c, " sind erkennbar.");
|
|
|
|
|
free_regionlist(rl);
|
|
|
|
|
/* Schreibe Paragraphen */
|
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
|
|
|
|
|
|
/* Wirkungen permanenter Spr<70>che */
|
|
|
|
|
print_curses(F, f, r, TYP_REGION,0);
|
|
|
|
|
|
|
|
|
|
/* Produktionsreduktion */
|
|
|
|
|
a = a_find(r->attribs, &at_reduceproduction);
|
|
|
|
|
if(a) {
|
|
|
|
|
sprintf(buf, "Die Region ist verw<72>stet, der Boden karg.");
|
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (edges) rnl(F);
|
|
|
|
|
for (e=edges;e;e=e->next) {
|
2005-05-05 05:19:35 +02:00
|
|
|
|
char * bufp = buf;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
boolean first = true;
|
|
|
|
|
for (d=0;d!=MAXDIRECTIONS;++d) {
|
|
|
|
|
if (!e->exist[d]) continue;
|
|
|
|
|
if (first) bufp += strxcpy(bufp, "Im ");
|
|
|
|
|
else {
|
|
|
|
|
if (e->lastd==d) bufp += strxcpy(bufp, " und im ");
|
|
|
|
|
else bufp += strxcpy(bufp, ", im ");
|
|
|
|
|
}
|
|
|
|
|
bufp += strxcpy(bufp, LOC(f->locale, directions[d]));
|
|
|
|
|
first = false;
|
|
|
|
|
}
|
|
|
|
|
if (!e->transparent) bufp += strxcpy(bufp, " versperrt ");
|
|
|
|
|
else bufp += strxcpy(bufp, " befindet sich ");
|
|
|
|
|
bufp += strxcpy(bufp, e->name);
|
|
|
|
|
if (!e->transparent) bufp += strxcpy(bufp, " die Sicht.");
|
|
|
|
|
else strcpy(bufp++, ".");
|
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
if (edges) {
|
|
|
|
|
while (edges) {
|
|
|
|
|
e = edges->next;
|
|
|
|
|
free(edges->name);
|
|
|
|
|
free(edges);
|
|
|
|
|
edges = e;
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
{
|
2006-01-29 15:05:28 +01:00
|
|
|
|
const unit *u;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
int number = 0, p = rpeasants(r);
|
2006-01-29 15:05:28 +01:00
|
|
|
|
message * m;
|
|
|
|
|
item *itm, *items = NULL;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char buf[4096];
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2007-08-19 19:30:40 +02:00
|
|
|
|
/* count */
|
2006-01-29 15:05:28 +01:00
|
|
|
|
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);
|
2005-04-11 21:10:38 +02:00
|
|
|
|
}
|
2006-01-29 15:05:28 +01:00
|
|
|
|
number += u->number;
|
2005-04-10 18:11:20 +02:00
|
|
|
|
}
|
2006-01-29 15:05:28 +01:00
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
/* print */
|
2006-01-29 15:05:28 +01:00
|
|
|
|
rnl(F);
|
|
|
|
|
m = msg_message("nr_stat_header", "region", r);
|
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
|
|
|
|
msg_release(m);
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
2006-01-29 15:05:28 +01:00
|
|
|
|
rnl(F);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
/* Region */
|
|
|
|
|
if (fval(r->terrain, LAND_REGION) && rmoney(r)) {
|
|
|
|
|
m = msg_message("nr_stat_maxentertainment", "max", entertainmoney(r));
|
2005-04-11 21:10:38 +02:00
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rparagraph(F, buf, 2, 2, 0);
|
2005-04-11 21:10:38 +02:00
|
|
|
|
msg_release(m);
|
2006-01-29 15:05:28 +01:00
|
|
|
|
}
|
|
|
|
|
if (production(r) && (!fval(r->terrain, SEA_REGION) || f->race == new_race[RC_AQUARIAN])) {
|
|
|
|
|
m = msg_message("nr_stat_salary", "max", wage(r, f, f->race));
|
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rparagraph(F, buf, 2, 2, 0);
|
2006-01-29 15:05:28 +01:00
|
|
|
|
msg_release(m);
|
|
|
|
|
}
|
|
|
|
|
if (p) {
|
|
|
|
|
m = msg_message("nr_stat_recruits", "max", p / RECRUITFRACTION);
|
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rparagraph(F, buf, 2, 2, 0);
|
2006-01-29 15:05:28 +01:00
|
|
|
|
msg_release(m);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
if (!TradeDisabled()) {
|
|
|
|
|
if (buildingtype_exists(r, bt_find("caravan"))) {
|
2006-04-17 01:16:19 +02:00
|
|
|
|
m = msg_message("nr_stat_luxuries", "max",
|
2006-01-29 15:05:28 +01:00
|
|
|
|
(p * 2) / TRADE_FRACTION);
|
|
|
|
|
} else {
|
2006-04-17 01:16:19 +02:00
|
|
|
|
m = msg_message("nr_stat_luxuries", "max",
|
2006-01-29 15:05:28 +01:00
|
|
|
|
p / TRADE_FRACTION);
|
|
|
|
|
}
|
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rparagraph(F, buf, 2, 2, 0);
|
2006-01-29 15:05:28 +01:00
|
|
|
|
msg_release(m);
|
2005-04-11 21:10:38 +02:00
|
|
|
|
}
|
2006-01-29 15:05:28 +01:00
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
/* info about units */
|
2006-01-29 15:05:28 +01:00
|
|
|
|
|
|
|
|
|
m = msg_message("nr_stat_people", "max", number);
|
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rparagraph(F, buf, 2, 2, 0);
|
2006-01-29 15:05:28 +01:00
|
|
|
|
msg_release(m);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-01-29 15:05:28 +01:00
|
|
|
|
for (itm = items; itm; itm=itm->next) {
|
2006-04-17 01:16:19 +02:00
|
|
|
|
sprintf(buf, "%s: %d",
|
2006-01-29 15:05:28 +01:00
|
|
|
|
LOC(f->locale, resourcename(itm->type->rtype, GR_PLURAL)),
|
|
|
|
|
itm->number);
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rparagraph(F, buf, 2, 2, 0);
|
2006-01-29 15:05:28 +01:00
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
{
|
2006-02-26 12:59:58 +01:00
|
|
|
|
if (fval(r, RF_TRAVELUNIT)) {
|
|
|
|
|
attrib *abegin = a_find(r->attribs, &at_travelunit), *a;
|
|
|
|
|
int counter = 0, maxtravel = 0;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char buf[8192];
|
2006-02-26 12:59:58 +01:00
|
|
|
|
char * str = buf;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2007-08-19 19:30:40 +02:00
|
|
|
|
/* How many are we listing? For grammar. */
|
2006-02-26 12:59:58 +01:00
|
|
|
|
for (a = abegin; a && a->type==&at_travelunit; a = a->next) {
|
|
|
|
|
unit * u = (unit*)a->data.v;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-26 12:59:58 +01:00
|
|
|
|
if (r!=u->region && (u->ship==NULL || fval(u, UFL_OWNER))) {
|
|
|
|
|
if (cansee_durchgezogen(f, r, u, 0)) {
|
|
|
|
|
++maxtravel;
|
|
|
|
|
}
|
2005-06-12 01:02:52 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-26 12:59:58 +01:00
|
|
|
|
if (maxtravel==0) {
|
2005-06-12 01:02:52 +02:00
|
|
|
|
return;
|
2006-02-26 12:59:58 +01:00
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-02-26 12:59:58 +01:00
|
|
|
|
/* Auflisten. */
|
|
|
|
|
*str = '\0';
|
|
|
|
|
rnl(F);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-02-26 12:59:58 +01:00
|
|
|
|
for (a = abegin; a && a->type==&at_travelunit; a = a->next) {
|
|
|
|
|
unit * u = (unit*)a->data.v;
|
|
|
|
|
|
|
|
|
|
if (r!=u->region && (u->ship==NULL || fval(u, UFL_OWNER))) {
|
|
|
|
|
if (cansee_durchgezogen(f, r, u, 0)) {
|
|
|
|
|
++counter;
|
|
|
|
|
if (u->ship != NULL) {
|
|
|
|
|
if (counter == 1) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
str += strlcpy(str, "Die ", sizeof(buf)-(str-buf));
|
2006-02-26 12:59:58 +01:00
|
|
|
|
} else {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
str += strlcpy(str, "die ", sizeof(buf)-(str-buf));
|
2006-02-26 12:59:58 +01:00
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
str += strlcpy(str, shipname(u->ship), sizeof(buf)-(str-buf));
|
2006-02-26 12:59:58 +01:00
|
|
|
|
} else {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
str += strlcpy(str, unitname(u), sizeof(buf)-(str-buf));
|
2006-02-26 12:59:58 +01:00
|
|
|
|
}
|
|
|
|
|
if (counter + 1 < maxtravel) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
str += strlcpy(str, ", ", sizeof(buf)-(str-buf));
|
2006-02-26 12:59:58 +01:00
|
|
|
|
} else if (counter + 1 == maxtravel) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
str += strlcpy(str, LOC(f->locale, "list_and"), sizeof(buf)-(str-buf));
|
2006-02-26 12:59:58 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (maxtravel == 1) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
str += strlcpy(str, " hat die Region durchquert.", sizeof(buf)-(str-buf));
|
2006-02-26 12:59:58 +01:00
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
|
|
|
|
} else {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
str += strlcpy(str, " haben die Region durchquert.", sizeof(buf)-(str-buf));
|
2006-02-26 12:59:58 +01:00
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
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;
|
2007-04-22 01:04:24 +02:00
|
|
|
|
if (!init) { init = true; nocost_ct = ct_find("nocostbuilding"); }
|
2005-04-16 13:15:47 +02:00
|
|
|
|
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
|
2007-08-19 19:30:40 +02:00
|
|
|
|
report_template(const char * filename, report_context * ctx, const char * charset)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2005-11-02 22:10:40 +01:00
|
|
|
|
faction * f = ctx->f;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
region *r;
|
|
|
|
|
plane *pl;
|
2005-11-19 00:23:47 +01:00
|
|
|
|
FILE * F = fopen(filename, "wt");
|
2006-02-19 23:43:56 +01:00
|
|
|
|
seen_region * sr = NULL;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char buf[8192];
|
|
|
|
|
char * bufp;
|
|
|
|
|
int enc = xmlParseCharEncoding(charset);
|
2006-02-19 23:43:56 +01:00
|
|
|
|
|
2005-11-19 00:23:47 +01:00
|
|
|
|
if (F==NULL) {
|
|
|
|
|
perror(filename);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2007-08-19 19:30:40 +02:00
|
|
|
|
if (enc==XML_CHAR_ENCODING_UTF8) {
|
|
|
|
|
const unsigned char utf8_bom[4] = { 0xef, 0xbb, 0xbf };
|
|
|
|
|
fwrite(utf8_bom, 1, 3, F);
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
2006-07-26 16:50:05 +02:00
|
|
|
|
sprintf(buf, "; ECHECK %s-w4 -r%d -v%s", (f->options & want(O_SILBERPOOL)) ? "-l " : "",
|
2004-06-21 18:45:27 +02:00
|
|
|
|
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
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
for (r=ctx->first; sr==NULL && r!=ctx->last; r=r->next) {
|
|
|
|
|
sr = find_seen(ctx->seen, r);
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
for (;sr!=NULL;sr=sr->next) {
|
|
|
|
|
region * r = sr->r;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit *u;
|
|
|
|
|
int dh = 0;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (sr->mode<see_unit) continue;
|
|
|
|
|
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
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);
|
2005-11-20 13:58:59 +01:00
|
|
|
|
sprintf(buf,"; ECheck Lohn %d", wage(r, f, f->race));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
rps_nowrap(F, buf);
|
|
|
|
|
rnl(F);
|
|
|
|
|
rps_nowrap(F, "");
|
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
|
|
|
|
dh = 1;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp = buf + sprintf(buf, "%s %s; %s [%d,%d$", LOC(u->faction->locale, parameters[P_UNIT]),
|
2004-06-21 18:45:27 +02:00
|
|
|
|
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) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, ",U", sizeof(buf)-(bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, itoa10(cost), sizeof(buf)-(bufp-buf));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
} else if (u->ship) {
|
|
|
|
|
if (fval(u, UFL_OWNER))
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, ",S", sizeof(buf)-(bufp-buf));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
else
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, ",s", sizeof(buf)-(bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, shipid(u->ship), sizeof(buf)-(bufp-buf));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
}
|
|
|
|
|
if (lifestyle(u) == 0)
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, ",I", sizeof(buf)-(bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, "]", sizeof(buf)-(bufp-buf));
|
2004-06-21 18:45:27 +02:00
|
|
|
|
|
|
|
|
|
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) {
|
2005-06-05 18:48:22 +02:00
|
|
|
|
if (u->old_orders && is_repeated(ord)) continue; /* unit has defaults */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
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
|
|
|
|
}
|
2006-02-19 23:43:56 +01:00
|
|
|
|
}
|
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-11-19 00:23:47 +01:00
|
|
|
|
fclose(F);
|
2005-04-24 23:49:51 +02:00
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2007-08-19 19:30:40 +02:00
|
|
|
|
show_allies(FILE * F, const faction * f, const ally * allies, char * buf, size_t size)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
int allierte = 0;
|
|
|
|
|
int i=0, h, hh = 0;
|
|
|
|
|
int dh = 0;
|
|
|
|
|
const ally * sf;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char * bufp = buf + strlen(buf); /* buf already contains data */
|
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
for (sf = allies; sf; sf = sf->next) {
|
|
|
|
|
int mode = alliedgroup(NULL, f, sf->faction, sf, HELP_ALL);
|
|
|
|
|
if (mode > 0) ++allierte;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (sf = allies; sf; sf = sf->next) {
|
|
|
|
|
int mode = alliedgroup(NULL, f, sf->faction, sf, HELP_ALL);
|
|
|
|
|
if (mode <= 0) continue;
|
|
|
|
|
i++;
|
|
|
|
|
if (dh) {
|
|
|
|
|
if (i == allierte)
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, LOC(f->locale, "list_and"), size-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
else
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, ", ", size-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
dh = 1;
|
|
|
|
|
hh = 0;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, factionname(sf->faction), size-(bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, " (", size-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if ((mode & HELP_ALL) == HELP_ALL) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, "Alles", size-(bufp-buf));
|
|
|
|
|
} else {
|
2006-04-17 01:16:19 +02:00
|
|
|
|
for (h = 1; h < HELP_ALL; h *= 2) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
int p = MAXPARAMS;
|
|
|
|
|
if ((mode & h) == h) {
|
2006-04-17 01:16:19 +02:00
|
|
|
|
switch (h) {
|
|
|
|
|
case HELP_TRAVEL:
|
2007-08-19 19:30:40 +02:00
|
|
|
|
p = P_TRAVEL;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
break;
|
|
|
|
|
case HELP_MONEY:
|
2007-08-19 19:30:40 +02:00
|
|
|
|
p = P_MONEY;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
hh = 1;
|
|
|
|
|
break;
|
|
|
|
|
case HELP_FIGHT:
|
2007-08-19 19:30:40 +02:00
|
|
|
|
p = P_FIGHT;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
break;
|
|
|
|
|
case HELP_GIVE:
|
2007-08-19 19:30:40 +02:00
|
|
|
|
p = P_GIVE;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
break;
|
|
|
|
|
case HELP_GUARD:
|
2007-08-19 19:30:40 +02:00
|
|
|
|
p = P_GUARD;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
break;
|
|
|
|
|
case HELP_FSTEALTH:
|
2007-08-19 19:30:40 +02:00
|
|
|
|
p = P_FACTIONSTEALTH;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
}
|
|
|
|
|
if (p!=MAXPARAMS) {
|
|
|
|
|
if (hh) strlcpy(bufp, ", ", size-(bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, parameters[p], size-(bufp-buf));
|
|
|
|
|
hh = 1;
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
}
|
|
|
|
|
strlcpy(bufp, ")", size-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
strlcpy(bufp, ".", size-(bufp-buf));
|
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
|
|
|
|
rnl(F);
|
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
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
const group * g = f->groups;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char buf[8192];
|
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if (f->allies) {
|
|
|
|
|
if (!f->allies->next) {
|
|
|
|
|
strcpy(buf, "Wir helfen der Partei ");
|
|
|
|
|
} else {
|
|
|
|
|
strcpy(buf, "Wir helfen den Parteien ");
|
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
show_allies(F, f, f->allies, buf, sizeof(buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
show_allies(F, f, g->allies, buf, sizeof(buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
g = g->next;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2005-11-20 13:58:59 +01:00
|
|
|
|
#ifdef ENEMIES
|
2002-12-18 18:40:21 +01:00
|
|
|
|
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(".");
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
|
|
|
|
rnl(F);
|
2002-12-18 18:40:21 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#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)
|
2007-02-01 23:13:22 +01:00
|
|
|
|
{
|
|
|
|
|
/* die Partei see sieht dies; wegen
|
|
|
|
|
* "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) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char buf[8192];
|
|
|
|
|
char * bufp = buf;
|
|
|
|
|
bufp += strlcpy(bufp, "Die Region wird von ", sizeof(buf) - (bufp-buf));
|
|
|
|
|
|
|
|
|
|
for (i = 0; i!=nextguard+(tarned?1:0); ++i) {
|
|
|
|
|
if (i!=0) {
|
|
|
|
|
if (i == nextguard-(tarned?0:1))
|
|
|
|
|
strlcpy(bufp, LOC(see->locale, "list_and"), sizeof(buf) - (bufp-buf));
|
|
|
|
|
else
|
|
|
|
|
strlcpy(bufp, ", ", sizeof(buf) - (bufp-buf));
|
|
|
|
|
}
|
|
|
|
|
if (i<nextguard) strlcpy(bufp, factionname(guardians[i]), sizeof(buf) - (bufp-buf));
|
2004-05-04 21:24:03 +02:00
|
|
|
|
|
2007-08-19 19:30:40 +02:00
|
|
|
|
else strlcpy(bufp, "unbekannten Einheiten", sizeof(buf) - (bufp-buf));
|
2004-05-04 21:24:03 +02:00
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
strlcpy(bufp, " bewacht.", sizeof(buf) - (bufp-buf));
|
|
|
|
|
rnl(F);
|
|
|
|
|
rparagraph(F, buf, 0, 0, 0);
|
2002-12-18 18:40:21 +01:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
rpline(FILE * F)
|
|
|
|
|
{
|
2006-01-27 00:05:40 +01:00
|
|
|
|
static char line[REPORTWIDTH+1];
|
|
|
|
|
if (line[0]!='-') {
|
|
|
|
|
memset(line, '-', sizeof(line));
|
|
|
|
|
line[REPORTWIDTH] = '\n';
|
|
|
|
|
}
|
|
|
|
|
fwrite(line, sizeof(char), sizeof(line), F);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
const faction_list *flist = seenfactions;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
centre(F, LOC(uf->locale, "nr_addresses"), false);
|
|
|
|
|
rnl(F);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
while (flist!=NULL) {
|
|
|
|
|
const faction * f = flist->data;
|
|
|
|
|
if (f->no!=MONSTER_FACTION) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char buf[8192];
|
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
sprintf(buf, "%s: %s; %s", factionname(f), f->email, f->banner);
|
|
|
|
|
rparagraph(F, buf, 4, 0, (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
|
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
flist = flist->next;
|
|
|
|
|
}
|
|
|
|
|
rnl(F);
|
|
|
|
|
rpline(F);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_building(FILE *F, const region * r, const building * b, const faction * f, int mode)
|
|
|
|
|
{
|
2006-02-20 22:24:09 +01:00
|
|
|
|
int i;
|
|
|
|
|
unit *u;
|
2005-07-23 20:18:53 +02:00
|
|
|
|
const char * bname;
|
2006-02-20 22:24:09 +01:00
|
|
|
|
const struct locale * lang = NULL;
|
|
|
|
|
const building_type * type = b->type;
|
2005-07-23 20:18:53 +02:00
|
|
|
|
static const struct building_type * bt_illusion;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char buffer[8192];
|
|
|
|
|
char * bufp = buffer;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-07-23 20:18:53 +02:00
|
|
|
|
if (!bt_illusion) bt_illusion = bt_find("illusion");
|
2006-02-20 22:24:09 +01:00
|
|
|
|
if (f) lang = f->locale;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += snprintf(bufp, sizeof(buffer)-(bufp-buffer), "%s, %s %d, ", buildingname(b), LOC(f->locale, "nr_size"), b->size);
|
2005-07-23 20:18:53 +02:00
|
|
|
|
|
|
|
|
|
if (b->type==bt_illusion) {
|
|
|
|
|
attrib * a = a_find(b->attribs, &at_icastle);
|
|
|
|
|
if (a!=NULL) {
|
|
|
|
|
type = ((icastle_data*)a->data.v)->type;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bname = LOC(lang, buildingtype(type, b, b->size));
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, bname, sizeof(buffer)-(bufp-buffer));
|
2005-07-23 20:18:53 +02:00
|
|
|
|
if (type!=b->type) {
|
|
|
|
|
unit * owner = buildingowner(r, b);
|
|
|
|
|
if (owner && owner->faction==f) {
|
|
|
|
|
/* illusion. report real type */
|
|
|
|
|
char lbuf[32];
|
|
|
|
|
bname = LOC(lang, buildingtype(b->type, b, b->size));
|
|
|
|
|
sprintf(lbuf, " (%s)", bname);
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, lbuf, sizeof(buffer)-(bufp-buffer));
|
2005-07-23 20:18:53 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-20 22:24:09 +01:00
|
|
|
|
if (b->size < type->maxsize) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, " (im Bau)", sizeof(buffer)-(bufp-buffer));
|
2006-02-20 22:24:09 +01:00
|
|
|
|
}
|
2005-10-23 13:27:55 +02:00
|
|
|
|
|
2006-02-20 22:24:09 +01:00
|
|
|
|
if (b->besieged > 0 && mode>=see_lighthouse) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, ", belagert von ", sizeof(buffer)-(bufp-buffer));
|
|
|
|
|
bufp += strlcpy(bufp, itoa10(b->besieged), sizeof(buffer)-(bufp-buffer));
|
|
|
|
|
bufp += strlcpy(bufp, " Personen ", sizeof(buffer)-(bufp-buffer));
|
2006-02-20 22:24:09 +01:00
|
|
|
|
if (b->besieged >= b->size * SIEGEFACTOR) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, "(abgeschnitten)", sizeof(buffer)-(bufp-buffer));
|
2006-02-20 22:24:09 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
i = 0;
|
|
|
|
|
if (b->display && b->display[0]) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, "; ", sizeof(buffer)-(bufp-buffer));
|
|
|
|
|
bufp += strlcpy(bufp, b->display, sizeof(buffer)-(bufp-buffer));
|
2006-02-20 22:24:09 +01:00
|
|
|
|
i = b->display[strlen(b->display) - 1];
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2005-10-23 13:27:55 +02:00
|
|
|
|
#ifdef WDW_PYRAMID
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-02-20 22:24:09 +01:00
|
|
|
|
if (i != '!' && i != '?' && i != '.') {
|
|
|
|
|
scat(", ");
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-01-01 19:35:55 +01:00
|
|
|
|
if (b->type == bt_find("pyramid")) {
|
2005-10-23 13:27:55 +02:00
|
|
|
|
unit * owner = buildingowner(r, b);
|
|
|
|
|
scat("Gr<EFBFBD><EFBFBD>enstufe ");
|
|
|
|
|
icat(wdw_pyramid_level(b));
|
|
|
|
|
scat(".");
|
|
|
|
|
|
|
|
|
|
if (owner && owner->faction==f) {
|
|
|
|
|
const construction *ctype = b->type->construction;
|
|
|
|
|
int completed = b->size;
|
|
|
|
|
int c;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2005-10-23 13:27:55 +02:00
|
|
|
|
scat(" Baukosten pro Gr<47><72>enpunkt: ");
|
|
|
|
|
|
|
|
|
|
while(ctype->improvement != NULL &&
|
|
|
|
|
ctype->improvement != ctype &&
|
|
|
|
|
ctype->maxsize > 0 &&
|
|
|
|
|
ctype->maxsize <= completed)
|
|
|
|
|
{
|
|
|
|
|
completed -= ctype->maxsize;
|
|
|
|
|
ctype = ctype->improvement;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(ctype->materials != NULL);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-10-23 13:27:55 +02:00
|
|
|
|
for (c=0;ctype->materials[c].number;c++) {
|
2005-10-29 13:17:21 +02:00
|
|
|
|
const resource_type * rtype = ctype->materials[c].rtype;
|
2005-10-23 13:27:55 +02:00
|
|
|
|
int number = ctype->materials[c].number;
|
|
|
|
|
|
|
|
|
|
if(c > 0) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
}
|
|
|
|
|
icat(number);
|
|
|
|
|
scat(" ");
|
2005-10-29 13:17:21 +02:00
|
|
|
|
scat(locale_string(lang, resourcename(rtype, number!=1?GR_PLURAL:0)));
|
2005-10-23 13:27:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
scat(".");
|
2006-02-05 19:21:11 +01:00
|
|
|
|
|
|
|
|
|
scat(" Erforderlicher Talentwert: ");
|
|
|
|
|
icat(b->type->construction->minskill);
|
|
|
|
|
scat(".");
|
2005-09-11 22:16:04 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2005-10-23 13:27:55 +02:00
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
2006-02-20 22:24:09 +01:00
|
|
|
|
if (i != '!' && i != '?' && i != '.')
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, ".", sizeof(buffer)-(bufp-buffer));
|
2005-10-23 13:27:55 +02:00
|
|
|
|
|
2005-09-11 22:16:04 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
2007-08-19 19:30:40 +02:00
|
|
|
|
rparagraph(F, buffer, 2, 0, 0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-20 22:24:09 +01:00
|
|
|
|
if (mode<see_lighthouse) return;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-20 22:24:09 +01:00
|
|
|
|
print_curses(F, f, b, TYP_BUILDING, 4);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-20 22:24:09 +01:00
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->building == b) {
|
|
|
|
|
assert(fval(u, UFL_OWNER) || !"you must call reorder_owners() first!");
|
|
|
|
|
rpunit(F, f, u, 6, mode);
|
|
|
|
|
u = u->next;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (;u!=NULL && u->building==b;u=u->next) {
|
|
|
|
|
rpunit(F, f, u, 6, mode);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2005-11-02 22:10:40 +01:00
|
|
|
|
int
|
2007-08-19 19:30:40 +02:00
|
|
|
|
report_plaintext(const char * filename, report_context * ctx, const char * charset)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2006-02-19 23:43:56 +01:00
|
|
|
|
int flag = 0;
|
|
|
|
|
char ch;
|
|
|
|
|
int dh;
|
|
|
|
|
int anyunits;
|
|
|
|
|
const struct region *r;
|
2005-11-02 22:10:40 +01:00
|
|
|
|
faction * f = ctx->f;
|
2006-02-19 23:43:56 +01:00
|
|
|
|
building *b;
|
|
|
|
|
ship *sh;
|
|
|
|
|
unit *u;
|
2005-11-02 22:10:40 +01:00
|
|
|
|
char pzTime[64];
|
2006-02-19 23:43:56 +01:00
|
|
|
|
attrib *a;
|
|
|
|
|
message * m;
|
|
|
|
|
unsigned char op;
|
2006-07-26 16:50:05 +02:00
|
|
|
|
int ix = want(O_STATISTICS);
|
2006-02-19 23:43:56 +01:00
|
|
|
|
int wants_stats = (f->options & ix);
|
2005-11-19 00:23:47 +01:00
|
|
|
|
FILE * F = fopen(filename, "wt");
|
2006-02-19 23:43:56 +01:00
|
|
|
|
seen_region * sr = NULL;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char buf[8192];
|
|
|
|
|
char * bufp;
|
|
|
|
|
int enc = xmlParseCharEncoding(charset);
|
2006-02-19 23:43:56 +01:00
|
|
|
|
|
2005-11-19 00:23:47 +01:00
|
|
|
|
if (F==NULL) {
|
|
|
|
|
perror(filename);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
if (enc==XML_CHAR_ENCODING_UTF8) {
|
|
|
|
|
const unsigned char utf8_bom[4] = { 0xef, 0xbb, 0xbf };
|
|
|
|
|
fwrite(utf8_bom, 1, 3, F);
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2005-11-02 22:10:40 +01:00
|
|
|
|
strftime(pzTime, 64, "%A, %d. %B %Y, %H:%M", localtime(&ctx->report_time));
|
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);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
centre(F, buf, true);
|
2002-07-23 09:23:28 +02:00
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
centre(F, gamedate_season(f->locale), true);
|
|
|
|
|
rnl(F);
|
|
|
|
|
sprintf(buf, "%s, %s/%s (%s)", factionname(f),
|
|
|
|
|
LOC(f->locale, rc_name(f->race, 1)),
|
2005-10-23 11:05:11 +02:00
|
|
|
|
LOC(f->locale, mkname("school", magietypen[f->magiegebiet])),
|
2006-04-17 01:16:19 +02:00
|
|
|
|
f->email);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
if (f->alliance!=NULL) {
|
|
|
|
|
centre(F, alliancename(f->alliance), true);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-17 23:59:03 +01:00
|
|
|
|
#ifdef KARMA_MODULE
|
2006-04-17 01:16:19 +02:00
|
|
|
|
buf[0] = 0;
|
|
|
|
|
dh = 0;
|
|
|
|
|
for (a=a_find(f->attribs, &at_faction_special); a && a->type==&at_faction_special; a=a->next) {
|
2005-11-02 22:10:40 +01:00
|
|
|
|
char buf2[80];
|
2006-04-17 01:16:19 +02:00
|
|
|
|
dh++;
|
|
|
|
|
if (fspecials[a->data.sa[0]].maxlevel != 100) {
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
if (f->karma > 0) {
|
|
|
|
|
sprintf(buf, "Deine Partei hat %d Karma.", f->karma);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
}
|
2006-02-17 23:59:03 +01:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-17 23:59:03 +01:00
|
|
|
|
dh = 0;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if (f->age <= 2) {
|
2007-05-28 21:45:08 +02:00
|
|
|
|
const char * s;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if (f->age <= 1) {
|
|
|
|
|
ADDMSG(&f->msgs, msg_message("changepasswd",
|
|
|
|
|
"value", f->passw));
|
|
|
|
|
}
|
|
|
|
|
RENDER(f, buf, sizeof(buf), ("newbie_password", "password", f->passw));
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, buf, true);
|
2007-05-28 21:45:08 +02:00
|
|
|
|
s = locale_getstring(f->locale, "newbie_info_1");
|
|
|
|
|
if (s) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, s, true);
|
|
|
|
|
}
|
|
|
|
|
s = locale_getstring(f->locale, "newbie_info_2");
|
|
|
|
|
if (s) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, s, true);
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if ((f->options & want(O_COMPUTER)) == 0) {
|
|
|
|
|
f->options |= want(O_COMPUTER);
|
2007-05-28 21:45:08 +02:00
|
|
|
|
s = locale_getstring(f->locale, "newbie_info_3");
|
|
|
|
|
if (s) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, s, true);
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rnl(F);
|
2005-07-31 18:07:02 +02:00
|
|
|
|
#ifdef SCORE_MODULE
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if (f->options & want(O_SCORE) && f->age > DISPLAYSCORE) {
|
|
|
|
|
RENDER(f, buf, sizeof(buf), ("nr_score", "score average", f->score, average_score_of_age(f->age, f->age / 24 + 1)));
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
}
|
2005-07-31 18:07:02 +02:00
|
|
|
|
#endif
|
2006-04-17 01:16:19 +02: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);
|
2005-07-25 21:21:05 +02:00
|
|
|
|
m = msg_message("nr_migrants", "units maxunits", count_migrants(f), maxmig);
|
2005-07-25 21:10:21 +02:00
|
|
|
|
nr_render(m, f->locale, buf, sizeof(buf), f);
|
2005-07-25 21:21:05 +02:00
|
|
|
|
msg_release(m);
|
2006-04-17 01:16:19 +02: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) {
|
2006-01-08 13:25:00 +01:00
|
|
|
|
message * msg = msg_message("nr_heroes", "units maxunits", countheroes(f), maxh);
|
|
|
|
|
nr_render(msg, f->locale, buf, sizeof(buf), f);
|
|
|
|
|
msg_release(msg);
|
2004-10-19 00:03:32 +02:00
|
|
|
|
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) {
|
2006-01-08 13:25:00 +01:00
|
|
|
|
message * msg = msg_message("nr_claims", "items", f->items);
|
|
|
|
|
nr_render(msg, f->locale, buf, sizeof(buf), f);
|
|
|
|
|
msg_release(msg);
|
2004-12-22 01:53:12 +01:00
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
}
|
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
/* Insekten-Winter-Warnung */
|
2007-08-19 19:30:40 +02:00
|
|
|
|
if (f->race == new_race[RC_INSECT]) {
|
2005-06-05 15:34:08 +02:00
|
|
|
|
static int thisseason = -1;
|
|
|
|
|
if (thisseason<0) thisseason = get_gamedate(turn+1, 0)->season;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
if (thisseason == 0) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
centre(F, LOC(f->locale, "nr_insectwinter"), true);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
rnl(F);
|
2005-06-05 15:34:08 +02:00
|
|
|
|
} else {
|
|
|
|
|
static int nextseason = -1;
|
|
|
|
|
if (nextseason<0) nextseason = get_gamedate(turn+2, 0)->season;
|
|
|
|
|
if (nextseason == 0) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
centre(F, LOC(f->locale, "nr_insectfall"), true);
|
2005-06-05 15:34:08 +02:00
|
|
|
|
rnl(F);
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp = buf + sprintf(buf, "%s:", LOC(f->locale, "nr_options"));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
for (op = 0; op != MAXOPTIONS; op++) {
|
2006-07-26 16:50:05 +02:00
|
|
|
|
if (f->options & want(op)) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, " ", sizeof(buf)-(bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, LOC(f->locale, options[op]), sizeof(buf)-(bufp-buf));
|
2001-02-28 23:14:59 +01:00
|
|
|
|
#ifdef AT_OPTION
|
2006-04-17 01:16:19 +02: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;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, "(", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
for(i=1; sec != 0; i *= 2) {
|
|
|
|
|
if(sec & i) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, itoa10(i), sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
sec = sec & ~i;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
if (sec) bufp += strlcpy(bufp, ",", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, ")", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-02-28 23:14:59 +01:00
|
|
|
|
#endif
|
2006-04-17 01:16:19 +02:00
|
|
|
|
flag++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (flag > 0) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
}
|
2006-01-21 09:34:01 +01:00
|
|
|
|
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rp_messages(F, f->msgs, f, 0, true);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
rp_battles(F, f);
|
|
|
|
|
a = a_find(f->attribs, &at_reportspell);
|
|
|
|
|
if (a) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, LOC(f->locale, "section_newspells"), true);
|
|
|
|
|
while (a && a->type==&at_reportspell) {
|
2006-01-01 19:35:55 +01:00
|
|
|
|
spell *sp = (spell *)a->data.v;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
report_spell(F, sp, f->locale);
|
|
|
|
|
a = a->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ch = 0;
|
|
|
|
|
for (a=a_find(f->attribs, &at_showitem);a && a->type==&at_showitem;a=a->next) {
|
|
|
|
|
const potion_type * ptype = resource2potion(((const item_type*)a->data.v)->rtype);
|
|
|
|
|
const char * description = NULL;
|
|
|
|
|
requirement * m;
|
2003-05-28 18:24:28 +02:00
|
|
|
|
if (ptype!=NULL) {
|
|
|
|
|
const char * pname = resourcename(ptype->itype->rtype, 0);
|
2007-08-19 19:30:40 +02:00
|
|
|
|
char * bufp;
|
|
|
|
|
|
2006-04-17 01:16:19 +02:00
|
|
|
|
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);
|
2007-08-19 19:30:40 +02:00
|
|
|
|
|
|
|
|
|
bufp = buf + sprintf(buf, "%s: ", LOC(f->locale, "nr_herbsrequired"));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
while (m->number) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, resourcename(m->rtype, 0), sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
++m;
|
2007-08-19 19:30:40 +02:00
|
|
|
|
if (m->number)
|
|
|
|
|
bufp += strlcpy(bufp, ", ", sizeof(buf)-(bufp-buf));
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
|
|
|
|
centre(F, buf, true);
|
|
|
|
|
rnl(F);
|
2005-10-30 10:51:02 +01:00
|
|
|
|
if (description==NULL) {
|
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);
|
|
|
|
|
}
|
2006-02-19 23:43:56 +01:00
|
|
|
|
centre(F, description, true);
|
2003-05-28 18:24:28 +02:00
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
}
|
2006-02-19 23:43:56 +01:00
|
|
|
|
rnl(F);
|
|
|
|
|
centre(F, LOC(f->locale, "nr_alliances"), false);
|
|
|
|
|
rnl(F);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2005-11-20 13:58:59 +01:00
|
|
|
|
#ifdef ENEMIES
|
2002-12-18 18:40:21 +01:00
|
|
|
|
enemies(F, f);
|
|
|
|
|
#endif
|
2006-02-19 23:43:56 +01:00
|
|
|
|
allies(F, f);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
rpline(F);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
anyunits = 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
for (r=ctx->first;sr==NULL && r!=ctx->last;r=r->next) {
|
|
|
|
|
sr = find_seen(ctx->seen, r);
|
|
|
|
|
}
|
|
|
|
|
for (;sr!=NULL;sr=sr->next) {
|
|
|
|
|
region * r = sr->r;
|
2007-02-21 20:59:27 +01:00
|
|
|
|
int stealthmod = stealth_modifier(sr->mode);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2007-02-21 20:59:27 +01:00
|
|
|
|
if (sr->mode<see_lighthouse) continue;
|
2006-01-29 15:05:28 +01:00
|
|
|
|
/* Beschreibung */
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2007-02-21 20:59:27 +01:00
|
|
|
|
if (sr->mode==see_unit) {
|
2007-02-25 09:58:01 +01:00
|
|
|
|
anyunits = 1;
|
2006-01-29 15:05:28 +01:00
|
|
|
|
describe(F, r, 0, f);
|
|
|
|
|
if (!TradeDisabled() && !fval(r->terrain, SEA_REGION) && rpeasants(r)/TRADE_FRACTION > 0) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
prices(F, r, f);
|
|
|
|
|
}
|
|
|
|
|
guards(F, r, f);
|
|
|
|
|
durchreisende(F, r, f);
|
|
|
|
|
}
|
2002-12-18 18:40:21 +01:00
|
|
|
|
else {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (sr->mode==see_far) {
|
|
|
|
|
describe(F, r, 3, f);
|
|
|
|
|
guards(F, r, f);
|
|
|
|
|
durchreisende(F, r, f);
|
|
|
|
|
}
|
2007-02-21 20:59:27 +01:00
|
|
|
|
else if (sr->mode==see_lighthouse) {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
describe(F, r, 2, f);
|
|
|
|
|
durchreisende(F, r, f);
|
|
|
|
|
} else {
|
|
|
|
|
describe(F, r, 1, f);
|
|
|
|
|
durchreisende(F, r, f);
|
|
|
|
|
}
|
2002-12-18 18:40:21 +01:00
|
|
|
|
}
|
2006-02-19 23:43:56 +01:00
|
|
|
|
/* Statistik */
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2007-02-21 20:59:27 +01:00
|
|
|
|
if (wants_stats && sr->mode==see_unit)
|
2006-02-19 23:43:56 +01:00
|
|
|
|
statistics(F, r, f);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
/* Nachrichten an REGION in der Region */
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2007-02-21 20:59:27 +01:00
|
|
|
|
if (sr->mode==see_unit || sr->mode==see_travel) {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
message_list * mlist = r_getmessages(r, f);
|
|
|
|
|
rp_messages(F, r->msgs, f, 0, true);
|
|
|
|
|
if (mlist) rp_messages(F, mlist, f, 0, true);
|
|
|
|
|
}
|
|
|
|
|
/* Burgen und ihre Einheiten */
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
for (b = rbuildings(r); b; b = b->next) {
|
|
|
|
|
rnl(F);
|
|
|
|
|
report_building(F, r, b, f, sr->mode);
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
/* Restliche Einheiten */
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2007-02-21 20:59:27 +01:00
|
|
|
|
if (stealthmod>INT_MIN) {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (!u->building && !u->ship) {
|
2007-02-21 20:59:27 +01:00
|
|
|
|
if (u->faction == f || cansee(f, r, u, stealthmod)) {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (dh == 0 && !(rbuildings(r) || r->ships)) {
|
|
|
|
|
dh = 1;
|
|
|
|
|
/* rnl(F); */
|
|
|
|
|
}
|
|
|
|
|
rpunit(F, f, u, 4, sr->mode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
/* Schiffe und ihre Einheiten */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
for (sh = r->ships; sh; sh = sh->next) {
|
|
|
|
|
faction *of = NULL;
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
rnl(F);
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
/* Gewicht feststellen */
|
2006-04-17 01:16:19 +02: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)) {
|
|
|
|
|
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 */
|
2006-04-17 01:16:19 +02:00
|
|
|
|
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp = buf + 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 {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp = buf + sprintf(buf, "%s, %s", shipname(sh), LOC(f->locale, sh->type->name[0]));
|
2005-04-17 18:02:13 +02:00
|
|
|
|
}
|
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) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += sprintf(bufp, ", %s (%d/%d)",
|
2005-04-17 18:02:13 +02:00
|
|
|
|
LOC(f->locale, "nr_undercons"), sh->size,
|
|
|
|
|
sh->type->construction->maxsize);
|
|
|
|
|
}
|
|
|
|
|
if (sh->damage) {
|
2006-05-19 21:37:33 +02:00
|
|
|
|
int percent = (sh->damage*100+DAMAGE_SCALE-1)/(sh->size*DAMAGE_SCALE);
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += sprintf(bufp, ", %d%% %s", percent, LOC(f->locale, "nr_damaged"));
|
2005-04-17 18:02:13 +02:00
|
|
|
|
}
|
2005-10-25 14:38:01 +02:00
|
|
|
|
if (!fval(r->terrain, SEA_REGION)) {
|
2005-04-17 18:02:13 +02:00
|
|
|
|
if (sh->coast != NODIRECTION) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, ", ", sizeof(buf) - (bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, LOC(f->locale, coasts[sh->coast]), sizeof(buf) - (bufp-buf));
|
2005-04-17 18:02:13 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ch = 0;
|
2005-04-23 11:47:03 +02:00
|
|
|
|
if (sh->display && sh->display[0]) {
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, "; ", sizeof(buf) - (bufp-buf));
|
|
|
|
|
bufp += strlcpy(bufp, sh->display, sizeof(buf) - (bufp-buf));
|
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 != '.')
|
2007-08-19 19:30:40 +02:00
|
|
|
|
bufp += strlcpy(bufp, ".", sizeof(buf) - (bufp-buf));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-01-30 00:17:38 +01:00
|
|
|
|
rparagraph(F, buf, 2, 0, 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)) {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
rpunit(F, f, u, 6, sr->mode);
|
2005-04-17 18:02:13 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
if (u->ship == sh && !fval(u, UFL_OWNER)) {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
rpunit(F, f, u, 6, sr->mode);
|
2005-04-17 18:02:13 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rnl(F);
|
|
|
|
|
rpline(F);
|
|
|
|
|
}
|
|
|
|
|
if (f->no != MONSTER_FACTION) {
|
|
|
|
|
if (!anyunits) {
|
|
|
|
|
rnl(F);
|
2006-01-29 23:14:43 +01:00
|
|
|
|
rparagraph(F, LOC(f->locale, "nr_youaredead"), 0, 2, 0);
|
2005-04-17 18:02:13 +02:00
|
|
|
|
} else {
|
2005-11-02 22:10:40 +01:00
|
|
|
|
list_address(F, f, ctx->addresses);
|
2005-04-17 18:02:13 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2005-11-19 00:23:47 +01:00
|
|
|
|
fclose(F);
|
2005-04-24 23:49:51 +02:00
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
base36conversion(void)
|
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
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 {
|
2006-04-17 01:16:19 +02:00
|
|
|
|
struct fsee * nexthash;
|
|
|
|
|
faction * f;
|
|
|
|
|
struct see {
|
|
|
|
|
struct see * next;
|
|
|
|
|
faction * seen;
|
|
|
|
|
unit * proof;
|
|
|
|
|
} * see;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} * 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)
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
unit *
|
|
|
|
|
can_find(faction * f, faction * f2)
|
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
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) {
|
|
|
|
|
/* bei TARNE PARTEI yxz muss die Partei von unit proof nicht
|
|
|
|
|
* wirklich Partei f2 sein! */
|
|
|
|
|
/* assert(ss->proof->faction==f2); */
|
|
|
|
|
return ss->proof;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
{
|
2006-04-17 01:16:19 +02: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-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
static void
|
2001-01-25 10:37:55 +01:00
|
|
|
|
update_find(void)
|
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
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)) {
|
|
|
|
|
faction *fv = visible_faction(u->faction, u2);
|
|
|
|
|
lastf = fv;
|
|
|
|
|
add_find(u->faction, u2, fv);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
initial = false;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boolean
|
|
|
|
|
kann_finden(faction * f1, faction * f2)
|
|
|
|
|
{
|
2006-04-17 01:16:19 +02:00
|
|
|
|
update_find();
|
|
|
|
|
return (boolean)(can_find(f1, f2)!=NULL);
|
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
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_init(void)
|
|
|
|
|
{
|
2005-11-02 22:10:40 +01:00
|
|
|
|
register_reporttype("nr", &report_plaintext, 1<<O_REPORT);
|
|
|
|
|
register_reporttype("txt", &report_template, 1<<O_ZUGVORLAGE);
|
- 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
|
|
|
|
}
|
2005-11-02 22:10:40 +01:00
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_cleanup(void)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for (i=0;i!=FMAXHASH;++i) {
|
|
|
|
|
while (fsee[i]) {
|
|
|
|
|
struct fsee * fs = fsee[i]->nexthash;
|
|
|
|
|
free(fsee[i]);
|
|
|
|
|
fsee[i] = fs;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|