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