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