[net.sources.games] larn 12.0 part 5/6

noah@condor.UUCP (Noah Morgan) (08/08/86)

*** REPLACE THIS LINE WITH YOUR MESSAGE ***
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	object.c
#	regen.c
#	scores.c
#	signal.c
#	tok.c
#	MANIFEST
# This archive created: Wed Aug  6 14:59:47 1986
export PATH; PATH=/bin:$PATH
echo shar: extracting "'object.c'" '(25376 characters)'
if test -f 'object.c'
then
	echo shar: will not over-write existing file "'object.c'"
else
cat << \SHAR_EOF > 'object.c'
/*	object.c		Larn is copyrighted 1986 by Noah Morgan. */
#include "header.h"

/*
	***************
	LOOK_FOR_OBJECT
	***************

	subroutine to look for an object and give the player his options
	if an object was found.
 */
lookforobject()
{
register int i,j;
if (c[TIMESTOP])  return;	/* can't find objects is time is stopped	*/
i=item[playerx][playery];	if (i==0) return;
showcell(playerx,playery);  cursors();  yrepcount=0;
switch(i)
	{
	case OGOLDPILE:	case OMAXGOLD:
	case OKGOLD:	case ODGOLD:	lprcat("\n\nYou have found some gold!");	ogold(i);	break;

	case OPOTION:	lprcat("\n\nYou have found a magic potion");
				i = iarg[playerx][playery];
				if (potionname[i][0]) lprintf(" of %s",&potionname[i][1]);  opotion(i);  break;

	case OSCROLL:	lprcat("\n\nYou have found a magic scroll");
				i = iarg[playerx][playery];
				if (scrollname[i][0])	lprintf(" of %s",&scrollname[i][1]);
				oscroll(i);  break;

	case OALTAR:	if (nearbymonst()) return;
					lprcat("\n\nThere is a Holy Altar here!"); oaltar(); break;

	case OBOOK:	lprcat("\n\nYou have found a book."); obook(); break;

	case OCOOKIE:	lprcat("\n\nYou have found a fortune cookie."); ocookie(); break;

	case OTHRONE:	if (nearbymonst()) return;
					lprintf("\n\nThere is %s here!",objectname[i]); othrone(0); break;

	case OTHRONE2:	if (nearbymonst()) return;
					lprintf("\n\nThere is %s here!",objectname[i]); othrone(1); break;

	case ODEADTHRONE: lprintf("\n\nThere is %s here!",objectname[i]); odeadthrone(); break;

	case OORB:		lprcat("\n\nYou have found the Orb!!!!!"); oorb(); break;

	case OPIT:		lprcat("\n\nYou're standing at the top of a pit."); opit(); break;

	case OSTAIRSUP:		lprcat("\n\nThere is a circular staircase here"); ostairs(1);  /* up */ break;

	case OELEVATORUP:	lprcat("\n\nYou feel heavy for a moment, but the feeling disappears");
				oelevator(1);  /*  up  */  break;

	case OFOUNTAIN:	if (nearbymonst()) return;
					lprcat("\n\nThere is a fountain here"); ofountain(); break;

	case OSTATUE:	if (nearbymonst()) return;
					lprcat("\n\nYou are standing in front of a statue"); ostatue(); break;

	case OCHEST:	lprcat("\n\nThere is a chest here");  ochest();  break;

	case OIVTELETRAP:	if (rnd(11)<6) return;
						item[playerx][playery] = OTELEPORTER;
						know[playerx][playery] = 1;

	case OTELEPORTER:	lprcat("\nZaaaappp!  You've been teleported!\n");
						beep(); nap(3000); oteleport(0);
						break; 

	case OSCHOOL:	if (nearbymonst()) return;
				lprcat("\n\nYou have found the College of Larn.");
				lprcat("\nDo you (g) go inside, or (i) stay here? ");
				i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar();
				if (i == 'g') { oschool();  /*	the college of larn	*/ }
				else	lprcat(" stay here");
				break;

	case OMIRROR:	if (nearbymonst()) return;
					lprcat("\n\nThere is a mirror here");	omirror();	break;

	case OBANK2:
	case OBANK:	if (nearbymonst()) return;
				if (i==OBANK) lprcat("\n\nYou have found the bank of Larn.");
				else lprcat("\n\nYou have found a branch office of the bank of Larn.");
				lprcat("\nDo you (g) go inside, or (i) stay here? ");
				j=0; while ((j!='g') && (j!='i') && (j!='\33')) j=getchar();
				if (j == 'g') {  if (i==OBANK) obank(); else obank2(); /*  the bank of larn  */  }
				else   lprcat(" stay here");
				break;

	case ODEADFOUNTAIN:	if (nearbymonst()) return;
						lprcat("\n\nThere is a dead fountain here"); break;

	case ODNDSTORE:	if (nearbymonst()) return;
					lprcat("\n\nThere is a DND store here.");
					lprcat("\nDo you (g) go inside, or (i) stay here? ");
					i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar();
					if (i == 'g')
						dndstore();  /*  the dnd adventurers store  */
					else  lprcat(" stay here");
					break;

	case OSTAIRSDOWN:	lprcat("\n\nThere is a circular staircase here"); ostairs(-1); /* down */ break;

	case OELEVATORDOWN:	lprcat("\n\nYou feel light for a moment, but the feeling disappears");
				oelevator(-1);	/*	down	*/
				break;

	case OOPENDOOR:		lprintf("\n\nYou have found %s",objectname[i]);
						lprcat("\nDo you (c) close it"); iopts();
						i=0; while ((i!='c') && (i!='i') && (i!='\33')) i=getchar();
						if ((i=='\33') || (i=='i')) { ignore();  break; }
						lprcat("close");  forget();
						item[playerx][playery]=OCLOSEDDOOR;
						iarg[playerx][playery]=0;
						playerx = lastpx;  playery = lastpy;
						break;

	case OCLOSEDDOOR:	lprintf("\n\nYou have found %s",objectname[i]);
						lprcat("\nDo you (o) try to open it"); iopts();
						i=0; while ((i!='o') && (i!='i') && (i!='\33')) i=getchar();
						if ((i=='\33') || (i=='i'))
							{ ignore();  playerx = lastpx;
							playery = lastpy; break; }
						else
						{
						lprcat("open");
						if (rnd(11)<7)
						  {
						  switch(iarg[playerx][playery])
							{
							case 6: c[AGGRAVATE] += rnd(400);	break;

							case 7:	lprcat("\nYou are jolted by an electric shock "); 
									lastnum=274; losehp(rnd(20));  bottomline();  break;

							case 8:	loselevel();  break;

							case 9:	lprcat("\nYou suddenly feel weaker ");
									if (c[STRENGTH]>3) c[STRENGTH]--;
									bottomline();  break;

							default:	break;
							}
						  playerx = lastpx;  playery = lastpy;
						  }
						else
						  {
						  forget();  item[playerx][playery]=OOPENDOOR;
						  }
						}
						break;

	case OENTRANCE:	lprcat("\nYou have found "); lprcat(objectname[OENTRANCE]);
					lprcat("\nDo you (g) go inside"); iopts();
					i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar();
					if (i == 'g')
						{
						newcavelevel(1); playerx=33; playery=MAXY-2;
						item[33][MAXY-1]=know[33][MAXY-1]=mitem[33][MAXY-1]=0;
						draws(0,MAXX,0,MAXY); bot_linex(); return;
						}
					else   ignore();
					break;

	case OVOLDOWN:	lprcat("\nYou have found "); lprcat(objectname[OVOLDOWN]);
						lprcat("\nDo you (c) climb down"); iopts();
						i=0; while ((i!='c') && (i!='i') && (i!='\33')) i=getchar();
						if ((i=='\33') || (i=='i')) { ignore();  break; }
					if (level!=0) { lprcat("\nThe shaft only extends 5 feet downward!"); return; }
					if (packweight() > 45+3*(c[STRENGTH]+c[STREXTRA])) { lprcat("\nYou slip and fall down the shaft"); beep();
											  lastnum=275;  losehp(30+rnd(20)); bottomhp(); }
					
					else lprcat("climb down");  nap(3000);  newcavelevel(MAXLEVEL);
					for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++) /* put player near volcano shaft */
						if (item[j][i]==OVOLUP) { playerx=j; playery=i; j=MAXX; i=MAXY; positionplayer(); }
					draws(0,MAXX,0,MAXY); bot_linex(); return;

	case OVOLUP:	lprcat("\nYou have found "); lprcat(objectname[OVOLUP]);
						lprcat("\nDo you (c) climb up"); iopts();
						i=0; while ((i!='c') && (i!='i') && (i!='\33')) i=getchar();
						if ((i=='\33') || (i=='i')) { ignore();  break; }
					if (level!=11) { lprcat("\nThe shaft only extends 8 feet upwards before you find a blockage!"); return; }
					if (packweight() > 45+5*(c[STRENGTH]+c[STREXTRA])) { lprcat("\nYou slip and fall down the shaft"); beep();
											  lastnum=275; losehp(15+rnd(20)); bottomhp(); return; }
					lprcat("climb up"); lflush(); nap(3000); newcavelevel(0);
					for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++) /* put player near volcano shaft */
						if (item[j][i]==OVOLDOWN) { playerx=j; playery=i; j=MAXX; i=MAXY; positionplayer(); }
					draws(0,MAXX,0,MAXY); bot_linex(); return;

	case OTRAPARROWIV:	if (rnd(17)<13) return;	/* for an arrow trap */
						item[playerx][playery] = OTRAPARROW;
						know[playerx][playery] = 0;

	case OTRAPARROW:	lprcat("\nYou are hit by an arrow"); beep();	/* for an arrow trap */
						lastnum=259;	losehp(rnd(10)+level);
						bottomhp();	return;

	case OIVDARTRAP:	if (rnd(17)<13) return;		/* for a dart trap */
						item[playerx][playery] = ODARTRAP;
						know[playerx][playery] = 0;

	case ODARTRAP:		lprcat("\nYou are hit by a dart"); beep();	/* for a dart trap */
						lastnum=260;	losehp(rnd(5));
						if ((--c[STRENGTH]) < 3) c[STRENGTH] = 3;
						bottomline();	return;

	case OIVTRAPDOOR:	if (rnd(17)<13) return;		/* for a trap door */
						item[playerx][playery] = OTRAPDOOR;
						know[playerx][playery] = 1;

	case OTRAPDOOR:		lastnum = 272; /* a trap door */
						if ((level==MAXLEVEL-1) || (level==MAXLEVEL+MAXVLEVEL-1))
							{ lprcat("\nYou fell through a bottomless trap door!"); beep();  nap(3000);  died(271); }
						lprcat("\nYou fall through a trap door!"); beep();	/* for a trap door */
						losehp(rnd(5+level));
						nap(2000);  newcavelevel(level+1);  draws(0,MAXX,0,MAXY); bot_linex();
						return;


	case OTRADEPOST:	if (nearbymonst()) return;
				lprcat("\nYou have found the Larn trading Post.");
				lprcat("\nDo you (g) go inside, or (i) stay here? ");
				i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar();
				if (i == 'g')  otradepost();  else  lprcat("stay here");
				return;

	case OHOME:	if (nearbymonst()) return;
				lprcat("\nYou have found your way home.");
				lprcat("\nDo you (g) go inside, or (i) stay here? ");
				i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar();
				if (i == 'g')  ohome();  else  lprcat("stay here");
				return;

	case OWALL:	break;

	case OANNIHILATION:	died(283); return; 	/* annihilated by sphere of annihilation */

	case OLRS:	if (nearbymonst()) return;
				lprcat("\n\nThere is an LRS office here.");
				lprcat("\nDo you (g) go inside, or (i) stay here? ");
				i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchar();
				if (i == 'g')
					olrs();  /*  the larn revenue service */
				else  lprcat(" stay here");
				break;

	default:	finditem(i); break;
	};
}

/*
	function to say what object we found and ask if player wants to take it
 */
finditem(itm)
	int itm;
	{
	int tmp,i;
	lprintf("\n\nYou have found %s ",objectname[itm]);
	tmp=iarg[playerx][playery];
	switch(itm)
		{
		case ODIAMOND:		case ORUBY:			case OEMERALD:
		case OSAPPHIRE:		case OSPIRITSCARAB:	case OORBOFDRAGON:
		case OCUBEofUNDEAD:	case ONOTHEFT:	break;

		default:
		if (tmp>0) lprintf("+ %d",(long)tmp); else if (tmp<0) lprintf(" %d",(long)tmp);
		}
	lprcat("\nDo you want to (t) take it"); iopts();
	i=0; while (i!='t' && i!='i' && i!='\33') i=getchar();
	if (i == 't')
		{	lprcat("take");  if (take(itm,tmp)==0)  forget();	return;	}
	ignore();
	}


/*
	*******
	OSTAIRS
	*******

	subroutine to process the stair cases
	if dir > 0 the up else down
 */
ostairs(dir)
	int dir;
	{
	register int k;
	lprcat("\nDo you (s) stay here  ");
	if (dir > 0)	lprcat("(u) go up  ");	else	lprcat("(d) go down  ");
	lprcat("or (f) kick stairs? ");

	while (1) switch(getchar())
		{
		case '\33':
		case 's':	case 'i':	lprcat("stay here");	return;

		case 'f':	lprcat("kick stairs");
					if (rnd(2) == 1)
						lprcat("\nI hope you feel better.  Showing anger rids you of frustration.");
					else
						{
						k=rnd((level+1)<<1);
						lprintf("\nYou hurt your foot dumb dumb!  You suffer %d hit points",(long)k);
						lastnum=276;  losehp(k);  bottomline();
						}
					return;

		case 'u':	lprcat("go up");
					if (dir < 0)	lprcat("\nThe stairs don't go up!");
					else
					  if (level>=2 && level!=11)
						{
						k = level;  newcavelevel(level-1);
						draws(0,MAXX,0,MAXY); bot_linex();
						}
					  else lprcat("\nThe stairs lead to a dead end!");
					return;

		case 'd':	lprcat("go down");
					if (dir > 0)	lprcat("\nThe stairs don't go down!");
					else
					  if (level!=0 && level!=10 && level!=13)
						{
						k = level;  newcavelevel(level+1);
						draws(0,MAXX,0,MAXY); bot_linex();
						}
					  else lprcat("\nThe stairs lead to a dead end!");
					return;
		};
	}


/*
	*********
	OTELEPORTER
	*********

	subroutine to handle a teleport trap +/- 1 level maximum
 */
oteleport(err)
	int err;
	{
	register int tmp;
	if (err) if (rnd(151)<3)  died(264);  /*	stuck in a rock */
	c[TELEFLAG]=1;	/*	show ?? on bottomline if been teleported	*/
	if (level==0) tmp=0;
	else if (level < MAXLEVEL)
		{ tmp=rnd(5)+level-3; if (tmp>=MAXLEVEL) tmp=MAXLEVEL-1;
			if (tmp<1) tmp=1; }
	else
		{ tmp=rnd(3)+level-2; if (tmp>=MAXLEVEL+MAXVLEVEL) tmp=MAXLEVEL+MAXVLEVEL-1;
			if (tmp<MAXLEVEL) tmp=MAXLEVEL; }
	playerx = rnd(MAXX-2);	playery = rnd(MAXY-2);
	if (level != tmp)	newcavelevel(tmp);  positionplayer();
	draws(0,MAXX,0,MAXY); bot_linex();
	}

/*
	*******
	OPOTION
	*******

	function to process a potion
 */
opotion(pot)
	int pot;
	{
	lprcat("\nDo you (d) drink it, (t) take it"); iopts();
	while (1) switch(getchar())
		{
		case '\33':
		case 'i':	ignore();  return;

		case 'd':	lprcat("drink\n");	forget();	/*	destroy potion	*/
					quaffpotion(pot);		return;

		case 't':	lprcat("take\n");	if (take(OPOTION,pot)==0)  forget();
					return;
		};
	}
		
/*
	function to drink a potion
 */
quaffpotion(pot)
	int pot;
	{
	register int i,j,k;
	if (pot<0 || pot>=MAXPOTION) return; /* check for within bounds */
	potionname[pot][0] = ' ';
	switch(pot)
		{
		case 9: lprcat("\nYou feel greedy . . .");   nap(2000);
				for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
				  if ((item[j][i]==OGOLDPILE) || (item[j][i]==OMAXGOLD))
					{
					know[j][i]=1; show1cell(j,i);
					}
				showplayer();  return;

		case 19: lprcat("\nYou feel greedy . . .");   nap(2000);
				for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
					{
					k=item[j][i];
					if ((k==ODIAMOND) || (k==ORUBY) || (k==OEMERALD) || (k==OMAXGOLD)
						 || (k==OSAPPHIRE) || (k==OLARNEYE) || (k==OGOLDPILE))
						 {
						 know[j][i]=1; show1cell(j,i);
						 }
					}
				showplayer();  return;

		case 20: c[HP] = c[HPMAX]; break;	/* instant healing */

		case 1:	lprcat("\nYou feel better");
				if (c[HP] == c[HPMAX])  raisemhp(1);
				else if ((c[HP] += rnd(20)+20+c[LEVEL]) > c[HPMAX]) c[HP]=c[HPMAX];  break;

		case 2:	lprcat("\nSuddenly, you feel much more skillful!");
				raiselevel();  raisemhp(1); return;

		case 3:	lprcat("\nYou feel strange for a moment"); 
				c[rund(6)]++;  break;

		case 4:	lprcat("\nYou feel more self confident!");
				c[WISDOM] += rnd(2);  break;

		case 5:	lprcat("\nWow!  You feel great!");
				if (c[STRENGTH]<12) c[STRENGTH]=12; else c[STRENGTH]++;  break;

		case 6:	lprcat("\nYour charm went up by one!");  c[CHARISMA]++;  break;

		case 8:	lprcat("\nYour intelligence went up by one!");
				c[INTELLIGENCE]++;  break;

		case 10: for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
				   if (mitem[j][i])
					{
					know[j][i]=1; show1cell(j,i);
					}
				 /*	monster detection	*/  return;

		case 12: lprcat("\nThis potion has no taste to it");  return;

		case 15: lprcat("\nWOW!!!  You feel Super-fantastic!!!");
				 if (c[HERO]==0) for (i=0; i<6; i++) c[i] += 11;
					c[HERO] += 250;  break;

		case 16: lprcat("\nYou have a greater intestinal constitude!");
				 c[CONSTITUTION]++;  break;

		case 17: lprcat("\nYou now have incredibly bulging muscles!!!");
				 if (c[GIANTSTR]==0) c[STREXTRA] += 21;
				 c[GIANTSTR] += 700;  break;

		case 18: lprcat("\nYou feel a chill run up your spine!");
				 c[FIRERESISTANCE] += 1000;  break;

		case 0:	lprcat("\nYou fall asleep. . .");
				i=rnd(11)-(c[CONSTITUTION]>>2)+2;  while(--i>0) { parse2();  nap(1000); }
				cursors();  lprcat("\nYou woke up!");  return;

		case 7:	lprcat("\nYou become dizzy!");
				if (--c[STRENGTH] < 3) c[STRENGTH]=3;  break;

		case 11: lprcat("\nYou stagger for a moment . .");
				 for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
					know[j][i]=0;
				 nap(2000);	draws(0,MAXX,0,MAXY); /* potion of forgetfulness */  return;

		case 13: lprcat("\nYou can't see anything!");  /* blindness */
				 c[BLINDCOUNT]+=500;  return;

		case 14: lprcat("\nYou feel confused"); c[CONFUSE]+= 20+rnd(9); return;

		case 21: lprcat("\nYou don't seem to be affected");  return; /* cure dianthroritis */

		case 22: lprcat("\nYou feel a sickness engulf you"); /* poison */
				 c[HALFDAM] += 200 + rnd(200);  return;

		case 23: lprcat("\nYou feel your vision sharpen");	/* see invisible */
				 c[SEEINVISIBLE] += rnd(1000)+400;
				 monstnamelist[INVISIBLESTALKER] = 'I';  return;
		};
	bottomline();		/*	show new stats		*/  return;
	}

/*
	*******
	OSCROLL
	*******

	function to process a magic scroll
 */
oscroll(typ)
	int typ;
	{
	lprcat("\nDo you ");
	if (c[BLINDCOUNT]==0) lprcat("(r) read it, "); lprcat("(t) take it"); iopts();
	while (1) switch(getchar())
		{
		case '\33':
		case 'i':	ignore();  return;

		case 'r':	if (c[BLINDCOUNT]) break;
					lprcat("read"); forget();
					if (typ==2 || typ==15)  { show1cell(playerx,playery); cursors(); }
					/*	destroy it	*/	read_scroll(typ);  return;

		case 't':	lprcat("take"); if (take(OSCROLL,typ)==0)	forget();	/*	destroy it	*/
					return;
		};
	}

/*
	data for the function to read a scroll
 */
static int xh,yh,yl,xl;
static char curse[] = { BLINDCOUNT, CONFUSE, AGGRAVATE, HASTEMONST, ITCHING,
	LAUGHING, DRAINSTRENGTH, CLUMSINESS, INFEEBLEMENT, HALFDAM };
static char exten[] = { PROTECTIONTIME, DEXCOUNT, STRCOUNT, CHARMCOUNT,
	INVISIBILITY, CANCELLATION, HASTESELF, GLOBE, SCAREMONST, HOLDMONST, TIMESTOP };
char time_change[] = { HASTESELF,HERO,ALTPRO,PROTECTIONTIME,DEXCOUNT,
	STRCOUNT,GIANTSTR,CHARMCOUNT,INVISIBILITY,CANCELLATION,
	HASTESELF,AGGRAVATE,SCAREMONST,STEALTH,AWARENESS,HOLDMONST,HASTEMONST,
	FIRERESISTANCE,GLOBE,SPIRITPRO,UNDEADPRO,HALFDAM,SEEINVISIBLE,
	ITCHING,CLUMSINESS, WTW };
/*
 *	function to adjust time when time warping and taking courses in school
 */
adjtime(tim)
	register long tim;
	{
	register int j;
	for (j=0; j<26; j++)	/* adjust time related parameters */
		if (c[time_change[j]])
			if ((c[time_change[j]] -= tim) < 1) c[time_change[j]]=1;
	regen();
	}

/*
	function to read a scroll
 */
read_scroll(typ)
	int typ;
	{
	register int i,j;
	if (typ<0 || typ>=MAXSCROLL) return;  /* be sure we are within bounds */
	scrollname[typ][0] = ' ';
	switch(typ)
	  {
	  case 0:	lprcat("\nYour armor glows for a moment");  enchantarmor(); return;

	  case 1:	lprcat("\nYour weapon glows for a moment"); enchweapon(); return;  /* enchant weapon */

	  case 2:	lprcat("\nYou have been granted enlightenment!");
				yh = min(playery+7,MAXY);	xh = min(playerx+25,MAXX);
				yl = max(playery-7,0);		xl = max(playerx-25,0);
				for (i=yl; i<yh; i++) for (j=xl; j<xh; j++)  know[j][i]=1;
				nap(2000);	draws(xl,xh,yl,yh);	return;

	  case 3:	lprcat("\nThis scroll seems to be blank");	return;

	  case 4:	createmonster(makemonst(level+1));  return;  /*  this one creates a monster  */

	  case 5:	something(level);	/*	create artifact		*/  return;

	  case 6:	c[AGGRAVATE]+=800; return; /* aggravate monsters */

	  case 7:	gtime += (i = rnd(1000) - 850); /* time warp */ 
				if (i>=0) lprintf("\nYou went forward in time by %d mobuls",(long)((i+99)/100));
				else lprintf("\nYou went backward in time by %d mobuls",(long)(-(i+99)/100));
				adjtime((long)i);	/* adjust time for time warping */
				return;

	  case 8:	oteleport(0);	  return;	/*	teleportation */

	  case 9:	c[AWARENESS] += 1800;  return;	/* expanded awareness	*/

	  case 10:	c[HASTEMONST] += rnd(55)+12; return;	/* haste monster */

	  case 11:	for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
					if (mitem[j][i])
						hitp[j][i] = monster[mitem[j][i]].hitpoints;
				return;	/* monster healing */
	  case 12:	c[SPIRITPRO] += 300 + rnd(200); bottomline(); return; /* spirit protection */

	  case 13:	c[UNDEADPRO] += 300 + rnd(200); bottomline(); return; /* undead protection */

	  case 14:	c[STEALTH] += 250 + rnd(250);  bottomline(); return; /* stealth */

	  case 15:	lprcat("\nYou have been granted enlightenment!"); /* magic mapping */
				for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++)  know[j][i]=1;
				nap(2000);	draws(0,MAXX,0,MAXY);	return;

	  case 16:	c[HOLDMONST] += 30; bottomline(); return; /* hold monster */

	  case 17:	for (i=0; i<26; i++)	/* gem perfection */
					switch(iven[i])
						{
						case ODIAMOND:	case ORUBY:
						case OEMERALD:	case OSAPPHIRE:
							j = ivenarg[i];  j &= 255;  j <<= 1;
							if (j  > 255) j=255; /* double value */
							ivenarg[i] = j;	break;
						}
				break;

	  case 18:	for (i=0; i<11; i++)	c[exten[i]] <<= 1; /* spell extension */
				break;

	  case 19:	for (i=0; i<26; i++)	/* identify */
					{
					if (iven[i]==OPOTION)  potionname[ivenarg[i]][0] = ' ';
					if (iven[i]==OSCROLL)  scrollname[ivenarg[i]][0] = ' ';
					}
				break;

	  case 20:	for (i=0; i<10; i++)	/* remove curse */
					if (c[curse[i]]) c[curse[i]] = 1;
				break;

	  case 21:	annihilate();	break;	/* scroll of annihilation */

	  case 22:	godirect(22,150,"The ray hits the %s",0,' ');	/* pulverization */
				break;
	  case 23:  c[LIFEPROT]++;  break; /* life protection */
	  };
	}


oorb()
	{
	}

opit()
	{
	register int i;
	if (rnd(101)<81)
	  if (rnd(70) > 9*c[DEXTERITY]-packweight() || rnd(101)<5)
		if (level==MAXLEVEL-1) obottomless(); else
		if (level==MAXLEVEL+MAXVLEVEL-1) obottomless(); else
			{
			if (rnd(101)<20)
				{
				i=0; lprcat("\nYou fell into a pit!  Your fall is cushioned by an unknown force\n");
				}
			else
				{
				i = rnd(level*3+3);
				lprintf("\nYou fell into a pit!  You suffer %d hit points damage",(long)i);
				lastnum=261; 	/*	if he dies scoreboard will say so */
				}
			losehp(i); nap(2000);  newcavelevel(level+1);  draws(0,MAXX,0,MAXY);
			}
	}

obottomless()
	{
	lprcat("\nYou fell into a bottomless pit!");  beep(); nap(3000);  died(262);
	}
oelevator(dir)
	int dir;
	{
#ifdef lint
	int x;
	x=dir;
	dir=x;
#endif lint
	}

ostatue()
	{
	}

omirror()
	{
	}

obook()
	{
	lprcat("\nDo you ");
	if (c[BLINDCOUNT]==0) lprcat("(r) read it, "); lprcat("(t) take it"); iopts();
	while (1) switch(getchar())
		{
		case '\33':
		case 'i':	ignore();	return;

		case 'r':	if (c[BLINDCOUNT]) break;
					lprcat("read");
					/* no more book	*/	readbook(iarg[playerx][playery]);  forget(); return;

		case 't':	lprcat("take");  if (take(OBOOK,iarg[playerx][playery])==0)  forget();	/* no more book	*/
					return;
		};
	}

/*
	function to read a book
 */
readbook(lev)
	register int lev;
	{
	register int i,tmp;
	if (lev<=3) i = rund((tmp=splev[lev])?tmp:1); else
		i = rnd((tmp=splev[lev]-9)?tmp:1) + 9;
	spelknow[i]=1;
	lprintf("\nSpell \"%s\":  %s\n%s",spelcode[i],spelname[i],speldescript[i]);
	if (rnd(10)==4)
	 { lprcat("\nYour int went up by one!"); c[INTELLIGENCE]++; bottomline(); }
	}

ocookie()
	{
	char *p;
	lprcat("\nDo you (e) eat it, (t) take it"); iopts();
	while (1) switch(getchar())
		{
		case '\33':
		case 'i':	ignore();	return;

		case 'e':	lprcat("eat\nThe cookie tasted good.");
					forget(); /* no more cookie	*/
					if (c[BLINDCOUNT]) return;
					if (!(p=fortune(fortfile))) return;
					lprcat("  A message inside the cookie reads:\n"); lprcat(p);
					return;

		case 't':	lprcat("take");  if (take(OCOOKIE,0)==0) forget();	/* no more book	*/
					return;
		};
	}


/* routine to pick up some gold -- if arg==OMAXGOLD then the pile is worth 100* the argument */
ogold(arg)
	int arg;
	{
	register long i;
	i = iarg[playerx][playery];
	if (arg==OMAXGOLD) i *= 100;
		else if (arg==OKGOLD) i *= 1000;
			else if (arg==ODGOLD) i *= 10;
	lprintf("\nIt is worth %d!",(long)i);	c[GOLD] += i;  bottomgold();
	item[playerx][playery] = know[playerx][playery] = 0; /*	destroy gold	*/
	}

ohome()
	{
	register int i;
	nosignal = 1;	/* disable signals */
	for (i=0; i<26; i++) if (iven[i]==OPOTION) if (ivenarg[i]==21)
		{
		iven[i]=0;	/* remove the potion of cure dianthroritis from inventory */
		clear(); lprcat("Congratulations.  You found a potion of cure dianthroritis.\n");
		lprcat("\nFrankly, No one thought you could do it.  Boy!  Did you surprise them!\n");
		if (gtime>TIMELIMIT)
			{
			lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
			lprcat("You didn't make it in time.  In your agony, you kill the doctor,\nyour wife, and yourself!  Too bad!\n");
			nap(5000); died(269);
			}
		else
			{
			lprcat("\nThe doctor is now administering the potion, and in a few moments\n");
			lprcat("Your daughter should be well on her way to recovery.\n");
			nap(6000);
			lprcat("\nThe potion is"); nap(3000); lprcat(" working!  The doctor thinks that\n");
			lprcat("your daughter will recover in a few days.  Congratulations!\n");
			beep(); nap(5000); died(263);
			}
		}

	while (1)
		{
		clear(); lprintf("Welcome home %s.  Latest word from the doctor is not good.\n",logname);

		if (gtime>TIMELIMIT)
			{
			lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
			lprcat("You didn't make it in time.  In your agony, you kill the doctor,\nyour wife, and yourself!  Too bad!\n");
			nap(5000); died(269);
			}

		lprcat("\nThe diagnosis is confirmed as dianthroritis.  He guesses that\n");
		lprintf("your daughter has only %d mobuls left in this world.  It's up to you,\n",(long)((TIMELIMIT-gtime+99)/100));
		lprintf("%s, to find the only hope for your daughter, the very rare\n",logname);
		lprcat("potion of cure dianthroritis.  It is rumored that only deep in the\n");
		lprcat("depths of the caves can this potion be found.\n\n\n");
		lprcat("\n     ----- press "); standout("return");
		lprcat(" to continue, "); standout("escape");
		lprcat(" to leave ----- ");
		i=getchar();  while (i!='\33' && i!='\n') i=getchar();
		if (i=='\33') { drawscreen(); nosignal = 0; /* enable signals */ return; }
		}
	}

/*	routine to save program space	*/
iopts()
	{	lprcat(", or (i) ignore it? ");	}
ignore()
	{	lprcat("ignore\n");	}

SHAR_EOF
if test 25376 -ne "`wc -c < 'object.c'`"
then
	echo shar: error transmitting "'object.c'" '(should have been 25376 characters)'
fi
fi
echo shar: extracting "'regen.c'" '(3323 characters)'
if test -f 'regen.c'
then
	echo shar: will not over-write existing file "'regen.c'"
else
cat << \SHAR_EOF > 'regen.c'
/* regen.c 			Larn is copyrighted 1986 by Noah Morgan. */
#include "header.h"
/*
	*******
	REGEN()
	*******
	regen()

	subroutine to regenerate player hp and spells
 */
regen()
	{
	register int i,flag;
	register long *d;
	d = c;
#ifdef EXTRA
	d[MOVESMADE]++;
#endif
	if (d[TIMESTOP])  { if(--d[TIMESTOP]<=0) bottomline();  return; }	/* for stop time spell */
	flag=0;

	if (d[STRENGTH]<3)	{ d[STRENGTH]=3; flag=1; }
	if ((d[HASTESELF]==0) || ((d[HASTESELF] & 1) == 0))
		gtime++;

	if (d[HP] != d[HPMAX])
		if (d[REGENCOUNTER]-- <= 0)		/*	regenerate hit points	*/
			{
			d[REGENCOUNTER] = 22 + (d[HARDGAME]<<1) - d[LEVEL];
			if ((d[HP] += d[REGEN]) > d[HPMAX])  d[HP] = d[HPMAX];
			bottomhp();
			}

	if (d[SPELLS] < d[SPELLMAX])		/*	regenerate spells	*/
		if (d[ECOUNTER]-- <= 0)
			{
			d[ECOUNTER] = 100+4*(d[HARDGAME]-d[LEVEL]-d[ENERGY]);
			d[SPELLS]++;	bottomspell();
			}

	if (d[HERO])			if (--d[HERO]<=0) { for (i=0; i<6; i++) d[i] -= 10; flag=1; }
	if (d[ALTPRO])			if (--d[ALTPRO]<=0)			{ d[MOREDEFENSES]-=3; flag=1; }
	if (d[PROTECTIONTIME])	if (--d[PROTECTIONTIME]<=0)	{ d[MOREDEFENSES]-=2; flag=1; }
	if (d[DEXCOUNT])		if (--d[DEXCOUNT]<=0)		{ d[DEXTERITY]-=3; flag=1; }
	if (d[STRCOUNT])		if (--d[STRCOUNT]<=0)		{ d[STREXTRA]-=3; flag=1; }
	if (d[BLINDCOUNT])		if (--d[BLINDCOUNT]<=0)		{ cursors();  lprcat("\nThe blindness lifts  "); beep(); }
	if (d[CONFUSE])			if (--d[CONFUSE]<=0) { cursors();  lprcat("\nYou regain your senses"); beep(); }
	if (d[GIANTSTR])		if (--d[GIANTSTR]<=0) { d[STREXTRA] -= 20; flag=1; }
	if (d[CHARMCOUNT])		if ((--d[CHARMCOUNT]) <= 0) flag=1;
	if (d[INVISIBILITY])	if ((--d[INVISIBILITY]) <= 0) flag=1;
	if (d[CANCELLATION])	if ((--d[CANCELLATION]) <= 0) flag=1;
	if (d[WTW])				if ((--d[WTW]) <= 0) flag=1;
	if (d[HASTESELF])		if ((--d[HASTESELF]) <= 0) flag=1;
	if (d[AGGRAVATE])		--d[AGGRAVATE]; 
	if (d[SCAREMONST])		if ((--d[SCAREMONST]) <= 0) flag=1; 
	if (d[STEALTH])			if ((--d[STEALTH]) <= 0) flag=1; 
	if (d[AWARENESS])		--d[AWARENESS];
	if (d[HOLDMONST])		if ((--d[HOLDMONST]) <= 0) flag=1;
	if (d[HASTEMONST])		--d[HASTEMONST];
	if (d[FIRERESISTANCE])	if ((--d[FIRERESISTANCE]) <= 0) flag=1;
	if (d[GLOBE])			if (--d[GLOBE]<=0) { d[MOREDEFENSES]-=10; flag=1; }
	if (d[SPIRITPRO])		if (--d[SPIRITPRO] <= 0) flag=1;
	if (d[UNDEADPRO])		if (--d[UNDEADPRO] <= 0) flag=1;
	if (d[HALFDAM])			if (--d[HALFDAM]<=0)  { cursors();  lprcat("\nYou now feel better "); beep(); }
	if (d[SEEINVISIBLE])
	  if (--d[SEEINVISIBLE]<=0)
		{ monstnamelist[INVISIBLESTALKER] = ' ';
		  cursors();  lprcat("\nYou feel your vision return to normal"); beep(); }
	if (d[ITCHING])
		{
		if (d[ITCHING]>1)
			if ((d[WEAR]!= -1) || (d[SHIELD]!= -1))
				if (rnd(100)<50)
					{
					d[WEAR]=d[SHIELD]= -1; cursors();
					lprcat("\nThe hysteria of itching forces you to remove your armor!"); 
					beep(); recalc();  bottomline();
					}
		if (--d[ITCHING]<=0) { cursors();  lprcat("\nYou now feel the irritation subside!"); beep(); }
		}
	if (d[CLUMSINESS])
		{
		if (d[WIELD] != -1)
			if (d[CLUMSINESS]>1)
			  if (item[playerx][playery]==0)	/* only if nothing there */
				if (rnd(100)<33) /* drop your weapon due to clumsiness */
					drop_object((int)d[WIELD]);
		if (--d[CLUMSINESS]<=0) { cursors();  lprcat("\nYou now feel less awkward!"); beep(); }
		}
	if (flag) bottomline();
	}

SHAR_EOF
if test 3323 -ne "`wc -c < 'regen.c'`"
then
	echo shar: error transmitting "'regen.c'" '(should have been 3323 characters)'
fi
fi
echo shar: extracting "'scores.c'" '(21238 characters)'
if test -f 'scores.c'
then
	echo shar: will not over-write existing file "'scores.c'"
else
cat << \SHAR_EOF > 'scores.c'
/* scores.c			 Larn is copyrighted 1986 by Noah Morgan.
 *
 *	Functions in this file are:
 *
 *	readboard() 	Function to read in the scoreboard into a static buffer
 *	writeboard()	Function to write the scoreboard from readboard()'s buffer
 *	makeboard() 	Function to create a new scoreboard (wipe out old one)
 *	hashewon()	 Function to return 1 if player has won a game before, else 0
 *	long paytaxes(x)	 Function to pay taxes if any are due
 *	winshou()		Subroutine to print out the winning scoreboard
 *	shou(x)			Subroutine to print out the non-winners scoreboard
 *	showscores()		Function to show the scoreboard on the terminal
 *	showallscores()	Function to show scores and the iven lists that go with them
 *	sortboard()		Function to sort the scoreboard
 *	newscore(score, whoo, whyded, winner) 	Function to add entry to scoreboard
 *	new1sub(score,i,whoo,taxes) 		  Subroutine to put player into a 
 *	new2sub(score,i,whoo,whyded)	 	  Subroutine to put player into a 
 *	died(x) 	Subroutine to record who played larn, and what the score was
 *	diedsub(x) Subroutine to print out a line showing player when he is killed
 *	diedlog() 	Subroutine to read a log file and print it out in ascii format
 *	getplid(name)		Function to get players id # from id file
 *
 */
#include <sys/types.h>
#include <sys/times.h>
#include <sys/stat.h>
#include "header.h"

struct scofmt			/*	This is the structure for the scoreboard 		*/
	{
	long score;			/* the score of the player 							*/
	long suid;			/* the user id number of the player 				*/
	short what;			/* the number of the monster that killed player 	*/
	short level;		/* the level player was on when he died 			*/
	short hardlev;		/* the level of difficulty player played at 		*/
	short order;		/* the relative ordering place of this entry 		*/
	char who[40];		/* the name of the character 						*/
	char sciv[26][2];	/* this is the inventory list of the character 		*/
	};
struct wscofmt			/* This is the structure for the winning scoreboard */
	{
	long score;			/* the score of the player 							*/
	long timeused;		/* the time used in mobuls to win the game 			*/
	long taxes;			/* taxes he owes to LRS 							*/
	long suid;			/* the user id number of the player 				*/
	short hardlev;		/* the level of difficulty player played at 		*/
	short order;		/* the relative ordering place of this entry 		*/
	char who[40];		/* the name of the character 						*/
	};

struct log_fmt			/* 102 bytes struct for the log file 				*/
	{
	long score;			/* the players score 								*/
	long diedtime;		/* time when game was over 							*/
	short cavelev;		/* level in caves 									*/
	short diff;			/* difficulty player played at 						*/
#ifdef EXTRA
	long elapsedtime;	/* real time of game in seconds 					*/
	long bytout;		/* bytes input and output 							*/
	long bytin;
	long moves;			/* number of moves made by player 					*/
	short ac;			/* armor class of player 							*/
	short hp,hpmax;		/* players hitpoints 								*/
	short cputime;		/* cpu time needed in seconds 						*/
	short killed,spused;/* monsters killed and spells cast 					*/
	short usage;		/* usage of the cpu in % 							*/
	short lev;			/* player level 									*/
#endif
	char who[12];		/* player name 										*/
	char what[46];		/* what happened to player 							*/
	};

static struct scofmt sco[SCORESIZE];	/* the structure for the scoreboard  */
static struct wscofmt winr[SCORESIZE];	/* struct for the winning scoreboard */
static struct log_fmt logg;				/* structure for the log file 		 */
static char *whydead[] = {
	"quit", "suspended", "self - annihilated", "shot by an arrow",
	"hit by a dart", "fell into a pit", "fell into a bottomless pit",
	"a winner", "trapped in solid rock", "killed by a missing save file",
	"killed by an old save file", "caught by the greedy cheater checker trap",
	"killed by a protected save file","killed his family and committed suicide",
	"erased by a wayward finger", "fell through a bottomless trap door",
	"fell through a trap door", "drank some poisonous water",
	"fried by an electric shock", "slipped on a volcano shaft",
	"killed by a stupid act of frustration", "attacked by a revolting demon",
	"hit by his own magic", "demolished by an unseen attacker",
	"fell into the dreadful sleep", "killed by an exploding chest",
/*26*/	"killed by a missing maze data file", "annihilated in a sphere",
	"died a post mortem death","wasted by a malloc() failure"
	};

/*
 *	readboard() 	Function to read in the scoreboard into a static buffer
 *
 *	returns -1 if unable to read in the scoreboard, returns 0 if all is OK
 */
readboard()
	{
	if (lopen(scorefile)<0)
	  { lprcat("Can't read scoreboard\n"); lflush(); return(-1); }
	lrfill((char*)sco,sizeof(sco));		lrfill((char*)winr,sizeof(winr));
	lrclose();  lcreat((char*)0);  return(0);
	}

/*
 *	writeboard()	Function to write the scoreboard from readboard()'s buffer
 *
 *	returns -1 if unable to write the scoreboard, returns 0 if all is OK
 */
writeboard()
	{
	set_score_output();
	if (lcreat(scorefile)<0)
	  { lprcat("Can't write scoreboard\n"); lflush(); return(-1); }
	lwrite((char*)sco,sizeof(sco));		lwrite((char*)winr,sizeof(winr));
	lwclose();  lcreat((char*)0);  return(0);
	}

/*
 *	makeboard() 		Function to create a new scoreboard (wipe out old one)
 *
 *	returns -1 if unable to write the scoreboard, returns 0 if all is OK
 */
makeboard()
	{
	register int i;
	for (i=0; i<SCORESIZE; i++)
		{
		winr[i].taxes = winr[i].score = sco[i].score = 0;
		winr[i].order = sco[i].order = i;
		}
	if (writeboard()) return(-1);
	chmod(scorefile,0666);
	return(0);
	}

/*
 *	hashewon()	 Function to return 1 if player has won a game before, else 0
 *
 *	This function also sets c[HARDGAME] to appropriate value -- 0 if not a
 *	winner, otherwise the next level of difficulty listed in the winners
 *	scoreboard.  This function also sets outstanding_taxes to the value in
 *	the winners scoreboard.
 */
hashewon()
	{
	register int i;
	c[HARDGAME] = 0;
	if (readboard() < 0) return(0);	/* can't find scoreboard */
	for (i=0; i<SCORESIZE; i++)	/* search through winners scoreboard */
	   if (winr[i].suid == userid)
		  if (winr[i].score > 0)
			{
			c[HARDGAME]=winr[i].hardlev+1;  outstanding_taxes=winr[i].taxes;
			return(1);
			}
	return(0);
	}

/*
 *	long paytaxes(x)		 Function to pay taxes if any are due
 *
 *	Enter with the amount (in gp) to pay on the taxes.
 *	Returns amount actually paid.
 */
long paytaxes(x)
	long x;
	{
	register int i;
	register long amt;
	if (x<0) return(0L);
	if (readboard()<0) return(0L);
	for (i=0; i<SCORESIZE; i++)
		if (winr[i].suid == userid)	/* look for players winning entry */
			if (winr[i].score>0) /* search for a winning entry for the player */
				{
				amt = winr[i].taxes;
				if (x < amt) amt=x;		/* don't overpay taxes (Ughhhhh) */
				winr[i].taxes -= amt;
				outstanding_taxes -= amt;
				if (writeboard()<0) return(0);
				return(amt);
				}
	return(0L);	/* couldn't find user on winning scoreboard */
	}

/*
 *	winshou()		Subroutine to print out the winning scoreboard
 *
 *	Returns the number of players on scoreboard that were shown 
 */
winshou()
	{
	register struct wscofmt *p;
	register int i,j,count;
	for (count=j=i=0; i<SCORESIZE; i++) /* is there anyone on the scoreboard? */
		if (winr[i].score != 0)
			{ j++; break; }
	if (j)
		{
		lprcat("\n  Score    Difficulty   Time Needed   Larn Winners List\n");

		for (i=0; i<SCORESIZE; i++)	/* this loop is needed to print out the */
		  for (j=0; j<SCORESIZE; j++) /* winners in order */
			{
			p = &winr[j];	/* pointer to the scoreboard entry */
			if (p->order == i)
				{
				if (p->score)
					{
					count++;
					lprintf("%10d     %2d      %5d Mobuls   %s \n",
					(long)p->score,(long)p->hardlev,(long)p->timeused,p->who);
					}
				break;
				}
			}
		}
	return(count);	/* return number of people on scoreboard */
	}

/*
 *	shou(x)			Subroutine to print out the non-winners scoreboard
 *		int x;
 *
 *	Enter with 0 to list the scores, enter with 1 to list inventories too
 *	Returns the number of players on scoreboard that were shown 
 */
shou(x)
	int x;
	{
	register int i,j,n,k;
	int count;
	for (count=j=i=0; i<SCORESIZE; i++)	/* is the scoreboard empty? */
		if (sco[i].score!= 0)
			{ j++; break; }
	if (j)
		{
		lprcat("\n   Score   Difficulty   Larn Visitor Log\n");
		for (i=0; i<SCORESIZE; i++) /* be sure to print them out in order */
		  for (j=0; j<SCORESIZE; j++)
			if (sco[j].order == i)
				{
				if (sco[j].score)
					{
					count++;
					lprintf("%10d     %2d       %s ",
						(long)sco[j].score,(long)sco[j].hardlev,sco[j].who);
					if (sco[j].what < 256) lprintf("killed by a %s",monster[sco[j].what].name);
						else lprintf("%s",whydead[sco[j].what - 256]);
					if (x != 263) lprintf(" on %s",levelname[sco[j].level]);
					if (x)
						{
						for (n=0; n<26; n++) { iven[n]=sco[j].sciv[n][0]; ivenarg[n]=sco[j].sciv[n][1]; }
						for (k=1; k<99; k++)
						  for (n=0; n<26; n++)
							if (k==iven[n])  { srcount=0; show3(n); }
						lprcat("\n\n");
						}
					else lprc('\n');
					}
				j=SCORESIZE;
				}
		}
	return(count);	/* return the number of players just shown */
	}

/*
 *	showscores()		Function to show the scoreboard on the terminal
 *
 *	Returns nothing of value
 */
static char esb[] = "The scoreboard is empty.\n";
showscores()
	{
	register int i,j;
	lflush();  lcreat((char*)0);  if (readboard()<0) return;
	i=winshou();	j=shou(0);	
	if (i+j == 0) lprcat(esb); else lprc('\n');
	lflush();
	}

/*
 *	showallscores()	Function to show scores and the iven lists that go with them
 *
 *	Returns nothing of value
 */
showallscores()
	{
	register int i,j;
	lflush();  lcreat((char*)0);  if (readboard()<0) return;
	c[WEAR] = c[WIELD] = c[SHIELD] = -1;  /* not wielding or wearing anything */
	for (i=0; i<MAXPOTION; i++) potionname[i][0]=' ';
	for (i=0; i<MAXSCROLL; i++) scrollname[i][0]=' ';
	i=winshou();  j=shou(1);
	if (i+j==0) lprcat(esb); else lprc('\n');
	lflush();
	}

/*
 *	sortboard()		Function to sort the scoreboard
 *
 *	Returns 0 if no sorting done, else returns 1
 */
sortboard()
	{
	register int i,j,pos;
	long jdat;
	for (i=0; i<SCORESIZE; i++) sco[i].order = winr[i].order = -1;
	pos=0;  while (pos < SCORESIZE)
		{
		jdat=0;
		for (i=0; i<SCORESIZE; i++)
			if ((sco[i].order < 0) && (sco[i].score >= jdat))
				{ j=i;  jdat=sco[i].score; }
		sco[j].order = pos++;
		}
	pos=0;  while (pos < SCORESIZE)
		{
		jdat=0;
		for (i=0; i<SCORESIZE; i++)
			if ((winr[i].order < 0) && (winr[i].score >= jdat))
				{ j=i;  jdat=winr[i].score; }
		winr[j].order = pos++;
		}
	return(1);
	}

/*
 *	newscore(score, whoo, whyded, winner) 	Function to add entry to scoreboard
 *		int score, winner, whyded;
 *		char *whoo;
 *
 *	Enter with the total score in gp in score,  players name in whoo,
 *		died() reason # in whyded, and TRUE/FALSE in winner if a winner
 *	ex.		newscore(1000, "player 1", 32, 0);
 */
newscore(score, whoo, whyded, winner)
	long score;
	int winner, whyded;
	char *whoo;
	{
	register int i;
	long taxes;
	if (readboard() < 0) return; 	/*	do the scoreboard	*/
	/* if a winner then delete all non-winning scores */
	if (cheat) winner=0;	/* if he cheated, don't let him win */
	if (winner)
		{
		for (i=0; i<SCORESIZE; i++) if (sco[i].suid == userid) sco[i].score=0;
		taxes = score*TAXRATE;
		score += 100000*c[HARDGAME];	/* bonus for winning */
	/* if he has a slot on the winning scoreboard update it if greater score */
		for (i=0; i<SCORESIZE; i++) if (winr[i].suid == userid)
				{ new1sub(score,i,whoo,taxes); return; }
	/* he had no entry. look for last entry and see if he has a greater score */
		for (i=0; i<SCORESIZE; i++) if (winr[i].order == SCORESIZE-1)
				{ new1sub(score,i,whoo,taxes); return; }
		}
	else if (!cheat) /* for not winning scoreboard */
		{
	/* if he has a slot on the scoreboard update it if greater score */
		for (i=0; i<SCORESIZE; i++) if (sco[i].suid == userid)
				{ new2sub(score,i,whoo,whyded); return; }
	/* he had no entry. look for last entry and see if he has a greater score */
		for (i=0; i<SCORESIZE; i++) if (sco[i].order == SCORESIZE-1)
				{ new2sub(score,i,whoo,whyded); return; }
		}
	}

/*
 *	new1sub(score,i,whoo,taxes) 	  Subroutine to put player into a 
 *		int score,i,whyded,taxes;		  winning scoreboard entry if his score
 *		char *whoo; 					  is high enough
 *
 *	Enter with the total score in gp in score,  players name in whoo,
 *		died() reason # in whyded, and TRUE/FALSE in winner if a winner
 *		slot in scoreboard in i, and the tax bill in taxes.
 *	Returns nothing of value
 */
new1sub(score,i,whoo,taxes)
	long score,taxes;
	int i;
	char *whoo;
	{
	register struct wscofmt *p;
	p = &winr[i];
	p->taxes += taxes;
	if ((score >= p->score) || (c[HARDGAME] > p->hardlev))
		{
		strcpy(p->who,whoo);  		p->score=score;
		p->hardlev=c[HARDGAME];		p->suid=userid;
		p->timeused=gtime/100;
		}
	}

/*
 *	new2sub(score,i,whoo,whyded)	 	  Subroutine to put player into a 
 *		int score,i,whyded,taxes;		  non-winning scoreboard entry if his
 *		char *whoo; 					  score is high enough
 *
 *	Enter with the total score in gp in score,  players name in whoo,
 *		died() reason # in whyded, and slot in scoreboard in i.
 *	Returns nothing of value
 */
new2sub(score,i,whoo,whyded)
	long score;
	int i,whyded;
	char *whoo;
	{
	register int j;
	register struct scofmt *p;
	p = &sco[i];
	if ((score >= p->score) || (c[HARDGAME] > p->hardlev))
		{
		strcpy(p->who,whoo);  p->score=score;
		p->what=whyded;       p->hardlev=c[HARDGAME];
		p->suid=userid;		  p->level=level;
		for (j=0; j<26; j++)
			{ p->sciv[j][0]=iven[j]; p->sciv[j][1]=ivenarg[j]; }
		}
	}

/*
 *	died(x) 	Subroutine to record who played larn, and what the score was
 *		int x;
 *
 *	if x < 0 then don't show scores
 *	died() never returns! (unless c[LIFEPROT] and a reincarnatable death!)
 *
 *		< 256	killed by the monster number
 *		256		quit
 *		257		suspended
 *		258		self - annihilated
 *		259		shot by an arrow
 *		260		hit by a dart
 *		261		fell into a pit
 *		262		fell into a bottomless pit
 *		263		a winner
 *		264		trapped in solid rock
 *		265		killed by a missing save file
 *		266		killed by an old save file
 *		267		caught by the greedy cheater checker trap
 *		268		killed by a protected save file
 *		269		killed his family and killed himself
 *		270		erased by a wayward finger
 *		271		fell through a bottomless trap door
 *		272		fell through a trap door
 *		273		drank some poisonous water
 *		274		fried by an electric shock
 *		275		slipped on a volcano shaft
 *		276		killed by a stupid act of frustration
 *		277		attacked by a revolting demon
 *		278		hit by his own magic
 *		279		demolished by an unseen attacker
 *		280		fell into the dreadful sleep
 *		281		killed by an exploding chest
 *		282		killed by a missing maze data file
 *		283		killed by a sphere of annihilation
 *		284		died a post mortem death
 *		285		malloc() failure
 *		300		quick quit -- don't put on scoreboard
 */

static int scorerror;
died(x)
	int x;
	{
	register int f,win;
	char ch,*mod;
	long zzz,i;
	struct tms cputime;
	if (c[LIFEPROT]>0) /* if life protection */
		{
		switch((x>0) ? x : -x)
			{
			case 256: case 257: case 262: case 263: case 265: case 266:
			case 267: case 268: case 269: case 271: case 282: case 284:
			case 285: case 300:  goto invalid; /* can't be saved */
			};
		--c[LIFEPROT]; c[HP]=1; --c[CONSTITUTION];
		cursors(); lprcat("\nYou feel wiiieeeeerrrrrd all over! "); beep();
		lflush();  sleep(4);
		return; /* only case where died() returns */
		}
invalid:
	clearvt100();  lflush();  f=0;
	if (ckpflag) unlink(ckpfile);	/* remove checkpoint file if used */
	if (x<0) { f++; x = -x; }	/* if we are not to display the scores */
	if ((x == 300) || (x == 257))  exit();	/* for quick exit or saved game */
	if (x == 263)  win = 1;  else  win = 0;
	c[GOLD] += c[BANKACCOUNT];   c[BANKACCOUNT] = 0;
		/*	now enter the player at the end of the scoreboard */
	newscore(c[GOLD], logname, x, win);
	diedsub(x);	/* print out the score line */  lflush();

	set_score_output();
	if ((wizard == 0) && (c[GOLD] > 0)) 	/*	wizards can't score		*/
		{
		if (lappend(logfile)<0)  /* append to file */
			{
			if (lcreat(logfile)<0) /* and can't create new log file */
		    	{
				lcreat((char*)0);
				lprcat("\nCan't open record file:  I can't post your score.\n");
				sncbr();  resetscroll();  lflush();  exit();
				}
			chmod(logfile,0666);
			}
		strcpy(logg.who,loginname);
		logg.score = c[GOLD];		logg.diff = c[HARDGAME];
		if (x < 256)
			{
			ch = *monster[x].name;
			if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u')
				mod="an";  else mod="a";
			sprintf(logg.what,"killed by %s %s",mod,monster[x].name);
			}
		else sprintf(logg.what,"%s",whydead[x - 256]);
		logg.cavelev=level;
		time(&zzz);	  /* get cpu time -- write out score info */
		logg.diedtime=zzz;
#ifdef EXTRA
		times(&cputime);  /* get cpu time -- write out score info */
		logg.cputime = i = (cputime.tms_utime + cputime.tms_stime)/60 + c[CPUTIME];
		logg.lev=c[LEVEL];			logg.ac=c[AC];
		logg.hpmax=c[HPMAX];		logg.hp=c[HP];
		logg.elapsedtime=(zzz-initialtime+59)/60;
		logg.usage=(10000*i)/(zzz-initialtime);
		logg.bytin=c[BYTESIN];		logg.bytout=c[BYTESOUT];
		logg.moves=c[MOVESMADE];	logg.spused=c[SPELLSCAST];
		logg.killed=c[MONSTKILLED];
#endif
		lwrite((char*)&logg,sizeof(struct log_fmt));	 lwclose();

/*	now for the scoreboard maintenance -- not for a suspended game 	*/
		if (x != 257)
			{
			if (sortboard())  scorerror = writeboard();
			}
		}
	if ((x==256) || (x==257) || (f != 0)) exit();
	if (scorerror == 0) showscores();	/* if we updated the scoreboard */
	if (x == 263) mailbill();		exit();
	}

/*
 *	diedsub(x) Subroutine to print out the line showing the player when he is killed
 *		int x;
 */
diedsub(x)
int x;
	{
	register char ch,*mod;
	lprintf("Score: %d, Diff: %d,  %s ",(long)c[GOLD],(long)c[HARDGAME],logname);
	if (x < 256)
		{
		ch = *monster[x].name;
		if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u')
			mod="an";  else mod="a";
		lprintf("killed by %s %s",mod,monster[x].name);
		}
	else lprintf("%s",whydead[x - 256]);
	if (x != 263) lprintf(" on %s\n",levelname[level]);  else lprc('\n');
	}

/*
 *	diedlog() 	Subroutine to read a log file and print it out in ascii format
 */
diedlog()
	{
	register int n;
	register char *p;
	struct stat stbuf;
	lcreat((char*)0);
	if (lopen(logfile)<0)
		{
		lprintf("Can't locate log file <%s>\n",logfile);
		return;
		}
	if (fstat(fd,&stbuf) < 0)
		{
		lprintf("Can't  stat log file <%s>\n",logfile);
		return;
		}
	for (n=stbuf.st_size/sizeof(struct log_fmt); n>0; --n)
		{
		lrfill((char*)&logg,sizeof(struct log_fmt));
		p = ctime(&logg.diedtime); p[16]='\n'; p[17]=0;
		lprintf("Score: %d, Diff: %d,  %s %s on %d at %s",(long)(logg.score),(long)(logg.diff),logg.who,logg.what,(long)(logg.cavelev),p+4);
#ifdef EXTRA
		if (logg.moves<=0) logg.moves=1;
		lprintf("  Experience Level: %d,  AC: %d,  HP: %d/%d,  Elapsed Time: %d minutes\n",(long)(logg.lev),(long)(logg.ac),(long)(logg.hp),(long)(logg.hpmax),(long)(logg.elapsedtime));
		lprintf("  CPU time used: %d seconds,  Machine usage: %d.%02d%%\n",(long)(logg.cputime),(long)(logg.usage/100),(long)(logg.usage%100));
		lprintf("  BYTES in: %d, out: %d, moves: %d, deaths: %d, spells cast: %d\n",(long)(logg.bytin),(long)(logg.bytout),(long)(logg.moves),(long)(logg.killed),(long)(logg.spused));
		lprintf("  out bytes per move: %d,  time per move: %d ms\n",(long)(logg.bytout/logg.moves),(long)((logg.cputime*1000)/logg.moves));
#endif
		}
		lflush();  lrclose();  return;
	}

#ifndef UIDSCORE
/*
 *	getplid(name)		Function to get players id # from id file
 *
 *	Enter with the name of the players character in name.
 *	Returns the id # of the players character, or -1 if failure.
 *	This routine will try to find the name in the id file, if its not there,
 *	it will try to make a new entry in the file.  Only returns -1 if can't
 *	find him in the file, and can't make a new entry in the file.
 *	Format of playerids file:
 *			Id # in ascii     \n     character name     \n   
 */
static int havepid= -1;	/* playerid # if previously done */
getplid(nam)
	char *nam;
	{
	int fd7,high=999,no;
	register char *p,*p2;
	char name[80];
	if (havepid != -1) return(havepid);	/* already did it */
	lflush();	/* flush any pending I/O */
	sprintf(name,"%s\n",nam);	/* append a \n to name */
	if (lopen(playerids) < 0)	/* no file, make it */
		{
		if ((fd7=creat(playerids,0666)) < 0)  return(-1); /* can't make it */
		close(fd7);  goto addone;	/* now append new playerid record to file */
		}
	for (;;)	/* now search for the name in the player id file */
		{
		p = lgetl();  if (p==NULL) break;	/* EOF? */
		no = atoi(p);	/* the id # */
		p2= lgetl();  if (p2==NULL) break;	/* EOF? */
		if (no>high) high=no;	/* accumulate highest id # */
		if (strcmp(p2,name)==0)	/* we found him */
			{
			return(no);	/* his id number */
			}
		}
	lrclose();
	/* if we get here, we didn't find him in the file -- put him there */
addone:
	if (lappend(playerids) < 0) return(-1);	/* can't open file for append */
	lprintf("%d\n%s",(long)++high,name);  /* new id # and name */
	lwclose();
	lcreat((char*)0);	/* re-open terminal channel */
	return(high);
	}
#endif UIDSCORE

SHAR_EOF
if test 21238 -ne "`wc -c < 'scores.c'`"
then
	echo shar: error transmitting "'scores.c'" '(should have been 21238 characters)'
fi
fi
echo shar: extracting "'signal.c'" '(4780 characters)'
if test -f 'signal.c'
then
	echo shar: will not over-write existing file "'signal.c'"
else
cat << \SHAR_EOF > 'signal.c'
#include <signal.h>
#include "header.h"			/* "Larn is copyrighted 1986 by Noah Morgan.\n" */
#define BIT(a) (1<<((a)-1))
extern char savefilename[],wizard,predostuff,nosignal;
static s2choose()	/* text to be displayed if ^C during intro screen */
	{
	cursor(1,24); lprcat("Press "); setbold(); lprcat("return"); resetbold();
	lprcat(" to continue: ");   lflush(); 
	}

static cntlc()	/* what to do for a ^C */
	{
	if (nosignal) return;	/* don't do anything if inhibited */
	signal(SIGQUIT,SIG_IGN);	signal(SIGINT,SIG_IGN);
	quit(); if (predostuff==1) s2choose(); else showplayer();
	lflush();
	signal(SIGQUIT,cntlc);	signal(SIGINT,cntlc);
	}

/*
 *	subroutine to save the game if a hangup signal
 */
static sgam()
	{
	savegame(savefilename);  wizard=1;  died(-257); /* hangup signal */
	}

#ifdef SIGTSTP
static tstop() /* control Y	*/
	{
	if (nosignal)   return;  /* nothing if inhibited */
	lcreat((char*)0);  clearvt100();	lflush();	  signal(SIGTSTP,SIG_DFL);
#ifdef SIGVTALRM
	/* looks like BSD4.2 or higher - must clr mask for signal to take effect*/
	sigsetmask(sigblock(0)& ~BIT(SIGTSTP));
#endif
	kill(getpid(),SIGTSTP);

	setupvt100();  signal(SIGTSTP,tstop);
	if (predostuff==1) s2choose(); else drawscreen();
	showplayer();	lflush();
	}
#endif SIGTSTP

/*
 *	subroutine to issue the needed signal traps  called from main()
 */
static sigill()  { sigpanic(SIGILL); }	 static sigtrap() { sigpanic(SIGTRAP); }
static sigiot()  { sigpanic(SIGIOT); }   static sigemt()  { sigpanic(SIGEMT); }
static sigfpe()  { sigpanic(SIGFPE); }   static sigbus()  { sigpanic(SIGBUS); }
static sigsegv() { sigpanic(SIGSEGV); }  static sigsys()  { sigpanic(SIGSYS); }
static sigpipe() { sigpanic(SIGPIPE); }  static sigterm() { sigpanic(SIGTERM); }
sigsetup()
	{
	signal(SIGQUIT, cntlc); 		signal(SIGINT,  cntlc); 
	signal(SIGKILL, SIG_IGN);		signal(SIGHUP,  sgam);
	signal(SIGILL,  sigill);		signal(SIGTRAP, sigtrap);
	signal(SIGIOT,  sigiot);		signal(SIGEMT,  sigemt);
	signal(SIGFPE,  sigfpe);		signal(SIGBUS,  sigbus);
	signal(SIGSEGV, sigsegv);		signal(SIGSYS,  sigsys);
	signal(SIGPIPE, sigpipe);		signal(SIGTERM, sigterm);
#ifdef SIGTSTP
	signal(SIGTSTP,tstop);		signal(SIGSTOP,tstop);
#endif SIGTSTP
	}

#ifdef BSD	/* for BSD UNIX? */

static char *signame[NSIG] = { "",
"SIGHUP",  /*	1	 hangup */
"SIGINT",  /*	2	 interrupt */
"SIGQUIT", /*	3	 quit */
"SIGILL",  /*	4	 illegal instruction (not reset when caught) */
"SIGTRAP", /*	5	 trace trap (not reset when caught) */
"SIGIOT",  /*	6	 IOT instruction */
"SIGEMT",  /*	7	 EMT instruction */
"SIGFPE",  /*	8	 floating point exception */
"SIGKILL", /*	9	 kill (cannot be caught or ignored) */
"SIGBUS",  /*	10	 bus error */
"SIGSEGV", /*	11	 segmentation violation */
"SIGSYS",  /*	12	 bad argument to system call */
"SIGPIPE", /*	13	 write on a pipe with no one to read it */
"SIGALRM", /*	14	 alarm clock */
"SIGTERM", /*	15	 software termination signal from kill */
"SIGURG",  /*	16	 urgent condition on IO channel */
"SIGSTOP", /*	17	 sendable stop signal not from tty */
"SIGTSTP", /*	18	 stop signal from tty */
"SIGCONT", /*	19	 continue a stopped process */
"SIGCHLD", /*	20	 to parent on child stop or exit */
"SIGTTIN", /*	21	 to readers pgrp upon background tty read */
"SIGTTOU", /*	22	 like TTIN for output if (tp->t_local&LTOSTOP) */
"SIGIO",   /*	23	 input/output possible signal */
"SIGXCPU", /*	24	 exceeded CPU time limit */
"SIGXFSZ", /*	25	 exceeded file size limit */
"SIGVTALRM",/*  26	 virtual time alarm */
"SIGPROF", /*	27	 profiling time alarm */
"","","","" };

#else BSD	/* for system V? */

static char *signame[NSIG] = { "",
"SIGHUP",  /*	1	 hangup */
"SIGINT",  /*	2	 interrupt */
"SIGQUIT", /*	3	 quit */
"SIGILL",  /*	4	 illegal instruction (not reset when caught) */
"SIGTRAP", /*	5	 trace trap (not reset when caught) */
"SIGIOT",  /*	6	 IOT instruction */
"SIGEMT",  /*	7	 EMT instruction */
"SIGFPE",  /*	8	 floating point exception */
"SIGKILL", /*	9	 kill (cannot be caught or ignored) */
"SIGBUS",  /*	10	 bus error */
"SIGSEGV", /*	11	 segmentation violation */
"SIGSYS",  /*	12	 bad argument to system call */
"SIGPIPE", /*	13	 write on a pipe with no one to read it */
"SIGALRM", /*	14	 alarm clock */
"SIGTERM", /*	15	 software termination signal from kill */
"SIGUSR1",  /*	16	 user defines signal 1 */
"SIGUSR2", /*	17	 user defines signal 2 */
"SIGCLD",  /*	18	 child death */
"SIGPWR",  /*	19	 power fail */
"","","","","","","","","","","","" };

#endif BSD

/*
 *	routine to process a fatal error signal
 */
static sigpanic(sig)
	int sig;
	{
	char buf[128];
	signal(sig,SIG_DFL);
	sprintf(buf,"\nLarn - Panic! Signal %d received [%s]",sig,signame[sig]);
	write(2,buf,strlen(buf));  sleep(2);
	sncbr();
	savegame(savefilename); 
	kill(getpid(),sig); /* this will terminate us */
	}
SHAR_EOF
if test 4780 -ne "`wc -c < 'signal.c'`"
then
	echo shar: error transmitting "'signal.c'" '(should have been 4780 characters)'
fi
fi
echo shar: extracting "'tok.c'" '(5637 characters)'
if test -f 'tok.c'
then
	echo shar: will not over-write existing file "'tok.c'"
else
cat << \SHAR_EOF > 'tok.c'
/* tok.c		Larn is copyrighted 1986 by Noah Morgan. */
#include <sys/types.h>
#ifdef SYSV
#include <fcntl.h>
#include <termio.h>
#else SYSV
#include <sys/ioctl.h>
#endif SYSV
#include "header.h"

static char lastok=0;
int yrepcount=0,dayplay=0;
#ifndef FLUSHNO
#define FLUSHNO 5
#endif FLUSHNO
static int flushno=FLUSHNO;	/* input queue flushing threshold */
#define MAXUM 52	/* maximum number of user re-named monsters */
#define MAXMNAME 40	/* max length of a monster re-name */
static char usermonster[MAXUM][MAXMNAME]; /* the user named monster name goes here */
static char usermpoint=0;			/* the user monster pointer */

/*
	lexical analyzer for larn
 */
yylex()
	{
	char cc;
	int ic;
	if (hit2flag) { hit2flag=0;  yrepcount=0;  return(' '); }
	if (yrepcount>0)	{ --yrepcount;  return(lastok);	} else yrepcount=0;
	if (yrepcount==0) { bottomdo(); showplayer(); }	/*	show where the player is	*/
	lflush();  
	while (1)
		{
		c[BYTESIN]++;
		if (ckpflag)
		  if ((c[BYTESIN] % 400) == 0)	/* check for periodic checkpointing */
			{
#ifndef DOCHECKPOINTS
			savegame(ckpfile);
#else
			wait(0);	/* wait for other forks to finish */
			if (fork() == 0) { savegame(ckpfile); exit(); }
#endif


#ifdef TIMECHECK
			if (dayplay==0)
			  if (playable())
				{
				cursor(1,19);
				lprcat("\nSorry, but it is now time for work.  Your game has been saved.\n"); beep();
				lflush();  savegame(savefilename);  wizard=nomove=1;  sleep(4);
				died(-257);
				}
#endif TIMECHECK

			}

		do		/* if keyboard input buffer is too big, flush some of it */
			{
			ioctl(0,FIONREAD,&ic);
			if (ic>flushno)   read(0,&cc,1);
			}
		while (ic>flushno);

		if (read(0,&cc,1) != 1) return(lastok = -1);

		if (cc == 'Y'-64)	/* control Y -- shell escape */
			{
			resetscroll();  clear(); /* scrolling region, home, clear, no attributes */
			if ((ic=fork())==0) /* child */
				{
				execl("/bin/csh",0);	exit();
				}
			wait(0);
			if (ic<0) /* error */
				{
				write(2,"Can't fork off a shell!\n",25); sleep(2);
				}

			setscroll();
			return(lastok = 'L'-64);	/* redisplay screen */
			}
		
		if ((cc <= '9') && (cc >= '0'))
			{ yrepcount = yrepcount*10 + cc - '0'; }
		else	{ if (yrepcount>0) --yrepcount;  return(lastok = cc); }
		}
	}

/*
 *	flushall()		Function to flush all type-ahead in the input buffer
 */
flushall()
	{
	char cc;
	int ic;
	for (;;)		/* if keyboard input buffer is too big, flush some of it */
		{
		ioctl(0,FIONREAD,&ic);
		if (ic<=0) return;
		while (ic>0)   { read(0,&cc,1); --ic; } /* gobble up the byte */
		}
	}

/*
	function to set the desired hardness 
	enter with hard= -1 for default hardness, else any desired hardness
 */
sethard(hard)
	int hard;
	{
	register int j,k,i;
	j=c[HARDGAME]; hashewon(); 
	if (restorflag==0)	/* don't set c[HARDGAME] if restoring game */
		{
		if (hard >= 0) c[HARDGAME]= hard;
		}
	else c[HARDGAME]=j; /* set c[HARDGAME] to proper value if restoring game */

	if (k=c[HARDGAME])
	  for (j=0; j<=MAXMONST+8; j++)
		{
		i = ((6+k)*monster[j].hitpoints+1)/6;
		monster[j].hitpoints = (i<0) ? 32767 : i;
		i = ((6+k)*monster[j].damage+1)/5;
		monster[j].damage = (i>127) ? 127 : i;
		i = (10*monster[j].gold)/(10+k);
		monster[j].gold = (i>32767) ? 32767 : i;
		i = monster[j].armorclass - k;
		monster[j].armorclass = (i< -127) ? -127 : i;
		i = (7*monster[j].experience)/(7+k) + 1;
		monster[j].experience = (i<=0) ? 1 : i;
		}				
	}

/*
	function to read and process the larn options file
 */
readopts()
	{
	register char *i;
	register int j,k;
	int flag;
	flag=1;	/* set to 0 if he specifies a name for his character */
	if (lopen(optsfile) < 0)
		{
		strcpy(logname,loginname); return; /* user name if no character name */
		}
	i = " ";
	while (*i)
	  {
	  if ((i=(char *)lgetw()) == 0) break; /* check for EOF */
	  while ((*i==' ') || (*i=='\t')) i++; /* eat leading whitespace */
	  switch(*i)
		{
		case 'b':	if (strcmp(i,"bold-objects") == 0)  boldon=1;
					break;

		case 'e':	if (strcmp(i,"enable-checkpointing") == 0) ckpflag=1;
					break;

		case 'i':	if (strcmp(i,"inverse-objects") == 0)  boldon=0;
					break;

		case 'f':	if (strcmp(i,"female") 	== 0)	sex=0; /* male or female */
					break;

		case 'm':	if (strcmp(i,"monster:")== 0)   /* name favorite monster */
						{
						if ((i=lgetw())==0) break;
						if (strlen(i)>=MAXMNAME) i[MAXMNAME-1]=0;
						strcpy(usermonster[usermpoint],i); 
						if (usermpoint >= MAXUM) break; /* defined all of em */
						if (isalpha(j=usermonster[usermpoint][0]))
							{
							for (k=1; k<MAXMONST+8; k++) /* find monster */
							  if (monstnamelist[k] == j)
								{
								monster[k].name = &usermonster[usermpoint++][0];
								break;
								}
							}
						}
					else if (strcmp(i,"male") == 0)	sex=1;
					break;

		case 'n':	if (strcmp(i,"name:") == 0) /* defining players name */
						{
						if ((i=lgetw())==0) break;
						if (strlen(i)>=LOGNAMESIZE) i[LOGNAMESIZE-1]=0;
						strcpy(logname,i); flag=0;
						}
					else if (strcmp(i,"no-introduction") == 0) nowelcome=1;
					else if (strcmp(i,"no-beep") == 0) nobeep=1;
					break;

		case 'p':	if (strcmp(i,"process-name:")== 0) 
						{
						if ((i=lgetw())==0) break;
						if (strlen(i)>=PSNAMESIZE) i[PSNAMESIZE-1]=0;
						strcpy(psname,i);
						}
					else if (strcmp(i,"play-day-play") == 0)  dayplay=1;
					break;

		case 's':	if (strcmp(i,"savefile:") == 0) /* defining savefilename */
						{
						if ((i=lgetw())==0) break;
						if (strlen(i)>=SAVEFILENAMESIZE) /* avoid overflow */
							i[SAVEFILENAMESIZE-1]=0;
						strcpy(savefilename,i); flag=0;
						}
					break;
		};
	  }
	if (flag)  strcpy(logname,loginname);
	}

SHAR_EOF
if test 5637 -ne "`wc -c < 'tok.c'`"
then
	echo shar: error transmitting "'tok.c'" '(should have been 5637 characters)'
fi
fi
echo shar: extracting "'MANIFEST'" '(1097 characters)'
if test -f 'MANIFEST'
then
	echo shar: will not over-write existing file "'MANIFEST'"
else
cat << \SHAR_EOF > 'MANIFEST'
File Name                 Kit Number
--------------            ----------
.holidays                    6
.larn.help.uue               6
.larnmaze                    6
.larnopts                    3
.lfortune                    4
Fixed.Bugs                   1
MANIFEST                     5
Make.lint                    1
Makefile                     1
README                       1
bill.c                       1
config.c                     1
create.c                     1
data.c                       2
diag.c                       1
display.c                    2
fortune.c                    1
global.c                     2
header.h                     3
help.c                       1
io.c                         3
main.c                       3
monster.c                    4
moreobj.c                    4
movem.c                      4
nap.c                        2
object.c                     5
regen.c                      5
savelev.c                    1
scores.c                     5
signal.c                     5
store.c                      6
tok.c                        5
SHAR_EOF
if test 1097 -ne "`wc -c < 'MANIFEST'`"
then
	echo shar: error transmitting "'MANIFEST'" '(should have been 1097 characters)'
fi
fi
exit 0
#	End of shell archive