[comp.sources.games] v12i056: larn2 - dungeon type adventure game

billr@saab.CNA.TEK.COM (Bill Randle) (04/24/91)

Submitted-by: routley@tle.ENET.DEC.COM (Kevin Routley)
Posting-number: Volume 12, Issue 56
Archive-name: larn2/Part03
Supersedes: larn: Volume 11, Issue 84-94
Environment: Unix, VMS, MS-DOS, OS/2, termcap



#! /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 3 (of 12)."
# Contents:  io.c moreobj.c patchlev.h
# Wrapped by billr@saab on Tue Apr 23 13:50:28 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'io.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'io.c'\"
else
echo shar: Extracting \"'io.c'\" \(32203 characters\)
sed "s/^X//" >'io.c' <<'END_OF_FILE'
X/* io.c
X *
X *  setupvt100()    Subroutine to set up terminal in correct mode for game
X *  clearvt100()    Subroutine to clean up terminal when the game is over
X *  ttgetch()       Routine to read in one character from the terminal
X *  scbr()          Function to set cbreak -echo for the terminal
X *  sncbr()         Function to set -cbreak echo for the terminal
X *  newgame()       Subroutine to save the initial time and seed rnd()
X *
X *  FILE OUTPUT ROUTINES
X *
X *  lprintf(format,args . . .)  printf to the output buffer
X *  lprint(integer)         send binary integer to output buffer
X *  lwrite(buf,len)         write a buffer to the output buffer
X *  lprcat(str)         sent string to output buffer
X *
X *  FILE OUTPUT MACROS (in header.h)
X *
X *  lprc(character)         put the character into the output buffer
X *
X *  FILE INPUT ROUTINES
X *
X *  long lgetc()            read one character from input buffer
X *  long lrint()            read one integer from input buffer
X *  lrfill(address,number)      put input bytes into a buffer
X *  char *lgetw()           get a whitespace ended word from input
X *  char *lgetl()           get a \n or EOF ended line from input
X *
X *  FILE OPEN / CLOSE ROUTINES
X *
X *  lcreat(filename)        create a new file for write
X *  lopen(filename)         open a file for read
X *  lappend(filename)       open for append to an existing file
X *  lrclose()           close the input file
X *  lwclose()           close output file
X *  lflush()            flush the output buffer
X *
X *  Other Routines
X *
X *  cursor(x,y)     position cursor at [x,y]
X *  cursors()       position cursor at [1,24] (saves memory)
X *  cl_line(x,y)            Clear line at [1,y] and leave cursor at [x,y]
X *  cl_up(x,y)          Clear screen from [x,1] to current line.
X *  cl_dn(x,y)      Clear screen from [1,y] to end of display. 
X *  standout(str)       Print the string in standout mode.
X *  set_score_output()  Called when output should be literally printed.
X ** ttputch(ch)     Print one character in decoded output buffer.
X ** flush_buf()     Flush buffer with decoded output.
X ** init_term()     Terminal initialization -- setup termcap info
X ** char *tmcapcnv(sd,ss)   Routine to convert VT100 \33's to termcap format
X *  beep()          Routine to emit a beep if enabled (see no-beep in .larnopts)
X *
X * Note: ** entries are available only in termcap mode.
X */
X
X#include "header.h"
X#include "larndefs.h"
X#include <ctype.h>
X
X#ifdef SYSV /* system III or system V */
X# ifndef MSDOS
X#   include <termio.h>
X# endif
X#define sgttyb termio
X#define stty(_a,_b) ioctl(_a,TCSETA,_b)
X#define gtty(_a,_b) ioctl(_a,TCGETA,_b)
X#ifndef MSDOS
Xstatic int rawflg = 0;
Xstatic char saveeof,saveeol;
X#define doraw(_a) if(!rawflg){++rawflg;saveeof=_a.c_cc[VMIN];saveeol=_a.c_cc[VTIME];}\
X    _a.c_cc[VMIN]=1;_a.c_cc[VTIME]=1;_a.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL)
X#define unraw(_a) _a.c_cc[VMIN]=saveeof;_a.c_cc[VTIME]=saveeol;_a.c_lflag |= ICANON|ECHO|ECHOE|ECHOK|ECHONL
X#endif
X#else not SYSV
X#ifdef VMS
X#include    <descrip.h>
X#include    <ssdef.h>
X#include    <stsdef.h>
X#include    <iodef.h>
X#include    <ttdef.h>
X#include    <tt2def.h>
X#else VMS
X#ifndef BSD
X#define CBREAK RAW      /* V7 has no CBREAK */
X#endif
X#define doraw(_a) (_a.sg_flags |= CBREAK,_a.sg_flags &= ~ECHO)
X#define unraw(_a) (_a.sg_flags &= ~CBREAK,_a.sg_flags |= ECHO)
X#include <sgtty.h>
X#endif not SYSV
X#endif VMS
X
X#ifndef NOVARARGS   /* if we have varargs */
X#include <varargs.h>
X#else NOVARARGS /* if we don't have varargs */
Xtypedef char *va_list;
X#define va_dcl int va_alist;
X#define va_start(plist) plist = (char *) &va_alist
X#define va_end(plist)
X#define va_arg(plist,mode) ((mode *)(plist += sizeof(mode)))[-1]
X#endif NOVARARGS
X
X#define LINBUFSIZE 128      /* size of the lgetw() and lgetl() buffer       */
Xint lfd;            /*  output file numbers     */
Xint fd;             /*  input file numbers      */
X# ifndef MSDOS
X# ifndef VMS
Xstatic struct sgttyb ttx;   /* storage for the tty modes                    */
X# else
Xint iochan;         /* storage for the tty channel  */
Xint ttx[3];         /* storage for the tty modes    */
Xint cbflag;         /* cbreak flag.  Set when SCBRd */
X# endif
X# endif
Xstatic int ipoint=MAXIBUF,iepoint=MAXIBUF;  /*  input buffering pointers    */
Xstatic char lgetwbuf[LINBUFSIZE];   /* get line (word) buffer               */
X
X#ifdef MSDOS
X# include <setjmp.h>
X extern jmp_buf save_jbuf;
X extern int save_mode;
X#endif
X
X# ifdef MSDOS
X# include <fcntl.h>     /* For O_BINARY */
Xstatic int (*getchfn)();
Xint getche(), kgetch();
X# endif
X
X/*
X *  setupvt100()        Subroutine to set up terminal in correct mode for game
X *
X *  Attributes off, clear screen, set scrolling region, set tty mode 
X */
Xsetupvt100()
X    {
X#ifdef VMS
X    struct  dsc$descriptor  idsc;
X    register int        status;
X
X    idsc.dsc$a_pointer = "SYS$COMMAND";
X    idsc.dsc$w_length  = strlen(idsc.dsc$a_pointer);
X    idsc.dsc$b_dtype   = DSC$K_DTYPE_T;
X    idsc.dsc$b_class   = DSC$K_CLASS_S;
X    status = SYS$ASSIGN(&idsc, &iochan, 0, 0);
X    if (status&STS$M_SUCCESS == 0)
X        exit(status);
X#endif
X    lprc(T_INIT);
X    clear();  setscroll();  scbr(); /* system("stty cbreak -echo"); */
X# ifdef MSDOS
X    setraw();
X    setcursor();
X
X    /* Select normal ASCII and line drawing character sets.
X     */
X    if (DECRainbow)
X        lprcat("\033(B\033)0");
X# endif
X    }
X
X/*
X *  clearvt100()        Subroutine to clean up terminal when the game is over
X *
X *  Attributes off, clear screen, unset scrolling region, restore tty mode 
X */
Xclearvt100()
X    {
X    lprc(T_END);
X    resetscroll();  clear();  sncbr(); /* system("stty -cbreak echo"); */
X# ifdef MSDOS
X    unsetraw();
X    resetcursor();
X# endif
X#ifdef VMS
X    SYS$DASSGN(iochan);
X#endif
X    }
X
X/*
X *  ttgetch()       Routine to read in one character from the terminal
X */
X
X#ifdef VMS
X
Xttgetch()
X{
X#define NIBUF   80      /* characters in the buffer.    */
X    static char ibuf[NIBUF];
X    static int  ibufi = 0;
X    static int  nibuf = 0;
X    int status;
X    int iosb[2];
X    int term[2];
X
X    lflush();       /* be sure output buffer is flushed */
X    term[0] = 0;
X    term[1] = 0;
X    while (ibufi >= nibuf) {
X        if (cbflag) {
X        /* cbroken */
X            ibufi   = 0;
X/*
X            status = SYS$QIOW(0, iochan, IO$_READLBLK|IO$M_TIMED,
X                 iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
X*/
X            status = SYS$QIOW(0, iochan, IO$_READLBLK,
X                 iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
X        if (status != SS$_NORMAL)
X            continue;
X        status = iosb[0] & 0xFFFF;
X        if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
X            continue;
X        nibuf = (iosb[0]>>16) + (iosb[1]>>16);
X        if (nibuf == 0) 
X        {
X        status = SYS$QIOW(0, iochan, IO$_READLBLK,
X            iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
X        if (status != SS$_NORMAL)
X            continue;
X        if ((iosb[0]&0xFFFF) != SS$_NORMAL)
X            continue;
X        nibuf = (iosb[0]>>16) + (iosb[1]>>16);
X        }
X        } else {
X        /* not cbroken */
X        try_again:
X            ibufi    = 0;
X            status   = SYS$QIOW(0, iochan, IO$_READLBLK, iosb,
X                    0, 0, ibuf, NIBUF, 0, 0, 0, 0);
X            if (status != SS$_NORMAL)
X                goto try_again;
X            if ((iosb[0]&0xFFFF) != SS$_NORMAL)
X                goto try_again;
X            nibuf = (iosb[0]>>16) + (iosb[1]>>16);
X        }
X    }
X    if ((ibuf[ibufi]&0xFF) == '\r')     /* carriage return */
X        ibuf[ibufi] = '\n';     /* turns to newline */
X    return (ibuf[ibufi++]&0xFF);
X}
X#else VMS
X
Xttgetch()
X    {
X    char byt;
X#ifdef EXTRA
X    c[BYTESIN]++;
X#endif EXTRA
X    lflush();       /* be sure output buffer is flushed */
X# ifdef MSDOS
X    if ((byt = (*getchfn)()) == '\r')
X        byt = '\n';
X    return byt;
X# else MSDOS
X    read(0,&byt,1);     /* get byte from terminal */
X    return(byt);
X# endif MSDOS
X    }
X# endif VMS
X
X/*
X *  scbr()      Function to set cbreak -echo for the terminal
X *
X *  like: system("stty cbreak -echo")
X */
Xscbr()
X    {
X# ifdef MSDOS
X    /* Set up to use the direct console input call which may
X     * read from the keypad;
X     */
X    getchfn = kgetch;
X# else
X# ifdef VMS
X    int status;
X    int iosb[2];
X
X    cbflag = 1;
X    status = SYS$QIOW(0, iochan, IO$_SENSEMODE, iosb, 0, 0,
X              ttx, sizeof(ttx), 0, 0, 0, 0);
X    if (status&STS$M_SUCCESS == 0)
X        exit(status);
X    ttx[1] |= TT$M_NOECHO;
X    ttx[2] |= TT2$M_PASTHRU;
X    status = SYS$QIOW(0, iochan, IO$_SETMODE, iosb, 0, 0,
X              ttx, sizeof(ttx), 0, 0, 0, 0);
X    if (status&STS$M_SUCCESS == 0)
X        exit(status);
X# else
X    gtty(0,&ttx);       doraw(ttx);     stty(0,&ttx);
X# endif
X# endif
X    }
X
X/*
X *  sncbr()     Function to set -cbreak echo for the terminal
X *
X *  like: system("stty -cbreak echo")
X */
Xsncbr()
X    {
X# ifdef MSDOS
X    /* Set up to use the direct console input call with echo, getche()
X     */
X    getchfn = getche;
X# else
X# ifdef VMS
X    int status;
X    int iosb[2];
X    cbflag = 0;
X    status = SYS$QIOW(0, iochan, IO$_SENSEMODE, iosb, 0, 0,
X              ttx, sizeof(ttx), 0, 0, 0, 0);
X    if (status&STS$M_SUCCESS == 0)
X        exit(status);
X    ttx[1] &= ~TT$M_NOECHO;
X    ttx[2] &= ~TT2$M_PASTHRU;
X    status = SYS$QIOW(0, iochan, IO$_SETMODE, iosb, 0, 0,
X              ttx, sizeof(ttx), 0, 0, 0, 0);
X    if (status&STS$M_SUCCESS == 0)
X        exit(status);
X# else
X    gtty(0,&ttx);       unraw(ttx);     stty(0,&ttx);
X# endif
X# endif
X    }
X
X/*
X *  newgame()       Subroutine to save the initial time and seed rnd()
X */
Xnewgame()
X{
X    register long *p,*pe;
X    for (p=c,pe=c+100; p<pe; *p++ =0);
X    time(&initialtime);
X    srand(initialtime);
X    lcreat((char*)0);   /* open buffering for output to terminal */
X}
X
X/*
X *  lprintf(format,args . . .)      printf to the output buffer
X *      char *format;
X *      ??? args . . .
X *
X *  Enter with the format string in "format", as per printf() usage
X *      and any needed arguments following it
X *  Note: lprintf() only supports %s, %c and %d, with width modifier and left
X *      or right justification.
X *  No correct checking for output buffer overflow is done, but flushes 
X *      are done beforehand if needed.
X *  Returns nothing of value.
X */
X#ifdef lint
X/*VARARGS*/
Xlprintf(str)
X    char *str;
X    {
X    char *str2;
X    str2 = str;
X    str = str2; /* to make lint happy */
X    }
X/*VARARGS*/
Xsprintf(str)
X    char *str;
X    {
X    char *str2;
X    str2 = str;
X    str = str2; /* to make lint happy */
X    }
X#else lint
X/*VARARGS*/
Xlprintf(va_alist)
Xva_dcl
X    {
X    va_list ap; /* pointer for variable argument list */
X    register char *fmt;
X    register char *outb,*tmpb;
X    register long wide,left,cont,n;     /* data for lprintf */
X    char db[12];            /* %d buffer in lprintf */
X
X    va_start(ap);   /* initialize the var args pointer */
X    fmt = va_arg(ap, char *);   /* pointer to format string */
X    if (lpnt >= lpend) lflush(); 
X    outb = lpnt;
X    for ( ; ; )
X        {
X        while (*fmt != '%')
X            if (*fmt) *outb++ = *fmt++;  else { lpnt=outb;  return; }
X        wide = 0;   left = 1;   cont=1;
X        while (cont)
X          switch(*(++fmt))
X            {
X            case 'd':   n = va_arg(ap, long);
X                        if (n<0) { n = -n;  *outb++ = '-';  if (wide) --wide; }
X                        tmpb = db+11;   *tmpb = (char)(n % 10 + '0');
X                        while (n>9)  *(--tmpb) = (char)((n /= 10) % 10 + '0');
X                        if (wide==0)  while (tmpb < db+12) *outb++ = *tmpb++;
X                        else
X                            {
X                            wide -= db-tmpb+12;
X                            if (left)  while (wide-- > 0) *outb++ = ' ';
X                            while (tmpb < db+12) *outb++ = *tmpb++;
X                            if (left==0)  while (wide-- > 0) *outb++ = ' ';
X                            }
X                        cont=0; break;
X
X            case 's':   tmpb = va_arg(ap, char *);
X                        if (wide==0)  { while (*outb++ = *tmpb++);  --outb; } 
X                        else
X                            {
X                            n = wide - strlen(tmpb);
X                            if (left)  while (n-- > 0) *outb++ = ' ';
X                            while (*outb++ = *tmpb++);  --outb;
X                            if (left==0)  while (n-- > 0) *outb++ = ' ';
X                            }
X                        cont=0; break;
X
X            case 'c':   *outb++ = va_arg(ap, int);  cont=0;  break;
X
X            case '0':
X            case '1':
X            case '2':
X            case '3':
X            case '4':
X            case '5':
X            case '6':
X            case '7':
X            case '8':
X            case '9':   wide = 10*wide + *fmt - '0';    break;
X
X            case '-':   left = 0;   break;
X
X            default:    *outb++ = *fmt;  cont=0;    break;
X            };
X        fmt++;
X        }
X    va_end(ap);
X    }
X#endif lint
X
X/*
X *  lprint(long-integer)                send binary integer to output buffer
X *      long integer;
X *
X *      +---------+---------+---------+---------+
X *      |   high  |         |         |   low   |
X *      |  order  |         |         |  order  |
X *      |   byte  |         |         |   byte  |
X *      +---------+---------+---------+---------+
X *     31  ---  24 23 --- 16 15 ---  8 7  ---   0
X *
X *  The save order is low order first, to high order (4 bytes total)
X *      and is written to be system independent.
X *  No checking for output buffer overflow is done, but flushes if needed!
X *  Returns nothing of value.
X */
Xlprint(x)
X    register long x;
X    {
X    if (lpnt >= lpend) lflush();
X    *lpnt++ =  255 & x;         *lpnt++ =  255 & (x>>8);
X    *lpnt++ =  255 & (x>>16);   *lpnt++ =  255 & (x>>24);
X    }
X
X/*
X *  lwrite(buf,len)         write a buffer to the output buffer
X *      char *buf;
X *      int len;
X *  
X *  Enter with the address and number of bytes to write out
X *  Returns nothing of value
X */
Xlwrite(buf,len)
X    register char *buf;
X    int len;
X    {
X    register char *str;
X    register int num2;
X    if (len > 399)  /* don't copy data if can just write it */
X        {
X#ifdef EXTRA
X        c[BYTESOUT] += len;
X#endif
X
X#ifndef VT100
X        for (str=buf;  len>0; --len)
X            lprc(*str++);
X#else VT100
X        lflush();
X        write(lfd,buf,len);
X#endif VT100
X        } 
X    else while (len)
X        {
X        if (lpnt >= lpend) lflush();    /* if buffer is full flush it   */
X        num2 = lpbuf+BUFBIG-lpnt;   /*  # bytes left in output buffer   */
X        if (num2 > len) num2=len;
X        str = lpnt;  len -= num2;
X        while (num2--)  *str++ = *buf++;    /* copy in the bytes */
X        lpnt = str;
X        }
X    }
X
X/*
X *  long lgetc()        Read one character from input buffer
X *
X *  Returns 0 if EOF, otherwise the character
X */
Xlong lgetc()
X    {
X    register int i;
X
X    if (ipoint != iepoint)  return(inbuffer[ipoint++]);
X    if (iepoint!=MAXIBUF)   return(0);
X    if ((i=vread(fd,inbuffer,MAXIBUF))<=0) {
X        if (i!=0)
X            write(1,"error reading from input file\n",30);
X    iepoint = ipoint = 0;
X    return(0);
X    }
X    ipoint=1;  iepoint=i;  return(*inbuffer);
X}
X
X/*
X *  long lrint()            Read one integer from input buffer
X *
X *      +---------+---------+---------+---------+
X *      |   high  |         |         |   low   |
X *      |  order  |         |         |  order  |
X *      |   byte  |         |         |   byte  |
X *      +---------+---------+---------+---------+
X *     31  ---  24 23 --- 16 15 ---  8 7  ---   0
X *
X *  The save order is low order first, to high order (4 bytes total)
X *  Returns the int read
X */
Xlong lrint()
X    {
X    register unsigned long i;
X    i  = 255 & lgetc();             i |= (255 & lgetc()) << 8;
X    i |= (255 & lgetc()) << 16;     i |= (255 & lgetc()) << 24;
X    return(i);
X    }
X
X/*
X *  lrfill(address,number)          put input bytes into a buffer
X *      char *address;
X *      int number;
X *
X *  Reads "number" bytes into the buffer pointed to by "address".
X *  Returns nothing of value
X */
Xlrfill(adr,num)
X    register char *adr;
X    int num;
X    {
X    register char *pnt;
X    register int num2;
X    while (num)
X        {
X        if (iepoint == ipoint)
X            {
X            if (num>5) /* fast way */
X                {
X                if (vread(fd,adr,num) != num)
X                    write(2,"error reading from input file\n",30);
X                num=0;
X                }
X            else { *adr++ = lgetc();  --num; }
X            }
X        else
X            {
X            num2 = iepoint-ipoint;  /*  # of bytes left in the buffer   */
X            if (num2 > num) num2=num;
X            pnt = inbuffer+ipoint;  num -= num2;  ipoint += num2;
X            while (num2--)  *adr++ = *pnt++;
X            }
X        }
X    }
X
X/*
X *  char *lgetw()           Get a whitespace ended word from input
X *
X *  Returns pointer to a buffer that contains word.  If EOF, returns a NULL
X */
Xchar *lgetw()
X    {
X    register char *lgp,cc;
X    register int n=LINBUFSIZE,quote=0;
X    lgp = lgetwbuf;
X    do cc=lgetc();  while ((cc <= 32) && (cc > NULL));  /* eat whitespace */
X    for ( ; ; --n,cc=lgetc())
X        {
X        if ((cc==NULL) && (lgp==lgetwbuf))  return(NULL);   /* EOF */
X        if ((n<=1) || ((cc<=32) && (quote==0))) { *lgp=NULL; return(lgetwbuf); }
X        if (cc != '"') *lgp++ = cc;   else quote ^= 1;
X        }
X    }
X
X/*
X *  char *lgetl()       Function to read in a line ended by newline or EOF
X *
X *  Returns pointer to a buffer that contains the line.  If EOF, returns NULL
X */
Xchar *lgetl()
X{
X    register int i=LINBUFSIZE,ch;
X    register char *str=lgetwbuf;
X    for ( ; ; --i) {
X        *str++ = ch = lgetc();
X        if (ch == 0) {
X            if (str == lgetwbuf+1)
X                return(NULL);   /* EOF */
X        ot: *str = 0;
X            return(lgetwbuf);   /* line ended by EOF */
X        }
X        if ((ch=='\n') || (i<=1))
X            goto ot;        /* line ended by \n */
X    }
X}
X
X/*
X *  lcreat(filename)            Create a new file for write
X *      char *filename;
X *
X *  lcreat((char*)0); means to the terminal
X *  Returns -1 if error, otherwise the file descriptor opened.
X */
Xlcreat(str)
X    char *str;
X    {
X    lpnt = lpbuf;   lpend = lpbuf+BUFBIG;
X    if (str==NULL) return(lfd=1);
X    if ((lfd=creat(str,0644)) < 0) 
X        {
X        lfd=1; lprintf("error creating file <%s>\n",str); lflush(); return(-1);
X        }
X# ifdef MSDOS
X    setmode(lfd, O_BINARY);
X# endif
X    return(lfd);
X    }
X
X/*
X *  lopen(filename)         Open a file for read
X *      char *filename;
X *
X *  lopen(0) means from the terminal
X *  Returns -1 if error, otherwise the file descriptor opened.
X */
Xlopen(str)
X    char *str;
X    {
X    ipoint = iepoint = MAXIBUF;
X    if (str==NULL) return(fd=0);
X    if ((fd=open(str,0)) < 0)
X        {
X        lwclose(); lfd=1; lpnt=lpbuf; return(-1);
X        }
X# ifdef MSDOS
X    setmode(fd, O_BINARY);
X# endif
X    return(fd);
X    }
X
X/*
X *  lappend(filename)       Open for append to an existing file
X *      char *filename;
X *
X *  lappend(0) means to the terminal
X *  Returns -1 if error, otherwise the file descriptor opened.
X */
Xlappend(str)
X    char *str;
X    {
X    lpnt = lpbuf;   lpend = lpbuf+BUFBIG;
X    if (str==NULL) return(lfd=1);
X    if ((lfd=open(str,2)) < 0)
X        {
X        lfd=1; return(-1);
X        }
X# ifdef MSDOS
X    setmode(lfd, O_BINARY);
X# endif
X    lseek(lfd,0L,2);    /* seek to end of file */
X    return(lfd);
X    }
X
X/*
X *  lrclose()                       close the input file
X *
X *  Returns nothing of value.
X */
Xlrclose()
X    {
X    if (fd > 0) close(fd);
X    }
X
X/*
X *  lwclose()                       close output file flushing if needed
X *
X *  Returns nothing of value.
X */
Xlwclose()
X    {
X    lflush();   if (lfd > 2) close(lfd);
X    }
X
X/*
X *  lprcat(string)                  append a string to the output buffer
X *                                  avoids calls to lprintf (time consuming)
X */
Xlprcat(str)
X    register char *str;
X    {
X    register char *str2;
X    if (lpnt >= lpend) lflush(); 
X    str2 = lpnt;
X    while (*str2++ = *str++);
X    lpnt = str2 - 1;
X    }
X
X#ifdef VT100
X/*
X *  cursor(x,y)         Subroutine to set the cursor position
X *
X *  x and y are the cursor coordinates, and lpbuff is the output buffer where
X *  escape sequence will be placed. 
X */
Xstatic char *y_num[]= { "\33[","\33[","\33[2","\33[3","\33[4","\33[5","\33[6",
X    "\33[7","\33[8","\33[9","\33[10","\33[11","\33[12","\33[13","\33[14",
X    "\33[15","\33[16","\33[17","\33[18","\33[19","\33[20","\33[21","\33[22",
X    "\33[23","\33[24" };
X
Xstatic char *x_num[]= { "H","H",";2H",";3H",";4H",";5H",";6H",";7H",";8H",";9H",
X    ";10H",";11H",";12H",";13H",";14H",";15H",";16H",";17H",";18H",";19H",
X    ";20H",";21H",";22H",";23H",";24H",";25H",";26H",";27H",";28H",";29H",
X    ";30H",";31H",";32H",";33H",";34H",";35H",";36H",";37H",";38H",";39H",
X    ";40H",";41H",";42H",";43H",";44H",";45H",";46H",";47H",";48H",";49H",
X    ";50H",";51H",";52H",";53H",";54H",";55H",";56H",";57H",";58H",";59H",
X    ";60H",";61H",";62H",";63H",";64H",";65H",";66H",";67H",";68H",";69H",
X    ";70H",";71H",";72H",";73H",";74H",";75H",";76H",";77H",";78H",";79H",
X    ";80H" };
X
Xcursor(x,y)
X    int x,y;
X    {
X    register char *p;
X    if (lpnt >= lpend) lflush();
X
X    p = y_num[y];   /* get the string to print */
X    while (*p) *lpnt++ = *p++;  /* print the string */
X
X    p = x_num[x];   /* get the string to print */
X    while (*p) *lpnt++ = *p++;  /* print the string */
X    }
X#else VT100
X/*
X * cursor(x,y)    Put cursor at specified coordinates staring at [1,1] (termcap)
X */
Xcursor (x,y)
X    int x,y;
X    {
X    if (lpnt >= lpend) lflush ();
X
X    *lpnt++ = CURSOR;       *lpnt++ = x;        *lpnt++ = y;
X    }
X#endif VT100
X
X/*
X *  Routine to position cursor at beginning of 24th line
X */
Xcursors()
X    {
X    cursor(1,24);
X    }
X
X#ifndef VT100
X/*
X * Warning: ringing the bell is control code 7. Don't use in defines.
X * Don't change the order of these defines.
X * Also used in helpfiles. Codes used in helpfiles should be \E[1 to \E[7 with
X * obvious meanings.
X */
X
Xstatic char cap[256];
Xstatic char *CM, *CE, *CD, *CL, *SO, *SE, *AL, *DL, *TI, *TE;/* Termcap capabilities */
Xstatic char *outbuf=0;  /* translated output buffer */
X
Xstatic int ttputch ();
X
X/*
X * init_term()      Terminal initialization -- setup termcap info
X */
Xinit_term()
X    {
X    char termbuf[1024];
X    char *capptr = cap+10;
X    char *term;
X
X# ifdef MSDOS
X    term = getenv("TERM");
X    if (term == NULL)
X        term = "ibmpc-mono";
X    switch (tgetent(termbuf, term))
X# else
X# ifdef VMS
X    term = getenv("TERM");
X    if (term == NULL)
X        term = getenv("TERMINAL");
X    switch (tgetent(termbuf, term))
X# else
X    switch (tgetent(termbuf, term = getenv("TERM")))
X# endif
X# endif
X        {
X        case -1: 
X            write(2, "Cannot open termcap file.\n", 26); exit();
X        case 0: 
X            write(2, "Cannot find entry of ", 21);
X            write(2, term, strlen (term));
X            write(2, " in termcap\n", 12);
X            exit();
X        };
X
X    CM = tgetstr("cm", &capptr);  /* Cursor motion */
X    CE = tgetstr("ce", &capptr);  /* Clear to eoln */
X    CL = tgetstr("cl", &capptr);  /* Clear screen */
X
X/* OPTIONAL */
X    AL = tgetstr("al", &capptr);  /* Insert line */
X    DL = tgetstr("dl", &capptr);  /* Delete line */
X    SO = tgetstr("so", &capptr);  /* Begin standout mode */
X    SE = tgetstr("se", &capptr);  /* End standout mode */
X    CD = tgetstr("cd", &capptr);  /* Clear to end of display */
X    TI = tgetstr("ti", &capptr);  /* Terminal initialization */
X    TE = tgetstr("te", &capptr);  /* Terminal end */
X
X    if (!CM)    /* can't find cursor motion entry */
X        {
X        write(2, "Sorry, for a ",13);       write(2, term, strlen(term));
X        write(2, ", I can't find the cursor motion entry in termcap\n",50);
X        exit();
X        }
X    if (!CE)    /* can't find clear to end of line entry */
X        {
X        write(2, "Sorry, for a ",13);       write(2, term, strlen(term));
X        write(2,", I can't find the clear to end of line entry in termcap\n",57);
X        exit();
X        }
X    if (!CL)    /* can't find clear entire screen entry */
X        {
X        write(2, "Sorry, for a ",13);       write(2, term, strlen(term));
X        write(2, ", I can't find the clear entire screen entry in termcap\n",56);
X        exit();
X        }
X    if ((outbuf=(char *)malloc(BUFBIG+16))==0) /* get memory for decoded output buffer*/
X        {
X        write(2,"Error malloc'ing memory for decoded output buffer\n",50);
X        died(-285); /* malloc() failure */
X        }
X    }
X#endif VT100
X
X/*
X * cl_line(x,y)  Clear the whole line indicated by 'y' and leave cursor at [x,y]
X */
Xcl_line(x,y)
X    int x,y;
X    {
X#ifdef VT100
X    cursor(x,y);        lprcat("\33[2K");
X#else VT100
X    cursor(1,y);        *lpnt++ = CL_LINE;      cursor(x,y);
X#endif VT100
X    }
X
X/*
X * cl_up(x,y) Clear screen from [x,1] to current position. Leave cursor at [x,y]
X */
Xcl_up(x,y)
X    register int x,y;
X    {
X#ifdef VT100
X    cursor(x,y);  lprcat("\33[1J\33[2K");
X#else VT100
X    register int i;
X    cursor(1,1);
X    for (i=1; i<=y; i++)   { *lpnt++ = CL_LINE;  *lpnt++ = '\n'; }
X    cursor(x,y);
X#endif VT100
X    }
X
X/*
X * cl_dn(x,y)   Clear screen from [1,y] to end of display. Leave cursor at [x,y]
X */
Xcl_dn(x,y)
X    register int x,y;
X    {
X#ifdef VT100
X    cursor(x,y); lprcat("\33[J\33[2K");
X#else VT100
X    register int i;
X    cursor(1,y);
X    if (!CD)
X        {
X        *lpnt++ = CL_LINE;
X        for (i=y; i<=24; i++) { *lpnt++ = CL_LINE;  if (i!=24) *lpnt++ = '\n'; }
X        cursor(x,y);
X        }
X    else
X        *lpnt++ = CL_DOWN;
X    cursor(x,y);
X#endif VT100
X    }
X
X/*
X * standout(str)    Print the argument string in inverse video (standout mode).
X */
Xstandout(str)
X    register char *str;
X    {
X#ifdef VT100
X    setbold();
X    while (*str)
X        *lpnt++ = *str++;
X    resetbold();
X#else VT100
X    *lpnt++ = ST_START;
X    while (*str)
X        *lpnt++ = *str++;
X    *lpnt++ = ST_END;
X#endif VT100
X    }
X
X/*
X * set_score_output()   Called when output should be literally printed.
X */
Xset_score_output()
X    {
X    enable_scroll = -1;
X    }
X
X/*
X *  lflush()                        Flush the output buffer
X *
X *  Returns nothing of value.
X *  for termcap version: Flush output in output buffer according to output
X *                       status as indicated by `enable_scroll'
X */
X#ifndef VT100
Xstatic int scrline=18; /* line # for wraparound instead of scrolling if no DL */
Xlflush ()
X    {
X    register int lpoint;
X    register char *str;
X    static int curx = 0;
X    static int cury = 0;
X
X    if ((lpoint = lpnt - lpbuf) > 0)
X        {
X#ifdef EXTRA
X        c[BYTESOUT] += lpoint;
X#endif
X        if (enable_scroll <= -1) {
X            flush_buf();
X# ifdef MSDOS
X            /* Catch write errors on save files
X             */
X                if (write(lfd,lpbuf,lpoint) != lpoint) {
X                    if (save_mode)
X                        longjmp(save_jbuf, -1);
X                    else
X                        warn("Error writing output file\n");
X                }
X# else
X                if (write(lfd,lpbuf,lpoint) != lpoint)
X                write(2,"error writing to output file\n",29);
X# endif
X            lpnt = lpbuf;   /* point back to beginning of buffer */
X            return;
X        }
X        for (str = lpbuf; str < lpnt; str++)
X            {
X            if (*str>=32)   { ttputch (*str); curx++; }
X            else switch (*str) {
X                case CLEAR:     tputs (CL, 1, ttputch);     curx = cury = 0;
X                                break;
X
X                case CL_LINE:   tputs (CE, 1, ttputch);
X                                break;
X
X                case CL_DOWN:   tputs (CD, 1, ttputch);
X                                break;
X
X                case ST_START:  tputs (SO, 1, ttputch);
X                                break;
X
X                case ST_END:    tputs (SE, 1, ttputch);
X                                break;
X
X                case CURSOR:    curx = *++str - 1;      cury = *++str - 1;
X                                tputs (tgoto (CM, curx, cury), 1, ttputch);
X                                break;
X
X                case '\n':      if ((cury == 23) && enable_scroll)
X                                  {
X                                  if (!DL || !AL) /* wraparound or scroll? */
X                                    {
X                                    if (++scrline > 23) scrline=19;
X
X                                    if (++scrline > 23) scrline=19;
X                                    tputs (tgoto (CM, 0, scrline), 1, ttputch);
X                                    tputs (CE, 1, ttputch);
X
X                                    if (--scrline < 19) scrline=23;
X                                    tputs (tgoto (CM, 0, scrline), 1, ttputch);
X                                    tputs (CE, 1, ttputch);
X                                    }
X                                  else
X                                    {
X                                    tputs (tgoto (CM, 0, 19), 1, ttputch);
X                                    tputs (DL, 1, ttputch);
X                                    tputs (tgoto (CM, 0, 23), 1, ttputch);
X                                /*  tputs (AL, 1, ttputch); */
X                                    }
X                                  }
X                                else
X                                  {
X                                  ttputch ('\n');       cury++;
X                                  }
X                                curx = 0;
X                                break;
X                case T_INIT:
X                    if (TI)
X                        tputs(TI, 1, ttputch);
X                    break;
X                case T_END:
X                    if (TE)
X                        tputs(TE, 1, ttputch);
X                    break;
X                default:
X                    ttputch (*str);
X                    curx++;
X                }
X            }
X        }
X    lpnt = lpbuf;
X    flush_buf();    /* flush real output buffer now */
X    }
X#else VT100
X/*
X *  lflush()                        flush the output buffer
X *
X *  Returns nothing of value.
X */
Xlflush()
X    {
X    register int lpoint;
X    if ((lpoint = lpnt - lpbuf) > 0)
X        {
X#ifdef EXTRA
X        c[BYTESOUT] += lpoint;
X#endif
X        if (write(lfd,lpbuf,lpoint) != lpoint)
X            write(2,"error writing to output file\n",29);
X        }
X    lpnt = lpbuf;   /* point back to beginning of buffer */
X    }
X#endif VT100
X
X#ifndef VT100
Xstatic int index=0;
X/*
X * ttputch(ch)      Print one character in decoded output buffer.
X */
Xstatic int ttputch(c)
Xint c;
X    {
X    outbuf[index++] = c;
X    if (index >= BUFBIG)  flush_buf();
X    }
X
X/*
X * flush_buf()          Flush buffer with decoded output.
X */
Xstatic flush_buf()
X    {
X    if (index) write(lfd, outbuf, index);
X    index = 0;
X    }
X
X/*
X *  char *tmcapcnv(sd,ss)  Routine to convert VT100 escapes to termcap format
X *
X *  Processes only the \33[#m sequence (converts . files for termcap use 
X */
Xchar *tmcapcnv(sd,ss)  
X    register char *sd,*ss;
X    {
X    register int tmstate=0; /* 0=normal, 1=\33 2=[ 3=# */
X    char tmdigit=0; /* the # in \33[#m */
X    while (*ss)
X        {
X        switch(tmstate)
X            {
X            case 0: if (*ss=='\33')  { tmstate++; break; }
X              ign:  *sd++ = *ss;
X              ign2: tmstate = 0;
X                    break;
X            case 1: if (*ss!='[') goto ign;
X                    tmstate++;
X                    break;
X            case 2: if (isdigit(*ss)) { tmdigit= *ss-'0'; tmstate++; break; }
X                    if (*ss == 'm') { *sd++ = ST_END; goto ign2; }
X                    goto ign;
X            case 3: if (*ss == 'm')
X                        {
X                        if (tmdigit) *sd++ = ST_START;
X                            else *sd++ = ST_END;
X                        goto ign2;
X                        }
X            default: goto ign;
X            };
X        ss++;
X        }
X    *sd=0; /* NULL terminator */
X    return(sd);
X    }
X#endif VT100
X
X/*
X *  beep()      Routine to emit a beep if enabled (see no-beep in .larnopts)
X */
Xbeep() {
X    if (!nobeep) *lpnt++ = '\7';
X    }
END_OF_FILE
if test 32203 -ne `wc -c <'io.c'`; then
    echo shar: \"'io.c'\" unpacked with wrong size!
fi
# end of 'io.c'
fi
if test -f 'moreobj.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'moreobj.c'\"
else
echo shar: Extracting \"'moreobj.c'\" \(18865 characters\)
sed "s/^X//" >'moreobj.c' <<'END_OF_FILE'
X/* moreobj.c
X
X   Routines in this file:
X
X   oaltar()
X   othrone()
X   odeadthrone()
X   ochest()
X   ofountain()
X   fntchange()
X   fch()
X   drink_fountain()
X   wash_fountain()
X   enter()
X   remove_gems()
X   sit_on_throne()
X   up_stairs()
X   down_stairs()
X   open_something()
X   close_something()
X   desecrate_altar()
X   pray_at_altar()
X*/
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X
X       void specify_object();
Xstatic void specify_obj_nocurs();
Xstatic void specify_obj_cursor();
Xextern int dropflag ;
Xstatic void move_cursor();
X
X/*
X    subroutine to process an altar object
X*/
Xoaltar()
X    {
X    unsigned long k;
X
X    lprcat("\nDo you (p) pray  (d) desecrate"); iopts();
X    while (1) switch(ttgetch())
X        {
X        case 'p':
X        lprcat(" pray\nDo you (m) give money or (j) just pray? ");
X            while (1) switch(ttgetch())
X                {
X                case 'j': 
X            lprcat("\n");
X            act_just_pray();
X            return;
X
X                case 'm':
X            act_donation_pray();
X            return;
X
X                case '\33':
X            return;
X                };
X
X        case 'd':
X        lprcat(" desecrate");
X        act_desecrate_altar();
X        return;
X
X        case 'i':
X        case '\33':
X        ignore();
X        act_ignore_altar();
X            return;
X        };
X    }
X
X/*
X    subroutine to process a throne object
X*/
Xothrone(arg)
X    int arg;
X    {
X
X    lprcat("\nDo you (p) pry off jewels, (s) sit down"); iopts();
X    while (1)
X      {
X      while (1) switch(ttgetch())
X        {
X        case 'p':   
X            lprcat(" pry off");  
X            act_remove_gems( arg );
X            return;
X
X        case 's':
X            lprcat(" sit down");
X            act_sit_throne( arg );
X            return;
X
X        case 'i':
X        case '\33': ignore(); return;
X        };
X      }
X    }
X
Xodeadthrone()
X    {
X    lprcat("\nDo you (s) sit down"); iopts();
X    while (1)
X      {
X      while (1) switch(ttgetch())
X        {
X        case 's':   
X            lprcat(" sit down");  
X            act_sit_throne(1);
X            return;
X
X        case 'i':
X        case '\33': ignore(); return;
X        };
X      }
X    }
X
X/*
X    subroutine to process a chest object
X*/
Xochest()
X    {
X    lprcat("\nDo you (t) take it, (o) try to open it"); iopts();
X    while (1)
X      {
X      switch(ttgetch())
X        {
X    case 'o':
X        lprcat(" open it");
X        act_open_chest( playerx, playery );
X        return;
X
X    case 't':
X        lprcat(" take");
X        if (take(OCHEST,iarg[playerx][playery])==0)
X        item[playerx][playery]=know[playerx][playery]=0;
X        return;
X
X        case 'i':
X        case '\33': ignore(); return;
X        };
X      }
X    }
X
X/*
X    process a fountain object
X*/
Xofountain()
X    {
X    cursors();
X    lprcat("\nDo you (d) drink, (w) wash yourself"); iopts();
X    while (1) switch(ttgetch())
X        {
X        case 'd':
X            act_drink_fountain();
X            return;
X
X        case '\33':
X        case 'i':   
X            ignore();  
X            return;
X
X        case 'w':   
X            act_wash_fountain();
X            return;
X        }
X    }
X
X/*
X    a subroutine to raise or lower character levels
X    if x > 0 they are raised   if x < 0 they are lowered
X*/
Xfntchange(how)
X    int how;
X    {
X    register long j;
X    lprc('\n');
X    switch(rnd(9))
X        {
X        case 1: 
X            lprcat("Your strength");        
X            fch(how,&c[STRENGTH]);     break;
X        case 2:
X            lprcat("Your intelligence");    
X            fch(how,&c[INTELLIGENCE]);     break;
X        case 3:
X            lprcat("Your wisdom");          
X            fch(how,&c[WISDOM]);     break;
X        case 4: 
X            lprcat("Your constitution");    
X            fch(how,&c[CONSTITUTION]);     break;
X        case 5:
X            lprcat("Your dexterity");
X            fch(how,&c[DEXTERITY]);     break;
X        case 6:
X            lprcat("Your charm");
X            fch(how,&c[CHARISMA]);     break;
X        case 7: 
X            j=rnd(level+1);
X            if (how < 0)
X                {
X                lprintf("You lose %d hit point",(long)j);
X                if (j>1) lprcat("s!"); else lprc('!');
X                losemhp((int)j);
X                }
X            else
X                { lprintf("You gain %d hit point",(long)j);  if (j>1) lprcat("s!"); else lprc('!'); raisemhp((int)j); }
X            bottomline();       break;
X
X        case 8: j=rnd(level+1);
X                if (how > 0)
X                    {
X                    lprintf("You just gained %d spell",(long)j);  raisemspells((int)j);
X                    if (j>1) lprcat("s!"); else lprc('!');
X                    }
X                else
X                    {
X                    lprintf("You just lost %d spell",(long)j);  losemspells((int)j);
X                    if (j>1) lprcat("s!"); else lprc('!');
X                    }
X                bottomline();       break;
X
X        case 9: j = 5*rnd((level+1)*(level+1));
X                if (how < 0)
X                    {
X                    lprintf("You just lost %d experience point",(long)j);
X                    if (j>1) lprcat("s!"); else lprc('!'); loseexperience((long)j);
X                    }
X                else
X                    {
X                    lprintf("You just gained %d experience point",(long)j);
X                    if (j>1) lprcat("s!"); else lprc('!'); raiseexperience((long)j);
X                    }
X                break;
X        }
X    cursors();
X    }
X
X/*
X    subroutine to process an up/down of a character attribute for ofountain
X*/
Xstatic fch(how,x)
X    int how;
X    long *x;
X    {
X    if (how < 0)     { lprcat(" went down by one!");    --(*x); }
X        else         { lprcat(" went up by one!");  (*x)++; }
X    bottomline();
X    }
X
X/*
X    For command mode.  Perform drinking at a fountain.
X*/
Xdrink_fountain()
X    {
X    cursors() ;
X    if (item[playerx][playery] == ODEADFOUNTAIN)
X        lprcat("\nThere is no water to drink!") ;
X
X    else if (item[playerx][playery] != OFOUNTAIN)
X        lprcat("\nI see no fountain to drink from here!") ;
X
X    else 
X        act_drink_fountain();
X    return;
X    }
X
X/*
X    For command mode.  Perform washing (tidying up) at a fountain.
X*/
Xwash_fountain()
X    {
X    cursors() ;
X    if (item[playerx][playery] == ODEADFOUNTAIN)
X        lprcat("\nThere is no water to wash in!") ;
X
X    else if (item[playerx][playery] != OFOUNTAIN)
X        lprcat("\nI see no fountain to wash at here!") ;
X
X    else
X        act_wash_fountain();
X    return;
X    }
X
X/*
X    For command mode.  Perform entering a building.
X*/
Xenter()
X    {
X    cursors() ;
X    switch ( item[playerx][playery] )
X        {
X        case OSCHOOL:
X            oschool();
X            break ;
X
X        case OBANK:
X            obank() ;
X            break ;
X
X        case OBANK2:
X            obank2() ;
X            break ;
X
X        case ODNDSTORE:
X            dndstore() ;
X            break ;
X
X        case OENTRANCE:
X            /* place player in front of entrance on level 1.  newcavelevel()
X               prevents player from landing on a monster/object.
X            */
X            playerx = 33 ;
X            playery = MAXY - 2 ;
X            newcavelevel( 1 );
X            know[33][MAXY - 1] = KNOWALL ;
X            mitem[33][MAXY - 1] = 0 ;
X            draws( 0, MAXX, 0, MAXY );
X            showcell(playerx, playery);         /* to show around player */
X            bot_linex() ;
X            break ;
X
X        case OTRADEPOST:
X            otradepost();
X            break;
X
X        case OLRS:
X            olrs();
X            break;
X
X        case OHOME:
X            ohome();
X            break;
X
X        default :
X            lprcat("\nThere is no place to enter here!\n");
X            break;
X        }
X    }
X
X/*
X    For command mode.  Perform removal of gems from a jeweled throne.
X*/
Xremove_gems ( )
X    {
X    cursors();
X    if (item[playerx][playery] == ODEADTHRONE)
X        lprcat("\nThere are no gems to remove!");
X    
X    else if (item[playerx][playery] == OTHRONE)
X        act_remove_gems(0);
X
X    else if (item[playerx][playery] == OTHRONE2)
X        act_remove_gems(1);
X
X    else
X        lprcat("\nI see no throne here to remove gems from!");
X    return;
X    }
X
X/*
X    For command mode.  Perform sitting on a throne.
X*/
Xsit_on_throne( )
X    {
X    cursors();
X    if (item[playerx][playery] == OTHRONE)
X        act_sit_throne(0);
X    
X    else if ((item[playerx][playery] == OTHRONE2) ||
X             (item[playerx][playery] == ODEADTHRONE))
X        act_sit_throne(1);
X    
X    else
X        lprcat("\nI see no throne to sit on here!");
X
X    return;
X    }
X
X/*
X    For command mode.  Checks that player is actually standing at a set up
X    up stairs or volcanic shaft.  
X*/
Xup_stairs()
X    {
X    cursors();
X    if (item[playerx][playery] == OSTAIRSDOWN)
X        lprcat("\nThe stairs don't go up!");
X
X    else if (item[playerx][playery] == OVOLUP)
X        act_up_shaft();
X
X    else if (item[playerx][playery] != OSTAIRSUP)
X        lprcat("\nI see no way to go up here!");
X
X    else
X        act_up_stairs();
X    }
X
X/*
X    For command mode.  Checks that player is actually standing at a set of
X    down stairs or volcanic shaft.
X*/
Xdown_stairs()
X    {
X    cursors();
X    if (item[playerx][playery] == OSTAIRSUP)
X        lprcat("\nThe stairs don't go down!");
X
X    else if (item[playerx][playery] == OVOLDOWN)
X        act_down_shaft();
X
X    else if (item[playerx][playery] != OSTAIRSDOWN)
X        lprcat("\nI see no way to go down here!");
X
X    else
X        act_down_stairs();
X    }
X
X/*
X    For command mode.  Perform opening an object (door, chest).
X*/
Xopen_something( )
X    {
X    int x,y;    /* direction to open */
X    char tempc; /* result of prompting to open a chest */
X
X    cursors();
X    /* check for confusion.
X    */
X    if (c[CONFUSE])
X        {
X        lprcat("You're too confused!");
X        beep();
X        return;
X        }
X
X    /* check for player standing on a chest.  If he is, prompt for and
X       let him open it.  If player ESCs from prompt, quit the Open
X       command.
X    */
X    if (item[playerx][playery] == OCHEST)
X        {
X        lprcat("There is a chest here.  Open it?");
X        if ((tempc = getyn()) == 'y')
X            {
X            act_open_chest( playerx, playery );
X            dropflag = 1;     /* prevent player from picking back up if fail */
X            return;
X            }
X        else if (tempc != 'n' )
X            return;
X        }
X
X    /* get direction of object to open.  test 'openability' of object
X       indicated, call common command/prompt mode routines to actually open.
X    */
X    dirsub( &x, &y );
X    switch( item[x][y] )
X        {
X        case OOPENDOOR:
X            lprcat("The door is already open!");
X            beep();
X            break;
X
X        case OCHEST:
X            act_open_chest( x, y );
X            break;
X
X        case OCLOSEDDOOR:
X            act_open_door( x, y );
X            break;
X
X        default:
X            lprcat("You can't open that!");
X            beep();
X            break;
X        }
X    }
X
X/*
X    For command mode.  Perform the action of closing something (door).
X*/
Xclose_something()
X    {
X    int x,y;
X
X    cursors();
X    /* check for confusion.
X    */
X    if (c[CONFUSE])
X        {
X        lprcat("You're too confused!");
X        beep();
X        return;
X        }
X
X    /* get direction of object to close.  test 'closeability' of object
X       indicated.
X    */
X    dirsub( &x, &y );
X    switch( item[x][y] )
X        {
X        case OCLOSEDDOOR:
X            lprcat("The door is already closed!");
X            beep();
X            break;
X
X        case OOPENDOOR:
X            if (mitem[x][y])
X                {
X                lprcat("Theres a monster in the way!");
X                return;
X                }
X            item[x][y] = OCLOSEDDOOR;
X            know[x][y] = 0 ;
X            iarg[x][y] = 0 ;
X            break;
X
X        default:
X            lprcat("You can't close that!");
X            beep();
X            break;
X        }
X    }
X
X/*
X    For command mode.  Perform the act of descecrating an altar.
X*/
Xdesecrate_altar()
X    {
X    cursors();
X    if (item[playerx][playery] == OALTAR)
X        act_desecrate_altar();
X    else
X        lprcat("\nI see no altar to desecrate here!");
X    }
X
X/*
X    For command mode.  Perform the act of praying at an altar.
X*/
Xpray_at_altar()
X    {
X    extern char prayed ;
X
X    cursors();
X    if (item[playerx][playery] != OALTAR)
X        lprcat("\nI see no altar to pray at here!");
X    else
X    act_donation_pray();
X    prayed = 1 ;
X    }
X
X/*
X    Identify objects for the player.
X*/
Xvoid specify_object()
X    {
X    cursors();
X    lprcat("\n\nIdentify unknown object by cursor [ynq]?");
X    while (1)
X        {
X        switch (ttgetch())
X            {
X            case '\33':
X            case 'q':
X                return;
X                break;
X            case 'y':
X            case 'Y':
X                specify_obj_cursor();
X                return;
X                break;
X            case 'n':
X            case 'N':
X                specify_obj_nocurs();
X                return;
X                break;
X            default:
X                break;
X            }
X        }
X    }
X
X/* perform the actions of identifying the object/monster associated with a
X   character typed by the user.  assumes cursors().
X*/
Xstatic void specify_obj_nocurs()
X    {
X    register int i, j, flag;
X
X    lprcat("\nType object character:");
X    switch (i=ttgetch())
X        {
X        case '\33':
X        case '\n':
X            return;
X        case '@':
X            lprintf("\n@: %s", logname );
X            return;
X        case ' ':
X            lprintf("\n : An as-yet-unseen place in the dungeon" );
X            return;
X        default:
X            if ( i == floorc )
X                {
X                lprc('\n');
X                lprc(floorc);
X                lprintf(": the floor of the dungeon");
X                return;
X                }
X            flag = FALSE;
X            for (j=0; j < MAXMONST+8 ; j++)
X                if (i==monstnamelist[j])
X                    {
X                    lprintf("\n%c: %s", i, monster[j].name);
X                    flag = TRUE;
X                    }
X            /* check for spurious object character
X            */
X            if (i != '_')
X                for (j=0; j < MAXOBJECT; j++)
X                    if (i==objnamelist[j])
X                        {
X                        lprc('\n');
X                        if (boldobjects)
X                            {
X                            setbold();
X                            lprc(i);
X                            resetbold();
X                            }
X                        else
X                            lprc(i);
X                        lprintf(": %s", objectname[j]);
X                        flag = TRUE;
X                        }
X            if (!flag)
X                lprintf("\n%c: unknown monster/object", i );
X            return;
X            break;
X        }
X    }
X
Xstatic void specify_obj_cursor()
X    {
X#if __STDC__
X    signed char objx, objy;
X#else
X    char objx, objy;
X#endif
X    int i;
X
X    lprcat("\nMove the cursor to an unknown item.");
X    lprcat("\n(For instructions type a ?)");
X
X    objx = playerx ;
X    objy = playery ;
X    cursor( objx+1, objy+1 );
X/* make cursor visible.
X*/
X    while (1)
X        {
X        switch(ttgetch())
X            {
X            case '?':
X                cursors();
X                lprcat("\nUse [hjklnbyu] to move the cursor to the unknown object.");
X                lprcat("\nType a . when the cursor is at the desired place.");
X                lprcat("\nType q, Return, or Escape to exit.");
X                cursor( objx+1, objy+1);
X                break;
X
X            case '\33':
X            case 'q':
X            case '\n':
X/* reset cursor
X*/
X                cursor( playerx+1, playery+1);
X                return;
X            case '.':
X/* reset cursor
X*/
X                cursor( playerx+1, playery+1);
X                cursors();
X
X                if ((objx == playerx) &&
X                    (objy == playery))
X                    {
X                    lprintf("\n@: %s", logname );
X                    return;
X                    }
X
X                i = mitem[objx][objy];
X                if ( i && ( know[objx][objy] & KNOWHERE))
X
X                    /* check for invisible monsters and not display
X                    */
X                    if ( monstnamelist[i] != floorc )
X                        {
X                        lprintf("\n%c: %s", monstnamelist[i], monster[i].name);
X                        return;
X                        }
X
X                /* handle floor separately so as not to display traps, etc.
X                */
X                i = item[objx][objy];
X                if ( i == 0 )
X                    {
X                    lprc('\n');
X                    lprc(floorc);
X                    lprintf(": the floor of the dungeon");
X                    return;
X                    }
X
X                if ( know[objx][objy] & HAVESEEN )
X                    {
X                    lprc('\n');
X                    if (boldobjects)
X                        {
X                        setbold();
X                        lprc(objnamelist[i]);
X                        resetbold();
X                        }
X                    else
X                        lprc(objnamelist[i]);
X                    lprintf(": %s", objectname[i]);
X                    return;
X                    }
X
X                lprintf("\n : An as-yet-unseen place in the dungeon" );
X                return;
X
X            case 'H':
X            case 'h':
X                move_cursor( &objx, &objy, 4);
X                break;
X            case 'J':
X            case 'j':
X                move_cursor( &objx, &objy, 1);
X                break;
X            case 'K':
X            case 'k':
X                move_cursor( &objx, &objy, 3);
X                break;
X            case 'L':
X            case 'l':
X                move_cursor( &objx, &objy, 2);
X                break;
X            case 'B':
X            case 'b':
X                move_cursor( &objx, &objy, 8);
X                break;
X            case 'N':
X            case 'n':
X                move_cursor( &objx, &objy, 7);
X                break;
X            case 'Y':
X            case 'y':
X                move_cursor( &objx, &objy, 6);
X                break;
X            case 'U':
X            case 'u':
X                move_cursor( &objx, &objy, 5);
X                break;
X            default:
X                break;
X            }
X        }
X    }
X
Xstatic void move_cursor( xx, yy, cdir )
X#if __STDC__
Xsigned char *xx ;
Xsigned char *yy ;
X#else
Xchar *xx ;
Xchar *yy ;
X#endif
Xunsigned char cdir ;
X    {
X    *xx += diroffx[cdir];
X    *yy += diroffy[cdir];
X    if ( *yy < 0 ) *yy = MAXY-1;
X    if ( *yy > MAXY-1 ) *yy = 0;
X    if ( *xx < 0 ) *xx = MAXX-1;
X    if ( *xx > MAXX-1 ) *xx = 0;
X    cursor( *xx+1, *yy+1 );
X    }
END_OF_FILE
if test 18865 -ne `wc -c <'moreobj.c'`; then
    echo shar: \"'moreobj.c'\" unpacked with wrong size!
fi
# end of 'moreobj.c'
fi
if test -f 'patchlev.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'patchlev.h'\"
else
echo shar: Extracting \"'patchlev.h'\" \(77 characters\)
sed "s/^X//" >'patchlev.h' <<'END_OF_FILE'
X/* indicate which patches have been applied to Larn.
X*/
X#define PATCHLEVEL 0
END_OF_FILE
if test 77 -ne `wc -c <'patchlev.h'`; then
    echo shar: \"'patchlev.h'\" unpacked with wrong size!
fi
# end of 'patchlev.h'
fi
echo shar: End of archive 3 \(of 12\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 12 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