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