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

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

Submitted-by: routley@tle.ENET.DEC.COM (Kevin Routley)
Posting-number: Volume 11, Issue 86
Archive-name: larn/Part03
Environment: Unix, VMS, MS-DOS, termcap



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 3 (of 11)."
# Contents:  scores.c store.c
# Wrapped by billr@saab on Tue Dec 18 10:14:17 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'scores.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'scores.c'\"
else
echo shar: Extracting \"'scores.c'\" \(22208 characters\)
sed "s/^X//" >'scores.c' <<'END_OF_FILE'
X/* scores.c			 Larn is copyrighted 1986 by Noah Morgan.
X *
X *	Functions in this file are:
X *
X *	readboard() 	Function to read in the scoreboard into a static buffer
X *	writeboard()	Function to write the scoreboard from readboard()'s buffer
X *	makeboard() 	Function to create a new scoreboard (wipe out old one)
X *	hashewon()	 Function to return 1 if player has won a game before, else 0
X *	long paytaxes(x)	 Function to pay taxes if any are due
X *	winshou()		Subroutine to print out the winning scoreboard
X *	shou(x)			Subroutine to print out the non-winners scoreboard
X *	showscores()		Function to show the scoreboard on the terminal
X *	showallscores()	Function to show scores and the iven lists that go with them
X *	sortboard()		Function to sort the scoreboard
X *	newscore(score, whoo, whyded, winner) 	Function to add entry to scoreboard
X *	new1sub(score,i,whoo,taxes) 		  Subroutine to put player into a 
X *	new2sub(score,i,whoo,whyded)	 	  Subroutine to put player into a 
X *	died(x) 	Subroutine to record who played larn, and what the score was
X *	diedsub(x) Subroutine to print out a line showing player when he is killed
X *	diedlog() 	Subroutine to read a log file and print it out in ascii format
X *	getplid(name)		Function to get players id # from id file
X *
X */
X#ifdef VMS
X# include <types.h>
X# include <stat.h>
X#else
X# include <sys/types.h>
X# ifndef MSDOS
X#  include <sys/times.h>
X# endif
X# include <sys/stat.h>
X#endif
X#include "header.h"
X
Xstruct scofmt			/*	This is the structure for the scoreboard 		*/
X	{
X	long score;			/* the score of the player 							*/
X	long suid;			/* the user id number of the player 				*/
X	short what;			/* the number of the monster that killed player 	*/
X	short level;		/* the level player was on when he died 			*/
X	short hardlev;		/* the level of difficulty player played at 		*/
X	short order;		/* the relative ordering place of this entry 		*/
X	char who[40];		/* the name of the character 						*/
X	char sciv[26][2];	/* this is the inventory list of the character 		*/
X	};
Xstruct wscofmt			/* This is the structure for the winning scoreboard */
X	{
X	long score;			/* the score of the player 							*/
X	long timeused;		/* the time used in mobuls to win the game 			*/
X	long taxes;			/* taxes he owes to LRS 							*/
X	long suid;			/* the user id number of the player 				*/
X	short hardlev;		/* the level of difficulty player played at 		*/
X	short order;		/* the relative ordering place of this entry 		*/
X# ifndef MAIL			/* dgk */
X	char hasmail;		/* 1 if mail is to be read, 0 otherwise */
X# endif
X	char who[40];		/* the name of the character 						*/
X	};
X
Xstruct log_fmt			/* 102 bytes struct for the log file 				*/
X	{
X	long score;			/* the players score 								*/
X	long diedtime;		/* time when game was over 							*/
X	short cavelev;		/* level in caves 									*/
X	short diff;			/* difficulty player played at 						*/
X#ifdef EXTRA
X	long elapsedtime;	/* real time of game in seconds 					*/
X	long bytout;		/* bytes input and output 							*/
X	long bytin;
X	long moves;			/* number of moves made by player 					*/
X	short ac;			/* armor class of player 							*/
X	short hp,hpmax;		/* players hitpoints 								*/
X	short cputime;		/* cpu time needed in seconds 						*/
X	short killed,spused;/* monsters killed and spells cast 					*/
X	short usage;		/* usage of the cpu in % 							*/
X	short lev;			/* player level 									*/
X#endif
X	char who[12];		/* player name 										*/
X	char what[46];		/* what happened to player 							*/
X	};
X
Xstatic struct scofmt sco[SCORESIZE];	/* the structure for the scoreboard  */
Xstatic struct wscofmt winr[SCORESIZE];	/* struct for the winning scoreboard */
Xstatic struct log_fmt logg;				/* structure for the log file 		 */
Xstatic char *whydead[] = {
X	"quit", "suspended", "self - annihilated", "shot by an arrow",
X	"hit by a dart", "fell into a pit", "fell into a bottomless pit",
X	"a winner", "trapped in solid rock", "killed by a missing save file",
X	"killed by an old save file", "caught by the greedy cheater checker trap",
X	"killed by a protected save file","killed his family and committed suicide",
X	"erased by a wayward finger", "fell through a bottomless trap door",
X	"fell through a trap door", "drank some poisonous water",
X	"fried by an electric shock", "slipped on a volcano shaft",
X	"killed by a stupid act of frustration", "attacked by a revolting demon",
X	"hit by his own magic", "demolished by an unseen attacker",
X	"fell into the dreadful sleep", "killed by an exploding chest",
X/*26*/	"killed by a missing maze data file", "annihilated in a sphere",
X	"died a post mortem death","wasted by a malloc() failure"
X	};
X
X
X/*
X *	readboard() 	Function to read in the scoreboard into a static buffer
X *
X *	returns -1 if unable to read in the scoreboard, returns 0 if all is OK
X */
Xreadboard()
X	{
X	if (lopen(scorefile)<0)
X	  { lprcat("Can't read scoreboard\n"); lflush(); return(-1); }
X	lrfill((char*)sco,sizeof(sco));		lrfill((char*)winr,sizeof(winr));
X	lrclose();  lcreat((char*)0);  return(0);
X	}
X
X/*
X *	writeboard()	Function to write the scoreboard from readboard()'s buffer
X *
X *	returns -1 if unable to write the scoreboard, returns 0 if all is OK
X */
Xwriteboard()
X	{
X	set_score_output();
X	if (lcreat(scorefile)<0)
X	  { lprcat("Can't write scoreboard\n"); lflush(); return(-1); }
X	lwrite((char*)sco,sizeof(sco));		lwrite((char*)winr,sizeof(winr));
X	lwclose();  lcreat((char*)0);  return(0);
X	}
X
X/*
X *	makeboard() 		Function to create a new scoreboard (wipe out old one)
X *
X *	returns -1 if unable to write the scoreboard, returns 0 if all is OK
X */
Xmakeboard()
X	{
X	register int i;
X	for (i=0; i<SCORESIZE; i++)
X		{
X		winr[i].taxes = winr[i].score = sco[i].score = 0;
X		winr[i].order = sco[i].order = i;
X		}
X	if (writeboard()) return(-1);
X	chmod(scorefile,0666);
X	return(0);
X	}
X
X/*
X *	hashewon()	 Function to return 1 if player has won a game before, else 0
X *
X *	This function also sets c[HARDGAME] to appropriate value -- 0 if not a
X *	winner, otherwise the next level of difficulty listed in the winners
X *	scoreboard.  This function also sets outstanding_taxes to the value in
X *	the winners scoreboard.
X */
Xhashewon()
X	{
X	register int i;
X	c[HARDGAME] = 0;
X	if (readboard() < 0) return(0);	/* can't find scoreboard */
X	for (i=0; i<SCORESIZE; i++)	/* search through winners scoreboard */
X	   if (winr[i].suid == userid)
X		  if (winr[i].score > 0)
X			{
X			c[HARDGAME]=winr[i].hardlev+1;  outstanding_taxes=winr[i].taxes;
X			return(1);
X			}
X	return(0);
X	}
X
X# ifndef MAIL			/* dgk */
Xcheckmail()
X{
X	register int	i;
X	long		gold, taxes;
X
X	if (readboard() < 0)
X		return;			/* can't find scoreboard */
X	for (i = 0; i < SCORESIZE; i++)	/* search through winners scoreboard */
X		if (winr[i].suid == userid
X		&&  winr[i].score > 0
X		&&  winr[i].hasmail) {
X			winr[i].hasmail = 0;
X			gold = taxes = winr[i].taxes;
X			writeboard();
X
X			/* Intuit the amount of gold -- should have changed
X			 * the score file, but ...  TAXRATE is an fraction.
X			 */
X			while ((gold * TAXRATE) < taxes)
X				gold += taxes;
X			readmail(gold);
X		}
X}
X# endif
X
X
X/*
X *	long paytaxes(x)		 Function to pay taxes if any are due
X *
X *	Enter with the amount (in gp) to pay on the taxes.
X *	Returns amount actually paid.
X */
Xlong paytaxes(x)
X	long x;
X	{
X	register int i;
X	register long amt;
X	if (x<0) return(0L);
X	if (readboard()<0) return(0L);
X	for (i=0; i<SCORESIZE; i++)
X		if (winr[i].suid == userid)	/* look for players winning entry */
X			if (winr[i].score>0) /* search for a winning entry for the player */
X				{
X				amt = winr[i].taxes;
X				if (x < amt) amt=x;		/* don't overpay taxes (Ughhhhh) */
X				winr[i].taxes -= amt;
X				outstanding_taxes -= amt;
X				if (writeboard()<0) return(0);
X				return(amt);
X				}
X	return(0L);	/* couldn't find user on winning scoreboard */
X	}
X
X/*
X *	winshou()		Subroutine to print out the winning scoreboard
X *
X *	Returns the number of players on scoreboard that were shown 
X */
Xwinshou()
X	{
X	register struct wscofmt *p;
X	register int i,j,count;
X	for (count=j=i=0; i<SCORESIZE; i++) /* is there anyone on the scoreboard? */
X		if (winr[i].score != 0)
X			{ j++; break; }
X	if (j)
X		{
X		lprcat("\n  Score    Difficulty   Time Needed   Larn Winners List\n");
X
X		for (i=0; i<SCORESIZE; i++)	/* this loop is needed to print out the */
X		  for (j=0; j<SCORESIZE; j++) /* winners in order */
X			{
X			p = &winr[j];	/* pointer to the scoreboard entry */
X			if (p->order == i)
X				{
X				if (p->score)
X					{
X					count++;
X					lprintf("%10d     %2d      %5d Mobuls   %s \n",
X					(long)p->score,(long)p->hardlev,(long)p->timeused,p->who);
X					}
X				break;
X				}
X			}
X		}
X	return(count);	/* return number of people on scoreboard */
X	}
X
X/*
X *	shou(x)			Subroutine to print out the non-winners scoreboard
X *		int x;
X *
X *	Enter with 0 to list the scores, enter with 1 to list inventories too
X *	Returns the number of players on scoreboard that were shown 
X */
Xshou(x)
X	int x;
X	{
X	register int i,j,n,k;
X	int count;
X	for (count=j=i=0; i<SCORESIZE; i++)	/* is the scoreboard empty? */
X		if (sco[i].score!= 0)
X			{ j++; break; }
X	if (j)
X		{
X		lprcat("\n   Score   Difficulty   Larn Visitor Log\n");
X		for (i=0; i<SCORESIZE; i++) /* be sure to print them out in order */
X		  for (j=0; j<SCORESIZE; j++)
X			if (sco[j].order == i)
X				{
X				if (sco[j].score)
X					{
X					count++;
X					lprintf("%10d     %2d       %s ",
X						(long)sco[j].score,(long)sco[j].hardlev,sco[j].who);
X					if (sco[j].what < 256) lprintf("killed by a %s",monster[sco[j].what].name);
X						else lprintf("%s",whydead[sco[j].what - 256]);
X					if (x != 263) lprintf(" on %s",levelname[sco[j].level]);
X					if (x)
X						{
X						for (n=0; n<26; n++) { iven[n]=sco[j].sciv[n][0]; ivenarg[n]=sco[j].sciv[n][1]; }
X						for (k=1; k<99; k++)
X						  for (n=0; n<26; n++)
X							if (k==iven[n])  { srcount=0; show3(n); }
X						lprcat("\n\n");
X						}
X					else lprc('\n');
X					}
X				j=SCORESIZE;
X				}
X		}
X	return(count);	/* return the number of players just shown */
X	}
X
X/*
X *	showscores()		Function to show the scoreboard on the terminal
X *
X *	Returns nothing of value
X */
Xstatic char esb[] = "The scoreboard is empty.\n";
Xshowscores()
X	{
X	register int i,j;
X	lflush();  lcreat((char*)0);  if (readboard()<0) return;
X	i=winshou();	j=shou(0);	
X	if (i+j == 0) lprcat(esb); else lprc('\n');
X	lflush();
X	}
X
X/*
X *	showallscores()	Function to show scores and the iven lists that go with them
X *
X *	Returns nothing of value
X */
Xshowallscores()
X	{
X	register int i,j;
X	lflush();  lcreat((char*)0);  if (readboard()<0) return;
X	c[WEAR] = c[WIELD] = c[SHIELD] = -1;  /* not wielding or wearing anything */
X	for (i=0; i<MAXPOTION; i++) potionname[i][0]=' ';
X	for (i=0; i<MAXSCROLL; i++) scrollname[i][0]=' ';
X	i=winshou();  j=shou(1);
X	if (i+j==0) lprcat(esb); else lprc('\n');
X	lflush();
X	}
X
X/*
X *	sortboard()		Function to sort the scoreboard
X *
X *	Returns 0 if no sorting done, else returns 1
X */
Xsortboard()
X	{
X	register int i,j,pos;
X	long jdat;
X	for (i=0; i<SCORESIZE; i++) sco[i].order = winr[i].order = -1;
X	pos=0;  while (pos < SCORESIZE)
X		{
X		jdat=0;
X		for (i=0; i<SCORESIZE; i++)
X			if ((sco[i].order < 0) && (sco[i].score >= jdat))
X				{ j=i;  jdat=sco[i].score; }
X		sco[j].order = pos++;
X		}
X	pos=0;  while (pos < SCORESIZE)
X		{
X		jdat=0;
X		for (i=0; i<SCORESIZE; i++)
X			if ((winr[i].order < 0) && (winr[i].score >= jdat))
X				{ j=i;  jdat=winr[i].score; }
X		winr[j].order = pos++;
X		}
X	return(1);
X	}
X
X/*
X *	newscore(score, whoo, whyded, winner) 	Function to add entry to scoreboard
X *		int score, winner, whyded;
X *		char *whoo;
X *
X *	Enter with the total score in gp in score,  players name in whoo,
X *		died() reason # in whyded, and TRUE/FALSE in winner if a winner
X *	ex.		newscore(1000, "player 1", 32, 0);
X */
Xnewscore(score, whoo, whyded, winner)
X	long score;
X	int winner, whyded;
X	char *whoo;
X	{
X	register int i;
X	long taxes;
X	if (readboard() < 0) return; 	/*	do the scoreboard	*/
X	/* if a winner then delete all non-winning scores */
X	if (cheat) winner=0;	/* if he cheated, don't let him win */
X	if (winner)
X		{
X		for (i=0; i<SCORESIZE; i++) if (sco[i].suid == userid) sco[i].score=0;
X		taxes = score*TAXRATE;
X		score += 100000*c[HARDGAME];	/* bonus for winning */
X	/* if he has a slot on the winning scoreboard update it if greater score */
X		for (i=0; i<SCORESIZE; i++) if (winr[i].suid == userid)
X				{ new1sub(score,i,whoo,taxes); return; }
X	/* he had no entry. look for last entry and see if he has a greater score */
X		for (i=0; i<SCORESIZE; i++) if (winr[i].order == SCORESIZE-1)
X				{ new1sub(score,i,whoo,taxes); return; }
X		}
X	else if (!cheat) /* for not winning scoreboard */
X		{
X	/* if he has a slot on the scoreboard update it if greater score */
X		for (i=0; i<SCORESIZE; i++) if (sco[i].suid == userid)
X				{ new2sub(score,i,whoo,whyded); return; }
X	/* he had no entry. look for last entry and see if he has a greater score */
X		for (i=0; i<SCORESIZE; i++) if (sco[i].order == SCORESIZE-1)
X				{ new2sub(score,i,whoo,whyded); return; }
X		}
X	}
X
X/*
X *	new1sub(score,i,whoo,taxes) 	  Subroutine to put player into a 
X *		int score,i,whyded,taxes;		  winning scoreboard entry if his score
X *		char *whoo; 					  is high enough
X *
X *	Enter with the total score in gp in score,  players name in whoo,
X *		died() reason # in whyded, and TRUE/FALSE in winner if a winner
X *		slot in scoreboard in i, and the tax bill in taxes.
X *	Returns nothing of value
X */
Xnew1sub(score,i,whoo,taxes)
X	long score,taxes;
X	int i;
X	char *whoo;
X	{
X	register struct wscofmt *p;
X	p = &winr[i];
X	p->taxes += taxes;
X	if ((score >= p->score) || (c[HARDGAME] > p->hardlev))
X		{
X		strcpy(p->who,whoo);  		p->score=score;
X		p->hardlev=c[HARDGAME];		p->suid=userid;
X		p->timeused=gtime/100;
X# ifndef MAIL			/* dgk */
X		p->hasmail = 1;
X# endif
X		}
X	}
X
X/*
X *	new2sub(score,i,whoo,whyded)	 	  Subroutine to put player into a 
X *		int score,i,whyded,taxes;		  non-winning scoreboard entry if his
X *		char *whoo; 					  score is high enough
X *
X *	Enter with the total score in gp in score,  players name in whoo,
X *		died() reason # in whyded, and slot in scoreboard in i.
X *	Returns nothing of value
X */
Xnew2sub(score,i,whoo,whyded)
X	long score;
X	int i,whyded;
X	char *whoo;
X	{
X	register int j;
X	register struct scofmt *p;
X	p = &sco[i];
X	if ((score >= p->score) || (c[HARDGAME] > p->hardlev))
X		{
X		strcpy(p->who,whoo);  p->score=score;
X		p->what=whyded;       p->hardlev=c[HARDGAME];
X		p->suid=userid;		  p->level=level;
X		for (j=0; j<26; j++)
X			{ p->sciv[j][0]=iven[j]; p->sciv[j][1]=ivenarg[j]; }
X		}
X	}
X
X/*
X *	died(x) 	Subroutine to record who played larn, and what the score was
X *		int x;
X *
X *	if x < 0 then don't show scores
X *	died() never returns! (unless c[LIFEPROT] and a reincarnatable death!)
X *
X *		< 256	killed by the monster number
X *		256		quit
X *		257		suspended
X *		258		self - annihilated
X *		259		shot by an arrow
X *		260		hit by a dart
X *		261		fell into a pit
X *		262		fell into a bottomless pit
X *		263		a winner
X *		264		trapped in solid rock
X *		265		killed by a missing save file
X *		266		killed by an old save file
X *		267		caught by the greedy cheater checker trap
X *		268		killed by a protected save file
X *		269		killed his family and killed himself
X *		270		erased by a wayward finger
X *		271		fell through a bottomless trap door
X *		272		fell through a trap door
X *		273		drank some poisonous water
X *		274		fried by an electric shock
X *		275		slipped on a volcano shaft
X *		276		killed by a stupid act of frustration
X *		277		attacked by a revolting demon
X *		278		hit by his own magic
X *		279		demolished by an unseen attacker
X *		280		fell into the dreadful sleep
X *		281		killed by an exploding chest
X *		282		killed by a missing maze data file
X *		283		killed by a sphere of annihilation
X *		284		died a post mortem death
X *		285		malloc() failure
X *		300		quick quit -- don't put on scoreboard
X */
X
Xstatic int scorerror;
Xdied(x)
X	int x;
X	{
X	register int f,win;
X	char ch,*mod;
X	long zzz,i;
X# ifdef EXTRA
X	struct tms cputime;
X# endif
X	if (c[LIFEPROT]>0) /* if life protection */
X		{
X		switch((x>0) ? x : -x)
X			{
X			case 256: case 257: case 262: case 263: case 265: case 266:
X			case 267: case 268: case 269: case 271: case 282: case 284:
X			case 285: case 300:  goto invalid; /* can't be saved */
X			};
X		--c[LIFEPROT]; c[HP]=1; --c[CONSTITUTION];
X		cursors(); lprcat("\nYou feel wiiieeeeerrrrrd all over! "); beep();
X		lflush();  sleep(4);
X		return; /* only case where died() returns */
X		}
Xinvalid:
X	clearvt100();  lflush();  f=0;
X	if (ckpflag) unlink(ckpfile);	/* remove checkpoint file if used */
X# ifdef MSDOS
X	if (swapfd) {
X		close(swapfd);
X		(void) unlink(swapfile);/* Remove swapfile */
X	}
X	unsetraw();
X# endif
X	if (x<0) { f++; x = -x; }	/* if we are not to display the scores */
X	if ((x == 300) || (x == 257))  exit();	/* for quick exit or saved game */
X	if (x == 263)  win = 1;  else  win = 0;
X	c[GOLD] += c[BANKACCOUNT];   c[BANKACCOUNT] = 0;
X		/*	now enter the player at the end of the scoreboard */
X	newscore(c[GOLD], logname, x, win);
X	diedsub(x);	/* print out the score line */  lflush();
X
X	set_score_output();
X	if ((wizard == 0) && (c[GOLD] > 0)) 	/*	wizards can't score		*/
X		{
X		if (lappend(logfile)<0)  /* append to file */
X			{
X			if (lcreat(logfile)<0) /* and can't create new log file */
X		    	{
X				lcreat((char*)0);
X				lprcat("\nCan't open record file:  I can't post your score.\n");
X				sncbr();  resetscroll();  lflush();  exit();
X				}
X			chmod(logfile,0666);
X			}
X		strcpy(logg.who,loginname);
X		logg.score = c[GOLD];		logg.diff = c[HARDGAME];
X		if (x < 256)
X			{
X			ch = *monster[x].name;
X			if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u')
X				mod="an";  else mod="a";
X			sprintf(logg.what,"killed by %s %s",mod,monster[x].name);
X			}
X		else sprintf(logg.what,"%s",whydead[x - 256]);
X		logg.cavelev=level;
X		time(&zzz);	  /* get cpu time -- write out score info */
X		logg.diedtime=zzz;
X#ifdef EXTRA
X		times(&cputime);  /* get cpu time -- write out score info */
X		logg.cputime = i = (cputime.tms_utime + cputime.tms_stime)/60 + c[CPUTIME];
X		logg.lev=c[LEVEL];			logg.ac=c[AC];
X		logg.hpmax=c[HPMAX];		logg.hp=c[HP];
X		logg.elapsedtime=(zzz-initialtime+59)/60;
X		logg.usage=(10000*i)/(zzz-initialtime);
X		logg.bytin=c[BYTESIN];		logg.bytout=c[BYTESOUT];
X		logg.moves=c[MOVESMADE];	logg.spused=c[SPELLSCAST];
X		logg.killed=c[MONSTKILLED];
X#endif
X		lwrite((char*)&logg,sizeof(struct log_fmt));	 lwclose();
X
X/*	now for the scoreboard maintenance -- not for a suspended game 	*/
X		if (x != 257)
X			{
X			if (sortboard())  scorerror = writeboard();
X			}
X		}
X	if ((x==256) || (x==257) || (f != 0)) exit();
X	if (scorerror == 0) showscores();	/* if we updated the scoreboard */
X# ifdef MAIL
X	if (x == 263) mailbill();
X# endif
X	exit();
X	}
X
X/*
X *	diedsub(x) Subroutine to print out the line showing the player when he is killed
X *		int x;
X */
Xdiedsub(x)
Xint x;
X	{
X	register char ch,*mod;
X	lprintf("Score: %d, Diff: %d,  %s ",(long)c[GOLD],(long)c[HARDGAME],logname);
X	if (x < 256)
X		{
X		ch = *monster[x].name;
X		if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u')
X			mod="an";  else mod="a";
X		lprintf("killed by %s %s",mod,monster[x].name);
X		}
X	else lprintf("%s",whydead[x - 256]);
X	if (x != 263) lprintf(" on %s\n",levelname[level]);  else lprc('\n');
X	}
X
X/*
X *	diedlog() 	Subroutine to read a log file and print it out in ascii format
X */
Xdiedlog()
X	{
X	register int n;
X	register char *p;
X	struct stat stbuf;
X	lcreat((char*)0);
X	if (lopen(logfile)<0)
X		{
X		lprintf("Can't locate log file <%s>\n",logfile);
X		return;
X		}
X	if (fstat(fd,&stbuf) < 0)
X		{
X		lprintf("Can't  stat log file <%s>\n",logfile);
X		return;
X		}
X	for (n=stbuf.st_size/sizeof(struct log_fmt); n>0; --n)
X		{
X		lrfill((char*)&logg,sizeof(struct log_fmt));
X		p = ctime(&logg.diedtime); p[16]='\n'; p[17]=0;
X		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);
X#ifdef EXTRA
X		if (logg.moves<=0) logg.moves=1;
X		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));
X		lprintf("  CPU time used: %d seconds,  Machine usage: %d.%02d%%\n",(long)(logg.cputime),(long)(logg.usage/100),(long)(logg.usage%100));
X		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));
X		lprintf("  out bytes per move: %d,  time per move: %d ms\n",(long)(logg.bytout/logg.moves),(long)((logg.cputime*1000)/logg.moves));
X#endif
X		}
X		lflush();  lrclose();  return;
X	}
X
X#ifndef UIDSCORE
X/*
X *	getplid(name)		Function to get players id # from id file
X *
X *	Enter with the name of the players character in name.
X *	Returns the id # of the players character, or -1 if failure.
X *	This routine will try to find the name in the id file, if its not there,
X *	it will try to make a new entry in the file.  Only returns -1 if can't
X *	find him in the file, and can't make a new entry in the file.
X *	Format of playerids file:
X *			Id # in ascii     \n     character name     \n   
X */
Xstatic int havepid= -1;	/* playerid # if previously done */
Xgetplid(nam)
X	char *nam;
X	{
X	int fd7,high=999,no;
X	register char *p,*p2;
X	char name[80];
X	if (havepid != -1) return(havepid);	/* already did it */
X	lflush();	/* flush any pending I/O */
X	sprintf(name,"%s\n",nam);	/* append a \n to name */
X	if (lopen(playerids) < 0)	/* no file, make it */
X		{
X		if ((fd7=creat(playerids,0666)) < 0)  return(-1); /* can't make it */
X		close(fd7);  goto addone;	/* now append new playerid record to file */
X		}
X	for (;;)	/* now search for the name in the player id file */
X		{
X		p = lgetl();  if (p==NULL) break;	/* EOF? */
X		no = atoi(p);	/* the id # */
X		p2= lgetl();  if (p2==NULL) break;	/* EOF? */
X		if (no>high) high=no;	/* accumulate highest id # */
X		if (strcmp(p2,name)==0)	/* we found him */
X			{
X			return(no);	/* his id number */
X			}
X		}
X	lrclose();
X	/* if we get here, we didn't find him in the file -- put him there */
Xaddone:
X	if (lappend(playerids) < 0) return(-1);	/* can't open file for append */
X	lprintf("%d\n%s",(long)++high,name);  /* new id # and name */
X	lwclose();
X	lcreat((char*)0);	/* re-open terminal channel */
X	return(high);
X	}
X#endif UIDSCORE
X
END_OF_FILE
if test 22208 -ne `wc -c <'scores.c'`; then
    echo shar: \"'scores.c'\" unpacked with wrong size!
fi
# end of 'scores.c'
fi
if test -f 'store.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'store.c'\"
else
echo shar: Extracting \"'store.c'\" \(28738 characters\)
sed "s/^X//" >'store.c' <<'END_OF_FILE'
X/*  store.c     Larn is copyrighted 1986 by Noah Morgan. */
X/*
XThis module contains data and routines to handle buildings at the home level.
XRoutines:
X
X  dnd_2hed
X  dnd_hed
X  dndstore      The DND store main routine
X  handsfull     To tell the player he can carry no more
X  out_of_stock  To tell the player an item is out of stock
X  no_gold       To tell the player he has no gold
X  dnditem       Display DND store items
X  sch_head      print the school header
X  oschool       main school routine
X  obank         Larn National Bank
X  obank2        5th level branch of the bank
X  banktitle     bank header
X  ointerest     accrue interest to bank account
X  obanksub      bank main subroutine
X  otradhead     trading post header
X  otradepost    trading post main function
X  cnsitm
X  olrs          larn revenue service function
X
X*/
X
X#include "header.h"
Xstatic int dndcount=0,dnditm=0;
X
X/* number of items in the dnd inventory table   */
X#define MAXITM 83
X
X/*  this is the data for the stuff in the dnd store */
Xstruct _itm itm[90] = {
X/*cost    memory    iven name   iven arg   how
X  gp     pointer      iven[]    ivenarg[]  many */
X
X{ 2,        0,      OLEATHER,       0,      3   },
X{ 10,       0,      OSTUDLEATHER,   0,      2   },
X{ 40,       0,      ORING,          0,      2   },
X{ 85,       0,      OCHAIN,         0,      2   },
X{ 220,      0,      OSPLINT,        0,      1   },
X{ 400,      0,      OPLATE,         0,      1   },
X{ 900,      0,      OPLATEARMOR,    0,      1   },
X{ 2600,     0,      OSSPLATE,       0,      1   },
X{ 150,      0,      OSHIELD,        0,      1   },
X
X/*cost    memory    iven name   iven arg   how
X  gp     pointer      iven[]    ivenarg[]  many */
X
X{ 2,        0,      ODAGGER,        0,      3   },
X{ 20,       0,      OSPEAR,         0,      3   },
X{ 80,       0,      OFLAIL,         0,      2   },
X{ 150,      0,      OBATTLEAXE,     0,      2   },
X{ 450,      0,      OLONGSWORD,     0,      2   },
X{ 1000,     0,      O2SWORD,        0,      2   },
X{ 5000,     0,      OSWORD,         0,      1   },
X{ 16500,    0,      OLANCE,         0,      1   },
X{ 6000,     0,   OSWORDofSLASHING,  0,      0   },
X{ 10000,    0,      OHAMMER,        0,      0   },
X
X/*cost    memory    iven name   iven arg   how
X  gp     pointer      iven[]    ivenarg[]  many */
X
X{ 150,      0,      OPROTRING,      1,      1   },
X{ 85,       0,      OSTRRING,       1,      1   },
X{ 120,      0,      ODEXRING,       1,      1   },
X{ 120,      0,      OCLEVERRING,    1,      1   },
X{ 180,      0,      OENERGYRING,    0,      1   },
X{ 125,      0,      ODAMRING,       0,      1   },
X{ 220,      0,      OREGENRING,     0,      1   },
X{ 1000,     0,      ORINGOFEXTRA,   0,      1   },
X
X{ 280,      0,      OBELT,          0,      1   },
X
X{ 400,      0,      OAMULET,        0,      1   },
X
X{ 6500,     0,      OORBOFDRAGON,   0,      0   },
X{ 5500,     0,      OSPIRITSCARAB,  0,      0   },
X{ 5000,     0,      OCUBEofUNDEAD,  0,      0   },
X{ 6000,     0,      ONOTHEFT,       0,      0   },
X
X{ 590,      0,      OCHEST,         6,      1   },
X{ 200,      0,      OBOOK,          8,      1   },
X{ 10,       0,      OCOOKIE,        0,      3   },
X
X/*cost    memory    iven name   iven arg   how
X  gp     pointer      iven[]    ivenarg[]  many */
X
X{   20,     potionname, OPOTION,    0,      6   },
X{   90,     potionname, OPOTION,    1,      5   },
X{   520,    potionname, OPOTION,    2,      1   },
X{   100,    potionname, OPOTION,    3,      2   },
X{   50,     potionname, OPOTION,    4,      2   },
X{   150,    potionname, OPOTION,    5,      2   },
X{   70,     potionname, OPOTION,    6,      1   },
X{   30,     potionname, OPOTION,    7,      7   },
X{   200,    potionname, OPOTION,    8,      1   },
X{   50,     potionname, OPOTION,    9,      1   },
X{   80,     potionname, OPOTION,    10,     1   },
X
X/*cost    memory    iven name   iven arg   how
X  gp     pointer      iven[]    ivenarg[]  many */
X
X{   30,     potionname, OPOTION,    11,     3   },
X{   20,     potionname, OPOTION,    12,     5   },
X{   40,     potionname, OPOTION,    13,     3   },
X{   35,     potionname, OPOTION,    14,     2   },
X{   520,    potionname, OPOTION,    15,     1   },
X{   90,     potionname, OPOTION,    16,     2   },
X{   200,    potionname, OPOTION,    17,     2   },
X{   220,    potionname, OPOTION,    18,     4   },
X{   80,     potionname, OPOTION,    19,     6   },
X{   370,    potionname, OPOTION,    20,     3   },
X{   50,     potionname, OPOTION,    22,     1   },
X{   150,    potionname, OPOTION,    23,     3   },
X
X/*cost    memory    iven name   iven arg   how
X  gp     pointer      iven[]    ivenarg[]  many */
X
X{ 100,  scrollname,     OSCROLL,    0,      2   },
X{ 125,  scrollname,     OSCROLL,    1,      2   },
X{ 60,   scrollname,     OSCROLL,    2,      4   },
X{ 10,   scrollname,     OSCROLL,    3,      4   },
X{ 100,  scrollname,     OSCROLL,    4,      3   },
X{ 200,  scrollname,     OSCROLL,    5,      2   },
X{ 110,  scrollname,     OSCROLL,    6,      1   },
X{ 500,  scrollname,     OSCROLL,    7,      2   },
X{ 200,  scrollname,     OSCROLL,    8,      2   },
X{ 250,  scrollname,     OSCROLL,    9,      4   },
X{ 20,   scrollname,     OSCROLL,    10,     5   },
X{ 30,   scrollname,     OSCROLL,    11,     3   },
X
X/*cost    memory    iven name   iven arg   how
X  gp     pointer      iven[]    ivenarg[]  many */
X
X{ 340,  scrollname,     OSCROLL,    12,     1   },
X{ 340,  scrollname,     OSCROLL,    13,     1   },
X{ 300,  scrollname,     OSCROLL,    14,     2   },
X{ 400,  scrollname,     OSCROLL,    15,     2   },
X{ 500,  scrollname,     OSCROLL,    16,     2   },
X{ 1000, scrollname,     OSCROLL,    17,     1   },
X{ 500,  scrollname,     OSCROLL,    18,     1   },
X{ 340,  scrollname,     OSCROLL,    19,     2   },
X{ 220,  scrollname,     OSCROLL,    20,     3   },
X{ 3900, scrollname,     OSCROLL,    21,     0   },
X{ 610,  scrollname,     OSCROLL,    22,     1   },
X{ 3000, scrollname,     OSCROLL,    23,     0   }
X };
X
X/*
X    for the college of larn
X */
Xchar course[26];    /*  the list of courses taken   */
Xchar coursetime[] = { 10, 15, 10, 20, 10, 10, 10, 5 };
X
X/*
X    function for the dnd store
X */
Xdnd_2hed()
X    {
X    lprcat("Welcome to the Larn Thrift Shoppe.  We stock many items explorers find useful\n");
X    lprcat(" in their adventures.  Feel free to browse to your hearts content.\n");
X    lprcat("Also be advised, if you break 'em, you pay for 'em.");
X    }
X
Xdnd_hed()
X    {
X    register int i;
X    for (i=dnditm; i<26+dnditm; i++)    dnditem(i);
X    cursor(50,18); lprcat("You have ");
X    }
X
Xdndstore()
X  {
X  register int i;
X  dnditm = 0;
X  nosignal = 1; /* disable signals */
X  clear();  dnd_2hed();
X  if (outstanding_taxes>0)
X    {
X    lprcat("\n\nThe Larn Revenue Service has ordered us to not do business with tax evaders.\n"); beep();
X    lprintf("They have also told us that you owe %d gp in back taxes, and as we must\n",(long)outstanding_taxes);
X    lprcat("comply with the law, we cannot serve you at this time.  Soo Sorry.\n");
X    cursors();  
X    lprcat("\nPress "); standout("escape"); lprcat(" to leave: "); lflush();
X    i=0;
X    while (i!='\33') i=ttgetch();
X    drawscreen();  nosignal = 0; /* enable signals */ return;
X    }
X
X  dnd_hed();
X  while (1)
X    {
X    cursor(59,18); lprintf("%d gold pieces",(long)c[GOLD]);
X    cltoeoln(); cl_dn(1,20);    /* erase to eod */
X    lprcat("\nEnter your transaction ["); standout("space");
X    lprcat(" for more, "); standout("escape");
X    lprcat(" to leave]? ");
X    i=0;
X    while ((i<'a' || i>'z') && (i!=' ') && (i!='\33') && (i!=12))  i=ttgetch();
X    if (i==12) { clear();  dnd_2hed();  dnd_hed(); }
X    else if (i=='\33')
X        { drawscreen();  nosignal = 0; /* enable signals */ return; }
X    else if (i==' ')
X        {
X        cl_dn(1,4);
X    if ((dnditm += 26) >= MAXITM)
X            dnditm=0;
X        dnd_hed();
X        }
X    else
X        {  /* buy something */
X        lprc(i);    /* echo the byte */
X        i += dnditm - 'a';
X    if (i>=MAXITM) outofstock(); else
X        if (itm[i].qty <= 0) outofstock(); else
X        if (pocketfull()) handsfull(); else
X        if (c[GOLD] < (long) itm[i].price * 10) nogold(); else
X            {
X            if (itm[i].mem != 0) *itm[i].mem[itm[i].arg] = ' ';
X            c[GOLD] -= (long) itm[i].price * 10;
X            itm[i].qty--;  take(itm[i].obj,itm[i].arg);
X            if (itm[i].qty==0) dnditem(i);  nap(1001);
X            }
X        }
X
X    }
X  }
X
X/*
X    function for the players hands are full
X */
Xstatic handsfull()
X    { lprcat("\nYou can't carry anything more!"); lflush(); nap(2200); }
Xstatic outofstock()
X    { lprcat("\nSorry, but we are out of that item."); lflush(); nap(2200); }
Xstatic nogold()
X    { lprcat("\nYou don't have enough gold to pay for that!"); lflush(); nap(2200); }
X
X/*
X    dnditem(index)
X
X    to print the item list;  used in dndstore() enter with the index into itm
X */
Xstatic dnditem(i)
X    register int i;
X    {
X    register int j,k;
X    if (i >= MAXITM)  return;
X    cursor( (j=(i&1)*40+1) , (k=((i%26)>>1)+5) );
X    if (itm[i].qty == 0)  { lprintf("%39s","");  return; }
X    lprintf("%c) ",(i%26)+'a');
X    if (itm[i].obj == OPOTION)
X        { lprcat("potion of "); lprintf("%s",&potionname[itm[i].arg][1]); }
X    else if (itm[i].obj == OSCROLL)
X        { lprcat("scroll of "); lprintf("%s",&scrollname[itm[i].arg][1]); }
X    else lprintf("%s",objectname[itm[i].obj]);
X    cursor( j+31,k );  lprintf("%6d", (long) itm[i].price * 10);
X    }
X
X
X/*
X    function to display the header info for the school
X */
Xsch_hed()
X    {
X    clear();
X    lprcat("The College of Larn offers the exciting opportunity of higher education to\n");
X    lprcat("all inhabitants of the caves.  Here is a list of the class schedule:\n\n\n");
X    lprcat("\t\t    Course Name \t       Time Needed\n\n");
X
X    if (course[0]==0) lprcat("\t\ta)  Fighters Training I         10 mobuls"); /*line 7 of crt*/
X    lprc('\n');
X    if (course[1]==0) lprcat("\t\tb)  Fighters Training II        15 mobuls");
X    lprc('\n');
X    if (course[2]==0) lprcat("\t\tc)  Introduction to Wizardry    10 mobuls");
X    lprc('\n');
X    if (course[3]==0) lprcat("\t\td)  Applied Wizardry            20 mobuls");
X    lprc('\n');
X    if (course[4]==0) lprcat("\t\te)  Behavioral Psychology       10 mobuls");
X    lprc('\n');
X    if (course[5]==0) lprcat("\t\tf)  Faith for Today             10 mobuls");
X    lprc('\n');
X    if (course[6]==0) lprcat("\t\tg)  Contemporary Dance          10 mobuls");
X    lprc('\n');
X    if (course[7]==0) lprcat("\t\th)  History of Larn              5 mobuls");
X
X    lprcat("\n\n\t\tAll courses cost 250 gold pieces.");
X    cursor(30,18);
X    lprcat("You are presently carrying ");
X    }
X
Xoschool()
X    {
X    register int i;
X    long time_used;
X    nosignal = 1; /* disable signals */
X    sch_hed();
X    while (1)
X        {
X        cursor(57,18); lprintf("%d gold pieces.   ",(long)c[GOLD]); cursors();
X        lprcat("\nWhat is your choice ["); standout("escape");
X        lprcat(" to leave] ? ");  yrepcount=0;
X        i=0;  while ((i<'a' || i>'h') && (i!='\33') && (i!=12)) i=ttgetch();
X        if (i==12) { sch_hed();  continue; }
X        else if (i=='\33')
X            { nosignal = 0; drawscreen();  /* enable signals */ return; }
X        lprc(i);
X        if (c[GOLD] < 250)  nogold();  else
X        if (course[i-'a'])
X            { lprcat("\nSorry, but that class is filled."); nap(1000); }
X        else
X        if (i <= 'h')
X            {
X            c[GOLD] -= 250; time_used=0;
X            switch(i)
X                {
X                case 'a':   c[STRENGTH] += 2;  c[CONSTITUTION]++;
X                            lprcat("\nYou feel stronger!");
X                            cl_line(16,7);
X                            break;
X
X                case 'b':   if (course[0]==0)
X                                {
X                                lprcat("\nSorry, but this class has a prerequisite of Fighters Training I");
X                                c[GOLD]+=250;  time_used= -10000;  break;
X                                }
X                            lprcat("\nYou feel much stronger!");
X                            cl_line(16,8);
X                            c[STRENGTH] += 2;  c[CONSTITUTION] += 2;  break;
X
X                case 'c':   c[INTELLIGENCE] += 2; 
X                            lprcat("\nThe task before you now seems more attainable!");
X                            cl_line(16,9);  break;
X
X                case 'd':   if (course[2]==0)
X                                {
X                                lprcat("\nSorry, but this class has a prerequisite of Introduction to Wizardry");
X                                c[GOLD]+=250;  time_used= -10000;  break;
X                                }
X                            lprcat("\nThe task before you now seems very attainable!");
X                            cl_line(16,10);
X                            c[INTELLIGENCE] += 2;  break;
X
X                case 'e':   c[CHARISMA] += 3;  
X                            lprcat("\nYou now feel like a born leader!");
X                            cl_line(16,11);  break;
X
X                case 'f':   c[WISDOM] += 2;  
X                            lprcat("\nYou now feel more confident that you can find the potion in time!");
X                            cl_line(16,12);  break;
X
X                case 'g':   c[DEXTERITY] += 3;  
X                            lprcat("\nYou feel like dancing!");
X                            cl_line(16,13);  break;
X
X                case 'h':   c[INTELLIGENCE]++;
X                            lprcat("\nYour instructor told you that the Eye of Larn is rumored to be guarded\n");
X                            lprcat("by a platinum dragon who possesses psionic abilities. ");
X                            cl_line(16,14);  break;
X                }
X            time_used += coursetime[i-'a']*100;
X            if (time_used > 0)
X              {
X              gtime += time_used;
X              course[i-'a']++;  /*  remember that he has taken that course  */
X              c[HP] = c[HPMAX];  c[SPELLS] = c[SPELLMAX]; /* he regenerated */ 
X
X              if (c[BLINDCOUNT])    c[BLINDCOUNT]=1;  /* cure blindness too!  */
X              if (c[CONFUSE])       c[CONFUSE]=1;   /*  end confusion   */
X              adjtime((long)time_used); /* adjust parameters for time change */
X              }
X            nap(1000);
X            }
X        }
X    }
X
X/*
X *  for the first national bank of Larn
X */
Xint lasttime=0; /* last time he was in bank */
Xobank()
X    {
X    banktitle("    Welcome to the First National Bank of Larn.");
X    }
Xobank2()
X    {
X    banktitle("Welcome to the 5th level branch office of the First National Bank of Larn.");
X    }
Xstatic banktitle(str)
X    char *str;
X    {
X    nosignal = 1; /* disable signals */
X    clear();  lprcat(str);
X    if (outstanding_taxes>0)
X        {
X        register int i;
X        lprcat("\n\nThe Larn Revenue Service has ordered that your account be frozen until all\n"); beep();
X        lprintf("levied taxes have been paid.  They have also told us that you owe %d gp in\n",(long)outstanding_taxes);
X        lprcat("taxes, and we must comply with them. We cannot serve you at this time.  Sorry.\n");
X        lprcat("We suggest you go to the LRS office and pay your taxes.\n");
X        cursors();  
X        lprcat("\nPress "); standout("escape"); lprcat(" to leave: "); lflush();
X        i=0;
X        while (i!='\33') i=ttgetch();
X        drawscreen();  nosignal = 0; /* enable signals */ return;
X        }
X    lprcat("\n\n\tGemstone\t      Appraisal\t\tGemstone\t      Appraisal");
X    obanksub();     nosignal = 0; /* enable signals */
X    drawscreen();
X    }
X
X/*
X *  function to put interest on your bank account
X */
Xointerest()
X    {
X    register int i;
X    if (c[BANKACCOUNT]<0) c[BANKACCOUNT] = 0;
X    else if ((c[BANKACCOUNT]>0) && (c[BANKACCOUNT]<500000))
X        {
X        i = (gtime-lasttime)/100; /* # mobuls elapsed */
X        while ((i-- > 0) && (c[BANKACCOUNT]<500000))
X            c[BANKACCOUNT] += c[BANKACCOUNT]/250;
X        if (c[BANKACCOUNT]>500000) c[BANKACCOUNT]=500000; /* interest limit */
X        }
X    lasttime = (gtime/100)*100;
X    }
X
Xobanksub()
X    {
X    short gemorder[26];  /* the reference to screen location for each gem */
X    long gemvalue[26];   /* the appraisal of the gems */
X    unsigned long amt;
X    register int i,k,gems_sold=0;
X
X    ointerest();    /* credit any needed interest */
X
X    for (k=i=0; i<26; i++)
X        switch(iven[i])
X            {
X            case OLARNEYE: case ODIAMOND: case OEMERALD:
X            case ORUBY: case OSAPPHIRE:
X
X                    if (iven[i]==OLARNEYE)
X                        {
X                        gemvalue[i]=250000-((gtime*7)/100)*100;
X                        if (gemvalue[i]<50000) gemvalue[i]=50000;
X                        }
X                    else gemvalue[i] = (255&ivenarg[i])*100;
X                    gemorder[i]=k;
X                    cursor( (k%2)*40+1 , (k>>1)+4 );
X                    lprintf("%c) %s",i+'a',objectname[iven[i]]);
X                    cursor( (k%2)*40+33 , (k>>1)+4 );
X                    lprintf("%5d",(long)gemvalue[i]);  k++;
X                    break;
X
X            default:        /* make sure player can't sell non-existant gems */
X                gemvalue[i] = 0 ;
X                gemorder[i] = 0 ;
X            };
X    cursor(31,17); lprintf("You have %8d gold pieces in the bank.",(long)c[BANKACCOUNT]);
X    cursor(40,18); lprintf("You have %8d gold pieces",(long)c[GOLD]);
X    if (c[BANKACCOUNT]+c[GOLD] >= 500000)
X        lprcat("\nNote:  Larndom law states that only deposits under 500,000gp  can earn interest.");
X    while (1)
X        {
X        cl_dn(1,20);
X        lprcat("\nYour wish? [("); standout("d"); lprcat(") deposit, (");
X        standout("w"); lprcat(") withdraw, ("); standout("s");
X        lprcat(") sell a stone, or "); standout("escape"); lprcat("]  ");
X        yrepcount=0;
X        i=0; while (i!='d' && i!='w' && i!='s' && i!='\33') i=ttgetch();
X        switch(i)
X            {
X# ifdef MSDOS
X            case 'd':
X              lprcat("deposit\n");
X              cltoeoln();
X              lprcat("How much? "); amt = readnum((long)c[GOLD]);
X# else
X            case 'd':   lprcat("deposit\nHow much? ");  amt = readnum((long)c[GOLD]);
X# endif
X                        if (amt<0) { lprcat("\nSorry, but we can't take negative gold!"); nap(2000); amt=0; } else
X                        if (amt>c[GOLD])
X                          { lprcat("  You don't have that much.");  nap(2000); }
X                        else { c[GOLD] -= amt;  c[BANKACCOUNT] += amt; }
X                        break;
X
X            case 'w':   lprcat("withdraw\nHow much? "); amt = readnum((long)c[BANKACCOUNT]);
X                        if (amt<0) { lprcat("\nSorry, but we don't have any negative gold!");  nap(2000); amt=0; }
X                        else if (amt > c[BANKACCOUNT])
X                          { lprcat("\nYou don't have that much in the bank!"); nap(2000); }
X                        else { c[GOLD] += amt;  c[BANKACCOUNT] -= amt; }
X                        break;
X
X            case 's':   lprcat("\nWhich stone would you like to sell? ");
X            i=0; while ((i<'a' || i>'z') && i!='*' && i!='\33')
X                i=ttgetch();
X                        if (i=='*')
X              {
X              for (i=0; i<26; i++)
X                            {
X                            if (gemvalue[i])
X                                {
X                gems_sold = TRUE ;
X                c[GOLD]+=gemvalue[i];  iven[i]=0;
X                                gemvalue[i]=0;  k = gemorder[i];
X                                cursor( (k%2)*40+1 , (k>>1)+4 );
X                                lprintf("%39s","");
X                                }
X                            }
X              if (!gems_sold)
X                  {
X                  lprcat("\nYou have no gems to sell!");
X                  nap(2000);
X                  }
X              }
X            else if ( i != '\33' )
X                            {
X                            if (gemvalue[i=i-'a']==0)
X                                {
X                                lprintf("\nItem %c is not a gemstone!",i+'a');
X                                nap(2000); break;
X                                }
X                            c[GOLD]+=gemvalue[i];  iven[i]=0;
X                            gemvalue[i]=0;  k = gemorder[i];
X                            cursor( (k%2)*40+1 , (k>>1)+4 ); lprintf("%39s","");
X                            }
X                        break;
X
X            case '\33': return;
X            };
X        cursor(40,17); lprintf("%8d",(long)c[BANKACCOUNT]);
X        cursor(49,18); lprintf("%8d",(long)c[GOLD]);
X        }
X    }
X
X/*
X    function for the trading post
X */
Xstatic otradhead()
X    {
X    clear();
X    lprcat("Welcome to the Larn Trading Post.  We buy items that explorers no longer find\n");
X    lprcat("useful.  Since the condition of the items you bring in is not certain,\n");
X    lprcat("and we incur great expense in reconditioning the items, we usually pay\n");
X    lprcat("only 20% of their value were they to be new.  If the items are badly\n");
X    lprcat("damaged, we will pay only 10% of their new value.\n\n");
X
X    lprcat("Here are the items we would be willing to buy from you:\n");
X    }
X
Xshort tradorder[26];   /* screen locations for trading post inventory */
Xotradiven()
X    {
X    int i,j ;
X
X  /* Print user's iventory like bank */
X  for (j=i=0 ; i<26 ; i++)
X      if (iven[i])
X          {
X      cursor( (j%2)*40, (j>>1)+8 );
X      tradorder[i] = 0 ;    /* init position on screen to zero */
X      switch (iven[i])
X              {
X              case OPOTION:
X          if ( potionname[ivenarg[i]][0] != 0 )
X              {
X              tradorder[i] = j++ ;   /* will display only if identified */
X              lprintf( "%c) %s", i+'a', objectname[iven[i]] );
X              lprintf(" of%s", potionname[ivenarg[i]] );
X              }
X                  break;
X              case OSCROLL:
X          if ( scrollname[ivenarg[i]][0] != 0 )
X              {
X              tradorder[i] = j++ ;   /* will display only if identified */
X              lprintf( "%c) %s", i+'a', objectname[iven[i]] );
X              lprintf(" of%s", scrollname[ivenarg[i]] );
X              }
X          break;
X          case OLARNEYE:
X          case OBOOK:
X          case OSPIRITSCARAB:
X          case ODIAMOND:
X          case ORUBY:
X          case OEMERALD:
X          case OCHEST:
X          case OSAPPHIRE:
X          case OCUBEofUNDEAD:
X          case OCOOKIE:
X          case ONOTHEFT:
X          tradorder[i] = j++ ;  /* put on screen */
X          lprintf( "%c) %s", i+'a', objectname[iven[i]] );
X          break;
X          default:
X          tradorder[i] = j++ ;  /* put on screen */
X          lprintf( "%c) %s", i+'a', objectname[iven[i]] );
X          if (ivenarg[i] > 0)
X              lprintf(" +%d", (long)ivenarg[i] );
X          else if (ivenarg[i] < 0)
X              lprintf(" %d",  (long)ivenarg[i] );
X          break;
X          }
X      }
X      else
X       tradorder[i] = 0;  /* make sure order array is clear */
X    }
X
Xcleartradiven( i )
Xint i ;
X    {
X    int j;
X    j = tradorder[i] ;
X    cursor( (j%2)*40, (j>>1)+8 );
X    lprintf( "%39s", "" );
X    tradorder[i] = 0;
X    }
X
Xotradepost()
X    {
X    register int i,j,isub,izarg,found;
X    register long value;
X
X    dnditm = dndcount = 0;
X    nosignal = 1; /* disable signals */
X    otradhead();
X    otradiven();
X
X    while (1)
X       {
X       cl_dn(1,21);
X       lprcat("\nWhat item do you want to sell to us [");
X       standout("escape"); lprcat("] ? ");
X       i=0;
X       while ( i>'z' || i<'a' && i!=12 && i!='\33' )
X           i=ttgetch();
X       if (i == '\33')
X           {
X           recalc();
X           drawscreen();
X           nosignal=0; /* enable signals */
X           return;
X           }
X       while (1)   /* inner loop for simpler control */
X           {
X           if (i == 12)
X               {
X               clear();
X               otradhead();
X               otradiven();
X               break;      /* leave inner while */
X               }
X
X           isub = i - 'a' ;
X           if (iven[isub] == 0)
X               {
X               lprintf("\nYou don't have item %c!",isub+'a');
X               nap(2000);
X               break;      /* leave inner while */
X               }
X           if (iven[isub]==OSCROLL)
X               if (scrollname[ivenarg[isub]][0]==0)
X                   {
X                   cnsitm();
X                   break;      /* leave inner while */
X                   }
X           if (iven[isub]==OPOTION)
X               if (potionname[ivenarg[isub]][0]==0)
X                   {
X                   cnsitm();
X                   break;      /* leave inner while */
X                   }
X           if (iven[isub]==ODIAMOND ||
X               iven[isub]==ORUBY    ||
X               iven[isub]==OEMERALD ||
X	       iven[isub]==OSAPPHIRE )
X	       value = 20L * (ivenarg[isub] & 255);
X	   else if (iven[isub]==OLARNEYE)
X	       {
X	       value = 50000 - (((gtime*7) / 100) * 20 );
X	       if (value < 10000)
X		   value = 10000;
X	       }
X	   else
X               {
X               /* find object in itm[] list for price info */
X               found = MAXITM ;
X               for (j=0; j<MAXITM; j++)
X                   if (itm[j].obj == iven[isub])
X                       {
X                       found = j ;
X                       break;      /* leave for loop */
X                       }
X               if (found == MAXITM)
X                   {
X                   lprcat("\nSo sorry, but we are not authorized to accept that item.");
X                   nap(2000);
X                   break;      /* leave inner while */
X                   }
X               if (iven[isub] == OSCROLL ||
X                   iven[isub] == OPOTION)
X                   value = 2 * (long)itm[ j + ivenarg[isub]].price ;
X               else
X                   {
X                   izarg=ivenarg[isub];
X                   value = itm[j].price;
X                   /* appreciate if a +n object */
X                   if (izarg >= 0) value *= 2;
X                   while ((izarg-- > 0) && ((value=14*(67+value)/10) < 500000));
X                   }
X               }
X           /* we have now found the value of the item, and dealt with any error
X              cases.  Print the object's value, let the user sell it.
X           */
X           lprintf("\nItem (%c) is worth %d gold pieces to us.  Do you want to sell it? ",i,(long)value);
X           yrepcount=0;
X           if (getyn()=='y')
X               {
X               lprcat("yes\n"); c[GOLD]+=value;
X               if (c[WEAR] == isub) c[WEAR] = -1;
X               if (c[WIELD] == isub) c[WIELD] = -1;
X               if (c[SHIELD] == isub) c[SHIELD] = -1;
X               adjustcvalues(iven[isub],ivenarg[isub]);
X               iven[isub]=0;
X               cleartradiven( isub );
X               }
X           else
X           {
X           lprcat("no thanks.\n");
X           nap(500);
X           }
X       break;          /* exit inner while */
X           }   /* end of inner while */
X        }       /* end of outer while */
X    }       /* end of routine */
X
Xcnsitm()
X    {
X    lprcat("\nSorry, we can't accept unidentified objects.");
X    nap(2000);
X    }
X
X/*
X *  for the Larn Revenue Service
X */
Xolrs()
X    {
X    register int i,first;
X    unsigned long amt;
X    first = nosignal = 1; /* disable signals */
X    clear();  resetscroll(); cursor(1,4);
X    lprcat("Welcome to the Larn Revenue Service district office.  How can we help you?");
X    while (1)
X        {
X        if (first) { first=0; goto nxt; }
X        setscroll();
X        cursors();
X        lprcat("\n\nYour wish? [(");
X        standout("p");
X        lprcat(") pay taxes, or ");
X        standout("escape");
X        lprcat("]  ");  yrepcount=0;
X        i=0; while (i!='p' && i!='\33') i=ttgetch();
X        switch(i)
X            {
X            case 'p':   lprcat("pay taxes\nHow much? "); amt = readnum((long)c[GOLD]);
X                        if (amt<0) { lprcat("\nSorry, but we can't take negative gold\n"); amt=0; } else
X                        if (amt>c[GOLD])    lprcat("  You don't have that much.\n");
X                        else  c[GOLD] -= paytaxes((long)amt);
X                        break;
X
X            case '\33': nosignal = 0; /* enable signals */
X                        setscroll(); drawscreen();  return;
X            };
X
Xnxt:    cursor(1,6);
X        if (outstanding_taxes>0)
X            lprintf("You presently owe %d gp in taxes.  ",(long)outstanding_taxes);
X        else
X            lprcat("You do not owe us any taxes.           ");
X        cursor(1,8);
X        if (c[GOLD]>0)
X            lprintf("You have %6d gp.    ",(long)c[GOLD]);
X        else
X            lprcat("You have no gold pieces.  ");
X        }
X    }
END_OF_FILE
if test 28738 -ne `wc -c <'store.c'`; then
    echo shar: \"'store.c'\" unpacked with wrong size!
fi
# end of 'store.c'
fi
echo shar: End of archive 3 \(of 11\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 11 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0