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