[comp.sources.games] v11i091: larn - dungeon type adventure game, Part08/11

billr@saab.CNA.TEK.COM (Bill Randle) (12/19/90)

Submitted-by: routley@tle.ENET.DEC.COM (Kevin Routley)
Posting-number: Volume 11, Issue 91
Archive-name: larn/Part08
Environment: Unix, VMS, MS-DOS, 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 8 (of 11)."
# Contents:  create.c diag.c header.h nansi.doc
# Wrapped by billr@saab on Tue Dec 18 10:14:21 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'create.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'create.c'\"
else
echo shar: Extracting \"'create.c'\" \(15787 characters\)
sed "s/^X//" >'create.c' <<'END_OF_FILE'
X/*  create.c        Larn is copyrighted 1986 by Noah Morgan. */
X#include "header.h"
Xextern char spelknow[],larnlevels[];
Xextern char beenhere[],wizard,level;
Xextern short oldx,oldy;
X/*
X    makeplayer()
X
X    subroutine to create the player and the players attributes
X    this is called at the beginning of a game and at no other time
X */
Xmakeplayer()
X    {
X    register int i;
X    scbr();  clear();
X    c[HPMAX]=c[HP]=10;      /*  start player off with 15 hit points */
X    c[LEVEL]=1;             /*  player starts at level one          */
X    c[SPELLMAX]=c[SPELLS]=1;    /*  total # spells starts off as 3  */
X    c[REGENCOUNTER]=16;     c[ECOUNTER]=96; /*start regeneration correctly*/
X    c[SHIELD] = c[WEAR] = c[WIELD] = -1;
X    for (i=0; i<26; i++)  iven[i]=0;
X    spelknow[0]=spelknow[1]=1; /*he knows protection, magic missile*/
X    if (c[HARDGAME]<=0)
X        {
X        iven[0]=OLEATHER; iven[1]=ODAGGER; iven[2] = 0;
X        ivenarg[1]=ivenarg[0]=c[WEAR]=0;  c[WIELD]=1;
X        }
X    playerx=rnd(MAXX-2);    playery=rnd(MAXY-2);
X    oldx=0;         oldy=25;
X    gtime=0;            /*  time clock starts at zero   */
X    cbak[SPELLS] = -50;
X    for (i=0; i<6; i++)  c[i]=12; /* make the attributes, ie str, int, etc. */
X    recalc();
X    }
X
X/*
X    newcavelevel(level)
X    int level;
X
X    function to enter a new level.  This routine must be called anytime the
X    player changes levels.  If that level is unknown it will be created.
X    A new set of monsters will be created for a new level, and existing
X    levels will get a few more monsters.
X    Note that it is here we remove genocided monsters from the present level.
X */
Xnewcavelevel(x)
X    register int x;
X    {
X    register int i,j;
X    if (beenhere[level]) savelevel();   /* put the level back into storage  */
X    level = x;              /* get the new level and put in working storage */
X	if (beenhere[x])
X		{
X		getlevel();
X		sethp(0);
X		checkgen();
X		return;
X		}
X
X	/* fill in new level
X	*/
X	for (i=0; i<MAXY; i++)
X		for (j=0; j<MAXX; j++)
X			know[j][i]=mitem[j][i]=0;
X	makemaze(x);
X	makeobject(x);
X	beenhere[x]=1;
X	sethp(1);
X	checkgen();   /* wipe out any genocided monsters */
X
X#if WIZID
X    if (wizard || x==0)
X#else
X    if (x==0)
X#endif
X        for (j=0; j<MAXY; j++)
X            for (i=0; i<MAXX; i++)
X                know[i][j] = KNOWALL;
X    }
X
X/*
X    makemaze(level)
X    int level;
X
X    subroutine to make the caverns for a given level.  only walls are made.
X */
Xstatic int mx,mxl,mxh,my,myl,myh,tmp2;
Xstatic makemaze(k)
X    int k;
X    {
X    register int i,j,tmp;
X    int z;
X    if (k > 1 && (rnd(17)<=4 || k==MAXLEVEL-1 || k==MAXLEVEL+MAXVLEVEL-1))
X        {
X        if (cannedlevel(k));    return;     /* read maze from data file */
X        }
X    if (k==0)  tmp=0;  else tmp=OWALL;
X    for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)  item[j][i]=tmp;
X    if (k==0) return;       eat(1,1);
X    if (k==1) item[33][MAXY-1]=0;   /* exit from dungeon */
X
X/*  now for open spaces -- not on level 10  */
X    if (k != MAXLEVEL-1)
X        {
X        tmp2 = rnd(3)+3;
X        for (tmp=0; tmp<tmp2; tmp++)
X            {
X            my = rnd(11)+2;   myl = my - rnd(2);  myh = my + rnd(2);
X            if (k < MAXLEVEL)
X                {
X                mx = rnd(44)+5;  mxl = mx - rnd(4);  mxh = mx + rnd(12)+3;
X                z=0;
X                }
X            else
X                {
X                mx = rnd(60)+3;  mxl = mx - rnd(2);  mxh = mx + rnd(2);
X                z = makemonst(k);
X                }
X            for (i=mxl; i<mxh; i++)     for (j=myl; j<myh; j++)
X                {  item[i][j]=0;
X                   if ((mitem[i][j]=z)) hitp[i][j]=monster[z].hitpoints;
X                }
X            }
X        }
X    if (k!=MAXLEVEL-1) { my=rnd(MAXY-2);  for (i=1; i<MAXX-1; i++)  item[i][my] = 0; }
X    if (k>1)  treasureroom(k);
X    }
X
X/*
X    function to eat away a filled in maze
X */
Xeat(xx,yy)
X    register int xx,yy;
X    {
X    register int dir,try;
X    dir = rnd(4);   try=2;
X    while (try)
X        {
X        switch(dir)
X            {
X            case 1: if (xx <= 2) break;     /*  west    */
X                    if ((item[xx-1][yy]!=OWALL) || (item[xx-2][yy]!=OWALL)) break;
X                    item[xx-1][yy] = item[xx-2][yy] = 0;
X                    eat(xx-2,yy);   break;
X
X            case 2: if (xx >= MAXX-3) break;    /*  east    */
X                    if ((item[xx+1][yy]!=OWALL) || (item[xx+2][yy]!=OWALL)) break;
X                    item[xx+1][yy] = item[xx+2][yy] = 0;
X                    eat(xx+2,yy);   break;
X
X            case 3: if (yy <= 2) break;     /*  south   */
X                    if ((item[xx][yy-1]!=OWALL) || (item[xx][yy-2]!=OWALL)) break;
X                    item[xx][yy-1] = item[xx][yy-2] = 0;
X                    eat(xx,yy-2);   break;
X
X            case 4: if (yy >= MAXY-3 ) break;   /*  north   */
X                    if ((item[xx][yy+1]!=OWALL) || (item[xx][yy+2]!=OWALL)) break;
X                    item[xx][yy+1] = item[xx][yy+2] = 0;
X                    eat(xx,yy+2);   break;
X            };
X        if (++dir > 4)  { dir=1;  --try; }
X        }
X    }
X
X/*
X *  function to read in a maze from a data file
X *
X *  Format of maze data file:  1st character = # of mazes in file (ascii digit)
X *              For each maze: 18 lines (1st 17 used) 67 characters per line
X *
X *  Special characters in maze data file:
X *
X *      #   wall            D   door            .   random monster
X *      ~   eye of larn     !   cure dianthroritis
X *      -   random object
X */
Xstatic cannedlevel(k)
X    int k;
X    {
X    char *row,*lgetl();
X    register int i,j;
X    int it,arg,mit,marg;
X    if (lopen(larnlevels)<0)
X        {
X        write(1,"Can't open the maze data file\n",30);   died(-282); return(0);
X        }
X    i=lgetc();  if (i<='0') { died(-282); return(0); }
X    for (i=18*rund(i-'0'); i>0; i--)    lgetl();   /* advance to desired maze */
X    for (i=0; i<MAXY; i++)
X        {
X        row = lgetl();
X        for (j=0; j<MAXX; j++)
X            {
X            it = mit = arg = marg = 0;
X            switch(*row++)
X                {
X                case '#': it = OWALL;                               break;
X                case 'D': it = OCLOSEDDOOR;     arg = rnd(30);      break;
X                case '~': if (k!=MAXLEVEL-1) break;
X                          it = OLARNEYE;
X                          mit = rund(8)+DEMONLORD;
X                          marg = monster[mit].hitpoints;            break;
X                case '!': if (k!=MAXLEVEL+MAXVLEVEL-1)  break;
X                          it = OPOTION;         arg = 21;
X                          mit = DEMONLORD+7;
X                          marg = monster[mit].hitpoints;            break;
X                case '.': if (k<MAXLEVEL)  break;
X                          mit = makemonst(k+1);
X                          marg = monster[mit].hitpoints;            break;
X                case '-': it = newobject(k+1,&arg);                 break;
X                };
X            item[j][i] = it;        iarg[j][i] = arg;
X            mitem[j][i] = mit;      hitp[j][i] = marg;
X
X#if WIZID
X            know[j][i] = (wizard) ? KNOWALL : 0;
X#else
X            know[j][i] = 0;
X#endif
X            }
X        }
X    lrclose();
X    return(1);
X    }
X
X/*
X    function to make a treasure room on a level
X    level 10's treasure room has the eye in it and demon lords
X    level V3 has potion of cure dianthroritis and demon prince
X */
Xstatic treasureroom(lv)
X    register int lv;
X    {
X    register int tx,ty,xsize,ysize;
X
X    for (tx=1+rnd(10);  tx<MAXX-10;  tx+=10)
X      if ( (lv==MAXLEVEL-1) || (lv==MAXLEVEL+MAXVLEVEL-1) || rnd(13)==2)
X        {
X        xsize = rnd(6)+3;       ysize = rnd(3)+3;  
X        ty = rnd(MAXY-9)+1;  /* upper left corner of room */
X        if (lv==MAXLEVEL-1 || lv==MAXLEVEL+MAXVLEVEL-1)
X            troom(lv,xsize,ysize,tx=tx+rnd(MAXX-24),ty,rnd(3)+6);
X            else troom(lv,xsize,ysize,tx,ty,rnd(9));
X        }
X    }
X
X/*
X *  subroutine to create a treasure room of any size at a given location 
X *  room is filled with objects and monsters 
X *  the coordinate given is that of the upper left corner of the room
X */
Xstatic troom(lv,xsize,ysize,tx,ty,glyph)
X    int lv,xsize,ysize,tx,ty,glyph;
X    {
X    register int i,j;
X    int tp1,tp2;
X    for (j=ty-1; j<=ty+ysize; j++)
X        for (i=tx-1; i<=tx+xsize; i++)          /* clear out space for room */
X            item[i][j]=0;
X    for (j=ty; j<ty+ysize; j++)
X        for (i=tx; i<tx+xsize; i++)             /* now put in the walls */
X            {
X            item[i][j]=OWALL; mitem[i][j]=0; 
X            }
X    for (j=ty+1; j<ty+ysize-1; j++)
X        for (i=tx+1; i<tx+xsize-1; i++)         /* now clear out interior */
X            item[i][j]=0;
X
X    switch(rnd(2))      /* locate the door on the treasure room */
X        {
X        case 1: item[i=tx+rund(xsize)][j=ty+(ysize-1)*rund(2)]=OCLOSEDDOOR;
X                iarg[i][j] = glyph;     /* on horizontal walls */
X                break;
X        case 2: item[i=tx+(xsize-1)*rund(2)][j=ty+rund(ysize)]=OCLOSEDDOOR;
X                iarg[i][j] = glyph;     /* on vertical walls */
X                break;
X        };
X
X    tp1=playerx;  tp2=playery;  playery=ty+(ysize>>1);
X    if (c[HARDGAME]<2)
X        for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2)
X            for (i=0, j=rnd(6); i<=j; i++)
X                { something(lv+2); createmonster(makemonst(lv+1)); }
X    else
X        for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2)
X            for (i=0, j=rnd(4); i<=j; i++)
X                { something(lv+2); createmonster(makemonst(lv+3)); }
X
X    playerx=tp1;  playery=tp2;
X    }
X
X/*
X    ***********
X    MAKE_OBJECT
X    ***********
X    subroutine to create the objects in the maze for the given level
X */
Xstatic makeobject(j)
X    register int j;
X    {
X    register int i;
X    if (j==0)
X        {
X        fillroom(OENTRANCE,0);      /*  entrance to dungeon         */
X        fillroom(ODNDSTORE,0);      /*  the DND STORE               */
X        fillroom(OSCHOOL,0);        /*  college of Larn             */
X        fillroom(OBANK,0);          /*  1st national bank of larn   */
X        fillroom(OVOLDOWN,0);       /*  volcano shaft to temple     */
X        fillroom(OHOME,0);          /*  the players home & family   */
X        fillroom(OTRADEPOST,0);     /*  the trading post            */
X        fillroom(OLRS,0);           /*  the larn revenue service    */
X        return;
X        }
X
X    if (j==MAXLEVEL) fillroom(OVOLUP,0); /* volcano shaft up from the temple */
X
X/*  make the fixed objects in the maze STAIRS   */
X    if ((j>0) && (j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1))
X        fillroom(OSTAIRSDOWN,0);
X	if ((j > 1) && (j != MAXLEVEL))
X		fillroom(OSTAIRSUP,0);
X
X/*  make the random objects in the maze     */
X
X    fillmroom(rund(3),OBOOK,j);             fillmroom(rund(3),OALTAR,0);
X    fillmroom(rund(3),OSTATUE,0);           fillmroom(rund(3),OPIT,0);
X    fillmroom(rund(3),OFOUNTAIN,0);         fillmroom( rnd(3)-2,OIVTELETRAP,0);
X    fillmroom(rund(2),OTHRONE,0);           fillmroom(rund(2),OMIRROR,0);
X    fillmroom(rund(2),OTRAPARROWIV,0);      fillmroom( rnd(3)-2,OIVDARTRAP,0);
X    fillmroom(rund(3),OCOOKIE,0);
X    if (j==1) fillmroom(1,OCHEST,j);
X        else fillmroom(rund(2),OCHEST,j);
X    if ((j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1))
X        fillmroom(rund(2),OIVTRAPDOOR,0);
X    if (j<=10)
X        {
X        fillmroom((rund(2)),ODIAMOND,rnd(10*j+1)+10);
X        fillmroom(rund(2),ORUBY,rnd(6*j+1)+6);
X        fillmroom(rund(2),OEMERALD,rnd(4*j+1)+4);
X        fillmroom(rund(2),OSAPPHIRE,rnd(3*j+1)+2);
X        }
X    for (i=0; i<rnd(4)+3; i++)
X        fillroom(OPOTION,newpotion());  /*  make a POTION   */
X    for (i=0; i<rnd(5)+3; i++)
X        fillroom(OSCROLL,newscroll());  /*  make a SCROLL   */
X    for (i=0; i<rnd(12)+11; i++)
X        fillroom(OGOLDPILE,12*rnd(j+1)+(j<<3)+10); /* make GOLD */
X    if (j==5)   fillroom(OBANK2,0);             /*  branch office of the bank */
X    froom(2,ORING,0);               /* a ring mail          */
X    froom(1,OSTUDLEATHER,0);        /* a studded leather    */
X    froom(3,OSPLINT,0);             /* a splint mail        */
X    froom(5,OSHIELD,rund(3));       /* a shield             */
X    froom(2,OBATTLEAXE,rund(3));    /* a battle axe         */
X    froom(5,OLONGSWORD,rund(3));    /* a long sword         */
X    froom(5,OFLAIL,rund(3));        /* a flail              */
X    froom(4,OREGENRING,rund(3));    /* ring of regeneration */
X    froom(1,OPROTRING,rund(3)); /* ring of protection   */
X    froom(2,OSTRRING,4);        /* ring of strength + 4 */
X    froom(7,OSPEAR,rnd(5));     /* a spear              */
X    froom(3,OORBOFDRAGON,0);    /* orb of dragon slaying*/
X    froom(4,OSPIRITSCARAB,0);       /*scarab of negate spirit*/
X    froom(4,OCUBEofUNDEAD,0);       /* cube of undead control   */
X    froom(2,ORINGOFEXTRA,0);    /* ring of extra regen      */
X    froom(3,ONOTHEFT,0);            /* device of antitheft      */
X    froom(2,OSWORDofSLASHING,0); /* sword of slashing */
X    if (c[BESSMANN]==0)
X        {
X        froom(4,OHAMMER,0);/*Bessman's flailing hammer*/ c[BESSMANN]=1;
X        }
X    if (c[HARDGAME]<3 || (rnd(4)==3))
X        {
X        if (j>3)
X            {
X            froom(3,OSWORD,3);      /* sunsword + 3         */
X            froom(5,O2SWORD,rnd(4));  /* a two handed sword */
X            froom(3,OBELT,4);           /* belt of striking     */
X            froom(3,OENERGYRING,3); /* energy ring          */
X            froom(4,OPLATE,5);      /* platemail + 5        */
X            }
X        }
X    }
X
X/*
X    subroutine to fill in a number of objects of the same kind
X */
X
Xstatic fillmroom(n,what,arg)
X    int n,arg;
X    char what;
X    {
X    register int i;
X    for (i=0; i<n; i++)     fillroom(what,arg);
X    }
Xstatic froom(n,itm,arg)
X    int n,arg;
X    char itm;
X    {   if (rnd(151) < n) fillroom(itm,arg);    }
X
X/*
X    subroutine to put an object into an empty room
X *  uses a random walk
X */
Xstatic fillroom(what,arg)
X    int arg;
X    char what;
X    {
X    register int x,y;
X
X#ifdef EXTRA
X    c[FILLROOM]++;
X#endif
X
X    x=rnd(MAXX-2);  y=rnd(MAXY-2);
X    while (item[x][y])
X        {
X
X#ifdef EXTRA
X        c[RANDOMWALK]++;    /* count up these random walks */
X#endif
X
X        x += rnd(3)-2;      y += rnd(3)-2;
X        if (x > MAXX-2)  x=1;       if (x < 1)  x=MAXX-2;
X        if (y > MAXY-2)  y=1;       if (y < 1)  y=MAXY-2;
X        }
X    item[x][y]=what;        iarg[x][y]=arg;
X    }
X
X/*
X    subroutine to put monsters into an empty room without walls or other
X    monsters
X */
Xfillmonst(what)
X    char what;
X    {
X    register int x,y,trys;
X    for (trys=5; trys>0; --trys) /* max # of creation attempts */
X      {
X      x=rnd(MAXX-2);  y=rnd(MAXY-2);
X      if ((item[x][y]==0) && (mitem[x][y]==0) && ((playerx!=x) || (playery!=y)))
X        {
X        mitem[x][y] = what;  know[x][y] &= ~KNOWHERE;
X        hitp[x][y] = monster[what].hitpoints;  return(0);
X        }
X      }
X    return(-1); /* creation failure */
X    }
X
X/*
X    creates an entire set of monsters for a level
X    must be done when entering a new level
X    if sethp(1) then wipe out old monsters else leave them there
X */
Xstatic sethp(flg)
X    int flg;
X    {
X    register int i,j;
X    if (flg) for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) stealth[j][i]=0;
X    if (level==0) { c[TELEFLAG]=0; return; } /* if teleported and found level 1 then know level we are on */
X    if (flg)   j = rnd(12) + 2 + (level>>1);   else   j = (level>>1) + 1;
X    for (i=0; i<j; i++)  fillmonst(makemonst(level));
X    positionplayer();
X    }
X
X/*
X *  Function to destroy all genocided monsters on the present level
X */
Xstatic checkgen()
X    {
X    register int x,y;
X    for (y=0; y<MAXY; y++)
X        for (x=0; x<MAXX; x++)
X            if (monster[mitem[x][y]].genocided)
X                mitem[x][y]=0; /* no more monster */
X    }
END_OF_FILE
if test 15787 -ne `wc -c <'create.c'`; then
    echo shar: \"'create.c'\" unpacked with wrong size!
fi
# end of 'create.c'
fi
if test -f 'diag.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'diag.c'\"
else
echo shar: Extracting \"'diag.c'\" \(13978 characters\)
sed "s/^X//" >'diag.c' <<'END_OF_FILE'
X/*  diag.c      Larn is copyrighted 1986 by Noah Morgan. */
X#ifdef VMS
X# include <types.h>
X# include <stat.h>
X#else
X# include <sys/types.h>
X# include <sys/stat.h>
X#endif VMS
X
X#ifndef MSDOS
X# ifndef VMS
X#  include <sys/times.h>
X  static struct tms cputime;
X# endif VMS
X#endif MSDOS
X
X#include "header.h"
Xextern long int initialtime;
Xextern int rmst,maxitm,lasttime;
Xextern char nosignal;
X
X/*
X    ***************************
X    DIAG -- dungeon diagnostics
X    ***************************
X
X    subroutine to print out data for debugging
X */
X#ifdef EXTRA
Xstatic int rndcount[16];
Xdiag()
X    {
X    register int i,j;
X    int hit,dam;
X    cursors();  lwclose();
X    if (lcreat(diagfile) < 0)   /*  open the diagnostic file    */
X        {
X        lcreat((char*)0); lprcat("\ndiagnostic failure\n"); return(-1);
X        }
X
X    write(1,"\nDiagnosing . . .\n",18);
X    lprcat("\n\nBeginning of DIAG diagnostics ----------\n");
X
X/*  for the character attributes    */
X
X    lprintf("\n\nPlayer attributes:\n\nHit points: %2d(%2d)",(long)c[HP],(long)c[HPMAX]);
X    lprintf("\ngold: %d  Experience: %d  Character level: %d  Level in caverns: %d",
X        (long)c[GOLD],(long)c[EXPERIENCE],(long)c[LEVEL],(long)level);
X    lprintf("\nTotal types of monsters: %d",(long)MAXMONST+8);
X
X    lprcat("\f\nHere's the dungeon:\n\n");
X
X    i=level;
X    for (j=0; j<MAXLEVEL+MAXVLEVEL; j++)
X        {
X        newcavelevel(j);
X        lprintf("\nMaze for level %s:\n",levelname[level]);
X        diagdrawscreen();
X        }
X    newcavelevel(i);
X
X    lprcat("\f\nNow for the monster data:\n\n");
X    lprcat("   Monster Name      LEV  AC   DAM  ATT  DEF    GOLD   HP     EXP   \n");
X    lprcat("--------------------------------------------------------------------------\n");
X    for (i=0; i<=MAXMONST+8; i++)
X        {
X        lprintf("%19s  %2d  %3d ",monster[i].name,(long)monster[i].level,(long)monster[i].armorclass);
X        lprintf(" %3d  %3d  %3d  ",(long)monster[i].damage,(long)monster[i].attack,(long)monster[i].defense);
X        lprintf("%6d  %3d   %6d\n",(long)monster[i].gold,(long)monster[i].hitpoints,(long)monster[i].experience);
X        }
X
X    lprcat("\n\nHere's a Table for the to hit percentages\n");
X    lprcat("\n     We will be assuming that players level = 2 * monster level");
X    lprcat("\n     and that the players dexterity and strength are 16.");
X    lprcat("\n    to hit: if (rnd(22) < (2[monst AC] + your level + dex + WC/8 -1)/2) then hit");
X    lprcat("\n    damage = rund(8) + WC/2 + STR - c[HARDGAME] - 4");
X    lprcat("\n    to hit:  if rnd(22) < to hit  then player hits\n");
X    lprcat("\n    Each entry is as follows:  to hit / damage / number hits to kill\n");
X    lprcat("\n          monster     WC = 4         WC = 20        WC = 40");
X    lprcat("\n---------------------------------------------------------------");
X    for (i=0; i<=MAXMONST+8; i++)
X        {
X        hit = 2*monster[i].armorclass+2*monster[i].level+16;
X        dam = 16 - c[HARDGAME];
X        lprintf("\n%20s   %2d/%2d/%2d       %2d/%2d/%2d       %2d/%2d/%2d",
X                    monster[i].name,
X                    (long)(hit/2),(long)max(0,dam+2),(long)(monster[i].hitpoints/(dam+2)+1),
X                    (long)((hit+2)/2),(long)max(0,dam+10),(long)(monster[i].hitpoints/(dam+10)+1),
X                    (long)((hit+5)/2),(long)max(0,dam+20),(long)(monster[i].hitpoints/(dam+20)+1));
X        }
X
X    lprcat("\n\nHere's the list of available potions:\n\n");
X    for (i=0; i<MAXPOTION; i++) lprintf("%20s\n",&potionname[i][1]);
X    lprcat("\n\nHere's the list of available scrolls:\n\n");
X    for (i=0; i<MAXSCROLL; i++) lprintf("%20s\n",&scrollname[i][1]);
X    lprcat("\n\nHere's the spell list:\n\n");
X    lprcat("spell          name           description\n");
X    lprcat("-------------------------------------------------------------------------------------------\n\n");
X    for (j=0; j<SPNUM; j++)
X        {
X        lprc(' ');  lprcat(spelcode[j]);
X        lprintf(" %21s  %s\n",spelname[j],speldescript[j]); 
X        }
X
X    lprcat("\n\nFor the c[] array:\n");
X    for (j=0; j<100; j+=10)
X        {
X        lprintf("\nc[%2d] = ",(long)j); for (i=0; i<9; i++) lprintf("%5d ",(long)c[i+j]);
X        }
X
X    lprcat("\n\nTest of random number generator ----------------");
X    lprcat("\n    for 25,000 calls divided into 16 slots\n\n");
X
X    for (i=0; i<16; i++)  rndcount[i]=0;
X    for (i=0; i<25000; i++) rndcount[rund(16)]++;
X    for (i=0; i<16; i++)  { lprintf("  %5d",(long)rndcount[i]); if (i==7) lprc('\n'); }
X
X    lprcat("\n\n");         lwclose();
X    lcreat((char*)0);       lprcat("Done Diagnosing . . .");
X    return(0);
X    }
X/*
X    subroutine to count the number of occurrences of an object
X */
Xdcount(l)
X    int l;
X    {
X    register int i,j,p;
X    int k;
X    k=0;
X    for (i=0; i<MAXX; i++)
X        for (j=0; j<MAXY; j++)
X            for (p=0; p<MAXLEVEL; p++)
X                if (cell[(long) p*MAXX*MAXY+i*MAXY+j].item == l) k++;
X    return(k);
X    }
X
X/*
X    subroutine to draw the whole screen as the player knows it
X */
Xdiagdrawscreen()
X    {
X    register int i,j,k;
X
X    for (i=0; i<MAXY; i++)
X
X/*  for the east west walls of this line    */
X        {
X        for (j=0; j<MAXX; j++)  if (k=mitem[j][i]) lprc(monstnamelist[k]); else
X                                lprc(objnamelist[item[j][i]]);
X        lprc('\n');
X        }
X    }
X#endif
X
X/*
X    to save the game in a file
X */
Xstatic long int zzz=0;
Xsavegame(fname)
X    char *fname;
X    {
X    extern char lastmonst[], course[];
X    register int i,k;
X    register struct sphere *sp;
X    struct stat statbuf;
X# ifdef MSDOS
X    struct  cel buf[MAXX];
X    RAMBLOCK    *rp;
X    DISKBLOCK   *dp;
X# endif
X
X    nosignal=1;  lflush();  savelevel();
X    ointerest();
X    if (lcreat(fname) < 0)
X        {
X        lcreat((char*)0); lprintf("\nCan't open file <%s> to save game\n",fname);
X        nosignal=0;  return(-1);
X        }
X
X    set_score_output();
X
X# ifdef MSDOS
X    lwrite((char*)beenhere,MAXLEVEL+MAXVLEVEL);
X
X    /* Some levels may be out on disk, some are in memory.
X     */
X    for (k = 0; k < MAXLEVEL + MAXVLEVEL; k++)
X        if (beenhere[k]) {
X
X            /* Is the level in memory already ?
X             */
X            for (rp = ramblks; rp; rp = rp->next)
X                if (rp->level == k)
X                    break;
X            if (rp != NULL) {
X                lwrite((char *) &rp->gtime, sizeof (long));
X                warn(" %d", k);
X# ifdef ndef
X                warn("From memory\n", k);
X# endif
X                lwrite((char *) rp->cell, sizeof rp->cell);
X                continue;
X            }
X
X            /* Is it on disk ?
X             */
X            for (dp = diskblks; dp; dp = dp->next)
X                if (dp->level == k)
X                    break;
X
X            if (dp == NULL) {
X                levelinfo();
X                error("Level %d is neither in memory nor on disk\n", k);
X            }
X
X            /* Copy the contents of the SWAPFILE */
X            lwrite((char *) &dp->gtime, sizeof (long));
X# ifdef ndef
X            warn("From swap file...\n", k);
X# endif
X            warn(" %ds", k);
X            if (lseek(swapfd, dp->fpos, 0) < 0) {
X                warn("Can't seek to %ld\n", dp->fpos);
X                return -1;
X            }
X            for (i = 0; i < MAXY; i++) {
X# ifdef ndef
X                warn("Copying swap file...\n");
X# endif
X                if (vread(swapfd, (char *) buf, sizeof buf) !=
X                    sizeof buf) {
X                    warn("Swap file short!\n");
X                    return -1;
X                }
X                lwrite((char *) buf, sizeof buf);
X            }
X        }
X# else
X    lwrite((char*)beenhere,MAXLEVEL+MAXVLEVEL);
X    for (k=0; k<MAXLEVEL+MAXVLEVEL; k++)
X        if (beenhere[k])
X            lwrite((char*)&cell[(long) k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
X# endif
X#ifndef VMS
X# ifndef MSDOS
X    times(&cputime);    /* get cpu time */
X    c[CPUTIME] += (cputime.tms_utime+cputime.tms_stime)/60;
X# endif MSDOS
X#endif VMS
X    lwrite((char*)&c[0],100*sizeof(long));
X    lprint((long)gtime);        lprc(level);
X    lprc(playerx);      lprc(playery);
X    lwrite((char*)iven,26); lwrite((char*)ivenarg,26*sizeof(short));
X    for (k=0; k<MAXSCROLL; k++)  lprc(scrollname[k][0]);
X    for (k=0; k<MAXPOTION; k++)  lprc(potionname[k][0]);
X    lwrite((char*)spelknow,SPNUM);       lprc(wizard);
X    lprc(rmst);     /*  random monster generation counter */
X    for (i=0; i<90; i++)    lprc(itm[i].qty);
X    lwrite((char*)course,25);           lprc(cheat);        lprc(VERSION);
X    for (i=0; i<MAXMONST; i++) lprc(monster[i].genocided); /* genocide info */
X    for (sp=spheres; sp; sp=sp->p)
X        lwrite((char*)sp,sizeof(struct sphere));    /* save spheres of annihilation */
X    time(&zzz);         lprint((long)(zzz-initialtime));
X    lwrite((char*)&zzz,sizeof(long));
X# ifndef MSDOS
X    if (fstat(lfd,&statbuf)< 0) lprint(0L);
X    else lprint((long)statbuf.st_ino); /* inode # */
X# endif
X
X    lwclose();  lastmonst[0] = 0;
X#ifndef VT100
X    setscroll();
X#endif VT100
X    lcreat((char*)0);  nosignal=0;
X    return(0);
X    }
X
Xrestoregame(fname)
X    char *fname;
X    {
X    register int i,k;
X    register struct sphere *sp,*sp2;
X    struct stat filetimes;
X# ifdef MSDOS
X    RAMBLOCK    *rp, *getramblk();
X# endif
X
X    cursors(); lprcat("\nRestoring . . .");  lflush();
X    if (lopen(fname) <= 0)
X        {
X        lcreat((char*)0); lprintf("\nCan't open file <%s>to restore game\n",fname);
X        nap(2000); c[GOLD]=c[BANKACCOUNT]=0;  died(-265); return;
X        }
X    lrfill((char*)beenhere,MAXLEVEL+MAXVLEVEL);
X
X# ifdef MSDOS
X    /* As levels get read in from the save file, store them away
X     * by calling putsavelevel.
X     */
X    for (k = 0; k < MAXLEVEL + MAXVLEVEL; k++)
X        if (beenhere[k]) {
X            rp = getramblk(k);
X            lrfill((char *) &rp->gtime, sizeof (long));
X            lrfill((char *) rp->cell, sizeof rp->cell);
X            rp->level = k;
X        }
X# else
X    for (k=0; k<MAXLEVEL+MAXVLEVEL; k++)
X        if (beenhere[k])
X            lrfill((char*)&cell[(long) k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
X# endif
X
X    lrfill((char*)&c[0],100*sizeof(long));  gtime = lrint();
X    level = c[CAVELEVEL] = lgetc();
X    playerx = lgetc();      playery = lgetc();
X    lrfill((char*)iven,26);     lrfill((char*)ivenarg,26*sizeof(short));
X    for (k=0; k<MAXSCROLL; k++)  scrollname[k][0] = lgetc();
X    for (k=0; k<MAXPOTION; k++)  potionname[k][0] = lgetc();
X    lrfill((char*)spelknow,SPNUM);      wizard = lgetc();
X    rmst = lgetc();         /*  random monster creation flag */
X
X    for (i=0; i<90; i++)    itm[i].qty = lgetc();
X    lrfill((char*)course,25);           cheat = lgetc();
X    if (VERSION != lgetc())     /*  version number  */
X        {
X        cheat=1;
X        lprcat("Sorry, But your save file is for an older version of larn\n");
X        nap(2000); c[GOLD]=c[BANKACCOUNT]=0;  died(-266); return;
X        }
X
X    for (i=0; i<MAXMONST; i++) monster[i].genocided=lgetc(); /* genocide info */
X    for (sp=0,i=0; i<c[SPHCAST]; i++)
X        {
X        sp2 = sp;
X        sp = (struct sphere *)malloc(sizeof(struct sphere));
X        if (sp==0) { write(2,"Can't malloc() for sphere space\n",32); break; }
X        lrfill((char*)sp,sizeof(struct sphere));    /* get spheres of annihilation */
X        sp->p=0;    /* null out pointer */
X        if (i==0) spheres=sp;   /* beginning of list */
X            else sp2->p = sp;
X        }
X
X    time(&zzz);
X    initialtime = zzz-lrint();
X    fstat(fd,&filetimes);   /*  get the creation and modification time of file  */
X    lrfill((char*)&zzz,sizeof(long));   zzz += 6;
X    if (filetimes.st_ctime > zzz) fsorry(); /*  file create time    */
X    else if (filetimes.st_mtime > zzz) fsorry(); /* file modify time    */
X    if (c[HP]<0) { died(284); return; } /* died a post mortem death */
X
X    oldx = oldy = 0;
X#ifndef VMS
X# ifndef MSDOS
X    i = lrint();  /* inode # */
X    if (i && (filetimes.st_ino!=i)) fsorry();
X# endif MSDOS
X#endif VMS
X    lrclose();
X    if (strcmp(fname,ckpfile) == 0)
X        {
X        if (lappend(fname) < 0) fcheat();  else { lprc(' '); lwclose(); }
X        lcreat((char*)0);
X        }
X    else if (unlink(fname) < 0) fcheat(); /* can't unlink save file */
X/*  for the greedy cheater checker  */
X    for (k=0; k<6; k++) if (c[k]>99) greedy();
X    if (c[HPMAX]>999 || c[SPELLMAX]>125) greedy();
X    if (c[LEVEL]==25 && c[EXPERIENCE]>skill[24]) /* if patch up lev 25 player */
X        {
X        long tmp;
X        tmp = c[EXPERIENCE]-skill[24]; /* amount to go up */
X        c[EXPERIENCE] = skill[24];
X        raiseexperience((long)tmp);
X        }
X    getlevel();  lasttime=gtime;
X    }
X
X/*
X    subroutine to not allow greedy cheaters
X */
Xstatic greedy()
X    {
X#if WIZID
X    if (wizard) return;
X#endif
X
X    lprcat("\n\nI am so sorry, but your character is a little TOO good!  Since this\n");
X    lprcat("cannot normally happen from an honest game, I must assume that you cheated.\n");
X    lprcat("In that you are GREEDY as well as a CHEATER, I cannot allow this game\n");
X    lprcat("to continue.\n"); nap(5000);  c[GOLD]=c[BANKACCOUNT]=0;  died(-267); return;
X    }
X
X/*
X    subroutine to not allow altered save files and terminate the attempted
X    restart
X */
Xstatic fsorry()
X    {
X    lprcat("\nSorry, but your savefile has been altered.\n");
X    lprcat("However, seeing as I am a good sport, I will let you play.\n");
X    lprcat("Be advised though, you won't be placed on the normal scoreboard.");
X    cheat = 1;  nap(4000);
X    }
X
X/*
X    subroutine to not allow game if save file can't be deleted
X */
Xstatic fcheat()
X    {
X#if WIZID
X    if (wizard) return;
X#endif
X
X    lprcat("\nSorry, but your savefile can't be deleted.  This can only mean\n");
X    lprcat("that you tried to CHEAT by protecting the directory the savefile\n");
X    lprcat("is in.  Since this is unfair to the rest of the larn community, I\n");
X    lprcat("cannot let you play this game.\n");
X    nap(5000);  c[GOLD]=c[BANKACCOUNT]=0;  died(-268); return;
X    }
END_OF_FILE
if test 13978 -ne `wc -c <'diag.c'`; then
    echo shar: \"'diag.c'\" unpacked with wrong size!
fi
# end of 'diag.c'
fi
if test -f 'header.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'header.h'\"
else
echo shar: Extracting \"'header.h'\" \(14883 characters\)
sed "s/^X//" >'header.h' <<'END_OF_FILE'
X/*  header.h        Larn is copyrighted 1986 by Noah Morgan. */
X
X#ifdef MSDOS
X#   define LARNHOME "\\"
X#endif
X
X#ifndef WIZID
X#   define WIZID  1000
X#endif
X
X#define TRUE 1
X#define FALSE 0
X#define VER    12
X#define SUBVER  2
X
X#ifdef VMS
X#define unlink(x)   delete(x)    /* remove a file */
X#endif
X
X#define SCORENAME   "larn.scr"
X#define LOGFNAME    "larn.log"
X#define HELPNAME    "larn.hlp"
X#define LEVELSNAME  "larn.maz"
X#define FORTSNAME   "larn.ftn"
X#define PLAYERIDS   "larn.pid"
X#define HOLIFILE    "holidays"
X#ifdef MSDOS
X#   define LARNOPTS "larn.opt"
X#   define SAVEFILE "larn.sav"
X#   define SWAPFILE "larn.swp"
X#   define CKPFILE  "larn.ckp"
X#else
X# ifdef VMS
X#   define LARNOPTS "larn.opt"
X#   define SAVEFILE "larn.sav"
X#   define CKPFILE  "larn.ckp"
X# else
X#   define LARNOPTS ".larnopts"
X#   define SAVEFILE "Larn.sav"
X#   define CKPFILE  "larn.ckp"
X#   define MAIL     /* disable the mail routines for MSDOS */
X# endif VMS
X#endif MSDOS
X
X#define MAXLEVEL 11    /*  max # levels in the dungeon         */
X#define MAXVLEVEL 3    /*  max # of levels in the temple of the luran  */
X#define MAXX 67
X#define MAXY 17
X
X#define SCORESIZE 10    /* this is the number of people on a scoreboard max */
X#define MAXPLEVEL 100   /* maximum player level allowed        */
X#define MAXMONST 56     /* maximum # monsters in the dungeon   */
X#define SPNUM 38        /* maximum number of spells in existance   */
X#define MAXSCROLL 28    /* maximum number of scrolls that are possible */
X#define MAXPOTION 35    /* maximum number of potions that are possible */
X#define TIMELIMIT 30000 /* maximum number of moves before the game is called */
X#define TAXRATE 1/20    /* tax rate for the LRS */
X#define MAXOBJ 93       /* the maximum number of objects   n < MAXOBJ */
X
X/*  this is the structure definition of the monster data    
X*/
Xstruct monst
X    {
X    char    *name;
X    char    level;
X    short   armorclass;
X    char    damage;
X    char    attack;
X    char    defense;
X    char    genocided;
X    char    intelligence; /* monsters intelligence -- used to choose movement */
X    short   gold;
X    short   hitpoints;
X    unsigned long experience;
X    };
X
X/*  this is the structure definition for the items in the dnd store */
Xstruct _itm
X    {
X    short   price;
X    char    **mem;
X    char    obj;
X    char    arg;
X    char    qty;
X    };
X
X/*  this is the structure that holds the entire dungeon specifications  */
Xstruct cel
X    {
X    short   hitp;   /*  monster's hit points    */
X    char    mitem;  /*  the monster ID          */
X    char    item;   /*  the object's ID         */
X    short   iarg;   /*  the object's argument   */
X    char    know;   /*  have we been here before*/
X    };
X
X/* this is the structure for maintaining & moving the spheres of annihilation */
Xstruct sphere
X    {
X    struct sphere *p;   /* pointer to next structure */
X    char x,y,lev;       /* location of the sphere */
X    char dir;           /* direction sphere is going in */
X    char lifetime;      /* duration of the sphere */
X    };
X
X# ifdef MSDOS
X/* Since only 1 level is needed at one time, each level can be swapped
X * to disk if there is not enough memory to allocate it.  Thus, there
X * need only be room for 1 level.  When a level is needed, if it is
X * already in memory, there is nothing to do.  If it isn't, get it from
X * disk after swapping out the oldest level - dgk.
X */
X# define FREEBLOCK  -99
Xtypedef struct _ramblock RAMBLOCK;
Xtypedef struct _diskblock DISKBLOCK;
Xstruct _ramblock {
X    RAMBLOCK    *next;          /* For a linked list */
X    int     level;          /* Level stored or FREEBLOCK */
X    long        gtime;          /* The time stored */
X    struct  cel cell[MAXX * MAXY];  /* The storage */
X};
Xstruct _diskblock {
X    DISKBLOCK   *next;          /* For linked list */
X    int     level;          /* Level stored or FREEBLOCK */
X    long        gtime;          /* The time stored */
X    long        fpos;           /* The disk position */
X};
Xextern RAMBLOCK *ramblks;
Xextern DISKBLOCK *diskblks;
X
X# endif MSDOS
X
X/*  defines for the character attribute array   c[] */
X#define STRENGTH 0      /* characters physical strength not due to objects */
X#define INTELLIGENCE 1
X#define WISDOM 2
X#define CONSTITUTION 3
X#define DEXTERITY 4
X#define CHARISMA 5
X#define HPMAX 6
X#define HP 7
X#define GOLD 8
X#define EXPERIENCE 9
X#define LEVEL 10
X#define REGEN 11
X#define WCLASS 12
X#define AC 13
X#define BANKACCOUNT 14
X#define SPELLMAX 15
X#define SPELLS 16
X#define ENERGY 17
X#define ECOUNTER 18
X#define MOREDEFENSES 19
X#define WEAR 20
X#define PROTECTIONTIME 21
X#define WIELD 22
X#define AMULET 23
X#define REGENCOUNTER 24
X#define MOREDAM 25
X#define DEXCOUNT 26
X#define STRCOUNT 27
X#define BLINDCOUNT 28
X#define CAVELEVEL 29
X#define CONFUSE 30
X#define ALTPRO 31
X#define HERO 32
X#define CHARMCOUNT 33
X#define INVISIBILITY 34
X#define CANCELLATION 35
X#define HASTESELF 36
X#define EYEOFLARN 37
X#define AGGRAVATE 38
X#define GLOBE 39
X#define TELEFLAG 40
X#define SLAYING 41
X#define NEGATESPIRIT 42
X#define SCAREMONST 43
X#define AWARENESS 44
X#define HOLDMONST 45
X#define TIMESTOP 46
X#define HASTEMONST 47
X#define CUBEofUNDEAD 48
X#define GIANTSTR 49
X#define FIRERESISTANCE 50
X#define BESSMANN 51
X#define NOTHEFT 52
X#define HARDGAME 53
X#define CPUTIME 54
X#define BYTESIN 55
X#define BYTESOUT 56
X#define MOVESMADE 57
X#define MONSTKILLED 58
X#define SPELLSCAST 59
X#define LANCEDEATH 60
X#define SPIRITPRO 61
X#define UNDEADPRO 62
X#define SHIELD 63
X#define STEALTH 64
X#define ITCHING 65
X#define LAUGHING 66
X#define DRAINSTRENGTH 67
X#define CLUMSINESS 68
X#define INFEEBLEMENT 69
X#define HALFDAM 70
X#define SEEINVISIBLE 71
X#define FILLROOM 72
X#define RANDOMWALK 73
X#define SPHCAST 74  /* nz if an active sphere of annihilation */
X#define WTW 75      /* walk through walls */
X#define STREXTRA 76 /* character strength due to objects or enchantments */
X#define TMP 77      /* misc scratch space */
X#define LIFEPROT 78 /* life protection counter */
X
X/*  defines for the objects in the game     */
X#define MAXOBJECT  92
X
X#define OALTAR 1
X#define OTHRONE 2
X#define OORB 3
X#define OPIT 4
X#define OSTAIRSUP 5
X#define OELEVATORUP 6
X#define OFOUNTAIN 7
X#define OSTATUE 8
X#define OTELEPORTER 9
X#define OSCHOOL 10
X#define OMIRROR 11
X#define ODNDSTORE 12
X#define OSTAIRSDOWN 13
X#define OELEVATORDOWN 14
X#define OBANK2 15
X#define OBANK 16
X#define ODEADFOUNTAIN 17
X#define OMAXGOLD 70
X#define OGOLDPILE 18
X#define OOPENDOOR 19
X#define OCLOSEDDOOR 20
X#define OWALL 21
X#define OTRAPARROW 66
X#define OTRAPARROWIV 67
X
X#define OLARNEYE 22
X
X#define OPLATE 23
X#define OCHAIN 24
X#define OLEATHER 25
X#define ORING 60
X#define OSTUDLEATHER 61
X#define OSPLINT 62
X#define OPLATEARMOR 63
X#define OSSPLATE 64
X#define OSHIELD 68
X#define OELVENCHAIN 92
X
X#define OSWORDofSLASHING 26
X#define OHAMMER 27
X#define OSWORD 28
X#define O2SWORD 29
X#define OSPEAR 30
X#define ODAGGER 31
X#define OBATTLEAXE 57
X#define OLONGSWORD 58
X#define OFLAIL 59
X#define OLANCE 65
X#define OVORPAL 90
X#define OSLAYER 91
X
X#define ORINGOFEXTRA 32
X#define OREGENRING 33
X#define OPROTRING 34
X#define OENERGYRING 35
X#define ODEXRING 36
X#define OSTRRING 37
X#define OCLEVERRING 38
X#define ODAMRING 39
X
X#define OBELT 40
X
X#define OSCROLL 41
X#define OPOTION 42
X#define OBOOK 43
X#define OCHEST 44             
X#define OAMULET 45
X
X#define OORBOFDRAGON 46
X#define OSPIRITSCARAB 47
X#define OCUBEofUNDEAD 48
X#define ONOTHEFT 49
X
X#define ODIAMOND 50
X#define ORUBY 51
X#define OEMERALD 52
X#define OSAPPHIRE 53
X
X#define OENTRANCE 54
X#define OVOLDOWN 55
X#define OVOLUP 56
X#define OHOME 69
X
X#define OKGOLD 71
X#define ODGOLD 72
X#define OIVDARTRAP 73
X#define ODARTRAP 74
X#define OTRAPDOOR 75
X#define OIVTRAPDOOR 76
X#define OTRADEPOST 77
X#define OIVTELETRAP 78
X#define ODEADTHRONE 79
X#define OANNIHILATION 80        /* sphere of annihilation */
X#define OTHRONE2 81
X#define OLRS 82             /* Larn Revenue Service */
X#define OCOOKIE 83
X#define OURN 84
X#define OBRASSLAMP 85
X#define OHANDofFEAR 86      /* hand of fear */
X#define OSPHTAILSMAN 87     /* tailsman of the sphere */
X#define OWWAND 88           /* wand of wonder */
X#define OPSTAFF 89          /* staff of power */
X/* used up to 92 */
X
X/*  defines for the monsters as objects     */
X
X#define BAT 1 
X#define GNOME 2
X#define HOBGOBLIN 3
X#define JACKAL 4 
X#define KOBOLD 5 
X#define ORC 6 
X#define SNAKE 7
X#define CENTIPEDE 8
X#define JACULI 9 
X#define TROGLODYTE 10 
X#define ANT 11 
X#define EYE 12 
X#define LEPRECHAUN 13
X#define NYMPH 14
X#define QUASIT 15 
X#define RUSTMONSTER 16 
X#define ZOMBIE 17 
X#define ASSASSINBUG 18 
X#define BUGBEAR 19 
X#define HELLHOUND 20 
X#define ICELIZARD 21 
X#define CENTAUR 22 
X#define TROLL 23 
X#define YETI 24 
X#define WHITEDRAGON 25
X#define ELF 26
X#define CUBE 27 
X#define METAMORPH 28 
X#define VORTEX 29 
X#define ZILLER 30 
X#define VIOLETFUNGI 31 
X#define WRAITH 32 
X#define FORVALAKA 33 
X#define LAMANOBE 34 
X#define OSEQUIP 35 
X#define ROTHE 36
X#define XORN 37 
X#define VAMPIRE 38
X#define INVISIBLESTALKER 39 
X#define POLTERGEIST 40 
X#define DISENCHANTRESS 41 
X#define SHAMBLINGMOUND 42 
X#define YELLOWMOLD 43
X#define UMBERHULK 44
X#define GNOMEKING 45
X#define MIMIC 46
X#define WATERLORD 47
X#define BRONZEDRAGON 48
X#define GREENDRAGON 49
X#define PURPLEWORM 50
X#define XVART 51
X#define SPIRITNAGA 52
X#define SILVERDRAGON 53
X#define PLATINUMDRAGON 54
X#define GREENURCHIN 55
X#define REDDRAGON 56
X#define DEMONLORD 57
X#define DEMONPRINCE 64
X
X# ifdef MSDOS
X#  define NULL 0L       /* For large model only */
X# else
X#  define NULL 0
X# endif MSDOS
X#define BUFBIG  4096            /* size of the output buffer */
X#define MAXIBUF 4096            /* size of the input buffer */
X#define LOGNAMESIZE 40          /* max size of the players name */
X#define PSNAMESIZE 40           /* max size of the process name */
X#define SAVEFILENAMESIZE 128    /* max size of the savefile path */
X
X#ifndef NODEFS
Xextern char floorc, wallc;
Xextern char boldobjects;
Xextern char auto_pickup;
Xextern char VERSION,SUBVERSION;
Xextern char aborted[],beenhere[],boldon,cheat,ckpfile[],ckpflag;
Xextern char *class[],course[],diagfile[],fortfile[],helpfile[],holifile[];
Xextern char ckpfile[];
X# ifdef MSDOS
Xextern int  swapfd;
Xextern char swapfile[];
Xextern long tell(), lseek();
X# endif
Xextern char *inbuffer;
Xextern char item[MAXX][MAXY],iven[],know[MAXX][MAXY],larnlevels[],lastmonst[];
Xextern char level,*levelname[],logfile[],loginname[],logname[],*lpbuf,*lpend;
Xextern char *lpnt,mitem[MAXX][MAXY],monstlevel[];
Xextern char monstnamelist[],nch[],ndgg[],nlpts[],nomove,nosignal,nowelcome;
Xextern char nplt[],nsw[],*objectname[];
Xextern char hacklike_objnamelist[];
Xextern char original_objnamelist[];
Xextern char objnamelist[],optsfile[],*potionname[],playerids[],potprob[];
Xextern char predostuff,psname[],restorflag,savefilename[],scorefile[],scprob[];
Xextern char screen[MAXX][MAXY],*scrollname[],sex,*spelcode[],*speldescript[];
Xextern char spelknow[],*spelname[],*spelmes[],spelweird[MAXMONST+8][SPNUM];
Xextern char splev[],stealth[MAXX][MAXY],wizard;
Xextern short diroffx[],diroffy[],hitflag,hit2flag,hit3flag,hitp[MAXX][MAXY];
Xextern short iarg[MAXX][MAXY],ivenarg[],lasthx,lasthy,lastnum,lastpx,lastpy;
Xextern short nobeep,oldx,oldy,playerx,playery;
Xextern int dayplay,enable_scroll,srcount,yrepcount,userid,wisid,lfd,fd;
Xextern long initialtime,outstanding_taxes,skill[],gtime,c[],cbak[];
Xextern unsigned long lrandx;
X# ifndef MSDOS      /* Different storage under MSDOS */
Xextern struct cel *cell;
X# endif
Xextern struct monst monster[];
Xextern struct sphere *spheres;
Xextern struct _itm itm[];
X
Xvoid *malloc();
Xchar *fortune(),*getenv(),*getlogin(),*lgetw(),*lgetl(),*ctime();
Xchar *tmcapcnv(),*tgetstr(),*tgoto();
Xlong paytaxes(),lgetc(),lrint(),time();
Xunsigned long readnum();
X
X    /* macro to create scroll #'s with probability of occurrence */
X#define newscroll() (scprob[rund(81)])
X    /* macro to return a potion # created with probability of occurrence */
X#define newpotion() (potprob[rund(41)])
X    /* macro to return the + points on created leather armor */
X#define newleather() (nlpts[rund(c[HARDGAME]?13:15)])
X    /* macro to return the + points on chain armor */
X#define newchain() (nch[rund(10)])
X    /* macro to return + points on plate armor */
X#define newplate() (nplt[rund(c[HARDGAME]?4:12)])
X    /* macro to return + points on new daggers */
X#define newdagger() (ndgg[rund(13)])
X    /* macro to return + points on new swords */
X#define newsword() (nsw[rund(c[HARDGAME]?6:13)])
X    /* macro to destroy object at present location */
X#define forget() (item[playerx][playery]=know[playerx][playery]=0)
X    /* macro to wipe out a monster at a location */
X#define disappear(x,y) (mitem[x][y]=know[x][y]=0)
X
X#ifdef VT100
X    /* macro to turn on bold display for the terminal */
X#define setbold() (lprcat(boldon?"\33[1m":"\33[7m"))
X    /* macro to turn off bold display for the terminal */
X#define resetbold() (lprcat("\33[m"))
X    /* macro to setup the scrolling region for the terminal */
X#define setscroll() (lprcat("\33[20;24r"))
X    /* macro to clear the scrolling region for the terminal */
X#define resetscroll() (lprcat("\33[;24r"))
X    /* macro to clear the screen and home the cursor */
X#define clear() (lprcat("\33[2J\33[f"), cbak[SPELLS]= -50)
X#define cltoeoln() lprcat("\33[K")
X#else /* VT100 */
X    /* defines below are for use in the termcap mode only */
X#define ST_START 1
X#define ST_END   2
X#define BOLD     3
X#define END_BOLD 4
X#define CLEAR    5
X#define CL_LINE  6
X#define T_INIT   7
X#define T_END    8
X#define CL_DOWN 14
X#define CURSOR  15
X    /* macro to turn on bold display for the terminal */
X#define setbold() (*lpnt++ = ST_START)
X    /* macro to turn off bold display for the terminal */
X#define resetbold() (*lpnt++ = ST_END)
X    /* macro to setup the scrolling region for the terminal */
X#define setscroll() enable_scroll=1
X    /* macro to clear the scrolling region for the terminal */
X#define resetscroll() enable_scroll=0
X    /* macro to clear the screen and home the cursor */
X#define clear() (*lpnt++ =CLEAR, cbak[SPELLS]= -50)
X    /* macro to clear to end of line */
X#define cltoeoln() (*lpnt++ = CL_LINE)
X#endif /* VT100 */
X
X    /* macro to output one byte to the output buffer */
X#define lprc(ch) ((lpnt>=lpend)?(*lpnt++ =(ch), lflush()):(*lpnt++ =(ch)))
X
X    /* macro to seed the random number generator */
X#define srand(x) (lrandx=x)
X#ifdef MACRORND
X    /* macros to generate random numbers   1<=rnd(N)<=N   0<=rund(N)<=N-1 */
X#define rnd(x)  ((((lrandx=lrandx*1103515245+12345)>>7)%(x))+1)
X#define rund(x) ((((lrandx=lrandx*1103515245+12345)>>7)%(x))  )
X#endif /* MACRORND */
X
X# ifdef DGK
X#  define HAVESEEN  0x1
X#  define KNOWHERE  0x2
X#  define KNOWALL   (HAVESEEN | KNOWHERE)
X# ifdef DGK_MSDOS
X#  define PATHLEN   80
X#  define DIRLEN    64
X   extern   char    larndir[];
X   extern int       raw_io, DECRainbow, keypad, ramlevels, cursorset;
X   extern unsigned char cursorstart, cursorend;
X# endif DGK_MSDOS
X#endif DGK
Xextern char prompt_mode ;
X#endif /* NODEFS */
END_OF_FILE
if test 14883 -ne `wc -c <'header.h'`; then
    echo shar: \"'header.h'\" unpacked with wrong size!
fi
# end of 'header.h'
fi
if test -f 'nansi.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'nansi.doc'\"
else
echo shar: Extracting \"'nansi.doc'\" \(6967 characters\)
sed "s/^X//" >'nansi.doc' <<'END_OF_FILE'
XSYNOPSIS
X	Include in \config.sys the line
X		device=nansi.sys
X
XDESCRIPTION
X	Nansi.sys is a console driver which understands ANSI control
X	sequences. It has several advantages over ANSI.SYS (the driver
X	supplied with DOS):
X	1. It supports new escape sequences (see below).
X	2. It provides MUCH faster output under certain conditions.
X	3. It supports the 43-line mode of the EGA.
X	4. The darned bell is now 1/4 second instead of 1/2 second long.
X
X	What a console driver does:
X	When you, for example, type
X		C:> type foo.txt
X	COMMAND.COM opens the file foo.txt, reads it, and writes it to
X	the console driver, which puts it up on the screen.
X
X	Both ansi.sys and nansi.sys use IBM Video BIOS to control the screen.
X	However, nansi.sys bypasses BIOS if the screen is in a text mode; this
X	allows much faster operation under certain conditions.
X
X	While putting text up on the screen, (n)ansi.sys keeps a lookout for
X	the escape character (chr(27), known as ESC); this character signals
X	the start of a terminal control sequence.
X	Terminal control sequences follow the format
X		ESC [ param; param; ...; param cmd
X	where
X		ESC	is the escape character chr$(27).
X		[	is the left bracket character.
X		param	is an ASCII decimal number, or a string in quotes.
X		cmd	is a case-specific letter identifying the command.
X	Usually, zero, one, or two parameters are given.  If parameters
X	are omitted, they usually default to 1; however, some commands
X	(KKR and DKOCT) treat the no-parameter case specially.
X	Spaces are not allowed between parameters.
X
X	For example, both ESC[1;1H and ESC[H send the cursor to the home
X	position (1,1), which is the upper left.
X
X	Either single or double quotes may be used to quote a string.
X	Each character inside a quoted string is equivalent to one numeric
X	parameter.  Quoted strings are normally used only for the Keyboard
X	Key Reassignment command.
X
XControl Sequences
X	The following table lists the sequences understood by nansi.sys.
X	Differences between nansi.sys and the standard ansi.sys are marked
X	with a vertical bar (|).
X
XCursor Positioning
XShort	Long name		Format		Notes
XCUP	cursor position		ESC[y;xH	Sets cursor position.
XHVP	cursor position		ESC[y;xf	Same as CUP; not recommended.
XCUU	cursor up		ESC[nA		n = # of lines to move
XCUD	cursor down		ESC[nB
XCUF	cursor forward		ESC[nC		n = # of columns to move
XCUB	cursor backward		ESC[nD
XDSR	Device Status, Report!	ESC[6n		Find out cursor position.
XCPR	Cursor Position report	ESC[y;xR	Response to DSR, as if typed.
XSCP	Save Cursor Position	ESC[s		Not nestable.
XRCP	Restore Cursor Position ESC[u
X
XEditing
XED	Erase in Display	ESC[2J	Clears screen.
XEL	Erase in Line		ESC[K	Clears to end of line.
XIL  |	Insert Lines		ESC[nL	Inserts n blank lines at cursor line.
XDL  |	Delete Lines		ESC[nM	Deletes n lines including cursor line.
XICH |	Insert Characters	ESC[n@	Inserts n blank chars at cursor.
XDCH |	Delete Characters	ESC[nP	Deletes n chars including cursor char.
X
X
XMode-Setting
XSGR	Set Graphics Rendition	ESC[n;n;...nm	See character attribute table.
XSM	Set Mode		ESC[=nh		See screen mode table.
XRM	Reset Mode		ESC[=nl		See screen mode table.
XIBMKKR	Keyboard Key Reass.	ESC["string"p
X	The first char of the string gives the key to redefine; the rest
X	of the string is the key's new value.
X	To specify unprintable chars, give the ASCII value of the char
X	outside of quotes, as a normal parameter.
X	IBM function keys are two byte strings; see the IBM Basic manual.
X	For instance, ESC[0;";dir a:";13;p redefines function key 1 to
X	have the value "dir a:" followed by the ENTER key.
X      | If no parameters given, all keys are reset to their default values.
X
XDKOCT | Output char translate	ESC[n;ny
X      | When first char is encountered in output request, it is replaced with
X      | the second char.  This might be useful for previewing text before
X      | sending it to a printer with a funny print wheel.
X      | If no parameters are given, all chars are reset to normal.
X
X
XCharacter Attributes
X	The Set Graphics Rendition command is used to select foreground
X	and background colors or attributes.
X	When you use multiple parameters, they are executed in sequence, and
X	the effects are cumulative.
X	   Attrib code		Value
X		0		All attributes off (normal white on black)
X		1		Bold
X		4		Underline
X		5		Blink
X		7		Reverse Video
X		8		Invisible (but why?)
X		30-37		foregnd blk/red/grn/yel/blu/magenta/cyan/white
X		40-47		background
X
XScreen Modes
X	The IBM BIOS supports several video modes; the codes given in the
X	BIOS documentation are used as parameters to the Set Mode command.
X      | (In bitmap modes, the cursor is simulated with a small blob (^V).)
X	    Mode Code		Value
X		0		text 40x25 Black & White
X		1		text 40x25 Color
X		2		text 80x25 Black & White
X		3		text 80x25 Color
X		4		bitmap 320x200 4 bits/pixel
X		5		bitmap 320x200 1 bit/pixel
X		6		bitmap 640x200 1 bit/pixel
X		7		(cursor wrap kludge)
X		13 (EGA)	bitmap 320x200 4 bits/pixel ?
X		14 (EGA)	bitmap 640x200 4 bits/pixel
X		16 (EGA)	bitmap 640x350 4 bits/pixel
X	Mode 7 is an unfortunate kludge; Setting mode 7 tells the cursor
X	to wrap around to the next line when it passes the end of a line;
X	Resetting mode 7 tells the cursor to not wrap, but rather stay put.
X      | If your computer has the Enhanced Graphics Adaptor, modes between
X      | 8 and 15 are also supported; see the EGA BIOS for info.
X      | The EGA also lets you use a shorter character cell in text modes
X      | in order to squeeze 43 lines of text out of the 25-line text modes.
X      | To enter 43 line mode, set the desired 25-line text mode (0 to 3),
X      | then Set Mode 43.  For instance: ESC[=3h ESC[=43h.
X      | To exit 43 line mode, set the desired 25-line text mode again.
X      | Nansi.sys ignores mode 43 unless there is an EGA on your computer.
X
XFaster Output
X      | Any program that sets the console to RAW mode, and buffers its
X      | output properly, can achieve extremely high screen update speeds in
X      | return for giving up the special functions of the keys ^C, ^S, and ^P.
X      | See IOCTL in the MS-DOS 3.x Technical Reference for more info.
X	Also, a small improvement in speed may be noticed with some
X	programs that use the DOS console in normal mode, as this driver
X	efficiently implements the (standard but undocumented) INT 29h
X	most-favored-device putchar used by DOS.
X
XBUGS
X	Insert and delete character do not work in graphics modes.
X	Graphics mode writing is slow.
X	The simulated cursor in graphics mode slows down single-char
X	writes by a factor of 3; it should be disable-able.
X	Does not support erase-to-end-of-screen and other useful functions.
X
XVersion
X	This version, 2.2, created February 1986.  Problems should
X	be reported to Daniel Kegel, 1-60 CIT, Pasadena, CA 91126
X	(or, after June 1986, 2648 169th Ave SE, Bellevue, Wa. 98008).
X	Your suggestions for improvement would be most welcome.
X
XNOTE
X	This program may be distributed for educational and personal use
X	only.  Commercial use is verboten; get in touch with the author.
END_OF_FILE
if test 6967 -ne `wc -c <'nansi.doc'`; then
    echo shar: \"'nansi.doc'\" unpacked with wrong size!
fi
# end of 'nansi.doc'
fi
echo shar: End of archive 8 \(of 11\).
cp /dev/null ark8isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 11 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