billr@saab.CNA.TEK.COM (Bill Randle) (04/24/91)
Submitted-by: routley@tle.ENET.DEC.COM (Kevin Routley)
Posting-number: Volume 12, Issue 54
Archive-name: larn2/Part01
Supersedes: larn: Volume 11, Issue 84-94
Environment: Unix, VMS, MS-DOS, OS/2, termcap
[This is an update of the larn game posted earlier. This
includes patches, enhancements and additional support for
OS/2. -br]
#! /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 1 (of 12)."
# Contents: README MANIFEST main.c tgoto.c
# Wrapped by billr@saab on Tue Apr 23 13:50:27 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1841 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X
XHere is the source to Larn V12.3. I had made a number of changes without
Xchanging the save file format, so I decided to make another distribution
Xbefore making the big leap to V14.0.
X
XThis distribution incorporates all the changes distributed as Patches to V12.2,
Xa few others that were suggested but not sent out as patches, plus my own
Xdevelopment. See LARN123.FIX for a partial list.
X
XThe source correctly compiles and executes under DEC Ultrix (BSD), using the cc
Xcompiler. The enclosed makefile.unix is for U*ix systems (rename to Makefile).
XI've endevoured to make Larn buildable under SYSV, and it builds/runs correctly
Xwith Ultrix V3.1's SYSTEM_FIVE environment, so I expect its fairly close to
Xbeing usable under SYSV as well.
X
XThe source correctly compiles and executes under VAX/VMS, using the VAX C V3.x
Xcompiler. The enclosed descrip.mms is a MMS file for building under VAX/VMS.
XSee the VMSREADME.TXT for some more VMS-related information.
X
XThe source correctly compiles and executes under MS-DOS, using Turbo C++ V1.0.
XI am no longer able to verify that it compiles using Turbo C V2.0. The
Xmakefile.pc and tlink.rsp are for building the MS-DOS Larn.
X
XThe source correctly compiles and executes under OS/2, using Microsoft C.
XThe makefile.os2, os2larn.def and os2larn.lnk are for building the OS/2 Larn.
X
XI am interested in receiving source changes that allow Larn to be ported or
Xbuilt correctly on other architectures or operating systems. I am also
Xinterested in constructive changes or additions to improve the game.
X
XBug fixes, bug reports, and requests welcome.
X
XI am reachable at tle.enet.dec.com!routley or routley@tle.enet.dec.com.
XBecause I cannot provide a stable mail address, all USmail should be sent to:
X
XKevin Routley
XDigital Equipment Corporation
XZKO2-3/N30
X110 Spitbrook Road
XNashua, NH 03060
X
END_OF_FILE
if test 1841 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'MANIFEST' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(2692 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X File Name Archive # Description
X-----------------------------------------------------------
X MANIFEST 1 This shipping list
X Makefile.unix 2 Makefile for U*ix.
X README 1 General readme
X action.c 9
X bill.c 8
X config.c 12
X create.c 8
X data.c 4
X descrip.mms 12 MMS build file for VAX/VMS
X diag.c 9
X display.c 5
X fgetlr.c 12 Termcap support for VMS/MS-DOS.
X fortune.c 10
X global.c 2
X header.h 12
X help.c 12
X io.c 3
X iventory.c 10
X larn.ftn 12 Fortune File
X larn.maz 7 Maze file
X larn.opt 12 Sample options file. Rename to .larnopts for U*ix.
X larn123.doc 7 Documentation for Larn V12.3
X larn123.fix 11 List of changes since Larn V12.0
X larndefs.h 12
X larnhlp.txt 9 Help file without ansi escape sequences
X larnhlp.uue 10 Uuencoded help file with ansi escape sequences
X main.c 1
X makefile.os2 12 OS/2-Microsoft C Makefile
X makefile.pc 11 MS-DOS, Turbo C++ Makefile
X monster.c 6
X monsters.h 9
X moreobj.c 3
X movem.c 4
X msdos.c 10 MS-DOS Specific code.
X nansi.doc 11 Docs for NANSI.SYS, a MS-DOS ANSI.SYS replacement
X nansisys.uue 12 UUENCODED NANSI.SYS
X nap.c 12
X object.c 2
X objects.h 12
X os2larn.def 5 OS/2 Build support
X os2larn.lnk 4 OS/2 Build support
X patchlev.h 3
X player.h 12
X regen.c 11
X savelev.c 12
X scores.c 8
X signal.c 11
X spells.c 6
X spheres.c 11
X store.c 5
X termcap.pc 5 Termcap file for MS-DOS.
X termcap.vms 12 Termcap file for VMS.
X tgetent.c 10 Termcap support for VMS/MS-DOS.
X tgetstr.c 11 Termcap support for VMS/MS-DOS.
X tgoto.c 1 Termcap support for VMS/MS-DOS.
X tlink.rsp 4 Turbo C++ MS-DOS Build support
X tok.c 9
X tputs.c 7 Termcap support for VMS/MS-DOS.
X vms.c 11 VMS Specific code.
X vmsreadme.txt 6 VMS Specific Readme
END_OF_FILE
if test 2692 -ne `wc -c <'MANIFEST'`; then
echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'main.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'main.c'\"
else
echo shar: Extracting \"'main.c'\" \(40768 characters\)
sed "s/^X//" >'main.c' <<'END_OF_FILE'
X/* main.c */
X
X#ifdef MSDOS
X#include "errno.h"
X#include "setjmp.h"
X#include "stdlib.h"
X#endif
X
X#include "header.h"
X#include "larndefs.h"
X#include "monsters.h"
X#include "objects.h"
X#include "player.h"
X#include "patchlev.h"
X
X#ifndef MSDOS
X# ifndef VMS
X# include <pwd.h>
X# endif VMS
X#endif MSDOS
X
Xextern char move_no_pickup;
Xint dropflag=0; /* if 1 then don't lookforobject() next round */
Xint rmst=80; /* random monster creation counter */
Xint userid; /* the players login user id number */
Xchar nowelcome=0,nomove=0; /* if (nomove) then don't count next iteration as a
X move */
Xstatic char viewflag=0; /* if viewflag then we have done a 99 stay here
X and don't showcell in the main loop */
Xchar restorflag=0; /* 1 means restore has been done */
Xchar prompt_mode = 0; /* 1 if prompting for actions */
X
X#ifdef MSDOS
X
Xstatic char cmdhelp[] = "\
XCmd line format: larn [-slicnhp] [-o<optsfile>] [-##] [++]\n\
X -s show the scoreboard\n\
X -l show the logfile (wizard id only)\n\
X -i show scoreboard with inventories of dead characters\n\
X -c create new scoreboard (wizard id only)\n\
X -n suppress welcome message on starting game\n\
X -## specify level of difficulty (example: -5)\n\
X -h print this help text\n\
X -p prompt for actions on objects\n\
X ++ restore game from checkpoint file\n\
X -o<optsfile> specify larnopts filename to be used instead of \"larn.opt\"\n\
X";
X
X# else
X
Xstatic char cmdhelp[] = "\
XCmd line format: larn [-slicnhp] [-o<optsfile>] [-##] [++]\n\
X -s show the scoreboard\n\
X -l show the logfile (wizard id only)\n\
X -i show scoreboard with inventories of dead characters\n\
X -c create new scoreboard (wizard id only)\n\
X -n suppress welcome message on starting game\n\
X -## specify level of difficulty (example: -5)\n\
X -h print this help text\n\
X -p prompt for actions on objects\n\
X ++ restore game from checkpoint file\n\
X -o<optsfile> specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
X";
X
X# endif
X
X#ifdef MSDOS
Xint save_mode = 0; /* 1 if doing a save game */
Xjmp_buf save_jbuf; /* To recover from disk full errors */
X#endif
X
X#ifdef VT100
Xstatic char *termtypes[] = { "vt100", "vt101", "vt102", "vt103", "vt125",
X "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340",
X "vt341" };
X#endif
X
X#ifdef VMS
X# define EXIT_FAILURE
X# define EXIT_SUCCESS 1
X#else
X# define EXIT_FAILURE 1
X# define EXIT_SUCCESS 0
X#endif
X
X/*
X ************
X MAIN PROGRAM
X ************
X*/
Xmain(argc,argv)
X int argc;
X char **argv;
X {
X register int i,j;
X int hard = -1;
X char *ptr=0;
X#ifdef VT100
X char *ttype;
X#endif
X#ifndef MSDOS
X struct passwd *pwe,*getpwuid();
X#endif
X
X/*
X * first task is to identify the player
X */
X#ifndef VT100
X init_term(); /* setup the terminal (find out what type) for termcap */
X#endif
X#ifdef MSDOS
X ptr = "PLAYER";
X#else
X#ifdef VMS
X ptr = getenv("USER");
X#else
X if (((ptr = getlogin()) == 0) || (*ptr==0)) /* try to get login name */
X if (pwe=getpwuid(getuid())) /* can we get it from /etc/passwd? */
X ptr = pwe->pw_name;
X else
X if ((ptr = getenv("USER")) == 0)
X if ((ptr = getenv("LOGNAME")) == 0)
X {
X noone: write(2, "Can't find your logname. Who Are You?\n",39);
X exit();
X }
X if (ptr==0) goto noone;
X if (strlen(ptr)==0) goto noone;
X#endif
X#endif
X
X/*
X * second task is to prepare the pathnames the player will need
X */
X strcpy(loginname,ptr); /* save loginname of the user for logging purposes */
X strcpy(logname,ptr); /* this will be overwritten with the players name */
X
X/* Set up the input and output buffers.
X */
X lpbuf = (char *)malloc((5* BUFBIG)>>2); /* output buffer */
X inbuffer = (char *)malloc((5*MAXIBUF)>>2); /* output buffer */
X if ((lpbuf==0) || (inbuffer==0))
X died(-285); /* malloc() failure */
X
X# ifdef MSDOS
X /* LARNHOME now comes from the options file, so it must be read in
X * before constructing the other file names. Unfortunately we have
X * to look for the -o option now.
X */
X strcpy(optsfile, LARNOPTS);
X for (i = 1; i < argc; i++)
X if (strncmp(argv[i], "-o", 2) == 0)
X {
X argv[i][0] = 0; /* remove this argv */
X if (argv[i][2] != '\0')
X strncpy(optsfile, &argv[i][2], PATHLEN);
X else
X {
X strncpy(optsfile, argv[i + 1], PATHLEN);
X argv[i + 1][0] = 0; /* and this argv */
X }
X optsfile[PATHLEN - 1] = 0;
X break;
X }
X readopts();
X append_slash(larndir);
X
X /* Savefile and swapfile can be given explicitly as options
X */
X if (!savefilename[0])
X {
X strcpy(savefilename, larndir);
X strcat(savefilename, SAVEFILE);
X }
X if (!swapfile[0])
X {
X strcpy(swapfile, larndir);
X strcat(swapfile, SWAPFILE);
X }
X strcpy(scorefile, larndir);
X strcpy(logfile, larndir);
X strcpy(helpfile, larndir);
X strcpy(larnlevels, larndir);
X strcpy(fortfile, larndir);
X strcpy(playerids, larndir);
X strcpy(ckpfile, larndir);
X
X# else /* MSDOS */
X
X if ((ptr = getenv("HOME")) == 0)
X ptr = ".";
X#ifdef SAVEINHOME
X /* save file name in home directory */
X# ifdef VMS
X sprintf(savefilename, "%s%s",ptr, SAVEFILE);
X# else
X sprintf(savefilename, "%s/%s",ptr, SAVEFILE);
X# endif VMS
X#else
X strcat(savefilename,logname); /* prepare savefile name */
X strcat(savefilename,".sav"); /* prepare savefile name */
X#endif
X#ifdef VMS
X sprintf(optsfile, "%s%s",ptr, LARNOPTS); /* the options filename */
X#else
X sprintf(optsfile, "%s/%s",ptr, LARNOPTS); /* the options filename */
X#endif VMS
X
X# endif /* MSDOS */
X
X strcat(scorefile, SCORENAME); /* the larn scoreboard filename */
X strcat(logfile, LOGFNAME); /* larn activity logging filename */
X strcat(helpfile, HELPNAME); /* the larn on-line help file */
X strcat(larnlevels, LEVELSNAME); /* the pre-made cave level data file */
X strcat(fortfile, FORTSNAME); /* the fortune data file name */
X strcat(playerids, PLAYERIDS); /* the playerid data file name */
X strcat(ckpfile, CKPFILE);
X
X# ifdef TIMECHECK
X strcat(holifile, HOLIFILE); /* the holiday data file name */
X# endif
X
X#ifdef VT100
X/*
X * check terminal type to avoid users who have not vt100 type terminals
X */
X ttype = getenv("TERM");
X for (j=1, i=0; i<sizeof(termtypes)/sizeof(char *); i++)
X if (strcmp(ttype,termtypes[i]) == 0) { j=0; break; }
X if (j)
X {
X lprcat("Sorry, Larn needs a VT100 family terminal for all it's features.\n"); lflush();
X exit(EXIT_FAILURE);
X }
X#endif
X
X/*
X * now make scoreboard if it is not there (don't clear)
X */
X if (access(scorefile,0) == -1) /* not there */
X makeboard();
X
X/*
X * now process the command line arguments
X */
X for (i=1; i<argc; i++)
X {
X if (argv[i][0] == '-')
X switch(argv[i][1])
X {
X case 's': /* show scoreboard */
X showscores();
X exit(EXIT_SUCCESS);
X
X case 'l': /* show log file */
X diedlog();
X exit(EXIT_SUCCESS);
X
X case 'i': /* show all scoreboard */
X showallscores();
X exit(EXIT_SUCCESS);
X
X case 'c': /* anyone with password can create scoreboard */
X lprcat("Preparing to initialize the scoreboard.\n");
X if (getpassword() != 0) /*make new scoreboard*/
X {
X makeboard();
X lprc('\n');
X showscores();
X }
X exit(EXIT_SUCCESS);
X
X case 'n': /* no welcome msg */
X nowelcome=1;
X argv[i][0]=0;
X break;
X
X case '0': case '1': case '2': case '3': case '4': case '5':
X case '6': case '7': case '8': case '9': /* for hardness */
X hard = atoi(&argv[i][1]);
X break;
X
X case 'h': /* print out command line arguments */
X case '?':
X write(1,cmdhelp,sizeof(cmdhelp));
X exit(EXIT_SUCCESS);
X
X case 'o': /* specify a .larnopts filename */
X if (argv[i]+2 != '\0')
X strncpy(optsfile,argv[i]+2,127);
X else
X {
X strncpy( optsfile, argv[i+1][0], 127 );
X argv[i+1][0] = '\0';
X }
X break;
X
X case 'p': /* set 'prompt_mode' flag */
X prompt_mode = 1 ;
X break ;
X
X default:
X printf("Unknown option <%s>\n",argv[i]);
X write(1,cmdhelp,sizeof(cmdhelp));
X exit(EXIT_SUCCESS);
X };
X
X if (strcmp(argv[i], "++") == 0)
X restorflag = 1;
X }
X
X#ifndef MSDOS
X readopts(); /* read the options file if there is one */
X#endif
X
X#ifdef TIMECHECK
X/*
X * this section of code checks to see if larn is allowed during working hours
X */
X if (dayplay==0) /* check for not-during-daytime-hours */
X if (playable())
X {
X write(2,"Sorry, Larn can not be played during working hours.\n",52);
X exit(EXIT_SUCCESS);
X }
X#endif TIMECHECK
X
X#ifdef UIDSCORE
X userid = geteuid(); /* obtain the user's effective id number */
X#else UIDSCORE
X userid = getplid(logname); /* obtain the players id number */
X#endif UIDSCORE
X#ifdef VMS
X wisid = userid;
X#endif
X if (userid < 0)
X {
X write(2,"Can't obtain playerid\n",22);
X exit(EXIT_SUCCESS);
X }
X
X#ifdef HIDEBYLINK
X/*
X * this section of code causes the program to look like something else to ps
X */
X if (strcmp(psname,argv[0])) /* if a different process name only */
X {
X if ((i=access(psname,1)) < 0)
X { /* link not there */
X if (link(argv[0],psname)>=0)
X {
X argv[0] = psname; execv(psname,argv);
X }
X }
X else
X unlink(psname);
X }
X
X for (i=1; i<argc; i++)
X {
X szero(argv[i]); /* zero the argument to avoid ps snooping */
X }
X#endif HIDEBYLINK
X
X/*
X * He really wants to play, so malloc the memory for the dungeon.
X */
X# ifdef MSDOS
X allocate_memory();
X# else
X cell = (struct cel *)malloc(sizeof(struct cel)*(MAXLEVEL+MAXVLEVEL)*MAXX*MAXY);
X if (cell == 0) died(-285); /* malloc failure */
X# endif
X lcreat((char*)0);
X newgame(); /* set the initial clock */
X
X if (restorflag == 1) /* restore checkpoint file */
X {
X clear();
X hitflag = 1;
X restoregame(ckpfile);
X }
X else if (access(savefilename,0)==0) /* restore game if need to */
X {
X clear();
X restorflag = 1;
X hitflag=1;
X restoregame(savefilename); /* restore last game */
X }
X sigsetup(); /* trap all needed signals */
X setupvt100(); /* setup the terminal special mode */
X sethard(hard); /* set up the desired difficulty */
X if (c[HP]==0) /* create new game */
X {
X makeplayer(); /* make the character that will play */
X newcavelevel(0);/* make the dungeon */
X predostuff = 1; /* tell signals that we are in the welcome screen */
X if (nowelcome==0)
X welcome(); /* welcome the player to the game */
X# ifdef MSDOS
X /* Display their mail if they've just won the previous game
X */
X checkmail();
X# endif
X }
X
X lprc(T_INIT); /* Reinit the screen because of welcome and check mail
X * having embedded escape sequences.*/
X drawscreen(); /* show the initial dungeon */
X predostuff = 2; /* tell the trap functions that they must do a showplayer()
X from here on */
X /* nice(1); /* games should be run niced */
X yrepcount = hit2flag = 0;
X /* init previous player position to be current position, so we don't
X reveal any stuff on the screen prematurely.
X */
X oldx = playerx ;
X oldy = playery;
X gtime = -1;
X
X /* MAINLOOP
X find objects, move stuff, get commands, regenerate
X */
X while (1)
X {
X if (dropflag==0)
X /* see if there is an object here.
X
X If in prompt mode, identify and prompt; else
X identify, pickup if ( auto pickup and not move-no-pickup ),
X never prompt.
X */
X if (prompt_mode)
X lookforobject( TRUE, FALSE, TRUE );
X else
X lookforobject( TRUE, ( auto_pickup && !move_no_pickup ), FALSE );
X else
X dropflag=0; /* don't show it just dropped an item */
X
X /* handle global activity
X update game time, move spheres, move walls, move monsters
X all the stuff affected by TIMESTOP and HASTESELF
X */
X if (c[TIMESTOP] <= 0)
X if (c[HASTESELF] == 0 ||
X (c[HASTESELF] & 1) == 0)
X {
X gtime++;
X movsphere();
X
X if (hitflag==0)
X {
X if (c[HASTEMONST])
X movemonst();
X movemonst();
X }
X }
X
X /* show stuff around the player
X */
X if (viewflag==0)
X showcell(playerx,playery);
X else
X viewflag=0;
X
X if (hit3flag)
X lflushall();
X hitflag=hit3flag=0;
X bot_linex(); /* update bottom line */
X
X /* get commands and make moves
X */
X nomove=1;
X while (nomove)
X {
X if (hit3flag)
X lflushall();
X nomove=0;
X parse();
X }
X regen(); /* regenerate hp and spells */
X if (c[TIMESTOP]==0)
X if (--rmst <= 0)
X {
X rmst = 120-(level<<2);
X fillmonst(makemonst(level));
X }
X }
X }
X
X/*
X subroutine to randomly create monsters if needed
X */
Xstatic randmonst()
X {
X if (c[TIMESTOP]) return; /* don't make monsters if time is stopped */
X if (--rmst <= 0)
X {
X rmst = 120 - (level<<2); fillmonst(makemonst(level));
X }
X }
X
X
X/*
X parse()
X
X get and execute a command
X */
Xstatic parse()
X {
X register int i,j,k,flag;
X extern showeat(),showquaff(),showread();
X
X while (1)
X {
X k = yylex();
X switch(k) /* get the token from the input and switch on it */
X {
X case 'h': moveplayer(4); return; /* west */
X case 'H': run(4); return; /* west */
X case 'l': moveplayer(2); return; /* east */
X case 'L': run(2); return; /* east */
X case 'j': moveplayer(1); return; /* south */
X case 'J': run(1); return; /* south */
X case 'k': moveplayer(3); return; /* north */
X case 'K': run(3); return; /* north */
X case 'u': moveplayer(5); return; /* northeast */
X case 'U': run(5); return; /* northeast */
X case 'y': moveplayer(6); return; /* northwest */
X case 'Y': run(6); return; /* northwest */
X case 'n': moveplayer(7); return; /* southeast */
X case 'N': run(7); return; /* southeast */
X case 'b': moveplayer(8); return; /* southwest */
X case 'B': run(8); return; /* southwest */
X
X case '.': /* stay here */
X if (yrepcount)
X viewflag=1;
X return;
X
X case 'c':
X yrepcount=0;
X cast();
X return; /* cast a spell */
X
X case 'd':
X yrepcount=0;
X if (c[TIMESTOP]==0)
X dropobj();
X return; /* to drop an object */
X
X case 'e':
X yrepcount=0;
X if (c[TIMESTOP]==0)
X if (!floor_consume( OCOOKIE, "eat" ))
X consume( OCOOKIE, "eat", showeat );
X return; /* to eat a fortune cookie */
X
X case 'g':
X yrepcount = 0 ;
X cursors();
X lprintf("\nThe stuff you are carrying presently weighs %d pounds",(long)packweight());
X break ;
X
X case 'i': /* inventory */
X yrepcount=0;
X nomove=1;
X showstr(FALSE);
X return;
X
X case 'p': /* pray at an altar */
X yrepcount = 0;
X if (!prompt_mode)
X pray_at_altar();
X else
X nomove = 1;
X return;
X
X case 'q': /* quaff a potion */
X yrepcount=0;
X if (c[TIMESTOP]==0)
X if (!floor_consume( OPOTION, "quaff"))
X consume( OPOTION, "quaff", showquaff );
X return;
X
X case 'r':
X yrepcount=0;
X if (c[BLINDCOUNT])
X {
X cursors();
X lprcat("\nYou can't read anything when you're blind!");
X }
X else if (c[TIMESTOP]==0)
X if (!floor_consume( OSCROLL, "read" ))
X if (!floor_consume( OBOOK, "read" ))
X consume( OSCROLL, "read", showread );
X return; /* to read a scroll */
X
X case 's':
X yrepcount = 0 ;
X if (!prompt_mode)
X sit_on_throne();
X else
X nomove = 1;
X return ;
X
X case 't': /* Tidy up at fountain */
X yrepcount = 0 ;
X if (!prompt_mode)
X wash_fountain() ;
X else
X nomove = 1;
X return ;
X
X case 'v':
X yrepcount=0;
X nomove = 1;
X cursors();
X lprintf("\nCaverns of Larn, Version %d.%d.%d, Diff=%d",(long)VERSION,(long)SUBVERSION,(long)PATCHLEVEL,(long)c[HARDGAME]);
X if (wizard)
X lprcat(" Wizard");
X if (cheat)
X lprcat(" Cheater");
X lprcat("\nThis version of Larn by Kevin Routley");
X return;
X
X case 'w': /* wield a weapon */
X yrepcount=0;
X wield();
X return;
X
X case 'A':
X yrepcount = 0;
X if (!prompt_mode)
X desecrate_altar();
X else
X nomove = 1;
X return;
X
X case 'C': /* Close something */
X yrepcount = 0 ;
X if (!prompt_mode)
X close_something();
X else
X nomove = 1;
X return;
X
X case 'D': /* Drink at fountain */
X yrepcount = 0 ;
X if (!prompt_mode)
X drink_fountain() ;
X else
X nomove = 1;
X return ;
X
X case 'E': /* Enter a building */
X yrepcount = 0 ;
X if (!prompt_mode)
X enter() ;
X else
X nomove = 1;
X break ;
X
X case 'I': /* list spells and scrolls */
X yrepcount=0;
X seemagic(0);
X nomove=1;
X return;
X
X case 'O': /* Open something */
X yrepcount = 0 ;
X if (!prompt_mode)
X open_something();
X else
X nomove = 1;
X return;
X
X case 'P':
X cursors();
X yrepcount = 0;
X nomove = 1;
X if (outstanding_taxes>0)
X lprintf("\nYou presently owe %d gp in taxes.",(long)outstanding_taxes);
X else
X lprcat("\nYou do not owe any taxes.");
X return;
X
X case 'Q': /* quit */
X yrepcount=0;
X quit();
X nomove=1;
X return;
X
X case 'R' : /* remove gems from a throne */
X yrepcount = 0 ;
X if (!prompt_mode)
X remove_gems( );
X else
X nomove = 1;
X return ;
X
X# ifdef MSDOS
X case 'S':
X /* Set up error recovery
X */
X if (setjmp(save_jbuf) != 0) {
X
X /* can't use lwclose!
X */
X if (lfd > 2)
X close(lfd);
X lcreat(NULL);
X setscroll();
X cursors();
X lprcat("\nSave failed !\n");
X if (errno == ENOSPC)
X lprcat("Disk is full !\n");
X beep();
X (void) unlink(savefilename);
X save_mode = 0;
X yrepcount = 0;
X nomove = 1;
X break;
X }
X
X /* And do the save.
X */
X cursors();
X lprintf("\nSaving to `%s' . . . ", savefilename);
X lflush();
X save_mode = 1;
X savegame(savefilename);
X clear();
X lflush();
X wizard=1;
X died(-257); /* doesn't return */
X break;
X# else
X case 'S': clear(); lprcat("Saving . . ."); lflush();
X savegame(savefilename); wizard=1; died(-257); /* save the game - doesn't return */
X# endif MSDOS
X
X case 'T': yrepcount=0; cursors(); if (c[SHIELD] != -1) { c[SHIELD] = -1; lprcat("\nYour shield is off"); bottomline(); } else
X if (c[WEAR] != -1) { c[WEAR] = -1; lprcat("\nYour armor is off"); bottomline(); }
X else lprcat("\nYou aren't wearing anything");
X return;
X
X case 'W':
X yrepcount=0;
X wear();
X return; /* wear armor */
X
X case 'Z':
X yrepcount=0;
X if (c[LEVEL]>9)
X {
X oteleport(1);
X return;
X }
X cursors();
X lprcat("\nAs yet, you don't have enough experience to use teleportation");
X return; /* teleport yourself */
X
X case ' ': yrepcount=0; nomove=1; return;
X
X# ifdef MSDOS
X case 'D'-64:
X yrepcount = 0;
X nomove = 1;
X levelinfo();
X return;
X# endif
X
X case 'L'-64: yrepcount=0; drawscreen(); nomove=1; return; /* look */
X
X#if WIZID
X#ifdef EXTRA
X case 'A'-64: yrepcount=0; nomove=1; if (wizard) { diag(); return; } /* create diagnostic file */
X return;
X#endif
X#endif
X case '<': /* Go up stairs or vol shaft */
X yrepcount = 0 ;
X if (!prompt_mode)
X up_stairs();
X else
X nomove = 1;
X return ;
X
X case '>': /* Go down stairs or vol shaft*/
X yrepcount = 0 ;
X if (!prompt_mode)
X down_stairs();
X else
X nomove = 1;
X return ;
X
X case '?': /* give the help screen */
X yrepcount=0;
X help();
X nomove=1;
X return;
X
X case ',': /* pick up an item */
X yrepcount = 0 ;
X if (!prompt_mode)
X /* pickup, don't identify or prompt for action */
X lookforobject( FALSE, TRUE, FALSE );
X else
X nomove = 1;
X return;
X
X case ':': /* look at object */
X yrepcount = 0 ;
X if (!prompt_mode)
X /* identify, don't pick up or prompt for action */
X lookforobject( TRUE, FALSE, FALSE );
X nomove = 1; /* assumes look takes no time */
X return;
X
X case '@': /* toggle auto-pickup */
X yrepcount = 0 ;
X nomove = 1;
X cursors();
X lprcat("\nAuto pickup: ");
X auto_pickup = !auto_pickup;
X if (auto_pickup)
X lprcat("On.");
X else
X lprcat("Off.");
X return;
X
X case '/': /* identify object/monster */
X specify_object();
X nomove = 1 ;
X yrepcount = 0 ;
X return;
X
X case '^': /* identify traps */
X flag = yrepcount = 0;
X cursors();
X lprc('\n');
X for (j=playery-1; j<playery+2; j++)
X {
X if (j < 0)
X j=0;
X if (j >= MAXY)
X break;
X for (i=playerx-1; i<playerx+2; i++)
X {
X if (i < 0)
X i=0;
X if (i >= MAXX)
X break;
X switch(item[i][j])
X {
X case OTRAPDOOR: case ODARTRAP:
X case OTRAPARROW: case OTELEPORTER:
X case OPIT:
X lprcat("\nIts ");
X lprcat(objectname[item[i][j]]);
X flag++;
X };
X }
X }
X if (flag==0)
X lprcat("\nNo traps are visible");
X return;
X
X#if WIZID
X case '_': /* this is the fudge player password for wizard mode*/
X yrepcount=0; cursors(); nomove=1;
X# ifndef MSDOS
X if (userid!=wisid)
X {
X lprcat("Sorry, you are not empowered to be a wizard.\n");
X scbr(); /* system("stty -echo cbreak"); */
X lflush(); return;
X }
X# endif
X if (getpassword()==0)
X {
X scbr(); /* system("stty -echo cbreak"); */ return;
X }
X wizard=1; scbr(); /* system("stty -echo cbreak"); */
X for (i=0; i<6; i++) c[i]=70; iven[0]=iven[1]=0;
X take(OPROTRING,50); take(OLANCE,25); c[WIELD]=1;
X c[LANCEDEATH]=1; c[WEAR] = c[SHIELD] = -1;
X raiseexperience(6000000L); c[AWARENESS] += 25000;
X {
X register int i,j;
X for (i=0; i<MAXY; i++)
X for (j=0; j<MAXX; j++) know[j][i]=KNOWALL;
X for (i=0; i<SPNUM; i++) spelknow[i]=1;
X for (i=0; i<MAXSCROLL; i++) scrollname[i][0]=' ';
X for (i=0; i<MAXPOTION; i++) potionname[i][0]=' ';
X }
X for (i=0; i<MAXSCROLL; i++)
X if (strlen(scrollname[i])>2) /* no null items */
X { item[i][0]=OSCROLL; iarg[i][0]=i; }
X for (i=MAXX-1; i>MAXX-1-MAXPOTION; i--)
X if (strlen(potionname[i-MAXX+MAXPOTION])>2) /* no null items */
X { item[i][0]=OPOTION; iarg[i][0]=i-MAXX+MAXPOTION; }
X for (i=1; i<MAXY; i++)
X { item[0][i]=i; iarg[0][i]=0; }
X for (i=MAXY; i<MAXY+MAXX; i++)
X { item[i-MAXY][MAXY-1]=i; iarg[i-MAXY][MAXY-1]=0; }
X for (i=MAXX+MAXY; i<MAXOBJECT; i++)
X {
X item[MAXX-1][i-MAXX-MAXY]=i;
X iarg[MAXX-1][i-MAXX-MAXY]=0;
X }
X c[GOLD]+=250000; drawscreen(); return;
X#endif
X
X };
X }
X }
X
Xparse2()
X {
X if (c[HASTEMONST]) movemonst(); movemonst(); /* move the monsters */
X randmonst(); regen();
X }
X
Xstatic run(dir)
X int dir;
X {
X register int i;
X i=1; while (i)
X {
X i=moveplayer(dir);
X if (i>0) { if (c[HASTEMONST]) movemonst(); movemonst(); randmonst(); regen(); }
X if (hitflag) i=0;
X if (i!=0) showcell(playerx,playery);
X }
X }
X
X/*
X function to wield a weapon
X */
Xstatic wield()
X {
X register int i;
X while (1)
X {
X if ((i = whatitem("wield (- for nothing)")) == '\33')
X return;
X if (i != '.')
X {
X if (i=='*')
X {
X i = showwield();
X cursors();
X }
X if ( i == '-' )
X {
X c[WIELD] = -1 ;
X bottomline();
X return;
X }
X if (i && i != '.')
X if (iven[i-'a']==0)
X { ydhi(i); return; }
X else if (iven[i-'a']==OPOTION)
X { ycwi(i); return; }
X else if (iven[i-'a']==OSCROLL)
X { ycwi(i); return; }
X else if ((c[SHIELD]!= -1) && (iven[i-'a']==O2SWORD))
X { lprcat("\nBut one arm is busy with your shield!");
X return; }
X else
X {
X c[WIELD]=i-'a';
X if (iven[i-'a'] == OLANCE)
X c[LANCEDEATH]=1;
X else c[LANCEDEATH]=0;
X bottomline();
X return;
X }
X }
X }
X }
X
X/*
X common routine to say you don't have an item
X */
Xstatic ydhi(x)
X int x;
X { cursors(); lprintf("\nYou don't have item %c!",x); }
Xstatic ycwi(x)
X int x;
X { cursors(); lprintf("\nYou can't wield item %c!",x); }
X
X/*
X function to wear armor
X */
Xstatic wear()
X {
X register int i;
X while (1)
X {
X if ((i = whatitem("wear"))=='\33')
X return;
X if (i != '.' && i != '-')
X {
X if (i=='*')
X {
X i = showwear();
X cursors();
X }
X if (i && i != '.')
X switch(iven[i-'a'])
X {
X case 0:
X ydhi(i);
X return;
X case OLEATHER: case OCHAIN: case OPLATE:
X case ORING: case OSPLINT: case OPLATEARMOR:
X case OSTUDLEATHER: case OSSPLATE:
X if (c[WEAR] != -1) { lprcat("\nYou're already wearing some armor"); return; }
X c[WEAR]=i-'a'; bottomline(); return;
X case OSHIELD: if (c[SHIELD] != -1) { lprcat("\nYou are already wearing a shield"); return; }
X if (iven[c[WIELD]]==O2SWORD) { lprcat("\nYour hands are busy with the two handed sword!"); return; }
X c[SHIELD] = i-'a'; bottomline(); return;
X default: lprcat("\nYou can't wear that!");
X };
X }
X }
X }
X
X/*
X function to drop an object
X */
Xstatic dropobj()
X {
X register int i;
X register char *p;
X long amt;
X
X p = &item[playerx][playery];
X while (1)
X {
X if ((i = whatitem("drop"))=='\33')
X return;
X if (i=='*')
X {
X i = showstr(TRUE);
X cursors();
X }
X if ( i != '-' )
X {
X if (i=='.') /* drop some gold */
X {
X if (*p) { lprcat("\nThere's something here already!"); return; }
X lprcat("\n\n");
X cl_dn(1,23);
X lprcat("How much gold do you drop? ");
X if ((amt=readnum((long)c[GOLD])) == 0) return;
X if (amt>c[GOLD])
X {
X#ifndef MSDOS
X lprcat("\n");
X#endif MSDOS
X lprcat("You don't have that much!");
X return; }
X if (amt<=32767)
X { *p=OGOLDPILE; i=amt; }
X else if (amt<=327670L)
X { *p=ODGOLD; i=amt/10; amt = 10L*i; }
X else if (amt<=3276700L)
X { *p=OMAXGOLD; i=amt/100; amt = 100L*i; }
X else if (amt<=32767000L)
X { *p=OKGOLD; i=amt/1000; amt = 1000L*i; }
X else
X { *p=OKGOLD; i=32767; amt = 32767000L; }
X c[GOLD] -= amt;
X#ifndef MSDOS
X lprintf("You drop %d gold pieces",(long)amt);
X#else
X lprintf("\nYou drop %d gold pieces",(long)amt);
X#endif MSDOS
X iarg[playerx][playery]=i; bottomgold();
X know[playerx][playery]=0; dropflag=1; return;
X }
X if (i)
X {
X drop_object(i-'a');
X return;
X }
X }
X }
X }
X
Xstatic int floor_consume( search_item, cons_verb )
Xint search_item;
Xchar *cons_verb;
X {
X register int i;
X char tempc;
X
X cursors();
X i = item[playerx][playery];
X
X /* item not there, quit
X */
X if (i != search_item)
X return( 0 );
X
X /* item there. does the player want to consume it?
X */
X lprintf("\nThere is %s", objectname[i] );
X if (i==OSCROLL)
X if (scrollname[iarg[playerx][playery]][0])
X lprintf(" of%s", scrollname[iarg[playerx][playery]]);
X if (i==OPOTION)
X if (potionname[iarg[playerx][playery]][0])
X lprintf(" of%s", potionname[iarg[playerx][playery]]);
X lprintf(" here. Do you want to %s it?", cons_verb );
X
X if ((tempc = getyn()) == 'n' )
X return( 0 ); /* item there, not consumed */
X else if (tempc != 'y')
X {
X lprcat(" aborted");
X return( -1 ); /* abort */
X }
X
X /* consume the item.
X */
X switch( i )
X {
X case OCOOKIE:
X outfortune();
X forget();
X break;
X case OBOOK:
X readbook( iarg[playerx][playery] );
X forget();
X break;
X case OPOTION:
X quaffpotion( iarg[playerx][playery] );
X forget();
X break;
X case OSCROLL:
X /* scrolls are tricky because of teleport.
X */
X i = iarg[playerx][playery];
X know[playerx][playery] = 0;
X item[playerx][playery] = iarg[playerx][playery] = 0 ;
X read_scroll( i );
X break;
X }
X return( 1 );
X }
X
Xstatic int consume( search_item, prompt, showfunc )
Xint search_item ;
Xchar *prompt;
Xint (*showfunc)();
X {
X register int i;
X
X while (1)
X {
X if ((i = whatitem( prompt )) == '\33')
X return;
X if (i != '.' && i != '-')
X {
X if (i == '*')
X {
X i = showfunc();
X cursors();
X }
X if (i && i != '.')
X {
X switch (iven[i-'a'])
X {
X case OSCROLL:
X if ( search_item != OSCROLL )
X {
X lprintf("\nYou can't %s that.", prompt );
X return;
X }
X read_scroll( ivenarg[i-'a'] );
X break;
X case OBOOK:
X if ( search_item != OSCROLL )
X {
X lprintf("\nYou can't %s that.", prompt );
X return;
X }
X readbook( ivenarg[i-'a'] );
X break;
X case OCOOKIE:
X if ( search_item != OCOOKIE )
X {
X lprintf("\nYou can't %s that.", prompt );
X return;
X }
X outfortune();
X break;
X case OPOTION:
X if ( search_item != OPOTION )
X {
X lprintf("\nYou can't %s that.", prompt );
X return;
X }
X quaffpotion( ivenarg[i-'a'], TRUE );
X break;
X case 0:
X ydhi(i);
X return;
X default:
X lprintf("\nYou can't %s that.", prompt );
X return;
X }
X iven[i-'a'] = 0;
X return;
X }
X }
X }
X }
X
X/*
X function to ask what player wants to do
X */
Xstatic whatitem(str)
X char *str;
X {
X int i=0;
X cursors(); lprintf("\nWhat do you want to %s [* for all] ? ",str);
X while (i>'z' || (i<'a' && i!='-' && i!='*' && i!='\33' && i!='.'))
X i=ttgetch();
X if (i=='\33')
X lprcat(" aborted");
X return(i);
X }
X
X/*
X subroutine to get a number from the player
X and allow * to mean return amt, else return the number entered
X */
Xunsigned long readnum(mx)
X long mx;
X {
X register int i;
X register unsigned long amt=0;
X
X sncbr();
X /* allow him to say * for all gold
X */
X if ((i=ttgetch()) == '*')
X amt = mx;
X else
X /* read chars into buffer, deleting when requested */
X while (i != '\n')
X {
X if (i=='\033') { scbr(); lprcat(" aborted"); return(0); }
X if ((i <= '9') && (i >= '0') && (amt<999999999))
X amt = amt*10+i-'0';
X if ((i=='\010') || (i=='\177'))
X amt = (long)(amt / 10) ;
X i = ttgetch();
X }
X scbr();
X return(amt);
X }
X
X#ifdef HIDEBYLINK
X/*
X * routine to zero every byte in a string
X */
Xszero(str)
X register char *str;
X {
X while (*str)
X *str++ = 0;
X }
X#endif HIDEBYLINK
X
X#ifdef TIMECHECK
X/*
X * routine to check the time of day and return 1 if its during work hours
X * checks the file ".holidays" for forms like "mmm dd comment..."
X */
Xint playable()
X {
X long g_time,time();
X int hour,day,year;
X char *date,*month,*p;
X
X time(&g_time); /* get the time and date */
X date = ctime(&g_time); /* format: Fri Jul 4 00:27:56 EDT 1986 */
X year = atoi(date+20);
X hour = (date[11]-'0')*10 + date[12]-'0';
X day = (date[8]!=' ') ? ((date[8]-'0')*10 + date[9]-'0') : (date[9]-'0');
X month = date+4; date[7]=0; /* point to and NULL terminate month */
X
X if (((hour>=8 && hour<17)) /* 8AM - 5PM */
X && strncmp("Sat",date,3)!=0 /* not a Saturday */
X && strncmp("Sun",date,3)!=0) /* not a Sunday */
X {
X /* now check for a .holidays datafile */
X lflush();
X if (lopen(holifile) >= 0)
X for ( ; ; )
X {
X if ((p=lgetw())==0) break;
X if (strlen(p)<6) continue;
X if ((strncmp(p,month,3)==0) && (day==atoi(p+4)) && (year==atoi(p+7)))
X return(0); /* a holiday */
X }
X lrclose(); lcreat((char*)0);
X return(1);
X }
X return(0);
X }
X#endif TIMECHECK
END_OF_FILE
if test 40768 -ne `wc -c <'main.c'`; then
echo shar: \"'main.c'\" unpacked with wrong size!
fi
# end of 'main.c'
fi
if test -f 'tgoto.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tgoto.c'\"
else
echo shar: Extracting \"'tgoto.c'\" \(6360 characters\)
sed "s/^X//" >'tgoto.c' <<'END_OF_FILE'
X/************************************************************************
X * *
X * Copyright (c) 1982, Fred Fish *
X * All Rights Reserved *
X * *
X * This software and/or documentation is released for public *
X * distribution for personal, non-commercial use only. *
X * Limited rights to use, modify, and redistribute are hereby *
X * granted for non-commercial purposes, provided that all *
X * copyright notices remain intact and all changes are clearly *
X * documented. The author makes no warranty of any kind with *
X * respect to this product and explicitly disclaims any implied *
X * warranties of merchantability or fitness for any particular *
X * purpose. *
X * *
X ************************************************************************
X */
X
X
X/*
X * LIBRARY FUNCTION
X *
X * tgoto expand cursor addressing string from cm capability
X *
X * KEY WORDS
X *
X * termcap
X *
X * SYNOPSIS
X *
X * char *tgoto(cm,destcol,destline)
X * char *cm;
X * int destcol;
X * int destline;
X *
X * DESCRIPTION
X *
X * Returns cursor addressing string, decoded from the cm
X * capability string, to move cursor to column destcol on
X * line destline.
X *
X * The following sequences uses one input argument, either
X * line or column, and place the appropriate substitution
X * in the output string:
X *
X * %d substitute decimal value (in ASCII)
X * %2 like %d but forces field width to 2
X * %3 like %d but forces field width to 3
X * %. like %c
X * %+x like %c but adds ASCII value of x
X *
X * The following sequences cause processing modifications
X * but do not "use up" one of the arguments. If they
X * act on an argument they act on the next one to
X * be converted.
X *
X * %>xy if next value to be converted is
X * greater than value of ASCII char x
X * then add value of ASCII char y.
X * %r reverse substitution of line
X * and column (line is substituted
X * first by default).
X * %i causes input values destcol and
X * destline to be incremented.
X * %% gives single % character in output.
X *
X * BUGS
X *
X * Does not implement some of the more arcane sequences for
X * radically weird terminals (specifically %n, %B, & %D).
X * If you have one of these you deserve whatever happens.
X *
X */
X
X/*
X * Miscellaneous stuff
X */
X
X#include <stdio.h>
X
X#define MAXARGS 2
X
Xstatic char *in; /* Internal copy of input string pointer */
Xstatic char *out; /* Pointer to output array */
Xstatic int args[MAXARGS]; /* Maximum number of args to convert */
Xstatic int pcount; /* Count of args processed */
Xstatic char output[64]; /* Converted string */
X
X
X/*
X * PSEUDO CODE
X *
X * Begin tgoto
X * If no string to process then
X * Return pointer to error string.
X * Else
X * Initialize pointer to input string.
X * Initialize pointer to result string.
X * First arg is line number by default.
X * Second arg is col number by default.
X * No arguments processed yet.
X * While there is another character to process
X * If character is a not a % character then
X * Simply copy to output.
X * Else
X * Process the control sequence.
X * End if
X * End while
X * TERMINATE STRING! (rde)
X * Return pointer to static output string.
X * End if
X * End tgoto
X *
X */
X
Xchar *tgoto(cm,destcol,destline)
Xchar *cm;
Xint destcol;
Xint destline;
X{
X if (cm == NULL) {
X return("OOPS");
X } else {
X in = cm;
X out = output;
X args[0] = destline;
X args[1] = destcol;
X pcount = 0;
X while (*in != NULL) {
X if (*in != '%') {
X *out++ = *in++;
X } else {
X process();
X }
X }
X *out = '\0'; /* rde 18-DEC-86: don't assume out was all zeros */
X return(output);
X }
X}
X
X/*
X * INTERNAL FUNCTION
X *
X * process process the conversion/command sequence
X *
X * SYNOPSIS
X *
X * static process()
X *
X * DESCRIPTION
X *
X * Processes the sequence beginning with the % character.
X * Directly manipulates the input string pointer, the
X * output string pointer, and the arguments. Leaves
X * the input string pointer pointing to the next character
X * to be processed, and the output string pointer pointing
X * to the next output location. If conversion of
X * one of the numeric arguments occurs, then the pcount
X * is incremented.
X *
X */
X
X/*
X * PSEUDO CODE
X *
X * Begin process
X * Skip over the % character.
X * Switch on next character after %
X * Case 'd':
X * Process %d type conversion (variable width).
X * Reinitialize output pointer.
X * Break;
X * Case '2':
X * Process %d type conversion (width 2).
X * Reinitialize output pointer.
X * Break;
X * Case '3':
X * Process %d type conversion (width 3).
X * Reinitialize output pointer.
X * Break;
X * Case '.'
X * Process %c type conversion.
X * Break;
X * Case '+':
X * Process %c type conversion with offset.
X * Break;
X * Case '>':
X * Process argument modification.
X * Break;
X * Case 'r':
X * Process argument reversal.
X * Break;
X * Case 'i':
X * Increment argument values.
X * Break;
X * Case '%':
X * Copy to output, incrementing pointers.
X * Break;
X * End switch
X * End process
X *
X */
X
X
Xstatic process()
X{
X int temp;
X
X in++;
X switch(*in++) {
X case 'd':
X sprintf(out,"%d",args[pcount++]);
X out = &output[strlen(output)];
X break;
X case '2':
X sprintf(out,"%02d",args[pcount++]);
X out += 2 ;
X/*
X out = &output[strlen(output)];
X*/
X break;
X case '3':
X sprintf(out,"%03d",args[pcount++]);
X out = &output[strlen(output)];
X break;
X case '.':
X *out++ = args[pcount++];
X break;
X case '+':
X *out++ = args[pcount++] + *in++;
X break;
X case '>':
X if (args[pcount] > *in++) {
X args[pcount] += *in++;
X } else {
X in++;
X }
X break;
X case 'r':
X temp = args[pcount];
X args[pcount] = args[pcount+1];
X args[pcount+1] = temp;
X break;
X case 'i':
X args[pcount]++;
X args[pcount+1]++;
X break;
X case '%':
X *out++ = '%';
X break;
X }
X}
END_OF_FILE
if test 6360 -ne `wc -c <'tgoto.c'`; then
echo shar: \"'tgoto.c'\" unpacked with wrong size!
fi
# end of 'tgoto.c'
fi
echo shar: End of archive 1 \(of 12\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 12 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