Sync usage with man page.
[netbsd-mini2440.git] / games / larn / main.c
blob9f61dc9cc8248da1c51378b81136208d535fe7f8
1 /* $NetBSD: main.c,v 1.23 2008/02/03 21:24:58 dholland Exp $ */
3 /* main.c */
4 #include <sys/cdefs.h>
5 #ifndef lint
6 __RCSID("$NetBSD: main.c,v 1.23 2008/02/03 21:24:58 dholland Exp $");
7 #endif /* not lint */
9 #include <sys/types.h>
10 #include <stdio.h>
11 #include <pwd.h>
12 #include <unistd.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include "header.h"
16 #include "extern.h"
18 static void showstr(void);
19 static void t_setup(int);
20 static void t_endup(int);
21 static void showwear(void);
22 static void showwield(void);
23 static void showread(void);
24 static void showeat(void);
25 static void showquaff(void);
26 static void show1(int, const char *[]);
27 static void randmonst(void);
28 static void parse(void);
29 static void run(int);
30 static void wield(void);
31 static void ydhi(int);
32 static void ycwi(int);
33 static void wear(void);
34 static void dropobj(void);
35 static void readscr(void);
36 static void eatcookie(void);
37 static void quaff(void);
38 static int whatitem(const char *);
40 static char copyright[] = "\nLarn is copyrighted 1986 by Noah Morgan.\n";
41 int srcount = 0; /* line counter for showstr() */
42 int dropflag = 0; /* if 1 then don't lookforobject() next round */
43 int rmst = 80; /* random monster creation counter */
44 int userid; /* the players login user id number */
45 gid_t gid, egid; /* used for security */
46 u_char nowelcome = 0, nomove = 0; /* if (nomove) then don't
47 * count next iteration as a
48 * move */
49 static char viewflag = 0;
51 * if viewflag then we have done a 99 stay here and don't showcell in the
52 * main loop
54 u_char restorflag = 0; /* 1 means restore has been done */
55 static char cmdhelp[] = "\
56 Cmd line format: larn [-slicnh] [-o<optsfile>] [-##] [++]\n\
57 -s show the scoreboard\n\
58 -l show the logfile (wizard id only)\n\
59 -i show scoreboard with inventories of dead characters\n\
60 -c create new scoreboard (wizard id only)\n\
61 -n suppress welcome message on starting game\n\
62 -## specify level of difficulty (example: -5)\n\
63 -h print this help text\n\
64 ++ restore game from checkpoint file\n\
65 -o<optsfile> specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
67 #ifdef VT100
68 static char *termtypes[] = {"vt100", "vt101", "vt102", "vt103", "vt125",
69 "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340",
70 "vt341"};
71 #endif /* VT100 */
73 ************
74 MAIN PROGRAM
75 ************
77 int
78 main(argc, argv)
79 int argc;
80 char **argv;
82 int i;
83 int hard;
84 const char *ptr = 0;
85 struct passwd *pwe;
87 i = 0;
88 egid = getegid();
89 gid = getgid();
90 setegid(gid); /* give up "games" if we have it */
92 * first task is to identify the player
94 #ifndef VT100
95 init_term(); /* setup the terminal (find out what type)
96 * for termcap */
97 #endif /* VT100 */
98 /* try to get login name */
99 if (((ptr = getlogin()) == 0) || (*ptr == 0)) {
100 /* can we get it from /etc/passwd? */
101 if ((pwe = getpwuid(getuid())) != NULL)
102 ptr = pwe->pw_name;
103 else if ((ptr = getenv("USER")) == 0)
104 if ((ptr = getenv("LOGNAME")) == 0) {
105 noone: write(2, "Can't find your logname. Who Are You?\n", 39);
106 exit(1);
109 if (ptr == 0)
110 goto noone;
111 if (strlen(ptr) == 0)
112 goto noone;
114 * second task is to prepare the pathnames the player will need
116 strcpy(loginname, ptr); /* save loginname of the user for logging
117 * purposes */
118 strcpy(logname, ptr); /* this will be overwritten with the players
119 * name */
120 if ((ptr = getenv("HOME")) == NULL)
121 ptr = ".";
122 strcpy(savefilename, ptr);
123 strcat(savefilename, "/Larn.sav"); /* save file name in home
124 * directory */
125 snprintf(optsfile, sizeof(optsfile), "%s/.larnopts", ptr);
126 /* the .larnopts filename */
129 * now malloc the memory for the dungeon
131 cell = (struct cel *) malloc(sizeof(struct cel) * (MAXLEVEL + MAXVLEVEL) * MAXX * MAXY);
132 if (cell == 0)
133 died(-285); /* malloc failure */
134 lpbuf = malloc((5 * BUFBIG) >> 2); /* output buffer */
135 inbuffer = malloc((5 * MAXIBUF) >> 2); /* output buffer */
136 if ((lpbuf == 0) || (inbuffer == 0))
137 died(-285); /* malloc() failure */
139 lcreat((char *) 0);
140 newgame(); /* set the initial clock */
141 hard = -1;
143 #ifdef VT100
145 * check terminal type to avoid users who have not vt100 type terminals
147 ttype = getenv("TERM");
148 for (j = 1, i = 0; i < sizeof(termtypes) / sizeof(char *); i++)
149 if (strcmp(ttype, termtypes[i]) == 0) {
150 j = 0;
151 break;
153 if (j) {
154 lprcat("Sorry, Larn needs a VT100 family terminal for all its features.\n");
155 lflush();
156 exit(1);
158 #endif /* VT100 */
161 * now make scoreboard if it is not there (don't clear)
163 if (access(scorefile, 0) == -1) /* not there */
164 makeboard();
167 * now process the command line arguments
169 for (i = 1; i < argc; i++) {
170 if (argv[i][0] == '-')
171 switch (argv[i][1]) {
172 case 's':
173 showscores();
174 exit(0); /* show scoreboard */
176 case 'l': /* show log file */
177 diedlog();
178 exit(0);
180 case 'i':
181 showallscores();
182 exit(0); /* show all scoreboard */
184 case 'c': /* anyone with password can create
185 * scoreboard */
186 lprcat("Preparing to initialize the scoreboard.\n");
187 if (getpassword() != 0) { /* make new scoreboard */
188 makeboard();
189 lprc('\n');
190 showscores();
192 exit(0);
194 case 'n': /* no welcome msg */
195 nowelcome = 1;
196 argv[i][0] = 0;
197 break;
199 case '0':
200 case '1':
201 case '2':
202 case '3':
203 case '4':
204 case '5':
205 case '6':
206 case '7':
207 case '8':
208 case '9': /* for hardness */
209 sscanf(&argv[i][1], "%d", &hard);
210 break;
212 case 'h': /* print out command line arguments */
213 write(1, cmdhelp, sizeof(cmdhelp));
214 exit(0);
216 case 'o': /* specify a .larnopts filename */
217 strncpy(optsfile, argv[i] + 2, 127);
218 break;
220 default:
221 printf("Unknown option <%s>\n", argv[i]);
222 exit(1);
225 if (argv[i][0] == '+') {
226 clear();
227 restorflag = 1;
228 if (argv[i][1] == '+') {
229 hitflag = 1;
230 restoregame(ckpfile); /* restore checkpointed
231 * game */
233 i = argc;
237 readopts(); /* read the options file if there is one */
240 #ifdef UIDSCORE
241 userid = geteuid(); /* obtain the user's effective id number */
242 #else /* UIDSCORE */
243 userid = getplid(logname); /* obtain the players id number */
244 #endif /* UIDSCORE */
245 if (userid < 0) {
246 write(2, "Can't obtain playerid\n", 22);
247 exit(1);
249 #ifdef HIDEBYLINK
251 * this section of code causes the program to look like something else to ps
253 if (strcmp(psname, argv[0])) { /* if a different process name only */
254 if ((i = access(psname, 1)) < 0) { /* link not there */
255 if (link(argv[0], psname) >= 0) {
256 argv[0] = psname;
257 execv(psname, argv);
259 } else
260 unlink(psname);
262 for (i = 1; i < argc; i++) {
263 szero(argv[i]); /* zero the argument to avoid ps snooping */
265 #endif /* HIDEBYLINK */
267 if (access(savefilename, 0) == 0) { /* restore game if need to */
268 clear();
269 restorflag = 1;
270 hitflag = 1;
271 restoregame(savefilename); /* restore last game */
273 sigsetup(); /* trap all needed signals */
274 sethard(hard); /* set up the desired difficulty */
275 setupvt100(); /* setup the terminal special mode */
276 if (c[HP] == 0) { /* create new game */
277 makeplayer(); /* make the character that will play */
278 newcavelevel(0);/* make the dungeon */
279 predostuff = 1; /* tell signals that we are in the welcome
280 * screen */
281 if (nowelcome == 0)
282 welcome(); /* welcome the player to the game */
284 drawscreen(); /* show the initial dungeon */
285 predostuff = 2; /* tell the trap functions that they must do
286 * a showplayer() from here on */
287 #if 0
288 nice(1); /* games should be run niced */
289 #endif
290 yrepcount = hit2flag = 0;
291 while (1) {
292 if (dropflag == 0)
293 lookforobject(); /* see if there is an object
294 * here */
295 else
296 dropflag = 0; /* don't show it just dropped an item */
297 if (hitflag == 0) {
298 if (c[HASTEMONST])
299 movemonst();
300 movemonst();
301 } /* move the monsters */
302 if (viewflag == 0)
303 showcell(playerx, playery);
304 else
305 viewflag = 0; /* show stuff around player */
306 if (hit3flag)
307 flushall();
308 hitflag = hit3flag = 0;
309 nomove = 1;
310 bot_linex(); /* update bottom line */
311 while (nomove) {
312 if (hit3flag)
313 flushall();
314 nomove = 0;
315 parse();
316 } /* get commands and make moves */
317 regen(); /* regenerate hp and spells */
318 if (c[TIMESTOP] == 0)
319 if (--rmst <= 0) {
320 rmst = 120 - (level << 2);
321 fillmonst(makemonst(level));
328 showstr()
330 show character's inventory
332 static void
333 showstr()
335 int i, number;
336 for (number = 3, i = 0; i < 26; i++)
337 if (iven[i])
338 number++; /* count items in inventory */
339 t_setup(number);
340 qshowstr();
341 t_endup(number);
344 void
345 qshowstr()
347 int i, j, k, sigsav;
348 srcount = 0;
349 sigsav = nosignal;
350 nosignal = 1; /* don't allow ^c etc */
351 if (c[GOLD]) {
352 lprintf(".) %ld gold pieces", (long) c[GOLD]);
353 srcount++;
355 for (k = 26; k >= 0; k--)
356 if (iven[k]) {
357 for (i = 22; i < 84; i++)
358 for (j = 0; j <= k; j++)
359 if (i == iven[j])
360 show3(j);
361 k = 0;
363 lprintf("\nElapsed time is %ld. You have %ld mobuls left", (long) ((gltime + 99) / 100 + 1), (long) ((TIMELIMIT - gltime) / 100));
364 more();
365 nosignal = sigsav;
369 * subroutine to clear screen depending on # lines to display
371 static void
372 t_setup(count)
373 int count;
375 if (count < 20) { /* how do we clear the screen? */
376 cl_up(79, count);
377 cursor(1, 1);
378 } else {
379 resetscroll();
380 clear();
385 * subroutine to restore normal display screen depending on t_setup()
387 static void
388 t_endup(count)
389 int count;
391 if (count < 18) /* how did we clear the screen? */
392 draws(0, MAXX, 0, (count > MAXY) ? MAXY : count);
393 else {
394 drawscreen();
395 setscroll();
400 function to show the things player is wearing only
402 static void
403 showwear()
405 int i, j, sigsav, count;
406 sigsav = nosignal;
407 nosignal = 1; /* don't allow ^c etc */
408 srcount = 0;
410 for (count = 2, j = 0; j <= 26; j++) /* count number of items we
411 * will display */
412 if ((i = iven[j]) != 0)
413 switch (i) {
414 case OLEATHER:
415 case OPLATE:
416 case OCHAIN:
417 case ORING:
418 case OSTUDLEATHER:
419 case OSPLINT:
420 case OPLATEARMOR:
421 case OSSPLATE:
422 case OSHIELD:
423 count++;
426 t_setup(count);
428 for (i = 22; i < 84; i++)
429 for (j = 0; j <= 26; j++)
430 if (i == iven[j])
431 switch (i) {
432 case OLEATHER:
433 case OPLATE:
434 case OCHAIN:
435 case ORING:
436 case OSTUDLEATHER:
437 case OSPLINT:
438 case OPLATEARMOR:
439 case OSSPLATE:
440 case OSHIELD:
441 show3(j);
443 more();
444 nosignal = sigsav;
445 t_endup(count);
449 function to show the things player can wield only
451 static void
452 showwield()
454 int i, j, sigsav, count;
455 sigsav = nosignal;
456 nosignal = 1; /* don't allow ^c etc */
457 srcount = 0;
459 for (count = 2, j = 0; j <= 26; j++) /* count how many items */
460 if ((i = iven[j]) != 0)
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 count++;
479 t_setup(count);
481 for (i = 22; i < 84; i++)
482 for (j = 0; j <= 26; j++)
483 if (i == iven[j])
484 switch (i) {
485 case ODIAMOND:
486 case ORUBY:
487 case OEMERALD:
488 case OSAPPHIRE:
489 case OBOOK:
490 case OCHEST:
491 case OLARNEYE:
492 case ONOTHEFT:
493 case OSPIRITSCARAB:
494 case OCUBEofUNDEAD:
495 case OPOTION:
496 case OSCROLL:
497 break;
498 default:
499 show3(j);
501 more();
502 nosignal = sigsav;
503 t_endup(count);
507 * function to show the things player can read only
509 static void
510 showread()
512 int i, j, sigsav, count;
513 sigsav = nosignal;
514 nosignal = 1; /* don't allow ^c etc */
515 srcount = 0;
517 for (count = 2, j = 0; j <= 26; j++)
518 switch (iven[j]) {
519 case OBOOK:
520 case OSCROLL:
521 count++;
523 t_setup(count);
525 for (i = 22; i < 84; i++)
526 for (j = 0; j <= 26; j++)
527 if (i == iven[j])
528 switch (i) {
529 case OBOOK:
530 case OSCROLL:
531 show3(j);
533 more();
534 nosignal = sigsav;
535 t_endup(count);
539 * function to show the things player can eat only
541 static void
542 showeat()
544 int i, j, sigsav, count;
545 sigsav = nosignal;
546 nosignal = 1; /* don't allow ^c etc */
547 srcount = 0;
549 for (count = 2, j = 0; j <= 26; j++)
550 switch (iven[j]) {
551 case OCOOKIE:
552 count++;
554 t_setup(count);
556 for (i = 22; i < 84; i++)
557 for (j = 0; j <= 26; j++)
558 if (i == iven[j])
559 switch (i) {
560 case OCOOKIE:
561 show3(j);
563 more();
564 nosignal = sigsav;
565 t_endup(count);
569 function to show the things player can quaff only
571 static void
572 showquaff()
574 int i, j, sigsav, count;
575 sigsav = nosignal;
576 nosignal = 1; /* don't allow ^c etc */
577 srcount = 0;
579 for (count = 2, j = 0; j <= 26; j++)
580 switch (iven[j]) {
581 case OPOTION:
582 count++;
584 t_setup(count);
586 for (i = 22; i < 84; i++)
587 for (j = 0; j <= 26; j++)
588 if (i == iven[j])
589 switch (i) {
590 case OPOTION:
591 show3(j);
593 more();
594 nosignal = sigsav;
595 t_endup(count);
598 static void
599 show1(idx, str2)
600 int idx;
601 const char *str2[];
603 lprintf("\n%c) %s", idx + 'a', objectname[iven[idx]]);
604 if (str2 != 0 && str2[ivenarg[idx]][0] != 0)
605 lprintf(" of%s", str2[ivenarg[idx]]);
608 void
609 show3(int indx)
611 switch (iven[indx]) {
612 case OPOTION:
613 show1(indx, potionname);
614 break;
615 case OSCROLL:
616 show1(indx, scrollname);
617 break;
619 case OLARNEYE:
620 case OBOOK:
621 case OSPIRITSCARAB:
622 case ODIAMOND:
623 case ORUBY:
624 case OCUBEofUNDEAD:
625 case OEMERALD:
626 case OCHEST:
627 case OCOOKIE:
628 case OSAPPHIRE:
629 case ONOTHEFT:
630 show1(indx, NULL);
631 break;
633 default:
634 lprintf("\n%c) %s", indx + 'a', objectname[iven[indx]]);
635 if (ivenarg[indx] > 0)
636 lprintf(" + %ld", (long) ivenarg[indx]);
637 else if (ivenarg[indx] < 0)
638 lprintf(" %ld", (long) ivenarg[indx]);
639 break;
641 if (c[WIELD] == indx)
642 lprcat(" (weapon in hand)");
643 if ((c[WEAR] == indx) || (c[SHIELD] == indx))
644 lprcat(" (being worn)");
645 if (++srcount >= 22) {
646 srcount = 0;
647 more();
648 clear();
653 subroutine to randomly create monsters if needed
655 static void
656 randmonst()
658 if (c[TIMESTOP])
659 return; /* don't make monsters if time is stopped */
660 if (--rmst <= 0) {
661 rmst = 120 - (level << 2);
662 fillmonst(makemonst(level));
669 parse()
671 get and execute a command
673 static void
674 parse()
676 int i, j, k, flag;
677 while (1) {
678 k = yylex();
679 switch (k) { /* get the token from the input and switch on
680 * it */
681 case 'h':
682 moveplayer(4);
683 return; /* west */
684 case 'H':
685 run(4);
686 return; /* west */
687 case 'l':
688 moveplayer(2);
689 return; /* east */
690 case 'L':
691 run(2);
692 return; /* east */
693 case 'j':
694 moveplayer(1);
695 return; /* south */
696 case 'J':
697 run(1);
698 return; /* south */
699 case 'k':
700 moveplayer(3);
701 return; /* north */
702 case 'K':
703 run(3);
704 return; /* north */
705 case 'u':
706 moveplayer(5);
707 return; /* northeast */
708 case 'U':
709 run(5);
710 return; /* northeast */
711 case 'y':
712 moveplayer(6);
713 return; /* northwest */
714 case 'Y':
715 run(6);
716 return; /* northwest */
717 case 'n':
718 moveplayer(7);
719 return; /* southeast */
720 case 'N':
721 run(7);
722 return; /* southeast */
723 case 'b':
724 moveplayer(8);
725 return; /* southwest */
726 case 'B':
727 run(8);
728 return; /* southwest */
730 case '.':
731 if (yrepcount)
732 viewflag = 1;
733 return; /* stay here */
735 case 'w':
736 yrepcount = 0;
737 wield();
738 return; /* wield a weapon */
740 case 'W':
741 yrepcount = 0;
742 wear();
743 return; /* wear armor */
745 case 'r':
746 yrepcount = 0;
747 if (c[BLINDCOUNT]) {
748 cursors();
749 lprcat("\nYou can't read anything when you're blind!");
750 } else if (c[TIMESTOP] == 0)
751 readscr();
752 return; /* to read a scroll */
754 case 'q':
755 yrepcount = 0;
756 if (c[TIMESTOP] == 0)
757 quaff();
758 return; /* quaff a potion */
760 case 'd':
761 yrepcount = 0;
762 if (c[TIMESTOP] == 0)
763 dropobj();
764 return; /* to drop an object */
766 case 'c':
767 yrepcount = 0;
768 cast();
769 return; /* cast a spell */
771 case 'i':
772 yrepcount = 0;
773 nomove = 1;
774 showstr();
775 return; /* status */
777 case 'e':
778 yrepcount = 0;
779 if (c[TIMESTOP] == 0)
780 eatcookie();
781 return; /* to eat a fortune cookie */
783 case 'D':
784 yrepcount = 0;
785 seemagic(0);
786 nomove = 1;
787 return; /* list spells and scrolls */
789 case '?':
790 yrepcount = 0;
791 help();
792 nomove = 1;
793 return; /* give the help screen */
795 case 'S':
796 clear();
797 lprcat("Saving . . .");
798 lflush();
799 savegame(savefilename);
800 wizard = 1;
801 died(-257); /* save the game - doesn't return */
803 case 'Z':
804 yrepcount = 0;
805 if (c[LEVEL] > 9) {
806 oteleport(1);
807 return;
809 cursors();
810 lprcat("\nAs yet, you don't have enough experience to use teleportation");
811 return; /* teleport yourself */
813 case '^': /* identify traps */
814 flag = yrepcount = 0;
815 cursors();
816 lprc('\n');
817 for (j = playery - 1; j < playery + 2; j++) {
818 if (j < 0)
819 j = 0;
820 if (j >= MAXY)
821 break;
822 for (i = playerx - 1; i < playerx + 2; i++) {
823 if (i < 0)
824 i = 0;
825 if (i >= MAXX)
826 break;
827 switch (item[i][j]) {
828 case OTRAPDOOR:
829 case ODARTRAP:
830 case OTRAPARROW:
831 case OTELEPORTER:
832 lprcat("\nIt's ");
833 lprcat(objectname[item[i][j]]);
834 flag++;
838 if (flag == 0)
839 lprcat("\nNo traps are visible");
840 return;
842 #if WIZID
843 case '_': /* this is the fudge player password for
844 * wizard mode */
845 yrepcount = 0;
846 cursors();
847 nomove = 1;
848 if (userid != wisid) {
849 lprcat("Sorry, you are not empowered to be a wizard.\n");
850 scbr(); /* system("stty -echo cbreak"); */
851 lflush();
852 return;
854 if (getpassword() == 0) {
855 scbr(); /* system("stty -echo cbreak"); */
856 return;
858 wizard = 1;
859 scbr(); /* system("stty -echo cbreak"); */
860 for (i = 0; i < 6; i++)
861 c[i] = 70;
862 iven[0] = iven[1] = 0;
863 take(OPROTRING, 50);
864 take(OLANCE, 25);
865 c[WIELD] = 1;
866 c[LANCEDEATH] = 1;
867 c[WEAR] = c[SHIELD] = -1;
868 raiseexperience(6000000L);
869 c[AWARENESS] += 25000;
871 int i, j;
872 for (i = 0; i < MAXY; i++)
873 for (j = 0; j < MAXX; j++)
874 know[j][i] = 1;
875 for (i = 0; i < SPNUM; i++)
876 spelknow[i] = 1;
877 for (i = 0; i < MAXSCROLL; i++)
878 scrollname[i] = scrollhide[i];
879 for (i = 0; i < MAXPOTION; i++)
880 potionname[i] = potionhide[i];
882 for (i = 0; i < MAXSCROLL; i++)
883 if (strlen(scrollname[i]) > 2) { /* no null items */
884 item[i][0] = OSCROLL;
885 iarg[i][0] = i;
887 for (i = MAXX - 1; i > MAXX - 1 - MAXPOTION; i--)
888 if (strlen(potionname[i - MAXX + MAXPOTION]) > 2) { /* no null items */
889 item[i][0] = OPOTION;
890 iarg[i][0] = i - MAXX + MAXPOTION;
892 for (i = 1; i < MAXY; i++) {
893 item[0][i] = i;
894 iarg[0][i] = 0;
896 for (i = MAXY; i < MAXY + MAXX; i++) {
897 item[i - MAXY][MAXY - 1] = i;
898 iarg[i - MAXY][MAXY - 1] = 0;
900 for (i = MAXX + MAXY; i < MAXX + MAXY + MAXY; i++) {
901 item[MAXX - 1][i - MAXX - MAXY] = i;
902 iarg[MAXX - 1][i - MAXX - MAXY] = 0;
904 c[GOLD] += 25000;
905 drawscreen();
906 return;
907 #endif
909 case 'T':
910 yrepcount = 0;
911 cursors();
912 if (c[SHIELD] != -1) {
913 c[SHIELD] = -1;
914 lprcat("\nYour shield is off");
915 bottomline();
916 } else if (c[WEAR] != -1) {
917 c[WEAR] = -1;
918 lprcat("\nYour armor is off");
919 bottomline();
920 } else
921 lprcat("\nYou aren't wearing anything");
922 return;
924 case 'g':
925 cursors();
926 lprintf("\nThe stuff you are carrying presently weighs %ld pounds", (long) packweight());
927 case ' ':
928 yrepcount = 0;
929 nomove = 1;
930 return;
932 case 'v':
933 yrepcount = 0;
934 cursors();
935 lprintf("\nCaverns of Larn, Version %ld.%ld, Diff=%ld",
936 (long) VERSION, (long) SUBVERSION,
937 (long) c[HARDGAME]);
938 if (wizard)
939 lprcat(" Wizard");
940 nomove = 1;
941 if (cheat)
942 lprcat(" Cheater");
943 lprcat(copyright);
944 return;
946 case 'Q':
947 yrepcount = 0;
948 quit();
949 nomove = 1;
950 return; /* quit */
952 case 'L' - 64:
953 yrepcount = 0;
954 drawscreen();
955 nomove = 1;
956 return; /* look */
958 #if WIZID
959 #ifdef EXTRA
960 case 'A':
961 yrepcount = 0;
962 nomove = 1;
963 if (wizard) {
964 diag();
965 return;
966 } /* create diagnostic file */
967 return;
968 #endif
969 #endif
970 case 'P':
971 cursors();
972 if (outstanding_taxes > 0)
973 lprintf("\nYou presently owe %ld gp in taxes.",
974 (long) outstanding_taxes);
975 else
976 lprcat("\nYou do not owe any taxes.");
977 return;
982 void
983 parse2()
985 if (c[HASTEMONST])
986 movemonst();
987 movemonst(); /* move the monsters */
988 randmonst();
989 regen();
992 static void
993 run(dir)
994 int dir;
996 int i;
997 i = 1;
998 while (i) {
999 i = moveplayer(dir);
1000 if (i > 0) {
1001 if (c[HASTEMONST])
1002 movemonst();
1003 movemonst();
1004 randmonst();
1005 regen();
1007 if (hitflag)
1008 i = 0;
1009 if (i != 0)
1010 showcell(playerx, playery);
1015 function to wield a weapon
1017 static void
1018 wield()
1020 int i;
1021 while (1) {
1022 if ((i = whatitem("wield")) == '\33')
1023 return;
1024 if (i != '.') {
1025 if (i == '*')
1026 showwield();
1027 else if (iven[i - 'a'] == 0) {
1028 ydhi(i);
1029 return;
1030 } else if (iven[i - 'a'] == OPOTION) {
1031 ycwi(i);
1032 return;
1033 } else if (iven[i - 'a'] == OSCROLL) {
1034 ycwi(i);
1035 return;
1036 } else if ((c[SHIELD] != -1) && (iven[i - 'a'] == O2SWORD)) {
1037 lprcat("\nBut one arm is busy with your shield!");
1038 return;
1039 } else {
1040 c[WIELD] = i - 'a';
1041 if (iven[i - 'a'] == OLANCE)
1042 c[LANCEDEATH] = 1;
1043 else
1044 c[LANCEDEATH] = 0;
1045 bottomline();
1046 return;
1053 common routine to say you don't have an item
1055 static void
1056 ydhi(x)
1057 int x;
1059 cursors();
1060 lprintf("\nYou don't have item %c!", x);
1062 static void
1063 ycwi(x)
1064 int x;
1066 cursors();
1067 lprintf("\nYou can't wield item %c!", x);
1071 function to wear armor
1073 static void
1074 wear()
1076 int i;
1077 while (1) {
1078 if ((i = whatitem("wear")) == '\33')
1079 return;
1080 if (i != '.') {
1081 if (i == '*')
1082 showwear();
1083 else
1084 switch (iven[i - 'a']) {
1085 case 0:
1086 ydhi(i);
1087 return;
1088 case OLEATHER:
1089 case OCHAIN:
1090 case OPLATE:
1091 case OSTUDLEATHER:
1092 case ORING:
1093 case OSPLINT:
1094 case OPLATEARMOR:
1095 case OSSPLATE:
1096 if (c[WEAR] != -1) {
1097 lprcat("\nYou're already wearing some armor");
1098 return;
1100 c[WEAR] = i - 'a';
1101 bottomline();
1102 return;
1103 case OSHIELD:
1104 if (c[SHIELD] != -1) {
1105 lprcat("\nYou are already wearing a shield");
1106 return;
1108 if (iven[c[WIELD]] == O2SWORD) {
1109 lprcat("\nYour hands are busy with the two handed sword!");
1110 return;
1112 c[SHIELD] = i - 'a';
1113 bottomline();
1114 return;
1115 default:
1116 lprcat("\nYou can't wear that!");
1123 function to drop an object
1125 static void
1126 dropobj()
1128 int i;
1129 unsigned char *p;
1130 long amt;
1131 p = &item[playerx][playery];
1132 while (1) {
1133 if ((i = whatitem("drop")) == '\33')
1134 return;
1135 if (i == '*')
1136 showstr();
1137 else {
1138 if (i == '.') { /* drop some gold */
1139 if (*p) {
1140 lprcat("\nThere's something here already!");
1141 return;
1143 lprcat("\n\n");
1144 cl_dn(1, 23);
1145 lprcat("How much gold do you drop? ");
1146 if ((amt = readnum((long) c[GOLD])) == 0)
1147 return;
1148 if (amt > c[GOLD]) {
1149 lprcat("\nYou don't have that much!");
1150 return;
1152 if (amt <= 32767) {
1153 *p = OGOLDPILE;
1154 i = amt;
1155 } else if (amt <= 327670L) {
1156 *p = ODGOLD;
1157 i = amt / 10;
1158 amt = 10 * i;
1159 } else if (amt <= 3276700L) {
1160 *p = OMAXGOLD;
1161 i = amt / 100;
1162 amt = 100 * i;
1163 } else if (amt <= 32767000L) {
1164 *p = OKGOLD;
1165 i = amt / 1000;
1166 amt = 1000 * i;
1167 } else {
1168 *p = OKGOLD;
1169 i = 32767;
1170 amt = 32767000L;
1172 c[GOLD] -= amt;
1173 lprintf("You drop %ld gold pieces", (long)amt);
1174 iarg[playerx][playery] = i;
1175 bottomgold();
1176 know[playerx][playery] = 0;
1177 dropflag = 1;
1178 return;
1180 drop_object(i - 'a');
1181 return;
1187 * readscr() Subroutine to read a scroll one is carrying
1189 static void
1190 readscr()
1192 int i;
1193 while (1) {
1194 if ((i = whatitem("read")) == '\33')
1195 return;
1196 if (i != '.') {
1197 if (i == '*')
1198 showread();
1199 else {
1200 if (iven[i - 'a'] == OSCROLL) {
1201 read_scroll(ivenarg[i - 'a']);
1202 iven[i - 'a'] = 0;
1203 return;
1205 if (iven[i - 'a'] == OBOOK) {
1206 readbook(ivenarg[i - 'a']);
1207 iven[i - 'a'] = 0;
1208 return;
1210 if (iven[i - 'a'] == 0) {
1211 ydhi(i);
1212 return;
1214 lprcat("\nThere's nothing on it to read");
1215 return;
1222 * subroutine to eat a cookie one is carrying
1224 static void
1225 eatcookie(void)
1227 const char *p;
1228 int i;
1230 while (1) {
1231 if ((i = whatitem("eat")) == '\33')
1232 return;
1233 if (i != '.') {
1234 if (i == '*')
1235 showeat();
1236 else {
1237 if (iven[i - 'a'] == OCOOKIE) {
1238 lprcat("\nThe cookie was delicious.");
1239 iven[i - 'a'] = 0;
1240 if (!c[BLINDCOUNT]) {
1241 if ((p = fortune()) != NULL) {
1242 lprcat(" Inside you find a scrap of paper that says:\n");
1243 lprcat(p);
1246 return;
1248 if (iven[i - 'a'] == 0) {
1249 ydhi(i);
1250 return;
1252 lprcat("\nYou can't eat that!");
1253 return;
1260 * subroutine to quaff a potion one is carrying
1262 static void
1263 quaff()
1265 int i;
1266 while (1) {
1267 if ((i = whatitem("quaff")) == '\33')
1268 return;
1269 if (i != '.') {
1270 if (i == '*')
1271 showquaff();
1272 else {
1273 if (iven[i - 'a'] == OPOTION) {
1274 quaffpotion(ivenarg[i - 'a']);
1275 iven[i - 'a'] = 0;
1276 return;
1278 if (iven[i - 'a'] == 0) {
1279 ydhi(i);
1280 return;
1282 lprcat("\nYou wouldn't want to quaff that, would you? ");
1283 return;
1290 function to ask what player wants to do
1292 static int
1293 whatitem(const char *str)
1295 int i;
1296 cursors();
1297 lprintf("\nWhat do you want to %s [* for all] ? ", str);
1298 i = 0;
1299 while (i > 'z' || (i < 'a' && i != '*' && i != '\33' && i != '.'))
1300 i = ttgetch();
1301 if (i == '\33')
1302 lprcat(" aborted");
1303 return (i);
1307 subroutine to get a number from the player
1308 and allow * to mean return amt, else return the number entered
1310 unsigned long
1311 readnum(mx)
1312 long mx;
1314 int i;
1315 unsigned long amt = 0;
1316 sncbr();
1317 if ((i = ttgetch()) == '*')
1318 amt = mx; /* allow him to say * for all gold */
1319 else
1320 while (i != '\n') {
1321 if (i == '\033') {
1322 scbr();
1323 lprcat(" aborted");
1324 return (0);
1326 if ((i <= '9') && (i >= '0') && (amt < 99999999))
1327 amt = amt * 10 + i - '0';
1328 i = ttgetch();
1330 scbr();
1331 return (amt);
1334 #ifdef HIDEBYLINK
1336 * routine to zero every byte in a string
1338 void
1339 szero(str)
1340 char *str;
1342 while (*str)
1343 *str++ = 0;
1345 #endif /* HIDEBYLINK */