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