|
|
1.1 root 1: /* main.c */
2: #include <sys/types.h>
3: #include "header.h"
4: #include <pwd.h>
5: static char copyright[]="\nLarn is copyrighted 1986 by Noah Morgan.\n";
6: int srcount=0; /* line counter for showstr() */
7: int dropflag=0; /* if 1 then don't lookforobject() next round */
8: int rmst=80; /* random monster creation counter */
9: int userid; /* the players login user id number */
10: char nowelcome=0,nomove=0; /* if (nomove) then don't count next iteration as a move */
11: static char viewflag=0;
12: /* if viewflag then we have done a 99 stay here and don't showcell in the main loop */
13: char restorflag=0; /* 1 means restore has been done */
14: static char cmdhelp[] = "\
15: Cmd line format: larn [-slicnh] [-o<optsifle>] [-##] [++]\n\
16: -s show the scoreboard\n\
17: -l show the logfile (wizard id only)\n\
18: -i show scoreboard with inventories of dead characters\n\
19: -c create new scoreboard (wizard id only)\n\
20: -n suppress welcome message on starting game\n\
21: -## specify level of difficulty (example: -5)\n\
22: -h print this help text\n\
23: ++ restore game from checkpoint file\n\
24: -o<optsfile> specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
25: ";
26: #ifdef VT100
27: static char *termtypes[] = { "vt100", "vt101", "vt102", "vt103", "vt125",
28: "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340",
29: "vt341" };
30: #endif VT100
31: /*
32: ************
33: MAIN PROGRAM
34: ************
35: */
36: main(argc,argv)
37: int argc;
38: char **argv;
39: {
40: register int i,j;
41: int hard;
42: char *ptr=0,*ttype;
43: struct passwd *pwe,*getpwuid();
44:
45: /*
46: * first task is to identify the player
47: */
48: #ifndef VT100
49: init_term(); /* setup the terminal (find out what type) for termcap */
50: #endif VT100
51: if (((ptr = getlogin()) == 0) || (*ptr==0)) /* try to get login name */
52: if (pwe=getpwuid(getuid())) /* can we get it from /etc/passwd? */
53: ptr = pwe->pw_name;
54: else
55: if ((ptr = getenv("USER")) == 0)
56: if ((ptr = getenv("LOGNAME")) == 0)
57: {
58: noone: write(2, "Can't find your logname. Who Are You?\n",39);
59: exit();
60: }
61: if (ptr==0) goto noone;
62: if (strlen(ptr)==0) goto noone;
63: /*
64: * second task is to prepare the pathnames the player will need
65: */
66: strcpy(loginname,ptr); /* save loginname of the user for logging purposes */
67: strcpy(logname,ptr); /* this will be overwritten with the players name */
68: if ((ptr = getenv("HOME")) == 0) ptr = ".";
69: strcpy(savefilename, ptr);
70: strcat(savefilename, "/Larn.sav"); /* save file name in home directory */
71: sprintf(optsfile, "%s/.larnopts",ptr); /* the .larnopts filename */
72:
73: /*
74: * now malloc the memory for the dungeon
75: */
76: cell = (struct cel *)malloc(sizeof(struct cel)*(MAXLEVEL+MAXVLEVEL)*MAXX*MAXY);
77: if (cell == 0) died(-285); /* malloc failure */
78: lpbuf = malloc((5* BUFBIG)>>2); /* output buffer */
79: inbuffer = malloc((5*MAXIBUF)>>2); /* output buffer */
80: if ((lpbuf==0) || (inbuffer==0)) died(-285); /* malloc() failure */
81:
82: lcreat((char*)0); newgame(); /* set the initial clock */ hard= -1;
83:
84: #ifdef VT100
85: /*
86: * check terminal type to avoid users who have not vt100 type terminals
87: */
88: ttype = getenv("TERM");
89: for (j=1, i=0; i<sizeof(termtypes)/sizeof(char *); i++)
90: if (strcmp(ttype,termtypes[i]) == 0) { j=0; break; }
91: if (j)
92: {
93: lprcat("Sorry, Larn needs a VT100 family terminal for all it's features.\n"); lflush();
94: exit();
95: }
96: #endif VT100
97:
98: /*
99: * now make scoreboard if it is not there (don't clear)
100: */
101: if (access(scorefile,0) == -1) /* not there */
102: makeboard();
103:
104: /*
105: * now process the command line arguments
106: */
107: for (i=1; i<argc; i++)
108: {
109: if (argv[i][0] == '-')
110: switch(argv[i][1])
111: {
112: case 's': showscores(); exit(); /* show scoreboard */
113:
114: case 'l': /* show log file */
115: diedlog(); exit();
116:
117: case 'i': showallscores(); exit(); /* show all scoreboard */
118:
119: case 'c': /* anyone with password can create scoreboard */
120: lprcat("Preparing to initialize the scoreboard.\n");
121: if (getpassword() != 0) /*make new scoreboard*/
122: {
123: makeboard(); lprc('\n'); showscores();
124: }
125: exit();
126:
127: case 'n': /* no welcome msg */ nowelcome=1; argv[i][0]=0; break;
128:
129: case '0': case '1': case '2': case '3': case '4': case '5':
130: case '6': case '7': case '8': case '9': /* for hardness */
131: sscanf(&argv[i][1],"%d",&hard);
132: break;
133:
134: case 'h': /* print out command line arguments */
135: write(1,cmdhelp,sizeof(cmdhelp)); exit();
136:
137: case 'o': /* specify a .larnopts filename */
138: strncpy(optsfile,argv[i]+2,127); break;
139:
140: default: printf("Unknown option <%s>\n",argv[i]); exit();
141: };
142:
143: if (argv[i][0] == '+')
144: {
145: clear(); restorflag = 1;
146: if (argv[i][1] == '+')
147: {
148: hitflag=1; restoregame(ckpfile); /* restore checkpointed game */
149: }
150: i = argc;
151: }
152: }
153:
154: readopts(); /* read the options file if there is one */
155:
156:
157: #ifdef UIDSCORE
158: userid = geteuid(); /* obtain the user's effective id number */
159: #else UIDSCORE
160: userid = getplid(logname); /* obtain the players id number */
161: #endif UIDSCORE
162: if (userid < 0) { write(2,"Can't obtain playerid\n",22); exit(); }
163:
164: #ifdef HIDEBYLINK
165: /*
166: * this section of code causes the program to look like something else to ps
167: */
168: if (strcmp(psname,argv[0])) /* if a different process name only */
169: {
170: if ((i=access(psname,1)) < 0)
171: { /* link not there */
172: if (link(argv[0],psname)>=0)
173: {
174: argv[0] = psname; execv(psname,argv);
175: }
176: }
177: else
178: unlink(psname);
179: }
180:
181: for (i=1; i<argc; i++)
182: {
183: szero(argv[i]); /* zero the argument to avoid ps snooping */
184: }
185: #endif HIDEBYLINK
186:
187: if (access(savefilename,0)==0) /* restore game if need to */
188: {
189: clear(); restorflag = 1;
190: hitflag=1; restoregame(savefilename); /* restore last game */
191: }
192: sigsetup(); /* trap all needed signals */
193: sethard(hard); /* set up the desired difficulty */
194: setupvt100(); /* setup the terminal special mode */
195: if (c[HP]==0) /* create new game */
196: {
197: makeplayer(); /* make the character that will play */
198: newcavelevel(0);/* make the dungeon */
199: predostuff = 1; /* tell signals that we are in the welcome screen */
200: if (nowelcome==0) welcome(); /* welcome the player to the game */
201: }
202: drawscreen(); /* show the initial dungeon */
203: predostuff = 2; /* tell the trap functions that they must do a showplayer()
204: from here on */
205: /* nice(1); /* games should be run niced */
206: yrepcount = hit2flag = 0;
207: while (1)
208: {
209: if (dropflag==0) lookforobject(); /* see if there is an object here */
210: else dropflag=0; /* don't show it just dropped an item */
211: if (hitflag==0) { if (c[HASTEMONST]) movemonst(); movemonst(); } /* move the monsters */
212: if (viewflag==0) showcell(playerx,playery); else viewflag=0; /* show stuff around player */
213: if (hit3flag) flushall();
214: hitflag=hit3flag=0; nomove=1;
215: bot_linex(); /* update bottom line */
216: while (nomove)
217: {
218: if (hit3flag) flushall();
219: nomove=0; parse();
220: } /* get commands and make moves */
221: regen(); /* regenerate hp and spells */
222: if (c[TIMESTOP]==0)
223: if (--rmst <= 0)
224: { rmst = 120-(level<<2); fillmonst(makemonst(level)); }
225: }
226: }
227:
228: /*
229: showstr()
230:
231: show character's inventory
232: */
233: showstr()
234: {
235: register int i,number;
236: for (number=3, i=0; i<26; i++)
237: if (iven[i]) number++; /* count items in inventory */
238: t_setup(number); qshowstr(); t_endup(number);
239: }
240:
241: qshowstr()
242: {
243: register int i,j,k,sigsav;
244: srcount=0; sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
245: if (c[GOLD]) { lprintf(".) %d gold pieces",(long)c[GOLD]); srcount++; }
246: for (k=26; k>=0; k--)
247: if (iven[k])
248: { for (i=22; i<84; i++)
249: for (j=0; j<=k; j++) if (i==iven[j]) show3(j); k=0; }
250:
251: lprintf("\nElapsed time is %d. You have %d mobuls left",(long)((gtime+99)/100+1),(long)((TIMELIMIT-gtime)/100));
252: more(); nosignal=sigsav;
253: }
254:
255: /*
256: * subroutine to clear screen depending on # lines to display
257: */
258: t_setup(count)
259: register int count;
260: {
261: if (count<20) /* how do we clear the screen? */
262: {
263: cl_up(79,count); cursor(1,1);
264: }
265: else
266: {
267: resetscroll(); clear();
268: }
269: }
270:
271: /*
272: * subroutine to restore normal display screen depending on t_setup()
273: */
274: t_endup(count)
275: register int count;
276: {
277: if (count<18) /* how did we clear the screen? */
278: draws(0,MAXX,0,(count>MAXY) ? MAXY : count);
279: else
280: {
281: drawscreen(); setscroll();
282: }
283: }
284:
285: /*
286: function to show the things player is wearing only
287: */
288: showwear()
289: {
290: register int i,j,sigsav,count;
291: sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
292: srcount=0;
293:
294: for (count=2,j=0; j<=26; j++) /* count number of items we will display */
295: if (i=iven[j])
296: switch(i)
297: {
298: case OLEATHER: case OPLATE: case OCHAIN:
299: case ORING: case OSTUDLEATHER: case OSPLINT:
300: case OPLATEARMOR: case OSSPLATE: case OSHIELD:
301: count++;
302: };
303:
304: t_setup(count);
305:
306: for (i=22; i<84; i++)
307: for (j=0; j<=26; j++)
308: if (i==iven[j])
309: switch(i)
310: {
311: case OLEATHER: case OPLATE: case OCHAIN:
312: case ORING: case OSTUDLEATHER: case OSPLINT:
313: case OPLATEARMOR: case OSSPLATE: case OSHIELD:
314: show3(j);
315: };
316: more(); nosignal=sigsav; t_endup(count);
317: }
318:
319: /*
320: function to show the things player can wield only
321: */
322: showwield()
323: {
324: register int i,j,sigsav,count;
325: sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
326: srcount=0;
327:
328: for (count=2,j=0; j<=26; j++) /* count how many items */
329: if (i=iven[j])
330: switch(i)
331: {
332: case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE:
333: case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT:
334: case OSPIRITSCARAB: case OCUBEofUNDEAD:
335: case OPOTION: case OSCROLL: break;
336: default: count++;
337: };
338:
339: t_setup(count);
340:
341: for (i=22; i<84; i++)
342: for (j=0; j<=26; j++)
343: if (i==iven[j])
344: switch(i)
345: {
346: case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE:
347: case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT:
348: case OSPIRITSCARAB: case OCUBEofUNDEAD:
349: case OPOTION: case OSCROLL: break;
350: default: show3(j);
351: };
352: more(); nosignal=sigsav; t_endup(count);
353: }
354:
355: /*
356: * function to show the things player can read only
357: */
358: showread()
359: {
360: register int i,j,sigsav,count;
361: sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
362: srcount=0;
363:
364: for (count=2,j=0; j<=26; j++)
365: switch(iven[j])
366: {
367: case OBOOK: case OSCROLL: count++;
368: };
369: t_setup(count);
370:
371: for (i=22; i<84; i++)
372: for (j=0; j<=26; j++)
373: if (i==iven[j])
374: switch(i)
375: {
376: case OBOOK: case OSCROLL: show3(j);
377: };
378: more(); nosignal=sigsav; t_endup(count);
379: }
380:
381: /*
382: * function to show the things player can eat only
383: */
384: showeat()
385: {
386: register int i,j,sigsav,count;
387: sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
388: srcount=0;
389:
390: for (count=2,j=0; j<=26; j++)
391: switch(iven[j])
392: {
393: case OCOOKIE: count++;
394: };
395: t_setup(count);
396:
397: for (i=22; i<84; i++)
398: for (j=0; j<=26; j++)
399: if (i==iven[j])
400: switch(i)
401: {
402: case OCOOKIE: show3(j);
403: };
404: more(); nosignal=sigsav; t_endup(count);
405: }
406:
407: /*
408: function to show the things player can quaff only
409: */
410: showquaff()
411: {
412: register int i,j,sigsav,count;
413: sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
414: srcount=0;
415:
416: for (count=2,j=0; j<=26; j++)
417: switch(iven[j])
418: {
419: case OPOTION: count++;
420: };
421: t_setup(count);
422:
423: for (i=22; i<84; i++)
424: for (j=0; j<=26; j++)
425: if (i==iven[j])
426: switch(i)
427: {
428: case OPOTION: show3(j);
429: };
430: more(); nosignal=sigsav; t_endup(count);
431: }
432:
433: show1(idx,str2)
434: register int idx;
435: register char *str2[];
436: {
437: if (str2==0) lprintf("\n%c) %s",idx+'a',objectname[iven[idx]]);
438: else if (*str2[ivenarg[idx]]==0) lprintf("\n%c) %s",idx+'a',objectname[iven[idx]]);
439: else lprintf("\n%c) %s of%s",idx+'a',objectname[iven[idx]],str2[ivenarg[idx]]);
440: }
441:
442: show3(index)
443: register int index;
444: {
445: switch(iven[index])
446: {
447: case OPOTION: show1(index,potionname); break;
448: case OSCROLL: show1(index,scrollname); break;
449:
450: case OLARNEYE: case OBOOK: case OSPIRITSCARAB:
451: case ODIAMOND: case ORUBY: case OCUBEofUNDEAD:
452: case OEMERALD: case OCHEST: case OCOOKIE:
453: case OSAPPHIRE: case ONOTHEFT: show1(index,(char **)0); break;
454:
455: default: lprintf("\n%c) %s",index+'a',objectname[iven[index]]);
456: if (ivenarg[index]>0) lprintf(" + %d",(long)ivenarg[index]);
457: else if (ivenarg[index]<0) lprintf(" %d",(long)ivenarg[index]);
458: break;
459: }
460: if (c[WIELD]==index) lprcat(" (weapon in hand)");
461: if ((c[WEAR]==index) || (c[SHIELD]==index)) lprcat(" (being worn)");
462: if (++srcount>=22) { srcount=0; more(); clear(); }
463: }
464:
465: /*
466: subroutine to randomly create monsters if needed
467: */
468: randmonst()
469: {
470: if (c[TIMESTOP]) return; /* don't make monsters if time is stopped */
471: if (--rmst <= 0)
472: {
473: rmst = 120 - (level<<2); fillmonst(makemonst(level));
474: }
475: }
476:
477:
478: /*
479: parse()
480:
481: get and execute a command
482: */
483: parse()
484: {
485: register int i,j,k,flag;
486: while (1)
487: {
488: k = yylex();
489: switch(k) /* get the token from the input and switch on it */
490: {
491: case 'h': moveplayer(4); return; /* west */
492: case 'H': run(4); return; /* west */
493: case 'l': moveplayer(2); return; /* east */
494: case 'L': run(2); return; /* east */
495: case 'j': moveplayer(1); return; /* south */
496: case 'J': run(1); return; /* south */
497: case 'k': moveplayer(3); return; /* north */
498: case 'K': run(3); return; /* north */
499: case 'u': moveplayer(5); return; /* northeast */
500: case 'U': run(5); return; /* northeast */
501: case 'y': moveplayer(6); return; /* northwest */
502: case 'Y': run(6); return; /* northwest */
503: case 'n': moveplayer(7); return; /* southeast */
504: case 'N': run(7); return; /* southeast */
505: case 'b': moveplayer(8); return; /* southwest */
506: case 'B': run(8); return; /* southwest */
507:
508: case '.': if (yrepcount) viewflag=1; return; /* stay here */
509:
510: case 'w': yrepcount=0; wield(); return; /* wield a weapon */
511:
512: case 'W': yrepcount=0; wear(); return; /* wear armor */
513:
514: case 'r': yrepcount=0;
515: if (c[BLINDCOUNT]) { cursors(); lprcat("\nYou can't read anything when you're blind!"); } else
516: if (c[TIMESTOP]==0) readscr(); return; /* to read a scroll */
517:
518: case 'q': yrepcount=0; if (c[TIMESTOP]==0) quaff(); return; /* quaff a potion */
519:
520: case 'd': yrepcount=0; if (c[TIMESTOP]==0) dropobj(); return; /* to drop an object */
521:
522: case 'c': yrepcount=0; cast(); return; /* cast a spell */
523:
524: case 'i': yrepcount=0; nomove=1; showstr(); return; /* status */
525:
526: case 'e': yrepcount=0;
527: if (c[TIMESTOP]==0) eatcookie(); return; /* to eat a fortune cookie */
528:
529: case 'D': yrepcount=0; seemagic(0); nomove=1; return; /* list spells and scrolls */
530:
531: case '?': yrepcount=0; help(); nomove=1; return; /* give the help screen*/
532:
533: case 'S': clear(); lprcat("Saving . . ."); lflush();
534: savegame(savefilename); wizard=1; died(-257); /* save the game - doesn't return */
535:
536: case 'Z': yrepcount=0; if (c[LEVEL]>9) { oteleport(1); return; }
537: cursors(); lprcat("\nAs yet, you don't have enough experience to use teleportation");
538: return; /* teleport yourself */
539:
540: case '^': /* identify traps */ flag=yrepcount=0; cursors();
541: lprc('\n'); for (j=playery-1; j<playery+2; j++)
542: {
543: if (j < 0) j=0; if (j >= MAXY) break;
544: for (i=playerx-1; i<playerx+2; i++)
545: {
546: if (i < 0) i=0; if (i >= MAXX) break;
547: switch(item[i][j])
548: {
549: case OTRAPDOOR: case ODARTRAP:
550: case OTRAPARROW: case OTELEPORTER:
551: lprcat("\nIts "); lprcat(objectname[item[i][j]]); flag++;
552: };
553: }
554: }
555: if (flag==0) lprcat("\nNo traps are visible");
556: return;
557:
558: #if WIZID
559: case '_': /* this is the fudge player password for wizard mode*/
560: yrepcount=0; cursors(); nomove=1;
561: if (userid!=wisid)
562: {
563: lprcat("Sorry, you are not empowered to be a wizard.\n");
564: scbr(); /* system("stty -echo cbreak"); */
565: lflush(); return;
566: }
567: if (getpassword()==0)
568: {
569: scbr(); /* system("stty -echo cbreak"); */ return;
570: }
571: wizard=1; scbr(); /* system("stty -echo cbreak"); */
572: for (i=0; i<6; i++) c[i]=70; iven[0]=iven[1]=0;
573: take(OPROTRING,50); take(OLANCE,25); c[WIELD]=1;
574: c[LANCEDEATH]=1; c[WEAR] = c[SHIELD] = -1;
575: raiseexperience(6000000L); c[AWARENESS] += 25000;
576: {
577: register int i,j;
578: for (i=0; i<MAXY; i++)
579: for (j=0; j<MAXX; j++) know[j][i]=1;
580: for (i=0; i<SPNUM; i++) spelknow[i]=1;
581: for (i=0; i<MAXSCROLL; i++) scrollname[i][0]=' ';
582: for (i=0; i<MAXPOTION; i++) potionname[i][0]=' ';
583: }
584: for (i=0; i<MAXSCROLL; i++)
585: if (strlen(scrollname[i])>2) /* no null items */
586: { item[i][0]=OSCROLL; iarg[i][0]=i; }
587: for (i=MAXX-1; i>MAXX-1-MAXPOTION; i--)
588: if (strlen(potionname[i-MAXX+MAXPOTION])>2) /* no null items */
589: { item[i][0]=OPOTION; iarg[i][0]=i-MAXX+MAXPOTION; }
590: for (i=1; i<MAXY; i++)
591: { item[0][i]=i; iarg[0][i]=0; }
592: for (i=MAXY; i<MAXY+MAXX; i++)
593: { item[i-MAXY][MAXY-1]=i; iarg[i-MAXY][MAXY-1]=0; }
594: for (i=MAXX+MAXY; i<MAXX+MAXY+MAXY; i++)
595: { item[MAXX-1][i-MAXX-MAXY]=i; iarg[MAXX-1][i-MAXX-MAXY]=0; }
596: c[GOLD]+=25000; drawscreen(); return;
597: #endif
598:
599: case 'T': yrepcount=0; cursors(); if (c[SHIELD] != -1) { c[SHIELD] = -1; lprcat("\nYour shield is off"); bottomline(); } else
600: if (c[WEAR] != -1) { c[WEAR] = -1; lprcat("\nYour armor is off"); bottomline(); }
601: else lprcat("\nYou aren't wearing anything");
602: return;
603:
604: case 'g': cursors();
605: lprintf("\nThe stuff you are carrying presently weighs %d pounds",(long)packweight());
606: case ' ': yrepcount=0; nomove=1; return;
607:
608: case 'v': yrepcount=0; cursors();
609: lprintf("\nCaverns of Larn, Version %d.%d, Diff=%d",(long)VERSION,(long)SUBVERSION,(long)c[HARDGAME]);
610: if (wizard) lprcat(" Wizard"); nomove=1;
611: if (cheat) lprcat(" Cheater");
612: lprcat(copyright);
613: return;
614:
615: case 'Q': yrepcount=0; quit(); nomove=1; return; /* quit */
616:
617: case 'L'-64: yrepcount=0; drawscreen(); nomove=1; return; /* look */
618:
619: #if WIZID
620: #ifdef EXTRA
621: case 'A': yrepcount=0; nomove=1; if (wizard) { diag(); return; } /* create diagnostic file */
622: return;
623: #endif
624: #endif
625: case 'P': cursors();
626: if (outstanding_taxes>0)
627: lprintf("\nYou presently owe %d gp in taxes.",(long)outstanding_taxes);
628: else
629: lprcat("\nYou do not owe any taxes.");
630: return;
631: };
632: }
633: }
634:
635: parse2()
636: {
637: if (c[HASTEMONST]) movemonst(); movemonst(); /* move the monsters */
638: randmonst(); regen();
639: }
640:
641: run(dir)
642: int dir;
643: {
644: register int i;
645: i=1; while (i)
646: {
647: i=moveplayer(dir);
648: if (i>0) { if (c[HASTEMONST]) movemonst(); movemonst(); randmonst(); regen(); }
649: if (hitflag) i=0;
650: if (i!=0) showcell(playerx,playery);
651: }
652: }
653:
654: /*
655: function to wield a weapon
656: */
657: wield()
658: {
659: register int i;
660: while (1)
661: {
662: if ((i = whatitem("wield"))=='\33') return;
663: if (i != '.')
664: {
665: if (i=='*') showwield();
666: else if (iven[i-'a']==0) { ydhi(i); return; }
667: else if (iven[i-'a']==OPOTION) { ycwi(i); return; }
668: else if (iven[i-'a']==OSCROLL) { ycwi(i); return; }
669: else if ((c[SHIELD]!= -1) && (iven[i-'a']==O2SWORD)) { lprcat("\nBut one arm is busy with your shield!"); return; }
670: else { c[WIELD]=i-'a'; if (iven[i-'a'] == OLANCE) c[LANCEDEATH]=1; else c[LANCEDEATH]=0; bottomline(); return; }
671: }
672: }
673: }
674:
675: /*
676: common routine to say you don't have an item
677: */
678: ydhi(x)
679: int x;
680: { cursors(); lprintf("\nYou don't have item %c!",x); }
681: ycwi(x)
682: int x;
683: { cursors(); lprintf("\nYou can't wield item %c!",x); }
684:
685: /*
686: function to wear armor
687: */
688: wear()
689: {
690: register int i;
691: while (1)
692: {
693: if ((i = whatitem("wear"))=='\33') return;
694: if (i != '.')
695: {
696: if (i=='*') showwear(); else
697: switch(iven[i-'a'])
698: {
699: case 0: ydhi(i); return;
700: case OLEATHER: case OCHAIN: case OPLATE: case OSTUDLEATHER:
701: case ORING: case OSPLINT: case OPLATEARMOR: case OSSPLATE:
702: if (c[WEAR] != -1) { lprcat("\nYou're already wearing some armor"); return; }
703: c[WEAR]=i-'a'; bottomline(); return;
704: case OSHIELD: if (c[SHIELD] != -1) { lprcat("\nYou are already wearing a shield"); return; }
705: if (iven[c[WIELD]]==O2SWORD) { lprcat("\nYour hands are busy with the two handed sword!"); return; }
706: c[SHIELD] = i-'a'; bottomline(); return;
707: default: lprcat("\nYou can't wear that!");
708: };
709: }
710: }
711: }
712:
713: /*
714: function to drop an object
715: */
716: dropobj()
717: {
718: register int i;
719: register char *p;
720: long amt;
721: p = &item[playerx][playery];
722: while (1)
723: {
724: if ((i = whatitem("drop"))=='\33') return;
725: if (i=='*') showstr(); else
726: {
727: if (i=='.') /* drop some gold */
728: {
729: if (*p) { lprcat("\nThere's something here already!"); return; }
730: lprcat("\n\n");
731: cl_dn(1,23);
732: lprcat("How much gold do you drop? ");
733: if ((amt=readnum((long)c[GOLD])) == 0) return;
734: if (amt>c[GOLD])
735: { lprcat("\nYou don't have that much!"); return; }
736: if (amt<=32767)
737: { *p=OGOLDPILE; i=amt; }
738: else if (amt<=327670L)
739: { *p=ODGOLD; i=amt/10; amt = 10*i; }
740: else if (amt<=3276700L)
741: { *p=OMAXGOLD; i=amt/100; amt = 100*i; }
742: else if (amt<=32767000L)
743: { *p=OKGOLD; i=amt/1000; amt = 1000*i; }
744: else
745: { *p=OKGOLD; i=32767; amt = 32767000L; }
746: c[GOLD] -= amt;
747: lprintf("You drop %d gold pieces",(long)amt);
748: iarg[playerx][playery]=i; bottomgold();
749: know[playerx][playery]=0; dropflag=1; return;
750: }
751: drop_object(i-'a');
752: return;
753: }
754: }
755: }
756:
757: /*
758: * readscr() Subroutine to read a scroll one is carrying
759: */
760: readscr()
761: {
762: register int i;
763: while (1)
764: {
765: if ((i = whatitem("read"))=='\33') return;
766: if (i != '.')
767: {
768: if (i=='*') showread(); else
769: {
770: if (iven[i-'a']==OSCROLL) { read_scroll(ivenarg[i-'a']); iven[i-'a']=0; return; }
771: if (iven[i-'a']==OBOOK) { readbook(ivenarg[i-'a']); iven[i-'a']=0; return; }
772: if (iven[i-'a']==0) { ydhi(i); return; }
773: lprcat("\nThere's nothing on it to read"); return;
774: }
775: }
776: }
777: }
778:
779: /*
780: * subroutine to eat a cookie one is carrying
781: */
782: eatcookie()
783: {
784: register int i;
785: char *p;
786: while (1)
787: {
788: if ((i = whatitem("eat"))=='\33') return;
789: if (i != '.')
790: if (i=='*') showeat(); else
791: {
792: if (iven[i-'a']==OCOOKIE)
793: {
794: lprcat("\nThe cookie was delicious.");
795: iven[i-'a']=0;
796: if (!c[BLINDCOUNT])
797: {
798: if (p=fortune(fortfile))
799: {
800: lprcat(" Inside you find a scrap of paper that says:\n");
801: lprcat(p);
802: }
803: }
804: return;
805: }
806: if (iven[i-'a']==0) { ydhi(i); return; }
807: lprcat("\nYou can't eat that!"); return;
808: }
809: }
810: }
811:
812: /*
813: * subroutine to quaff a potion one is carrying
814: */
815: quaff()
816: {
817: register int i;
818: while (1)
819: {
820: if ((i = whatitem("quaff"))=='\33') return;
821: if (i != '.')
822: {
823: if (i=='*') showquaff(); else
824: {
825: if (iven[i-'a']==OPOTION) { quaffpotion(ivenarg[i-'a']); iven[i-'a']=0; return; }
826: if (iven[i-'a']==0) { ydhi(i); return; }
827: lprcat("\nYou wouldn't want to quaff that, would you? "); return;
828: }
829: }
830: }
831: }
832:
833: /*
834: function to ask what player wants to do
835: */
836: whatitem(str)
837: char *str;
838: {
839: int i;
840: cursors(); lprintf("\nWhat do you want to %s [* for all] ? ",str);
841: i=0; while (i>'z' || (i<'a' && i!='*' && i!='\33' && i!='.')) i=getchar();
842: if (i=='\33') lprcat(" aborted");
843: return(i);
844: }
845:
846: /*
847: subroutine to get a number from the player
848: and allow * to mean return amt, else return the number entered
849: */
850: unsigned long readnum(mx)
851: long mx;
852: {
853: register int i;
854: register unsigned long amt=0;
855: sncbr();
856: if ((i=getchar()) == '*') amt = mx; /* allow him to say * for all gold */
857: else
858: while (i != '\n')
859: {
860: if (i=='\033') { scbr(); lprcat(" aborted"); return(0); }
861: if ((i <= '9') && (i >= '0') && (amt<99999999))
862: amt = amt*10+i-'0';
863: i = getchar();
864: }
865: scbr(); return(amt);
866: }
867:
868: #ifdef HIDEBYLINK
869: /*
870: * routine to zero every byte in a string
871: */
872: szero(str)
873: register char *str;
874: {
875: while (*str)
876: *str++ = 0;
877: }
878: #endif HIDEBYLINK
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.