]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - larn/main.c
avoid unnecessary floating point ops
[bsdgames-darwin.git] / larn / main.c
1 /* $NetBSD: main.c,v 1.25 2012/06/19 05:30:43 dholland Exp $ */
2
3 /* main.c */
4 #include <sys/cdefs.h>
5 #ifndef lint
6 __RCSID("$NetBSD: main.c,v 1.25 2012/06/19 05:30:43 dholland Exp $");
7 #endif /* not lint */
8
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"
17
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 *);
39
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;
50 /*
51 * if viewflag then we have done a 99 stay here and don't showcell in the
52 * main loop
53 */
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\
66 ";
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 */
72 /*
73 ************
74 MAIN PROGRAM
75 ************
76 */
77 int
78 main(int argc, char **argv)
79 {
80 int i;
81 int hard;
82 const char *ptr = 0;
83 struct passwd *pwe;
84
85 i = 0;
86 egid = getegid();
87 gid = getgid();
88 setegid(gid); /* give up "games" if we have it */
89 /*
90 * first task is to identify the player
91 */
92 #ifndef VT100
93 init_term(); /* setup the terminal (find out what type)
94 * for termcap */
95 #endif /* VT100 */
96 /* try to get login name */
97 if (((ptr = getlogin()) == 0) || (*ptr == 0)) {
98 /* can we get it from /etc/passwd? */
99 if ((pwe = getpwuid(getuid())) != NULL)
100 ptr = pwe->pw_name;
101 else if ((ptr = getenv("USER")) == 0)
102 if ((ptr = getenv("LOGNAME")) == 0) {
103 noone: write(2, "Can't find your logname. Who Are You?\n", 39);
104 exit(1);
105 }
106 }
107 if (ptr == 0)
108 goto noone;
109 if (strlen(ptr) == 0)
110 goto noone;
111 /*
112 * second task is to prepare the pathnames the player will need
113 */
114 strcpy(loginname, ptr); /* save loginname of the user for logging
115 * purposes */
116 strcpy(logname, ptr); /* this will be overwritten with the players
117 * name */
118 if ((ptr = getenv("HOME")) == NULL)
119 ptr = ".";
120 strcpy(savefilename, ptr);
121 strcat(savefilename, "/Larn.sav"); /* save file name in home
122 * directory */
123 snprintf(optsfile, sizeof(optsfile), "%s/.larnopts", ptr);
124 /* the .larnopts filename */
125
126 /*
127 * now malloc the memory for the dungeon
128 */
129 cell = (struct cel *) malloc(sizeof(struct cel) * (MAXLEVEL + MAXVLEVEL) * MAXX * MAXY);
130 if (cell == 0)
131 died(-285); /* malloc failure */
132 lpbuf = malloc((5 * BUFBIG) >> 2); /* output buffer */
133 inbuffer = malloc((5 * MAXIBUF) >> 2); /* output buffer */
134 if ((lpbuf == 0) || (inbuffer == 0))
135 died(-285); /* malloc() failure */
136
137 lcreat((char *) 0);
138 newgame(); /* set the initial clock */
139 hard = -1;
140
141 #ifdef VT100
142 /*
143 * check terminal type to avoid users who have not vt100 type terminals
144 */
145 ttype = getenv("TERM");
146 for (j = 1, i = 0; i < sizeof(termtypes) / sizeof(char *); i++)
147 if (strcmp(ttype, termtypes[i]) == 0) {
148 j = 0;
149 break;
150 }
151 if (j) {
152 lprcat("Sorry, Larn needs a VT100 family terminal for all its features.\n");
153 lflush();
154 exit(1);
155 }
156 #endif /* VT100 */
157
158 /*
159 * now make scoreboard if it is not there (don't clear)
160 */
161 if (access(scorefile, 0) == -1) /* not there */
162 makeboard();
163
164 /*
165 * now process the command line arguments
166 */
167 for (i = 1; i < argc; i++) {
168 if (argv[i][0] == '-')
169 switch (argv[i][1]) {
170 case 's':
171 showscores();
172 exit(0); /* show scoreboard */
173
174 case 'l': /* show log file */
175 diedlog();
176 exit(0);
177
178 case 'i':
179 showallscores();
180 exit(0); /* show all scoreboard */
181
182 case 'c': /* anyone with password can create
183 * scoreboard */
184 lprcat("Preparing to initialize the scoreboard.\n");
185 if (getpassword() != 0) { /* make new scoreboard */
186 makeboard();
187 lprc('\n');
188 showscores();
189 }
190 exit(0);
191
192 case 'n': /* no welcome msg */
193 nowelcome = 1;
194 argv[i][0] = 0;
195 break;
196
197 case '0':
198 case '1':
199 case '2':
200 case '3':
201 case '4':
202 case '5':
203 case '6':
204 case '7':
205 case '8':
206 case '9': /* for hardness */
207 sscanf(&argv[i][1], "%d", &hard);
208 break;
209
210 case 'h': /* print out command line arguments */
211 write(1, cmdhelp, sizeof(cmdhelp));
212 exit(0);
213
214 case 'o': /* specify a .larnopts filename */
215 strncpy(optsfile, argv[i] + 2, 127);
216 break;
217
218 default:
219 printf("Unknown option <%s>\n", argv[i]);
220 exit(1);
221 };
222
223 if (argv[i][0] == '+') {
224 clear();
225 restorflag = 1;
226 if (argv[i][1] == '+') {
227 hitflag = 1;
228 restoregame(ckpfile); /* restore checkpointed
229 * game */
230 }
231 i = argc;
232 }
233 }
234
235 readopts(); /* read the options file if there is one */
236
237
238 #ifdef UIDSCORE
239 userid = geteuid(); /* obtain the user's effective id number */
240 #else /* UIDSCORE */
241 userid = getplid(logname); /* obtain the players id number */
242 #endif /* UIDSCORE */
243 if (userid < 0) {
244 write(2, "Can't obtain playerid\n", 22);
245 exit(1);
246 }
247 #ifdef HIDEBYLINK
248 /*
249 * this section of code causes the program to look like something else to ps
250 */
251 if (strcmp(psname, argv[0])) { /* if a different process name only */
252 if ((i = access(psname, 1)) < 0) { /* link not there */
253 if (link(argv[0], psname) >= 0) {
254 argv[0] = psname;
255 execv(psname, argv);
256 }
257 } else
258 unlink(psname);
259 }
260 for (i = 1; i < argc; i++) {
261 szero(argv[i]); /* zero the argument to avoid ps snooping */
262 }
263 #endif /* HIDEBYLINK */
264
265 if (access(savefilename, 0) == 0) { /* restore game if need to */
266 clear();
267 restorflag = 1;
268 hitflag = 1;
269 restoregame(savefilename); /* restore last game */
270 }
271 sigsetup(); /* trap all needed signals */
272 sethard(hard); /* set up the desired difficulty */
273 setupvt100(); /* setup the terminal special mode */
274 if (c[HP] == 0) { /* create new game */
275 makeplayer(); /* make the character that will play */
276 newcavelevel(0);/* make the dungeon */
277 predostuff = 1; /* tell signals that we are in the welcome
278 * screen */
279 if (nowelcome == 0)
280 welcome(); /* welcome the player to the game */
281 }
282 drawscreen(); /* show the initial dungeon */
283 predostuff = 2; /* tell the trap functions that they must do
284 * a showplayer() from here on */
285 #if 0
286 nice(1); /* games should be run niced */
287 #endif
288 yrepcount = hit2flag = 0;
289 while (1) {
290 if (dropflag == 0)
291 lookforobject(); /* see if there is an object
292 * here */
293 else
294 dropflag = 0; /* don't show it just dropped an item */
295 if (hitflag == 0) {
296 if (c[HASTEMONST])
297 movemonst();
298 movemonst();
299 } /* move the monsters */
300 if (viewflag == 0)
301 showcell(playerx, playery);
302 else
303 viewflag = 0; /* show stuff around player */
304 if (hit3flag)
305 flushall();
306 hitflag = hit3flag = 0;
307 nomove = 1;
308 bot_linex(); /* update bottom line */
309 while (nomove) {
310 if (hit3flag)
311 flushall();
312 nomove = 0;
313 parse();
314 } /* get commands and make moves */
315 regen(); /* regenerate hp and spells */
316 if (c[TIMESTOP] == 0)
317 if (--rmst <= 0) {
318 rmst = 120 - (level << 2);
319 fillmonst(makemonst(level));
320 }
321 }
322 }
323
324
325 /*
326 showstr()
327
328 show character's inventory
329 */
330 static void
331 showstr(void)
332 {
333 int i, number;
334 for (number = 3, i = 0; i < 26; i++)
335 if (iven[i])
336 number++; /* count items in inventory */
337 t_setup(number);
338 qshowstr();
339 t_endup(number);
340 }
341
342 void
343 qshowstr(void)
344 {
345 int i, j, k, sigsav;
346 srcount = 0;
347 sigsav = nosignal;
348 nosignal = 1; /* don't allow ^c etc */
349 if (c[GOLD]) {
350 lprintf(".) %ld gold pieces", (long) c[GOLD]);
351 srcount++;
352 }
353 for (k = 26; k >= 0; k--)
354 if (iven[k]) {
355 for (i = 22; i < 84; i++)
356 for (j = 0; j <= k; j++)
357 if (i == iven[j])
358 show3(j);
359 k = 0;
360 }
361 lprintf("\nElapsed time is %ld. You have %ld mobuls left", (long) ((gltime + 99) / 100 + 1), (long) ((TIMELIMIT - gltime) / 100));
362 more();
363 nosignal = sigsav;
364 }
365
366 /*
367 * subroutine to clear screen depending on # lines to display
368 */
369 static void
370 t_setup(int count)
371 {
372 if (count < 20) { /* how do we clear the screen? */
373 cl_up(79, count);
374 cursor(1, 1);
375 } else {
376 resetscroll();
377 clear();
378 }
379 }
380
381 /*
382 * subroutine to restore normal display screen depending on t_setup()
383 */
384 static void
385 t_endup(int count)
386 {
387 if (count < 18) /* how did we clear the screen? */
388 draws(0, MAXX, 0, (count > MAXY) ? MAXY : count);
389 else {
390 drawscreen();
391 setscroll();
392 }
393 }
394
395 /*
396 function to show the things player is wearing only
397 */
398 static void
399 showwear(void)
400 {
401 int i, j, sigsav, count;
402 sigsav = nosignal;
403 nosignal = 1; /* don't allow ^c etc */
404 srcount = 0;
405
406 for (count = 2, j = 0; j <= 26; j++) /* count number of items we
407 * will display */
408 if ((i = iven[j]) != 0)
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 count++;
420 };
421
422 t_setup(count);
423
424 for (i = 22; i < 84; i++)
425 for (j = 0; j <= 26; j++)
426 if (i == iven[j])
427 switch (i) {
428 case OLEATHER:
429 case OPLATE:
430 case OCHAIN:
431 case ORING:
432 case OSTUDLEATHER:
433 case OSPLINT:
434 case OPLATEARMOR:
435 case OSSPLATE:
436 case OSHIELD:
437 show3(j);
438 };
439 more();
440 nosignal = sigsav;
441 t_endup(count);
442 }
443
444 /*
445 function to show the things player can wield only
446 */
447 static void
448 showwield(void)
449 {
450 int i, j, sigsav, count;
451 sigsav = nosignal;
452 nosignal = 1; /* don't allow ^c etc */
453 srcount = 0;
454
455 for (count = 2, j = 0; j <= 26; j++) /* count how many items */
456 if ((i = iven[j]) != 0)
457 switch (i) {
458 case ODIAMOND:
459 case ORUBY:
460 case OEMERALD:
461 case OSAPPHIRE:
462 case OBOOK:
463 case OCHEST:
464 case OLARNEYE:
465 case ONOTHEFT:
466 case OSPIRITSCARAB:
467 case OCUBEofUNDEAD:
468 case OPOTION:
469 case OSCROLL:
470 break;
471 default:
472 count++;
473 };
474
475 t_setup(count);
476
477 for (i = 22; i < 84; i++)
478 for (j = 0; j <= 26; j++)
479 if (i == iven[j])
480 switch (i) {
481 case ODIAMOND:
482 case ORUBY:
483 case OEMERALD:
484 case OSAPPHIRE:
485 case OBOOK:
486 case OCHEST:
487 case OLARNEYE:
488 case ONOTHEFT:
489 case OSPIRITSCARAB:
490 case OCUBEofUNDEAD:
491 case OPOTION:
492 case OSCROLL:
493 break;
494 default:
495 show3(j);
496 };
497 more();
498 nosignal = sigsav;
499 t_endup(count);
500 }
501
502 /*
503 * function to show the things player can read only
504 */
505 static void
506 showread(void)
507 {
508 int i, j, sigsav, count;
509 sigsav = nosignal;
510 nosignal = 1; /* don't allow ^c etc */
511 srcount = 0;
512
513 for (count = 2, j = 0; j <= 26; j++)
514 switch (iven[j]) {
515 case OBOOK:
516 case OSCROLL:
517 count++;
518 };
519 t_setup(count);
520
521 for (i = 22; i < 84; i++)
522 for (j = 0; j <= 26; j++)
523 if (i == iven[j])
524 switch (i) {
525 case OBOOK:
526 case OSCROLL:
527 show3(j);
528 };
529 more();
530 nosignal = sigsav;
531 t_endup(count);
532 }
533
534 /*
535 * function to show the things player can eat only
536 */
537 static void
538 showeat(void)
539 {
540 int i, j, sigsav, count;
541 sigsav = nosignal;
542 nosignal = 1; /* don't allow ^c etc */
543 srcount = 0;
544
545 for (count = 2, j = 0; j <= 26; j++)
546 switch (iven[j]) {
547 case OCOOKIE:
548 count++;
549 };
550 t_setup(count);
551
552 for (i = 22; i < 84; i++)
553 for (j = 0; j <= 26; j++)
554 if (i == iven[j])
555 switch (i) {
556 case OCOOKIE:
557 show3(j);
558 };
559 more();
560 nosignal = sigsav;
561 t_endup(count);
562 }
563
564 /*
565 function to show the things player can quaff only
566 */
567 static void
568 showquaff(void)
569 {
570 int i, j, sigsav, count;
571 sigsav = nosignal;
572 nosignal = 1; /* don't allow ^c etc */
573 srcount = 0;
574
575 for (count = 2, j = 0; j <= 26; j++)
576 switch (iven[j]) {
577 case OPOTION:
578 count++;
579 };
580 t_setup(count);
581
582 for (i = 22; i < 84; i++)
583 for (j = 0; j <= 26; j++)
584 if (i == iven[j])
585 switch (i) {
586 case OPOTION:
587 show3(j);
588 };
589 more();
590 nosignal = sigsav;
591 t_endup(count);
592 }
593
594 static void
595 show1(int idx, const char *str2[])
596 {
597 lprintf("\n%c) %s", idx + 'a', objectname[iven[idx]]);
598 if (str2 != 0 && str2[ivenarg[idx]][0] != 0)
599 lprintf(" of%s", str2[ivenarg[idx]]);
600 }
601
602 void
603 show3(int indx)
604 {
605 switch (iven[indx]) {
606 case OPOTION:
607 show1(indx, potionname);
608 break;
609 case OSCROLL:
610 show1(indx, scrollname);
611 break;
612
613 case OLARNEYE:
614 case OBOOK:
615 case OSPIRITSCARAB:
616 case ODIAMOND:
617 case ORUBY:
618 case OCUBEofUNDEAD:
619 case OEMERALD:
620 case OCHEST:
621 case OCOOKIE:
622 case OSAPPHIRE:
623 case ONOTHEFT:
624 show1(indx, NULL);
625 break;
626
627 default:
628 lprintf("\n%c) %s", indx + 'a', objectname[iven[indx]]);
629 if (ivenarg[indx] > 0)
630 lprintf(" + %ld", (long) ivenarg[indx]);
631 else if (ivenarg[indx] < 0)
632 lprintf(" %ld", (long) ivenarg[indx]);
633 break;
634 }
635 if (c[WIELD] == indx)
636 lprcat(" (weapon in hand)");
637 if ((c[WEAR] == indx) || (c[SHIELD] == indx))
638 lprcat(" (being worn)");
639 if (++srcount >= 22) {
640 srcount = 0;
641 more();
642 clear();
643 }
644 }
645
646 /*
647 subroutine to randomly create monsters if needed
648 */
649 static void
650 randmonst(void)
651 {
652 if (c[TIMESTOP])
653 return; /* don't make monsters if time is stopped */
654 if (--rmst <= 0) {
655 rmst = 120 - (level << 2);
656 fillmonst(makemonst(level));
657 }
658 }
659
660
661
662 /*
663 parse()
664
665 get and execute a command
666 */
667 static void
668 parse(void)
669 {
670 int i, j, k, flag;
671 while (1) {
672 k = yylex();
673 switch (k) { /* get the token from the input and switch on
674 * it */
675 case 'h':
676 moveplayer(4);
677 return; /* west */
678 case 'H':
679 run(4);
680 return; /* west */
681 case 'l':
682 moveplayer(2);
683 return; /* east */
684 case 'L':
685 run(2);
686 return; /* east */
687 case 'j':
688 moveplayer(1);
689 return; /* south */
690 case 'J':
691 run(1);
692 return; /* south */
693 case 'k':
694 moveplayer(3);
695 return; /* north */
696 case 'K':
697 run(3);
698 return; /* north */
699 case 'u':
700 moveplayer(5);
701 return; /* northeast */
702 case 'U':
703 run(5);
704 return; /* northeast */
705 case 'y':
706 moveplayer(6);
707 return; /* northwest */
708 case 'Y':
709 run(6);
710 return; /* northwest */
711 case 'n':
712 moveplayer(7);
713 return; /* southeast */
714 case 'N':
715 run(7);
716 return; /* southeast */
717 case 'b':
718 moveplayer(8);
719 return; /* southwest */
720 case 'B':
721 run(8);
722 return; /* southwest */
723
724 case '.':
725 if (yrepcount)
726 viewflag = 1;
727 return; /* stay here */
728
729 case 'w':
730 yrepcount = 0;
731 wield();
732 return; /* wield a weapon */
733
734 case 'W':
735 yrepcount = 0;
736 wear();
737 return; /* wear armor */
738
739 case 'r':
740 yrepcount = 0;
741 if (c[BLINDCOUNT]) {
742 cursors();
743 lprcat("\nYou can't read anything when you're blind!");
744 } else if (c[TIMESTOP] == 0)
745 readscr();
746 return; /* to read a scroll */
747
748 case 'q':
749 yrepcount = 0;
750 if (c[TIMESTOP] == 0)
751 quaff();
752 return; /* quaff a potion */
753
754 case 'd':
755 yrepcount = 0;
756 if (c[TIMESTOP] == 0)
757 dropobj();
758 return; /* to drop an object */
759
760 case 'c':
761 yrepcount = 0;
762 cast();
763 return; /* cast a spell */
764
765 case 'i':
766 yrepcount = 0;
767 nomove = 1;
768 showstr();
769 return; /* status */
770
771 case 'e':
772 yrepcount = 0;
773 if (c[TIMESTOP] == 0)
774 eatcookie();
775 return; /* to eat a fortune cookie */
776
777 case 'D':
778 yrepcount = 0;
779 seemagic(0);
780 nomove = 1;
781 return; /* list spells and scrolls */
782
783 case '?':
784 yrepcount = 0;
785 help();
786 nomove = 1;
787 return; /* give the help screen */
788
789 case 'S':
790 clear();
791 lprcat("Saving . . .");
792 lflush();
793 savegame(savefilename);
794 wizard = 1;
795 died(-257); /* save the game - doesn't return */
796
797 case 'Z':
798 yrepcount = 0;
799 if (c[LEVEL] > 9) {
800 oteleport(1);
801 return;
802 }
803 cursors();
804 lprcat("\nAs yet, you don't have enough experience to use teleportation");
805 return; /* teleport yourself */
806
807 case '^': /* identify traps */
808 flag = yrepcount = 0;
809 cursors();
810 lprc('\n');
811 for (j = playery - 1; j < playery + 2; j++) {
812 if (j < 0)
813 j = 0;
814 if (j >= MAXY)
815 break;
816 for (i = playerx - 1; i < playerx + 2; i++) {
817 if (i < 0)
818 i = 0;
819 if (i >= MAXX)
820 break;
821 switch (item[i][j]) {
822 case OTRAPDOOR:
823 case ODARTRAP:
824 case OTRAPARROW:
825 case OTELEPORTER:
826 lprcat("\nIt's ");
827 lprcat(objectname[item[i][j]]);
828 flag++;
829 };
830 }
831 }
832 if (flag == 0)
833 lprcat("\nNo traps are visible");
834 return;
835
836 #if WIZID
837 case '_': /* this is the fudge player password for
838 * wizard mode */
839 yrepcount = 0;
840 cursors();
841 nomove = 1;
842 if (userid != wisid) {
843 lprcat("Sorry, you are not empowered to be a wizard.\n");
844 scbr(); /* system("stty -echo cbreak"); */
845 lflush();
846 return;
847 }
848 if (getpassword() == 0) {
849 scbr(); /* system("stty -echo cbreak"); */
850 return;
851 }
852 wizard = 1;
853 scbr(); /* system("stty -echo cbreak"); */
854 for (i = 0; i < 6; i++)
855 c[i] = 70;
856 iven[0] = iven[1] = 0;
857 take(OPROTRING, 50);
858 take(OLANCE, 25);
859 c[WIELD] = 1;
860 c[LANCEDEATH] = 1;
861 c[WEAR] = c[SHIELD] = -1;
862 raiseexperience(6000000L);
863 c[AWARENESS] += 25000;
864 {
865 int i, j;
866 for (i = 0; i < MAXY; i++)
867 for (j = 0; j < MAXX; j++)
868 know[j][i] = 1;
869 for (i = 0; i < SPNUM; i++)
870 spelknow[i] = 1;
871 for (i = 0; i < MAXSCROLL; i++)
872 scrollname[i] = scrollhide[i];
873 for (i = 0; i < MAXPOTION; i++)
874 potionname[i] = potionhide[i];
875 }
876 for (i = 0; i < MAXSCROLL; i++)
877 if (strlen(scrollname[i]) > 2) { /* no null items */
878 item[i][0] = OSCROLL;
879 iarg[i][0] = i;
880 }
881 for (i = MAXX - 1; i > MAXX - 1 - MAXPOTION; i--)
882 if (strlen(potionname[i - MAXX + MAXPOTION]) > 2) { /* no null items */
883 item[i][0] = OPOTION;
884 iarg[i][0] = i - MAXX + MAXPOTION;
885 }
886 for (i = 1; i < MAXY; i++) {
887 item[0][i] = i;
888 iarg[0][i] = 0;
889 }
890 for (i = MAXY; i < MAXY + MAXX; i++) {
891 item[i - MAXY][MAXY - 1] = i;
892 iarg[i - MAXY][MAXY - 1] = 0;
893 }
894 for (i = MAXX + MAXY; i < MAXX + MAXY + MAXY; i++) {
895 item[MAXX - 1][i - MAXX - MAXY] = i;
896 iarg[MAXX - 1][i - MAXX - MAXY] = 0;
897 }
898 c[GOLD] += 25000;
899 drawscreen();
900 return;
901 #endif
902
903 case 'T':
904 yrepcount = 0;
905 cursors();
906 if (c[SHIELD] != -1) {
907 c[SHIELD] = -1;
908 lprcat("\nYour shield is off");
909 bottomline();
910 } else if (c[WEAR] != -1) {
911 c[WEAR] = -1;
912 lprcat("\nYour armor is off");
913 bottomline();
914 } else
915 lprcat("\nYou aren't wearing anything");
916 return;
917
918 case 'g':
919 cursors();
920 lprintf("\nThe stuff you are carrying presently weighs %ld pounds", (long) packweight());
921 case ' ':
922 yrepcount = 0;
923 nomove = 1;
924 return;
925
926 case 'v':
927 yrepcount = 0;
928 cursors();
929 lprintf("\nCaverns of Larn, Version %ld.%ld, Diff=%ld",
930 (long) VERSION, (long) SUBVERSION,
931 (long) c[HARDGAME]);
932 if (wizard)
933 lprcat(" Wizard");
934 nomove = 1;
935 if (cheat)
936 lprcat(" Cheater");
937 lprcat(copyright);
938 return;
939
940 case 'Q':
941 yrepcount = 0;
942 quit();
943 nomove = 1;
944 return; /* quit */
945
946 case 'L' - 64:
947 yrepcount = 0;
948 drawscreen();
949 nomove = 1;
950 return; /* look */
951
952 #if WIZID
953 #ifdef EXTRA
954 case 'A':
955 yrepcount = 0;
956 nomove = 1;
957 if (wizard) {
958 diag();
959 return;
960 } /* create diagnostic file */
961 return;
962 #endif
963 #endif
964 case 'P':
965 cursors();
966 if (outstanding_taxes > 0)
967 lprintf("\nYou presently owe %ld gp in taxes.",
968 (long) outstanding_taxes);
969 else
970 lprcat("\nYou do not owe any taxes.");
971 return;
972 };
973 }
974 }
975
976 void
977 parse2(void)
978 {
979 if (c[HASTEMONST])
980 movemonst();
981 movemonst(); /* move the monsters */
982 randmonst();
983 regen();
984 }
985
986 static void
987 run(int dir)
988 {
989 int i;
990 i = 1;
991 while (i) {
992 i = moveplayer(dir);
993 if (i > 0) {
994 if (c[HASTEMONST])
995 movemonst();
996 movemonst();
997 randmonst();
998 regen();
999 }
1000 if (hitflag)
1001 i = 0;
1002 if (i != 0)
1003 showcell(playerx, playery);
1004 }
1005 }
1006
1007 /*
1008 function to wield a weapon
1009 */
1010 static void
1011 wield(void)
1012 {
1013 int i;
1014 while (1) {
1015 if ((i = whatitem("wield")) == '\33')
1016 return;
1017 if (i != '.') {
1018 if (i == '*')
1019 showwield();
1020 else if (iven[i - 'a'] == 0) {
1021 ydhi(i);
1022 return;
1023 } else if (iven[i - 'a'] == OPOTION) {
1024 ycwi(i);
1025 return;
1026 } else if (iven[i - 'a'] == OSCROLL) {
1027 ycwi(i);
1028 return;
1029 } else if ((c[SHIELD] != -1) && (iven[i - 'a'] == O2SWORD)) {
1030 lprcat("\nBut one arm is busy with your shield!");
1031 return;
1032 } else {
1033 c[WIELD] = i - 'a';
1034 if (iven[i - 'a'] == OLANCE)
1035 c[LANCEDEATH] = 1;
1036 else
1037 c[LANCEDEATH] = 0;
1038 bottomline();
1039 return;
1040 }
1041 }
1042 }
1043 }
1044
1045 /*
1046 common routine to say you don't have an item
1047 */
1048 static void
1049 ydhi(int x)
1050 {
1051 cursors();
1052 lprintf("\nYou don't have item %c!", x);
1053 }
1054 static void
1055 ycwi(int x)
1056 {
1057 cursors();
1058 lprintf("\nYou can't wield item %c!", x);
1059 }
1060
1061 /*
1062 function to wear armor
1063 */
1064 static void
1065 wear(void)
1066 {
1067 int i;
1068 while (1) {
1069 if ((i = whatitem("wear")) == '\33')
1070 return;
1071 if (i != '.') {
1072 if (i == '*')
1073 showwear();
1074 else
1075 switch (iven[i - 'a']) {
1076 case 0:
1077 ydhi(i);
1078 return;
1079 case OLEATHER:
1080 case OCHAIN:
1081 case OPLATE:
1082 case OSTUDLEATHER:
1083 case ORING:
1084 case OSPLINT:
1085 case OPLATEARMOR:
1086 case OSSPLATE:
1087 if (c[WEAR] != -1) {
1088 lprcat("\nYou're already wearing some armor");
1089 return;
1090 }
1091 c[WEAR] = i - 'a';
1092 bottomline();
1093 return;
1094 case OSHIELD:
1095 if (c[SHIELD] != -1) {
1096 lprcat("\nYou are already wearing a shield");
1097 return;
1098 }
1099 if (iven[c[WIELD]] == O2SWORD) {
1100 lprcat("\nYour hands are busy with the two handed sword!");
1101 return;
1102 }
1103 c[SHIELD] = i - 'a';
1104 bottomline();
1105 return;
1106 default:
1107 lprcat("\nYou can't wear that!");
1108 };
1109 }
1110 }
1111 }
1112
1113 /*
1114 function to drop an object
1115 */
1116 static void
1117 dropobj(void)
1118 {
1119 int i;
1120 unsigned char *p;
1121 long amt;
1122 p = &item[playerx][playery];
1123 while (1) {
1124 if ((i = whatitem("drop")) == '\33')
1125 return;
1126 if (i == '*')
1127 showstr();
1128 else {
1129 if (i == '.') { /* drop some gold */
1130 if (*p) {
1131 lprcat("\nThere's something here already!");
1132 return;
1133 }
1134 lprcat("\n\n");
1135 cl_dn(1, 23);
1136 lprcat("How much gold do you drop? ");
1137 if ((amt = readnum((long) c[GOLD])) == 0)
1138 return;
1139 if (amt > c[GOLD]) {
1140 lprcat("\nYou don't have that much!");
1141 return;
1142 }
1143 if (amt <= 32767) {
1144 *p = OGOLDPILE;
1145 i = amt;
1146 } else if (amt <= 327670L) {
1147 *p = ODGOLD;
1148 i = amt / 10;
1149 amt = 10 * i;
1150 } else if (amt <= 3276700L) {
1151 *p = OMAXGOLD;
1152 i = amt / 100;
1153 amt = 100 * i;
1154 } else if (amt <= 32767000L) {
1155 *p = OKGOLD;
1156 i = amt / 1000;
1157 amt = 1000 * i;
1158 } else {
1159 *p = OKGOLD;
1160 i = 32767;
1161 amt = 32767000L;
1162 }
1163 c[GOLD] -= amt;
1164 lprintf("You drop %ld gold pieces", (long)amt);
1165 iarg[playerx][playery] = i;
1166 bottomgold();
1167 know[playerx][playery] = 0;
1168 dropflag = 1;
1169 return;
1170 }
1171 drop_object(i - 'a');
1172 return;
1173 }
1174 }
1175 }
1176
1177 /*
1178 * readscr() Subroutine to read a scroll one is carrying
1179 */
1180 static void
1181 readscr(void)
1182 {
1183 int i;
1184 while (1) {
1185 if ((i = whatitem("read")) == '\33')
1186 return;
1187 if (i != '.') {
1188 if (i == '*')
1189 showread();
1190 else {
1191 if (iven[i - 'a'] == OSCROLL) {
1192 read_scroll(ivenarg[i - 'a']);
1193 iven[i - 'a'] = 0;
1194 return;
1195 }
1196 if (iven[i - 'a'] == OBOOK) {
1197 readbook(ivenarg[i - 'a']);
1198 iven[i - 'a'] = 0;
1199 return;
1200 }
1201 if (iven[i - 'a'] == 0) {
1202 ydhi(i);
1203 return;
1204 }
1205 lprcat("\nThere's nothing on it to read");
1206 return;
1207 }
1208 }
1209 }
1210 }
1211
1212 /*
1213 * subroutine to eat a cookie one is carrying
1214 */
1215 static void
1216 eatcookie(void)
1217 {
1218 const char *p;
1219 int i;
1220
1221 while (1) {
1222 if ((i = whatitem("eat")) == '\33')
1223 return;
1224 if (i != '.') {
1225 if (i == '*')
1226 showeat();
1227 else {
1228 if (iven[i - 'a'] == OCOOKIE) {
1229 lprcat("\nThe cookie was delicious.");
1230 iven[i - 'a'] = 0;
1231 if (!c[BLINDCOUNT]) {
1232 if ((p = fortune()) != NULL) {
1233 lprcat(" Inside you find a scrap of paper that says:\n");
1234 lprcat(p);
1235 }
1236 }
1237 return;
1238 }
1239 if (iven[i - 'a'] == 0) {
1240 ydhi(i);
1241 return;
1242 }
1243 lprcat("\nYou can't eat that!");
1244 return;
1245 }
1246 }
1247 }
1248 }
1249
1250 /*
1251 * subroutine to quaff a potion one is carrying
1252 */
1253 static void
1254 quaff(void)
1255 {
1256 int i;
1257 while (1) {
1258 if ((i = whatitem("quaff")) == '\33')
1259 return;
1260 if (i != '.') {
1261 if (i == '*')
1262 showquaff();
1263 else {
1264 if (iven[i - 'a'] == OPOTION) {
1265 quaffpotion(ivenarg[i - 'a']);
1266 iven[i - 'a'] = 0;
1267 return;
1268 }
1269 if (iven[i - 'a'] == 0) {
1270 ydhi(i);
1271 return;
1272 }
1273 lprcat("\nYou wouldn't want to quaff that, would you? ");
1274 return;
1275 }
1276 }
1277 }
1278 }
1279
1280 /*
1281 function to ask what player wants to do
1282 */
1283 static int
1284 whatitem(const char *str)
1285 {
1286 int i;
1287 cursors();
1288 lprintf("\nWhat do you want to %s [* for all] ? ", str);
1289 i = 0;
1290 while (i > 'z' || (i < 'a' && i != '*' && i != '\33' && i != '.'))
1291 i = ttgetch();
1292 if (i == '\33')
1293 lprcat(" aborted");
1294 return (i);
1295 }
1296
1297 /*
1298 subroutine to get a number from the player
1299 and allow * to mean return amt, else return the number entered
1300 */
1301 unsigned long
1302 readnum(long mx)
1303 {
1304 int i;
1305 unsigned long amt = 0;
1306 sncbr();
1307 if ((i = ttgetch()) == '*')
1308 amt = mx; /* allow him to say * for all gold */
1309 else
1310 while (i != '\n') {
1311 if (i == '\033') {
1312 scbr();
1313 lprcat(" aborted");
1314 return (0);
1315 }
1316 if ((i <= '9') && (i >= '0') && (amt < 99999999))
1317 amt = amt * 10 + i - '0';
1318 i = ttgetch();
1319 }
1320 scbr();
1321 return (amt);
1322 }
1323
1324 #ifdef HIDEBYLINK
1325 /*
1326 * routine to zero every byte in a string
1327 */
1328 void
1329 szero(str)
1330 char *str;
1331 {
1332 while (*str)
1333 *str++ = 0;
1334 }
1335 #endif /* HIDEBYLINK */