diff --git a/src/tools/address.crf b/src/tools/address.crf deleted file mode 100644 index ef6f82771..000000000 --- a/src/tools/address.crf +++ /dev/null @@ -1,6 +0,0 @@ -@VERSION -@ADRESSEN -;Partei -;Parteiname -;banner -;email diff --git a/src/tools/echeck.c b/src/tools/echeck.c deleted file mode 100644 index a001372be..000000000 --- a/src/tools/echeck.c +++ /dev/null @@ -1,4672 +0,0 @@ -/* vi: set ts=2 ai sw=2: - * - * $Id: echeck.c,v 1.5 2001/02/05 21:17:14 faroul Exp $ - * - * Eressea PB(E)M host Copyright (C) 1997-2000 - * Enno Rehling (rehling@usa.net) - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@gmx.de) - * - * based on: - * - * Atlantis v1.0 13 September 1993 Copyright 1993 by Russell Wallace - * Atlantis v1.7 Copyright 1996 by Alex Schröder - * - * This program is freeware. It may not be sold or used commercially. - * Please send any changes or bugfixes to the authors. - * - * Eressea PBeM Order Syntax Checker - */ - -#ifdef _MSC_VER -# pragma warning (disable: 4711) -#endif - -#define MAINVERSION "3" -#define MINVERSION "11" -#define PATCHLEVEL "0" - -#ifndef DEFAULT_PATH -# if defined(unix) -# define DEFAULT_PATH "/usr/local/lib/echeck:." -# define PATH_DELIM ":" -# else -# define DEFAULT_PATH NULL -# define PATH_DELIM ";" -# endif -#endif - - -#define VERSION MAINVERSION"."MINVERSION"."PATCHLEVEL - -#include -#include -#include -#include -#include - -#ifdef DMALLOC -# include -#endif - -#if macintosh -# include /* macintosh console handler zur eingabe von parametern - added 15.6.00 chartus */ -# define UMLAUTE -#endif - -enum { - UT_NONE, - UT_PARAM, - UT_ITEM, - UT_SKILL, - UT_KEYWORD, - UT_BUILDING, - UT_HERB, - UT_POTION, - UT_RACE, - UT_MAX -}; - - -#if __STDC__ -/* strdup ist nicht ANSI */ -# if !(defined __USE_SVID) && !(defined __USE_BSD) && !(defined __USE_XOPEN_EXTENDED) -/* ... ist aber unter Linux trotzdem definiert. */ -# define strdup(s) (strcpy((char*)malloc(sizeof(char)*strlen(s)+1), s)) -# endif -#endif - -#ifdef AMIGA - const char version[]="\0$VER: ECheck V"VERSION", "__DATE__"\0"; -#endif - -#ifdef _MSC_VER -# include -#endif - -#ifndef BOOL_DEFINED -# define BOOL_DEFINED -# ifndef bool -# define bool char -# define true ((bool)1) -# define false ((bool)0) -# endif -#endif - -#ifdef WIN32 -# define strncasecmp _strnicmp -# define strcasecmp _stricmp -#endif - -#if defined(AMIGA) || defined(UMLAUTE) - /* ohne brauchbares locale.h wird das nix bei Umlauten */ -int -a_isspace(char c) { - return (c==' ' || c=='\t' || c=='\f'); -} - - -char -a_tolower(char c) { - switch (c) { - case 'Ä': return 'ä'; - case 'Ö': return 'ö'; - case 'Ü': return 'ü'; - default: return (char) tolower(c); - } -} - - -int -a_strncasecmp(const char *a, const char *b, size_t s) { - int i,j; - - if (!a || !b || !*a || !*b || strlen(b) < s) - return -1; - do { - i=*a++ & 0xDF; /* 1101 1111 - Groß/Kleinschreibung weglassen */ - j=*b++ & 0xDF; - } while (i-j==0 && *a && *b && --s); - return i-j; -} - - -# define strncasecmp(x,y,n) a_strncasecmp(x,y,n) -# define strcasecmp(x,y) a_strncasecmp(x,y,strlen(x)) -# ifdef tolower -# undef tolower -# endif -# define tolower(x) a_tolower(x) - -#else -# include -# define a_isspace(c) isspace(c) -#endif - -#define SPACE_REPLACEMENT '~' -#define SPACE ' ' -#define ESCAPE_CHAR '\\' -#define COMMENT_CHAR ';' -#define MARGIN 78 -#define RECRUIT_COST 50 - -#define INDENT_FACTION 0 -#define INDENT_UNIT 2 -#define INDENT_ORDERS 4 -#define INDENT_NEW_ORDERS 6 - -#ifndef min -# define min(a,b) ((a) < (b) ? (a) : (b)) -#endif -#ifndef max -# define max(a,b) ((a) > (b) ? (a) : (b)) -#endif - -#define BUFSIZE 8192 -#define MAXLINE 4096 -#define DISPLAYSIZE 4095 -#define NAMESIZE 127 - -FILE *ERR, *OUT=0; - -int line_no, /* count line number */ - MAXSPELLS, - MAXITEMS; -char echo_it=0, /* option: echo input lines */ - no_comment=-3, /* Keine Infos in [] hinter EINHEIT */ - show_warnings=4, /* option: print warnings (levels) */ - warnings_cl=0, /* -w auf der Kommandozeile gegeben */ - warn_off=0, /* ECHECK NOWARN */ - use_stderr=0, /* option: use stderr for errors etc */ - brief=0, /* option: don't list errors */ - ignore_NameMe=0, /* option: ignoriere NameMe-Kommentare ;; */ - piping=0, /* option: wird output als pipe-input benutzt? */ - empiria=0, /* option: Empiria-Checking */ - lohn=10, /* Lohn für Arbeit - je Region zu setzen */ - silberpool=0, /* option: Silberpool-Verwaltung */ - line_start=0, /* option: Beginn der Zeilenzählung */ - noship=0, - noroute=0, - nolost=0, - has_version=0, - at_cmd=0, - attack_warning=0, - compile=0; /* option: compiler-style warnings */ -int error_count=0, /* counter: errors */ - warning_count=0; /* counter: warnings */ -char order_buf[BUFSIZE], /* current order line */ - checked_buf[BUFSIZE], /* checked order line */ - message_buf[BUFSIZE], /* messages are composed here */ - warn_buf[BUFSIZE], /* warnings are composed here */ - indent, next_indent, /* indent index */ - does_default=0, /* Ist DEFAULT aktiv? */ - befehle_ende, /* EOF der Befehlsdatei */ - *filename; -int rec_cost=RECRUIT_COST, - this_command, - this_unit, /* wird von getaunit gesetzt */ - Rx, Ry; /* Koordinaten der aktuellen Region */ -const char *path; -FILE *F; - -/* ------------------------------------------------------------- */ - -enum { - K_WORK, - K_ATTACK, - K_STEAL, - K_BESIEGE, - K_NAME, - K_USE, - K_DISPLAY, - K_ENTER, - K_GUARD, - K_MAIL, - K_END, - K_DRIVE, - K_FOLLOW, - K_RESEARCH, - K_GIVE, - K_ALLY, - K_STATUS, - K_COMBAT, - K_BUY, - K_CONTACT, - K_TEACH, - K_STUDY, - K_LIEFERE, - K_MAKE, - K_MOVE, - K_PASSWORD, - K_RECRUIT, - K_REPORT, - K_OPTION, - K_SPY, - K_SETSTEALTH, - K_TRANSPORT, - K_QUIT, - K_TAX, - K_TURMZAUBER, - K_ENTERTAIN, - K_SELL, - K_LEAVE, - K_CAST, - K_RESHOW, - K_DESTROY, - K_VERGESSE, - K_BIETE, - K_DEFAULT, - K_COMMENT, - K_ROUTE, - K_SABOTIERE, - K_ZUECHTE, - K_URSPRUNG, - K_EMAIL, - K_RESERVE, - K_BANNER, - K_MEINUNG, - K_NUMMER, - K_MAGIEGEBIET, - K_PIRATERIE, - K_NEUSTART, - K_GRUPPE, - K_SORTIERE, - /* Empiria only: */ - K_SEND, - K_FIND, - K_ADDRESS, - MAXKEYWORDS -}; - - -static char *keywords[MAXKEYWORDS]={ - "Arbeiten", - "Attackieren", - "Beklauen", - "Belagere", - "Benennen", - "Benutzen", - "Beschreiben", - "Betreten", - "Bewachen", - "Botschaft", - "Ende", - "Fahren", - "Folgen", - "Forschen", - "Gib", - "Helfen", - "Kämpfen", - "Kampfzauber", - "Kaufen", - "Kontaktieren", - "Lehren", - "Lernen", - "Liefere", - "Machen", - "Nach", - "Passwort", - "Rekrutieren", - "Report", - "Option", - "Spionieren", - "Tarnen", - "Transportieren", - "Stirb", - "Treiben", - "Turmzauber", - "Unterhalten", - "Verkaufen", - "Verlassen", - "Zaubere", - "Zeigen", - "Zerstören", - "Vergessen", - "Bieten", - "Default", - "//", - "Route", - "Sabotieren", - "Züchten", - "Ursprung", - "Email", - "Reservieren", - "Banner", - "Meinung", - "Nummer", - "Magiegebiet", - "Piraterie", - "Neustart", - "Gruppe", - "Sortiere", - /* Empiria only: */ - "Sende", - "Finde", - "Adresse" -}; - - -static char *magiegebiet[]={ - "Illaun", - "Tybied", - "Cerddor", - "Gwyrrd", - "Draig" -}; - - -enum { - P_ALLES, - P_PEASANT, - P_CASTLE, - P_GEBAEUDE, - P_UNIT, - P_FLEE, - P_BEHIND, - P_VORNE, - P_CONTROL, - P_HERBS, - P_NOT, - P_NEXT, - P_FACTION, - P_PERSON, - P_REGION, - P_SHIP, - P_SILVER, - P_ROAD, - P_TEMP, - P_PRIVAT, - P_KAEMPFE, - P_OBSERVE, - P_GIVE, - P_GUARD, - P_WARN, - P_SPELLBOOK, - P_STUFE, - P_HORSE, - P_FREMD, - MAXPARAMS -}; - - -static char *parameters[MAXPARAMS]={ - "Alles", - "Bauern", - "Burg", - "Gebäude", - "Einheit", - "Fliehe", - "Hinten", - "Vorne", - "Kommando", - "Kräuter", - "Nicht", - "Nächster", - "Partei", - "Personen", - "Region", - "Schiff", - "Silber", - "Straßen", - "Temp", - "Privat", - "Kämpfe", - "Wahrnehmung", - "Gib", - "Bewache", - "Warnung", - "Zauberbuch", - "Stufe", /* Eressea-Zauber */ - "Pferde", /* ZÜCHTE PFERDE */ - "Fremdes" -}; - - -static char *reports[]={ /* Fehler und Meldungen im Report */ - "Kampf", - "Ereignisse", - "Bewegung", - "Einkommen", - "Handel", - "Produktion", - "Orkvermehrung", - "Alles" -}; - -static const int MAXREPORTS=sizeof(reports)/sizeof(reports[0]); - - -static char *message_levels[]={ - "Wichtig", - "Debug", - "Fehler", - "Warnungen", - "Infos" -}; - -static const int ML_MAX=sizeof(message_levels)/sizeof(message_levels[0]); - - -static char *options[]={ - "Auswertung", - "Computer", - "Statistik", - "Zipped", - "Merian", - "Zugvorlage", /* ab hier Eressea only */ - "Silberpool", - "Materialpool", - "Adressen", - "Bzip2" -}; - -static const int MAXOPTIONS=sizeof(options)/sizeof(options[0]); - - -enum { - D_NORTH, - D_SOUTH, - D_EAST, - D_WEST, - D_PAUSE, - D_NORTHEAST, - D_NORTHWEST, - D_SOUTHEAST, - D_SOUTHWEST, - MAXDIRECTIONS -}; - - -static char *directions[MAXDIRECTIONS]={ - "Norden", - "Sueden", /* Empiria hat keine Umlaute! */ - "Osten", - "Westen", - "Pause", - "Nordosten", - "Nordwesten", - "Südosten", - "Südwesten" -}; - - -static char *Rassen[]={ - "Menschen", - "Zwerge", - "Elfen", - "Orks", - "Dämonen", - "Meermenschen", - "Halblinge", - "Trolle", - "Goblins", - "Katzen", - "Insekten" -}; - -static const int R_MAX=sizeof(Rassen)/sizeof(Rassen[0]); - - -static char *shiptypes[]={ - "Boot", - "Langboot", - "Drachenschiff", - "Karavelle", - "Trireme" -}; - -static const int MAXSHIPS=sizeof(shiptypes)/sizeof(shiptypes[0]); - - -enum { - POT_FAST, - POT_STRONG, - POT_TREES, - POT_DOMORE, - POT_HEILWASSER, - POT_BAUERNBLUT, - POT_WISE, - POT_FOOL, - POT_WARMTH, - POT_HORSE, - POT_BERSERK, - POT_PEOPLE, - POT_WAHRHEIT, - POT_MACHT, - POT_HEAL, - MAXPOTIONS -}; - - -enum { - H_PLAIN_1, - H_PLAIN_2, - H_PLAIN_3, - H_FOREST_1, - H_FOREST_2, - H_FOREST_3, - H_SWAMP_1, - H_SWAMP_2, - H_SWAMP_3, - H_DESERT_1, - H_DESERT_2, - H_DESERT_3, - H_HIGHLAND_1, - H_HIGHLAND_2, - H_HIGHLAND_3, - H_MOUNTAIN_1, - H_MOUNTAIN_2, - H_MOUNTAIN_3, - H_GLACIER_1, - H_GLACIER_2, - H_GLACIER_3, - MAXHERBS -}; - - -static char *herbdata[2][MAXHERBS]={ - { - "Flachwurz", - "Würziger Wagemut", - "Eulenauge", - "Grüner Spinnerich", - "Blauer Baumringel", - "Elfenlieb", - "Gurgelkraut", - "Knotiger Saugwurz", - "Blasenmorchel", - "Wasserfinder", - "Kakteenschwitz", - "Sandfäule", - "Windbeutel", - "Fjordwuchs", - "Alraune", - "Steinbeißer", - "Spaltwachs", - "Höhlenglimm", - "Eisblume", - "Weißer Wüterich", - "Schneekristall" - }, - { - "Flachwurze", - "Würzige Wagemute", - "Eulenaugen", - "Grüne Spinneriche", - "Blaue Baumringel", - "Elfenlieb", - "Gurgelkräuter", - "Knotige Saugwurze", - "Blasenmorcheln", - "Wasserfinder", - "Kakteenschwitze", - "Sandfäulen", - "Windbeutel", - "Fjordwuchse", - "Alraunen", - "Steinbeißer", - "Spaltwachse", - "Höhlenglimme", - "Eisblumen", - "Weiße Wüteriche", - "Schneekristalle" - } -}; - - -typedef struct _names { - char *txt; - struct _names *next; -} t_names; - - -typedef struct _item { - t_names *name; - struct _item *next; -} t_item; - -t_item *itemdata=NULL; - - -typedef struct t_spell { - char *name; - int kosten; - char typ; - struct t_spell *next; -} t_spell; - -t_spell *spells=NULL; - - -typedef struct _skills { - char *name; - int kosten; - struct _skills *next; -} t_skills; - -t_skills *skilldata=NULL; - - -enum { - I_BALM, - I_SPICES, - I_JEWELERY, - I_MYRRH, - I_OIL, - I_SILK, - I_INCENSE -}; - - -#define isluxury(i) (i<=I_INCENSE) - -#define SP_ZAUBER 1 -#define SP_KAMPF 2 -#define SP_POST 4 -#define SP_PRAE 8 -#define SP_BATTLE 14 /* 2+4+8 */ -#define SP_ALL 15 - -#define MAXPOTIONS 15 - -char* potionnames[2][MAXPOTIONS]={ - { - /* Stufe 1: */ - "Siebenmeilentee", - "Goliathwasser", - "Wasser des Lebens", - "Trank der Wahrheit", - /* Stufe 2: */ - "Schaffenstrunk", - "Wundsalbe", - "Bauernblut", - /* Stufe 3: */ - "Gehirnschmalz", - "Dumpfbackenbrot", - "Nestwärme", - "Pferdeglück", - "Berserkerblut", - /* Stufe 4: */ - "Bauernlieb", - "Elixier der Macht", - "Heiltrank" - }, { - /* Stufe 1: */ - "Siebenmeilentees", - "Goliathwasser", - "Wasser des Lebens", - "Tränke der Wahrheit", - /* Stufe 2: */ - "Schaffenstrünke", - "Wundsalben", - "Bauernblut", - /* Stufe 3: */ - "Gehirnschmalz", - "Dumpfbackenbrote", - "Nestwärme", - "Pferdeglück", - "Berserkerblut", - /* Stufe 4: */ - "Bauernlieb", - "Elixiere der Macht", - "Heiltränke" - } -}; - - -static char* buildingtypes[]={ - "Burg", - "Leuchtturm", - "Bergwerk", - "Steinbruch", - "Hafen", - "Akademie", /* wird in inittokens() für Empiria rausgefiltert */ - "Magierturm", - "Schmiede", - "Sägewerk", - "Pferdezucht", - "Monument", - "Damm", - "Karawanserei", - "Tunnel", - "Taverne", - "Universität", /* wird in inittokens() für Eressea rausgefiltert */ - NULL -}; - - -enum { - POSSIBLE, - NECESSARY -}; - - -/* --------------------------------------------------------------------- */ - -typedef struct list { - struct list *next; -} list; - - -typedef struct t_region { - struct t_region *next; - int personen, geld, x, y, line_no, reserviert; - char *name; -} t_region; - - -typedef struct unit { - struct unit *next; - int no; - int people; - int money; - int reserviert; - int unterhalt; - int line_no; - int temp; - int ship; /* Nummer unseres Schiffes; ship<0: ich bin owner */ - char lives, hasmoved; - t_region *region; - int newx, newy; - int transport; /* hier steht drin, welche Einheit mich TRANSPORTIEREn wird */ - int drive; /* hier steht drin, welche Einheit mich TRANSPORTIEREn soll */ - /* wenn drive!=0, muß transport==drive sein, sonst irgendwo Tippfehler */ - int start_of_orders_line; - int long_order_line; - char *start_of_orders; - char *long_order; - char *order; - int schueler; - int lehrer; - int lernt; - int spell; /* Bit-Map: 2^Spell-Typ */ -} unit; - - -typedef struct teach { - struct teach *next; - unit *teacher; - unit *student; -} teach; - - -teach *teachings=NULL; - -unit *units=NULL, - *order_unit, /* Die Einheit, die gerade dran ist */ - *mother_unit, /* Die Einheit, die MACHE TEMP macht */ - *cmd_unit; /* Die Einheit, die gerade angesprochen wird, z.B. mit GIB */ - -t_region *Regionen=NULL; - -typedef struct tnode { - char c; - bool leaf; - int id; - struct tnode * nexthash; - struct tnode * next[32]; -} tnode; - - -tnode tokens[UT_MAX]; - -/* Prototypes */ -unit * find_unit(int i, int t); -unit * newunit(int n, int t); - - -void * -cmalloc(int n) { - void *p; - - if (n==0) - n=1; - p=calloc(n,1); - if (p==NULL) { - puts("\007 * Kein freier Speicher mehr *"); - exit(1); - } - return p; -} - - -int -Pow(int p) { - if (!p) - return 1; - else - return 2<<(p-1); -} - - -char nulls[]="\0\0\0\0\0\0\0\0"; - -const char* -itob(int i) { - char *dst; - int b=i; - - if (i==0) return "0"; - - if (empiria) { - static char s[8]; - sprintf(s, "%d", i); - return s; - } - dst=nulls+6; - while (b>0) { - int x=b%36; - b/=36; dst--; - if (x<10) - *dst=(char)('0'+x); - else - *dst=(char)('a'+(x-10)); - } - return dst; -} - - -#define scat(X) strcat(checked_buf, X) -#define Scat(X) scat(" ");scat(X) - -void -qcat(char *s) { - char *x; - - x=strchr(s, ' '); - if (x != NULL && does_default==0) - scat(" \""); - else - scat(" "); - scat(s); - if (x != NULL && does_default==0) - scat("\""); -} - - -void -icat(int n) { - static char s[10]; - sprintf(s, " %d", n); - scat(s); -} - - -void -bcat(int n) { - if (empiria) - icat(n); - else { - static char s[10]; - sprintf(s, " %s", itob(n)); - scat(s); - } -} - - -char * -ItemName(int i, int plural) { - static int ino=0; - static t_item *item=NULL, *it=NULL; - int x; - - if (!it) item=it=itemdata; - if (i!=ino) { - x=i; - if (inext; - if (!it) { - fprintf(ERR,"Fehler: Item %d (%d) nicht gefunden!\n",ino,i); - exit(123); - } - item=it; - } - if (plural) - return item->name->next->txt; - return item->name->txt; -} - - -FILE * -path_fopen(const char *path, const char *file, const char *mode) { - FILE *f; - char *pathw = strdup(path); - char *token; - char buf[4096]; - - token = strtok(pathw, PATH_DELIM); - while(token) { - sprintf(buf, "%s/%s", token, file); - f = fopen(buf, mode); - if(f) { - free(pathw); - return f; - } - token = strtok(NULL, PATH_DELIM); - } - free(pathw); - return NULL; -} - - -void -readspells(void) { - char *s,*x; - t_spell *it, *in; - char *file; - - F = path_fopen(path, "zauber.txt", "r"); - if (!F) { - fprintf(ERR, "Kann Datei 'zauber.txt' nicht lesen.\n" - "Suchpfad ist '%s'\n", file, path); - return; - } - - it=in=spells; - for (;;) { - do { - s=fgets(order_buf, MAXLINE, F); - } while (s && (*s=='#' || *s=='\n')); /* Leer- und Kommentarzeilen überlesen */ - if (!s) { - fclose(F); - return; - } - it=cmalloc(sizeof(t_spell)); - x=strchr(s,';'); - if (!x) x=strchr(s,','); - if (x) *x=0; - else { - x=strchr(s,'\n'); - if (x) *x=0; - x=NULL; - } - it->name=strdup(s); - if (x) { - s=(char *)(x+1); - while (a_isspace(*s)) s++; - it->kosten=atoi(s); - x=strchr(s,';'); - if (!x) x=strchr(s,','); - if (x) { - s=(char *)(x+1); - it->typ=(char)Pow(atoi(s)); - } - } - if (in) in->next=it; - in=it; - if (!spells) spells=in; - } /* Abbruch oben */ -} - - -void -readskills(void) { - char *s,*x; - t_skills *it, *in; - char *file; - - F = path_fopen(path, "talente.txt", "r"); - if (!F) { - fprintf(ERR, "Kann Datei 'talente.txt' nicht lesen.\n" - "Suchpfad ist '%s'\n", file, path); - return; - } - - it=in=skilldata; - for (;;) { - do { - s=fgets(order_buf, MAXLINE, F); - } while (s && (*s=='#' || *s=='\n')); /* Leer- und Kommentarzeilen überlesen */ - if (!s) { - fclose(F); - return; - } - it=cmalloc(sizeof(t_skills)); - x=strchr(s,';'); - if (!x) x=strchr(s,','); - if (x) *x=0; - else { - x=strchr(s,'\n'); - if (x) *x=0; - x=NULL; - } - it->name=strdup(s); - if (x) { - s=(char *)(x+1); - while (a_isspace(*s)) s++; - it->kosten=atoi(s); - } - if (in) in->next=it; - in=it; - if (!skilldata) skilldata=in; - } /* Abbruch oben */ -} - - -void -readitems(void) { - char *s,*x; - t_item *it, *in; - t_names *n, *nn; - char *file; - - F = path_fopen(path, "items.txt", "r"); - if(!F) { - fprintf(ERR, "Kann Datei 'items.txt' nicht lesen.\n" - "Suchpfad ist '%s'\n", file, path); - return; - } - - it=in=itemdata; - for (;;) { - do { - s=fgets(order_buf, MAXLINE, F); - } while (s && (*s=='#' || *s=='\n')); /* Leer- und Kommentarzeilen überlesen */ - if (!s) { - fclose(F); - return; - } - it=cmalloc(sizeof(t_item)); - nn=NULL; - x=s; - do { - n=cmalloc(sizeof(t_names)); - x=strchr(s,';'); - if (x) *x=0; - else { - x=strchr(s,'\n'); - if (x) *x=0; - x=NULL; - } - n->txt=strdup(s); - if (x) { - s=(char *)(x+1); - while (a_isspace(*s)) s++; - } - if (nn) nn->next=n; - nn=n; - if (!it->name) it->name=nn; - } while (x && *s); - if (in) in->next=it; - in=it; - if (!itemdata) itemdata=in; - } /* Abbruch oben */ -} - - -void -porder(void) { - int i; - - if (echo_it) { - if (does_default != 2) - for (i=0; i != indent; i++) - putc(' ',OUT); - - if (at_cmd) - putc('@',OUT); - at_cmd=0; - if (does_default>0) - fprintf(OUT,"%s%s",checked_buf, does_default==2 ? "\"\n" : ""); - else - { - fputs(checked_buf,OUT); - putc('\n',OUT); - } - } - checked_buf[0]=0; - if (next_indent != indent) - indent=next_indent; -} - - -char * -wrap(char *s) { - int i, j, k; - - strcpy(message_buf,s); - - /* i zählt die Länge des Strings s ab. j zählt die Länge der Zeile ab. - Ist der Rand erreicht, wird k auf i gesetzt, und rückwärts eine - Leerstelle gesucht, die man mit einem '\n' ersetzen könnte. */ - - for (i=0, j=25; s[i]; i++, j++) { /* j=25: "Warnung zur Zeile xyz:" */ - if (j==MARGIN) { - for (k=i; !a_isspace(s[k]) && k>0; k--); - /* findet man eine Leerstelle, wird sie durch '\n' ersetzt: */ - if (k>0) { - message_buf[k]='\n'; - j=i-k; - } - } else - /* Hat man das letzte mal keine Leerstelle gefunden, so reagiert man - einfach auf die nächste Leerstelle, ohne nach vorwärts zu suchen - (das hat man ja schon einmal gemacht) */ - - if (j>MARGIN && a_isspace(s[i])) { - message_buf[i]='\n'; - j=0; - } - } - return message_buf; -} - - -void -Error(char *s, int l, char *o) { - error_count++; - if (!brief) { - if (!compile) - fprintf(ERR, "Fehler in Zeile %d: %s.\n `%s'\n\n", l, wrap(s), o); - else - fprintf(ERR, "%s(%d): Fehler: %s. `%s'\n", filename, l, s, o); - } -} - - -#define anerror(s) Error(s,line_no,order_buf) - -int -btoi(char *s) { - char *x=s; - int i=0; - - if (!(*s)) return 0; - while(isalnum(*s)) s++; - if (s) *s=0; - s=x; - if (strlen(s)>(size_t)(4+empiria)) { - sprintf(message_buf,"Zahl '%s' ist zu groß. Stattdessen 1 benutzt",s); - anerror(message_buf); - return 1; - } -#ifdef HAVE_STRTOL - i=(int)(strtol(x, NULL, empiria ? 10 : 36)); -#else - if (empiria) - i=atoi(s); - else { - while (isalnum(*s)) { - i*=36; - if (isupper(*s)) i+=(*s)-'A'+10; - else if (islower(*s)) i+=(*s)-'a'+10; - else if (isdigit(*s)) i+=(*s)-'0'; - ++s; - } - } -#endif - return i; -} - - -const char * -uid(unit *u) { - static char *bf=NULL; - if (!bf) bf=cmalloc(18); - sprintf(bf,"%s%s", u->temp!=0 ? "TEMP " : "", itob(u->no)); - return bf; -} - - -const char * -Uid(int i) { - static char *bf=NULL; - unit *u; - u=find_unit(i,0); - if (!u) u=find_unit(i,1); - if (!u) { - sprintf(warn_buf,"Konnte Einheit %s nicht ermitteln",itob(i)); - Error(warn_buf,line_no,""); - u=newunit(-1,0); - } - if (!bf) bf=cmalloc(18); - sprintf(bf,"%s%s", u->temp!=0 ? "TEMP " : "", itob(u->no)); - return bf; -} - - -void -warn(char *s, int line_no, char level) { - if (warn_off) return; - if (level>show_warnings) return; - warning_count++; - if (show_warnings && !brief) { - if (!compile) - fprintf(ERR, "Warnung zur Zeile %d: %s\n", line_no, wrap(s)); - else - fprintf(ERR, "%s(%d): Warnung (%d): %s\n", filename, line_no, level, s); - } -} - - -void -warning(char *s, int l, char *o, char level) { - if (warn_off) return; - if (level>show_warnings) return; - warning_count++; - if (show_warnings && !brief) { - if (!compile) - fprintf(ERR, "Warnung zur Zeile %d: %s.\n `%s'\n\n", l, wrap(s), o); - else - fprintf(ERR, "%s(%d): Warnung (%d): %s. `%s'\n", filename, l, level, s, o); - } -} - - -#define awarning(s,level) warning(s,line_no,order_buf,level) - -void -checkstring(char *s, size_t l, int type) { - if (l>0 && strlen(s)>l) { - sprintf(warn_buf, "Text zu lang (max. %d)", (int)(l)); - awarning(warn_buf,2); - } - if (s[0]==0 && type==NECESSARY) - awarning("Kein Text",1); - - strncpy(warn_buf, s, l); - - if (echo_it && s[0]) { - if (strlen(s) + strlen(checked_buf) > MARGIN) { - qcat(wrap(s)); - } else - qcat(s); - } -} - - -/* - Speicher und Listen Funktionen ---------------------------- */ - -#define addlist(l,p) (p->next=*l, *l=p) - -int current_temp_no; - /* Enthält die TEMP No, falls eine TEMP Einheit angesprochen wurde. */ - -int from_temp_unit_no; - /* Enthält die TEMP No, falls Befehle von einer TEMP Einheit gelesen werden. */ - -#define val(x) (x!=0) - -unit * -find_unit(int i, int t) { - unit *u; - - for (u=units; u; u=u->next) - if ((i < 0 && u->no < 0) || (u->no==i && val(u->temp)==val(t))) - break; - return u; -} - - - -t_region * -addregion(int x, int y, int pers) { - static t_region *r=NULL; - - if (!r || r->x != x || r->y != y) { - for (r=Regionen; r; r=r->next) - if (x==r->x && y==r->y) - break; - } - - if (!r) { - r=cmalloc(sizeof(t_region)); - r->x=x; - r->y=y; - r->personen=pers; - r->geld=0; - r->reserviert=0; - r->name=strdup("Region"); - r->line_no=line_no; - r->next=Regionen; - Regionen=r; - } else { - r->personen+=pers; - } - return r; -} - - -void -addteach(unit *teacher, unit *student) { - teach *t, **teachlist=&teachings; - - for (t=teachings; t; t=t->next) { - if (t->student==student) { - if (!teacher) /* Aufruf durch Schüler, aber Lehrer hat schon Struktur angelegt */ - return; - if (t->teacher==teacher) /* kann eigentlich nicht vorkommen, aber egal */ - return; - if (t->teacher==NULL) { /* Schüler hat Struct angelegt (mit unbek. Lehrer), - wir tragen jetzt nur noch den Lehrer nach */ - t->teacher=teacher; - return; - } - } - } - t=cmalloc(sizeof(teach)); - t->next=NULL; - t->teacher=teacher; - t->student=student; - addlist(teachlist, t); -} - - -unit * -newunit(int n, int t) { - unit *u=find_unit(n,t), **up=&units; - - if (!u) { - u=cmalloc(sizeof(unit)); - u->no=n; - u->line_no=line_no; - u->order=strdup(order_buf); - u->region=addregion(Rx, Ry, 0); - u->newx=Rx; - u->newy=Ry; - u->temp=t; - addlist(up, u); - } - - if (u->temp<0) { - sprintf(warn_buf, "`TEMP %s' wird in Region %d,%d und Region %d,%d " - "(Zeile %d) gebraucht", itob(u->no), Rx, Ry, u->newx, u->newy, - u->start_of_orders_line); - anerror(warn_buf); - u->long_order_line=0; - } - - if (u->temp<42) - u->temp=t; - - if (t) - current_temp_no=n; - else - current_temp_no=0; - - return u; -} - - -int -atoip(char *s) { - int n; - - n=atoi(s); - if (n<0) - n=0; - return n; -} - - -char * -igetstr(char *s1) { - int i; - static char *s; - static char buf[BUFSIZE]; - - if (s1) - s=s1; - while (s[0]==SPACE) - s++; - - for (i=0; s[0] && s[0] != SPACE && i < sizeof(buf); i++, s++) { - buf[i]=s[0]; - - if (s[0]==SPACE_REPLACEMENT) { - if (i>0 && buf[i-1]==ESCAPE_CHAR) - buf[--i]=SPACE_REPLACEMENT; - else - buf[i]=SPACE; - } - } - buf[i]=0; - - return buf; -} - - -#define getstr() igetstr(NULL) -#define getb() btoi(igetstr(NULL)) -#define geti() atoi(igetstr(NULL)) -#define getI() empiria?atoi(igetstr(NULL)):getb() - -int -findstr(char **v, const char *s, int max) { - int i; - size_t ss=strlen(s); - - if (!s[0]) - return -1; - for (i=0; i < max; i++) - if (v[i] && strncasecmp(s, v[i], ss)==0) - return i; - return -1; -} - - -int -findtoken(const char *str, int type) { - tnode *tk = &tokens[type]; - - if (*str=='@') { - str++; - at_cmd=1; - } else - at_cmd=0; - - while (*str) { - char c=(char)tolower(*str); - int index=((unsigned char)c)%32; - tk=tk->next[index]; - while (tk && tk->c!=c) tk=tk->nexthash; - ++str; - if (!tk) return -1; - } - if (tk->id>=0) return tk->id; - else return -1; -} - - -int -findparam(const char *s) { - int p; - p=findtoken(s, UT_PARAM); - if (p != -1) - return p; - p=findtoken(s, UT_BUILDING); - if (p != -1) - return P_GEBAEUDE; - return -1; -} - - -int -isparam(char *s, int i, char print) { - if (i != findparam(s)) - return 0; - - if (print) { - Scat(parameters[i]); - } - return 1; -} - - -t_spell * -findspell(char *s) { - t_spell *sp; - - if (!s[0] || !spells) - return NULL; - for (sp=spells; sp; sp=sp->next) - if (sp->name && !strncasecmp(sp->name, s, strlen(s))) - return sp; - return NULL; -} - - -t_skills * -findskill(char *s) { - int i; - t_skills *sk=skilldata; - - i=findtoken(s, UT_SKILL); - if (i<0) - return NULL; - while (i--) sk=sk->next; - return sk; -} - - -#define findherb(s) findtoken(s, UT_HERB) -#define findpotion(s) findtoken(s, UT_POTION) -#define finditem(s) findtoken(s, UT_ITEM) -#define findbuildingtype(s) findtoken(s, UT_BUILDING) -#define findreport(s) findstr(reports,s,MAXREPORTS) -#define findoption(s) findstr(options,s,MAXOPTIONS) -#define findshiptype(s) findstr(shiptypes,s,MAXSHIPS); -#define getskill() findskill(getstr()) -#define getparam() findparam(getstr()) -#define igetparam(s) findparam(igetstr(s)) - - -int -finddirection(char *s) { -#define MAXDIRNAMES 13 - char* dirs[MAXDIRNAMES]={ - "NW", - "NO", - "Nordwesten", - "Nordosten", - "Suedosten", - "Südosten", - "Suedwesten", - "Südwesten", - "SO", - "SW", - "Pause", - "Osten", - "Westen" - /* mit dieser routine kann man mehrere namen für eine direction geben, - * das ist für die hexes ideal. */ - }; - static const int dir_xref[MAXDIRNAMES]={ - D_NORTHWEST, - D_NORTHEAST, - D_NORTHWEST, - D_NORTHEAST, - D_SOUTHEAST, - D_SOUTHEAST, - D_SOUTHWEST, - D_SOUTHWEST, - D_SOUTHEAST, - D_SOUTHWEST, - D_PAUSE, - D_EAST, - D_WEST - }; - int uc; - - if (!*s) - return -2; - if (empiria) - return findstr(directions, s, 4); - else { - if (strcmp(s,"//")==0) /* "NACH NW NO NO // nach Xontormia" ist erlaubt */ - return -2; - uc=findstr(dirs, s, MAXDIRNAMES); - } - if (uc != -1) - return dir_xref[uc]; - return uc; -} - - -#define getdirection() finddirection(getstr()) - -int -getoption(void) { - int i=findoption(getstr()); - if (empiria && i>5) /* Option ist Eressea only */ - return -1; - return i; -} - - -#define findkeyword(s) findtoken(s, UT_KEYWORD) -#define igetkeyword(s) findkeyword(igetstr(s)) - -char * -getbuf(void) { - char lbuf[MAXLINE]; - bool cont = false; - bool quote = false; - bool report = false; - char * cp = warn_buf; - - lbuf[MAXLINE-1] = '@'; - - do { - bool eatwhite = true; - bool start = true; - char *end; - char *bp = fgets(lbuf, MAXLINE, F); - - if (!bp) return NULL; - - end=bp+strlen(bp); - if (*(end-1)=='\n') { - line_no++; - *(--end)=0; - } else { - /* wenn die Zeile länger als erlaubt war, wird der Rest weggeworfen: */ - while (bp && !lbuf[MAXLINE-1] && lbuf[MAXLINE-2]!='\n') - bp=fgets(warn_buf, 1024, F); - sprintf(warn_buf, "%.30s", lbuf); - Error("Zeile zu lang", line_no, warn_buf); - bp=lbuf; - } - cont=false; - while (cp!=warn_buf+MAXLINE && bp!=lbuf+MAXLINE && *bp) { - if (a_isspace(*bp)) { - if (eatwhite) { - do { ++bp; } while (bp!=lbuf+MAXLINE && a_isspace(*bp)); - if (!quote && !start) *(cp++)=' '; - } else { - do { - *(cp++)=SPACE_REPLACEMENT; - ++bp; - } while (cp!=warn_buf+MAXLINE && bp!=lbuf+MAXLINE && a_isspace(*bp)); - } - } else { - cont=false; - if (*bp=='"') { - quote=(bool)!quote; - eatwhite=true; - } else { - if (*bp=='\\') cont=true; - else -#if !defined(AMIGA) && !defined(UMLAUTE) - if (!iscntrl(*bp)) { -#else - if ((unsigned char)(*bp)>32) { -#endif - - *(cp++) = *bp; - eatwhite = (bool)!quote; - } - } - ++bp; - } - start=false; - } - if (cp==warn_buf+MAXLINE) { - --cp; - if (!report) { - report=true; - sprintf(lbuf, "%.30s", warn_buf); - Error("Zeile zu lang", line_no, lbuf); - } - } - *cp=0; - } while (cont || cp==warn_buf); - - if (quote) - Error("Fehlende \"",line_no,lbuf); - - return warn_buf; -} - - -void -get_order(void) { - char *buf; - bool ok=false; - - while (!befehle_ende && !ok) { - buf=getbuf(); - - if (buf) { - if (buf[0]==COMMENT_CHAR && buf[1]==COMMENT_CHAR) { - if (ignore_NameMe) line_no--; - continue; - } - strcpy(order_buf,buf); - ok=true; - } else - befehle_ende=1; - } -} - - -void -getafaction(char *s) { - int i; - - if (empiria) i=atoi(s); - else i=btoi(s); - if (!s[0]) - anerror("Partei fehlt"); - else { - if (!i) - awarning("Partei 0 verwendet",1); - icat(i); - } -} - - -int -getmoreunits(bool partei) { - char *s; - int i, count, temp; - unit *u; - - count=0; - for (;;) { - s=getstr(); - if (!(*s)) - break; - - if (partei) { - if (empiria) - i=atoi(s); - else - i=btoi(s); - if (i<1) { - sprintf(warn_buf,"Partei '%s' ungültig",s); - anerror(warn_buf); - } else - bcat(i); - } else { - if (findparam(s)==P_TEMP) { - scat(" TEMP"); - temp=1; - s=getstr(); - } else - temp=0; - i=btoi(s); - - if (!i) { - sprintf(warn_buf,"Einheit '%s' geht hier nicht",s); - anerror(warn_buf); - } else { - bcat(i); - if (!does_default) { - u=newunit(i,temp); - addteach(order_unit, u); - } - } - } - count++; - } - return count; -} - - -int -getaunit(int type) { - char *s, is_temp=0; - int i; - - current_temp_no=0; - cmd_unit=NULL; - - s=getstr(); - switch (findparam(s)) { - case P_PEASANT: - Scat(parameters[P_PEASANT]); - this_unit=0; - return 2; - - case P_TEMP: - scat(" TEMP"); - s=getstr(); - current_temp_no=i=btoi(s); - is_temp=1; - break; - - default: - i=btoi(s); - break; - } - - if (type==42) { /* Nur Test, ob eine Einheit kommt, weil das ein Fehler ist */ - if (i) - return 42; - return 0; - } - - this_unit=i; - - if (s[0]==0) { - if (type==NECESSARY) - anerror("Einheit fehlt"); - return 0; - } - /* wenn in s etwas drinnen steht, aber i==0 ist, gilt es! */ - if (s[0] && i==0) { - if (empiria) awarning("Einheit 0 verwendet",2); - /* Bei Empiria kann man sich leichter vertippen; base36 erlaubt mehr */ - scat("0"); - return 2; /* Einheit 0==Bauern! */ - } - - cmd_unit=newunit(i,is_temp); /* Die Unit schon machen, wegen TEMP-Check */ - bcat(i); - if (is_temp) - return 3; - return 1; -} - - -void -copy_unit(unit *from, unit *to) { - to->no=from->no; - to->people=from->people; - to->money=from->money; - to->line_no=from->line_no; - to->temp=from->temp; - to->lives=from->lives; - to->start_of_orders_line=from->start_of_orders_line; - to->long_order_line=from->long_order_line; - if (from->start_of_orders_line) - to->start_of_orders=strdup(from->start_of_orders); - if (from->long_order_line) - to->long_order=strdup(from->long_order); - if (from->order) - to->order=strdup(from->order); - to->lernt=from->lernt; -} - - -char * -netaddress(char *s) { - char *s1, *s2; - - if (strncasecmp(s, "internet:", 9)!=0) - return 0; - - s1=strchr(s, '@'); - if (!s1) - return 0; - - while (s1 > s && *s1 && (isalnum(*s1) || *s1=='@' || *s1=='-' || - *s1=='.' || *s1=='_')) - s1--; - - s1++; - - s2=s1; - while (*s2 && (isalnum(*s2) || *s2=='@' || *s2=='-' || *s2=='.' || *s2=='_')) - s2++; - - *s2=0; - - if (s2-s1>DISPLAYSIZE) { - anerror("Adresse zu lang"); - return 0; - } - return s1; -} - - -void -checkemail(void) { - char *s, *addr; - - scat(keywords[K_EMAIL]); - addr=getstr(); - checkstring(addr, DISPLAYSIZE, NECESSARY); - - if (!addr) { - awarning("eMail bitte mit EMAIL setzen",3); - scat("; eMail bitte mit EMAIL setzen!"); - return; - } - s=strchr(addr, '@'); - if (!s) { - anerror("Ungültige eMail-Adresse"); - return; - } - scat("; Zustellung an "); - scat(addr); -} - - -void -checkaddr(void) { - char *s, *addr; - - scat(keywords[K_ADDRESS]); - s=getstr(); - checkstring(s, DISPLAYSIZE, NECESSARY); - - addr=netaddress(s); - if (!addr) { - strcpy(warn_buf,"Adresse enthält keine eMail mehr, bitte mit EMAIL setzen"); - awarning(warn_buf,1); - scat("; eMail bitte mit EMAIL setzen"); - } else { - scat("; Zustellung an "); - scat(addr); - } -} - - -/* Check auf langen Befehl usw. - aus ACheck.c 4.1 */ - -void -end_unit_orders(void) { - if (!order_unit) /* Für die ersten Befehle der ersten Einheit. */ - return; - - if (order_unit->lives>0 && !order_unit->long_order_line && order_unit->people>0) { - sprintf(warn_buf, "Einheit %s hat keinen langen Befehl bekommen", - uid(order_unit)); - warning(warn_buf, order_unit->start_of_orders_line, - order_unit->start_of_orders,2); - } -} - - -void -orders_for_unit(int i, unit *u) { - unit *t; - char *k, *j, *e; - int s; - - end_unit_orders(); - mother_unit=order_unit=u; - - if (u->start_of_orders_line) { - sprintf(warn_buf, "Einheit %s hat schon in Zeile %d Befehle bekommen. ", - uid(u), u->start_of_orders_line); - do { - i++; if (i<1) i=1; - u=newunit(i, 0); - } while (u->start_of_orders_line); - strcat(warn_buf,"Benutze stattdessen Einheit "); - strcat(warn_buf, itob(i)); - awarning(warn_buf,1); - order_unit=u; - } - - u->start_of_orders=strdup(order_buf); - u->start_of_orders_line=line_no; - u->lives=1; - - if (no_comment>0) - return; - - k=strchr(order_buf,'['); - if (!k) { - awarning("Kann Kommentar zu Personen nicht auswerten",4); - no_comment++; - return; - } - k++; - while (!atoi(k)) { /* Hier ist eine [ im Namen; - 0 Personen ist nicht in der Zugvorlage */ - k=strchr(k,'['); - if (!k) { - awarning("Kann Kommentar zu Personen nicht auswerten",4); - no_comment++; - return; - } - k++; - } - e=strchr(k,']'); - u->people+=atoi(k); - j=strchr(k,','); - if (!j) j=strchr(k,';'); - if (!j || j>e) { - awarning("Kann Kommentar zu Silber nicht auswerten",4); - no_comment++; - return; - } - while (!isdigit(j[0])) j++; - u->money+=atoi(j); - j=strchr(k,'U'); - if (j && junterhalt=atoi(j); - } - - if (!empiria) { - j=strchr(k,'I'); - if (j && jlives=-1; - } - j=strchr(k,'s'); - if (j && jship>=0) /* hat sonst schon ein Schiffskommando! */ - u->ship=btoi(j); - } - j=strchr(k,'S'); - if (j && jnext) /* vielleicht hat schon eine Einheit durch */ - if (t->ship==s) { /* BETRETE das Kommando; das ist ja falsch */ - t->ship=-s; - break; - } - u->ship=s; - } - } - addregion(Rx, Ry, u->people); -} - - -void -orders_for_temp_unit(unit *u) { - if (u->start_of_orders_line && u->region==Regionen) { - /* in Regionen steht die aktuelle Region drin */ - sprintf (warn_buf, "`TEMP %s' wurde in Zeile %d schon gebraucht", - itob(u->no), u->start_of_orders_line); - anerror (warn_buf); - /* return; Trotzdem kein return, damit die Befehle ordnungsgemäß - zugeordnet werden! */ - } - u->line_no=line_no; - u->lives=1; - if (u->order) - free(u->order); - u->order=strdup(order_buf); - if (u->start_of_orders) - free(u->start_of_orders); - u->start_of_orders=strdup(order_buf); - u->start_of_orders_line=line_no; - mother_unit=order_unit; - order_unit=u; -} - - -void -long_order(void) { - char *s, *q; - int i; - - if (order_unit->long_order_line) { - if (!empiria) { - s=strdup(order_unit->long_order); - q=strchr(s,' '); - if (q) *q=0; /* Den Befehl extrahieren */ - i=findkeyword(s); - switch (i) { - case K_CAST: - if (this_command==i) - return; - /* ZAUBERE ist zwar kein langer Befehl, aber man darf auch - * keine anderen langen haben - darum ist bei denen long_order() */ - case K_SELL: - case K_BUY: - if (this_command==K_SELL || this_command==K_BUY) - return; - /* Es sind mehrere VERKAUFE (und rein theoretisch auch KAUFE) - * pro Einheit möglich */ - } - if ((i==K_FOLLOW && this_command!=K_FOLLOW) || - (i!=K_FOLLOW && this_command==K_FOLLOW)) - return; /* FOLGE ist nur Trigger */ - } - - if (strlen(order_unit->long_order) > DISPLAYSIZE+NAMESIZE) - order_unit->long_order[DISPLAYSIZE+NAMESIZE]=0; - /* zu lange Befehle kappen */ - sprintf(warn_buf, "Einheit %s hat schon einen langen Befehl in" - " Zeile %d (`%s')", uid(order_unit), - order_unit->long_order_line, order_unit->long_order); - awarning(warn_buf,1); - } else { - order_unit->long_order=strdup(order_buf); - order_unit->long_order_line=line_no; - } -} - - -void -checknaming(void) { - int i; - char *s; - - scat(keywords[K_NAME]); - i=findparam(getstr()); - s=getstr(); - if (!empiria && i==P_FREMD) { - if (i==P_REGION) { - sprintf(warn_buf,"BENENNE FREMD nicht mit %s",parameters[i]); - anerror(warn_buf); - } else - Scat(parameters[P_FREMD]); - i=findparam(s); - s=getstr(); - } - if (strchr(s,'(')) - awarning("Namen dürfen keine Klammern enthalten",1); - - switch (i) { - case -1: - anerror("Objekt nicht erkannt"); - break; - - case P_UNIT: - case P_FACTION: - case P_GEBAEUDE: - case P_CASTLE: - case P_SHIP: - case P_REGION: - Scat(parameters[i]); - checkstring(s, NAMESIZE, NECESSARY); - break; - - default: - anerror("Objekt kann nicht umbenannt werden"); - } -} - - -void -checkdisplay(void) { - int i; - - scat(keywords[K_DISPLAY]); - i=findparam(getstr()); - - switch (i) { - case -1: - anerror("Objekt nicht erkannt"); - break; - - case P_REGION: - case P_UNIT: - case P_GEBAEUDE: - case P_CASTLE: - case P_SHIP: - case P_PRIVAT: - Scat(parameters[i]); - checkstring(getstr(), 0, POSSIBLE); - break; - - default: - anerror("Objekt kann nicht beschrieben werden"); - } -} - - -void -check_leave(void) { - unit *t,*T=NULL; - int s; - - s=order_unit->ship; - order_unit->ship=0; - if (s<0) { /* wir waren Kapitän, neuen suchen */ - for (t=units; t; t=t->next) - if (t->ship==-s) /* eine Unit auf dem selben Schiff */ - T=t; /* in ECheck sind die Units down->top, darum */ - if (T) /* die letzte der Liste==erste Unit im Programm */ - T->ship=s; - } -} - - -void -checkenter(void) { - int i,n; - unit *u; - - scat(keywords[K_ENTER]); - i=findparam(getstr()); - - switch (i) { - case -1: - anerror("Objekt nicht erkannt"); - return; - case P_GEBAEUDE: - case P_CASTLE: - case P_SHIP: - Scat(parameters[i]); - n=getI(); - if (!n) { - anerror("Nummer des Objektes fehlt"); - return; - } else - bcat(n); - break; - default: - anerror("Objekt kann nicht betreten werden"); - return; - } - check_leave(); - if (i==P_SHIP) { - order_unit->ship=n; - for (u=units; u; u=u->next) /* ggf. Kommando geben */ - if (u->ship==-n) /* da hat einer schon das Kommando */ - return; - order_unit->ship=-n; - } -} - - -int -getaspell(char *s, char spell_typ, unit *u, int turmzauber) { - t_spell *sp; - int p; - - if (!empiria) { - if (*s=='[' || *s=='<') { - anerror("[ ] und < > dürfen nicht mit eingegeben werden!"); - return 0; - } - if (findparam(s) == P_REGION) { - scat(parameters[P_REGION]); - s=getstr(); - if (*s) { - p=atoi(s); - icat(p); - s=getstr(); - if (*s) { - p=atoi(s); - icat(p); - } else { - anerror("Fehler bei Regions-Koordinaten"); - return 0; - } - } else { - anerror("Fehler bei REGION-Parametern"); - return 0; - } - s=getstr(); - } - if (findparam(s) == P_STUFE) { - scat(parameters[P_STUFE]); - s=getstr(); - if (!*s || atoi(s)<1) { - anerror("Fehler bei STUFE-Parameter"); - return 0; - } - p=atoi(s); - icat(p); - s=getstr(); - } - } - sp=findspell(s); - if (!sp) { - if (u) { /* sonst ist das der Test von GIB */ - if (show_warnings > 0) /* nicht bei -w0 */ - anerror("Zauberspruch nicht erkannt"); - if (*s>='0' && *s<='9') - anerror("Parameter STUFE oder REGION fehlt"); - qcat(s); - } - return 0; - } - qcat(sp->name); - if (!(sp->typ & spell_typ)) { - sprintf(warn_buf, "\"%s\" ist %sein Kampfzauber", sp->name, - (sp->typ & SP_ZAUBER) ? "k" : ""); - if (show_warnings > 0) /* nicht bei -w0 */ - anerror(warn_buf); - } else { - if (u && (sp->typ & SP_BATTLE) && (u->spell & sp->typ)) { - sprintf(warn_buf, "Einheit %s hat schon einen ",uid(u)); - switch (sp->typ) { - case SP_POST: - strcat(warn_buf,"Post-"); - break; - case SP_PRAE: - strcat(warn_buf,"Prä-"); - break; - } - strcat(warn_buf,"Kampfzauber gesetzt"); - if (show_warnings > 0) /* nicht bei -w0 */ - awarning(warn_buf,1); - } - if (u) { - p=sp->typ*turmzauber; - u->spell |= p; - u->money-=sp->kosten; - u->reserviert-=sp->kosten; - } - } - do { - s=getstr(); - if (*s) Scat(s); - } while (*s); /* restliche Parameter ohne Check ausgeben */ - return 1; -} - - -void -checkgiving(int key) { - char *s; - int i, n; - - scat(keywords[key]); - getaunit(NECESSARY); - s=getstr(); - if (!getaspell(s, SP_ALL, NULL, 0) - && !isparam(s, P_CONTROL,1) - && !isparam(s, P_HERBS,1) - && !isparam(s, P_SPELLBOOK,1) - && !isparam(s, P_UNIT,1)) { - n=atoi(s); - if (n<1) { - if (!empiria && findparam(s)==P_ALLES) { /* GIB xx ALLES wasauchimmer */ - n=-1; - Scat(parameters[P_ALLES]); - } else { - anerror("Anzahl Gegenstände/Personen/Silber fehlt"); - n=1; - } - } - if (n>0) icat(n); - - s=getstr(); - if (!(*s) && n<0 && !empiria) { /* GIB xx ALLES */ - if (cmd_unit) { - n=order_unit->money-order_unit->reserviert; - cmd_unit->money+=n; - cmd_unit->reserviert+=n; - } - order_unit->money=order_unit->reserviert; - return; - } - - if (!(*s)) { - anerror("Was übergeben?"); - return; - } - i=findparam(s); - switch (i) { - case P_PERSON: - Scat(parameters[i]); - if (n<0) n=order_unit->people; - if (cmd_unit) - cmd_unit->people+=n; - order_unit->people-=n; - if (order_unit->people<0 && no_comment<1 && !does_default) { - sprintf(warn_buf,"Einheit %s hat evtl. zu wenig Personen", uid(order_unit)); - awarning(warn_buf,4); - } - break; - - case P_SILVER: - Scat(parameters[i]); - if (n<0) n=order_unit->money-order_unit->reserviert; - if (cmd_unit) { - cmd_unit->money+=n; - cmd_unit->reserviert+=n; - } - order_unit->money-=n; - if (order_unit->money<0 && no_comment<1 && !does_default) { - sprintf(warn_buf,"Einheit %s hat evtl. zu wenig Silber", - uid(order_unit)); - awarning(warn_buf,4); - } - break; - - default: - i=finditem(s); - if (i < 0) { - i=findherb(s); - if (i < 0) { - i=findpotion(s); - if (i >= 0) { - if (piping) { - strcpy(warn_buf,potionnames[n!=1][i]); - s=strchr(warn_buf, ' '); - if (s) *s=0; - Scat(warn_buf); - } else { - qcat(potionnames[n!=1][i]); - } - } else { - awarning("Objekt nicht erkannt",1); - } - } else { - if (piping) { - strcpy(warn_buf,herbdata[n!=1][i]); - s=strchr(warn_buf, ' '); - if (s) *s=0; - Scat(warn_buf); - } else { - qcat(herbdata[n!=1][i]); - } - } - } else { - if (piping) { - strcpy(warn_buf,ItemName(i,n!=1)); - s=strchr(warn_buf, ' '); - if (s) *s=0; - Scat(warn_buf); - } else { - qcat(ItemName(i,n!=1)); - } - } - break; - } - } else if (findparam(s)==P_CONTROL) { - if (order_unit->ship && !does_default) { - if (order_unit->ship>0) { - sprintf(warn_buf,"Einheit %s hat evtl. nicht das Kommando" - " über Schiff %d",uid(order_unit),order_unit->ship); - awarning(warn_buf,4); - } else if (cmd_unit) { - if (cmd_unit->ship!=0 && abs(cmd_unit->ship) != -order_unit->ship) { - sprintf(warn_buf,"Einheit %s ist evtl. nicht auf Schiff %d sondern" - " auf Schiff %d", uid(cmd_unit), -order_unit->ship, abs(cmd_unit->ship)); - awarning(warn_buf,4); - } - cmd_unit->ship=order_unit->ship; - } - order_unit->ship=-order_unit->ship; - } else if (order_unit->unterhalt) { - if (cmd_unit) - cmd_unit->unterhalt=order_unit->unterhalt; - order_unit->unterhalt=0; - } - } -} - - -void getluxuries(int cmd) { - char *s; - int n, i; - - s=getstr(); - - n=atoi(s); - if (n<1) { - if (!empiria && findparam(s)==P_ALLES) { - if (cmd==K_BUY) { - anerror("KAUFE geht nicht mit ALLES"); - return; - } else - scat(" ALLE"); - } else { - anerror("Anzahl Luxusgüter fehlt"); - } - n=1; - } - - icat(n); - s=getstr(); - i=finditem(s); - - if (!isluxury(i)) - anerror("Kein Luxusgut"); - else { - Scat(ItemName(i,n!=1)); - if (cmd==K_BUY) { /* Silber abziehen; nur Grundpreis! */ - switch (i) { - case I_BALM: - i=4; break; - case I_SPICES: - i=5; break; - case I_JEWELERY: - i=7; break; - case I_MYRRH: - i=5; break; - case I_OIL: - i=3; break; - case I_SILK: - i=6; break; - case I_INCENSE: - i=4; break; - } - order_unit->money-=i*n; - order_unit->reserviert-=i*n; - } - } -} - - -void -checkmake(void) { - int i, j=0, k=0; - char *s; - - scat(keywords[K_MAKE]); - s=getstr(); - - if (s[0]>='0' && s[0]<='9') { /* MACHE anzahl "Gegenstand" */ - j=atoi(s); - if (j==0) - awarning("Anzahl 0 macht keinen Sinn",2); - s=getstr(); - } - - i=findparam(s); - - switch (i) { - case P_HERBS: - if (j) { - if (empiria) - anerror("Anzahl hier nicht möglich"); - else - icat(j); - } - scat(" Kräuter"); - long_order(); - return; - case P_TEMP: - if (j) - anerror("Anzahl hier nicht möglich"); - next_indent=INDENT_NEW_ORDERS; - scat(" TEMP"); - j=getb(); - if (!j) - anerror("Keine TEMP-Nummer"); - else { - unit *u; - bcat(j); - if (!empiria) { - s=getstr(); - if (*s) qcat(s); - } - from_temp_unit_no=j; - u=newunit(j,42); - if (u->ship==0) - u->ship=abs(order_unit->ship); - orders_for_temp_unit(u); - } - return; - - case P_SHIP: - if (j>0) icat(j); - k=getI(); - Scat(parameters[i]); - if (k) bcat(k); - long_order(); - return; - - case P_ROAD: - if (j>0) icat(j); - Scat(parameters[i]); - k=getdirection(); - if (k<0) - anerror("MACHE STRASSE "); - else - Scat(directions[k]); - long_order(); - return; - } - - i=findshiptype(s); - if (i != -1) { - qcat(shiptypes[i]); - long_order(); - getI(); - return; - } - - i=finditem(s); - if (!isluxury (i)) { - if (j) - icat(j); - if (piping) { - strcpy(warn_buf,ItemName(i,1)); - s=strchr(warn_buf, ' '); - if (s) *s=0; - Scat(warn_buf); - } else { - qcat(ItemName(i,1)); - } - long_order(); - return; - } - - i=findpotion(s); - if (i != -1) { - if (j) - awarning("Anzahl hier nicht möglich",2); - if (piping) { - strcpy(warn_buf,potionnames[1][i]); - s=strchr(warn_buf, ' '); - if (s) *s=0; - Scat(warn_buf); - } else { - qcat(potionnames[1][i]); - } - long_order(); - return; - } - - i=findbuildingtype(s); - if (i != -1) { - if (j) icat(j); - qcat(buildingtypes[i]); - long_order(); - k=getI(); - if (k) bcat(k); - return; - } - - /* Man kann MACHE ohne Parameter verwenden, wenn man in einer Burg oder - einem Schiff ist. Ist aber trotzdem eine Warnung wert. */ - if (s[0]) - anerror("Sowas kann man nicht machen"); - else - awarning("Einheit muß in einer Burg, in einem Gebäude" - " oder auf einem Schiff sein",4); - long_order(); - /* es kam ja eine Meldung - evtl. kennt ECheck das nur nicht? */ -} - - -void -checkdirections(int key) { - int i, count=0, x, y, sx, sy, rx, ry; - - rx=sx=x=Rx; ry=sy=y=Ry; - scat(keywords[key]); - - do { - i=getdirection(); - if (i<=-1 || (empiria && i >= D_PAUSE) || (!empiria && i < D_EAST)) { - if (i==-2) break; - anerror("Richtung nicht erkannt"); - } else { - if (key==K_ROUTE && i==D_PAUSE && count==0) - awarning("ROUTE beginnt mit PAUSE",2); - if (key==K_MOVE && i==D_PAUSE) - anerror("NACH geht nicht mit PAUSE"); - else { - Scat(directions[i]); - count++; - if (!noship && order_unit->ship==0 && key!=K_ROUTE && count==4) { - sprintf(warn_buf,"Einheit %s bewegt sich evtl. zu weit", - uid(order_unit)); - awarning(warn_buf,4); - } - switch (i) { - case D_NORTHEAST: - y++; - break; - case D_NORTHWEST: - y++; x--; - break; - case D_SOUTHEAST: - y--; x++; - break; - case D_SOUTHWEST: - y--; - break; - case D_EAST: - x++; - break; - case D_WEST: - x--; - break; - case D_PAUSE: - if (rx==sx && ry==sy) { - rx=x; ry=y; /* ROUTE: ersten Abschnitt merken für Silber verschieben */ - } - break; - } - } - } - } while (i >= 0); - - if (!count) - anerror("Richtung nicht erkannt"); - if (key==K_ROUTE && !noroute && (sx!=x || sy!=y)) { - sprintf(warn_buf, "ROUTE ist kein Kreis; (%d,%d) -> (%d,%d)",sx,sy,x,y); - awarning(warn_buf,4); - } - if (!does_default) { - if (order_unit->hasmoved) { - sprintf(warn_buf, "Einheit %s hat sich schon bewegt", uid(order_unit)); - anerror(warn_buf); - return; - } - order_unit->hasmoved=2; /* 2: selber bewegt */ - if (key==K_ROUTE) { - order_unit->newx=rx; - order_unit->newy=ry; - } else { - order_unit->newx=x; - order_unit->newy=y; - } - } -} - - -void -check_sabotage(void) { - if (getparam() != P_SHIP) { - anerror("Bislang gibt es nur SABOTIERE SCHIFF"); - return; - } - Scat(parameters[P_SHIP]); - return; -} - - -void -checkmail(void) { - char *s; - - scat(keywords[K_MAIL]); - s=getstr(); - if (strcasecmp(s, "an")==0) - s=getstr(); - - switch (findparam(s)) { - case P_FACTION: - Scat(parameters[P_FACTION]); - break; - - case P_REGION: - Scat(parameters[P_REGION]); - break; - - /* implizit case P_UNIT: */ - default: - Scat(parameters[P_UNIT]); - bcat(getb()); - return; - } - s=getstr(); - checkstring(s, 0, NECESSARY); -} - - -void -reserve(void) { - char *s; - int i,n; - - scat(keywords[K_RESERVE]); - - if (from_temp_unit_no) { - anerror("TEMP-Einheiten können nichts reservieren! Bitte GIB benutzen"); - return; - } - n=geti(); - if (n==0) { - anerror("RESERVIERE 0 xxx macht keinen Sinn"); - return; - } - icat(n); - s=getstr(); - - if (!(*s)) { - anerror("RESERVIERE was?"); - return; - } - i=finditem(s); - if (i>=0) { - Scat(ItemName(i,n!=1)); - return; - } - - if (findparam(s)==P_SILVER) { - Scat("Silber"); - order_unit->region->reserviert+=n; - order_unit->reserviert+=n; - return; - } - - i=findpotion(s); - if (i>=0) { - Scat(potionnames[n!=1][i]); - return; - } - - i=findherb(s); - if (i>=0) { - Scat(herbdata[n=!1][i]); - return; - } -} - - -void -check_ally(void) { - int i; - char *s; - - scat(keywords[K_ALLY]); - getafaction(getstr()); - s=getstr(); - - i=findparam(s); - switch (i) { - case P_GIVE: - case P_KAEMPFE: - case P_SILVER: - case P_OBSERVE: - case P_GUARD: - case P_ALLES: - case P_NOT: - Scat(parameters[i]); - break; - default: - anerror("Helfe-Status falsch"); - return; - } - - s=getstr(); - if (findparam(s)==P_NOT) { - Scat(parameters[P_NOT]); - } -} - - -int -studycost(t_skills *talent) { - if (does_default) - return 0; - if (talent->kosten<0) { - int i; - /* Lerne Magie [gebiet] 2000 -> Lernkosten=2000 Silber */ - char *s=getstr(); - i=findstr(magiegebiet,s,5); - if (i>=0) { - fprintf(ERR,"Magiegebiet '%s' gewählt",magiegebiet[i]); - i=geti(); - } else - i=atoi(s); - if (i<100) { - i=200; - awarning("Lernkosten mit 200 Silber angenommen",2); - } - return i; - } - return talent->kosten; -} - - -void -check_meinung(void) { - int i; - - scat(keywords[K_MEINUNG]); - i=geti(); - if (i <= 0) - anerror("Nummer der Umfrage muß größer 0 sein"); - icat(i); - i=geti(); - if (i <= 0) - anerror("Nummer der Meinung muß größer 0 sein"); - icat(i); - checkstring(getstr(),DISPLAYSIZE,POSSIBLE); -} - - -void -check_comment(void) { - char *s; - int m; - - s=getstr(); - if (strncasecmp(s,"ECHECK",6)) - return; - s=getstr(); - - if (strncasecmp(s,"VERSION",7)==0) { - fprintf(ERR, "%s\n", order_buf); - return; - } - if (strncasecmp(s,"NOWARN", 6)==0) { /* Warnungen für nächste Zeile aus */ - warn_off=2; - return; - } - if (strncasecmp(s,"LOHN",4)==0) { /* LOHN für Arbeit */ - m=geti(); - lohn=(char)max(10,m); - return; - } - if (strncasecmp(s,"ROUT",4)==0) { /* ROUTe */ - noroute=(char)(1-noroute); - return; - } - if (strncasecmp(s,"KOMM",4)==0) { /* KOMMando */ - m=geti(); - if (!m) { - m=order_unit->ship; - if (!m) - m=rand(); - } - order_unit->ship=-abs(m); - return; - } - if (strncasecmp(s,"EMPTY",5)==0) { - order_unit->money=0; - order_unit->reserviert=0; - return; - } - if (strncasecmp(s,"NACH",4)==0) { - order_unit->hasmoved=1; - order_unit->newx=geti(); - order_unit->newy=geti(); - return; - } - m=atoi(s); - if (m) { - if (order_unit) { - order_unit->money+=m; - order_unit->reserviert+=m; - } - return; - } -} - - -void -check_money(bool do_move) { /* do_move=true: vor der Bewegung, anschließend */ - unit *u, *t; /* Bewegung ausführen, damit das Silber bewegt wird */ - t_region *r; - int i,x,y,um; - - u=find_unit(-1,0); - if (u) { /* Unit -1 leeren */ - u->people=u->money=u->unterhalt=u->reserviert=0; - u->lives=-1; - } - - if (do_move) { - for (u=units; u; u=u->next) { /* Check TEMP und leere Einheiten */ - if (u->lives<1) /* fremde Einheit oder Untot/Illusion */ - continue; /* auslassen, weil deren Geldbedarf nicht zählt */ - - if (u->temp && abs(u->temp)!=42) { - sprintf(warn_buf, "Einheit TEMP %s wurde nicht mit " - "MACHE TEMP generiert", itob(u->no)); - Error(warn_buf, u->line_no, u->order); - } - if (u->people<0) { - sprintf(warn_buf,"Einheit %s hat %d Personen!", uid(u), u->people); - warn(warn_buf, u->line_no, 3); - } - - if (u->people==0 && ((!nolost && !u->temp && u->money>0) || u->temp)) { - if (u->temp) { - if (u->money>0) - sprintf(warn_buf,"Einheit TEMP %s hat nicht rekrutiert und keine Personen" - " bekommen! Sie verliert Silber und evtl. Gegenstände", itob(u->no)); - else - sprintf(warn_buf,"Einheit TEMP %s hat nicht rekrutiert und keine Personen" - " bekommen", itob(u->no)); - warn(warn_buf,u->line_no,2); - } else if (no_comment<=0) { - sprintf(warn_buf,"Einheit %s verliert Silber und evtl. Gegenstände", uid(u)); - warn(warn_buf,u->line_no,3); - } - } - } - } - - if (Regionen && no_comment<1) { - if (silberpool && do_move) { - for (u=units; u; u=u->next) { - u->region->geld+=u->money; - /* Reservierung < Silber der Unit? Silber von anderen Units holen */ - if (u->reserviert > u->money) { - i=u->reserviert-u->money; - for (t=units; t && i>0; t=t->next) { - if (t->region!=u->region || t==u) continue; - um=min(i,t->money-t->reserviert); - if (um>0) { - u->money+=um; - i-=um; - t->money-=um; - } - } - } - } - } - - if (do_move) - for (r=Regionen; r; r=r->next) { - if (r->reserviert>0 && r->reserviert>r->geld) { /* nur explizit mit RESERVIERE */ - sprintf(warn_buf, "In %s (%d,%d) wurde mehr Silber reserviert (%d)" - " als vorhanden (%d).", r->name, r->x, r->y, r->reserviert, r->geld); - warn(warn_buf, r->line_no, 3); - } - } - - for (u=units; u; u=u->next) { /* fehlendes Silber aus dem Silberpool nehmen */ - if (do_move && u->unterhalt) { - u->money-=u->unterhalt; - u->reserviert-=u->unterhalt; - } - if (u->money<0 && silberpool) { - for (t=units; t && u->money<0; t=t->next) { - if (t->region!=u->region || t==u) continue; - um=min(-u->money,t->money-t->reserviert); - if (um>0) { - u->money+=um; - u->reserviert+=um; /* das so erworbene Silber muß auch reserviert sein */ - t->money-=um; - } - } - } - if (u->money<0) { - sprintf(warn_buf,"Einheit %s hat %s%d Silber!", - uid(u),do_move?"vor den Einnahmen ":"", u->money); - warn(warn_buf, u->line_no, 3); - if (u->unterhalt) { - if (do_move) - sprintf(warn_buf,"Einheit %s braucht noch %d Silber, " - "um ein Gebäude zu unterhalten.", uid(u), -u->money); - else - sprintf(warn_buf,"Einheit %s kann ein Gebäude nicht erhalten," - " es fehlen noch %d Silber!", uid(u), -u->money); - warn(warn_buf, u->line_no, 1); - } - } - } - } - - if (Regionen) - for (r=Regionen; r; r=r->next) - r->geld=0; /* gleich wird Geld bei den Einheiten bewegt, darum den Pool - * leeren und nach der Bewegung nochmal füllen */ - if (!do_move) /* Ebenso wird es in check_living nochmal neu eingezahlt */ - return; - - if (!Regionen) /* ohne Regionen Bewegung nicht sinnvoll */ - return; - - for (u=units; u; u=u->next) { /* Bewegen vormerken */ - if (u->lives<1) /* fremde Einheit oder Untot/Illusion */ - continue; - if (u->hasmoved>1) { - if (!noship && u->ship>0) { - sprintf(warn_buf,"Einheit %s will Schiff %d bewegen und" - " hat evtl. kein Kommando", uid(u), u->ship); - warn(warn_buf,u->line_no,4); - } - i=-u->ship; - if (i>0) { /* wir sind Kapitän; alle Einheiten auf dem Schiff auch bewegen */ - x=u->newx; y=u->newy; - for (t=units; t; t=t->next) { - if (t->ship==i) { - if (t->hasmoved>1) { /* schon bewegt! */ - sprintf(warn_buf, "Einheit %s auf Schiff %d hat sich schon bewegt", - uid(t),i); - Error(warn_buf,t->line_no,t->long_order); - } - t->hasmoved=1; - t->newx=x; - t->newy=y; - } - } - } - } - } - - for (u=units; u; u=u->next) { /* Bewegen ausführen */ - if (u->lives<1) /* fremde Einheit oder Untot/Illusion */ - continue; - - if (u->transport && u->drive && u->drive != u->transport) { - sprintf(checked_buf,"Einheit %s wird von Einheit %s transportiert, " - "fährt aber mit ", uid(u), Uid(u->transport)); - scat(Uid(u->drive)); - warning(checked_buf,u->line_no,u->long_order,1); - continue; - } - if (u->drive) { /* FAHRE; in u->transport steht die transportierende Einheit */ - if (u->hasmoved) { - sprintf(warn_buf,"Einheit %s hat sich bereits bewegt", uid(u)); - Error(warn_buf, u->line_no, u->long_order); - } - if (u->transport==0) { - t=find_unit(u->drive,0); - if (!t) t=find_unit(u->drive,1); - if (t && t->lives) { - sprintf(warn_buf,"Einheit %s fährt mit Einheit %s, " - "diese transportiert aber nicht",uid(u),Uid(u->drive)); - Error(warn_buf,u->line_no,u->long_order); - } else { /* unbekannte Einheit -> unbekanntes Ziel */ - u->hasmoved=1; - u->newx=-9999; - u->newy=-9999; - } - } else { - t=find_unit(u->transport,0); - if (!t) t=find_unit(u->transport,1); - /* muß es geben, hat ja schließlich u->transport gesetzt */ - u->hasmoved=1; - u->newx=t->newx; - u->newy=t->newy; - } - } else if (u->transport) { - t=find_unit(u->transport,0); - if (!t) t=find_unit(u->transport,1); - if (t && t->lives && t->drive != u->no) { - sprintf(warn_buf, "Einheit %s transportiert Einheit %s, " - "diese fährt aber nicht",Uid(u->transport),uid(u)); - Error(warn_buf,u->line_no,u->long_order); - } - } - - if (u->hasmoved) { /* NACH, gefahren oder auf Schiff */ - addregion(u->region->x, u->region->y, -(u->people)); - u->region=addregion(u->newx, u->newy, u->people); - if (u->region->line_no==line_no) /* line_no => NÄCHSTER */ - u->region->line_no=u->line_no; - } - } -} - - -void -check_living(void) { - unit *u; - t_region *r; - - /* Für die Nahrungsversorgung ist auch ohne Silberpool alles Silber der - * Region zuständig */ - - for (u=units; u; u=u->next) { /* Silber der Einheiten in den Silberpool "einzahlen" */ - if (u->lives<1) /* jetzt nach der Umverteilung von Silber */ - continue; - u->region->geld+=u->money; /* jetzt wird reserviertes Silber nicht festgehalten */ - } - - for (r=Regionen; r; r=r->next) { - for (u=units; u; u=u->next) - if (u->region==r && u->lives>0) - r->geld-=u->people*10; - if (r->geld<0) { - sprintf(warn_buf, "Das Silber in %s (%d,%d) reicht evtl. nicht" - " zum Leben; es fehlen %d Silber.", r->name, r->x, r->y, -(r->geld)); - warn(warn_buf, r->line_no, 4); - } - } -} - - -void -remove_temp(void) { - /* Markiert das TEMP-Flag von Einheiten der letzten Region - * -> falsche TEMP-Nummern bei GIB oder so fallen auf */ - unit *u; - - for (u=units; u; u=u->next) - u->temp=-u->temp; -} - - -void -check_teachings(void) { - teach *t; - unit *u; - int n; - - for (t=teachings; t; t=t->next) { - t->student->schueler=t->student->people; - if (t->teacher) { - t->teacher->lehrer=t->teacher->people*10; - if (t->teacher->lehrer==0) { - sprintf(warn_buf, "Einheit %s hat 0 Personen und lehrt Einheit ", - uid(t->teacher)); - strcat(warn_buf, uid(t->student)); - strcat(warn_buf, "."); - warn(warn_buf, t->teacher->line_no, 4); - } - if (t->student->schueler==0 && t->student->lives>0) { - sprintf(warn_buf, "Einheit %s hat 0 Personen und wird von Einheit ", - uid(t->student)); - strcat(warn_buf, uid(t->teacher)); - strcat(warn_buf, " gelehrt."); - warn(warn_buf, t->student->line_no, 4); - } - } - } - - for (t=teachings; t; t=t->next) { - if (t->teacher==NULL || t->student->lives<1) { /* lernt ohne Lehrer bzw. */ - t->student->schueler=0; /* keine eigene Einheit */ - continue; - } - - if (!t->student->lernt) { - if (t->student->temp ) /* unbekannte TEMP-Einheit, wird eh schon angemeckert */ - continue; - sprintf(warn_buf,"Einheit %s wird von Einheit ", uid(t->student)); - strcat(warn_buf,uid(t->teacher)); /* uid() hat ein static char*, das - im sprintf() dann zweimal das selbe ergibt */ - strcat(warn_buf," gelehrt, lernt aber nicht."); - warn(warn_buf, t->student->line_no, 2); - t->student->schueler=0; - continue; - } - - n=min(t->teacher->lehrer, t->student->schueler); - t->teacher->lehrer-=n; - t->student->schueler-=n; - } - - for (u=units; u; u=u->next) { - if (u->lives<1) continue; - if (u->lehrer>0) { - sprintf(warn_buf,"Einheit %s kann noch %d Schüler lehren.", - uid(u), u->lehrer); - warn(warn_buf, u->line_no, 5); - } - if (u->schueler>0) { - sprintf(warn_buf,"Einheit %s kann noch %d Lehrer gebrauchen.", - uid(u), (u->schueler+9)/10); - warn(warn_buf, u->line_no, 5); - } - } -} - - -void -checkanorder(char *Orders) { - int i, x; - char *s; - t_skills *sk; - unit *u; - - s=strchr(Orders,';'); - if (s) - *s=0; /* Ggf. Kommentar kappen */ - - if (Orders[0]==0) - return; /* Dies war eine Kommentarzeile */ - - strcpy(order_buf, Orders); - - i=igetkeyword(order_buf); - this_command=i; - switch (i) { - case -1: - anerror("Befehl nicht erkannt"); - return; - - case K_ADDRESS: - if (empiria) - checkaddr(); - else - anerror("Statt ADRESSE bitte EMAIL und BANNER benutzen"); - break; - - case K_NUMMER: - if (empiria) - anerror("Befehl nicht erkannt"); - else { - scat(keywords[K_NUMMER]); - i=getparam(); - if (!(i==P_UNIT || i==P_SHIP || i==P_GEBAEUDE || i==P_CASTLE - || i==P_FACTION)) { - anerror("NUMMER SCHIFF, NUMMER BURG, NUMMER PARTEI oder NUMMER EINHEIT"); - break; - } - Scat(parameters[i]); - s=getstr(); - if (strncasecmp(s,"TEMP",strlen(s))==0) - anerror("Nummer nicht erlaubt"); - else - Scat(s); - } - break; - - case K_MEINUNG: - if (empiria) - anerror("Befehl nicht erkannt"); - else - check_meinung(); - break; - - case K_BANNER: - if (empiria) - anerror("Befehl nicht erkannt"); - else { - scat(keywords[K_BANNER]); - checkstring(getstr(),DISPLAYSIZE,NECESSARY); - } - break; - - case K_EMAIL: - if (empiria) - anerror("Befehl nicht erkannt"); - else - checkemail(); - break; - - case K_URSPRUNG: - if (empiria) - anerror("Befehl nicht erkannt"); - else { - scat(keywords[K_URSPRUNG]); - s=getstr(); - if (*s) { - x=atoi(s); - icat(x); - s=getstr(); - if (*s) { - x=atoi(s); - icat(x); - } else - anerror("Beide Koordinaten müssen angegeben werden"); - } - } - break; - - case K_USE: - scat(keywords[K_USE]); - s=getstr(); - i=findpotion(s); - if (i<0) - anerror("Unbekannter Trank"); - else { - Scat(potionnames[1][i]); - } - break; - - case K_MAIL: - checkmail(); - break; - - case K_WORK: - scat(keywords[K_WORK]); - long_order(); - if (!does_default) - order_unit->money+=lohn*order_unit->people; - break; - - case K_ATTACK: - scat(keywords[K_ATTACK]); - if (getaunit(NECESSARY)==3) - anerror("TEMP-Einheiten kann man nicht ATTACKIEREn"); - if (!attack_warning) { - /* damit längere Angriffe nicht in Warnungs-Tiraden ausarten */ - awarning("Längere Kämpfe schließen den langen Befehl aus",5); - attack_warning=1; - } - if (getaunit(42)==42) { - strcpy(warn_buf,"Pro Einheit muß ein ATTACKIERE-Befehl gegeben werden"); - anerror(warn_buf); - } - break; - - case K_BESIEGE: - scat(keywords[K_BESIEGE]); - i=getI(); - if (!i) - anerror("Nummer der Burg fehlt"); - else - bcat(i); - long_order(); - break; - - case K_NAME: - checknaming(); - break; - - case K_ZUECHTE: - scat(keywords[K_ZUECHTE]); - if (!empiria) { - i=getparam(); - if (i==P_HERBS || i==P_HORSE) - scat(parameters[i]); - else - anerror("ZÜCHTE PFERDE oder ZÜCHTE KRÄUTER"); - } - long_order(); - break; - - case K_STEAL: - scat(keywords[K_STEAL]); - getaunit(NECESSARY); - long_order(); - break; - - case K_DISPLAY: - checkdisplay(); - break; - - case K_GUARD: - scat(keywords[K_GUARD]); - s=getstr(); - if (findparam(s)==P_NOT) { - Scat(parameters[P_NOT]); - } - break; - - case K_END: - if (from_temp_unit_no==0) - awarning("ENDE ohne MACHE TEMP",2); - scat(keywords[K_END]); - indent=next_indent=INDENT_ORDERS; - end_unit_orders(); - from_temp_unit_no=current_temp_no=0; - if (mother_unit) { - order_unit=mother_unit; - mother_unit=NULL; - } - break; - - case K_FIND: - if (!empiria) - awarning("FINDE wurde gegen OPTION ADRESSEN ersetzt",1); - else { - scat(keywords[K_FIND]); - s=getstr(); - if (findparam(s)==P_ALLES) { - Scat(parameters[P_ALLES]); - } else - getafaction(s); - } - break; - - case K_RESEARCH: - scat(keywords[K_RESEARCH]); - i=getparam(); - if (i==P_HERBS) { - scat(parameters[P_HERBS]); /* momentan nur FORSCHE KRÄUTER */ - } else - anerror("Es gibt nur FORSCHE KRÄUTER"); - long_order(); - break; - - case K_SETSTEALTH: - scat(keywords[K_SETSTEALTH]); - s=getstr(); - i=findstr(Rassen, s, R_MAX); - if (i >= 0) { - Scat(Rassen[i]); - break; - } - i=findparam(s); - if (i==P_FACTION) { - Scat(parameters[i]); - s=getstr(); - if (*s) { - if (findparam(s)!=P_NOT) - anerror("Falscher Parameter"); - else - Scat(parameters[P_NOT]); - } - break; - } - if (isdigit(s[0])) { - i=atoip(s); - icat(i); - break; - } - awarning("TARNE ohne Parameter",5); - break; - - case K_GIVE: - case K_LIEFERE: - if (this_command==K_LIEFERE && !empiria) - { - awarning("LIEFERE ist obsolet, bitte @GIB benutzen",3); - i=K_GIVE; - at_cmd=1; - } - checkgiving(i); - break; - - case K_BIETE: - if (empiria) { - scat(keywords[K_BIETE]); - if (getaunit(NECESSARY) > 1 || current_temp_no) { - sprintf(warn_buf, - "%s geht nur mit normalen Einheiten", keywords[K_BIETE]); - anerror(warn_buf); - break; - } - i=geti(); - if (i<1) - anerror("Geldgebot fehlt"); - icat(i); - long_order(); - } else - anerror("Befehl nicht erkannt"); - break; - - case K_ALLY: - check_ally(); - break; - - case K_STATUS: - scat(keywords[K_STATUS]); - s=getstr(); - i=findparam(s); - switch (i) { - case P_NOT: - case P_BEHIND: - case P_FLEE: - case P_VORNE: - Scat(parameters[i]); - break; - default: - if (*s) { - if (findkeyword(s)==K_ALLY) { - Scat(keywords[K_ALLY]); - s=getstr(); - if (findparam(s)==P_NOT) { - Scat(parameters[P_NOT]); - break; - } - } - Scat(s); - anerror("Falscher Kampfstatus"); - } else - Scat(parameters[P_VORNE]); - } - break; - - case K_COMBAT: - scat(keywords[K_COMBAT]); - s=getstr(); - getaspell(s, SP_KAMPF | SP_POST | SP_PRAE, order_unit, 1); - break; - - case K_BUY: - case K_SELL: - scat(keywords[i]); - getluxuries(i); - long_order(); - break; - - case K_CONTACT: - scat(keywords[K_CONTACT]); - getaunit(NECESSARY); - break; - - case K_SPY: - scat(keywords[K_SPY]); - i=getb(); - if (!i) - anerror("Einheit fehlt"); - else - bcat(i); - long_order(); - break; - - case K_TEACH: - scat(keywords[K_TEACH]); - if (!getmoreunits(false)) - anerror("Wen lehren?"); - long_order(); - break; - - case K_VERGESSE: - scat(keywords[K_VERGESSE]); - sk=getskill(); - if (!sk) - anerror("Talent nicht erkannt"); - else { - Scat(sk->name); - } - break; - - case K_STUDY: - scat(keywords[K_STUDY]); - sk=getskill(); - if (!sk) - anerror("Talent nicht erkannt"); - else { - Scat(sk->name); - if (!empiria && strcasecmp(sk->name,"Magie")==0) - if (order_unit->people>1) - anerror("Magiereinheiten dürfen nur eine Person haben"); - } - if (sk && !does_default) { - x=studycost(sk)*order_unit->people; - if (x) { - order_unit->money-=x; - order_unit->reserviert-=x; - } - addteach(NULL, order_unit); - order_unit->lernt=1; - } - long_order(); - break; - - case K_MAKE: - checkmake(); - break; - - case K_SABOTIERE: - scat(keywords[K_SABOTIERE]); - check_sabotage(); - long_order(); - break; - - case K_PASSWORD: - scat(keywords[K_PASSWORD]); - s=getstr(); - if (!s[0]) - awarning("Passwort gelöscht",0); - else - checkstring(s, NAMESIZE, POSSIBLE); - break; - - case K_RECRUIT: - scat(keywords[K_RECRUIT]); - i=geti(); - if (i) { - icat(i); - if (from_temp_unit_no) - u=newunit(from_temp_unit_no, 1); - else - u=order_unit; - if (does_default) - break; - u->money-=i*rec_cost; - u->reserviert-=i*rec_cost; - u->people+=i; - addregion(Rx, Ry, i); - } else - anerror("Anzahl Rekruten fehlt"); - break; - - case K_QUIT: - scat(keywords[K_QUIT]); - s=getstr(); - if (!s[0]) - anerror("Kein Passwort angeben"); - else - checkstring(s, NAMESIZE, POSSIBLE); - awarning("Achtung! STIRB gegeben! Die Partei wird aufgelöst!",0); - break; - - case K_TAX: - scat(keywords[K_TAX]); - i=(geti()/10)*10; - /* Steuern werden in Kontingenten von 10 Silber eingetrieben. */ - if (i) - icat(i); - else - i=20*order_unit->people; - while (*igetstr(NULL)); - long_order(); - if (!does_default) - order_unit->money+=i; - break; - - case K_ENTERTAIN: - scat(keywords[K_ENTERTAIN]); - i=geti(); - if (!does_default) { - if (!i) - i=20*order_unit->people; - order_unit->money+=i; - } - long_order(); - break; - - case K_ENTER: - checkenter(); - break; - - case K_LEAVE: - scat(keywords[K_LEAVE]); - check_leave(); - break; - - case K_ROUTE: - if (empiria) { - anerror("Befehl nicht erkannt"); - break; - } - case K_MOVE: - checkdirections(i); - long_order(); - break; - - case K_FOLLOW: - scat(keywords[K_FOLLOW]); - if (empiria) { - getaunit(NECESSARY); - long_order(); - } else { - s=getstr(); - if (s) { - i=findparam(s); - if (i==P_UNIT) { - Scat(parameters[i]); - getaunit(NECESSARY); - } else if (i==P_SHIP) { - Scat(parameters[i]); - s=getstr(); - x=atoi(s); - if (x<0 || x>9999) { - sprintf(warn_buf,"Schiffsnr. %s ungültig",s); - anerror(warn_buf); - } else - Scat(s); - } else - anerror("FOLGE EINHEIT xx, FOLGE SCHIFF xx oder FOLGE"); - } - } - break; - - case K_REPORT: - if (empiria) - anerror("Befehl nicht erkannt"); - else { - scat(keywords[K_REPORT]); - s=getstr(); - i=findreport(s); - if (i==-1) { - if (strncasecmp(s, "ZEIGEN", strlen(s))) - anerror("Unbekannte Report-Option"); - else - scat(" ZEIGEN"); - break; - } - Scat(reports[i]); - s=getstr(); - i=findstr(message_levels, s, ML_MAX); - if (i==-1) { - anerror("falscher Ausgabe-Level"); - break; - } - Scat(message_levels[i]); - } - break; - - case K_SEND: - if (!empiria) - awarning("SENDE wurde in OPTION umbenannt",4); - case K_OPTION: - if (i==K_OPTION && empiria) { - anerror("Befehl nicht erkannt"); - break; - } else { - if (empiria) - scat(keywords[K_SEND]); - else - scat(keywords[K_OPTION]); - } - i=getoption(); - if (i<0) { - anerror("Option unbekannt"); - break; - } - Scat(options[i]); - i=getparam(); - if (i==P_WARN) { - Scat(parameters[i]); - i=getparam(); - } - if (i==P_NOT) { - Scat(parameters[i]); - } - break; - - case K_CAST: - scat(keywords[K_CAST]); - s=getstr(); - getaspell(s, SP_ZAUBER, order_unit, 1); - long_order(); - break; - - case K_TURMZAUBER: - if (empiria) { - scat(keywords[K_TURMZAUBER]); - s=getstr(); - getaspell(s, SP_ZAUBER, order_unit, 256); - } else - anerror("Befehl nicht erkannt"); - break; - - case K_RESHOW: - scat(keywords[K_RESHOW]); - s=getstr(); - Scat(s); - break; - - case K_DESTROY: - scat(keywords[K_DESTROY]); - break; - - case K_DRIVE: - scat(keywords[K_DRIVE]); - if (getaunit(NECESSARY)==2) - anerror("Einheit 0 bzw. Bauern geht hier nicht"); - else if (!does_default) - order_unit->drive=this_unit; - long_order(); - break; - - case K_TRANSPORT: - scat(keywords[K_TRANSPORT]); - getaunit(NECESSARY); - if (!does_default) { - if (cmd_unit) cmd_unit->transport=order_unit->no; - else awarning("Kann zu transportierende Einheit nicht ermitteln",3); - } - if (getaunit(42)==42) - anerror("Pro Einheit muß ein TRANSPORTIERE-Befehl gegeben werden"); - break; - - case K_PIRATERIE: - if (empiria) - anerror("Befehl nicht erkannt"); - else - getmoreunits(true); - break; - - case K_MAGIEGEBIET: - if (empiria) - anerror("Befehl nicht erkannt"); - else { - s=getstr(); - i=findstr(magiegebiet,s,5); - if (i<0) { - sprintf(warn_buf,"Magiegebiet '%s' gibt es nicht",s); - anerror(warn_buf); - } else { - scat(keywords[K_MAGIEGEBIET]); - Scat(magiegebiet[i]); - } - } - break; - - case K_DEFAULT: - if (empiria) - anerror("Befehl nicht erkannt"); - else { - scat(keywords[K_DEFAULT]); - scat(" \""); - u=newunit(-1,0); - copy_unit(order_unit, u); - if (order_unit->start_of_orders) - free(order_unit->start_of_orders); - if (order_unit->long_order) - free(order_unit->long_order); - if (order_unit->order) - free(order_unit->order); - order_unit->long_order_line=0; - order_unit->start_of_orders_line=0; - order_unit->temp=0; - /* der DEFAULT gilt ja erst nächste Runde! */ - s=getstr(); - does_default=1; - porder(); - checkanorder(s); - does_default=2; - while (getstr()[0]); - copy_unit(u, order_unit); - u->no=-1; - u->long_order_line=0; - u->start_of_orders_line=0; - u->temp=0; - } - break; - - case K_COMMENT: - if (empiria) - anerror("Befehl nicht erkannt"); - else { - check_comment(); - scat(Orders); - } - break; - - case K_RESERVE: - if (empiria) - anerror("Befehl nicht erkannt"); - else - reserve(); - break; - - case K_NEUSTART: - if (empiria) - anerror("Befehl nicht erkannt"); - else { - i=findstr(Rassen, getstr(), R_MAX); - if (i<0) { - anerror("Unbekannte Rasse"); - break; - } else - Scat(Rassen[i]); - s=getstr(); - if (!*s) { - anerror("Passwort fehlt"); - break; - } else - qcat(s); - awarning("NEUSTART befohlen!",0); - } - break; - - case K_GRUPPE: - if (empiria) - anerror("Befehl nicht erkannt"); - else { - s=getstr(); - if (*s) - Scat(s); - } - break; - - case K_SORTIERE: - if (empiria) - anerror("Befehl nicht erkannt"); - else { - s=getstr(); - if (*s) { - if (strncasecmp(s, "VOR", strlen(s))==0 || - strncasecmp(s, "HINTER", strlen(s))==0) { - Scat(s); - i=getaunit(NECESSARY); - if (i==1 || i==3) /* normale oder TEMP-Einheit: ok */ - break; - } - } - anerror("SORTIERE VOR oder HINTER "); - } - break; - - default: - anerror("Befehl nicht erkannt"); - } - if (does_default != 1) { - porder(); - does_default=0; - } -} - - -void -readaunit(void) { - int i; - unit *u; - - i=getb(); - if (i==0) { - anerror("Keine Einheitsnummer"); - get_order(); - return; - } - u=newunit(i, 0); - u->line_no=line_no; - /* Sonst ist die Zeilennummer die Zeile, wo die Einheit zuerst von - * einer anderen Einheit angesprochen wurde... */ - orders_for_unit(i,u); - bcat(i); - - indent=INDENT_UNIT; - next_indent=INDENT_ORDERS; - porder(); - from_temp_unit_no=0; - - for (;;) { - get_order(); - - if (befehle_ende) - return; - - /* Erst wenn wir sicher sind, daß kein Befehl eingegeben wurde, checken - * wir, ob nun eine neue Einheit oder ein neuer Spieler drankommt */ - - if (igetkeyword(order_buf)==-1) { - if (order_buf[0]==';') { - check_comment(); - continue; - } - else switch (igetparam(order_buf)) { - case P_UNIT: - case P_FACTION: - case P_NEXT: - case P_REGION: - if (from_temp_unit_no != 0) { - sprintf(warn_buf,"TEMP-Einheit %s wird nicht durch ENDE abgeschlossen", - itob(from_temp_unit_no)); - awarning(warn_buf, 2); - from_temp_unit_no=0; - } - return; - } - } - if (order_buf[0]) - checkanorder(order_buf); - } -} - - -int -readafaction(void) { - int i; - char *s; - - if (line_start==1) - line_no=1; - i=getI(); - if (i) { - bcat(i); - s=getstr(); - if (s[0]==0) { - anerror("Kein Passwort"); - } else if (strcmp(s, "hier_passwort_eintragen") == 0) { - anerror("Nicht das korrekte Passwort eingesetzt"); - } - qcat(s); - } else - anerror("Keine Parteinummer"); - - indent=next_indent=INDENT_FACTION; - porder(); - return i; -} - - -void -help(const char *s) { - fprintf(ERR, "ECheck (Version "VERSION", "__DATE__ - "), Zug-Checker für Eressea - Freeware!\n\n" - " Benutzung: %s [Optionen] Befehlsdatei\n" -/***** Vorsicht, TABs! Neue Texte mit Tab-Width=8 rein *****/ - " - Verwendet stdin anstelle einer Eingabedatei.\n" - " -b unterdrückt Warnungen und Fehler (brief)\n" - " -q erwartet keine Angaben zu Personen/Silber in [] bei EINHEIT\n" - " -rnnn Legt Rekrutierungskosten auf nnn Silber fest\n" - " -c schreibt die Warnungen und Fehler in einer Compiler-ähnlichen Form\n" - " -e schreibt die geprüfte Datei auf stdout, Fehler nach stderr\n" - " -E schreibt die geprüfte Datei auf stdout, Fehler nach stdout\n" - " -ofile schreibt die geprüfte Datei in die Datei 'file'\n" - " -Ofile schreibt Fehler in die Datei 'file'\n" - " -h zeigt diese kleine Hilfe an\n" - " -s verwendet stderr für Warnungen, Fehler etc., nicht stdout\n" - " -p verkürzt einige Ausgaben für piping\n" - " -l simuliert Silberpool-Funktion (nicht bei Empiria)\n" - " -n zählt NameMe-Kommentare (;;) nicht als Zeile\n" - " -m Empiria-Checking\n" - " -noxxx Keine xxx-Warnungen. xxx kann sein:\n" - " ship Einheit steuert Schiff und hat evtl. kein Kommando\n" - " route kein Check auf zyklisches ROUTE\n" - " lost Einheit verliert Silber und Gegenstände\n" - " -w[n] Warnungen der Stufe n (default: 4=alle Warnungen)\n" - " -x Zeilenzählung ab PARTEI statt Dateianfang\n" - " -Ppfad Pfadangabe für items.txt, talente.txt und zauber.txt\n" - " -vm.l Mainversion.Level - für Test, ob richtige ECheck-Version\n" - , s); -} - - -void -check_options(int argc, char *argv[], char dostop, char command_line) { - int i; - char *x; - - for (i=1; i != argc; i++) { - if (argv[i][0]=='-' -#ifdef WIN32 - || argv[i][0]=='/' -#endif - ) { - switch (argv[i][1]) { - case 'P': - if (dostop && strlen(argv[i])>2) { - /* bei Optionen via "; ECHECK" nicht mehr machen */ - if (argv[i][2]==0) { /* -P path */ - i++; - if (argv[i]) - path=strdup((char *)(argv[i]+2)); - else { - fputs("Leere Pfad-Angabe ungültig\n",stderr); - exit(0); - } - } else - path=strdup((char *)(argv[i]+2)); - } - break; - - case 'v': - if (argv[i][2]==0) { /* -v version */ - i++; - if (!argv[i]) - break; - } - has_version=1; - x=strchr(argv[i],'.'); - if (x) { - *x=0; - if (strcmp(MAINVERSION,(char *)(argv[i]+2))==0) { - *x='.'; - x++; - if (show_warnings>1 && strcmp(MINVERSION,x)!=0) - fprintf(stderr,"Warnung, falsche ECheck-Version: %s\n",argv[i]+2); - break; - } - } - break; - - case 'b': - brief=1; - break; - - case 'l': - silberpool=1; - break; - - case 'm': - empiria=1; - break; - - case 'q': - no_comment=1; - noship=1; nolost=1; noroute=1; - break; - - case 'r': - if (argv[i][2]==0) { /* -r nnn */ - i++; - if (argv[i]) - rec_cost=atoi(argv[i]); - else - fprintf(stderr,"Fehlende Rekrutierungskosten, auf %d gesetzt",rec_cost); - } else - rec_cost=atoi(argv[i]+2); - break; - - case 'c': - compile=1; - break; - - case 'E': - if (dostop) { /* bei Optionen via "; ECHECK" nicht mehr machen */ - echo_it=1; - OUT=stdout; - ERR=stdout; - } - break; - - case 'e': - if (dostop) { /* bei Optionen via "; ECHECK" nicht mehr machen */ - echo_it=1; - OUT=stdout; - ERR=stderr; - } - break; - - case 'O': - if (dostop) { /* bei Optionen via "; ECHECK" nicht mehr machen */ - if (argv[i][2]==0) { /* "-o file" */ - i++; - x=argv[i]; - } else /* "-ofile" */ - x=argv[i]+2; - if (!x) { - fputs("Keine Datei für Fehler-Texte, stderr benutzt\n",stderr); - ERR=stderr; - break; - } - ERR=fopen(x,"w"); - if (!ERR) { - fprintf(stderr,"Kann Datei '%s' nicht schreiben:\n %s", - x,strerror(errno)); - exit(0); - } - } - break; - - case 'o': - if (dostop) { /* bei Optionen via "; ECHECK" nicht mehr machen */ - if (argv[i][2]==0) { /* "-o file" */ - i++; - x=argv[i]; - } else /* "-ofile" */ - x=argv[i]+2; - echo_it=1; - if (!x) { - fputs("Leere Datei für geprüfte Datei, stdout benutzt\n",stderr); - OUT=stdout; - break; - } - OUT=fopen(x,"w"); - if (!OUT) { - fprintf(stderr,"Kann Datei '%s' nicht schreiben:\n %s", - x,strerror(errno)); - exit(0); - } - } - break; - - case 'p': - piping=1; - break; - - case 'x': - line_start=1; - break; - - case 'w': - if (command_line == 1 || warnings_cl == 0) { - if (argv[i][2]) - show_warnings=(char)atoi(argv[i]+2); - else { - if (argv[i+1] && isdigit(*argv[i+1])) { - i++; - show_warnings=atoi(argv[i]); - } else - show_warnings=0; - } - } - if (command_line==1) - warnings_cl=1; - break; - - case 's': - if (dostop) /* bei Optionen via "; ECHECK" nicht mehr machen */ - ERR=stderr; - break; - - case 'n': - if (strlen(argv[i])>2) { - if (argv[i][3]==0) { /* -no xxx */ - i++; - x=argv[i]; - } else - x=argv[i]+3; - if (!x) { - fputs("-no ???\n",stderr); - break; - } - switch (*x) { - case 's': - noship=1; - break; - case 'r': - noroute=1; - break; - case 'l': - nolost=1; - break; - } - } else - ignore_NameMe=1; - break; - - case '?': - case 'h': - if (dostop) { /* bei Optionen via "; ECHECK" nicht mehr machen */ - help(argv[0]); - exit(1); - } - break; - - default: - if (argv[i][1]) { - fprintf(ERR, "Option '%s' unbekannt.\n", argv[i]); - if (dostop) /* Nicht stoppen, wenn dies die Parameter aus der - Datei selbst sind! */ - exit(10); - } - } - } - } - if (empiria && silberpool) { - fprintf(ERR,"Empiria hat keinen Silberpool\n"); - silberpool=0; - } -} - - -void -parse_options(char *p, char dostop) { - char *argv[10], **ap=argv, *vl, argc=0; - - vl=strtok(p, " \t,"); - do { - *ap++=vl; - argc++; - } while ((vl=strtok(NULL, " \t,"))!=NULL); - *ap=0; - check_options(argc, argv, dostop, 0); -} - - -void -check_OPTION(void) { - get_order(); - if (befehle_ende) return; - if (strncmp(order_buf, "From ", 5)==0) { /* es ist eine Mail */ - do { /* Bis zur Leerzeile suchen -> Mailheader zu Ende */ - fgets(order_buf, BUFSIZE, F); - } while (order_buf[0] != '\n' && !feof(F)); - if (feof(F)) { - befehle_ende=1; - return; - } - get_order(); - } - if (befehle_ende) return; - if (order_buf[0]==COMMENT_CHAR) - do { - if (strlen(order_buf)>9) { - if (strncasecmp(order_buf, "; OPTION", 8)==0 || - strncasecmp(order_buf, "; ECHECK", 8)==0) { - parse_options((char *)(order_buf+2),0); - /* "; " überspringen; zeigt dann auf "OPTION" */ - } else if (strncasecmp(order_buf, "; VERSION", 9)==0) - fprintf(ERR, "%s\n", order_buf); - } - get_order(); - if (befehle_ende) return; - } while (order_buf[0]==COMMENT_CHAR); -} - - -void -process_order_file(int *faction_count, int *unit_count) { - int f=0, next=0; - t_region *r; - unit *u; - char *x; - - line_no=befehle_ende=0; - - check_OPTION(); - - if (befehle_ende) /* dies war wohl eine Datei ohne Befehle */ - return; - - Rx=Ry=-10000; - - /* Auffinden der ersten Partei, und danach abarbeiten bis zur letzten Partei. */ - - while (!befehle_ende) { - switch (igetparam(order_buf)) { - case P_REGION: - if (Regionen) - remove_temp(); - attack_warning=0; - if (echo_it) - { - fputs(order_buf,OUT); - putc('\n',OUT); - } - x=getstr(); - if (*x) { - Rx=atoi(x); - x=strchr(order_buf, ','); - if (!x) { - x=strchr(order_buf, ' '); - if (x) x=strchr(++x, ' '); /* 2. Space ist Trenner? */ - else x=getstr(); - } - if (x && *x) - Ry=atoi(++x); - else - Ry=-10000; - } else - Rx=-10000; - if (Rx<-9999 || Ry<-9999) - awarning("REGION fehlerhaft",0); - r=addregion(Rx, Ry, 0); - r->line_no=line_no; - x=strchr(order_buf, ';'); - if (x) { - x++; - while (a_isspace(*x)) x++; - if(r->name) free(r->name); - r->name=strdup(x); - x=strchr(r->name,'\n'); - if (x) - *x=0; - } else { - if(r->name) free(r->name); - r->name=strdup(""); - } - get_order(); - break; - - case P_FACTION: - if (f && !next) - awarning("NÄCHSTER fehlt",0); - scat(parameters[P_FACTION]); - befehle_ende=0; - f=readafaction(); - fprintf(ERR, "Befehle für Partei %s gefunden.\n", itob(f)); - check_OPTION(); /* Nach PARTEI auf "; OPTION" bzw. "; ECHECK" testen */ - if (befehle_ende) return; - fprintf(ERR, "Rekrutierungskosten auf %d Silber gesetzt, " - "Warning Level %d.\n", rec_cost, show_warnings); - if (silberpool) - fputs("Silberpool", ERR); - else if (empiria) /* Empipria hat keinen Silberpool */ - fputs("Empiria-Modus", ERR); - if (empiria || silberpool) - fputs(" aktiviert.", ERR); - fputs("\n\n", ERR); - if (!has_version) - fputs("Hinweis: es wurde keine ECheck-Version angegeben (-v" - MAINVERSION"."MINVERSION")\n",ERR); - (*faction_count)++; - next=0; - break; - - case P_UNIT: - if (f) { - scat(parameters[P_UNIT]); - readaunit(); - (*unit_count)++; - } else - get_order(); - break; - - /* Falls in readunit abgebrochen wird, steht dort entweder eine neue - Partei, eine neue Einheit oder das File-Ende. Das switch wird erneut - durchlaufen, und die entsprechende Funktion aufgerufen. Man darf - order_buf auf alle Fälle nicht überschreiben! Bei allen anderen - Einträgen hier muß order_buf erneut gefüllt werden, da die - betreffende Information in nur einer Zeile steht, und nun die - nächste gelesen werden muß. */ - - case P_NEXT: - f=0; - scat(parameters[P_NEXT]); - indent=next_indent=INDENT_FACTION; - porder(); - next=1; - - check_money(true); /* Check für Lerngeld, Handel usw.; - * true: dann Bewegung ausführen */ - if (Regionen) { - check_money(false); /* Silber nochmal in den Pool, fehlendes aus Pool */ - check_living(); /* Ernährung mit allem Silber der Region */ - } - check_teachings(); - while (Regionen) { - r=Regionen->next; - if (Regionen->name) - free(Regionen->name); - free(Regionen); - Regionen=r; - } - while (units) { - u=units->next; - if (units->start_of_orders) - free(units->start_of_orders); - if (units->long_order) - free(units->long_order); - if (units->order) - free(units->order); - free(units); - units=u; - } - Regionen=(t_region *)NULL; - units=(unit *)NULL; - - default: - if (order_buf[0]==';') { - check_comment(); - } else { - if (f && order_buf[0]) - awarning("Wird von keiner Einheit ausgeführt",1); - } - get_order(); - } - } /* end while !befehle_ende */ - - if (igetparam(order_buf)==P_NEXT) /* diese Zeile wurde ggf. gelesen und dann kam */ - next=1; /* EOF -> kein Check mehr, next=0... */ - if (f && !next) - anerror("NÄCHSTER fehlt"); -} - - -void -addtoken(tnode *root, const char *str, int id) { - static char buf[1024]; - static struct replace { - char c; - char *str; - } replace[] = { - {'ä', "ae"}, - {'Ä', "ae"}, - {'ö', "oe"}, - {'Ö', "oe"}, - {'ü', "ue"}, - {'Ü', "ue"}, - {'ß', "ss"}, - { 0, 0} - }; - if (root->id>=0 && root->id!=id && !root->leaf) root->id=-1; - if (!*str) { - root->id = id; - root->leaf=1; - } else { - char c = (char)tolower(*str); - int index = ((unsigned char)c) % 32; - int i=0; - tnode * tk = root->next[index]; - if (root->id<0) root->id = id; - while (tk && tk->c != c) tk = tk->nexthash; - if (!tk) { - tk = calloc(1, sizeof(tnode)); - tk->id = -1; - tk->c = c; - tk->nexthash=root->next[index]; - root->next[index] = tk; - } - addtoken(tk, str+1, id); - while (replace[i].str) { - if (*str==replace[i].c) { - strcat(strcpy(buf, replace[i].str), str+1); - addtoken(root, buf, id); - break; - } - ++i; - } - } -} - - -void -inittokens(void) { - int i, k; - t_item *it; - t_names *n; - t_skills *s; - - for (i=0,it=itemdata; it; it=it->next,++i) - for (n=it->name; n; n=n->next) - addtoken(&tokens[UT_ITEM], n->txt, i); - for (i=0; i!=MAXPARAMS; ++i) - addtoken(&tokens[UT_PARAM], parameters[i], i); - for (i=0, s=skilldata; s; s=s->next,++i) - addtoken(&tokens[UT_SKILL], s->name, i); - for (i=0; i!=MAXKEYWORDS; ++i) - addtoken(&tokens[UT_KEYWORD], keywords[i], i); - k=0; - for (i=0; buildingtypes[i]; ++i) { - if (!empiria && strcmp(buildingtypes[i],"Universität")==0) { - k++; - continue; - } - if (empiria && strcmp(buildingtypes[i],"Akademie")==0) { - k++; - continue; - } - addtoken(&tokens[UT_BUILDING], buildingtypes[i], i-k); - } - for (i=0; i!=MAXHERBS; ++i) - for (k=0; k!=2; ++k) - addtoken(&tokens[UT_HERB], herbdata[k][i], i); - for (i=0; i!=MAXPOTIONS; ++i) - for (k=0;k!=2;++k) - addtoken(&tokens[UT_POTION], potionnames[k][i], i); -} - - -int -main(int argc, char *argv[]) { - int i, faction_count=0, unit_count=0; - -#if !defined(AMIGA) && !defined(UMLAUTE) - setlocale(LC_CTYPE, ""); -#endif - -#if macintosh - argc=ccommand(&argv); /* consolenabruf der parameter fuer macintosh - added 15.6.00 chartus*/ -#endif - - /* Path-Handling */ - path = getenv("ECHECKPATH"); - if(path == NULL) { - path = DEFAULT_PATH; - } - - ERR=stdout; - - if (argc <= 1) { - help(argv[0]); - return 0; - } - - if (argc>1) - check_options(argc, argv, 1, 1); - - fprintf(ERR, "ECheck (Version "VERSION - ", "__DATE__"), Zug-Checker für Eressea - Freeware!\n\n"); - - filename=getenv("ECHECKOPTS"); - if (filename) parse_options(filename,1); - - readitems(); - readspells(); - readskills(); - if (!skilldata || !spells) { - fputs("Die Dateien 'talente.txt' und 'items.txt' müssen vorhanden sein\n",ERR); - return 5; - } - inittokens(); - F=stdin; - - for (i=1; i1) - fprintf(ERR, "Es wurden %d Fehler", error_count); - else if (error_count==1) - fputs("Es wurde ein Fehler", ERR); - - if (warning_count) { - if (error_count) - fputs(" und", ERR); - else - fputs("Es wurde", ERR); - } - - if (warning_count>1) { - if (!error_count) - fputs("n", ERR); - fprintf(ERR," %d Warnungen", warning_count); - } else if (warning_count==1) - fputs(" eine Warnung", ERR); - - if (warning_count || error_count) - fputs(" entdeckt.\n", ERR); -#ifdef AMIGA - if (error_count>0) - return 10; /* FAIL beim AMIGA */ - if (warning_count>0) - return 5; /* WARN beim AMIGA */ -#endif - return 0; -} - diff --git a/src/tools/filter.c b/src/tools/filter.c deleted file mode 100644 index 812effe70..000000000 --- a/src/tools/filter.c +++ /dev/null @@ -1,130 +0,0 @@ -/* vi: set ts=2 ai sw=2 - * - * $Id: filter.c,v 1.2 2001/01/26 16:19:41 enno Exp $ - * Eressea PB(E)M host Copyright (C) 1997-99 - * Enno Rehling (rehling@usa.net) - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@gmx.de) - * - * based on: - * - * Atlantis v1.0 13 September 1993 Copyright 1993 by Russell Wallace - * Atlantis v1.7 Copyright 1996 by Alex Schröder - * - * This program may not be used, modified or distributed. It may not be - * sold or used commercially without prior written permission from the - * authors. - * - * Eressea PBeM CR Filter - */ - -#include -#include -#include - -typedef struct tag { - struct tag * next; - char * name; -} tag; - -typedef struct section { - struct section * next; - char * name; - tag * tags; -} section; - -section * -read_tags(FILE * in) -{ - char buf[64]; - section * sec = NULL; - - while (fgets(buf, 64, in)) { - size_t end = strlen(buf); - if (end && buf[end-1]=='\n') buf[end-1] = ' '; - if (buf[0]=='@') { - section * last = sec; - sec = (section *) calloc(1, sizeof(section)); - sec->next = last; - sec->name = (char*)calloc(strlen(buf), sizeof(char)); - strcpy(sec->name, buf+1); - } else if (sec) { - tag * last = sec->tags; - sec->tags = (tag *) calloc(1, sizeof(tag)); - sec->tags->next = last; - sec->tags->name = (char*)calloc(strlen(buf)+1, sizeof(char)); - strcpy(sec->tags->name, buf); - } - } - return sec; -} - -void -filter_stream(FILE * in, FILE * out, section * sec) -{ - char buf[8092]; - section * s = NULL; - while (fgets(buf, 8092, in)) { - section * c; - int found = 0; - size_t end = strlen(buf); - if (end && buf[end-1]=='\n') buf[end-1] = ' '; - for (c = sec;c;c=c->next) { - if (!strncmp(buf, c->name, min(strlen(buf), strlen(c->name)))) { - s = c; - fprintf(out, "%s\n", buf); - found = 1; - break; - } - } - if (s && !found) { - if (strchr(buf, ';')) { - tag * t; - for (t=s->tags;t;t = t->next) { - size_t len = strlen(t->name); - if (!strcmp(buf+strlen(buf)-len, t->name)) { - fprintf(out, "%s\n", buf); - found = 1; - break; - } - } - } else s = NULL; - } - } -} - -int -usage(const char* message) -{ - fprintf(stderr, "usage: filter \n"); - if (message) fprintf(stderr, "\nERROR: %s\n", message); - return -1; -} - -int -main(int argc, char** argv) -{ - FILE * filter; - FILE * in = stdin; - FILE * out = stdout; - section * sec; - if (argc<1) return usage(0); - - filter = fopen(argv[1], "rt"); - if (!filter) usage("cannot open filter definitions"); - - sec = read_tags(filter); - - if (argc>2) { - in = fopen(argv[2], "rt"); - if (!in) usage("cannot open input file"); - } - - if (argc>3) { - out = fopen(argv[3], "wt+"); - if (!out) usage("cannot open output file"); - } - - filter_stream(in, out, sec); -} diff --git a/src/tools/items.txt b/src/tools/items.txt deleted file mode 100644 index a3cc12285..000000000 --- a/src/tools/items.txt +++ /dev/null @@ -1,66 +0,0 @@ -# Liste der Items für ECheck V3 und höher - Faroul -# Alle Items stehen hier mit allen dem Server bekannten Namen. -# Pro Zeile gilt: -# erster Eintrag: Einzahl; -# zweiter Eintrag: Mehrzahl -# dritter und weitere Einträge: weitere Alternativen -# Umlaute müssen nicht umschrieben werden, sondern als ISO-Latin1 -# benutzt: ae=ä, oe=ö, ue=ü, Ae=Ä, Oe=Ö, Ue=Ü, sz=ß - -# Die Luxusgüter _MÜSSEN_ hier ganz vorne in dieser Reihenfolge stehen, -# sonst berechnet ECheck die Einkaufspreise nicht -Balsam; Balsam -Gewürz; Gewürz; Gewürze -Juwel; Juwelen -Myrrhe; Myrrhe -Öl; Öl; Öle -Seide; Seide -Weihrauch; Weihrauch - -# der Rest ist in der Reihenfolge egal: -Eisen; Eisen; Eisenbarren -Holz; Holz; Holzstamm; Holzstämme -Stein; Steine; Steinquader -Pferd; Pferde -Wagen; Wagen -Katapult; Katapulte -Schwert; Schwerter -Speer; Speere -Armbrust; Armbrüste -Bogen; Bögen; Langbogen; Langbögen -Kettenhemd; Kettenhemden; Hemden -Plattenpanzer; Plattenpanzer; Panzer -Bihänder; Bihänder; Zweihänder -Kriegsaxt; Kriegsäxte; Axt; Äxte -Elfenbogen; Elfenbögen -Laenschwert; Laenschwerter -Laenschild; Laenschilde -Laenkettenhemd; Laenkettenhemden -Laen; Laen -Schild; Schilde -Hellebarde; Hellebarden -Lanze; Lanzen -Mallorn; Mallorn -Amulett der Dunkelheit; Amulette der Dunkelheit; Dunkelheit -Amulett des Todes; Amulette des Todes; Todes -Amulett der Heilung; Amulette der Heilung; Heilung -Amulett des wahren Sehens; Amulette des wahren Sehens; Sehens -Mantel der Unverletzlichkeit; Mäntel der Unverletzlichkeit; Mantel der Unverletzbarkeit; Mäntel der Unverletzbarkeit; Unverletzbarkeit; Unverletzlichkeit -Ring der Unsichtbarkeit; Ringe der Unsichtbarkeit; Unsichtbarkeit -Ring der Macht; Ringe der Macht; Macht -Runenschwert; Runenschwerter -Schildstein; Schildsteine -Zauberstab des Feuers; Zauberstäbe des Feuers; Feuers -Zauberstab der Blitze; Zauberstäbe der Blitze; Blitze -Zauberstab der Teleportation; Zauberstäbe der Teleportation; Teleportation -Drachenkopf; Drachenköpfe; Kopf; Köpfe -Amulett der Keuschheit; Amulette der Keuschheit; Keuschheitsamulett -Amulett des Treffens; Amulette des Treffens; Treffens -Drachenblut; Drachenblut; Blut - -# So, das waren die offiziellen Items; diese Liste sollte man nicht ändern, -# wenn man auf das Ergebnis von ECheck Wert legt... -# Man kann aber neue Items anhängen; nein, ich werde keine Fragen zu -# etwaigen neuen Items beantworten, ebensowenig jemand anders aus dem -# Design-Team - Faroul - diff --git a/src/tools/map.crf b/src/tools/map.crf deleted file mode 100644 index 149962405..000000000 --- a/src/tools/map.crf +++ /dev/null @@ -1,5 +0,0 @@ -@VERSION -@REGION -;Terrain -;Name -;Insel