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