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