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