intr: Allow drivers to register high frequency interrupt.
[dragonfly.git] / games / larn / main.c
blob529f7345fc58755ab979ca18bb92fcf55e34cd53
1 /* $FreeBSD: src/games/larn/main.c,v 1.9 1999/11/30 03:48:59 billf Exp $ */
2 /* main.c */
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include "header.h"
6 #include <pwd.h>
7 static const char copyright[] = "\nLarn is copyrighted 1986 by Noah Morgan.\n";
8 int srcount = 0; /* line counter for showstr() */
9 int dropflag = 0; /* if 1 then don't lookforobject() next round */
10 int rmst = 80; /* random monster creation counter */
11 int userid; /* the players login user id number */
12 char nowelcome = 0, nomove = 0; /* if (nomove) then don't count next iteration as a move */
13 static char viewflag = 0;
14 /* if viewflag then we have done a 99 stay here and don't showcell in the main loop */
15 char restorflag=0; /* 1 means restore has been done */
16 static char cmdhelp[] = "\
17 Cmd line format: larn [-slicnh] [-o<optsifle>] [-##] [++]\n\
18 -s show the scoreboard\n\
19 -l show the logfile (wizard id only)\n\
20 -i show scoreboard with inventories of dead characters\n\
21 -c create new scoreboard (wizard id only)\n\
22 -n suppress welcome message on starting game\n\
23 -## specify level of difficulty (example: -5)\n\
24 -h print this help text\n\
25 ++ restore game from checkpoint file\n\
26 -o<optsfile> specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
28 #ifdef VT100
29 static const char *termtypes[] = { "vt100", "vt101", "vt102", "vt103", "vt125",
30 "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340",
31 "vt341" };
32 #endif /* VT100 */
34 static void showstr(void);
35 static void t_setup(int);
36 static void t_endup(int);
37 static void showwear(void);
38 static void showwield(void);
39 static void showread(void);
40 static void showeat(void);
41 static void showquaff(void);
42 static void show1(int, const char **);
43 static void randmonst(void);
44 static void parse(void);
45 static void run(int);
46 static void wield(void);
47 static void ydhi(int);
48 static void ycwi(int);
49 static void wear(void);
50 static void dropobj(void);
51 static void readscr(void);
52 static void eatcookie(void);
53 static void quaff(void);
54 static int whatitem(const char *);
55 #ifdef HIDEBYLINK
56 static void szero(char *);
57 #endif
60 ************
61 MAIN PROGRAM
62 ************
64 int
65 main(int argc, char **argv)
67 int i;
68 int hard;
69 const char *ptr;
70 #ifdef VT100
71 char *ttype;
72 int j;
73 #endif
74 struct passwd *pwe;
75 struct stat sb;
78 * first task is to identify the player
80 #ifndef VT100
81 init_term(); /* setup the terminal (find out what type) for termcap */
82 #endif /* VT100 */
83 /* try to get login name */
84 if (((ptr = getlogin()) == NULL) || (*ptr == 0)) {
85 /* can we get it from /etc/passwd? */
86 if ((pwe = getpwuid(getuid())) != NULL)
87 ptr = pwe->pw_name;
88 else if ((ptr = getenv("USER")) == NULL)
89 if ((ptr = getenv("LOGNAME")) == NULL) {
90 noone: write(2, "Can't find your logname. Who Are You?\n", 39);
91 exit(1);
94 if (ptr == NULL)
95 goto noone;
96 if (strlen(ptr) == 0)
97 goto noone;
100 * second task is to prepare the pathnames the player will need
102 strcpy(loginname, ptr); /* save loginname of the user for logging purposes */
103 strcpy(logname, ptr); /* this will be overwritten with the players name */
104 if ((ptr = getenv("HOME")) == NULL)
105 ptr = ".";
106 strcpy(savefilename, ptr);
107 strcat(savefilename, "/Larn.sav"); /* save file name in home directory */
108 sprintf(optsfile, "%s/.larnopts", ptr); /* the .larnopts filename */
111 * now malloc the memory for the dungeon
113 cell = malloc(sizeof(struct cel) * (MAXLEVEL + MAXVLEVEL) * MAXX * MAXY);
114 if (cell == NULL) /* malloc failure */
115 died(-285);
116 lpbuf = malloc((5 * BUFBIG) >> 2); /* output buffer */
117 inbuffer = malloc((5 * MAXIBUF) >> 2); /* output buffer */
118 if ((lpbuf == NULL) || (inbuffer == NULL)) /* malloc() failure */
119 died(-285);
121 lcreat(NULL);
122 newgame(); /* set the initial clock */
123 hard = -1;
125 #ifdef VT100
127 * check terminal type to avoid users who have not vt100 type terminals
129 ttype = getenv("TERM");
130 for (j = 1, i = 0; i < sizeof(termtypes) / sizeof(char *); i++)
131 if (strcmp(ttype, termtypes[i]) == 0) {
132 j = 0;
133 break;
135 if (j) {
136 lprcat("Sorry, Larn needs a VT100 family terminal for all it's features.\n");
137 lflush();
138 exit(1);
140 #endif /* VT100 */
143 * now make scoreboard if it is not there (don't clear)
145 if (stat(scorefile, &sb) < 0 || sb.st_size == 0) /* not there */
146 makeboard();
149 * now process the command line arguments
151 for (i = 1; i < argc; i++) {
152 if (argv[i][0] == '-')
153 switch (argv[i][1]) {
154 case 's':
155 showscores();
156 exit(0); /* show scoreboard */
158 case 'l': /* show log file */
159 diedlog();
160 exit(0);
162 case 'i':
163 showallscores();
164 exit(0); /* show all scoreboard */
166 case 'c': /* anyone with password can create scoreboard */
167 lprcat("Preparing to initialize the scoreboard.\n");
168 if (getpassword() != 0) { /* make new scoreboard */
169 makeboard();
170 lprc('\n');
171 showscores();
173 exit(0);
175 case 'n': /* no welcome msg */
176 nowelcome = 1;
177 argv[i][0] = 0;
178 break;
180 case '0':
181 case '1':
182 case '2':
183 case '3':
184 case '4':
185 case '5':
186 case '6':
187 case '7':
188 case '8':
189 case '9': /* for hardness */
190 sscanf(&argv[i][1], "%d", &hard);
191 break;
193 case 'h': /* print out command line arguments */
194 write(1, cmdhelp, sizeof(cmdhelp));
195 exit(0);
197 case 'o': /* specify a .larnopts filename */
198 strncpy(optsfile, argv[i] + 2, 127);
199 break;
201 default:
202 printf("Unknown option <%s>\n", argv[i]);
203 exit(1);
206 if (argv[i][0] == '+') {
207 clear();
208 restorflag = 1;
209 if (argv[i][1] == '+') {
210 hitflag = 1;
211 restoregame(ckpfile); /* restore checkpointed game */
213 i = argc;
217 readopts(); /* read the options file if there is one */
220 #ifdef UIDSCORE
221 userid = geteuid(); /* obtain the user's effective id number */
222 #else /* UIDSCORE */
223 userid = getplid(logname); /* obtain the players id number */
224 #endif /* UIDSCORE */
225 if (userid < 0) {
226 write(2, "Can't obtain playerid\n", 22);
227 exit(1);
230 #ifdef HIDEBYLINK
232 * this section of code causes the program to look like something else to ps
234 if (strcmp(psname, argv[0])) { /* if a different process name only */
235 if ((i = access(psname, 1)) < 0) { /* link not there */
236 if (link(argv[0], psname) >= 0) {
237 argv[0] = psname;
238 execv(psname, argv);
240 } else
241 unlink(psname);
244 for (i = 1; i < argc; i++) {
245 szero(argv[i]); /* zero the argument to avoid ps snooping */
247 #endif /* HIDEBYLINK */
249 if (access(savefilename, 0) == 0) { /* restore game if need to */
250 clear();
251 restorflag = 1;
252 hitflag = 1;
253 restoregame(savefilename); /* restore last game */
255 sigsetup(); /* trap all needed signals */
256 sethard(hard); /* set up the desired difficulty */
257 setupvt100(); /* setup the terminal special mode */
258 if (c[HP] == 0) { /* create new game */
259 makeplayer(); /* make the character that will play */
260 newcavelevel(0);/* make the dungeon */
261 predostuff = 1; /* tell signals that we are in the welcome screen */
262 if (nowelcome == 0)
263 welcome(); /* welcome the player to the game */
265 drawscreen(); /* show the initial dungeon */
266 predostuff = 2; /* tell the trap functions that they must do
267 * a showplayer() from here on */
268 #if 0
269 nice(1); /* games should be run niced */
270 #endif
271 yrepcount = hit2flag = 0;
272 while (1) {
273 if (dropflag == 0) /* see if there is an object here */
274 lookforobject();
275 else /* don't show it just dropped an item */
276 dropflag = 0;
277 if (hitflag == 0) {
278 if (c[HASTEMONST])
279 movemonst();
280 movemonst();
281 } /* move the monsters */
282 if (viewflag == 0)
283 showcell(playerx, playery);
284 else
285 viewflag = 0; /* show stuff around player */
286 if (hit3flag)
287 flushall();
288 hitflag = hit3flag = 0;
289 nomove = 1;
290 bot_linex(); /* update bottom line */
291 while (nomove) {
292 if (hit3flag)
293 flushall();
294 nomove = 0;
295 parse();
296 } /* get commands and make moves */
297 regen(); /* regenerate hp and spells */
298 if (c[TIMESTOP] == 0)
299 if (--rmst <= 0) {
300 rmst = 120 - (level << 2);
301 fillmonst(makemonst(level));
307 showstr()
309 show character's inventory
311 static void
312 showstr(void)
314 int i, number;
315 for (number = 3, i = 0; i < 26; i++)
316 if (iven[i]) /* count items in inventory */
317 number++;
318 t_setup(number);
319 qshowstr();
320 t_endup(number);
323 void
324 qshowstr(void)
326 int i, j, k, sigsav;
327 srcount = 0;
328 sigsav = nosignal;
329 nosignal = 1; /* don't allow ^c etc */
330 if (c[GOLD]) {
331 lprintf(".) %d gold pieces", (long)c[GOLD]);
332 srcount++;
334 for (k = 26; k >= 0; k--)
335 if (iven[k]) {
336 for (i = 22; i < 84; i++)
337 for (j = 0; j <= k; j++)
338 if (i == iven[j])
339 show3(j);
340 k = 0;
343 lprintf("\nElapsed time is %d. You have %d mobuls left", (long)((gtime + 99) / 100 + 1), (long)((TIMELIMIT - gtime) / 100));
344 more();
345 nosignal = sigsav;
349 * subroutine to clear screen depending on # lines to display
351 static void
352 t_setup(int count)
354 if (count < 20) { /* how do we clear the screen? */
355 cl_up(79, count);
356 cursor(1, 1);
357 } else {
358 resetscroll();
359 clear();
364 * subroutine to restore normal display screen depending on t_setup()
366 static void
367 t_endup(int count)
369 if (count < 18) /* how did we clear the screen? */
370 draws(0, MAXX, 0, (count > MAXY) ? MAXY : count);
371 else {
372 drawscreen();
373 setscroll();
378 function to show the things player is wearing only
380 static void
381 showwear(void)
383 int i, j, sigsav, count;
384 sigsav = nosignal;
385 nosignal = 1; /* don't allow ^c etc */
386 srcount = 0;
388 for (count = 2, j = 0; j <= 26; j++) /* count number of items we will display */
389 if ((i = iven[j]) != 0)
390 switch (i) {
391 case OLEATHER:
392 case OPLATE:
393 case OCHAIN:
394 case ORING:
395 case OSTUDLEATHER:
396 case OSPLINT:
397 case OPLATEARMOR:
398 case OSSPLATE:
399 case OSHIELD:
400 count++;
403 t_setup(count);
405 for (i = 22; i < 84; i++)
406 for (j = 0; j <= 26; j++)
407 if (i == iven[j])
408 switch (i) {
409 case OLEATHER:
410 case OPLATE:
411 case OCHAIN:
412 case ORING:
413 case OSTUDLEATHER:
414 case OSPLINT:
415 case OPLATEARMOR:
416 case OSSPLATE:
417 case OSHIELD:
418 show3(j);
420 more();
421 nosignal = sigsav;
422 t_endup(count);
426 function to show the things player can wield only
428 static void
429 showwield(void)
431 int i, j, sigsav, count;
432 sigsav = nosignal;
433 nosignal = 1; /* don't allow ^c etc */
434 srcount = 0;
436 for (count = 2, j = 0; j <= 26; j++) /* count how many items */
437 if ((i = iven[j]) != 0)
438 switch (i) {
439 case ODIAMOND:
440 case ORUBY:
441 case OEMERALD:
442 case OSAPPHIRE:
443 case OBOOK:
444 case OCHEST:
445 case OLARNEYE:
446 case ONOTHEFT:
447 case OSPIRITSCARAB:
448 case OCUBEofUNDEAD:
449 case OPOTION:
450 case OSCROLL:
451 break;
452 default:
453 count++;
456 t_setup(count);
458 for (i = 22; i < 84; i++)
459 for (j = 0; j <= 26; j++)
460 if (i == iven[j])
461 switch (i) {
462 case ODIAMOND:
463 case ORUBY:
464 case OEMERALD:
465 case OSAPPHIRE:
466 case OBOOK:
467 case OCHEST:
468 case OLARNEYE:
469 case ONOTHEFT:
470 case OSPIRITSCARAB:
471 case OCUBEofUNDEAD:
472 case OPOTION:
473 case OSCROLL:
474 break;
475 default:
476 show3(j);
478 more();
479 nosignal = sigsav;
480 t_endup(count);
484 * function to show the things player can read only
486 static void
487 showread(void)
489 int i, j, sigsav, count;
490 sigsav = nosignal;
491 nosignal = 1; /* don't allow ^c etc */
492 srcount = 0;
494 for (count = 2, j = 0; j <= 26; j++)
495 switch (iven[j]) {
496 case OBOOK:
497 case OSCROLL:
498 count++;
500 t_setup(count);
502 for (i = 22; i < 84; i++)
503 for (j = 0; j <= 26; j++)
504 if (i == iven[j])
505 switch (i) {
506 case OBOOK:
507 case OSCROLL:
508 show3(j);
510 more();
511 nosignal = sigsav;
512 t_endup(count);
516 * function to show the things player can eat only
518 static void
519 showeat(void)
521 int i, j, sigsav, count;
522 sigsav = nosignal;
523 nosignal = 1; /* don't allow ^c etc */
524 srcount = 0;
526 for (count = 2, j = 0; j <= 26; j++)
527 switch (iven[j]) {
528 case OCOOKIE:
529 count++;
531 t_setup(count);
533 for (i = 22; i < 84; i++)
534 for (j = 0; j <= 26; j++)
535 if (i == iven[j])
536 switch (i) {
537 case OCOOKIE:
538 show3(j);
540 more();
541 nosignal = sigsav;
542 t_endup(count);
546 function to show the things player can quaff only
548 static void
549 showquaff(void)
551 int i, j, sigsav, count;
552 sigsav = nosignal;
553 nosignal = 1; /* don't allow ^c etc */
554 srcount = 0;
556 for (count = 2, j = 0; j <= 26; j++)
557 switch (iven[j]) {
558 case OPOTION:
559 count++;
561 t_setup(count);
563 for (i = 22; i < 84; i++)
564 for (j = 0; j <= 26; j++)
565 if (i == iven[j])
566 switch (i) {
567 case OPOTION:
568 show3(j);
570 more();
571 nosignal = sigsav;
572 t_endup(count);
575 static void
576 show1(int idx, const char *str2[])
578 lprintf("\n%c) %s", idx + 'a', objectname[(int)iven[idx]]);
579 if (str2 != NULL && str2[ivenarg[idx]][0] != 0)
580 lprintf(" of%s", str2[ivenarg[idx]]);
583 void
584 show3(int idx)
586 switch (iven[idx]) {
587 case OPOTION:
588 show1(idx, potionname);
589 break;
590 case OSCROLL:
591 show1(idx, scrollname);
592 break;
594 case OLARNEYE:
595 case OBOOK:
596 case OSPIRITSCARAB:
597 case ODIAMOND:
598 case ORUBY:
599 case OCUBEofUNDEAD:
600 case OEMERALD:
601 case OCHEST:
602 case OCOOKIE:
603 case OSAPPHIRE:
604 case ONOTHEFT:
605 show1(idx, NULL);
606 break;
608 default:
609 lprintf("\n%c) %s", idx + 'a', objectname[(int)iven[idx]]);
610 if (ivenarg[idx] > 0)
611 lprintf(" + %d", (long)ivenarg[idx]);
612 else if (ivenarg[idx] < 0)
613 lprintf(" %d", (long)ivenarg[idx]);
614 break;
616 if (c[WIELD] == idx)
617 lprcat(" (weapon in hand)");
618 if ((c[WEAR] == idx) || (c[SHIELD] == idx))
619 lprcat(" (being worn)");
620 if (++srcount >= 22) {
621 srcount = 0;
622 more();
623 clear();
628 subroutine to randomly create monsters if needed
630 static void
631 randmonst(void)
633 if (c[TIMESTOP]) /* don't make monsters if time is stopped */
634 return;
635 if (--rmst <= 0) {
636 rmst = 120 - (level << 2);
637 fillmonst(makemonst(level));
642 parse()
644 get and execute a command
646 static void
647 parse(void)
649 int i, j, k, flag;
650 while (1) {
651 k = yylex();
652 switch (k) { /* get the token from the input and switch on it */
653 case 'h':
654 moveplayer(4);
655 return; /* west */
656 case 'H':
657 run(4);
658 return; /* west */
659 case 'l':
660 moveplayer(2);
661 return; /* east */
662 case 'L':
663 run(2);
664 return; /* east */
665 case 'j':
666 moveplayer(1);
667 return; /* south */
668 case 'J':
669 run(1);
670 return; /* south */
671 case 'k':
672 moveplayer(3);
673 return; /* north */
674 case 'K':
675 run(3);
676 return; /* north */
677 case 'u':
678 moveplayer(5);
679 return; /* northeast */
680 case 'U':
681 run(5);
682 return; /* northeast */
683 case 'y':
684 moveplayer(6);
685 return; /* northwest */
686 case 'Y':
687 run(6);
688 return; /* northwest */
689 case 'n':
690 moveplayer(7);
691 return; /* southeast */
692 case 'N':
693 run(7);
694 return; /* southeast */
695 case 'b':
696 moveplayer(8);
697 return; /* southwest */
698 case 'B':
699 run(8);
700 return; /* southwest */
702 case '.':
703 if (yrepcount)
704 viewflag = 1;
705 return; /* stay here */
707 case 'w':
708 yrepcount = 0;
709 wield();
710 return; /* wield a weapon */
712 case 'W':
713 yrepcount = 0;
714 wear();
715 return; /* wear armor */
717 case 'r':
718 yrepcount = 0;
719 if (c[BLINDCOUNT]) {
720 cursors();
721 lprcat("\nYou can't read anything when you're blind!");
722 } else if (c[TIMESTOP] == 0)
723 readscr();
724 return; /* to read a scroll */
726 case 'q':
727 yrepcount = 0;
728 if (c[TIMESTOP] == 0)
729 quaff();
730 return; /* quaff a potion */
732 case 'd':
733 yrepcount = 0;
734 if (c[TIMESTOP] == 0)
735 dropobj();
736 return; /* to drop an object */
738 case 'c':
739 yrepcount = 0;
740 cast();
741 return; /* cast a spell */
743 case 'i':
744 yrepcount = 0;
745 nomove = 1;
746 showstr();
747 return; /* status */
749 case 'e':
750 yrepcount = 0;
751 if (c[TIMESTOP] == 0)
752 eatcookie();
753 return; /* to eat a fortune cookie */
755 case 'D':
756 yrepcount = 0;
757 seemagic(0);
758 nomove = 1;
759 return; /* list spells and scrolls */
761 case '?':
762 yrepcount = 0;
763 help();
764 nomove = 1;
765 return; /* give the help screen */
767 case 'S':
768 clear();
769 lprcat("Saving . . .");
770 lflush();
771 savegame(savefilename);
772 wizard = 1;
773 died(-257); /* save the game - doesn't return */
775 case 'Z':
776 yrepcount = 0;
777 if (c[LEVEL] > 9) {
778 oteleport(1);
779 return;
781 cursors();
782 lprcat("\nAs yet, you don't have enough experience to use teleportation");
783 return; /* teleport yourself */
785 case '^': /* identify traps */
786 flag = yrepcount = 0;
787 cursors();
788 lprc('\n');
789 for (j = playery - 1; j < playery + 2; j++) {
790 if (j < 0)
791 j = 0;
792 if (j >= MAXY)
793 break;
794 for (i = playerx - 1; i < playerx + 2; i++) {
795 if (i < 0)
796 i = 0;
797 if (i >= MAXX)
798 break;
799 switch (item[i][j]) {
800 case OTRAPDOOR:
801 case ODARTRAP:
802 case OTRAPARROW:
803 case OTELEPORTER:
804 lprcat("\nIts ");
805 lprcat(objectname[(int)item[i][j]]);
806 flag++;
810 if (flag == 0)
811 lprcat("\nNo traps are visible");
812 return;
814 #if WIZID
815 case '_': /* this is the fudge player password for wizard mode */
816 yrepcount = 0;
817 cursors();
818 nomove = 1;
819 if (userid != wisid) {
820 lprcat("Sorry, you are not empowered to be a wizard.\n");
821 scbr(); /* system("stty -echo cbreak"); */
822 lflush();
823 return;
825 if (getpassword() == 0) {
826 scbr(); /* system("stty -echo cbreak"); */
827 return;
829 wizard = 1;
830 scbr(); /* system("stty -echo cbreak"); */
831 for (i = 0; i < 6; i++)
832 c[i] = 70;
833 iven[0] = iven[1] = 0;
834 take(OPROTRING, 50);
835 take(OLANCE, 25);
836 c[WIELD] = 1;
837 c[LANCEDEATH] = 1;
838 c[WEAR] = c[SHIELD] = -1;
839 raiseexperience(6000000L);
840 c[AWARENESS] += 25000;
842 int i, j;
843 for (i = 0; i < MAXY; i++)
844 for (j = 0; j < MAXX; j++)
845 know[j][i] = 1;
846 for (i = 0; i < SPNUM; i++)
847 spelknow[i] = 1;
848 for (i = 0; i < MAXSCROLL; i++)
849 scrollname[i] = scrollhide[i];
850 for (i = 0; i < MAXPOTION; i++)
851 potionname[i] = potionhide[i];
853 for (i = 0; i < MAXSCROLL; i++)
854 if (strlen(scrollname[i]) > 2) { /* no null items */
855 item[i][0] = OSCROLL;
856 iarg[i][0] = i;
858 for (i = MAXX - 1; i > MAXX - 1 - MAXPOTION; i--)
859 if (strlen(potionname[i - MAXX + MAXPOTION]) > 2) { /* no null items */
860 item[i][0] = OPOTION;
861 iarg[i][0] = i - MAXX + MAXPOTION;
863 for (i = 1; i < MAXY; i++) {
864 item[0][i] = i;
865 iarg[0][i] = 0;
867 for (i = MAXY; i < MAXY + MAXX; i++) {
868 item[i - MAXY][MAXY - 1] = i;
869 iarg[i - MAXY][MAXY - 1] = 0;
871 for (i = MAXX + MAXY; i < MAXX + MAXY + MAXY; i++) {
872 item[MAXX - 1][i - MAXX - MAXY] = i;
873 iarg[MAXX - 1][i - MAXX - MAXY] = 0;
875 c[GOLD] += 25000;
876 drawscreen();
877 return;
878 #endif
880 case 'T':
881 yrepcount = 0;
882 cursors();
883 if (c[SHIELD] != -1) {
884 c[SHIELD] = -1;
885 lprcat("\nYour shield is off");
886 bottomline();
887 } else if (c[WEAR] != -1) {
888 c[WEAR] = -1;
889 lprcat("\nYour armor is off");
890 bottomline();
891 } else
892 lprcat("\nYou aren't wearing anything");
893 return;
895 case 'g':
896 cursors();
897 lprintf("\nThe stuff you are carrying presently weighs %d pounds", (long)packweight());
898 case ' ':
899 yrepcount = 0;
900 nomove = 1;
901 return;
903 case 'v':
904 yrepcount = 0;
905 cursors();
906 lprintf("\nCaverns of Larn, Version %d.%d, Diff=%d", (long)VERSION, (long)SUBVERSION, (long)c[HARDGAME]);
907 if (wizard)
908 lprcat(" Wizard");
909 nomove = 1;
910 if (cheat)
911 lprcat(" Cheater");
912 lprcat(copyright);
913 return;
915 case 'Q':
916 yrepcount = 0;
917 quit();
918 nomove = 1;
919 return; /* quit */
921 case 'L' - 64:
922 yrepcount = 0;
923 drawscreen();
924 nomove = 1;
925 return; /* look */
927 #if WIZID
928 #ifdef EXTRA
929 case 'A':
930 yrepcount = 0;
931 nomove = 1;
932 if (wizard) {
933 diag();
934 return;
935 } /* create diagnostic file */
936 return;
937 #endif
938 #endif
939 case 'P':
940 cursors();
941 if (outstanding_taxes > 0)
942 lprintf("\nYou presently owe %d gp in taxes.", (long)outstanding_taxes);
943 else
944 lprcat("\nYou do not owe any taxes.");
945 return;
950 void
951 parse2(void)
953 if (c[HASTEMONST])
954 movemonst();
955 movemonst(); /* move the monsters */
956 randmonst();
957 regen();
960 static void
961 run(int dir)
963 int i;
964 i = 1;
965 while (i) {
966 i = moveplayer(dir);
967 if (i > 0) {
968 if (c[HASTEMONST])
969 movemonst();
970 movemonst();
971 randmonst();
972 regen();
974 if (hitflag)
975 i = 0;
976 if (i != 0)
977 showcell(playerx, playery);
982 function to wield a weapon
984 static void
985 wield(void)
987 int i;
988 while (1) {
989 if ((i = whatitem("wield")) == '\33')
990 return;
991 if (i != '.') {
992 if (i == '*')
993 showwield();
994 else if (iven[i - 'a'] == 0) {
995 ydhi(i);
996 return;
997 } else if (iven[i - 'a'] == OPOTION) {
998 ycwi(i);
999 return;
1000 } else if (iven[i - 'a'] == OSCROLL) {
1001 ycwi(i);
1002 return;
1003 } else if ((c[SHIELD] != -1) && (iven[i - 'a'] == O2SWORD)) {
1004 lprcat("\nBut one arm is busy with your shield!");
1005 return;
1006 } else {
1007 c[WIELD] = i - 'a';
1008 if (iven[i - 'a'] == OLANCE)
1009 c[LANCEDEATH] = 1;
1010 else
1011 c[LANCEDEATH] = 0;
1012 bottomline();
1013 return;
1020 common routine to say you don't have an item
1022 static void
1023 ydhi(int x)
1025 cursors();
1026 lprintf("\nYou don't have item %c!", x);
1029 static void
1030 ycwi(int x)
1032 cursors();
1033 lprintf("\nYou can't wield item %c!", x);
1037 function to wear armor
1039 static void
1040 wear(void)
1042 int i;
1043 while (1) {
1044 if ((i = whatitem("wear")) == '\33')
1045 return;
1046 if (i != '.') {
1047 if (i == '*')
1048 showwear();
1049 else
1050 switch (iven[i - 'a']) {
1051 case 0:
1052 ydhi(i);
1053 return;
1054 case OLEATHER:
1055 case OCHAIN:
1056 case OPLATE:
1057 case OSTUDLEATHER:
1058 case ORING:
1059 case OSPLINT:
1060 case OPLATEARMOR:
1061 case OSSPLATE:
1062 if (c[WEAR] != -1) {
1063 lprcat("\nYou're already wearing some armor");
1064 return;
1066 c[WEAR] = i - 'a';
1067 bottomline();
1068 return;
1069 case OSHIELD:
1070 if (c[SHIELD] != -1) {
1071 lprcat("\nYou are already wearing a shield");
1072 return;
1074 if (iven[c[WIELD]] == O2SWORD) {
1075 lprcat("\nYour hands are busy with the two handed sword!");
1076 return;
1078 c[SHIELD] = i - 'a';
1079 bottomline();
1080 return;
1081 default:
1082 lprcat("\nYou can't wear that!");
1089 function to drop an object
1091 static void
1092 dropobj(void)
1094 int i;
1095 char *p;
1096 long amt;
1097 p = &item[playerx][playery];
1098 while (1) {
1099 if ((i = whatitem("drop")) == '\33')
1100 return;
1101 if (i == '*')
1102 showstr();
1103 else {
1104 if (i == '.') { /* drop some gold */
1105 if (*p) {
1106 lprcat("\nThere's something here already!");
1107 return;
1109 lprcat("\n\n");
1110 cl_dn(1, 23);
1111 lprcat("How much gold do you drop? ");
1112 if ((amt = readnum((long)c[GOLD])) == 0)
1113 return;
1114 if (amt > c[GOLD]) {
1115 lprcat("\nYou don't have that much!");
1116 return;
1118 if (amt <= 32767) {
1119 *p = OGOLDPILE;
1120 i = amt;
1121 } else if (amt <= 327670L) {
1122 *p = ODGOLD;
1123 i = amt / 10;
1124 amt = 10 * i;
1125 } else if (amt <= 3276700L) {
1126 *p = OMAXGOLD;
1127 i = amt / 100;
1128 amt = 100 * i;
1129 } else if (amt <= 32767000L) {
1130 *p = OKGOLD;
1131 i = amt / 1000;
1132 amt = 1000 * i;
1133 } else {
1134 *p = OKGOLD;
1135 i = 32767;
1136 amt = 32767000L;
1138 c[GOLD] -= amt;
1139 lprintf("You drop %d gold pieces", (long)amt);
1140 iarg[playerx][playery] = i;
1141 bottomgold();
1142 know[playerx][playery] = 0;
1143 dropflag = 1;
1144 return;
1146 drop_object(i - 'a');
1147 return;
1153 * readscr() Subroutine to read a scroll one is carrying
1155 static void
1156 readscr(void)
1158 int i;
1159 while (1) {
1160 if ((i = whatitem("read")) == '\33')
1161 return;
1162 if (i != '.') {
1163 if (i == '*')
1164 showread();
1165 else {
1166 if (iven[i - 'a'] == OSCROLL) {
1167 read_scroll(ivenarg[i - 'a']);
1168 iven[i - 'a'] = 0;
1169 return;
1171 if (iven[i - 'a'] == OBOOK) {
1172 readbook(ivenarg[i - 'a']);
1173 iven[i - 'a'] = 0;
1174 return;
1176 if (iven[i - 'a'] == 0) {
1177 ydhi(i);
1178 return;
1180 lprcat("\nThere's nothing on it to read");
1181 return;
1188 * subroutine to eat a cookie one is carrying
1190 static void
1191 eatcookie(void)
1193 int i;
1194 const char *p;
1196 while (1) {
1197 if ((i = whatitem("eat")) == '\33')
1198 return;
1199 if (i != '.') {
1200 if (i == '*')
1201 showeat();
1202 else {
1203 if (iven[i - 'a'] == OCOOKIE) {
1204 lprcat("\nThe cookie was delicious.");
1205 iven[i - 'a'] = 0;
1206 if (!c[BLINDCOUNT]) {
1207 if ((p = fortune()) != NULL) {
1208 lprcat(" Inside you find a scrap of paper that says:\n");
1209 lprcat(p);
1212 return;
1214 if (iven[i - 'a'] == 0) {
1215 ydhi(i);
1216 return;
1218 lprcat("\nYou can't eat that!");
1219 return;
1226 * subroutine to quaff a potion one is carrying
1228 static void
1229 quaff(void)
1231 int i;
1232 while (1) {
1233 if ((i = whatitem("quaff")) == '\33')
1234 return;
1235 if (i != '.') {
1236 if (i == '*')
1237 showquaff();
1238 else {
1239 if (iven[i - 'a'] == OPOTION) {
1240 quaffpotion(ivenarg[i - 'a']);
1241 iven[i - 'a'] = 0;
1242 return;
1244 if (iven[i - 'a'] == 0) {
1245 ydhi(i);
1246 return;
1248 lprcat("\nYou wouldn't want to quaff that, would you? ");
1249 return;
1256 function to ask what player wants to do
1258 static int
1259 whatitem(const char *str)
1261 int i;
1262 cursors();
1263 lprintf("\nWhat do you want to %s [* for all] ? ", str);
1264 i = 0;
1265 while (i > 'z' || (i < 'a' && i != '*' && i != '\33' && i != '.'))
1266 i = getchr();
1267 if (i == '\33')
1268 lprcat(" aborted");
1269 return (i);
1273 subroutine to get a number from the player
1274 and allow * to mean return amt, else return the number entered
1276 unsigned long
1277 readnum(long mx)
1279 int i;
1280 unsigned long amt = 0;
1281 sncbr();
1282 if ((i = getchr()) == '*')
1283 amt = mx; /* allow him to say * for all gold */
1284 else
1285 while (i != '\n') {
1286 if (i == '\033') {
1287 scbr();
1288 lprcat(" aborted");
1289 return (0);
1291 if ((i <= '9') && (i >= '0') && (amt < 99999999))
1292 amt = amt * 10 + i - '0';
1293 i = getchr();
1295 scbr();
1296 return (amt);
1299 #ifdef HIDEBYLINK
1301 * routine to zero every byte in a string
1303 static void
1304 szero(char *str)
1306 while (*str)
1307 *str++ = 0;
1309 #endif /* HIDEBYLINK */