132222Sbostic /* main.c */ 232222Sbostic #include "header.h" 332222Sbostic #include <pwd.h> 432222Sbostic static char copyright[]="\nLarn is copyrighted 1986 by Noah Morgan.\n"; 532222Sbostic int srcount=0; /* line counter for showstr() */ 632222Sbostic int dropflag=0; /* if 1 then don't lookforobject() next round */ 732222Sbostic int rmst=80; /* random monster creation counter */ 832222Sbostic int userid; /* the players login user id number */ 932222Sbostic char nowelcome=0,nomove=0; /* if (nomove) then don't count next iteration as a move */ 1032222Sbostic static char viewflag=0; 1132222Sbostic /* if viewflag then we have done a 99 stay here and don't showcell in the main loop */ 1232222Sbostic char restorflag=0; /* 1 means restore has been done */ 1332222Sbostic static char cmdhelp[] = "\ 1432222Sbostic Cmd line format: larn [-slicnh] [-o<optsifle>] [-##] [++]\n\ 1532222Sbostic -s show the scoreboard\n\ 1632222Sbostic -l show the logfile (wizard id only)\n\ 1732222Sbostic -i show scoreboard with inventories of dead characters\n\ 1832222Sbostic -c create new scoreboard (wizard id only)\n\ 1932222Sbostic -n suppress welcome message on starting game\n\ 2032222Sbostic -## specify level of difficulty (example: -5)\n\ 2132222Sbostic -h print this help text\n\ 2232222Sbostic ++ restore game from checkpoint file\n\ 2332222Sbostic -o<optsfile> specify .larnopts filename to be used instead of \"~/.larnopts\"\n\ 2432222Sbostic "; 2532222Sbostic #ifdef VT100 2632222Sbostic static char *termtypes[] = { "vt100", "vt101", "vt102", "vt103", "vt125", 2732222Sbostic "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340", 2832222Sbostic "vt341" }; 2932222Sbostic #endif VT100 3032222Sbostic /* 3132222Sbostic ************ 3232222Sbostic MAIN PROGRAM 3332222Sbostic ************ 3432222Sbostic */ 3532222Sbostic main(argc,argv) 3632222Sbostic int argc; 3732222Sbostic char **argv; 3832222Sbostic { 3932222Sbostic register int i,j; 4032222Sbostic int hard; 4132222Sbostic char *ptr=0,*ttype; 4232222Sbostic struct passwd *pwe,*getpwuid(); 4332222Sbostic 4432222Sbostic /* 4532222Sbostic * first task is to identify the player 4632222Sbostic */ 4732222Sbostic #ifndef VT100 4832222Sbostic init_term(); /* setup the terminal (find out what type) for termcap */ 4932222Sbostic #endif VT100 5032222Sbostic if (((ptr = getlogin()) == 0) || (*ptr==0)) /* try to get login name */ 5132222Sbostic if (pwe=getpwuid(getuid())) /* can we get it from /etc/passwd? */ 5232222Sbostic ptr = pwe->pw_name; 5332222Sbostic else 5432222Sbostic if ((ptr = getenv("USER")) == 0) 5532222Sbostic if ((ptr = getenv("LOGNAME")) == 0) 5632222Sbostic { 5732222Sbostic noone: write(2, "Can't find your logname. Who Are You?\n",39); 5832222Sbostic exit(); 5932222Sbostic } 6032222Sbostic if (ptr==0) goto noone; 6132222Sbostic if (strlen(ptr)==0) goto noone; 6232222Sbostic /* 6332222Sbostic * second task is to prepare the pathnames the player will need 6432222Sbostic */ 6532222Sbostic strcpy(loginname,ptr); /* save loginname of the user for logging purposes */ 6632222Sbostic strcpy(logname,ptr); /* this will be overwritten with the players name */ 6732222Sbostic if ((ptr = getenv("HOME")) == 0) ptr = "."; 6832222Sbostic #ifdef SAVEINHOME 6932222Sbostic strcpy(savefilename, ptr); 7032222Sbostic strcat(savefilename, "/Larn.sav"); /* save file name in home directory */ 7132222Sbostic #else 7232222Sbostic strcat(savefilename,logname); /* prepare savefile name */ 7332222Sbostic strcat(savefilename,".sav"); /* prepare savefile name */ 7432222Sbostic #endif 7532222Sbostic sprintf(optsfile, "%s/.larnopts",ptr); /* the .larnopts filename */ 7632222Sbostic strcat(scorefile, SCORENAME); /* the larn scoreboard filename */ 7732222Sbostic strcat(logfile, LOGFNAME); /* larn activity logging filename */ 7832222Sbostic strcat(helpfile, HELPNAME); /* the larn on-line help file */ 7932222Sbostic strcat(larnlevels, LEVELSNAME); /* the pre-made cave level data file */ 8032222Sbostic strcat(fortfile, FORTSNAME); /* the fortune data file name */ 8132222Sbostic strcat(playerids, PLAYERIDS); /* the playerid data file name */ 8232222Sbostic strcat(holifile, HOLIFILE); /* the holiday data file name */ 8332222Sbostic 8432222Sbostic /* 8532222Sbostic * now malloc the memory for the dungeon 8632222Sbostic */ 8732222Sbostic cell = (struct cel *)malloc(sizeof(struct cel)*(MAXLEVEL+MAXVLEVEL)*MAXX*MAXY); 8832222Sbostic if (cell == 0) died(-285); /* malloc failure */ 8932222Sbostic lpbuf = malloc((5* BUFBIG)>>2); /* output buffer */ 9032222Sbostic inbuffer = malloc((5*MAXIBUF)>>2); /* output buffer */ 9132222Sbostic if ((lpbuf==0) || (inbuffer==0)) died(-285); /* malloc() failure */ 9232222Sbostic 9332222Sbostic lcreat((char*)0); newgame(); /* set the initial clock */ hard= -1; 9432222Sbostic 9532222Sbostic #ifdef VT100 9632222Sbostic /* 9732222Sbostic * check terminal type to avoid users who have not vt100 type terminals 9832222Sbostic */ 9932222Sbostic ttype = getenv("TERM"); 10032222Sbostic for (j=1, i=0; i<sizeof(termtypes)/sizeof(char *); i++) 10132222Sbostic if (strcmp(ttype,termtypes[i]) == 0) { j=0; break; } 10232222Sbostic if (j) 10332222Sbostic { 10432222Sbostic lprcat("Sorry, Larn needs a VT100 family terminal for all it's features.\n"); lflush(); 10532222Sbostic exit(); 10632222Sbostic } 10732222Sbostic #endif VT100 10832222Sbostic 10932222Sbostic /* 11032222Sbostic * now make scoreboard if it is not there (don't clear) 11132222Sbostic */ 112*32223Sbostic if (access(scorefile,0) == -1) /* not there */ 113*32223Sbostic makeboard(); 11432222Sbostic 11532222Sbostic /* 11632222Sbostic * now process the command line arguments 11732222Sbostic */ 11832222Sbostic for (i=1; i<argc; i++) 11932222Sbostic { 12032222Sbostic if (argv[i][0] == '-') 12132222Sbostic switch(argv[i][1]) 12232222Sbostic { 12332222Sbostic case 's': showscores(); exit(); /* show scoreboard */ 12432222Sbostic 12532222Sbostic case 'l': /* show log file */ 12632222Sbostic diedlog(); exit(); 12732222Sbostic 12832222Sbostic case 'i': showallscores(); exit(); /* show all scoreboard */ 12932222Sbostic 13032222Sbostic case 'c': /* anyone with password can create scoreboard */ 13132222Sbostic lprcat("Preparing to initialize the scoreboard.\n"); 13232222Sbostic if (getpassword() != 0) /*make new scoreboard*/ 13332222Sbostic { 13432222Sbostic makeboard(); lprc('\n'); showscores(); 13532222Sbostic } 13632222Sbostic exit(); 13732222Sbostic 13832222Sbostic case 'n': /* no welcome msg */ nowelcome=1; argv[i][0]=0; break; 13932222Sbostic 14032222Sbostic case '0': case '1': case '2': case '3': case '4': case '5': 14132222Sbostic case '6': case '7': case '8': case '9': /* for hardness */ 14232222Sbostic sscanf(&argv[i][1],"%d",&hard); 14332222Sbostic break; 14432222Sbostic 14532222Sbostic case 'h': /* print out command line arguments */ 14632222Sbostic write(1,cmdhelp,sizeof(cmdhelp)); exit(); 14732222Sbostic 14832222Sbostic case 'o': /* specify a .larnopts filename */ 14932222Sbostic strncpy(optsfile,argv[i]+2,127); break; 15032222Sbostic 15132222Sbostic default: printf("Unknown option <%s>\n",argv[i]); exit(); 15232222Sbostic }; 15332222Sbostic 15432222Sbostic if (argv[i][0] == '+') 15532222Sbostic { 15632222Sbostic clear(); restorflag = 1; 15732222Sbostic if (argv[i][1] == '+') 15832222Sbostic { 15932222Sbostic hitflag=1; restoregame(ckpfile); /* restore checkpointed game */ 16032222Sbostic } 16132222Sbostic i = argc; 16232222Sbostic } 16332222Sbostic } 16432222Sbostic 16532222Sbostic readopts(); /* read the options file if there is one */ 16632222Sbostic 16732222Sbostic #ifdef TIMECHECK 16832222Sbostic /* 16932222Sbostic * this section of code checks to see if larn is allowed during working hours 17032222Sbostic */ 17132222Sbostic if (dayplay==0) /* check for not-during-daytime-hours */ 17232222Sbostic if (playable()) 17332222Sbostic { 17432222Sbostic write(2,"Sorry, Larn can not be played during working hours.\n",52); 17532222Sbostic exit(); 17632222Sbostic } 17732222Sbostic #endif TIMECHECK 17832222Sbostic 17932222Sbostic #ifdef UIDSCORE 18032222Sbostic userid = geteuid(); /* obtain the user's effective id number */ 18132222Sbostic #else UIDSCORE 18232222Sbostic userid = getplid(logname); /* obtain the players id number */ 18332222Sbostic #endif UIDSCORE 18432222Sbostic if (userid < 0) { write(2,"Can't obtain playerid\n",22); exit(); } 18532222Sbostic 18632222Sbostic #ifdef HIDEBYLINK 18732222Sbostic /* 18832222Sbostic * this section of code causes the program to look like something else to ps 18932222Sbostic */ 19032222Sbostic if (strcmp(psname,argv[0])) /* if a different process name only */ 19132222Sbostic { 19232222Sbostic if ((i=access(psname,1)) < 0) 19332222Sbostic { /* link not there */ 19432222Sbostic if (link(argv[0],psname)>=0) 19532222Sbostic { 19632222Sbostic argv[0] = psname; execv(psname,argv); 19732222Sbostic } 19832222Sbostic } 19932222Sbostic else 20032222Sbostic unlink(psname); 20132222Sbostic } 20232222Sbostic 20332222Sbostic for (i=1; i<argc; i++) 20432222Sbostic { 20532222Sbostic szero(argv[i]); /* zero the argument to avoid ps snooping */ 20632222Sbostic } 20732222Sbostic #endif HIDEBYLINK 20832222Sbostic 20932222Sbostic if (access(savefilename,0)==0) /* restore game if need to */ 21032222Sbostic { 21132222Sbostic clear(); restorflag = 1; 21232222Sbostic hitflag=1; restoregame(savefilename); /* restore last game */ 21332222Sbostic } 21432222Sbostic sigsetup(); /* trap all needed signals */ 21532222Sbostic sethard(hard); /* set up the desired difficulty */ 21632222Sbostic setupvt100(); /* setup the terminal special mode */ 21732222Sbostic if (c[HP]==0) /* create new game */ 21832222Sbostic { 21932222Sbostic makeplayer(); /* make the character that will play */ 22032222Sbostic newcavelevel(0);/* make the dungeon */ 22132222Sbostic predostuff = 1; /* tell signals that we are in the welcome screen */ 22232222Sbostic if (nowelcome==0) welcome(); /* welcome the player to the game */ 22332222Sbostic } 22432222Sbostic drawscreen(); /* show the initial dungeon */ 22532222Sbostic predostuff = 2; /* tell the trap functions that they must do a showplayer() 22632222Sbostic from here on */ 22732222Sbostic /* nice(1); /* games should be run niced */ 22832222Sbostic yrepcount = hit2flag = 0; 22932222Sbostic while (1) 23032222Sbostic { 23132222Sbostic if (dropflag==0) lookforobject(); /* see if there is an object here */ 23232222Sbostic else dropflag=0; /* don't show it just dropped an item */ 23332222Sbostic if (hitflag==0) { if (c[HASTEMONST]) movemonst(); movemonst(); } /* move the monsters */ 23432222Sbostic if (viewflag==0) showcell(playerx,playery); else viewflag=0; /* show stuff around player */ 23532222Sbostic if (hit3flag) flushall(); 23632222Sbostic hitflag=hit3flag=0; nomove=1; 23732222Sbostic bot_linex(); /* update bottom line */ 23832222Sbostic while (nomove) 23932222Sbostic { 24032222Sbostic if (hit3flag) flushall(); 24132222Sbostic nomove=0; parse(); 24232222Sbostic } /* get commands and make moves */ 24332222Sbostic regen(); /* regenerate hp and spells */ 24432222Sbostic if (c[TIMESTOP]==0) 24532222Sbostic if (--rmst <= 0) 24632222Sbostic { rmst = 120-(level<<2); fillmonst(makemonst(level)); } 24732222Sbostic } 24832222Sbostic } 24932222Sbostic 25032222Sbostic /* 25132222Sbostic showstr() 25232222Sbostic 25332222Sbostic show character's inventory 25432222Sbostic */ 25532222Sbostic showstr() 25632222Sbostic { 25732222Sbostic register int i,number; 25832222Sbostic for (number=3, i=0; i<26; i++) 25932222Sbostic if (iven[i]) number++; /* count items in inventory */ 26032222Sbostic t_setup(number); qshowstr(); t_endup(number); 26132222Sbostic } 26232222Sbostic 26332222Sbostic qshowstr() 26432222Sbostic { 26532222Sbostic register int i,j,k,sigsav; 26632222Sbostic srcount=0; sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ 26732222Sbostic if (c[GOLD]) { lprintf(".) %d gold pieces",(long)c[GOLD]); srcount++; } 26832222Sbostic for (k=26; k>=0; k--) 26932222Sbostic if (iven[k]) 27032222Sbostic { for (i=22; i<84; i++) 27132222Sbostic for (j=0; j<=k; j++) if (i==iven[j]) show3(j); k=0; } 27232222Sbostic 27332222Sbostic lprintf("\nElapsed time is %d. You have %d mobuls left",(long)((gtime+99)/100+1),(long)((TIMELIMIT-gtime)/100)); 27432222Sbostic more(); nosignal=sigsav; 27532222Sbostic } 27632222Sbostic 27732222Sbostic /* 27832222Sbostic * subroutine to clear screen depending on # lines to display 27932222Sbostic */ 28032222Sbostic t_setup(count) 28132222Sbostic register int count; 28232222Sbostic { 28332222Sbostic if (count<20) /* how do we clear the screen? */ 28432222Sbostic { 28532222Sbostic cl_up(79,count); cursor(1,1); 28632222Sbostic } 28732222Sbostic else 28832222Sbostic { 28932222Sbostic resetscroll(); clear(); 29032222Sbostic } 29132222Sbostic } 29232222Sbostic 29332222Sbostic /* 29432222Sbostic * subroutine to restore normal display screen depending on t_setup() 29532222Sbostic */ 29632222Sbostic t_endup(count) 29732222Sbostic register int count; 29832222Sbostic { 29932222Sbostic if (count<18) /* how did we clear the screen? */ 30032222Sbostic draws(0,MAXX,0,(count>MAXY) ? MAXY : count); 30132222Sbostic else 30232222Sbostic { 30332222Sbostic drawscreen(); setscroll(); 30432222Sbostic } 30532222Sbostic } 30632222Sbostic 30732222Sbostic /* 30832222Sbostic function to show the things player is wearing only 30932222Sbostic */ 31032222Sbostic showwear() 31132222Sbostic { 31232222Sbostic register int i,j,sigsav,count; 31332222Sbostic sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ 31432222Sbostic srcount=0; 31532222Sbostic 31632222Sbostic for (count=2,j=0; j<=26; j++) /* count number of items we will display */ 31732222Sbostic if (i=iven[j]) 31832222Sbostic switch(i) 31932222Sbostic { 32032222Sbostic case OLEATHER: case OPLATE: case OCHAIN: 32132222Sbostic case ORING: case OSTUDLEATHER: case OSPLINT: 32232222Sbostic case OPLATEARMOR: case OSSPLATE: case OSHIELD: 32332222Sbostic count++; 32432222Sbostic }; 32532222Sbostic 32632222Sbostic t_setup(count); 32732222Sbostic 32832222Sbostic for (i=22; i<84; i++) 32932222Sbostic for (j=0; j<=26; j++) 33032222Sbostic if (i==iven[j]) 33132222Sbostic switch(i) 33232222Sbostic { 33332222Sbostic case OLEATHER: case OPLATE: case OCHAIN: 33432222Sbostic case ORING: case OSTUDLEATHER: case OSPLINT: 33532222Sbostic case OPLATEARMOR: case OSSPLATE: case OSHIELD: 33632222Sbostic show3(j); 33732222Sbostic }; 33832222Sbostic more(); nosignal=sigsav; t_endup(count); 33932222Sbostic } 34032222Sbostic 34132222Sbostic /* 34232222Sbostic function to show the things player can wield only 34332222Sbostic */ 34432222Sbostic showwield() 34532222Sbostic { 34632222Sbostic register int i,j,sigsav,count; 34732222Sbostic sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ 34832222Sbostic srcount=0; 34932222Sbostic 35032222Sbostic for (count=2,j=0; j<=26; j++) /* count how many items */ 35132222Sbostic if (i=iven[j]) 35232222Sbostic switch(i) 35332222Sbostic { 35432222Sbostic case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE: 35532222Sbostic case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT: 35632222Sbostic case OSPIRITSCARAB: case OCUBEofUNDEAD: 35732222Sbostic case OPOTION: case OSCROLL: break; 35832222Sbostic default: count++; 35932222Sbostic }; 36032222Sbostic 36132222Sbostic t_setup(count); 36232222Sbostic 36332222Sbostic for (i=22; i<84; i++) 36432222Sbostic for (j=0; j<=26; j++) 36532222Sbostic if (i==iven[j]) 36632222Sbostic switch(i) 36732222Sbostic { 36832222Sbostic case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE: 36932222Sbostic case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT: 37032222Sbostic case OSPIRITSCARAB: case OCUBEofUNDEAD: 37132222Sbostic case OPOTION: case OSCROLL: break; 37232222Sbostic default: show3(j); 37332222Sbostic }; 37432222Sbostic more(); nosignal=sigsav; t_endup(count); 37532222Sbostic } 37632222Sbostic 37732222Sbostic /* 37832222Sbostic * function to show the things player can read only 37932222Sbostic */ 38032222Sbostic showread() 38132222Sbostic { 38232222Sbostic register int i,j,sigsav,count; 38332222Sbostic sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ 38432222Sbostic srcount=0; 38532222Sbostic 38632222Sbostic for (count=2,j=0; j<=26; j++) 38732222Sbostic switch(iven[j]) 38832222Sbostic { 38932222Sbostic case OBOOK: case OSCROLL: count++; 39032222Sbostic }; 39132222Sbostic t_setup(count); 39232222Sbostic 39332222Sbostic for (i=22; i<84; i++) 39432222Sbostic for (j=0; j<=26; j++) 39532222Sbostic if (i==iven[j]) 39632222Sbostic switch(i) 39732222Sbostic { 39832222Sbostic case OBOOK: case OSCROLL: show3(j); 39932222Sbostic }; 40032222Sbostic more(); nosignal=sigsav; t_endup(count); 40132222Sbostic } 40232222Sbostic 40332222Sbostic /* 40432222Sbostic * function to show the things player can eat only 40532222Sbostic */ 40632222Sbostic showeat() 40732222Sbostic { 40832222Sbostic register int i,j,sigsav,count; 40932222Sbostic sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ 41032222Sbostic srcount=0; 41132222Sbostic 41232222Sbostic for (count=2,j=0; j<=26; j++) 41332222Sbostic switch(iven[j]) 41432222Sbostic { 41532222Sbostic case OCOOKIE: count++; 41632222Sbostic }; 41732222Sbostic t_setup(count); 41832222Sbostic 41932222Sbostic for (i=22; i<84; i++) 42032222Sbostic for (j=0; j<=26; j++) 42132222Sbostic if (i==iven[j]) 42232222Sbostic switch(i) 42332222Sbostic { 42432222Sbostic case OCOOKIE: show3(j); 42532222Sbostic }; 42632222Sbostic more(); nosignal=sigsav; t_endup(count); 42732222Sbostic } 42832222Sbostic 42932222Sbostic /* 43032222Sbostic function to show the things player can quaff only 43132222Sbostic */ 43232222Sbostic showquaff() 43332222Sbostic { 43432222Sbostic register int i,j,sigsav,count; 43532222Sbostic sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ 43632222Sbostic srcount=0; 43732222Sbostic 43832222Sbostic for (count=2,j=0; j<=26; j++) 43932222Sbostic switch(iven[j]) 44032222Sbostic { 44132222Sbostic case OPOTION: count++; 44232222Sbostic }; 44332222Sbostic t_setup(count); 44432222Sbostic 44532222Sbostic for (i=22; i<84; i++) 44632222Sbostic for (j=0; j<=26; j++) 44732222Sbostic if (i==iven[j]) 44832222Sbostic switch(i) 44932222Sbostic { 45032222Sbostic case OPOTION: show3(j); 45132222Sbostic }; 45232222Sbostic more(); nosignal=sigsav; t_endup(count); 45332222Sbostic } 45432222Sbostic 45532222Sbostic show1(idx,str2) 45632222Sbostic register int idx; 45732222Sbostic register char *str2[]; 45832222Sbostic { 45932222Sbostic if (str2==0) lprintf("\n%c) %s",idx+'a',objectname[iven[idx]]); 46032222Sbostic else if (*str2[ivenarg[idx]]==0) lprintf("\n%c) %s",idx+'a',objectname[iven[idx]]); 46132222Sbostic else lprintf("\n%c) %s of%s",idx+'a',objectname[iven[idx]],str2[ivenarg[idx]]); 46232222Sbostic } 46332222Sbostic 46432222Sbostic show3(index) 46532222Sbostic register int index; 46632222Sbostic { 46732222Sbostic switch(iven[index]) 46832222Sbostic { 46932222Sbostic case OPOTION: show1(index,potionname); break; 47032222Sbostic case OSCROLL: show1(index,scrollname); break; 47132222Sbostic 47232222Sbostic case OLARNEYE: case OBOOK: case OSPIRITSCARAB: 47332222Sbostic case ODIAMOND: case ORUBY: case OCUBEofUNDEAD: 47432222Sbostic case OEMERALD: case OCHEST: case OCOOKIE: 47532222Sbostic case OSAPPHIRE: case ONOTHEFT: show1(index,(char **)0); break; 47632222Sbostic 47732222Sbostic default: lprintf("\n%c) %s",index+'a',objectname[iven[index]]); 47832222Sbostic if (ivenarg[index]>0) lprintf(" + %d",(long)ivenarg[index]); 47932222Sbostic else if (ivenarg[index]<0) lprintf(" %d",(long)ivenarg[index]); 48032222Sbostic break; 48132222Sbostic } 48232222Sbostic if (c[WIELD]==index) lprcat(" (weapon in hand)"); 48332222Sbostic if ((c[WEAR]==index) || (c[SHIELD]==index)) lprcat(" (being worn)"); 48432222Sbostic if (++srcount>=22) { srcount=0; more(); clear(); } 48532222Sbostic } 48632222Sbostic 48732222Sbostic /* 48832222Sbostic subroutine to randomly create monsters if needed 48932222Sbostic */ 49032222Sbostic randmonst() 49132222Sbostic { 49232222Sbostic if (c[TIMESTOP]) return; /* don't make monsters if time is stopped */ 49332222Sbostic if (--rmst <= 0) 49432222Sbostic { 49532222Sbostic rmst = 120 - (level<<2); fillmonst(makemonst(level)); 49632222Sbostic } 49732222Sbostic } 49832222Sbostic 49932222Sbostic 50032222Sbostic /* 50132222Sbostic parse() 50232222Sbostic 50332222Sbostic get and execute a command 50432222Sbostic */ 50532222Sbostic parse() 50632222Sbostic { 50732222Sbostic register int i,j,k,flag; 50832222Sbostic while (1) 50932222Sbostic { 51032222Sbostic k = yylex(); 51132222Sbostic switch(k) /* get the token from the input and switch on it */ 51232222Sbostic { 51332222Sbostic case 'h': moveplayer(4); return; /* west */ 51432222Sbostic case 'H': run(4); return; /* west */ 51532222Sbostic case 'l': moveplayer(2); return; /* east */ 51632222Sbostic case 'L': run(2); return; /* east */ 51732222Sbostic case 'j': moveplayer(1); return; /* south */ 51832222Sbostic case 'J': run(1); return; /* south */ 51932222Sbostic case 'k': moveplayer(3); return; /* north */ 52032222Sbostic case 'K': run(3); return; /* north */ 52132222Sbostic case 'u': moveplayer(5); return; /* northeast */ 52232222Sbostic case 'U': run(5); return; /* northeast */ 52332222Sbostic case 'y': moveplayer(6); return; /* northwest */ 52432222Sbostic case 'Y': run(6); return; /* northwest */ 52532222Sbostic case 'n': moveplayer(7); return; /* southeast */ 52632222Sbostic case 'N': run(7); return; /* southeast */ 52732222Sbostic case 'b': moveplayer(8); return; /* southwest */ 52832222Sbostic case 'B': run(8); return; /* southwest */ 52932222Sbostic 53032222Sbostic case '.': if (yrepcount) viewflag=1; return; /* stay here */ 53132222Sbostic 53232222Sbostic case 'w': yrepcount=0; wield(); return; /* wield a weapon */ 53332222Sbostic 53432222Sbostic case 'W': yrepcount=0; wear(); return; /* wear armor */ 53532222Sbostic 53632222Sbostic case 'r': yrepcount=0; 53732222Sbostic if (c[BLINDCOUNT]) { cursors(); lprcat("\nYou can't read anything when you're blind!"); } else 53832222Sbostic if (c[TIMESTOP]==0) readscr(); return; /* to read a scroll */ 53932222Sbostic 54032222Sbostic case 'q': yrepcount=0; if (c[TIMESTOP]==0) quaff(); return; /* quaff a potion */ 54132222Sbostic 54232222Sbostic case 'd': yrepcount=0; if (c[TIMESTOP]==0) dropobj(); return; /* to drop an object */ 54332222Sbostic 54432222Sbostic case 'c': yrepcount=0; cast(); return; /* cast a spell */ 54532222Sbostic 54632222Sbostic case 'i': yrepcount=0; nomove=1; showstr(); return; /* status */ 54732222Sbostic 54832222Sbostic case 'e': yrepcount=0; 54932222Sbostic if (c[TIMESTOP]==0) eatcookie(); return; /* to eat a fortune cookie */ 55032222Sbostic 55132222Sbostic case 'D': yrepcount=0; seemagic(0); nomove=1; return; /* list spells and scrolls */ 55232222Sbostic 55332222Sbostic case '?': yrepcount=0; help(); nomove=1; return; /* give the help screen*/ 55432222Sbostic 55532222Sbostic case 'S': clear(); lprcat("Saving . . ."); lflush(); 55632222Sbostic savegame(savefilename); wizard=1; died(-257); /* save the game - doesn't return */ 55732222Sbostic 55832222Sbostic case 'Z': yrepcount=0; if (c[LEVEL]>9) { oteleport(1); return; } 55932222Sbostic cursors(); lprcat("\nAs yet, you don't have enough experience to use teleportation"); 56032222Sbostic return; /* teleport yourself */ 56132222Sbostic 56232222Sbostic case '^': /* identify traps */ flag=yrepcount=0; cursors(); 56332222Sbostic lprc('\n'); for (j=playery-1; j<playery+2; j++) 56432222Sbostic { 56532222Sbostic if (j < 0) j=0; if (j >= MAXY) break; 56632222Sbostic for (i=playerx-1; i<playerx+2; i++) 56732222Sbostic { 56832222Sbostic if (i < 0) i=0; if (i >= MAXX) break; 56932222Sbostic switch(item[i][j]) 57032222Sbostic { 57132222Sbostic case OTRAPDOOR: case ODARTRAP: 57232222Sbostic case OTRAPARROW: case OTELEPORTER: 57332222Sbostic lprcat("\nIts "); lprcat(objectname[item[i][j]]); flag++; 57432222Sbostic }; 57532222Sbostic } 57632222Sbostic } 57732222Sbostic if (flag==0) lprcat("\nNo traps are visible"); 57832222Sbostic return; 57932222Sbostic 58032222Sbostic #if WIZID 58132222Sbostic case '_': /* this is the fudge player password for wizard mode*/ 58232222Sbostic yrepcount=0; cursors(); nomove=1; 58332222Sbostic if (userid!=wisid) 58432222Sbostic { 58532222Sbostic lprcat("Sorry, you are not empowered to be a wizard.\n"); 58632222Sbostic scbr(); /* system("stty -echo cbreak"); */ 58732222Sbostic lflush(); return; 58832222Sbostic } 58932222Sbostic if (getpassword()==0) 59032222Sbostic { 59132222Sbostic scbr(); /* system("stty -echo cbreak"); */ return; 59232222Sbostic } 59332222Sbostic wizard=1; scbr(); /* system("stty -echo cbreak"); */ 59432222Sbostic for (i=0; i<6; i++) c[i]=70; iven[0]=iven[1]=0; 59532222Sbostic take(OPROTRING,50); take(OLANCE,25); c[WIELD]=1; 59632222Sbostic c[LANCEDEATH]=1; c[WEAR] = c[SHIELD] = -1; 59732222Sbostic raiseexperience(6000000L); c[AWARENESS] += 25000; 59832222Sbostic { 59932222Sbostic register int i,j; 60032222Sbostic for (i=0; i<MAXY; i++) 60132222Sbostic for (j=0; j<MAXX; j++) know[j][i]=1; 60232222Sbostic for (i=0; i<SPNUM; i++) spelknow[i]=1; 60332222Sbostic for (i=0; i<MAXSCROLL; i++) scrollname[i][0]=' '; 60432222Sbostic for (i=0; i<MAXPOTION; i++) potionname[i][0]=' '; 60532222Sbostic } 60632222Sbostic for (i=0; i<MAXSCROLL; i++) 60732222Sbostic if (strlen(scrollname[i])>2) /* no null items */ 60832222Sbostic { item[i][0]=OSCROLL; iarg[i][0]=i; } 60932222Sbostic for (i=MAXX-1; i>MAXX-1-MAXPOTION; i--) 61032222Sbostic if (strlen(potionname[i-MAXX+MAXPOTION])>2) /* no null items */ 61132222Sbostic { item[i][0]=OPOTION; iarg[i][0]=i-MAXX+MAXPOTION; } 61232222Sbostic for (i=1; i<MAXY; i++) 61332222Sbostic { item[0][i]=i; iarg[0][i]=0; } 61432222Sbostic for (i=MAXY; i<MAXY+MAXX; i++) 61532222Sbostic { item[i-MAXY][MAXY-1]=i; iarg[i-MAXY][MAXY-1]=0; } 61632222Sbostic for (i=MAXX+MAXY; i<MAXX+MAXY+MAXY; i++) 61732222Sbostic { item[MAXX-1][i-MAXX-MAXY]=i; iarg[MAXX-1][i-MAXX-MAXY]=0; } 61832222Sbostic c[GOLD]+=25000; drawscreen(); return; 61932222Sbostic #endif 62032222Sbostic 62132222Sbostic case 'T': yrepcount=0; cursors(); if (c[SHIELD] != -1) { c[SHIELD] = -1; lprcat("\nYour shield is off"); bottomline(); } else 62232222Sbostic if (c[WEAR] != -1) { c[WEAR] = -1; lprcat("\nYour armor is off"); bottomline(); } 62332222Sbostic else lprcat("\nYou aren't wearing anything"); 62432222Sbostic return; 62532222Sbostic 62632222Sbostic case 'g': cursors(); 62732222Sbostic lprintf("\nThe stuff you are carrying presently weighs %d pounds",(long)packweight()); 62832222Sbostic case ' ': yrepcount=0; nomove=1; return; 62932222Sbostic 63032222Sbostic case 'v': yrepcount=0; cursors(); 63132222Sbostic lprintf("\nCaverns of Larn, Version %d.%d, Diff=%d",(long)VERSION,(long)SUBVERSION,(long)c[HARDGAME]); 63232222Sbostic if (wizard) lprcat(" Wizard"); nomove=1; 63332222Sbostic if (cheat) lprcat(" Cheater"); 63432222Sbostic lprcat(copyright); 63532222Sbostic return; 63632222Sbostic 63732222Sbostic case 'Q': yrepcount=0; quit(); nomove=1; return; /* quit */ 63832222Sbostic 63932222Sbostic case 'L'-64: yrepcount=0; drawscreen(); nomove=1; return; /* look */ 64032222Sbostic 64132222Sbostic #if WIZID 64232222Sbostic #ifdef EXTRA 64332222Sbostic case 'A': yrepcount=0; nomove=1; if (wizard) { diag(); return; } /* create diagnostic file */ 64432222Sbostic return; 64532222Sbostic #endif 64632222Sbostic #endif 64732222Sbostic case 'P': cursors(); 64832222Sbostic if (outstanding_taxes>0) 64932222Sbostic lprintf("\nYou presently owe %d gp in taxes.",(long)outstanding_taxes); 65032222Sbostic else 65132222Sbostic lprcat("\nYou do not owe any taxes."); 65232222Sbostic return; 65332222Sbostic }; 65432222Sbostic } 65532222Sbostic } 65632222Sbostic 65732222Sbostic parse2() 65832222Sbostic { 65932222Sbostic if (c[HASTEMONST]) movemonst(); movemonst(); /* move the monsters */ 66032222Sbostic randmonst(); regen(); 66132222Sbostic } 66232222Sbostic 66332222Sbostic run(dir) 66432222Sbostic int dir; 66532222Sbostic { 66632222Sbostic register int i; 66732222Sbostic i=1; while (i) 66832222Sbostic { 66932222Sbostic i=moveplayer(dir); 67032222Sbostic if (i>0) { if (c[HASTEMONST]) movemonst(); movemonst(); randmonst(); regen(); } 67132222Sbostic if (hitflag) i=0; 67232222Sbostic if (i!=0) showcell(playerx,playery); 67332222Sbostic } 67432222Sbostic } 67532222Sbostic 67632222Sbostic /* 67732222Sbostic function to wield a weapon 67832222Sbostic */ 67932222Sbostic wield() 68032222Sbostic { 68132222Sbostic register int i; 68232222Sbostic while (1) 68332222Sbostic { 68432222Sbostic if ((i = whatitem("wield"))=='\33') return; 68532222Sbostic if (i != '.') 68632222Sbostic { 68732222Sbostic if (i=='*') showwield(); 68832222Sbostic else if (iven[i-'a']==0) { ydhi(i); return; } 68932222Sbostic else if (iven[i-'a']==OPOTION) { ycwi(i); return; } 69032222Sbostic else if (iven[i-'a']==OSCROLL) { ycwi(i); return; } 69132222Sbostic else if ((c[SHIELD]!= -1) && (iven[i-'a']==O2SWORD)) { lprcat("\nBut one arm is busy with your shield!"); return; } 69232222Sbostic else { c[WIELD]=i-'a'; if (iven[i-'a'] == OLANCE) c[LANCEDEATH]=1; else c[LANCEDEATH]=0; bottomline(); return; } 69332222Sbostic } 69432222Sbostic } 69532222Sbostic } 69632222Sbostic 69732222Sbostic /* 69832222Sbostic common routine to say you don't have an item 69932222Sbostic */ 70032222Sbostic ydhi(x) 70132222Sbostic int x; 70232222Sbostic { cursors(); lprintf("\nYou don't have item %c!",x); } 70332222Sbostic ycwi(x) 70432222Sbostic int x; 70532222Sbostic { cursors(); lprintf("\nYou can't wield item %c!",x); } 70632222Sbostic 70732222Sbostic /* 70832222Sbostic function to wear armor 70932222Sbostic */ 71032222Sbostic wear() 71132222Sbostic { 71232222Sbostic register int i; 71332222Sbostic while (1) 71432222Sbostic { 71532222Sbostic if ((i = whatitem("wear"))=='\33') return; 71632222Sbostic if (i != '.') 71732222Sbostic { 71832222Sbostic if (i=='*') showwear(); else 71932222Sbostic switch(iven[i-'a']) 72032222Sbostic { 72132222Sbostic case 0: ydhi(i); return; 72232222Sbostic case OLEATHER: case OCHAIN: case OPLATE: case OSTUDLEATHER: 72332222Sbostic case ORING: case OSPLINT: case OPLATEARMOR: case OSSPLATE: 72432222Sbostic if (c[WEAR] != -1) { lprcat("\nYou're already wearing some armor"); return; } 72532222Sbostic c[WEAR]=i-'a'; bottomline(); return; 72632222Sbostic case OSHIELD: if (c[SHIELD] != -1) { lprcat("\nYou are already wearing a shield"); return; } 72732222Sbostic if (iven[c[WIELD]]==O2SWORD) { lprcat("\nYour hands are busy with the two handed sword!"); return; } 72832222Sbostic c[SHIELD] = i-'a'; bottomline(); return; 72932222Sbostic default: lprcat("\nYou can't wear that!"); 73032222Sbostic }; 73132222Sbostic } 73232222Sbostic } 73332222Sbostic } 73432222Sbostic 73532222Sbostic /* 73632222Sbostic function to drop an object 73732222Sbostic */ 73832222Sbostic dropobj() 73932222Sbostic { 74032222Sbostic register int i; 74132222Sbostic register char *p; 74232222Sbostic long amt; 74332222Sbostic p = &item[playerx][playery]; 74432222Sbostic while (1) 74532222Sbostic { 74632222Sbostic if ((i = whatitem("drop"))=='\33') return; 74732222Sbostic if (i=='*') showstr(); else 74832222Sbostic { 74932222Sbostic if (i=='.') /* drop some gold */ 75032222Sbostic { 75132222Sbostic if (*p) { lprcat("\nThere's something here already!"); return; } 75232222Sbostic lprcat("\n\n"); 75332222Sbostic cl_dn(1,23); 75432222Sbostic lprcat("How much gold do you drop? "); 75532222Sbostic if ((amt=readnum((long)c[GOLD])) == 0) return; 75632222Sbostic if (amt>c[GOLD]) 75732222Sbostic { lprcat("\nYou don't have that much!"); return; } 75832222Sbostic if (amt<=32767) 75932222Sbostic { *p=OGOLDPILE; i=amt; } 76032222Sbostic else if (amt<=327670L) 76132222Sbostic { *p=ODGOLD; i=amt/10; amt = 10*i; } 76232222Sbostic else if (amt<=3276700L) 76332222Sbostic { *p=OMAXGOLD; i=amt/100; amt = 100*i; } 76432222Sbostic else if (amt<=32767000L) 76532222Sbostic { *p=OKGOLD; i=amt/1000; amt = 1000*i; } 76632222Sbostic else 76732222Sbostic { *p=OKGOLD; i=32767; amt = 32767000L; } 76832222Sbostic c[GOLD] -= amt; 76932222Sbostic lprintf("You drop %d gold pieces",(long)amt); 77032222Sbostic iarg[playerx][playery]=i; bottomgold(); 77132222Sbostic know[playerx][playery]=0; dropflag=1; return; 77232222Sbostic } 77332222Sbostic drop_object(i-'a'); 77432222Sbostic return; 77532222Sbostic } 77632222Sbostic } 77732222Sbostic } 77832222Sbostic 77932222Sbostic /* 78032222Sbostic * readscr() Subroutine to read a scroll one is carrying 78132222Sbostic */ 78232222Sbostic readscr() 78332222Sbostic { 78432222Sbostic register int i; 78532222Sbostic while (1) 78632222Sbostic { 78732222Sbostic if ((i = whatitem("read"))=='\33') return; 78832222Sbostic if (i != '.') 78932222Sbostic { 79032222Sbostic if (i=='*') showread(); else 79132222Sbostic { 79232222Sbostic if (iven[i-'a']==OSCROLL) { read_scroll(ivenarg[i-'a']); iven[i-'a']=0; return; } 79332222Sbostic if (iven[i-'a']==OBOOK) { readbook(ivenarg[i-'a']); iven[i-'a']=0; return; } 79432222Sbostic if (iven[i-'a']==0) { ydhi(i); return; } 79532222Sbostic lprcat("\nThere's nothing on it to read"); return; 79632222Sbostic } 79732222Sbostic } 79832222Sbostic } 79932222Sbostic } 80032222Sbostic 80132222Sbostic /* 80232222Sbostic * subroutine to eat a cookie one is carrying 80332222Sbostic */ 80432222Sbostic eatcookie() 80532222Sbostic { 80632222Sbostic register int i; 80732222Sbostic char *p; 80832222Sbostic while (1) 80932222Sbostic { 81032222Sbostic if ((i = whatitem("eat"))=='\33') return; 81132222Sbostic if (i != '.') 81232222Sbostic if (i=='*') showeat(); else 81332222Sbostic { 81432222Sbostic if (iven[i-'a']==OCOOKIE) 81532222Sbostic { 81632222Sbostic lprcat("\nThe cookie was delicious."); 81732222Sbostic iven[i-'a']=0; 81832222Sbostic if (!c[BLINDCOUNT]) 81932222Sbostic { 82032222Sbostic if (p=fortune(fortfile)) 82132222Sbostic { 82232222Sbostic lprcat(" Inside you find a scrap of paper that says:\n"); 82332222Sbostic lprcat(p); 82432222Sbostic } 82532222Sbostic } 82632222Sbostic return; 82732222Sbostic } 82832222Sbostic if (iven[i-'a']==0) { ydhi(i); return; } 82932222Sbostic lprcat("\nYou can't eat that!"); return; 83032222Sbostic } 83132222Sbostic } 83232222Sbostic } 83332222Sbostic 83432222Sbostic /* 83532222Sbostic * subroutine to quaff a potion one is carrying 83632222Sbostic */ 83732222Sbostic quaff() 83832222Sbostic { 83932222Sbostic register int i; 84032222Sbostic while (1) 84132222Sbostic { 84232222Sbostic if ((i = whatitem("quaff"))=='\33') return; 84332222Sbostic if (i != '.') 84432222Sbostic { 84532222Sbostic if (i=='*') showquaff(); else 84632222Sbostic { 84732222Sbostic if (iven[i-'a']==OPOTION) { quaffpotion(ivenarg[i-'a']); iven[i-'a']=0; return; } 84832222Sbostic if (iven[i-'a']==0) { ydhi(i); return; } 84932222Sbostic lprcat("\nYou wouldn't want to quaff that, would you? "); return; 85032222Sbostic } 85132222Sbostic } 85232222Sbostic } 85332222Sbostic } 85432222Sbostic 85532222Sbostic /* 85632222Sbostic function to ask what player wants to do 85732222Sbostic */ 85832222Sbostic whatitem(str) 85932222Sbostic char *str; 86032222Sbostic { 86132222Sbostic int i; 86232222Sbostic cursors(); lprintf("\nWhat do you want to %s [* for all] ? ",str); 86332222Sbostic i=0; while (i>'z' || (i<'a' && i!='*' && i!='\33' && i!='.')) i=getchar(); 86432222Sbostic if (i=='\33') lprcat(" aborted"); 86532222Sbostic return(i); 86632222Sbostic } 86732222Sbostic 86832222Sbostic /* 86932222Sbostic subroutine to get a number from the player 87032222Sbostic and allow * to mean return amt, else return the number entered 87132222Sbostic */ 87232222Sbostic unsigned long readnum(mx) 87332222Sbostic long mx; 87432222Sbostic { 87532222Sbostic register int i; 87632222Sbostic register unsigned long amt=0; 87732222Sbostic sncbr(); 87832222Sbostic if ((i=getchar()) == '*') amt = mx; /* allow him to say * for all gold */ 87932222Sbostic else 88032222Sbostic while (i != '\n') 88132222Sbostic { 88232222Sbostic if (i=='\033') { scbr(); lprcat(" aborted"); return(0); } 88332222Sbostic if ((i <= '9') && (i >= '0') && (amt<99999999)) 88432222Sbostic amt = amt*10+i-'0'; 88532222Sbostic i = getchar(); 88632222Sbostic } 88732222Sbostic scbr(); return(amt); 88832222Sbostic } 88932222Sbostic 89032222Sbostic #ifdef HIDEBYLINK 89132222Sbostic /* 89232222Sbostic * routine to zero every byte in a string 89332222Sbostic */ 89432222Sbostic szero(str) 89532222Sbostic register char *str; 89632222Sbostic { 89732222Sbostic while (*str) 89832222Sbostic *str++ = 0; 89932222Sbostic } 90032222Sbostic #endif HIDEBYLINK 90132222Sbostic 90232222Sbostic #ifdef TIMECHECK 90332222Sbostic /* 90432222Sbostic * routine to check the time of day and return 1 if its during work hours 90532222Sbostic * checks the file ".holidays" for forms like "mmm dd comment..." 90632222Sbostic */ 90732222Sbostic int playable() 90832222Sbostic { 90932222Sbostic long g_time,time(); 91032222Sbostic int hour,day,year; 91132222Sbostic char *date,*month,*p; 91232222Sbostic 91332222Sbostic time(&g_time); /* get the time and date */ 91432222Sbostic date = ctime(&g_time); /* format: Fri Jul 4 00:27:56 EDT 1986 */ 91532222Sbostic year = atoi(date+20); 91632222Sbostic hour = (date[11]-'0')*10 + date[12]-'0'; 91732222Sbostic day = (date[8]!=' ') ? ((date[8]-'0')*10 + date[9]-'0') : (date[9]-'0'); 91832222Sbostic month = date+4; date[7]=0; /* point to and NULL terminate month */ 91932222Sbostic 92032222Sbostic if (((hour>=8 && hour<17)) /* 8AM - 5PM */ 92132222Sbostic && strncmp("Sat",date,3)!=0 /* not a Saturday */ 92232222Sbostic && strncmp("Sun",date,3)!=0) /* not a Sunday */ 92332222Sbostic { 92432222Sbostic /* now check for a .holidays datafile */ 92532222Sbostic lflush(); 92632222Sbostic if (lopen(holifile) >= 0) 92732222Sbostic for ( ; ; ) 92832222Sbostic { 92932222Sbostic if ((p=lgetw())==0) break; 93032222Sbostic if (strlen(p)<6) continue; 93132222Sbostic if ((strncmp(p,month,3)==0) && (day==atoi(p+4)) && (year==atoi(p+7))) 93232222Sbostic return(0); /* a holiday */ 93332222Sbostic } 93432222Sbostic lrclose(); lcreat((char*)0); 93532222Sbostic return(1); 93632222Sbostic } 93732222Sbostic return(0); 93832222Sbostic } 93932222Sbostic #endif TIMECHECK 940