kernel - Restore ability to thaw checkpoints
[dragonfly.git] / games / larn / main.c
blob77aa76166905c671fe17809e9836302577779c33
1 /* $FreeBSD: src/games/larn/main.c,v 1.9 1999/11/30 03:48:59 billf Exp $ */
2 /* $DragonFly: src/games/larn/main.c,v 1.5 2008/06/05 18:06:30 swildner Exp $ */
3 /* main.c */
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include "header.h"
7 #include <pwd.h>
8 static const char copyright[] = "\nLarn is copyrighted 1986 by Noah Morgan.\n";
9 int srcount = 0; /* line counter for showstr() */
10 int dropflag = 0; /* if 1 then don't lookforobject() next round */
11 int rmst = 80; /* random monster creation counter */
12 int userid; /* the players login user id number */
13 char nowelcome = 0, nomove = 0; /* if (nomove) then don't count next iteration as a move */
14 static char viewflag = 0;
15 /* if viewflag then we have done a 99 stay here and don't showcell in the main loop */
16 char restorflag=0; /* 1 means restore has been done */
17 static char cmdhelp[] = "\
18 Cmd line format: larn [-slicnh] [-o<optsifle>] [-##] [++]\n\
19 -s show the scoreboard\n\
20 -l show the logfile (wizard id only)\n\
21 -i show scoreboard with inventories of dead characters\n\
22 -c create new scoreboard (wizard id only)\n\
23 -n suppress welcome message on starting game\n\
24 -## specify level of difficulty (example: -5)\n\
25 -h print this help text\n\
26 ++ restore game from checkpoint file\n\
27 -o<optsfile> specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
29 #ifdef VT100
30 static const char *termtypes[] = { "vt100", "vt101", "vt102", "vt103", "vt125",
31 "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340",
32 "vt341" };
33 #endif /* VT100 */
35 static void showstr(void);
36 static void t_setup(int);
37 static void t_endup(int);
38 static void showwear(void);
39 static void showwield(void);
40 static void showread(void);
41 static void showeat(void);
42 static void showquaff(void);
43 static void show1(int, const char **);
44 static void randmonst(void);
45 static void parse(void);
46 static void run(int);
47 static void wield(void);
48 static void ydhi(int);
49 static void ycwi(int);
50 static void wear(void);
51 static void dropobj(void);
52 static void readscr(void);
53 static void eatcookie(void);
54 static void quaff(void);
55 static int whatitem(const char *);
56 #ifdef HIDEBYLINK
57 static void szero(char *);
58 #endif
61 ************
62 MAIN PROGRAM
63 ************
65 int
66 main(int argc, char **argv)
68 int i;
69 int hard;
70 const char *ptr;
71 #ifdef VT100
72 char *ttype;
73 int j;
74 #endif
75 struct passwd *pwe;
76 struct stat sb;
79 * first task is to identify the player
81 #ifndef VT100
82 init_term(); /* setup the terminal (find out what type) for termcap */
83 #endif /* VT100 */
84 /* try to get login name */
85 if (((ptr = getlogin()) == 0) || (*ptr == 0)) {
86 /* can we get it from /etc/passwd? */
87 if ((pwe = getpwuid(getuid())) != NULL)
88 ptr = pwe->pw_name;
89 else if ((ptr = getenv("USER")) == 0)
90 if ((ptr = getenv("LOGNAME")) == 0) {
91 noone: write(2, "Can't find your logname. Who Are You?\n", 39);
92 exit(1);
95 if (ptr == 0)
96 goto noone;
97 if (strlen(ptr) == 0)
98 goto noone;
101 * second task is to prepare the pathnames the player will need
103 strcpy(loginname, ptr); /* save loginname of the user for logging purposes */
104 strcpy(logname, ptr); /* this will be overwritten with the players name */
105 if ((ptr = getenv("HOME")) == 0)
106 ptr = ".";
107 strcpy(savefilename, ptr);
108 strcat(savefilename, "/Larn.sav"); /* save file name in home directory */
109 sprintf(optsfile, "%s/.larnopts", ptr); /* the .larnopts filename */
112 * now malloc the memory for the dungeon
114 cell = malloc(sizeof(struct cel) * (MAXLEVEL + MAXVLEVEL) * MAXX * MAXY);
115 if (cell == NULL) /* malloc failure */
116 died(-285);
117 lpbuf = malloc((5 * BUFBIG) >> 2); /* output buffer */
118 inbuffer = malloc((5 * MAXIBUF) >> 2); /* output buffer */
119 if ((lpbuf == NULL) || (inbuffer == NULL)) /* malloc() failure */
120 died(-285);
122 lcreat(NULL);
123 newgame(); /* set the initial clock */
124 hard = -1;
126 #ifdef VT100
128 * check terminal type to avoid users who have not vt100 type terminals
130 ttype = getenv("TERM");
131 for (j = 1, i = 0; i < sizeof(termtypes) / sizeof(char *); i++)
132 if (strcmp(ttype, termtypes[i]) == 0) {
133 j = 0;
134 break;
136 if (j) {
137 lprcat("Sorry, Larn needs a VT100 family terminal for all it's features.\n");
138 lflush();
139 exit(1);
141 #endif /* VT100 */
144 * now make scoreboard if it is not there (don't clear)
146 if (stat(scorefile, &sb) < 0 || sb.st_size == 0) /* not there */
147 makeboard();
150 * now process the command line arguments
152 for (i = 1; i < argc; i++) {
153 if (argv[i][0] == '-')
154 switch (argv[i][1]) {
155 case 's':
156 showscores();
157 exit(0); /* show scoreboard */
159 case 'l': /* show log file */
160 diedlog();
161 exit(0);
163 case 'i':
164 showallscores();
165 exit(0); /* show all scoreboard */
167 case 'c': /* anyone with password can create scoreboard */
168 lprcat("Preparing to initialize the scoreboard.\n");
169 if (getpassword() != 0) { /* make new scoreboard */
170 makeboard();
171 lprc('\n');
172 showscores();
174 exit(0);
176 case 'n': /* no welcome msg */
177 nowelcome = 1;
178 argv[i][0] = 0;
179 break;
181 case '0':
182 case '1':
183 case '2':
184 case '3':
185 case '4':
186 case '5':
187 case '6':
188 case '7':
189 case '8':
190 case '9': /* for hardness */
191 sscanf(&argv[i][1], "%d", &hard);
192 break;
194 case 'h': /* print out command line arguments */
195 write(1, cmdhelp, sizeof(cmdhelp));
196 exit(0);
198 case 'o': /* specify a .larnopts filename */
199 strncpy(optsfile, argv[i] + 2, 127);
200 break;
202 default:
203 printf("Unknown option <%s>\n", argv[i]);
204 exit(1);
207 if (argv[i][0] == '+') {
208 clear();
209 restorflag = 1;
210 if (argv[i][1] == '+') {
211 hitflag = 1;
212 restoregame(ckpfile); /* restore checkpointed game */
214 i = argc;
218 readopts(); /* read the options file if there is one */
221 #ifdef UIDSCORE
222 userid = geteuid(); /* obtain the user's effective id number */
223 #else /* UIDSCORE */
224 userid = getplid(logname); /* obtain the players id number */
225 #endif /* UIDSCORE */
226 if (userid < 0) {
227 write(2, "Can't obtain playerid\n", 22);
228 exit(1);
231 #ifdef HIDEBYLINK
233 * this section of code causes the program to look like something else to ps
235 if (strcmp(psname, argv[0])) { /* if a different process name only */
236 if ((i = access(psname, 1)) < 0) { /* link not there */
237 if (link(argv[0], psname) >= 0) {
238 argv[0] = psname;
239 execv(psname, argv);
241 } else
242 unlink(psname);
245 for (i = 1; i < argc; i++) {
246 szero(argv[i]); /* zero the argument to avoid ps snooping */
248 #endif /* HIDEBYLINK */
250 if (access(savefilename, 0) == 0) { /* restore game if need to */
251 clear();
252 restorflag = 1;
253 hitflag = 1;
254 restoregame(savefilename); /* restore last game */
256 sigsetup(); /* trap all needed signals */
257 sethard(hard); /* set up the desired difficulty */
258 setupvt100(); /* setup the terminal special mode */
259 if (c[HP] == 0) { /* create new game */
260 makeplayer(); /* make the character that will play */
261 newcavelevel(0);/* make the dungeon */
262 predostuff = 1; /* tell signals that we are in the welcome screen */
263 if (nowelcome == 0)
264 welcome(); /* welcome the player to the game */
266 drawscreen(); /* show the initial dungeon */
267 predostuff = 2; /* tell the trap functions that they must do
268 * a showplayer() from here on */
269 #if 0
270 nice(1); /* games should be run niced */
271 #endif
272 yrepcount = hit2flag = 0;
273 while (1) {
274 if (dropflag == 0) /* see if there is an object here */
275 lookforobject();
276 else /* don't show it just dropped an item */
277 dropflag = 0;
278 if (hitflag == 0) {
279 if (c[HASTEMONST])
280 movemonst();
281 movemonst();
282 } /* move the monsters */
283 if (viewflag == 0)
284 showcell(playerx, playery);
285 else
286 viewflag = 0; /* show stuff around player */
287 if (hit3flag)
288 flushall();
289 hitflag = hit3flag = 0;
290 nomove = 1;
291 bot_linex(); /* update bottom line */
292 while (nomove) {
293 if (hit3flag)
294 flushall();
295 nomove = 0;
296 parse();
297 } /* get commands and make moves */
298 regen(); /* regenerate hp and spells */
299 if (c[TIMESTOP] == 0)
300 if (--rmst <= 0) {
301 rmst = 120 - (level << 2);
302 fillmonst(makemonst(level));
308 showstr()
310 show character's inventory
312 static void
313 showstr(void)
315 int i, number;
316 for (number = 3, i = 0; i < 26; i++)
317 if (iven[i]) /* count items in inventory */
318 number++;
319 t_setup(number);
320 qshowstr();
321 t_endup(number);
324 void
325 qshowstr(void)
327 int i, j, k, sigsav;
328 srcount = 0;
329 sigsav = nosignal;
330 nosignal = 1; /* don't allow ^c etc */
331 if (c[GOLD]) {
332 lprintf(".) %d gold pieces", (long)c[GOLD]);
333 srcount++;
335 for (k = 26; k >= 0; k--)
336 if (iven[k]) {
337 for (i = 22; i < 84; i++)
338 for (j = 0; j <= k; j++)
339 if (i == iven[j])
340 show3(j);
341 k = 0;
344 lprintf("\nElapsed time is %d. You have %d mobuls left", (long)((gtime + 99) / 100 + 1), (long)((TIMELIMIT - gtime) / 100));
345 more();
346 nosignal = sigsav;
350 * subroutine to clear screen depending on # lines to display
352 static void
353 t_setup(int count)
355 if (count < 20) { /* how do we clear the screen? */
356 cl_up(79, count);
357 cursor(1, 1);
358 } else {
359 resetscroll();
360 clear();
365 * subroutine to restore normal display screen depending on t_setup()
367 static void
368 t_endup(int count)
370 if (count < 18) /* how did we clear the screen? */
371 draws(0, MAXX, 0, (count > MAXY) ? MAXY : count);
372 else {
373 drawscreen();
374 setscroll();
379 function to show the things player is wearing only
381 static void
382 showwear(void)
384 int i, j, sigsav, count;
385 sigsav = nosignal;
386 nosignal = 1; /* don't allow ^c etc */
387 srcount = 0;
389 for (count = 2, j = 0; j <= 26; j++) /* count number of items we will display */
390 if ((i = iven[j]) != 0)
391 switch (i) {
392 case OLEATHER:
393 case OPLATE:
394 case OCHAIN:
395 case ORING:
396 case OSTUDLEATHER:
397 case OSPLINT:
398 case OPLATEARMOR:
399 case OSSPLATE:
400 case OSHIELD:
401 count++;
404 t_setup(count);
406 for (i = 22; i < 84; i++)
407 for (j = 0; j <= 26; j++)
408 if (i == iven[j])
409 switch (i) {
410 case OLEATHER:
411 case OPLATE:
412 case OCHAIN:
413 case ORING:
414 case OSTUDLEATHER:
415 case OSPLINT:
416 case OPLATEARMOR:
417 case OSSPLATE:
418 case OSHIELD:
419 show3(j);
421 more();
422 nosignal = sigsav;
423 t_endup(count);
427 function to show the things player can wield only
429 static void
430 showwield(void)
432 int i, j, sigsav, count;
433 sigsav = nosignal;
434 nosignal = 1; /* don't allow ^c etc */
435 srcount = 0;
437 for (count = 2, j = 0; j <= 26; j++) /* count how many items */
438 if ((i = iven[j]) != 0)
439 switch (i) {
440 case ODIAMOND:
441 case ORUBY:
442 case OEMERALD:
443 case OSAPPHIRE:
444 case OBOOK:
445 case OCHEST:
446 case OLARNEYE:
447 case ONOTHEFT:
448 case OSPIRITSCARAB:
449 case OCUBEofUNDEAD:
450 case OPOTION:
451 case OSCROLL:
452 break;
453 default:
454 count++;
457 t_setup(count);
459 for (i = 22; i < 84; i++)
460 for (j = 0; j <= 26; j++)
461 if (i == iven[j])
462 switch (i) {
463 case ODIAMOND:
464 case ORUBY:
465 case OEMERALD:
466 case OSAPPHIRE:
467 case OBOOK:
468 case OCHEST:
469 case OLARNEYE:
470 case ONOTHEFT:
471 case OSPIRITSCARAB:
472 case OCUBEofUNDEAD:
473 case OPOTION:
474 case OSCROLL:
475 break;
476 default:
477 show3(j);
479 more();
480 nosignal = sigsav;
481 t_endup(count);
485 * function to show the things player can read only
487 static void
488 showread(void)
490 int i, j, sigsav, count;
491 sigsav = nosignal;
492 nosignal = 1; /* don't allow ^c etc */
493 srcount = 0;
495 for (count = 2, j = 0; j <= 26; j++)
496 switch (iven[j]) {
497 case OBOOK:
498 case OSCROLL:
499 count++;
501 t_setup(count);
503 for (i = 22; i < 84; i++)
504 for (j = 0; j <= 26; j++)
505 if (i == iven[j])
506 switch (i) {
507 case OBOOK:
508 case OSCROLL:
509 show3(j);
511 more();
512 nosignal = sigsav;
513 t_endup(count);
517 * function to show the things player can eat only
519 static void
520 showeat(void)
522 int i, j, sigsav, count;
523 sigsav = nosignal;
524 nosignal = 1; /* don't allow ^c etc */
525 srcount = 0;
527 for (count = 2, j = 0; j <= 26; j++)
528 switch (iven[j]) {
529 case OCOOKIE:
530 count++;
532 t_setup(count);
534 for (i = 22; i < 84; i++)
535 for (j = 0; j <= 26; j++)
536 if (i == iven[j])
537 switch (i) {
538 case OCOOKIE:
539 show3(j);
541 more();
542 nosignal = sigsav;
543 t_endup(count);
547 function to show the things player can quaff only
549 static void
550 showquaff(void)
552 int i, j, sigsav, count;
553 sigsav = nosignal;
554 nosignal = 1; /* don't allow ^c etc */
555 srcount = 0;
557 for (count = 2, j = 0; j <= 26; j++)
558 switch (iven[j]) {
559 case OPOTION:
560 count++;
562 t_setup(count);
564 for (i = 22; i < 84; i++)
565 for (j = 0; j <= 26; j++)
566 if (i == iven[j])
567 switch (i) {
568 case OPOTION:
569 show3(j);
571 more();
572 nosignal = sigsav;
573 t_endup(count);
576 static void
577 show1(int idx, const char *str2[])
579 lprintf("\n%c) %s", idx + 'a', objectname[(int)iven[idx]]);
580 if (str2 != NULL && str2[ivenarg[idx]][0] != 0)
581 lprintf(" of%s", str2[ivenarg[idx]]);
584 void
585 show3(int idx)
587 switch (iven[idx]) {
588 case OPOTION:
589 show1(idx, potionname);
590 break;
591 case OSCROLL:
592 show1(idx, scrollname);
593 break;
595 case OLARNEYE:
596 case OBOOK:
597 case OSPIRITSCARAB:
598 case ODIAMOND:
599 case ORUBY:
600 case OCUBEofUNDEAD:
601 case OEMERALD:
602 case OCHEST:
603 case OCOOKIE:
604 case OSAPPHIRE:
605 case ONOTHEFT:
606 show1(idx, NULL);
607 break;
609 default:
610 lprintf("\n%c) %s", idx + 'a', objectname[(int)iven[idx]]);
611 if (ivenarg[idx] > 0)
612 lprintf(" + %d", (long)ivenarg[idx]);
613 else if (ivenarg[idx] < 0)
614 lprintf(" %d", (long)ivenarg[idx]);
615 break;
617 if (c[WIELD] == idx)
618 lprcat(" (weapon in hand)");
619 if ((c[WEAR] == idx) || (c[SHIELD] == idx))
620 lprcat(" (being worn)");
621 if (++srcount >= 22) {
622 srcount = 0;
623 more();
624 clear();
629 subroutine to randomly create monsters if needed
631 static void
632 randmonst(void)
634 if (c[TIMESTOP]) /* don't make monsters if time is stopped */
635 return;
636 if (--rmst <= 0) {
637 rmst = 120 - (level << 2);
638 fillmonst(makemonst(level));
643 parse()
645 get and execute a command
647 static void
648 parse(void)
650 int i, j, k, flag;
651 while (1) {
652 k = yylex();
653 switch (k) { /* get the token from the input and switch on it */
654 case 'h':
655 moveplayer(4);
656 return; /* west */
657 case 'H':
658 run(4);
659 return; /* west */
660 case 'l':
661 moveplayer(2);
662 return; /* east */
663 case 'L':
664 run(2);
665 return; /* east */
666 case 'j':
667 moveplayer(1);
668 return; /* south */
669 case 'J':
670 run(1);
671 return; /* south */
672 case 'k':
673 moveplayer(3);
674 return; /* north */
675 case 'K':
676 run(3);
677 return; /* north */
678 case 'u':
679 moveplayer(5);
680 return; /* northeast */
681 case 'U':
682 run(5);
683 return; /* northeast */
684 case 'y':
685 moveplayer(6);
686 return; /* northwest */
687 case 'Y':
688 run(6);
689 return; /* northwest */
690 case 'n':
691 moveplayer(7);
692 return; /* southeast */
693 case 'N':
694 run(7);
695 return; /* southeast */
696 case 'b':
697 moveplayer(8);
698 return; /* southwest */
699 case 'B':
700 run(8);
701 return; /* southwest */
703 case '.':
704 if (yrepcount)
705 viewflag = 1;
706 return; /* stay here */
708 case 'w':
709 yrepcount = 0;
710 wield();
711 return; /* wield a weapon */
713 case 'W':
714 yrepcount = 0;
715 wear();
716 return; /* wear armor */
718 case 'r':
719 yrepcount = 0;
720 if (c[BLINDCOUNT]) {
721 cursors();
722 lprcat("\nYou can't read anything when you're blind!");
723 } else if (c[TIMESTOP] == 0)
724 readscr();
725 return; /* to read a scroll */
727 case 'q':
728 yrepcount = 0;
729 if (c[TIMESTOP] == 0)
730 quaff();
731 return; /* quaff a potion */
733 case 'd':
734 yrepcount = 0;
735 if (c[TIMESTOP] == 0)
736 dropobj();
737 return; /* to drop an object */
739 case 'c':
740 yrepcount = 0;
741 cast();
742 return; /* cast a spell */
744 case 'i':
745 yrepcount = 0;
746 nomove = 1;
747 showstr();
748 return; /* status */
750 case 'e':
751 yrepcount = 0;
752 if (c[TIMESTOP] == 0)
753 eatcookie();
754 return; /* to eat a fortune cookie */
756 case 'D':
757 yrepcount = 0;
758 seemagic(0);
759 nomove = 1;
760 return; /* list spells and scrolls */
762 case '?':
763 yrepcount = 0;
764 help();
765 nomove = 1;
766 return; /* give the help screen */
768 case 'S':
769 clear();
770 lprcat("Saving . . .");
771 lflush();
772 savegame(savefilename);
773 wizard = 1;
774 died(-257); /* save the game - doesn't return */
776 case 'Z':
777 yrepcount = 0;
778 if (c[LEVEL] > 9) {
779 oteleport(1);
780 return;
782 cursors();
783 lprcat("\nAs yet, you don't have enough experience to use teleportation");
784 return; /* teleport yourself */
786 case '^': /* identify traps */
787 flag = yrepcount = 0;
788 cursors();
789 lprc('\n');
790 for (j = playery - 1; j < playery + 2; j++) {
791 if (j < 0)
792 j = 0;
793 if (j >= MAXY)
794 break;
795 for (i = playerx - 1; i < playerx + 2; i++) {
796 if (i < 0)
797 i = 0;
798 if (i >= MAXX)
799 break;
800 switch (item[i][j]) {
801 case OTRAPDOOR:
802 case ODARTRAP:
803 case OTRAPARROW:
804 case OTELEPORTER:
805 lprcat("\nIts ");
806 lprcat(objectname[(int)item[i][j]]);
807 flag++;
811 if (flag == 0)
812 lprcat("\nNo traps are visible");
813 return;
815 #if WIZID
816 case '_': /* this is the fudge player password for wizard mode */
817 yrepcount = 0;
818 cursors();
819 nomove = 1;
820 if (userid != wisid) {
821 lprcat("Sorry, you are not empowered to be a wizard.\n");
822 scbr(); /* system("stty -echo cbreak"); */
823 lflush();
824 return;
826 if (getpassword() == 0) {
827 scbr(); /* system("stty -echo cbreak"); */
828 return;
830 wizard = 1;
831 scbr(); /* system("stty -echo cbreak"); */
832 for (i = 0; i < 6; i++)
833 c[i] = 70;
834 iven[0] = iven[1] = 0;
835 take(OPROTRING, 50);
836 take(OLANCE, 25);
837 c[WIELD] = 1;
838 c[LANCEDEATH] = 1;
839 c[WEAR] = c[SHIELD] = -1;
840 raiseexperience(6000000L);
841 c[AWARENESS] += 25000;
843 int i, j;
844 for (i = 0; i < MAXY; i++)
845 for (j = 0; j < MAXX; j++)
846 know[j][i] = 1;
847 for (i = 0; i < SPNUM; i++)
848 spelknow[i] = 1;
849 for (i = 0; i < MAXSCROLL; i++)
850 scrollname[i] = scrollhide[i];
851 for (i = 0; i < MAXPOTION; i++)
852 potionname[i] = potionhide[i];
854 for (i = 0; i < MAXSCROLL; i++)
855 if (strlen(scrollname[i]) > 2) { /* no null items */
856 item[i][0] = OSCROLL;
857 iarg[i][0] = i;
859 for (i = MAXX - 1; i > MAXX - 1 - MAXPOTION; i--)
860 if (strlen(potionname[i - MAXX + MAXPOTION]) > 2) { /* no null items */
861 item[i][0] = OPOTION;
862 iarg[i][0] = i - MAXX + MAXPOTION;
864 for (i = 1; i < MAXY; i++) {
865 item[0][i] = i;
866 iarg[0][i] = 0;
868 for (i = MAXY; i < MAXY + MAXX; i++) {
869 item[i - MAXY][MAXY - 1] = i;
870 iarg[i - MAXY][MAXY - 1] = 0;
872 for (i = MAXX + MAXY; i < MAXX + MAXY + MAXY; i++) {
873 item[MAXX - 1][i - MAXX - MAXY] = i;
874 iarg[MAXX - 1][i - MAXX - MAXY] = 0;
876 c[GOLD] += 25000;
877 drawscreen();
878 return;
879 #endif
881 case 'T':
882 yrepcount = 0;
883 cursors();
884 if (c[SHIELD] != -1) {
885 c[SHIELD] = -1;
886 lprcat("\nYour shield is off");
887 bottomline();
888 } else if (c[WEAR] != -1) {
889 c[WEAR] = -1;
890 lprcat("\nYour armor is off");
891 bottomline();
892 } else
893 lprcat("\nYou aren't wearing anything");
894 return;
896 case 'g':
897 cursors();
898 lprintf("\nThe stuff you are carrying presently weighs %d pounds", (long)packweight());
899 case ' ':
900 yrepcount = 0;
901 nomove = 1;
902 return;
904 case 'v':
905 yrepcount = 0;
906 cursors();
907 lprintf("\nCaverns of Larn, Version %d.%d, Diff=%d", (long)VERSION, (long)SUBVERSION, (long)c[HARDGAME]);
908 if (wizard)
909 lprcat(" Wizard");
910 nomove = 1;
911 if (cheat)
912 lprcat(" Cheater");
913 lprcat(copyright);
914 return;
916 case 'Q':
917 yrepcount = 0;
918 quit();
919 nomove = 1;
920 return; /* quit */
922 case 'L' - 64:
923 yrepcount = 0;
924 drawscreen();
925 nomove = 1;
926 return; /* look */
928 #if WIZID
929 #ifdef EXTRA
930 case 'A':
931 yrepcount = 0;
932 nomove = 1;
933 if (wizard) {
934 diag();
935 return;
936 } /* create diagnostic file */
937 return;
938 #endif
939 #endif
940 case 'P':
941 cursors();
942 if (outstanding_taxes > 0)
943 lprintf("\nYou presently owe %d gp in taxes.", (long)outstanding_taxes);
944 else
945 lprcat("\nYou do not owe any taxes.");
946 return;
951 void
952 parse2(void)
954 if (c[HASTEMONST])
955 movemonst();
956 movemonst(); /* move the monsters */
957 randmonst();
958 regen();
961 static void
962 run(int dir)
964 int i;
965 i = 1;
966 while (i) {
967 i = moveplayer(dir);
968 if (i > 0) {
969 if (c[HASTEMONST])
970 movemonst();
971 movemonst();
972 randmonst();
973 regen();
975 if (hitflag)
976 i = 0;
977 if (i != 0)
978 showcell(playerx, playery);
983 function to wield a weapon
985 static void
986 wield(void)
988 int i;
989 while (1) {
990 if ((i = whatitem("wield")) == '\33')
991 return;
992 if (i != '.') {
993 if (i == '*')
994 showwield();
995 else if (iven[i - 'a'] == 0) {
996 ydhi(i);
997 return;
998 } else if (iven[i - 'a'] == OPOTION) {
999 ycwi(i);
1000 return;
1001 } else if (iven[i - 'a'] == OSCROLL) {
1002 ycwi(i);
1003 return;
1004 } else if ((c[SHIELD] != -1) && (iven[i - 'a'] == O2SWORD)) {
1005 lprcat("\nBut one arm is busy with your shield!");
1006 return;
1007 } else {
1008 c[WIELD] = i - 'a';
1009 if (iven[i - 'a'] == OLANCE)
1010 c[LANCEDEATH] = 1;
1011 else
1012 c[LANCEDEATH] = 0;
1013 bottomline();
1014 return;
1021 common routine to say you don't have an item
1023 static void
1024 ydhi(int x)
1026 cursors();
1027 lprintf("\nYou don't have item %c!", x);
1030 static void
1031 ycwi(int x)
1033 cursors();
1034 lprintf("\nYou can't wield item %c!", x);
1038 function to wear armor
1040 static void
1041 wear(void)
1043 int i;
1044 while (1) {
1045 if ((i = whatitem("wear")) == '\33')
1046 return;
1047 if (i != '.') {
1048 if (i == '*')
1049 showwear();
1050 else
1051 switch (iven[i - 'a']) {
1052 case 0:
1053 ydhi(i);
1054 return;
1055 case OLEATHER:
1056 case OCHAIN:
1057 case OPLATE:
1058 case OSTUDLEATHER:
1059 case ORING:
1060 case OSPLINT:
1061 case OPLATEARMOR:
1062 case OSSPLATE:
1063 if (c[WEAR] != -1) {
1064 lprcat("\nYou're already wearing some armor");
1065 return;
1067 c[WEAR] = i - 'a';
1068 bottomline();
1069 return;
1070 case OSHIELD:
1071 if (c[SHIELD] != -1) {
1072 lprcat("\nYou are already wearing a shield");
1073 return;
1075 if (iven[c[WIELD]] == O2SWORD) {
1076 lprcat("\nYour hands are busy with the two handed sword!");
1077 return;
1079 c[SHIELD] = i - 'a';
1080 bottomline();
1081 return;
1082 default:
1083 lprcat("\nYou can't wear that!");
1090 function to drop an object
1092 static void
1093 dropobj(void)
1095 int i;
1096 char *p;
1097 long amt;
1098 p = &item[playerx][playery];
1099 while (1) {
1100 if ((i = whatitem("drop")) == '\33')
1101 return;
1102 if (i == '*')
1103 showstr();
1104 else {
1105 if (i == '.') { /* drop some gold */
1106 if (*p) {
1107 lprcat("\nThere's something here already!");
1108 return;
1110 lprcat("\n\n");
1111 cl_dn(1, 23);
1112 lprcat("How much gold do you drop? ");
1113 if ((amt = readnum((long)c[GOLD])) == 0)
1114 return;
1115 if (amt > c[GOLD]) {
1116 lprcat("\nYou don't have that much!");
1117 return;
1119 if (amt <= 32767) {
1120 *p = OGOLDPILE;
1121 i = amt;
1122 } else if (amt <= 327670L) {
1123 *p = ODGOLD;
1124 i = amt / 10;
1125 amt = 10 * i;
1126 } else if (amt <= 3276700L) {
1127 *p = OMAXGOLD;
1128 i = amt / 100;
1129 amt = 100 * i;
1130 } else if (amt <= 32767000L) {
1131 *p = OKGOLD;
1132 i = amt / 1000;
1133 amt = 1000 * i;
1134 } else {
1135 *p = OKGOLD;
1136 i = 32767;
1137 amt = 32767000L;
1139 c[GOLD] -= amt;
1140 lprintf("You drop %d gold pieces", (long)amt);
1141 iarg[playerx][playery] = i;
1142 bottomgold();
1143 know[playerx][playery] = 0;
1144 dropflag = 1;
1145 return;
1147 drop_object(i - 'a');
1148 return;
1154 * readscr() Subroutine to read a scroll one is carrying
1156 static void
1157 readscr(void)
1159 int i;
1160 while (1) {
1161 if ((i = whatitem("read")) == '\33')
1162 return;
1163 if (i != '.') {
1164 if (i == '*')
1165 showread();
1166 else {
1167 if (iven[i - 'a'] == OSCROLL) {
1168 read_scroll(ivenarg[i - 'a']);
1169 iven[i - 'a'] = 0;
1170 return;
1172 if (iven[i - 'a'] == OBOOK) {
1173 readbook(ivenarg[i - 'a']);
1174 iven[i - 'a'] = 0;
1175 return;
1177 if (iven[i - 'a'] == 0) {
1178 ydhi(i);
1179 return;
1181 lprcat("\nThere's nothing on it to read");
1182 return;
1189 * subroutine to eat a cookie one is carrying
1191 static void
1192 eatcookie(void)
1194 int i;
1195 const char *p;
1197 while (1) {
1198 if ((i = whatitem("eat")) == '\33')
1199 return;
1200 if (i != '.') {
1201 if (i == '*')
1202 showeat();
1203 else {
1204 if (iven[i - 'a'] == OCOOKIE) {
1205 lprcat("\nThe cookie was delicious.");
1206 iven[i - 'a'] = 0;
1207 if (!c[BLINDCOUNT]) {
1208 if ((p = fortune()) != NULL) {
1209 lprcat(" Inside you find a scrap of paper that says:\n");
1210 lprcat(p);
1213 return;
1215 if (iven[i - 'a'] == 0) {
1216 ydhi(i);
1217 return;
1219 lprcat("\nYou can't eat that!");
1220 return;
1227 * subroutine to quaff a potion one is carrying
1229 static void
1230 quaff(void)
1232 int i;
1233 while (1) {
1234 if ((i = whatitem("quaff")) == '\33')
1235 return;
1236 if (i != '.') {
1237 if (i == '*')
1238 showquaff();
1239 else {
1240 if (iven[i - 'a'] == OPOTION) {
1241 quaffpotion(ivenarg[i - 'a']);
1242 iven[i - 'a'] = 0;
1243 return;
1245 if (iven[i - 'a'] == 0) {
1246 ydhi(i);
1247 return;
1249 lprcat("\nYou wouldn't want to quaff that, would you? ");
1250 return;
1257 function to ask what player wants to do
1259 static int
1260 whatitem(const char *str)
1262 int i;
1263 cursors();
1264 lprintf("\nWhat do you want to %s [* for all] ? ", str);
1265 i = 0;
1266 while (i > 'z' || (i < 'a' && i != '*' && i != '\33' && i != '.'))
1267 i = getchr();
1268 if (i == '\33')
1269 lprcat(" aborted");
1270 return (i);
1274 subroutine to get a number from the player
1275 and allow * to mean return amt, else return the number entered
1277 unsigned long
1278 readnum(long mx)
1280 int i;
1281 unsigned long amt = 0;
1282 sncbr();
1283 if ((i = getchr()) == '*')
1284 amt = mx; /* allow him to say * for all gold */
1285 else
1286 while (i != '\n') {
1287 if (i == '\033') {
1288 scbr();
1289 lprcat(" aborted");
1290 return (0);
1292 if ((i <= '9') && (i >= '0') && (amt < 99999999))
1293 amt = amt * 10 + i - '0';
1294 i = getchr();
1296 scbr();
1297 return (amt);
1300 #ifdef HIDEBYLINK
1302 * routine to zero every byte in a string
1304 static void
1305 szero(char *str)
1307 while (*str)
1308 *str++ = 0;
1310 #endif /* HIDEBYLINK */