[comp.sources.games] v07i002: ularn - ultra-larn, an enhancement of the larn adventure game, Part02/08

billr@saab.CNA.TEK.COM (Bill Randle) (07/06/89)

Submitted-by: "Philip A. Cordier" <philc@sco.COM>
Posting-number: Volume 7, Issue 2
Archive-name: ularn/Part02



#! /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 2 (of 8)."
# Contents:  monster.c signal.c
# Wrapped by billr@saab on Thu Jun 29 08:10:17 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'monster.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'monster.c'\"
else
echo shar: Extracting \"'monster.c'\" \(46657 characters\)
sed "s/^X//" >'monster.c' <<'END_OF_FILE'
X/*
X *	monster.c
X *
X *	This file contains the following functions:
X *	------------------------------------------------------------------------
X *
X *	createmonster(monstno)	Function to create a monster next to the player
X *		int monstno;
X *
X *	int cgood(x,y,itm,monst)	Function to check location for emptiness
X *		int x,y,itm,monst;
X *
X *	createitem(it,arg) 	Routine to place an item next to the player
X *		int it,arg;
X *
X *	cast() 		Subroutine called by parse to cast a spell for the user
X *
X *	speldamage(x) 	Function to perform spell functions cast by the player
X *		int x;
X *
X *	loseint()	Routine to decrement your int (intelligence) if > 3
X *
X *	isconfuse() 	Routine to check to see if player is confused
X *
X *	nospell(x,monst) Routine to return 1 if a spell doesn't affect a monster
X *		int x,monst;
X *
X *	fullhit(xx)	Function to return full damage against a monst (aka web)
X *		int xx;
X *
X *			Routine to direct spell damage 1 square in 1 dir
X *	direct(spnum,dam,str,arg)	
X *		int spnum,dam,arg;
X *		char *str;
X *
X *			Function to perform missile attacks
X *	godirect(spnum,dam,str,delay,cshow)		
X *		int spnum,dam,delay;
X *		char *str,cshow;
X *
X *		  Routine to put "monster" or the monster name into lastmosnt
X *	ifblind(x,y)	
X *		int x,y;
X *
X *	tdirect(spnum)		Routine to teleport away a monster
X *		int spnum;
X *
X *		  	Routine to damage all monsters 1 square from player
X *	omnidirect(sp,dam,str)  
X *		int sp,dam;
X *		char *str;
X *
X *	dirsub(x,y)	Routine to ask for direction, then modify x,y for it
X *	int *x,*y;
X *
X *	vxy(x,y)  	Routine to verify/fix (*x,*y) for being within bounds
X *		int *x,*y;
X *
X *	dirpoly(spnum)	Routine to ask for a direction and polymorph a monst
X *		int spnum;
X *
X *	hitmonster(x,y) Function to hit a monster at the designated coordinates
X *		int x,y;
X *
X *	hitm(x,y,amt)	Function to just hit a monster at a given coordinates
X *		int x,y,amt;
X *
X *	hitplayer(x,y) 	Function for the monster to hit the player from (x,y)
X *		int x,y;
X *
X *	dropsomething(monst) 	Function to create an object when a monster dies
X *		int monst;
X *
X *	dropgold(amount)	Function to drop some gold around player
X *		int amount;
X *
X *	something(level) 	Function to create a random item around player
X *		int level;
X *
X *	newobject(lev,i) 	Routine to return a randomly selected new object
X *		int lev,*i;
X *
X *  spattack(atckno,xx,yy)    Function to process special attacks from monsters
X *  	int atckno,xx,yy;
X *
X *		   Routine to subtract hp from user and flag bottomline display
X *	checkloss(x) 	
X *		int x;
X *
X *		   Routine to annihilate monsters around player, playerx,playery
X *	annihilate()   
X *
X *		  Function to create a new sphere of annihilation
X *	newsphere(x,y,dir,lifetime)  
X *		int x,y,dir,lifetime;
X *
X *	rmsphere(x,y)	Function to delete a sphere of annihilation from list
X *		int x,y;
X *
X *	sphboom(x,y)	Function to perform the effects of a sphere detonation
X *		int x,y;
X *
X *	genmonst()	Function to ask for monster and genocide from game
X *
X */
X#include "header.h"
X
Xstruct isave	/* used for altar reality */
X{
X	char type;	/* 0=item,  1=monster */
X	char id;	/* item number or monster number */
X	short arg;	/* the type of item or hitpoints of monster */
X};
X
X/*
X *		Function to create a monster next to the player
X *	createmonster(monstno) 		
X *		int monstno;
X *
X *	Enter with the monster number (1 to MAXMONST+8)
X *	Returns no value.
X */
Xcreatemonster(mon)
Xint mon;
X{
X	register int x,y,k,i;
X	if (mon<1 || mon>MAXMONST+8)	{
X		beep(); 
X		lprintf("\ncan't createmonst(%d)\n",(long)mon); 
X		nap(3000); 
X		return;
X	}
X	while (monster[mon].genocided && mon<MAXMONST) 
X		mon++; /* genocided? */
X	for (k=rnd(8), i= -8; i<0; i++,k++)/* choose direction, then try all */
X	{
X		if (k>8) k=1;		/* wraparound the diroff arrays */
X		x = playerx + diroffx[k];		
X		y = playery + diroffy[k];
X		if (cgood(x,y,0,1))	/* if we can create here */
X		{
X			mitem[x][y] = mon;
X			hitp[x][y] = monster[mon].hitpoints;
X			stealth[x][y]=know[x][y]=0;
X			switch(mon) {
X			case ROTHE: 
X			case POLTERGEIST: 
X			case VAMPIRE:    
X				stealth[x][y]=1;
X			};
X			return;
X		}
X	}
X}
X
X/*
X *	int cgood(x,y,itm,monst)	Function to check location for emptiness
X *		int x,y,itm,monst;
X *
X *	Routine to return TRUE if a location does not have itm or monst there
X *	returns FALSE (0) otherwise
X *	Enter with itm or monst TRUE or FALSE if checking it
X *	Example:  if itm==TRUE check for no item at this location
X *			  if monst==TRUE check for no monster at this location
X *	This routine will return FALSE if at a wall or the dungeon exit on level 1
X */
Xcgood(x,y,itm,monst)
Xregister int x,y;
Xint itm,monst;
X{
X	if ((y>=0) && (y<=MAXY-1) 
X	    && (x>=0) && (x<=MAXX-1)) 		/* within bounds? */
X	  if (item[x][y]!=OWALL)		/* can't make on walls */
X	    if (itm==0 || (item[x][y]==0))	/* is it free of items? */
X		if (monst==0 || (mitem[x][y]==0)) /*is it free of monsters? */
X			if ((level!=1) || (x!=33) || (y!=MAXY-1)) 
X				/* not exit to level 1 */
X				return(1);
X	return(0);
X}
X
X/*
X *	createitem(it,arg) 	Routine to place an item next to the player
X *		int it,arg;
X *
X *	Enter with the item number and its argument (iven[], ivenarg[])
X *	Returns no value, thus we don't know about createitem() failures.
X */
Xcreateitem(it,arg)
Xint it;
Xlong arg;
X{
X	register int x,y,k,i;
X
X	if (it >= MAXOBJ) 
X		return;	/* no such object */
X
X	for (k=rnd(8), i= -8; i<0; i++,k++) { /* choose direction, try all */
X		if (k>8) k=1;		/* wraparound the diroff arrays */
X		x = playerx + diroffx[k];
X		y = playery + diroffy[k];
X		if ( (it != OMAXGOLD && it != OGOLDPILE) ) {
X		    if (cgood(x,y,1,0)) {	/* if we can create here */
X			item[x][y] = it;  
X			know[x][y]=0;  
X			iarg[x][y]=arg;  
X			return;
X		    }
X		}
X		else {
X			int i;
X			switch (item[x][y]) {
X			case OGOLDPILE :
X				if ( (iarg[x][y] + arg) < 32767) {
X					iarg[x][y] += arg;
X					return;
X				}
X			case ODGOLD :
X				if ( (10 * iarg[x][y] + arg) < 327670L) {
X					i = iarg[x][y] ;
X					iarg[x][y] = (10 * i + arg) / 10;
X					item[x][y] = ODGOLD;
X					return;
X				}
X			case OMAXGOLD :
X				if ( (100 * iarg[x][y] + arg) < 3276700L) {
X					i = (100 * iarg[x][y]) + arg;
X					iarg[x][y] = i / 100;
X					item[x][y] = OMAXGOLD;
X					return;
X				}
X			case OKGOLD :
X				if ( (1000 * iarg[x][y] + arg) < 32767000L) { 
X					i = iarg[x][y];
X					iarg[x][y] = (1000 * i + arg) / 1000;
X					item[x][y] = OKGOLD;
X					return;
X				}
X				else iarg[x][y] = 32767000L; 
X				return;
X			default :
X		    		if (cgood(x,y,1,0)) {
X					item[x][y] = it;  
X					know[x][y]=0;  
X					if (it == OMAXGOLD)
X						iarg[x][y]= arg / 100;  
X					else iarg[x][y]=arg;  
X					return;
X				}
X			} /* end switch */
X		} /* end else */
X	} /* end for */
X}
X
X/*
X *	cast() 		Subroutine called by parse to cast a spell for the user
X *
X *	No arguments and no return value.
X */
Xstatic char eys[] = "\nEnter your spell: ";
X
Xcast()
X{
X	register int i,j,a,b,d;
X
X	cursors();
X	if (c[SPELLS]<=0) {	
X		lprcat("\nYou don't have any spells!");	
X		return;	
X	}
X	lprcat(eys);		
X	--c[SPELLS];
X	while ((a=getcharacter())=='D') { 	
X		seemagic(-1); 
X		cursors();  
X		lprcat(eys); 
X	}
X	if (a=='\33') goto over; 	/* to escape casting a spell	*/
X	if ((b=getcharacter())=='\33') goto over; /*to escape casting a spell */
X	if ((d=getcharacter())=='\33') { 
Xover: 
X		lprcat(aborted); 
X		c[SPELLS]++; 
X		return; 
X	} 			/* to escape casting a spell */
X	/*seq search for his spell, hash?*/
X	for (lprc('\n'),j= -1,i=0; i<SPNUM+1; i++) 
X		if ((spelcode[i][0]==a) && (spelcode[i][1]==b) && (spelcode[i][2]==d))
X			if (spelknow[i]) {  	
X				speldamage(i);  
X				j = 1;  
X				i=SPNUM+1;
X			}
X
X	if (j == -1) lprcat("  Nothing Happened ");
X	bottomline();
X}
X
X/*
X *	speldamage(x)	Function to perform spell functions cast by the player
X *	int x;
X *
X *	Enter with the spell number, returns no value.
X *	Please insure that there are 2 spaces before all messages here
X */
Xspeldamage(x)
Xint x;
X{
X	register int i,j,clev;
X	int xl,xh,yl,yh;
X	register char *p,*kn,*pm;
X
X	if (x>=SPNUM+1) return;	/* no such spell */
X
X	if (c[TIMESTOP])  { 	
X		lprcat("  It didn't seem to work"); 
X		return; 
X	}  /* not if time stopped */
X
X	if ((rnd(23)==7) || (rnd(18) > c[INTELLIGENCE]))
X	{ 	
X		lprcat("  It didn't work!");  
X		return; 
X	}
X
X	clev = c[LEVEL];
X	if (clev*3+2 < x) 
X	{ 	
X		lprcat("  Nothing happens.  You seem inexperienced at this"); 
X		return; 
X	}
X
X	switch(x)
X	{
X		/* ----- LEVEL 1 SPELLS ----- */
X
X	case 0:	
X		if (c[PROTECTIONTIME]==0)
X			c[MOREDEFENSES]+=2; /* protection field +2 */
X		c[PROTECTIONTIME] += 250;   
X		return;
X
X	case 1: 
X		i = rnd(((clev+1)<<1)) + clev + 3;
X		godirect(x,i,(clev>=2)?"  Your missiles hit the %s":"  Your missile hit the %s",100,'+'); /* magic missile */
X		return;
X
X	case 2:	
X		if (c[DEXCOUNT]==0)	
X			c[DEXTERITY]+=3; /*	dexterity	*/
X		c[DEXCOUNT] += 400;  	
X		return;
X
X	case 3: 
X		i=rnd(3)+1;
X		p="  While the %s slept, you smashed it %d times";
Xws:			
X		direct(x,fullhit(i),p,i); /*	sleep	*/
X		return;
X
X	case 4:	/* charm monster */
X
X		c[CHARMCOUNT] += c[CHARISMA]<<1;	
X		return;
X
X		/* sonic spear */
X	case 5:	
X		godirect(x,rnd(10)+15+clev,"  The sound damages the %s",70,'@'); 
X		return;
X
X		/* ----- LEVEL 2 SPELLS ----- */
X
X	case 6: 
X		i=rnd(3)+2;	
X		p="  While the %s is entangled, you hit %d times";
X		goto ws; /* web */
X
X	case 7:	
X		if (c[STRCOUNT]==0) c[STREXTRA]+=3;/*	strength*/
X		c[STRCOUNT] += 150+rnd(100);    
X		return;
X
X	case 8:	
X		yl = playery-5;     /* enlightenment */
X		yh = playery+6;   
X		xl = playerx-15;   
X		xh = playerx+16;
X		vxy(&xl,&yl);   
X		vxy(&xh,&yh); /* check bounds */
X		for (i=yl; i<=yh; i++) /* enlightenment	*/
X			for (j=xl; j<=xh; j++)	know[j][i]=1;
X		draws(xl,xh+1,yl,yh+1);	
X		return;
X
X	case 9:	
X		raisehp(20+(clev<<1));  
X		return;  /* healing */
X
X	case 10:	
X		c[BLINDCOUNT]=0;	
X		return;	/* cure blindness	*/
X
X	case 11:	
X		createmonster(makemonst(level+1)+8);  
X		return;
X
X	case 12: 
X		if (rnd(11)+7 <= c[WISDOM]) 
X			direct(x,rnd(20)+20+clev,"  The %s believed!",0);
X		else 
X		    lprcat("  It didn't believe the illusions!");
X		return;
X
X		/* if he has the amulet of invisibility then add more time */
X	case 13:	
X		for (j=i=0; i<26; i++)
X			if (iven[i]==OAMULET) 
X				j+= 1+ivenarg[i];
X		c[INVISIBILITY] += (j<<7)+12;   
X		return;
X
X		/* ----- LEVEL 3 SPELLS ----- */
X
X	case 14:	
X		godirect(x,rnd(25+clev)+25+clev,"  The fireball hits the %s",40,'*'); 
X		return; /*	fireball */
X
X	case 15:	
X		godirect(x,rnd(25)+20+clev,"  Your cone of cold strikes the %s",60,'O');	/*	cold */
X		return;
X
X	case 16:	
X		dirpoly(x);  
X		return;	/*	polymorph */
X
X	case 17:	
X		c[CANCELLATION]+= 5+clev;	
X		return;	/*	cancellation	*/
X
X	case 18:	
X		c[HASTESELF]+= 7+clev;  
X		return;  /*	haste self	*/
X
X		/* cloud kill */
X	case 19:    
X		omnidirect(x,30+rnd(10),"  The %s gasps for air");	
X		return;
X
X		/* vaporize rock */
X	case 20:	
X		xh = min(playerx+1,MAXX-2);		
X		yh = min(playery+1,MAXY-2);
X		for (i=max(playerx-1,1); i<=xh; i++) 
X			for (j=max(playery-1,1); j<=yh; j++) {
X				kn = &know[i][j];    
X				pm = &mitem[i][j];
X				switch(*(p= &item[i][j])) {
X				case OWALL: 
X					if (level<MAXLEVEL+MAXVLEVEL-3)
X						*p = *kn = 0;
X					break;
X
X				case OSTATUE:
X					if (c[HARDGAME]>3 && rnd(60)<30)
X						break;
X					*p=OBOOK; 
X					iarg[i][j]=level;  
X					*kn=0;
X					break;
X
X				case OTHRONE: 
X					*pm=GNOMEKING;  
X					*kn=0;  
X					*p= OTHRONE2;
X					hitp[i][j]=monster[GNOMEKING].hitpoints; 
X					break;
X
X				case OALTAR:	
X					*pm=DEMONPRINCE;  
X					*kn=0;
X					hitp[i][j]=monster[DEMONPRINCE].hitpoints; 
X					createmonster(DEMONPRINCE);
X					createmonster(DEMONPRINCE);
X					createmonster(DEMONPRINCE);
X					createmonster(DEMONPRINCE);
X					break;
X				};
X				switch(*pm)
X				{	/* Xorn takes damage from vpr */
X				case XORN:	
X					ifblind(i,j);  
X					hitm(i,j,200); 
X					break; 
X				case TROLL:
X					ifblind(i,j);  
X					hitm(i,j,200); 
X					break; 
X				}
X			}
X		return;
X
X		/* ----- LEVEL 4 SPELLS ----- */
X
X	case 21:/* dehydration */
X
X		direct(x,100+clev,"  The %s shrivels up",0); 
X		return;
X
X	case 22:	/*	lightning */
X		godirect(x,rnd(25)+20+(clev<<1),"  A lightning bolt hits the %s",1,'~');	
X		return;
X
X	case 23:	
X		i=min(c[HP]-1,c[HPMAX]/2);	/* drain life */
X		direct(x,i+i,"",0);	
X		c[HP] -= i;  	
X		return;
X
X	case 24:	
X		if (c[GLOBE]==0) c[MOREDEFENSES] += 10;
X		c[GLOBE] += 200;  
X		loseint();  /* globe of invulnerability */
X		return;
X
X	case 25:	
X		omnidirect(x,32+clev,"  The %s struggles for air in your flood!"); /* flood */
X		return;
X
X		/* finger of death */
X	case 26:	
X		if (rnd(151)==63) { 
X			beep(); 
X			lprcat("\nYour heart stopped!\n"); 
X			nap(4000);  
X			died(270); 
X			return; 
X		}
X		if (c[WISDOM]>rnd(10)+10) direct(x,2000,"  The %s's heart stopped",0); 
X		else lprcat("  It didn't work"); 
X		return;
X
X		/* ----- LEVEL 5 SPELLS ----- */
X
X		/* scare monster */
X	case 27:	
X		c[SCAREMONST] += rnd(10)+clev;
X
X		/* if have HANDofFEAR make last longer */
X		for (j=i=0; i<26; i++)
X			if (iven[i]==OHANDofFEAR) {
X				c[SCAREMONST] *= 3;
X				break;
X			}
X		return;
X
X	case 28:	
X		c[HOLDMONST] += rnd(10)+clev;  
X		return;  /* hold monster */
X
X	case 29:	
X		c[TIMESTOP] += rnd(20)+(clev<<1);  
X		return;  /* time stop */
X
X	case 30:	
X		tdirect(x);  
X		return;  /* teleport away */
X
X		/* magic fire */
X	case 31:	
X		omnidirect(x,35+rnd(10)+clev,"  The %s cringes from the flame"); 
X		return;
X
X		/* ----- LEVEL 6 SPELLS ----- */
X
X	case 32:	/* make wall */
X		makewall(x);
X		return;
X
X		/* sphere of annihilation */
X	case 33:	
X		if ((rnd(23)==5) && (wizard==0)) 
X		{ 	
X			beep(); 
X			lprcat("\nYou have been enveloped by the zone of nothingness!\n");
X			nap(4000);  
X			died(258); 
X			return;
X		}
X		xl=playerx; 
X		yl=playery;
X		loseint();
X		i=dirsub(&xl,&yl); /* get direction of sphere */
X		newsphere(xl,yl,i,rnd(20)+11);/*make a sphere */
X		return;
X
X	case 34:	
X		genmonst();  
X		spelknow[34]=0;  /* genocide */
X		loseint();
X		return;
X
X	case 35:/* summon demon */
X		if (rnd(100) > 30) { 
X			direct(x-1,150,"  The demon strikes at the %s",0);  
X			return; 
X		}
X		if (rnd(100) > 15) { 
X			lprcat("  Nothing seems to have happened");  
X			return; 
X		}
X		lprcat("  The demon turned on you and vanished!"); 
X		beep();
X		i=rnd(40)+30;  
X		lastnum=277;
X		losehp(i); /* must say killed by a demon */
X
X		return;
X
X	case 36:/* walk through walls */
X		c[WTW] += rnd(10)+5;	
X		return;
X
X	case 37:/* alter reality */
X		{
X			struct isave *save;	
X			/* pointer to item save structure */
X			int sc;	
X			sc=0;	/* # items saved */
X			save = (struct isave *)malloc(sizeof(struct isave)*MAXX*MAXY*2);
X			for (j=0; j<MAXY; j++)/* save all items and monsters */
X				for (i=0; i<MAXX; i++)
X				{
X					xl = item[i][j];
X					if (xl && xl!=OWALL && xl!=OANNIHILATION) 
X					{
X						save[sc].type=0;  
X						save[sc].id=item[i][j];
X						save[sc++].arg=iarg[i][j];
X					}
X					if (mitem[i][j]) 
X					{
X						save[sc].type=1;  
X						save[sc].id=mitem[i][j];
X						save[sc++].arg=hitp[i][j];
X					}
X					item[i][j]=OWALL;   
X					mitem[i][j]=0;
X					if (wizard) know[i][j]=1; 
X					else know[i][j]=0;
X				}
X			eat(1,1);	
X			if (level==1) item[33][MAXY-1]=0;
X			for (j=rnd(MAXY-2), i=1; i<MAXX-1; i++) item[i][j]=0;
X			while (sc>0) /* put objects back in level */
X			{
X				--sc;
X				if (save[sc].type == 0)
X				{
X					int trys;
X					for (trys=100, i=j=1; --trys>0 && item[i][j]; i=rnd(MAXX-1), j=rnd(MAXY-1));
X					if (trys) { 
X						item[i][j]=save[sc].id; 
X						iarg[i][j]=save[sc].arg; 
X					}
X				}
X				else
X				{ /* put monsters back in */
X					int trys;
X					for (trys=100, i=j=1; --trys>0 && (item[i][j]==OWALL || mitem[i][j]); i=rnd(MAXX-1), j=rnd(MAXY-1));
X					if (trys) { 
X						mitem[i][j]=save[sc].id; 
X						hitp[i][j]=save[sc].arg; 
X					}
X				}
X			}
X			loseint();
X			draws(0,MAXX,0,MAXY);  
X			if (wizard==0) spelknow[37]=0;
X			free((char*)save);	 
X			positionplayer();  
X			return;
X		}
X
X	case 38:	/* permanence */
X
X		adjtime(-99999L);  
X		spelknow[38]=0; /* forget */
X		loseint();
X		return;
X
X	default:	
X		lprintf("  spell %d not available!",(long)x); 
X		beep();  
X		return;
X	};
X}
X
X/*
X *	loseint()		
X *		Routine to subtract 1 from your int (intelligence) if > 3
X *
X *	No arguments and no return value
X */
Xloseint()
X{
X	if (--c[INTELLIGENCE]<3)  c[INTELLIGENCE]=3;
X}
X
X/*
X *	isconfuse() 		Routine to check to see if player is confused
X *
X *	This routine prints out a message saying "You can't aim your magic!"
X *	returns 0 if not confused, non-zero (time remaining confused) 
X *	if confused
X */
Xisconfuse()
X{
X	if (c[CONFUSE]) { 
X		lprcat(" You can't aim your magic!"); 
X		beep(); 
X	}
X	return(c[CONFUSE]);
X}
X
X/*		Routine to return 1 if a spell doesn't affect a monster
X *	nospell(x,monst)	
X *	int x,monst;
X *
X *	Subroutine to return 1 if the spell can't affect the monster
X *	  otherwise returns 0
X *	Enter with the spell number in x, and the monster number in monst.
X */
Xnospell(x,monst)
Xint x,monst;
X{
X	register int tmp;
X
X	/* bad spell or monst */
X	if (x>=SPNUM || monst>MAXMONST+8 || monst<0 || x<0) return(0);	
X
X	if ((tmp=spelweird[monst-1][x])==0) 
X		return(0);
X	cursors();  
X	lprc('\n');  
X	lprintf(spelmes[tmp],monster[monst].name);  
X	return(1);
X}
X
X/*
X *		Function to return full damage against a monster (aka web)
X *	fullhit(xx)		
X *		int xx;
X *
X *	Function to return hp damage to monster due to a number of full hits
X *	Enter with the number of full hits being done
X */
Xfullhit(xx)
Xint xx;
X{
X	register int i;
X
X	if (xx<0 || xx>20) return(0);	/* fullhits are out of range */
X	if (c[LANCEDEATH]) return(10000);	/* lance of death */
X
Xi = xx * ((c[WCLASS]>>1)+c[STRENGTH]+c[STREXTRA]-c[HARDGAME]-12+c[MOREDAM]); 
X
X	return( (i>=1) ? i : xx );
X}
X
X/*
X *		Routine to direct spell damage 1 square in 1 dir
X *	direct(spnum,dam,str,arg)	
X *	int spnum,dam,arg;
X *	char *str;
X *
X *	Routine to ask for a direction to a spell and then hit the monster
X *	Enter with the spell number in spnum, the damage to be done in dam,
X *	  lprintf format string in str, and lprintf's argument in arg.
X *	Returns no value.
X */
Xdirect(spnum,dam,str,arg)
Xint spnum,dam,arg;
Xchar *str;
X{
X	int x,y;
X	register int m;
X	if (spnum<0 || spnum>=SPNUM || str==0) return; /* bad arguments */
X	if (isconfuse()) return;
X	dirsub(&x,&y);
X	m = mitem[x][y];
X	if (item[x][y]==OMIRROR) {
X		if (spnum==3) /* sleep */
X		{
X			lprcat("You fall asleep! "); 
X			beep();
Xfool:
X			arg += 2;
X			while (arg-- > 0) { 
X				parse2(); 
X				nap(1000); 
X			}
X			return;
X		}
X		else if (spnum==6) /* web */
X		{
X			lprcat("You get stuck in your own web! "); 
X			beep();
X			goto fool;
X		}
X		else {
X			lastnum=278; 
X			lprintf(str,"spell caster (thats you)",(long)arg);
X			beep(); 
X			losehp(dam); 
X			return;
X		}
X	}
X	if (m==0) {	
X		lprcat("  There wasn't anything there!");	
X		return;  
X	}
X	ifblind(x,y);
X	if (nospell(spnum,m)) { 
X		lasthx=x;  
X		lasthy=y; 
X		return; 
X	}
X	lprintf(str,lastmonst,(long)arg);       
X	hitm(x,y,dam);
X}
X
X/*
X *				Function to perform missile attacks
X *	godirect(spnum,dam,str,delay,cshow)		
X *		int spnum,dam,delay;
X *		char *str,cshow;
X *
X *	Function to hit in a direction from a missile weapon and have it keep
X *	on going in that direction until its power is exhausted
X *	Enter with the spell number in spnum, the power of the weapon in hp,
X *	  lprintf format string in str, the # of milliseconds to delay between 
X *	 locations in delay, and the character to represent the weapon in cshow.
X *	Returns no value.
X */
Xgodirect(spnum,dam,str,delay,cshow)
Xint spnum,dam,delay;
Xchar *str,cshow;
X{
X	register char *p;
X	register int x,y,m;
X	int dx,dy;
X
X	if (spnum<0 || spnum>=SPNUM || str==0 || delay<0) return; /* bad args */
X
X	if (isconfuse()) return;
X
X	dirsub(&dx,&dy);	
X	x=dx;	
X	y=dy;
X	dx = x-playerx;		
X	dy = y-playery;		
X	x = playerx;	
X	y = playery;
X
X	while (dam>0) {
X		x += dx;    
X		y += dy;
X		if ((x > MAXX-1) || (y > MAXY-1) || (x < 0) || (y < 0)) {
X			dam=0;	
X			break;  /* out of bounds */
X		}
X		if ((x==playerx) && (y==playery)) /* if energy hits player */
X		{
X			cursors(); 
X			lprcat("\nYou are hit my your own magic!"); 
X			beep();
X			lastnum=278;  
X			losehp(dam);  
X			return;
X		}
X		if (c[BLINDCOUNT]==0) /* if not blind show effect */
X		{
X			cursor(x+1,y+1); 
X			lprc(cshow); 
X			nap(delay); 
X			show1cell(x,y);
X		}
X		if ((m=mitem[x][y]))	/* is there a monster there? */
X		{
X			ifblind(x,y);
X			if (m == LUCIFER || (m>=DEMONLORD && rnd(100)<10) ) {
X				dx *= -1;	
X				dy *= -1;	
X				cursors();
X				lprc('\n');
X				lprintf("\nthe %s returns your puny missile!", monster[m].name);
X			} 
X			else {
X				if (nospell(spnum,m)) { 
X					lasthx=x;  
X					lasthy=y; 
X					return; 
X				}
X				cursors(); 
X				lprc('\n');
X				lprintf(str,lastmonst);		
X				dam -= hitm(x,y,dam);
X				show1cell(x,y);  
X				nap(1000);
X				x -= dx;
X				y -= dy;
X			}
X		}
X		else switch (*(p= &item[x][y])) {
X		case OWALL:	
X			cursors(); 
X			lprc('\n'); 
X			lprintf(str,"wall");
X			if (dam>=50+c[HARDGAME]) /* enough damage? */
X				if (level<MAXLEVEL+MAXVLEVEL-3) /* not on V3 */
X					if ((x<MAXX-1) && (y<MAXY-1) && (x) && (y))
X					{
X						lprcat("  The wall crumbles");
Xgod3:	
X						*p=0;
Xgod:	
X						know[x][y]=0;
X						show1cell(x,y);
X					}
Xgod2:	
X			dam = 0;	
X			break;
X
X		case OCLOSEDDOOR:	
X			cursors(); 
X			lprc('\n'); 
X			lprintf(str,"door");
X			if (dam>=40) {
X				lprcat("  The door is blasted apart");
X				goto god3;
X			}
X			goto god2;
X
X		case OSTATUE:	
X			cursors(); 
X			lprc('\n'); 
X			lprintf(str,"statue");
X			if (dam>44) {
X				if (c[HARDGAME] > 3 && rnd(60)<30)
X					goto god2;
X				lprcat("  The statue crumbles");
X				*p=OBOOK; 
X				iarg[x][y]=level;
X				goto god;
X			}
X			goto god2;
X
X		case OTHRONE:	
X			cursors(); 
X			lprc('\n'); 
X			lprintf(str,"throne");
X			if (dam>33) {
X				mitem[x][y]=GNOMEKING; 
X				hitp[x][y]=monster[GNOMEKING].hitpoints;
X				*p = OTHRONE2;
X				goto god;
X			}
X			goto god2;
X
X		case OMIRROR:
X			dx *= -1;	
X			dy *= -1;	
X			break;
X		};
X		dam -= 3 + (c[HARDGAME]>>1);
X	}
X}
X
X/*
X *		Routine to put "monster" or the monster name into lastmosnt
X *	ifblind(x,y)	
X *	int x,y;
X *
X *	Subroutine to copy the word "monster" into lastmonst if the player is 
X * 	blind. Enter with the coordinates (x,y) of the monster
X *	Returns no value.
X */
Xifblind(x,y)
Xint x,y;
X{
X	char *p;
X	vxy(&x,&y);	/* verify correct x,y coordinates */
X	if (c[BLINDCOUNT]) { 
X		lastnum=279;  
X		p="monster"; 
X	}
X	else { 
X		lastnum=mitem[x][y];  
X		p=monster[lastnum].name; 
X	}
X	strcpy(lastmonst,p);
X}
X
X/*
X *	tdirect(spnum)		Routine to teleport away a monster
X *	int spnum;
X *
X *	Routine to ask for a direction to a spell and then teleport away monster
X *	Enter with the spell number that wants to teleport away
X *	Returns no value.
X */
Xtdirect(spnum)
Xint spnum;
X{
X	int x,y;
X	register int m;
X
X	if (spnum<0 || spnum>=SPNUM) return; /* bad args */
X	if (isconfuse()) return;
X	dirsub(&x,&y);
X	if ((m=mitem[x][y])==0)
X	{	
X		lprcat("  There wasn't anything there!");	
X		return;  
X	}
X	ifblind(x,y);
X	if (nospell(spnum,m)) { 
X		lasthx=x;  
X		lasthy=y; 
X		return; 
X	}
X	fillmonst(m);  
X	mitem[x][y]=know[x][y]=0;
X}
X
X
Xmakewall(spnum)
Xint spnum;
X{
X	int x,y;
X
X	if (spnum<0 || spnum>=SPNUM) return; /* bad args */
X	if (isconfuse()) return;
X	dirsub(&x,&y);
X
X	if ((y>=0) && (y<=MAXY-1) && (x>=0) && (x<=MAXX-1)) /* within bounds? */
X		if (item[x][y]!=OWALL) {	/* can't make anything on walls */
X			if (item[x][y]==0){	/* is it free of items? */
X				if (mitem[x][y]==0){  /*is it free of monsters? */
X					if ((level!=1) || (x!=33) || (y!=MAXY-1)) {
X						item[x][y]=OWALL;
X						know[x][y]=1;
X						show1cell(x,y);
X					}
X					else lprcat("\nyou can't make a wall there!");
X				}
X				else lprcat("\nthere's a monster there!");
X			}
X			else lprcat("\nthere's something there already!");
X		}
X		else lprcat("\nthere's a wall there already!");
X
X}
X
X/*
X *	omnidirect(sp,dam,str)   Routine to damage all monsters 1 square from player
X *		int sp,dam;
X *		char *str;
X *
X *	Routine to cast a spell and then hit the monster in all directions
X *	Enter with the spell number in sp, the damage done to wach square in dam,
X *	  and the lprintf string to identify the spell in str.
X *	Returns no value.
X */
Xomnidirect(spnum,dam,str)
Xint spnum,dam;
Xchar *str;
X{
X	register int x,y,m;
X	if (spnum<0 || spnum>=SPNUM || str==0) return; /* bad args */
X	for (x=playerx-1; x<playerx+2; x++)
X		for (y=playery-1; y<playery+2; y++)
X		{
X			if (m=mitem[x][y])
X				if (nospell(spnum,m) == 0)
X				{
X					ifblind(x,y);
X					cursors(); 
X					lprc('\n'); 
X					lprintf(str,lastmonst);
X					hitm(x,y,dam);  
X					nap(800);
X				}
X				else  { 
X					lasthx=x;  
X					lasthy=y; 
X				}
X		}
X}
X
X/*
X *		Routine to ask for direction, then modify x,y for it
X *	static dirsub(x,y)		
X *	int *x,*y;
X *
X *	Function to ask for a direction and modify an x,y for that direction
X *	Enter with the origination coordinates in (x,y).
X *	Returns index into diroffx[] (0-8).
X */
Xdirsub(x,y)
Xint *x,*y;
X{
X	register int i;
X	lprcat("\nIn What Direction? ");
X	for (i=0; ; )
X		switch(getcharacter())
X		{
X		case 'b':	
X			i++;
X		case 'n':	
X			i++;	
X		case 'y':	
X			i++;	
X		case 'u':	
X			i++;
X		case 'h':	
X			i++;	
X		case 'k':	
X			i++;
X		case 'l':	
X			i++;	
X		case 'j':	
X			i++;		
X			goto out;
X		};
Xout:
X	*x = playerx+diroffx[i];		
X	*y = playery+diroffy[i];
X	vxy(x,y);  
X	return(i);
X}
X
X/*
X *	vxy(x,y)	   Routine to verify/fix coordinates for being within bounds
X *		int *x,*y;
X *
X *	Function to verify x & y are within the bounds for a level
X *	If *x or *y is not within the absolute bounds for a level, fix them so that
X *	  they are on the level.
X *	Returns TRUE if it was out of bounds, and the *x & *y in the calling
X *	routine are affected.
X */
Xvxy(x,y)
Xint *x,*y;
X{
X	int flag=0;
X	if (*x<0) { 
X		*x=0; 
X		flag++; 
X	}
X	if (*y<0) { 
X		*y=0; 
X		flag++; 
X	}
X	if (*x>=MAXX) { 
X		*x=MAXX-1; 
X		flag++; 
X	}
X	if (*y>=MAXY) { 
X		*y=MAXY-1; 
X		flag++; 
X	}
X	return(flag);
X}
X
X/*
X *	dirpoly(spnum)		Routine to ask for a direction and polymorph a monst
X *		int spnum;
X *
X *	Subroutine to polymorph a monster and ask for the direction its in
X *	Enter with the spell number in spmun.
X *	Returns no value.
X */
Xdirpoly(spnum)
Xint spnum;
X{
X	int x,y,m;
X	if (spnum<0 || spnum>=SPNUM) return; /* bad args */
X	if (isconfuse()) return;	/* if he is confused, he can't aim his magic */
X	dirsub(&x,&y);
X	if (mitem[x][y]==0)
X	{	
X		lprcat("  There wasn't anything there!");	
X		return;  
X	}
X	ifblind(x,y);
X	if (nospell(spnum,mitem[x][y])) { 
X		lasthx=x;  
X		lasthy=y; 
X		return; 
X	}
X	while ( monster[m = mitem[x][y] = rnd(MAXMONST+7)].genocided );
X	hitp[x][y] = monster[m].hitpoints;
X	show1cell(x,y);  /* show the new monster */
X}
X
X/*
X *		Function to hit a monster at the designated coordinates
X *	hitmonster(x,y) 	
X *	int x,y;
X *
X *	This routine is used for a bash & slash type attack on a monster
X *	Enter with the coordinates of the monster in (x,y).
X *	Returns no value.
X */
Xhitmonster(x,y)
Xint x,y;
X{
X	register int tmp,monst,damag,flag;
X
X	if (c[TIMESTOP])  return;  /* not if time stopped */
X
X	vxy(&x,&y);	/* verify coordinates are within range */
X
X	if ((monst = mitem[x][y]) == 0) return;
X
X	hit3flag=1;  
X	ifblind(x,y);
X
Xtmp = monster[monst].armorclass + c[LEVEL] + c[DEXTERITY] + c[WCLASS/4] -12 
X	    - c[HARDGAME];
X
X	cursors();
X
X	/* need at least random chance to hit */
X	if ((rnd(20) < tmp) || (rnd(71) < 5)) { 	
X		lprcat("\nYou hit");  
X		flag=1;
X		damag = fullhit(1);  
X		if (damag<9999) damag=rnd(damag)+1;
X	}
X	else { 	
X		lprcat("\nYou missed");  
X		flag=0;
X	}
X	lprcat(" the "); 
X
X	lprcat(lastmonst);
X	/*	lprintf(" (tmp = %d)", tmp); */
X
X	if (flag)	/* if the monster was hit */
X		if (iven[c[WIELD]] != OSWORDofSLASHING)
X			if ((monst==RUSTMONSTER) || (monst==DISENCHANTRESS) || (monst==CUBE))
X				if (c[WIELD]>0)
X					if (ivenarg[c[WIELD]] > -10) {
X						lprintf("\nYour weapon is dulled by the %s",lastmonst); 
X						beep();
X						--ivenarg[c[WIELD]];
X					}
X	if (flag) {
X		hitm(x,y,damag);
X		if ((monst >= DEMONLORD) && 
X		    (c[LANCEDEATH]) && 
X		    (hitp[x][y]) )
X			lprintf("\nYour lance of death tickles the %s!",lastmonst);
X	}
X/*
X	if (monst == VAMPIRE) 
X		if (hitp[x][y]<25)
X		{	mitem[x][y]=LEMMING; 
X			know[x][y]=0; 
X		}
X*/
X
X	if (monst == METAMORPH)
X		if (hitp[x][y]<25 && hitp[x][y] > 0)
X			mitem[x][y]=BRONZEDRAGON+rund(9);
X
X	if (mitem[x][y]==LEMMING)
X		if (rnd(100)<=40) createmonster(LEMMING);
X}
X
X/*
X *		Function to just hit a monster at a given coordinates
X *	hitm(x,y,amt)
X *		int x,y,amt;
X *
X *	Returns the number of hitpoints the monster absorbed
X *This routine is used to specifically damage a monster at a location (x,y)
X *	Called by hitmonster(x,y)
X */
Xhitm(x,y,amt)
Xint x,y;
Xregister amt;
X{
X	register int monst;
X	int hpoints,amt2;
X
X	vxy(&x,&y);	/* verify coordinates are within range */
X	amt2 = amt;	/* save initial damage so we can return it */
X	monst = mitem[x][y];
X
X	/* if half damage curse adjust damage points */
X	if (c[HALFDAM]) amt >>= 1;	
X	if (amt<=0) amt2 = amt = 1;
X
X	lasthx=x;
X	lasthy=y;
X
X	/* make sure hitting monst breaks stealth condition */
X	stealth[x][y]=1;	
X	c[HOLDMONST]=0;	/* hit a monster breaks hold monster spell	*/
X	switch(monst) /* if a dragon and orb(s) of dragon slaying	*/
X	{
X	case WHITEDRAGON:
X	case REDDRAGON:
X	case GREENDRAGON:
X	case BRONZEDRAGON:
X	case PLATINUMDRAGON:
X	case SILVERDRAGON:
X		if (c[SLAYING])
X			amt *= 3;
X		break;
X	}
X	/* invincible monster fix is here */
X	if (hitp[x][y] > monster[monst].hitpoints)
X		hitp[x][y] = monster[monst].hitpoints;
X
X	if (monst >= DEMONLORD) {
X		if (c[LANCEDEATH]) 
X			amt=300;
X		if (iven[c[WIELD]] == OSLAYER)
X			amt=10000;
X	}
X
X	if ((hpoints = hitp[x][y]) <= amt) {
X		lprintf("\nThe %s died!",lastmonst);
X		raiseexperience((long)monster[monst].experience);
X		amt = monster[monst].gold;  
X		if (amt>0) dropgold(rnd(amt)+amt);
X		dropsomething(monst);	
X		disappear(x,y);	
X		bottomline();
X		hitp[x][y] = 0;
X		return(hpoints);
X	}
X	hitp[x][y] = hpoints-amt;	
X	return(amt2);
X}
X
X/*
X *			Function for the monster to hit the player from (x,y)
X *	hitplayer(x,y) 		
X *		int x,y;
X *
X *	Function for the monster to hit the player with monster at location x,y
X *	Returns nothing of value.
X */
Xhitplayer(x,y)
Xint x,y;
X{
X	register int dam,tmp,mster,bias;
X
X	vxy(&x,&y);	/* verify coordinates are within range */
X
X	lastnum = mster = mitem[x][y];
X
X	if ((know[x][y]&1) == 0) {
X		know[x][y]=1; 
X		show1cell(x,y);
X	}
X
X	bias = (c[HARDGAME]) + 1;
X	hitflag = hit2flag = hit3flag = 1;
X	yrepcount=0;
X	cursors();	
X	ifblind(x,y);
X
X	if (mster < DEMONLORD)
X		if (c[INVISIBILITY]) if (rnd(33)<20) {
X			lprintf("\nThe %s misses wildly",lastmonst);	
X			return;
X		}
X
X	if ( (mster < DEMONLORD) && (mster != PLATINUMDRAGON) ) 
X		if (c[CHARMCOUNT]) 
X			if (rnd(30)+5*monster[mster].level-c[CHARISMA]<30) {
X	lprintf("\nThe %s is awestruck at your magnificence!",lastmonst);
X				return;
X			}
X
X	if (mster==LEMMING) return;
X	else {
X		dam = monster[mster].damage;
X		dam += rnd( (int) ((dam<1)?1:dam) ) + monster[mster].level;
X	}
X
X	/* demon lords/prince/god of hellfire damage is reduced if wielding
X			Slayer */
X	if (mster >= DEMONLORD)
X		if (iven[c[WIELD]]==OSLAYER)
X			dam=(int) (1 - (0.1 * rnd(5)) * dam);
X
X	/*	spirit naga's and poltergeist's damage is halved if scarab of 
X	  	negate spirit	*/
X	if (c[NEGATESPIRIT] || c[SPIRITPRO])  
X		if ((mster ==POLTERGEIST) || (mster ==SPIRITNAGA)) 
X			dam = (int) dam/2; 
X
X	/*	halved if undead and cube of undead control	*/
X	if (c[CUBEofUNDEAD] || c[UNDEADPRO]) 
X		if ((mster ==VAMPIRE) || (mster ==WRAITH) || (mster ==ZOMBIE)) 
X			dam = (int) dam/2;
X
X	tmp = 0;
X	if (monster[mster].attack>0)
X		if (((dam + bias + 8) > c[AC]) 
X	 	    || (rnd((int)((c[AC]>0)?c[AC]:1))==1)) { 	
X			if (spattack(monster[mster].attack,x,y)) { 	
X				flushall(); 
X				return; 
X			}
X			tmp = 1;  
X			bias -= 2; 
X			cursors(); 
X		}
X
X	if (((dam + bias) > c[AC]) || (rnd((int)((c[AC]>0)?c[AC]:1))==1)) {
X		lprintf("\n  The %s hit you ",lastmonst);	
X		tmp = 1;
X		if ((dam -= c[AC]) < 0) 
X			dam=0;
X
X		if (dam > 0) { 
X			losehp(dam); 
X			bottomhp(); 
X			flushall(); 
X		}
X	}
X
X	if (tmp == 0)  
X		lprintf("\n  The %s missed ",lastmonst);
X}
X
X/*
X *	dropsomething(monst) 	Function to create an object when a monster dies
X *		int monst;
X *
X *	Function to create an object near the player when 
X *	certain monsters are killed
X *	Enter with the monster number 
X *	Returns nothing of value.
X */
Xdropsomething(monst)
Xint monst;
X{
X	switch(monst) {
X	case ORC:  
X	case NYMPH:
X	case ELF:
X	case TROGLODYTE:
X	case TROLL:
X	case ROTHE:
X	case VIOLETFUNGI:
X	case PLATINUMDRAGON:
X	case GNOMEKING:
X	case REDDRAGON:
X		something(level); 
X		return;
X
X	case LEPRECHAUN: 
X		if (rnd(101)>=75) creategem();
X		if (rnd(5)==1) dropsomething(LEPRECHAUN);   
X		return;
X	case LEMMING:	/* createitem(OGOLDPILE,1); */
X		return;
X	}
X}
X
X/*
X *	dropgold(amount) 	Function to drop some gold around player
X *		int amount;
X *
X *	Enter with the number of gold pieces to drop
X *	Returns nothing of value.
X */
Xdropgold(amount)
Xregister int amount;
X{
X	if (amount > 250) createitem(OMAXGOLD, amount);  
X	else  createitem(OGOLDPILE,amount);
X}
X
X/*
X *	something(level) 	Function to create a random item around player
X *		int level;
X *
X *	Function to create an item from a designed probability around player
X *	Enter with the cave level on which something is to be dropped
X *	Returns nothing of value.
X */
Xsomething(lev)
Xint lev;
X{
X	register int j;
X	int i;
X
X	if (lev<0 || lev>MAXLEVEL+MAXVLEVEL) 
X		return;	/* correct level? */
X	if (rnd(101)<8) 
X		something(lev); /* possibly more than one item */
X	j = newobject(lev,&i);		
X	createitem(j,i);
X}
X
X/*
X *	newobject(lev,i) 	Routine to return a randomly selected new object
X *		int lev,*i;
X *
X *	Routine to return a randomly selected object to be created
X *	Returns the object number created, and sets *i for its argument
X *	Enter with the cave level and a pointer to the items arg
X */
Xstatic char nobjtab[] = 
X{ 
X	0, OSCROLL,  OSCROLL,  OSCROLL,  OSCROLL, OPOTION,
X	OPOTION, OPOTION, OPOTION, OGOLDPILE, OGOLDPILE, OGOLDPILE, OGOLDPILE, 
X	OBOOK, OBOOK, OBOOK, OBOOK, ODAGGER, ODAGGER, ODAGGER, OLEATHER, OLEATHER,
X	OLEATHER, OREGENRING, OPROTRING, OENERGYRING, ODEXRING, OSTRRING, OSPEAR,
X	OBELT, ORING, OSTUDLEATHER, OSHIELD, OFLAIL, OCHAIN, O2SWORD, OPLATE,
X	OLONGSWORD };
X
Xnewobject(lev,i)
Xregister int lev,*i;
X{
X	register int tmp=32,j;
X
X	if (level<0 || level>MAXLEVEL+MAXVLEVEL) 
X		return(0);	/* correct level? */
X
X	if (lev>6) tmp=37; 
X	else if (lev>4) tmp=35; 
X
X	j = nobjtab[tmp=rnd(tmp)];	/* the object type */
X	switch(tmp) {
X	case 1: 
X	case 2: 
X	case 3: 
X	case 4:	
X		*i=newscroll();	
X		break;
X	case 5: 
X	case 6: 
X	case 7: 
X	case 8:	
X		*i=newpotion();	
X		break;
X	case 9: 
X	case 10: 
X	case 11: 
X	case 12: 
X		*i=rnd((lev+1)*10)+lev*10+10; 
X		break;
X	case 13: 
X	case 14: 
X	case 15:
X	case 16:
X		*i=lev;	
X		break;
X	case 17: 
X	case 18: 
X	case 19: 
X		if (!(*i=newdagger()))  return(0);  
X		break;
X	case 20: 
X	case 21: 
X	case 22: 
X		if (!(*i=newleather()))  return(0);  
X		break;
X	case 23: 
X	case 32: 
X	case 35: 
X		*i=rund(lev/3+1); 
X		break;
X	case 24: 
X	case 26: 
X		*i=rnd(lev/4+1);   
X		break;
X	case 25: 
X		*i=rund(lev/4+1); 
X		break;
X	case 27: 
X		*i=rnd(lev/2+1);   
X		break;
X	case 28: 
X		*i=rund(lev/3+1); 
X		if (*i==0) return(0); 
X		break;
X	case 29: 
X	case 31: 
X		*i=rund(lev/2+1); 
X		if (*i==0) return(0); 
X		break;
X	case 30: 
X	case 33: 
X		*i=rund(lev/2+1);   
X		break;
X	case 34: 
X		*i=newchain();   	
X		break;
X	case 36: 
X		*i=newplate();   	
X		break;
X	case 37: 
X		*i=newsword();		
X		break; 
X	}
X	return(j);
X}
X
X/*
X *			Function to process special attacks from monsters
X *  spattack(atckno,xx,yy) 	
X *  	int atckno,xx,yy;
X *
X *	Enter with the special attack number, and the coordinates (xx,yy)
X *		of the monster that is special attacking
X *	Returns 1 if must do a show1cell(xx,yy) upon return, 0 otherwise
X *
X * atckno   monster     effect
X * ---------------------------------------------------
X *	0	none
X *	1	rust monster		eat armor
X *	2	hell hound		breathe light fire
X *	3	dragon			breathe fire
X *	4	giant centipede		weakening sing
X *	5	white dragon		cold breath
X *	6	wraith			drain level
X *	7	waterlord		water gusher
X *	8	leprechaun		steal gold
X *	9	disenchantress		disenchant weapon or armor
X *	10	ice lizard		hits with barbed tail
X *	11	umber hulk		confusion
X *	12	spirit naga		cast spells taken from special attacks
X *	13	platinum dragon		psionics
X *	14	nymph			steal objects
X *	15	bugbear			bite
X *	16	osequip			bite
X *
X *	char rustarm[ARMORTYPES][2];
X *	special array for maximum rust damage to armor from rustmonster
X *	format is: { armor type , minimum attribute 
X */
X#define ARMORTYPES 6
X
Xstatic char rustarm[ARMORTYPES][2] = 
X{ 
X	OSTUDLEATHER,-2,ORING,-4, OCHAIN,-5, OSPLINT,-6,OPLATE,-8,OPLATEARMOR,-9  };
X
Xstatic char spsel[] = { 
X	1, 2, 3, 5, 6, 8, 9, 11, 13, 14 };
Xspattack(x,xx,yy)
Xint x,xx,yy;
X{
X	register int i,j=0,k,m;
X	register char *p=0;
X
X	vxy(&xx,&yy);	/* verify x & y coordinates */
X
X	/* cancel only works 5% of time for demon prince
X		   and god */
X	if (c[CANCELLATION]) 
X		if (mitem[xx][yy] >= DEMONPRINCE) {
X			if (rnd(100) >= 95) return(0);
X		}
X		else return(0);
X
X	/* staff of power cancels demonlords/wraiths/vampires 75% of time */
X	if (mitem[xx][yy] != LUCIFER) {
X		if ( (mitem[xx][yy] >= DEMONLORD) ||
X		    (mitem[xx][yy] == WRAITH) ||
X		    (mitem[xx][yy] == VAMPIRE) )
X			for (i=0;i<26;i++)
X				if (iven[i]==OPSTAFF) 
X					if (rnd(100)<75)
X						return(0);
X	}
X
X	/* if have cube of undead control,  wraiths and vampires do nothing */	
X	if ( (mitem[xx][yy]==WRAITH) || (mitem[xx][yy]==VAMPIRE) )
X		if ( (c[CUBEofUNDEAD]) || (c[UNDEADPRO]) )
X			return(0);
X
X	switch(x) {
X	case 1:	/* rust your armor, j=1 when rusting has occurred */
X		m = k = c[WEAR];
X		if ((i=c[SHIELD]) != -1)
X			if (--ivenarg[i] < -1) 
X				ivenarg[i]= -1; 
X			else j=1;
X		if ((j==0) && (k != -1)) {
X			m = iven[k];
X			for (i=0; i<ARMORTYPES; i++)
X				if (m == rustarm[i][0]) 
X					/* find his armor in table */
X				{
X					if (--ivenarg[k]< rustarm[i][1])
X						ivenarg[k]= rustarm[i][1]; 
X					else j=1; 
X					break;
X				}
X		}
X		if (j==0)	/* if rusting did not occur */
X			switch(m) {
X			case OLEATHER:	
X				p = "\nThe %s hit you -- You are lucky you have leather on";
X				break;
X			case OSSPLATE:	
X				p = "\nThe %s hit you -- You are fortunate to have stainless steel armor!";
X				break;
X			case OELVENCHAIN:
X				p = "\nThe %s hit you -- You are very lucky to have such strong elven chain!";
X				break;
X			}
X		else  { 
X			beep(); 
X			p = "\nThe %s hit you -- your armor feels weaker"; 
X		}
X		break;
X
X	case 2:		
X		i = rnd(15)+8-c[AC];
Xspout:	
X		p="\nThe %s breathes fire at you!";
X		if (c[FIRERESISTANCE])
X			p="\nThe %s's flame doesn't phase you!";
X		else
Xspout2: 
X			if (p) { 
X				lprintf(p,lastmonst); 
X				beep(); 
X			}
X		checkloss(i);
X		return(0);
X
X	case 3:		
X		i = rnd(20)+25-c[AC];  
X		goto spout;
X
X	case 4:	
X		if (c[STRENGTH]>3) {
X			p="\nThe %s stung you!  You feel weaker"; 
X			beep();
X			if (--c[STRENGTH] < 3)
X				c[STRENGTH] = 3;
X		}
X		else p="\nThe %s stung you!";
X		break;
X
X	case 5:		
X		p="\nThe %s blasts you with his cold breath";
X		i = rnd(15)+18-c[AC];  
X		goto spout2;
X
X	case 6:		
X		lprintf("\nThe %s drains you of your life energy!",lastmonst);
X		loselevel();
X		if (mitem[xx][yy]==DEMONPRINCE) losemspells(1);
X		if (mitem[xx][yy]==LUCIFER) {
X			loselevel();
X			losemspells(2);
X			for (i=0;i<=5;i++) 
X				if (c[i]-- < 3) c[i]=3;
X		}
X		beep();  
X		return(0);
X
X	case 7:		
X		p="\nThe %s got you with a gusher!";
X		i = rnd(15)+25-c[AC];  
X		goto spout2;
X
X	case 8:	
X		if (c[NOTHEFT]) return(0); 
X		/* he has a device of no theft */
X		if (c[GOLD]) {
X			p="\nThe %s hit you -- Your purse feels lighter";
X			if (c[GOLD]>32767)  c[GOLD]>>=1;
X			else c[GOLD] -= rnd((int)(1+(c[GOLD]>>1)));
X			if (c[GOLD] < 0) c[GOLD]=0;
X		}
X		else  p="\nThe %s couldn't find any gold to steal";
X		lprintf(p,lastmonst); 
X		disappear(xx,yy); 
X		beep();
X		bottomgold();  
X		return(1);
X
X	case 9:	
X		for(j=50; ; )	/* disenchant */
X		{
X			i=rund(26);  
X			m=iven[i]; /* randomly select item */
X			if (m>0 && ivenarg[i]>0 && m!=OSCROLL && m!=OPOTION)
X			{
X				if ((ivenarg[i] -= 3)<0) ivenarg[i]=0;
X				lprintf("\nThe %s hits you with a spell of disenchantment! ",lastmonst);
X				srcount=0; 
X				beep(); 
X				show3(i);  
X				bottomline();  
X				return(0);
X			}
X			if (--j<=0) { 	
X				p="\nThe %s nearly misses"; 
X				break;
X			}
X			break;
X		}		
X		break;
X
X	case 10:   
X		p="\nThe %s hit you with his barbed tail";
X		i = rnd(25)-c[AC];  
X		goto spout2;
X
X	case 11:
X		p="\nThe %s has confused you"; 
X		beep();
X		c[CONFUSE]+= 10+rnd(10);		
X		break;
X
X	case 12:/*performs any number of other special attacks	*/
X		return(spattack(spsel[rund(10)],xx,yy));
X
X	case 13:	
X		p="\nThe %s flattens you with his psionics!";
X		i = rnd(15)+30-c[AC];  
X		goto spout2;
X
X	case 14:	
X		if (c[NOTHEFT]) return(0); 
X		/* he has device of no theft */
X		if (emptyhanded()==1) {
X			p="\nThe %s couldn't find anything to steal";
X			break;
X		}
X		lprintf("\nThe %s picks your pocket and takes:",lastmonst);
X		beep();
X		if (stealsomething()==0) lprcat("  nothing"); 
X		disappear(xx,yy);
X		bottomline();  
X		return(1);
X
X	case 15:
X		i= rnd(10)+ 5-c[AC];
Xspout3:	
X		p="\nThe %s bit you!";
X		goto spout2;
X
X	case 16:	
X		i= rnd(15)+10-c[AC];  
X		goto spout3;
X	};
X
X	if (p) { 
X		lprintf(p,lastmonst); 
X		bottomline(); 
X	}
X	return(0);
X}
X
X/*
X *		Routine to subtract hp from user and flag bottomline display
X *	checkloss(x) 	
X *		int x;
X *
X *	Enter with the number of hit points to lose
X *	Note: if x > c[HP] this routine could kill the player!
X */
Xcheckloss(x)
Xint x;
X{
X	if (x>0) { 
X		losehp(x);  
X		bottomhp(); 
X	}
X}
X
X/*
X *	Routine to annihilate all monsters around player (playerx,playery)
X *	annihilate() 	
X *
X *	Gives player experience, but no dropped objects
X *	Returns the experience gained from all monsters killed
X */
Xannihilate()
X{
X	int i,j;
X	register long k;
X	register char *p;
X
X	for (k=0, i=playerx-1; i<=playerx+1; i++)
X		for (j=playery-1; j<=playery+1; j++)
X			if (!vxy(&i,&j)) /* if not out of bounds */
X				if (*(p= &mitem[i][j]))	/* if a monster there */
X					if (*p<DEMONLORD) {
X						k += monster[*p].experience;	
X						*p=know[i][j]=0;
X					}
X					else {
X						lprintf("\nThe %s barely escapes being annihilated!",monster[*p].name);
X						hitp[i][j] = (hitp[i][j]>>1) + 1; 
X						/* lose half hit points*/
X					}
X	if (k>0) {
X		lprcat("\nYou hear loud screams of agony!");	
X		raiseexperience((long)k);
X	}
X	return(k);
X}
X
X/*
X *		Function to create a new sphere of annihilation
X *	newsphere(x,y,dir,lifetime)  
X *		int x,y,dir,lifetime;
X *
X *	Enter with the coordinates of the sphere in x,y
X *	  the direction (0-8 diroffx format) in dir, and the lifespan of the
X *	  sphere in lifetime (in turns)
X *	Returns the number of spheres currently in existence
X */
Xnewsphere(x,y,dir,life)
Xint x,y,dir,life;
X{
X	int m,i;
X	struct sphere *sp;
X
X	if (((sp=(struct sphere *)malloc(sizeof(struct sphere)))) == 0)
X		return(c[SPHCAST]);	/* can't malloc, therefore failure */
X	if (dir>=9) dir=0;	/* no movement if direction not found */
X	if (level==0) vxy(&x,&y);	/* don't go out of bounds */
X	else {
X		if (x<1) x=1;  
X		if (x>=MAXX-1) x=MAXX-2;
X		if (y<1) y=1;  
X		if (y>=MAXY-1) y=MAXY-2;
X	}
X
X	for (i=0;i<26;i++) 
X		if (iven[i]==OSPHTALISMAN) goto out;
X
X	/* demons dispel spheres */
X	if ((m=mitem[x][y]) >= DEMONLORD) {
X		i = hitp[x][y];
X		know[x][y]=1; 
X		show1cell(x,y);	/* show the demon (ha ha) */
X		cursors(); 
X		lprintf("\nThe %s dispels the sphere!",monster[m].name);
X		beep(); 
X		rmsphere(x,y);	/* remove any spheres that are here */
X		mitem[x][y] = m;
X		hitp[x][y] = i;
X		know[x][y]=0; 
X		return(c[SPHCAST]);
X	}
X
X	/* disenchantress cancels spheres */
X	if (m==DISENCHANTRESS) {
X		cursors(); 
X		lprintf("\nThe %s causes cancellation of the sphere!",monster[m].name); 
X		beep();
X
Xboom:		
X		sphboom(x,y);	/* blow up stuff around sphere */
X		rmsphere(x,y);	/* remove any spheres that are here */
X		return(c[SPHCAST]);
X	}
X
X	/* cancellation cancels spheres */
X	if (c[CANCELLATION]) {
X		cursors();
X		lprcat("\nAs the cancellation takes effect, you hear a great earth shaking blast!"); 
X		beep();
X		goto boom;
X	}
X	/* collision of sphere and player! */
X	if (playerx==x && playery==y) {
X		cursors();
X		lprcat("\nYou have been enveloped by the zone of nothingness!\n");
X		beep(); 
X		rmsphere(x,y);	/* remove any spheres that are here */
X		nap(4000);  
X		died(258);
X	}
Xout:
X	/* collision of spheres detonates spheres */
X	if (item[x][y]==OANNIHILATION) {
X		cursors(); 
X		lprcat("\nTwo spheres of annihilation collide! You hear a great earth shaking blast!"); 
X		beep();
X		rmsphere(x,y);
X		goto boom;
X	}
X
X	item[x][y]=OANNIHILATION;  
X	mitem[x][y]=0;  
X	know[x][y]=1;
X	show1cell(x,y);	/* show the new sphere */
X	sp->x=x;  
X	sp->y=y;  
X	sp->lev=level;  
X	sp->dir=dir;  
X	sp->lifetime=life;  
X	sp->p=0;
X	if (spheres==0) spheres=sp;	/* if first node in the sphere list */
X	else	/* add sphere to beginning of linked list */
X	{
X		sp->p = spheres;	
X		spheres = sp;
X	}
X	return(++c[SPHCAST]);	/* one more sphere in the world */
X}
X
X/*
X *	rmsphere(x,y)	Function to delete a sphere of annihilation from list
X *		int x,y;
X *
X *	Enter with the coordinates of the sphere (on current level)
X *	Returns the number of spheres currently in existence
X */
Xrmsphere(x,y)
Xint x,y;
X{
X	register struct sphere *sp,*sp2=0;
X
X	for (sp=spheres; sp; sp2=sp,sp=sp->p)
X		if (level==sp->lev)	/* is sphere on this level? */
X			if ((x==sp->x) && (y==sp->y))	
X				/* locate sphere at this location */
X			{
X				item[x][y]= mitem[x][y]= 0;  
X				know[x][y]=1;
X				show1cell(x,y);	/* show the now missing sphere */
X				--c[SPHCAST];	
X				if (sp==spheres) { 
X					sp2=sp; 
X					spheres=sp->p; 
X					free((char*)sp2); 
X				}
X				else
X				{ 
X					sp2->p = sp->p;  
X					free((char*)sp); 
X				}
X				break;
X			}
X	return(c[SPHCAST]);	/* return number of spheres in the world */
X}
X
X/*
X *	sphboom(x,y)	Function to perform the effects of a sphere detonation
X *		int x,y;
X *
X *	Enter with the coordinates of the blast, Returns no value
X */
Xsphboom(x,y)
Xint x,y;
X{
X	register int i,j,k;
X
X	if (c[HOLDMONST]) c[HOLDMONST]=1;
X	if (c[CANCELLATION]) c[CANCELLATION]=1;
X	for (j=max(1,x-2); j<min(x+3,MAXX-1); j++)
X		for (i=max(1,y-2); i<min(y+3,MAXY-1); i++)
X		{
X			item[j][i]=mitem[j][i]=0;
X			show1cell(j,i);
X			for (k=0;k<26;k++) if (iven[k]==OSPHTALISMAN) return;
X			if (playerx==j && playery==i)
X			{
X				cursors(); 
X				beep();
X				lprcat("\nYou were too close to the sphere!");
X				nap(3000);
X				died(283); /* player killed in explosion */
X			}
X		}
X}
X
X/*
X *		Function to ask for monster and genocide from game
X *	genmonst()		
X *
X *	This is done by setting a flag in the monster[] structure
X */
Xgenmonst()
X{
X	register int i,j;
X	cursors();  
X	lprcat("\nGenocide what monster? ");
X	for (i=0; (!isalpha(i)) && (i!=' '); i=getcharacter());
X	lprc(i);
X	for (j=0; j<MAXMONST; j++)	/* search for the monster type */
X		if (monstnamelist[j]==i)	/* have we found it? */
X			if (monster[j].genocided==0) {
X				monster[j].genocided=1;	/* genocided from game */
X				lprintf("  There will be no more %s's",monster[j].name);
X				/* now wipe out monsters on this level */
X				newcavelevel(level); 
X				draws(0,MAXX,0,MAXY); 
X				bot_linex();
X				return;
X			}
X	lprcat("  You sense failure!");
X}
END_OF_FILE
if test 46657 -ne `wc -c <'monster.c'`; then
    echo shar: \"'monster.c'\" unpacked with wrong size!
fi
# end of 'monster.c'
fi
if test -f 'signal.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'signal.c'\"
else
echo shar: Extracting \"'signal.c'\" \(4653 characters\)
sed "s/^X//" >'signal.c' <<'END_OF_FILE'
X/* signal.c */
X
X#include "header.h"			
X
X#define BIT(a) (1<<((a)-1))
Xextern char savefilename[],wizard,predostuff,nosignal;
X
Xs2choose()	/* text to be displayed if ^C during intro screen */
X{
X	cursor(1,24); 
X	lprcat("Press "); 
X	if (boldon) setbold(); 
X	lprcat("return"); 
X	if (boldon) resetbold();
X	lprcat(" to continue: ");
X	lflush(); 
X}
X
Xcntlc()	/* what to do for a ^C */
X{
X	if (nosignal) 
X		return;	/* don't do anything if inhibited */
X	signal(SIGINT,SIG_IGN);
X	quit(); 
X	if (predostuff==1) 
X		s2choose(); 
X	else 
X		showplayer();
X	lflush();
X	signal(SIGQUIT,cntlc);	
X	signal(SIGINT,cntlc);
X}
X
X/*
X *	subroutine to save the game if a hangup signal
X */
Xsgam()
X{
X	savegame(savefilename);  
X	wizard=1;  
X	died(-257); /* hangup signal */
X}
X
X#ifdef SIGTSTP
Xtstop() 
X{
X	if (nosignal)  
X		return;  /* nothing if inhibited */
X	lcreat((char*)0);  
X	clearvt100();	
X	lflush();	  
X	signal(SIGTSTP,SIG_DFL);
X#ifdef SIGVTALRM
X/* looks like BSD4.2 or higher - must clr mask for signal to take effect*/
X	sigsetmask(sigblock(0)& ~BIT(SIGTSTP));
X#endif
X	kill(getpid(),SIGTSTP);
X
X	setupvt100();  
X	signal(SIGTSTP,tstop);
X	if (predostuff==1) 
X		s2choose(); 
X	else 
X		drawscreen();
X	showplayer();	
X	lflush();
X}
X#endif /* SIGTSTP */
X
X/*
X *	subroutine to issue the needed signal traps  called from main()
X */
Xsigill()  { sigpanic(SIGILL); }	 
Xsigtrap() { sigpanic(SIGTRAP); }
Xsigiot()  { sigpanic(SIGIOT); }   
Xsigemt()  { sigpanic(SIGEMT); }
Xsigfpe()  { sigpanic(SIGFPE); }   
Xsigbus()  { sigpanic(SIGBUS); }
Xsigsegv() { sigpanic(SIGSEGV); }  
Xsigsys()  { sigpanic(SIGSYS); }
Xsigpipe() { sigpanic(SIGPIPE); }  
Xsigterm() { sigpanic(SIGTERM); }
X
Xsigsetup()
X{
X	signal(SIGQUIT, cntlc); 		
X	signal(SIGINT,  cntlc); 
X	signal(SIGKILL, SIG_IGN);		
X	signal(SIGHUP,  sgam);
X	signal(SIGILL,  sigill);		
X	signal(SIGTRAP, sigtrap);
X	signal(SIGIOT,  sigiot);		
X	signal(SIGEMT,  sigemt);
X	signal(SIGFPE,  sigfpe);		
X	signal(SIGBUS,  sigbus);
X	signal(SIGSEGV, sigsegv);		
X	signal(SIGSYS,  sigsys);
X	signal(SIGPIPE, sigpipe);		
X	signal(SIGTERM, sigterm);
X#ifdef SIGTSTP
X	signal(SIGTSTP,tstop);		
X	signal(SIGSTOP,tstop);
X#endif /* SIGTSTP */
X}
X
X#ifdef BSD	/* for BSD UNIX? */
X
Xstatic char *signame[NSIG] = { 
X	"",
X	"SIGHUP",  /*	1	 hangup */
X	"SIGINT",  /*	2	 interrupt */
X	"SIGQUIT", /*	3	 quit */
X	"SIGILL",  /*	4	 illegal instruction (not reset when caught) */
X	"SIGTRAP", /*	5	 trace trap (not reset when caught) */
X	"SIGIOT",  /*	6	 IOT instruction */
X	"SIGEMT",  /*	7	 EMT instruction */
X	"SIGFPE",  /*	8	 floating point exception */
X	"SIGKILL", /*	9	 kill (cannot be caught or ignored) */
X	"SIGBUS",  /*	10	 bus error */
X	"SIGSEGV", /*	11	 segmentation violation */
X	"SIGSYS",  /*	12	 bad argument to system call */
X	"SIGPIPE", /*	13	 write on a pipe with no one to read it */
X	"SIGALRM", /*	14	 alarm clock */
X	"SIGTERM", /*	15	 software termination signal from kill */
X	"SIGURG",  /*	16	 urgent condition on IO channel */
X	"SIGSTOP", /*	17	 sendable stop signal not from tty */
X	"SIGTSTP", /*	18	 stop signal from tty */
X	"SIGCONT", /*	19	 continue a stopped process */
X	"SIGCHLD", /*	20	 to parent on child stop or exit */
X	"SIGTTIN", /*	21	 to readers pgrp upon background tty read */
X	"SIGTTOU", /*	22	 like TTIN for output if (tp->t_local&LTOSTOP)*/
X	"SIGIO",   /*	23	 input/output possible signal */
X	"SIGXCPU", /*	24	 exceeded CPU time limit */
X	"SIGXFSZ", /*	25	 exceeded file size limit */
X	"SIGVTALRM",/*  26	 virtual time alarm */
X	"SIGPROF", /*	27	 profiling time alarm */
X	"","","","" };
X
X#else  /* SYSV */
Xstatic char *signame[NSIG] = { 
X	"",
X	"SIGHUP",  /*	1	 hangup */
X	"SIGINT",  /*	2	 interrupt */
X	"SIGQUIT", /*	3	 quit */
X	"SIGILL",  /*	4	 illegal instruction (not reset when caught) */
X	"SIGTRAP", /*	5	 trace trap (not reset when caught) */
X	"SIGIOT",  /*	6	 IOT instruction */
X	"SIGEMT",  /*	7	 EMT instruction */
X	"SIGFPE",  /*	8	 floating point exception */
X	"SIGKILL", /*	9	 kill (cannot be caught or ignored) */
X	"SIGBUS",  /*	10	 bus error */
X	"SIGSEGV", /*	11	 segmentation violation */
X	"SIGSYS",  /*	12	 bad argument to system call */
X	"SIGPIPE", /*	13	 write on a pipe with no one to read it */
X	"SIGALRM", /*	14	 alarm clock */
X	"SIGTERM", /*	15	 software termination signal from kill */
X	"SIGUSR1",  /*	16	 user defines signal 1 */
X	"SIGUSR2", /*	17	 user defines signal 2 */
X	"SIGCLD",  /*	18	 child death */
X	"SIGPWR"   /*	19	 power fail */
X};
X#endif /* BSD */
X
X/*
X *	routine to process a fatal error signal
X */
Xsigpanic(sig)
Xint sig;
X{
X	signal(sig,SIG_DFL);
X	fprintf(stderr,"\nUlarn - SHIT! Signal %d !!! [%s]\n",sig,signame[sig]);
X	fflush(stderr);
X	sleep(2);
X	sncbr();
X	savegame(savefilename); 
X	kill(getpid(),sig); /* this will terminate us */
X}
END_OF_FILE
if test 4653 -ne `wc -c <'signal.c'`; then
    echo shar: \"'signal.c'\" unpacked with wrong size!
fi
# end of 'signal.c'
fi
echo shar: End of archive 2 \(of 8\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 8 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0