home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!ogicse!zephyr.ens.tek.com!tekred!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v09i075: umoria3 - single player dungeon simulation (ver. 5.2), Part20/31
- Message-ID: <5610@tekred.CNA.TEK.COM>
- Date: 17 May 90 16:24:43 GMT
- Sender: news@tekred.CNA.TEK.COM
- Lines: 2796
- Approved: billr@saab.CNA.TEK.COM
- Posted: Thu May 17 09:24:43 1990
-
- Submitted-by: wilson@ernie.Berkeley.EDU (Jim Wilson)
- Posting-number: Volume 9, Issue 75
- Archive-name: umoria3/Part20
- Supersedes: umoria2: Volume 5, Issue 32-37,41-52,87
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 20 (of 31)."
- # Contents: source/io.c util/mc/creature.y
- # Wrapped by billr@saab on Wed May 16 11:54:35 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'source/io.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'source/io.c'\"
- else
- echo shar: Extracting \"'source/io.c'\" \(29702 characters\)
- sed "s/^X//" >'source/io.c' <<'END_OF_FILE'
- X/* io.c: terminal I/O code, uses the curses package
- X
- X Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
- X
- X This software may be copied and distributed for educational, research, and
- X not for profit purposes provided that this copyright and statement are
- X included in all such copies. */
- X
- X#ifdef MSDOS
- X#include <stdio.h>
- X#include <process.h>
- X#endif
- X
- X#if defined(NLS) && defined(lint)
- X/* for AIX, don't let curses include the NL stuff */
- X#undef NLS
- X#endif
- X
- X#if !defined(GEMDOS)
- X#ifdef MAC
- X#include <scrnmgr.h>
- X#else
- X#include <curses.h>
- X#endif
- X#else
- X#define ATARIST_MWC
- X#include "curses.h"
- Xlong wgetch();
- X#include <osbind.h>
- Xchar *getenv();
- X#endif
- X
- X#include "constant.h"
- X#include "config.h"
- X#include "types.h"
- X#include "externs.h"
- X
- X#include <ctype.h>
- X
- X#if defined(SYS_V) && defined(lint)
- X/* for AIX, prevent hundreds of unnecessary lint errors, must define before
- X signal.h is included */
- X#define _h_IEEETRAP
- Xtypedef struct { int stuff; } fpvmach;
- X#endif
- X
- X#if defined(MSDOS)
- X#if defined(ANSI)
- X#include "ms_ansi.h"
- X#endif
- X#else /* not msdos */
- X#if !defined(ATARIST_MWC) && !defined(MAC)
- X#ifndef VMS
- X#include <sys/ioctl.h>
- X#endif
- X#include <signal.h>
- X#endif
- X#endif
- X
- X#ifndef USG
- X/* only needed for Berkeley UNIX */
- X#include <sys/param.h>
- X#include <sys/file.h>
- X#include <sys/types.h>
- X#endif
- X
- X#ifdef USG
- X#ifndef ATARIST_MWC
- X#include <string.h>
- X#else
- X#include "string.h"
- X#endif
- X#if !defined(MAC) && !defined(MSDOS) && !defined(ATARIST_MWC)
- X#include <termio.h>
- X#endif
- X#else
- X#ifndef VMS
- X#include <strings.h>
- X#if defined(atarist) && defined(__GNUC__)
- X/* doesn't have sys/wait.h */
- X#else
- X#include <sys/wait.h>
- X#endif
- X#endif
- X#endif
- X
- X#if defined(SYS_V) && defined(lint)
- Xstruct screen { int dumb; };
- X#endif
- X
- X/* Fooling lint. Unfortunately, c defines all the TIO. -CJS-
- X constants to be long, and lint expects them to be int. Also,
- X ioctl is sometimes called with just two arguments. The
- X following definition keeps lint happy. It may need to be
- X reset for different systems. */
- X#ifndef MAC
- X#ifdef lint
- X#ifdef Pyramid
- X/* Pyramid makes constants greater than 65535 into long! Gakk! -CJS- */
- X/*ARGSUSED*/
- X/*VARARGS2*/
- Xstatic Ioctl(i, l, p) long l; char *p; { return 0; }
- X#else
- X/*ARGSUSED*/
- X/*VARARGS2*/
- Xstatic Ioctl(i, l, p) char *p; { return 0; }
- X#endif
- X#define ioctl Ioctl
- X#endif
- X
- X#if !defined(USG) && defined(lint)
- X/* This use_value hack is for curses macros which return a value,
- X but don't shut up about it when you try to tell them (void). */
- X/* only needed for Berkeley UNIX */
- Xint Use_value;
- X#define use_value Use_value +=
- X#else
- X#define use_value
- X#endif
- X
- X#if defined(SYS_V) && defined(lint)
- X/* This use_value2 hack is for curses macros which use a conditional
- X expression, and which say null effect even if you cast to (void). */
- X/* only needed for SYS V */
- Xint Use_value2;
- X#define use_value2 Use_value2 +=
- X#else
- X#define use_value2
- X#endif
- X
- X#endif
- X
- X#ifndef MAC
- Xchar *getenv();
- X#endif
- X
- X#ifdef USG
- Xvoid exit();
- Xunsigned sleep();
- X#endif
- X#ifdef ultrix
- Xvoid exit();
- Xvoid sleep();
- X#endif
- X
- X#if !defined(MAC) && !defined(MSDOS) && !defined(ATARIST_MWC)
- X#ifdef USG
- Xstatic struct termio save_termio;
- X#else
- X#ifndef VMS
- Xstatic struct ltchars save_special_chars;
- Xstatic struct sgttyb save_ttyb;
- Xstatic struct tchars save_tchars;
- Xstatic int save_local_chars;
- X#endif
- X#endif
- X#endif
- X
- X#ifndef MAC
- Xstatic int curses_on = FALSE;
- Xstatic WINDOW *savescr; /* Spare window for saving the screen. -CJS- */
- X#endif
- X
- X#ifdef MAC
- X/* Attributes of normal and hilighted characters */
- X#define ATTR_NORMAL attrNormal
- X#define ATTR_HILITED attrReversed
- X#endif
- X
- X#ifndef MAC
- X#ifdef SIGTSTP
- X/* suspend() -CJS-
- X Handle the stop and start signals. This ensures that the log
- X is up to date, and that the terminal is fully reset and
- X restored. */
- Xint suspend()
- X{
- X#ifdef USG
- X /* for USG systems with BSDisms that have SIGTSTP defined, but don't
- X actually implement it */
- X#else
- X struct sgttyb tbuf;
- X struct ltchars lcbuf;
- X struct tchars cbuf;
- X int lbuf;
- X long time();
- X
- X py.misc.male |= 2;
- X (void) ioctl(0, TIOCGETP, (char *)&tbuf);
- X (void) ioctl(0, TIOCGETC, (char *)&cbuf);
- X (void) ioctl(0, TIOCGLTC, (char *)&lcbuf);
- X (void) ioctl(0, TIOCLGET, (char *)&lbuf);
- X restore_term();
- X (void) kill(0, SIGSTOP);
- X curses_on = TRUE;
- X (void) ioctl(0, TIOCSETP, (char *)&tbuf);
- X (void) ioctl(0, TIOCSETC, (char *)&cbuf);
- X (void) ioctl(0, TIOCSLTC, (char *)&lcbuf);
- X (void) ioctl(0, TIOCLSET, (char *)&lbuf);
- X (void) wrefresh(curscr);
- X py.misc.male &= ~2;
- X#endif
- X return 0;
- X}
- X#endif
- X#endif
- X
- X/* initializes curses routines */
- Xvoid init_curses()
- X#ifdef MAC
- X{
- X /* Primary initialization is done in mac.c since game is restartable */
- X /* Only need to clear the screen here */
- X Rect scrn;
- X
- X scrn.left = scrn.top = 0;
- X scrn.right = SCRN_COLS;
- X scrn.bottom = SCRN_ROWS;
- X EraseScreen(&scrn);
- X UpdateScreen();
- X}
- X#else
- X{
- X int i, y, x;
- X
- X#ifndef USG
- X (void) ioctl(0, TIOCGLTC, (char *)&save_special_chars);
- X (void) ioctl(0, TIOCGETP, (char *)&save_ttyb);
- X (void) ioctl(0, TIOCGETC, (char *)&save_tchars);
- X (void) ioctl(0, TIOCLGET, (char *)&save_local_chars);
- X#else
- X#if !defined(VMS) && !defined(MSDOS) && !defined(ATARIST_MWC)
- X (void) ioctl(0, TCGETA, (char *)&save_termio);
- X#endif
- X#endif
- X
- X#ifdef ATARIST_MWC
- X WINDOW *newwin();
- X initscr();
- X if (ERR)
- X#else
- X#if defined(USG) && !defined(PC_CURSES) /* PC curses returns ERR */
- X if (initscr() == NULL)
- X#else
- X if (initscr() == ERR)
- X#endif
- X#endif
- X {
- X (void) printf("Error allocating screen in curses package.\n");
- X exit(1);
- X }
- X if (LINES < 24 || COLS < 80) /* Check we have enough screen. -CJS- */
- X {
- X (void) printf("Screen too small for moria.\n");
- X exit (1);
- X }
- X#ifdef SIGTSTP
- X (void) signal (SIGTSTP, suspend);
- X#endif
- X if ((savescr = newwin (0, 0, 0, 0)) == NULL)
- X {
- X (void) printf ("Out of memory in starting up curses.\n");
- X exit_game();
- X }
- X (void) clear();
- X (void) refresh();
- X moriaterm ();
- X
- X /* check tab settings, exit with error if they are not 8 spaces apart */
- X#ifdef ATARIST_MWC
- X move(0, 0);
- X#else
- X (void) move(0, 0);
- X#endif
- X for (i = 1; i < 10; i++)
- X {
- X#ifdef ATARIST_MWC
- X addch('\t');
- X#else
- X (void) addch('\t');
- X#endif
- X getyx(stdscr, y, x);
- X if (y != 0 || x != i*8)
- X break;
- X }
- X if (i != 10)
- X {
- X msg_print("Tabs must be set 8 spaces apart.");
- X exit_game();
- X }
- X}
- X#endif
- X
- X/* Set up the terminal into a suitable state for moria. -CJS- */
- Xvoid moriaterm()
- X#ifdef MAC
- X/* Nothing to do on Mac */
- X{
- X}
- X#else
- X{
- X#if !defined(MSDOS) && !defined(ATARIST_MWC)
- X#ifdef USG
- X struct termio tbuf;
- X#else
- X struct ltchars lbuf;
- X struct tchars buf;
- X#endif
- X#endif
- X
- X curses_on = TRUE;
- X#ifndef BSD4_3
- X use_value crmode();
- X#else
- X use_value cbreak();
- X#endif
- X use_value noecho();
- X /* can not use nonl(), because some curses do not handle it correctly */
- X#ifdef MSDOS
- X msdos_raw();
- X#else
- X#if !defined(ATARIST_MWC)
- X#ifdef USG
- X (void) ioctl(0, TCGETA, (char *)&tbuf);
- X /* disable all of the normal special control characters */
- X tbuf.c_cc[VINTR] = (char)3; /* control-C */
- X tbuf.c_cc[VQUIT] = (char)-1;
- X tbuf.c_cc[VERASE] = (char)-1;
- X tbuf.c_cc[VKILL] = (char)-1;
- X tbuf.c_cc[VEOF] = (char)-1;
- X
- X /* don't know what these are for */
- X tbuf.c_cc[VEOL] = (char)-1;
- X tbuf.c_cc[VEOL2] = (char)-1;
- X
- X /* stuff needed when !icanon, i.e. cbreak/raw mode */
- X tbuf.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
- X tbuf.c_cc[VTIME] = 0; /* no matter how long that takes. */
- X
- X (void) ioctl(0, TCSETA, (char *)&tbuf);
- X#else
- X#ifndef VMS
- X /* disable all of the special characters except the suspend char, interrupt
- X char, and the control flow start/stop characters */
- X (void) ioctl(0, TIOCGLTC, (char *)&lbuf);
- X lbuf.t_suspc = (char)26; /* control-Z */
- X lbuf.t_dsuspc = (char)-1;
- X lbuf.t_rprntc = (char)-1;
- X lbuf.t_flushc = (char)-1;
- X lbuf.t_werasc = (char)-1;
- X lbuf.t_lnextc = (char)-1;
- X (void) ioctl(0, TIOCSLTC, (char *)&lbuf);
- X
- X (void) ioctl (0, TIOCGETC, (char *)&buf);
- X buf.t_intrc = (char)3; /* control-C */
- X buf.t_quitc = (char)-1;
- X buf.t_startc = (char)17; /* control-Q */
- X buf.t_stopc = (char)19; /* control-S */
- X buf.t_eofc = (char)-1;
- X buf.t_brkc = (char)-1;
- X (void) ioctl(0, TIOCSETC, (char *)&buf);
- X#endif
- X#endif
- X#endif
- X#endif
- X}
- X#endif
- X
- X
- X/* Dump IO to buffer -RAK- */
- Xvoid put_buffer(out_str, row, col)
- Xchar *out_str;
- Xint row, col;
- X#ifdef MAC
- X{
- X /* The screen manager handles writes past the edge ok */
- X DSetScreenCursor(col, row);
- X DWriteScreenStringAttr(out_str, ATTR_NORMAL);
- X}
- X#else
- X{
- X vtype tmp_str;
- X
- X /* truncate the string, to make sure that it won't go past right edge of
- X screen */
- X if (col > 79)
- X col = 79;
- X (void) strncpy (tmp_str, out_str, 79 - col);
- X tmp_str [79 - col] = '\0';
- X
- X#ifndef ATARIST_MWC
- X if (mvaddstr(row, col, tmp_str) == ERR)
- X#else
- X mvaddstr(row, col, out_str);
- X if (ERR)
- X#endif
- X {
- X abort();
- X /* clear msg_flag to avoid problems with unflushed messages */
- X msg_flag = 0;
- X (void) sprintf(tmp_str, "error in put_buffer, row = %d col = %d\n",
- X row, col);
- X prt(tmp_str, 0, 0);
- X bell();
- X /* wait so user can see error */
- X (void) sleep(2);
- X }
- X}
- X#endif
- X
- X
- X/* Dump the IO buffer to terminal -RAK- */
- Xvoid put_qio()
- X{
- X screen_change = TRUE; /* Let inven_command know something has changed. */
- X#ifdef MAC
- X UpdateScreen();
- X#else
- X (void) refresh();
- X#endif
- X}
- X
- X/* Put the terminal in the original mode. -CJS- */
- Xvoid restore_term()
- X#ifdef MAC
- X/* Nothing to do on Mac */
- X{
- X}
- X#else
- X{
- X if (!curses_on)
- X return;
- X put_qio(); /* Dump any remaining buffer */
- X#ifdef MSDOS
- X (void) sleep(2); /* And let it be read. */
- X#endif
- X#ifdef VMS
- X pause_line(15);
- X#endif
- X /* this moves curses to bottom right corner */
- X mvcur(curscr->_cury, curscr->_curx, LINES-1, 0);
- X#ifdef VMS
- X pause_line(15);
- X#endif
- X endwin(); /* exit curses */
- X (void) fflush (stdout);
- X#ifdef MSDOS
- X msdos_noraw();
- X (void) clear();
- X#endif
- X /* restore the saved values of the special chars */
- X#ifdef USG
- X#if !defined(MSDOS) && !defined(ATARIST_MWC)
- X (void) ioctl(0, TCSETA, (char *)&save_termio);
- X#endif
- X#else
- X#ifndef VMS
- X (void) ioctl(0, TIOCSLTC, (char *)&save_special_chars);
- X (void) ioctl(0, TIOCSETP, (char *)&save_ttyb);
- X (void) ioctl(0, TIOCSETC, (char *)&save_tchars);
- X (void) ioctl(0, TIOCLSET, (char *)&save_local_chars);
- X#endif
- X#endif
- X curses_on = FALSE;
- X}
- X#endif
- X
- X
- Xvoid shell_out()
- X#ifdef MAC
- X{
- X alert_error("This command is not implemented on the Macintosh.");
- X}
- X#else
- X{
- X#ifdef USG
- X#if !defined(MSDOS) && !defined(ATARIST_MWC)
- X struct termio tbuf;
- X#endif
- X#else
- X struct sgttyb tbuf;
- X struct ltchars lcbuf;
- X struct tchars cbuf;
- X int lbuf;
- X#endif
- X#ifdef MSDOS
- X char *comspec, key;
- X#else
- X#ifdef ATARIST_MWC
- X char comstr[80];
- X char *str;
- X extern char **environ;
- X#else
- X int val;
- X char *str;
- X#endif
- X#endif
- X
- X save_screen();
- X /* clear screen and print 'exit' message */
- X clear_screen();
- X#ifndef ATARIST_MWC
- X put_buffer("[Entering shell, type 'exit' to resume your game.]\n",0,0);
- X#else
- X put_buffer("[Escaping to shell]\n",0,0);
- X#endif
- X put_qio();
- X
- X#ifdef USG
- X#if !defined(MSDOS) && !defined(ATARIST_MWC)
- X (void) ioctl(0, TCGETA, (char *)&tbuf);
- X#endif
- X#else
- X#ifndef VMS
- X (void) ioctl(0, TIOCGETP, (char *)&tbuf);
- X (void) ioctl(0, TIOCGETC, (char *)&cbuf);
- X (void) ioctl(0, TIOCGLTC, (char *)&lcbuf);
- X (void) ioctl(0, TIOCLGET, (char *)&lbuf);
- X#endif
- X#endif
- X /* would call nl() here if could use nl()/nonl(), see moriaterm() */
- X#ifndef BSD4_3
- X use_value nocrmode();
- X#else
- X use_value nocbreak();
- X#endif
- X#ifdef MSDOS
- X use_value msdos_noraw();
- X#endif
- X use_value echo();
- X ignore_signals();
- X#ifdef MSDOS /*{*/
- X if ((comspec = getenv("COMSPEC")) == NULL
- X || spawnl(P_WAIT, comspec, comspec, (char *) NULL) < 0) {
- X clear_screen(); /* BOSS key if shell failed */
- X put_buffer("M:\\> ", 0, 0);
- X do {
- X key = inkey(key);
- X } while (key != '!');
- X }
- X
- X#else /* MSDOS }{*/
- X#ifndef ATARIST_MWC
- X val = fork();
- X if (val == 0)
- X {
- X#endif
- X default_signals();
- X#ifdef USG
- X#if !defined(MSDOS) && !defined(ATARIST_MWC)
- X (void) ioctl(0, TCSETA, (char *)&save_termio);
- X#endif
- X#else
- X#ifndef VMS
- X (void) ioctl(0, TIOCSLTC, (char *)&save_special_chars);
- X (void) ioctl(0, TIOCSETP, (char *)&save_ttyb);
- X (void) ioctl(0, TIOCSETC, (char *)&save_tchars);
- X (void) ioctl(0, TIOCLSET, (char *)&save_local_chars);
- X#endif
- X#endif
- X#ifndef MSDOS
- X /* close scoreboard descriptor */
- X /* it is not open on MSDOS machines */
- X#if 0
- X /* this file is not open now, see init_file() in files.c */
- X (void) close(highscore_fd);
- X#endif
- X#endif
- X if (str = getenv("SHELL"))
- X#ifndef ATARIST_MWC
- X (void) execl(str, str, (char *) 0);
- X#else
- X system(str);
- X#endif
- X else
- X#ifndef ATARIST_MWC
- X (void) execl("/bin/sh", "sh", (char *) 0);
- X#endif
- X msg_print("Cannot execute shell.");
- X#ifndef ATARIST_MWC
- X exit(1);
- X }
- X if (val == -1)
- X {
- X msg_print("Fork failed. Try again.");
- X return;
- X }
- X#ifdef USG
- X (void) wait((int *) 0);
- X#else
- X (void) wait((union wait *) 0);
- X#endif
- X#endif /* ATARIST_MWC */
- X#endif /* MSDOS }*/
- X restore_signals();
- X /* restore the cave to the screen */
- X restore_screen();
- X#ifndef BSD4_3
- X use_value crmode();
- X#else
- X use_value cbreak();
- X#endif
- X use_value noecho();
- X /* would call nonl() here if could use nl()/nonl(), see moriaterm() */
- X#ifdef MSDOS
- X msdos_raw();
- X#endif
- X /* disable all of the local special characters except the suspend char */
- X /* have to disable ^Y for tunneling */
- X#ifdef USG
- X#if !defined(MSDOS) && !defined(ATARIST_MWC)
- X (void) ioctl(0, TCSETA, (char *)&tbuf);
- X#endif
- X#else
- X#ifndef VMS
- X (void) ioctl(0, TIOCSLTC, (char *)&lcbuf);
- X (void) ioctl(0, TIOCSETP, (char *)&tbuf);
- X (void) ioctl(0, TIOCSETC, (char *)&cbuf);
- X (void) ioctl(0, TIOCLSET, (char *)&lbuf);
- X#endif
- X#endif
- X (void) wrefresh(curscr);
- X}
- X#endif
- X
- X
- X/* Returns a single character input from the terminal. This silently -CJS-
- X consumes ^R to redraw the screen and reset the terminal, so that this
- X operation can always be performed at any input prompt. inkey() never
- X returns ^R. */
- Xchar inkey()
- X#ifdef MAC
- X/* The Mac does not need ^R, so it just consumes it */
- X/* This routine does nothing special with direction keys */
- X/* Just returns their keypad ascii value (e.g. '0'-'9') */
- X/* Compare with inkeydir() below */
- X{
- X char ch;
- X int dir;
- X int shift_flag, ctrl_flag;
- X
- X put_qio();
- X command_count = 0;
- X
- X do {
- X macgetkey(&ch, FALSE);
- X } while (ch == CTRL('R'));
- X
- X dir = extractdir(ch, &shift_flag, &ctrl_flag);
- X if (dir != -1)
- X ch = '0' + dir;
- X
- X return(ch);
- X}
- X#else
- X{
- X int i;
- X
- X put_qio(); /* Dump IO buffer */
- X command_count = 0; /* Just to be safe -CJS- */
- X while (TRUE)
- X {
- X#ifdef MSDOS
- X i = msdos_getch();
- X#else
- X i = getch();
- X#endif
- X
- X /* some machines may not sign extend. */
- X if (i == EOF)
- X {
- X eof_flag++;
- X /* avoid infinite loops while trying to call inkey() for a -more-
- X prompt. */
- X msg_flag = FALSE;
- X
- X (void) refresh ();
- X if (!character_generated || character_saved)
- X exit_game();
- X disturb(1, 0);
- X if (eof_flag > 100)
- X {
- X /* just in case, to make sure that the process eventually dies */
- X panic_save = 1;
- X (void) strcpy(died_from, "(end of input: panic saved)");
- X if (!save_char())
- X {
- X (void) strcpy(died_from, "panic: unexpected eof");
- X death = TRUE;
- X }
- X exit_game();
- X }
- X return ESCAPE;
- X }
- X if (i != CTRL('R'))
- X return (char)i;
- X (void) wrefresh (curscr);
- X moriaterm();
- X }
- X}
- X#endif
- X
- X
- X#ifdef MAC
- Xchar inkeydir()
- X/* The Mac does not need ^R, so it just consumes it */
- X/* This routine translates the direction keys in rogue-like mode */
- X/* Compare with inkeydir() below */
- X{
- X char ch;
- X int dir;
- X int shift_flag, ctrl_flag;
- X static char tab[9] = {
- X 'b', 'j', 'n',
- X 'h', '.', 'l',
- X 'y', 'k', 'u'
- X };
- X static char shifttab[9] = {
- X 'B', 'J', 'N',
- X 'H', '.', 'L',
- X 'Y', 'K', 'U'
- X };
- X static char ctrltab[9] = {
- X CTRL('B'), CTRL('J'), CTRL('N'),
- X CTRL('H'), '.', CTRL('L'),
- X CTRL('Y'), CTRL('K'), CTRL('U')
- X };
- X
- X put_qio();
- X command_count = 0;
- X
- X do {
- X macgetkey(&ch, FALSE);
- X } while (ch == CTRL('R'));
- X
- X dir = extractdir(ch, &shift_flag, &ctrl_flag);
- X
- X if (dir != -1) {
- X if (!rogue_like_commands) {
- X ch = '0' + dir;
- X }
- X else {
- X if (ctrl_flag)
- X ch = ctrltab[dir - 1];
- X else if (shift_flag)
- X ch = shifttab[dir - 1];
- X else
- X ch = tab[dir - 1];
- X }
- X }
- X
- X return(ch);
- X}
- X#endif
- X
- X
- X/* Flush the buffer -RAK- */
- Xvoid flush()
- X#ifdef MAC
- X{
- X/* Removed put_qio() call. Reduces flashing. Doesn't seem to hurt. */
- X FlushScreenKeys();
- X}
- X#else
- X{
- X#ifdef MSDOS
- X while (kbhit())
- X (void) getch();
- X#else
- X /* the code originally used ioctls, TIOCDRAIN, or TIOCGETP/TIOCSETP, or
- X TCGETA/TCSETAF, however this occasionally resulted in loss of output,
- X the happened especially often when rlogin from BSD to SYS_V machine,
- X using check_input makes the desired effect a bit clearer */
- X /* wierd things happen on EOF, don't try to flush input in that case */
- X if (!eof_flag)
- X while (check_input(0));
- X#endif
- X
- X /* used to call put_qio() here to drain output, but it is not necessary */
- X}
- X#endif
- X
- X
- X/* Clears given line of text -RAK- */
- Xvoid erase_line(row, col)
- Xint row;
- Xint col;
- X#ifdef MAC
- X{
- X Rect line;
- X
- X if (row == MSG_LINE && msg_flag)
- X msg_print(NULL);
- X
- X line.left = col;
- X line.top = row;
- X line.right = SCRN_COLS;
- X line.bottom = row + 1;
- X DEraseScreen(&line);
- X}
- X#else
- X{
- X if (row == MSG_LINE && msg_flag)
- X msg_print(NULL);
- X (void) move(row, col);
- X clrtoeol();
- X}
- X#endif
- X
- X
- X/* Clears screen */
- Xvoid clear_screen()
- X#ifdef MAC
- X{
- X Rect area;
- X
- X if (msg_flag)
- X msg_print(NULL);
- X
- X area.left = area.top = 0;
- X area.right = SCRN_COLS;
- X area.bottom = SCRN_ROWS;
- X DEraseScreen(&area);
- X}
- X#else
- X{
- X if (msg_flag)
- X msg_print(NULL);
- X (void) clear();
- X}
- X#endif
- X
- Xvoid clear_from (row)
- Xint row;
- X#ifdef MAC
- X{
- X Rect area;
- X
- X area.left = 0;
- X area.top = row;
- X area.right = SCRN_COLS;
- X area.bottom = SCRN_ROWS;
- X DEraseScreen(&area);
- X}
- X#else
- X{
- X (void) move(row, 0);
- X clrtobot();
- X}
- X#endif
- X
- X
- X/* Outputs a char to a given interpolated y, x position -RAK- */
- X/* sign bit of a character used to indicate standout mode. -CJS */
- Xvoid print(ch, row, col)
- Xchar ch;
- Xint row;
- Xint col;
- X#ifdef MAC
- X{
- X char cnow, anow;
- X
- X row -= panel_row_prt;/* Real co-ords convert to screen positions */
- X col -= panel_col_prt;
- X
- X GetScreenCharAttr(&cnow, &anow, col, row); /* Check current */
- X
- X /* If char is already set, ignore op */
- X if ((cnow != ch) || (anow != ATTR_NORMAL))
- X DSetScreenCharAttr(cnew, anew, col, row);
- X}
- X#else
- X{
- X vtype tmp_str;
- X
- X row -= panel_row_prt;/* Real co-ords convert to screen positions */
- X col -= panel_col_prt;
- X#if defined(ATARIST_MWC)
- X mvaddch (row, col, ch);
- X#else
- X if (mvaddch (row, col, ch) == ERR)
- X {
- X abort();
- X /* clear msg_flag to avoid problems with unflushed messages */
- X msg_flag = 0;
- X (void) sprintf(tmp_str, "error in print, row = %d col = %d\n", row, col);
- X prt(tmp_str, 0, 0);
- X bell ();
- X /* wait so user can see error */
- X (void) sleep(2);
- X }
- X#endif
- X}
- X#endif
- X
- X
- X/* Moves the cursor to a given interpolated y, x position -RAK- */
- Xvoid move_cursor_relative(row, col)
- Xint row;
- Xint col;
- X#ifdef MAC
- X{
- X row -= panel_row_prt;/* Real co-ords convert to screen positions */
- X col -= panel_col_prt;
- X
- X DSetScreenCursor(col, row);
- X}
- X#else
- X{
- X vtype tmp_str;
- X
- X row -= panel_row_prt;/* Real co-ords convert to screen positions */
- X col -= panel_col_prt;
- X if (move (row, col) == ERR)
- X {
- X abort();
- X /* clear msg_flag to avoid problems with unflushed messages */
- X msg_flag = 0;
- X (void) sprintf(tmp_str, "error in move_cursor_relative, row = %d col = %d\n", row, col);
- X prt(tmp_str, 0, 0);
- X bell();
- X /* wait so user can see error */
- X (void) sleep(2);
- X }
- X}
- X#endif
- X
- X
- X/* Print a message so as not to interrupt a counted command. -CJS- */
- Xvoid count_msg_print(p)
- Xchar *p;
- X{
- X int i;
- X
- X i = command_count;
- X msg_print(p);
- X command_count = i;
- X}
- X
- X
- X/* Outputs a line to a given y, x position -RAK- */
- Xvoid prt(str_buff, row, col)
- Xchar *str_buff;
- Xint row;
- Xint col;
- X#ifdef MAC
- X{
- X Rect line;
- X
- X if (row == MSG_LINE && msg_flag)
- X msg_print(NULL);
- X
- X line.left = col;
- X line.top = row;
- X line.right = SCRN_COLS;
- X line.bottom = row + 1;
- X DEraseScreen(&line);
- X
- X put_buffer(str_buff, row, col);
- X}
- X#else
- X{
- X if (row == MSG_LINE && msg_flag)
- X msg_print(NULL);
- X (void) move(row, col);
- X clrtoeol();
- X put_buffer(str_buff, row, col);
- X}
- X#endif
- X
- X
- X/* move cursor to a given y, x position */
- Xvoid move_cursor(row, col)
- Xint row, col;
- X#ifdef MAC
- X{
- X DSetScreenCursor(col, row);
- X}
- X#else
- X{
- X (void) move (row, col);
- X}
- X#endif
- X
- X
- X/* Outputs message to top line of screen */
- X/* These messages are kept for later reference. */
- Xvoid msg_print(str_buff)
- Xchar *str_buff;
- X{
- X register int old_len;
- X char in_char;
- X#ifdef MAC
- X Rect line;
- X#endif
- X
- X if (msg_flag)
- X {
- X old_len = strlen(old_msg[last_msg]) + 1;
- X /* ensure that the complete -more- message is visible. */
- X if (old_len > 73)
- X old_len = 73;
- X put_buffer(" -more-", MSG_LINE, old_len);
- X /* let sigint handler know that we are waiting for a space */
- X wait_for_more = 1;
- X do
- X {
- X in_char = inkey();
- X }
- X while ((in_char != ' ') && (in_char != ESCAPE) && (in_char != '\n') &&
- X (in_char != '\r'));
- X wait_for_more = 0;
- X }
- X#ifdef MAC
- X line.left = 0;
- X line.top = MSG_LINE;
- X line.right = SCRN_COLS;
- X line.bottom = MSG_LINE+1;
- X DEraseScreen(&line);
- X#else
- X (void) move(MSG_LINE, 0);
- X clrtoeol();
- X#endif
- X
- X /* Make the null string a special case. -CJS- */
- X if (str_buff)
- X {
- X put_buffer(str_buff, MSG_LINE, 0);
- X command_count = 0;
- X last_msg++;
- X if (last_msg >= MAX_SAVE_MSG)
- X last_msg = 0;
- X (void) strncpy(old_msg[last_msg], str_buff, VTYPESIZ);
- X old_msg[last_msg][VTYPESIZ - 1] = '\0';
- X msg_flag = TRUE;
- X }
- X else
- X msg_flag = FALSE;
- X}
- X
- X
- X/* Used to verify a choice - user gets the chance to abort choice. -CJS- */
- Xint get_check(prompt)
- Xchar *prompt;
- X{
- X int res;
- X int y, x;
- X
- X prt(prompt, 0, 0);
- X#ifdef MAC
- X GetScreenCursor(&x, &y);
- X#else
- X getyx(stdscr, y, x);
- X#if defined(lint)
- X /* prevent message 'warning: y is unused' */
- X x = y;
- X#endif
- X#endif
- X
- X if (x > 73)
- X#ifdef ATARIST_MWC
- X move(0, 73);
- X#else
- X (void) move(0, 73);
- X#endif
- X#ifdef MAC
- X DWriteScreenStringAttr(" [y/n]", ATTR_NORMAL);
- X#else
- X (void) addstr(" [y/n]");
- X#endif
- X do
- X {
- X res = inkey();
- X }
- X while(res == ' ');
- X erase_line(0, 0);
- X if (res == 'Y' || res == 'y')
- X return TRUE;
- X else
- X return FALSE;
- X}
- X
- X/* Prompts (optional) and returns ord value of input char */
- X/* Function returns false if <ESCAPE> is input */
- Xint get_com(prompt, command)
- Xchar *prompt;
- Xchar *command;
- X{
- X int res;
- X
- X if (prompt)
- X prt(prompt, 0, 0);
- X *command = inkey();
- X if (*command == 0 || *command == ESCAPE)
- X res = FALSE;
- X else
- X res = TRUE;
- X erase_line(MSG_LINE, 0);
- X return(res);
- X}
- X
- X#ifdef MAC
- X/* Same as get_com(), but translates direction keys from keypad */
- Xint get_comdir(prompt, command)
- Xchar *prompt;
- Xchar *command;
- X{
- X int res;
- X
- X if (prompt)
- X prt(prompt, 0, 0);
- X *command = inkeydir();
- X if (*command == 0 || *command == ESCAPE)
- X res = FALSE;
- X else
- X res = TRUE;
- X erase_line(MSG_LINE, 0);
- X return(res);
- X}
- X#endif
- X
- X
- X/* Gets a string terminated by <RETURN> */
- X/* Function returns false if <ESCAPE> is input */
- Xint get_string(in_str, row, column, slen)
- Xchar *in_str;
- Xint row, column, slen;
- X{
- X register int start_col, end_col, i;
- X char *p;
- X int flag, aborted;
- X#ifdef MAC
- X Rect area;
- X#endif
- X
- X aborted = FALSE;
- X flag = FALSE;
- X#ifdef MAC
- X area.left = column;
- X area.top = row;
- X area.right = column + slen;
- X area.bottom = row + 1;
- X DEraseScreen(&area);
- X DSetScreenCursor(column, row);
- X#else
- X (void) move(row, column);
- X for (i = slen; i > 0; i--)
- X (void) addch(' ');
- X (void) move(row, column);
- X#endif
- X start_col = column;
- X end_col = column + slen - 1;
- X if (end_col > 79)
- X {
- X slen = 80 - column;
- X end_col = 79;
- X }
- X p = in_str;
- X do
- X {
- X i = inkey();
- X switch(i)
- X {
- X case ESCAPE:
- X aborted = TRUE;
- X break;
- X case CTRL('J'): case CTRL('M'):
- X flag = TRUE;
- X break;
- X case DELETE: case CTRL('H'):
- X if (column > start_col)
- X {
- X column--;
- X put_buffer(" ", row, column);
- X move_cursor(row, column);
- X *--p = '\0';
- X }
- X break;
- X default:
- X if (!isprint(i) || column > end_col)
- X bell();
- X else
- X {
- X#ifdef MAC
- X DSetScreenCursor(column, row);
- X DWriteScreenCharAttr((char) i, ATTR_NORMAL);
- X#else
- X use_value2 mvaddch(row, column, (char)i);
- X#endif
- X *p++ = i;
- X column++;
- X }
- X break;
- X }
- X }
- X while ((!flag) && (!aborted));
- X if (aborted)
- X return(FALSE);
- X /* Remove trailing blanks */
- X while (p > in_str && p[-1] == ' ')
- X p--;
- X *p = '\0';
- X return(TRUE);
- X}
- X
- X
- X/* Pauses for user response before returning -RAK- */
- Xvoid pause_line(prt_line)
- Xint prt_line;
- X{
- X prt("[Press any key to continue.]", prt_line, 23);
- X (void) inkey();
- X erase_line(prt_line, 0);
- X}
- X
- X
- X/* Pauses for user response before returning -RAK- */
- X/* NOTE: Delay is for players trying to roll up "perfect" */
- X/* characters. Make them wait a bit. */
- Xvoid pause_exit(prt_line, delay)
- Xint prt_line;
- Xint delay;
- X{
- X char dummy;
- X
- X prt("[Press any key to continue, or Q to exit.]", prt_line, 10);
- X dummy = inkey();
- X if (dummy == 'Q')
- X {
- X erase_line(prt_line, 0);
- X#ifndef MSDOS /* PCs are slow enough as is -dgk */
- X if (delay > 0) (void) sleep((unsigned)delay);
- X#endif
- X#ifdef MAC
- X enablefilemenu(FALSE);
- X exit_game();
- X enablefilemenu(TRUE);
- X#else
- X exit_game();
- X#endif
- X }
- X erase_line(prt_line, 0);
- X}
- X
- X#ifdef MAC
- Xvoid save_screen()
- X{
- X mac_save_screen();
- X}
- X
- Xvoid restore_screen()
- X{
- X mac_restore_screen();
- X}
- X#else
- Xvoid save_screen()
- X{
- X overwrite(stdscr, savescr);
- X}
- X
- Xvoid restore_screen()
- X{
- X overwrite(savescr, stdscr);
- X touchwin(stdscr);
- X}
- X#endif
- X
- Xvoid bell()
- X{
- X put_qio();
- X#ifdef MAC
- X mac_beep();
- X#else
- X (void) write(1, "\007", 1);
- X#endif
- X}
- X
- X/* definitions used by screen_map() */
- X/* index into border character array */
- X#define TL 0 /* top left */
- X#define TR 1
- X#define BL 2
- X#define BR 3
- X#define HE 4 /* horizontal edge */
- X#define VE 5
- X
- X/* character set to use */
- X#ifdef MSDOS
- X# ifdef ANSI
- X# define CH(x) (ansi ? screen_border[0][x] : screen_border[1][x])
- X# else
- X# define CH(x) (screen_border[1][x])
- X# endif
- X#else
- X# define CH(x) (screen_border[0][x])
- X#endif
- X
- X /* Display highest priority object in the RATIO by RATIO area */
- X#define RATIO 3
- X
- Xvoid screen_map()
- X{
- X register int i, j;
- X static int8u screen_border[2][6] = {
- X {'+', '+', '+', '+', '-', '|'}, /* normal chars */
- X {201, 187, 200, 188, 205, 186} /* graphics chars */
- X };
- X int8u map[MAX_WIDTH / RATIO + 1];
- X int8u tmp;
- X int priority[256];
- X int row, orow, col, myrow, mycol = 0;
- X#ifndef MAC
- X char prntscrnbuf[80];
- X#endif
- X
- X for (i = 0; i < 256; i++)
- X priority[i] = 0;
- X priority['<'] = 5;
- X priority['>'] = 5;
- X priority['@'] = 10;
- X#ifdef MSDOS
- X priority[wallsym] = -5;
- X priority[floorsym] = -10;
- X#else
- X priority['#'] = -5;
- X priority['.'] = -10;
- X#endif
- X priority['\''] = -3;
- X priority[' '] = -15;
- X
- X save_screen();
- X clear_screen();
- X#ifdef MAC
- X DSetScreenCursor(0, 0);
- X DWriteScreenCharAttr(CH(TL), ATTR_NORMAL);
- X for (i = 0; i < MAX_WIDTH / RATIO; i++)
- X DWriteScreenCharAttr(CH(HE), ATTR_NORMAL);
- X DWriteScreenCharAttr(CH(TR), ATTR_NORMAL);
- X#else
- X use_value2 mvaddch(0, 0, CH(TL));
- X for (i = 0; i < MAX_WIDTH / RATIO; i++)
- X (void) addch(CH(HE));
- X (void) addch(CH(TR));
- X#endif
- X orow = -1;
- X map[MAX_WIDTH / RATIO] = '\0';
- X for (i = 0; i < MAX_HEIGHT; i++)
- X {
- X row = i / RATIO;
- X if (row != orow)
- X {
- X if (orow >= 0)
- X {
- X#ifdef MAC
- X DSetScreenCursor(0, orow+1);
- X DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
- X DWriteScreenString(map);
- X DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
- X#else
- X /* can not use mvprintw() on ibmpc, because PC-Curses is horribly
- X written, and mvprintw() causes the fp emulation library to be
- X linked with PC-Moria, makes the program 10K bigger */
- X (void) sprintf(prntscrnbuf,"%c%s%c",CH(VE), map, CH(VE));
- X use_value2 mvaddstr(orow+1, 0, prntscrnbuf);
- X#endif
- X }
- X for (j = 0; j < MAX_WIDTH / RATIO; j++)
- X map[j] = ' ';
- X orow = row;
- X }
- X for (j = 0; j < MAX_WIDTH; j++)
- X {
- X col = j / RATIO;
- X tmp = loc_symbol(i, j);
- X if (priority[map[col]] < priority[tmp])
- X map[col] = tmp;
- X if (map[col] == '@')
- X {
- X mycol = col + 1; /* account for border */
- X myrow = row + 1;
- X }
- X }
- X }
- X if (orow >= 0)
- X {
- X#ifdef MAC
- X DSetScreenCursor(0, orow+1);
- X DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
- X DWriteScreenString(map);
- X DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
- X#else
- X (void) sprintf(prntscrnbuf,"%c%s%c",CH(VE), map, CH(VE));
- X use_value2 mvaddstr(orow+1, 0, prntscrnbuf);
- X#endif
- X }
- X#ifdef MAC
- X DSetScreenCursor(0, orow + 2);
- X DWriteScreenCharAttr(CH(BL), ATTR_NORMAL);
- X for (i = 0; i < MAX_WIDTH / RATIO; i++)
- X DWriteScreenCharAttr(CH(HE), ATTR_NORMAL);
- X DWriteScreenCharAttr(CH(BR), ATTR_NORMAL);
- X#else
- X use_value2 mvaddch(orow + 2, 0, CH(BL));
- X for (i = 0; i < MAX_WIDTH / RATIO; i++)
- X (void) addch(CH(HE));
- X (void) addch(CH(BR));
- X#endif
- X
- X#ifdef MAC
- X DSetScreenCursor(23, 23);
- X DWriteScreenStringAttr("Hit any key to continue", ATTR_NORMAL);
- X if (mycol > 0)
- X DSetScreenCursor(mycol, myrow);
- X#else
- X use_value2 mvaddstr(23, 23, "Hit any key to continue");
- X if (mycol > 0)
- X (void) move(myrow, mycol);
- X#endif
- X (void) inkey();
- X restore_screen();
- X}
- END_OF_FILE
- if test 29702 -ne `wc -c <'source/io.c'`; then
- echo shar: \"'source/io.c'\" unpacked with wrong size!
- fi
- # end of 'source/io.c'
- fi
- if test -f 'util/mc/creature.y' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/mc/creature.y'\"
- else
- echo shar: Extracting \"'util/mc/creature.y'\" \(26718 characters\)
- sed "s/^X//" >'util/mc/creature.y' <<'END_OF_FILE'
- X/*
- X * creature_comp.y
- X * a Moria creature definition compiler
- X *
- X * Copyright 1989 by Joseph Hall.
- X * All rights reserved except as stated below.
- X * This program may contain portions excerpted from Moria which are
- X * copyrighted by others.
- X *
- X * Jim Wilson and any other holders of copyright on substantial portions
- X * of Moria are granted rights to use, modify, and distribute this program
- X * as they see fit, so long as the terms of its use, modification and/or
- X * distribution are no less restrictive than those applying to Moria,
- X * version 5.0 or later, itself, and so long as this use is related to
- X * the further development of Moria.
- X *
- X * Anyone having any other use in mind for this code should contact the
- X * author at 4116 Brewster Dr., Raleigh NC 27606 (jnh@ecemwl.ncsu.edu).
- X */
- X
- X%{
- X#include <stdio.h>
- X#include <string.h>
- X#include <ctype.h>
- X#include <math.h>
- X
- X#ifdef ANSI_LIBS
- X#include <stdlib.h>
- X#else
- Xextern double atof();
- Xextern char *malloc();
- Xextern char *calloc();
- Xextern void free();
- X#endif
- X
- X#include "st.h"
- X
- X#ifndef TRUE
- X#define TRUE 1
- X#endif
- X
- X#ifndef FALSE
- X#define FALSE 0
- X#endif
- X
- X#define VERBOSE /* to turn on debugging output */
- X
- Xtypedef unsigned long int32u;
- Xtypedef long int32;
- Xtypedef unsigned short int16u;
- Xtypedef short int16;
- Xtypedef unsigned char int8u;
- X
- Xtypedef struct creature_type
- X{
- X char *name; /* Descrip of creature */
- X int32u cmove; /* Bit field */
- X int32u spells; /* Creature spells */
- X int16u cdefense; /* Bit field */
- X int16u mexp; /* Exp value for kill */
- X int8u sleep; /* Inactive counter/10 */
- X int8u aaf; /* Area affect radius */
- X int8u ac; /* AC */
- X int8u speed; /* Movement speed+10 */
- X int8u cchar; /* Character rep. */
- X int8u hd[2]; /* Creatures hit die */
- X int8u damage[4]; /* Type attack and damage*/
- X int8u level; /* Level of creature */
- X
- X int32u general; /* general characteristics; not present in usual */
- X /* moria creature_type */
- X} creature_type;
- X
- X
- X
- X/*
- X * defined_t is used to indicate whether all fields have been defined
- X */
- X
- Xtypedef struct {
- X unsigned move: 1,
- X special: 1,
- X treasure: 1,
- X spell: 1,
- X breath: 1,
- X defense: 1,
- X mexp: 1,
- X sleep: 1,
- X aaf: 1,
- X ac: 1,
- X speed: 1,
- X cchar: 1,
- X hd: 1,
- X damage: 1,
- X level: 1;
- X} defined_t;
- X
- X
- X
- X/*
- X * template_t contains creature definition & flags
- X */
- X
- Xtypedef struct {
- X creature_type val;
- X defined_t def;
- X} template_t;
- X
- X
- X
- X/*
- X * attack_t describes a monster attack
- X */
- X
- Xtypedef struct {
- X int8u type,
- X desc,
- X dice,
- X sides;
- X} attack_t;
- X
- X
- X
- X/*
- X * symInit_t is used to initialize symbol tables with integer values
- X */
- X
- Xtypedef struct {
- X char *name;
- X int32u val;
- X} symInit_t;
- X
- X
- X
- Xstatic symInit_t defenseInit[] = {
- X { "dragon", 0 },
- X { "animal", 1 },
- X { "evil", 2 },
- X { "undead", 3 },
- X { "frost", 4 },
- X { "fire", 5 },
- X { "poison", 6 },
- X { "acid", 7 },
- X { "light", 8 },
- X { "stone", 9 },
- X { "bit_9", 10 },
- X { "bit_10", 11 },
- X { "no_sleep", 12 },
- X { "infra", 13 },
- X { "max_hp", 14 },
- X { "bit_15", 15 },
- X { NULL, 0 }
- X};
- X
- Xstatic symInit_t moveInit[] = {
- X { "attack_only", 0 },
- X { "move_normal", 1 },
- X { "bit_2", 2 },
- X { "random_20", 3 },
- X { "random_40", 4 },
- X { "random_75", 5 },
- X { NULL, 0 }
- X};
- X
- Xstatic symInit_t specialInit[] = {
- X { "invisible", 16 },
- X { "open_door", 17 },
- X { "phase", 18 },
- X { "eats_other", 19 },
- X { "picks_up", 20 },
- X { "multiply", 21 },
- X { "win_creature", 31 },
- X { NULL, 0 }
- X};
- X
- Xstatic symInit_t treasureInit[] = {
- X { "carry_obj", 24 },
- X { "carry_gold", 25 },
- X { "has_random_60", 26 },
- X { "has_random_90", 27 },
- X { "has_1d2_obj", 28 },
- X { "has_2d2_obj", 29 },
- X { "has_4d2_obj", 30 },
- X { NULL, 0 }
- X};
- X
- Xstatic symInit_t spellInit[] = {
- X { "tel_short", 4 },
- X { "tel_long", 5 },
- X { "tel_to", 6 },
- X { "lght_wnd", 7 },
- X { "ser_wnd", 8 },
- X { "hold_per", 9 },
- X { "blind", 10 },
- X { "confuse", 11 },
- X { "fear", 12 },
- X { "summon_mon", 13 },
- X { "summon_und", 14 },
- X { "slow_per", 15 },
- X { "drain_mana", 16 },
- X { "bit_17", 17 },
- X { "bit_18", 18 },
- X { NULL, 0 }
- X};
- X
- Xstatic symInit_t breathInit[] = {
- X { "light", 19 },
- X { "gas", 20 },
- X { "acid", 21 },
- X { "frost", 22 },
- X { "fire", 23 },
- X { NULL, 0 }
- X};
- X
- Xstatic symInit_t attackTypeInit[] = {
- X { "normal_damage", 1 },
- X { "lose_str", 2 },
- X { "confusion", 3 },
- X { "cause_fear", 4 },
- X { "fire_damage", 5 },
- X { "acid_damage", 6 },
- X { "cold_damage", 7 },
- X { "lightning_damage", 8 },
- X { "corrosion", 9 },
- X { "cause_blindness", 10 },
- X { "cause_paralysis", 11 },
- X { "steal_money", 12 },
- X { "steal_obj", 13 },
- X { "poison", 14 },
- X { "lose_dex", 15 },
- X { "lose_con", 16 },
- X { "lose_int", 17 },
- X { "lose_wis", 18 },
- X { "lose_exp", 19 },
- X { "aggravation", 20 },
- X { "disenchant", 21 },
- X { "eat_food", 22 },
- X { "eat_light", 23 },
- X { "eat_charges", 24 },
- X { "blank", 99 },
- X { NULL, 0 }
- X};
- X
- Xstatic symInit_t attackDescInit[] = {
- X { "hits", 1 },
- X { "bites", 2 },
- X { "claws", 3 },
- X { "stings", 4 },
- X { "touches", 5 },
- X { "kicks", 6 },
- X { "gazes", 7 },
- X { "breathes", 8 },
- X { "spits", 9 },
- X { "wails", 10 },
- X { "embraces", 11 },
- X { "crawls_on", 12 },
- X { "releases_spores", 13 },
- X { "begs_for_money", 14 },
- X { "slimes", 15 },
- X { "crushes", 16 },
- X { "tramples", 17 },
- X { "drools_on", 18 },
- X { "insults", 19 },
- X { "is_repelled", 99 },
- X { NULL, 0 }
- X};
- X
- X
- X
- X
- X/*
- X * Maximum token length = maximum string constant length
- X * Also, trim the stack to an "acceptable" size.
- X */
- X
- X#define MAX_TOK_LEN 64 /* maximum acceptable token length */
- X#define YYSTACKSIZE 128
- X
- X#define GEN_TYPE_TMPL 256 /* type of a template for st */
- X
- X/*
- X * Globals used by the tokenizer (lexical analyzer)
- X */
- X
- X#define INPUT_BUF_SIZE 256
- Xstatic char inputBuf[INPUT_BUF_SIZE] = { 0 };
- X /* input line buffer */
- Xstatic char *inputBufp = inputBuf; /* position in input line buffer */
- Xstatic int lineNo = 0; /* number of current line */
- Xstatic FILE *input_F;
- Xstatic char tokStr[MAX_TOK_LEN]; /* text of current token */
- Xstatic int tokType; /* type of current token */
- Xstatic double tokVal; /* numeric value of current token, */
- X /* if applicable */
- X
- Xstatic template_t blankTemplate = { 0 }; /* blank template for init-ing */
- Xstatic template_t tmpTemplate; /* working template for current */
- X /* class or creature */
- X
- X#define MAX_ATTACK 250
- Xstatic attack_t attackList[MAX_ATTACK] = { 0 };
- Xstatic int attackCt = 1, creatureAttacks = 0;
- Xstatic int maxCreatureLevel = 0;
- X
- X/*
- X * Global symbol tables
- X */
- X
- Xstatic st_Table_Pt keywordT_P, /* parser's keywords */
- X defenseT_P, /* defense flags */
- X moveT_P, /* movement flags */
- X specialT_P, /* special flags */
- X treasureT_P, /* treasure flags */
- X spellT_P, /* spell flags */
- X breathT_P, /* breath flags */
- X attackTypeT_P, /* attack type flags */
- X attackDescT_P, /* attack desc flags */
- X classT_P, /* class templates */
- X creatureT_P; /* creature definitions */
- X
- X/*
- X * Function declarations
- X */
- X
- Xextern void AddDefense();
- Xextern void NegDefense();
- Xextern void AddMove();
- Xextern void NegMove();
- Xextern void AddTreasure();
- Xextern void NegTreasure();
- Xextern void AddSpecial();
- Xextern void NegSpecial();
- Xextern void AddSpell();
- Xextern void NegSpell();
- Xextern void AddBreath();
- Xextern void NegBreath();
- Xextern void AddAttack();
- Xextern void WriteCreature();
- Xextern void PutClassTemplate();
- Xextern template_t GetClassTemplate();
- Xextern void PutCreature();
- X
- X%}
- X
- X
- X/*
- X * YACC DEFINITIONS
- X */
- X
- X/*
- X * The parser's stack can hold ints, doubles, and strings.
- X */
- X
- X%union {
- X int ival;
- X double dval;
- X char sval[MAX_TOK_LEN];
- X }
- X
- X/*
- X * Reserved words
- X */
- X
- X%token CLASS CREATURE NAMED HD D MOVE SPELL BREATH DEFENSE XP CCHAR SLEEP
- X%token RADIUS SPEED ATTACK FOR AC LEVEL TREASURE SPECIAL OF IN
- X
- X/*
- X * Entities
- X */
- X
- X%token <sval> IDENTIFIER /* identifier, not a keyword */
- X%token <dval> FLOAT_LIT /* floating-pt literal */
- X%token <ival> INT_LIT /* integer literal */
- X%token <sval> STRING_LIT /* string literal */
- X%token <ival> BOOL_LIT /* boolean literal */
- X
- X/*
- X * ASCII chars are their own tokens
- X */
- X
- X%start creatures
- X
- X
- X/*
- X * THE PARSER
- X */
- X
- X%%
- X
- Xcreatures : class_def ';' creatures
- X | creature_def ';' creatures
- X | /* empty */
- X ;
- X
- Xclass_def : CLASS IDENTIFIER parent_class '{' features '}'
- X { PutClassTemplate($<sval>2, &tmpTemplate); }
- X ;
- X
- Xparent_class : ':' IDENTIFIER
- X { tmpTemplate = GetClassTemplate($<sval>2);
- X creatureAttacks = 0; }
- X | /* empty */
- X { tmpTemplate = blankTemplate;
- X creatureAttacks = 0; }
- X ;
- X
- Xcreature_def : CREATURE STRING_LIT parent_class
- X '{' features '}'
- X { tmpTemplate.val.name =
- X (char *) malloc(strlen($<sval>2) + 1);
- X strcpy(tmpTemplate.val.name, $<sval>2);
- X PutCreature($<sval>2, &tmpTemplate);
- X }
- X ;
- X
- Xfeatures : feature ';' features
- X | /* empty */
- X ;
- X
- Xfeature : LEVEL ':' INT_LIT
- X { tmpTemplate.val.level = $<ival>3;
- X tmpTemplate.def.level = TRUE; }
- X | HD ':' INT_LIT D INT_LIT
- X { tmpTemplate.val.hd[0] = $<ival>3;
- X tmpTemplate.val.hd[1] = $<ival>5;
- X tmpTemplate.def.hd = TRUE; }
- X | XP ':' INT_LIT
- X { tmpTemplate.val.mexp = $<ival>3;
- X tmpTemplate.def.mexp = TRUE; }
- X | CCHAR ':' STRING_LIT
- X { tmpTemplate.val.cchar = $<sval>3[0];
- X tmpTemplate.def.cchar = TRUE; }
- X | AC ':' INT_LIT
- X { tmpTemplate.val.ac = $<ival>3;
- X tmpTemplate.def.ac = TRUE; }
- X | SLEEP ':' INT_LIT
- X { tmpTemplate.val.sleep = $<ival>3;
- X tmpTemplate.def.sleep = TRUE; }
- X | RADIUS ':' INT_LIT
- X { tmpTemplate.val.aaf = $<ival>3;
- X tmpTemplate.def.aaf = TRUE; }
- X | SPEED ':' INT_LIT
- X { tmpTemplate.val.speed = $<ival>3 + 10;
- X tmpTemplate.def.speed = TRUE; }
- X | ATTACK ':' attacks
- X | MOVE ':' moves
- X | SPELL ':' spells
- X | SPELL INT_LIT '%' ':' spells
- X { float chance = 100.0 / $<ival>2;
- X if (chance > 15.0)
- X chance = 0.0;
- X if (chance < 0.0)
- X chance = 0.0;
- X tmpTemplate.val.spells &= ~0xf;
- X tmpTemplate.val.spells |=
- X (int) ceil(chance);
- X tmpTemplate.def.spell = TRUE; }
- X | BREATH ':' breaths
- X | BREATH INT_LIT '%' ':' breaths
- X { float chance = 100.0 / $<ival>2;
- X if (chance > 15.0)
- X chance = 0.0;
- X if (chance < 0.0)
- X chance = 0.0;
- X tmpTemplate.val.spells &= ~0xf;
- X tmpTemplate.val.spells |=
- X (int) ceil(chance);
- X tmpTemplate.def.spell = TRUE; }
- X | DEFENSE ':' defenses
- X | TREASURE ':' carries
- X | SPECIAL ':' specials
- X ;
- X
- Xattacks : attack more_attacks
- X ;
- X
- Xattack : IDENTIFIER FOR INT_LIT D INT_LIT OF IDENTIFIER
- X { AddAttack($<sval>1, $<ival>3,
- X $<ival>5, $<sval>7); }
- X ;
- X
- Xmore_attacks : ',' attack more_attacks
- X | /* empty */
- X ;
- X
- Xmoves : move more_moves
- X ;
- X
- Xmove : IDENTIFIER { AddMove($<sval>1); }
- X | '~' IDENTIFIER { NegMove($<sval>2); }
- X ;
- X
- Xmore_moves : ',' move more_moves
- X | /* empty */
- X ;
- X
- Xspells : spell more_spells
- X | /* empty */
- X ;
- X
- Xspell : IDENTIFIER { AddSpell($<sval>1); }
- X | '~' IDENTIFIER { NegSpell($<sval>2); }
- X ;
- X
- Xmore_spells : ',' spell more_spells
- X | /* empty */
- X ;
- X
- Xbreaths : breath more_breaths
- X ;
- X
- Xbreath : IDENTIFIER { AddBreath($<sval>1); }
- X | '~' IDENTIFIER { NegBreath($<sval>2); }
- X ;
- X
- Xmore_breaths : ',' breath more_breaths
- X | /* empty */
- X ;
- X
- Xdefenses : defense more_defenses
- X ;
- X
- Xdefense : IDENTIFIER { AddDefense($<sval>1); }
- X | '~' IDENTIFIER { NegDefense($<sval>2); }
- X ;
- X
- Xmore_defenses : ',' defense more_defenses
- X | /* empty */
- X ;
- X
- Xcarries : carry more_carries
- X ;
- X
- Xcarry : IDENTIFIER { AddTreasure($<sval>1); }
- X | '~' IDENTIFIER { NegTreasure($<sval>2); }
- X ;
- X
- Xmore_carries : ',' carry more_carries
- X | /* empty */
- X ;
- X
- Xspecials : special more_specials
- X ;
- X
- Xspecial : IDENTIFIER { AddSpecial($<sval>1); }
- X | '~' IDENTIFIER { NegSpecial($<sval>2); }
- X ;
- X
- Xmore_specials : ',' special more_specials
- X | /* empty */
- X ;
- X
- X
- X%%
- X
- Xstatic symInit_t keywordInit[] = {
- X { "class", CLASS },
- X { "creature", CREATURE },
- X { "named", NAMED },
- X { "hd", HD },
- X { "d", D },
- X { "move", MOVE },
- X { "spell", SPELL },
- X { "breath", BREATH },
- X { "defense", DEFENSE },
- X { "xp", XP },
- X { "cchar", CCHAR },
- X { "sleep", SLEEP },
- X { "radius", RADIUS },
- X { "speed", SPEED },
- X { "attack", ATTACK },
- X { "for", FOR },
- X { "ac", AC },
- X { "level", LEVEL },
- X { "treasure", TREASURE },
- X { "special", SPECIAL },
- X { "of", OF },
- X { "in", IN },
- X { NULL, 0 }
- X};
- X
- X
- X
- X/*
- X * MyFGetC--
- X * fgetc with support for comments
- X *
- X * # is the comment character. comment lasts till end of line.
- X * Spews out an extra char of whitespace at EOF since something seems to
- X * need it. I'll figure this out eventually...
- X */
- Xstatic int MyFGetC(input_F)
- XFILE *input_F;
- X{
- X static int atEof = FALSE;
- X while (!*inputBufp || (*inputBufp == '#')) {
- X fgets(inputBuf, INPUT_BUF_SIZE, input_F);
- X if (feof(input_F))
- X return EOF;
- X lineNo++;
- X inputBufp = inputBuf;
- X }
- X return *inputBufp++;
- X}
- X
- X
- X
- X/*
- X * Advance--
- X * Advance to the next token in the input stream and set tokStr,
- X * tokType, tokVal as appropriate.
- X *
- X * On error, tokType is set to a negative value.
- X */
- Xstatic void Advance(input_F)
- XFILE *input_F;
- X{
- X
- X register char
- X *tok = tokStr; /* accumulating token string */
- X register int
- X len = 0; /* length of current token */
- X static int c = 32; /* current character; ' ' is harmless init */
- X
- X
- X /*
- X * Skip whitespace in the stream
- X */
- X while ((c != EOF) && isspace(c))
- X c = MyFGetC(input_F);
- X
- X /*
- X * At end of file?
- X */
- X if (c == EOF) {
- X tokType = EOF;
- X strcpy(tokStr, "[EOF]");
- X return;
- X }
- X
- X /*
- X * Recognize a number [+|-][dddd][.][dddd][{e|E}[+|-]dddd]
- X */
- X if (isdigit(c) || (c == '.') || (c == '+') || (c == '-')) {
- X
- X register int
- X decPt = FALSE, /* seen a decimal point yet? */
- X hasExp = FALSE; /* has an exponent? */
- X
- X if ((c == '-') || (c == '+')) {
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X }
- X
- X while ((len < MAX_TOK_LEN - 1) && (isdigit(c) || (c == '.'))) {
- X if (c == '.') {
- X if (decPt)
- X break;
- X else
- X decPt = TRUE;
- X }
- X
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X len++;
- X }
- X
- X if ((c == 'e') || (c == 'E')) {
- X hasExp = TRUE;
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X len++;
- X
- X if ((c == '-') || (c == '+')) {
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X len++;
- X }
- X
- X while ((len < MAX_TOK_LEN - 1) && isdigit(c)) {
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X len++;
- X }
- X }
- X
- X *tok = 0;
- X
- X if (decPt || hasExp) {
- X tokType = FLOAT_LIT;
- X yylval.dval = atof(tokStr);
- X } else {
- X tokType = INT_LIT;
- X yylval.ival = atoi(tokStr);
- X }
- X
- X return;
- X
- X }
- X
- X /*
- X * Recognize a quoted string
- X */
- X if (c == '\"') {
- X
- X c = MyFGetC(input_F);
- X
- X while ((len < MAX_TOK_LEN - 1) &&
- X (c != EOF) && (c != '\n') && (c != '\"')) {
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X }
- X
- X *tok = 0;
- X
- X c = MyFGetC(input_F);
- X
- X tokType = STRING_LIT;
- X strncpy(yylval.sval, tokStr, MAX_TOK_LEN - 1);
- X yylval.sval[MAX_TOK_LEN - 1] = 0;
- X
- X return;
- X
- X }
- X
- X /*
- X * Recognize an identifier and try to match it with a keyword.
- X * Identifiers begin with a letter and continue in letters and/or
- X * digits. Convert it to lowercase.
- X */
- X if (isalpha(c) || (c == '_') || (c == '$')) {
- X
- X if (isupper(c))
- X c = tolower(c);
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X len++;
- X
- X while ((len < MAX_TOK_LEN - 1) && (isalpha(c) || isdigit(c) ||
- X (c == '_') || (c == '$'))) {
- X if (isupper(c))
- X c = tolower(c);
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X len++;
- X }
- X
- X *tok = 0;
- X
- X /*
- X * We've got the identifier; see if it matches any keywords.
- X */
- X
- X {
- X generic_t gval;
- X int type;
- X if (St_GetSym(keywordT_P, tokStr, &type, &gval) ==
- X ST_SYM_FOUND) {
- X tokType = gval.i;
- X strncpy(yylval.sval, tokStr, MAX_TOK_LEN - 1);
- X yylval.sval[MAX_TOK_LEN - 1] = 0;
- X } else if (!strcmp(tokStr, "true")) {
- X tokType = BOOL_LIT;
- X yylval.ival = 1;
- X } else if (!strcmp(tokStr, "false")) {
- X tokType = BOOL_LIT;
- X yylval.ival = 0;
- X } else {
- X tokType = IDENTIFIER;
- X strncpy(yylval.sval, tokStr, MAX_TOK_LEN - 1);
- X yylval.sval[MAX_TOK_LEN - 1] = 0;
- X }
- X }
- X
- X return;
- X
- X }
- X
- X /*
- X * Recognize punctuation
- X */
- X
- X tokType = c;
- X *tok++ = c;
- X *tok = 0;
- X c = MyFGetC(input_F);
- X return;
- X
- X}
- X
- Xvoid ErrMsg(s)
- Xchar *s;
- X{
- X int i;
- X
- X fprintf(stderr, "Error: %s at line %d\n", s, lineNo);
- X fprintf(stderr, "%s", inputBuf);
- X for (i = 0; i < inputBufp - inputBuf; i++) {
- X fputc((inputBuf[i] == '\t' ? '\t' : ' '), stderr);
- X }
- X fprintf(stderr, "^ before here\n\n");
- X}
- X
- Xint yyerror(s)
- Xchar *s;
- X{
- X ErrMsg(s);
- X}
- X
- X
- Xint yylex()
- X{
- X Advance(input_F);
- X return(tokType);
- X}
- X
- Xvoid AddSpell(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(spellT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown spell '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.spells |= (1 << gval.i);
- X tmpTemplate.def.spell = TRUE;
- X }
- X}
- X
- X
- Xvoid NegSpell(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(spellT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown spell '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.spells &= ~(1 << gval.i);
- X tmpTemplate.def.spell = TRUE;
- X }
- X}
- X
- X
- Xvoid AddBreath(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(breathT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown breath '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.spells |= (1 << gval.i);
- X tmpTemplate.def.breath = TRUE;
- X }
- X}
- X
- X
- Xvoid NegBreath(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(breathT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown breath '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.spells &= ~(1 << gval.i);
- X tmpTemplate.def.breath = TRUE;
- X }
- X}
- X
- X
- Xvoid AddSpecial(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(specialT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown special '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cmove |= (1 << gval.i);
- X tmpTemplate.def.special = TRUE;
- X }
- X}
- X
- X
- Xvoid NegSpecial(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(specialT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown special '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cmove &= ~(1 << gval.i);
- X tmpTemplate.def.special = TRUE;
- X }
- X}
- X
- X
- Xvoid AddMove(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(moveT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown move '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cmove |= (1 << gval.i);
- X tmpTemplate.def.move = TRUE;
- X }
- X}
- X
- X
- Xvoid NegMove(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(moveT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown move '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cmove &= ~(1 << gval.i);
- X tmpTemplate.def.move = TRUE;
- X }
- X}
- X
- X
- Xvoid AddTreasure(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(treasureT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown treasure '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cmove |= (1 << gval.i);
- X tmpTemplate.def.treasure = TRUE;
- X }
- X}
- X
- X
- Xvoid NegTreasure(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(treasureT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown treasure '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cmove &= ~(1 << gval.i);
- X tmpTemplate.def.treasure = TRUE;
- X }
- X}
- X
- X
- Xvoid AddDefense(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(defenseT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown defense '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cdefense |= (1 << gval.i);
- X tmpTemplate.def.defense = TRUE;
- X }
- X}
- X
- X
- Xvoid NegDefense(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(defenseT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown defense '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cdefense &= ~(1 << gval.i);
- X tmpTemplate.def.defense = TRUE;
- X }
- X}
- X
- X
- Xint PutAttack(attack)
- Xattack_t attack;
- X{
- X register int i;
- X
- X for (i = 0; i < attackCt; i++) {
- X if ((attack.type == attackList[i].type) &&
- X (attack.desc == attackList[i].desc) &&
- X (attack.dice == attackList[i].dice) &&
- X (attack.sides == attackList[i].sides)) {
- X return(i);
- X }
- X }
- X
- X if (attackCt == MAX_ATTACK) {
- X fprintf(stderr, "fatal error: too many different attacks.\n");
- X fprintf(stderr, "increase MAX_ATTACK.\n");
- X exit(1);
- X }
- X
- X attackList[attackCt].type = attack.type;
- X attackList[attackCt].desc = attack.desc;
- X attackList[attackCt].dice = attack.dice;
- X attackList[attackCt].sides = attack.sides;
- X
- X return attackCt++;
- X}
- X
- Xvoid AddAttack(s1, dice, sides, s2)
- Xchar *s1, *s2;
- Xint dice, sides;
- X{
- X generic_t gval;
- X int type, aDesc;
- X attack_t attack;
- X char s[256];
- X
- X if (St_GetSym(attackDescT_P, s1, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s, "unknown attack description '%s'", s1);
- X ErrMsg(s);
- X return;
- X } else {
- X aDesc = gval.i;
- X }
- X
- X if (St_GetSym(attackTypeT_P, s2, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s, "unknown attack type '%s'", s2);
- X ErrMsg(s);
- X } else {
- X if (creatureAttacks > 3) {
- X sprintf(s, "creature limited to 4 attacks");
- X ErrMsg(s);
- X return;
- X }
- X attack.type = gval.i;
- X attack.dice = dice;
- X attack.desc = aDesc;
- X attack.sides = sides;
- X tmpTemplate.val.damage[creatureAttacks++] =
- X PutAttack(attack);
- X tmpTemplate.def.damage = TRUE;
- X }
- X}
- X
- Xst_Table_Pt InitTable(name, init)
- Xchar *name;
- XsymInit_t *init;
- X{
- X int i;
- X st_Table_Pt table_P;
- X generic_t gval;
- X
- X table_P = St_NewTable(name, 20);
- X for (i = 0; init[i].name; i++) {
- X gval.i = init[i].val;
- X St_DefSym(table_P, init[i].name, GEN_TYPE_INT, gval);
- X }
- X
- X return table_P;
- X}
- X
- X
- Xvoid InitTables()
- X{
- X int i;
- X generic_t gval;
- X
- X keywordT_P = InitTable("keyword", keywordInit);
- X defenseT_P = InitTable("defense", defenseInit);
- X spellT_P = InitTable("spell", spellInit);
- X moveT_P = InitTable("move", moveInit);
- X specialT_P = InitTable("special", specialInit);
- X breathT_P = InitTable("breath", breathInit);
- X treasureT_P = InitTable("treasure", treasureInit);
- X attackTypeT_P = InitTable("attackType", attackTypeInit);
- X attackDescT_P = InitTable("attackDesc", attackDescInit);
- X
- X classT_P = St_NewTable("class", 40);
- X creatureT_P = St_NewTable("creature", 200);
- X}
- X
- Xvoid WriteCreature(tmpl_P)
- Xtemplate_t *tmpl_P;
- X{
- X char s[256];
- X strcpy(s, "\"");
- X strcat(s, tmpl_P->val.name);
- X strcat(s, "\"");
- X printf("{%-28s, 0x%08x,0x%06x,0x%04x,%5d,%3d,\n",
- X s, tmpl_P->val.cmove, tmpl_P->val.spells,
- X tmpl_P->val.cdefense, tmpl_P->val.mexp, tmpl_P->val.sleep);
- X printf(" %2d, %3d, %2d, '%c', {%3d,%2d}, {%3d,%3d,%3d,%3d}, %3d},\n",
- X tmpl_P->val.aaf, tmpl_P->val.ac, tmpl_P->val.speed,
- X tmpl_P->val.cchar,
- X tmpl_P->val.hd[0], tmpl_P->val.hd[1],
- X tmpl_P->val.damage[0], tmpl_P->val.damage[1],
- X tmpl_P->val.damage[2], tmpl_P->val.damage[3],
- X tmpl_P->val.level);
- X}
- X
- Xvoid WriteCreatures()
- X{
- X char **s_A, **sp;
- X int level, type;
- X generic_t gval;
- X
- X s_A = St_SListTable(creatureT_P);
- X
- X printf("creature_type c_list[MAX_CREATURES] = {\n");
- X
- X for (level = 0; level <= maxCreatureLevel; level++) {
- X for (sp = s_A; *sp; sp++) {
- X if (St_GetSym(creatureT_P, *sp, &type, &gval) !=
- X ST_SYM_FOUND) {
- X fprintf(stderr, "internal err. in WriteCreatures\n");
- X exit(1);
- X }
- X if ((*(template_t *) gval.v).val.level == level) {
- X WriteCreature((template_t *) gval.v);
- X }
- X }
- X }
- X
- X printf("};\n\n");
- X
- X St_SListTable(NULL);
- X}
- X
- Xvoid PutClassTemplate(s, tmpl_P)
- Xchar *s;
- Xtemplate_t *tmpl_P;
- X{
- X generic_t gval;
- X char s1[256];
- X
- X gval.v = malloc(sizeof(template_t));
- X *(template_t *) gval.v = *tmpl_P;
- X
- X if (St_DefSym(classT_P, s, GEN_TYPE_TMPL, gval) == ST_SYM_FOUND) {
- X sprintf(s1, "attempt to redefine class '%s'", s);
- X ErrMsg(s1);
- X free(gval.v);
- X return;
- X }
- X}
- X
- X
- Xtemplate_t GetClassTemplate(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(classT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "class '%s' undefined\n", s);
- X ErrMsg(s1);
- X return blankTemplate;
- X } else {
- X return *(template_t *) gval.v;
- X }
- X}
- X
- X
- X
- X
- Xvoid NotDefined(name, s)
- Xchar *name, *s;
- X{
- X printf("Warning: %s not defined for \"%s\", line %d\n",
- X s, name, lineNo);
- X}
- X
- X
- Xvoid PutCreature(s, tmpl_P)
- Xchar *s;
- Xtemplate_t *tmpl_P;
- X{
- X generic_t gval;
- X char s1[256];
- X
- X gval.v = malloc(sizeof(template_t));
- X *(template_t *) gval.v = *tmpl_P;
- X
- X if (!tmpl_P->def.move)
- X NotDefined(tmpl_P->val.name, "MOVE");
- X if (!tmpl_P->def.treasure)
- X NotDefined(tmpl_P->val.name, "TREASURE");
- X if (!tmpl_P->def.defense)
- X NotDefined(tmpl_P->val.name, "DEFENSE");
- X if (!tmpl_P->def.mexp)
- X NotDefined(tmpl_P->val.name, "XP");
- X if (!tmpl_P->def.sleep)
- X NotDefined(tmpl_P->val.name, "SLEEP");
- X if (!tmpl_P->def.aaf)
- X NotDefined(tmpl_P->val.name, "RADIUS");
- X if (!tmpl_P->def.ac)
- X NotDefined(tmpl_P->val.name, "AC");
- X if (!tmpl_P->def.speed)
- X NotDefined(tmpl_P->val.name, "SPEED");
- X if (!tmpl_P->def.cchar)
- X NotDefined(tmpl_P->val.name, "CCHAR");
- X if (!tmpl_P->def.hd)
- X NotDefined(tmpl_P->val.name, "HD");
- X if (!tmpl_P->def.damage)
- X NotDefined(tmpl_P->val.name, "ATTACK");
- X if (!tmpl_P->def.level)
- X NotDefined(tmpl_P->val.name, "LEVEL");
- X
- X if (St_DefSym(creatureT_P, s, GEN_TYPE_TMPL, gval) == ST_SYM_FOUND) {
- X sprintf(s1, "attempt to redefine creature '%s'\n", s);
- X ErrMsg(s1);
- X free(gval.v);
- X return;
- X }
- X
- X if (tmpl_P->val.level > maxCreatureLevel)
- X maxCreatureLevel = tmpl_P->val.level;
- X
- X}
- X
- Xvoid WriteAttacks()
- X{
- X int i;
- X
- X printf("struct m_attack_type monster_attacks[N_MONS_ATTS] = {\n");
- X for (i = 0; i < attackCt; i++) {
- X printf("/* %3d */ { %2d, %2d, %2d, %2d },\n",
- X i, attackList[i].type, attackList[i].desc,
- X attackList[i].dice, attackList[i].sides);
- X };
- X printf("};\n");
- X}
- X
- Xvoid WriteConstants()
- X{
- X printf("/* These values should match the values defined in constant.h. */");
- X printf("\n#define MAX_CREATURES\t%d\n", St_TableSize(creatureT_P));
- X printf("#define N_MON_ATTS\t%d\n\n", attackCt);
- X}
- X
- Xvoid WriteMonsterHdr()
- X{
- X printf("/* The following code belongs in the file monster.c. */\n\n");
- X printf("/* The following data was generated by the program in util/mc. */\n\n");
- X}
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X char inputFilename[256];
- X
- X InitTables();
- X
- X if (argc > 1) {
- X strncpy(inputFilename, argv[1], 255);
- X inputFilename[255] = 0;
- X } else {
- X fprintf(stderr, "input file: ");
- X scanf("%255s", inputFilename);
- X }
- X
- X input_F = fopen(inputFilename, "r");
- X if (!input_F) {
- X printf("Error: couldn't open file.\n");
- X exit(1);
- X }
- X
- X if (yyparse()) {
- X printf("Errors prevent continuation.\n");
- X exit(1);
- X }
- X
- X WriteConstants();
- X WriteMonsterHdr();
- X WriteCreatures();
- X WriteAttacks();
- X}
- END_OF_FILE
- if test 26718 -ne `wc -c <'util/mc/creature.y'`; then
- echo shar: \"'util/mc/creature.y'\" unpacked with wrong size!
- fi
- # end of 'util/mc/creature.y'
- fi
- echo shar: End of archive 20 \(of 31\).
- cp /dev/null ark20isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 31 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-