main.c revision 1.14
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 18static char copyright[] = "\nLarn is copyrighted 1986 by Noah Morgan.\n"; 19int srcount = 0; /* line counter for showstr() */ 20int dropflag = 0; /* if 1 then don't lookforobject() next round */ 21int rmst = 80; /* random monster creation counter */ 22int userid; /* the players login user id number */ 23uid_t uid, euid; /* used for security */ 24u_char nowelcome = 0, nomove = 0; /* if (nomove) then don't 25 * count next iteration as a 26 * move */ 27static 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 */ 32u_char restorflag = 0; /* 1 means restore has been done */ 33static char cmdhelp[] = "\ 34Cmd 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 46static 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 */ 55int 56main(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 */ 308void 309showstr() 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 320void 321qshowstr() 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 */ 347void 348t_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 */ 363void 364t_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 */ 378void 379showwear() 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 */ 427void 428showwield() 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 */ 485void 486showread() 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 */ 517void 518showeat() 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 */ 547void 548showquaff() 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 574void 575show1(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 584void 585show3(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 */ 632void 633randmonst() 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 */ 650void 651parse() 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 956void 957parse2() 958{ 959 if (c[HASTEMONST]) 960 movemonst(); 961 movemonst(); /* move the monsters */ 962 randmonst(); 963 regen(); 964} 965 966void 967run(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 */ 991void 992wield() 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 */ 1029void 1030ydhi(x) 1031 int x; 1032{ 1033 cursors(); 1034 lprintf("\nYou don't have item %c!", x); 1035} 1036void 1037ycwi(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 */ 1047void 1048wear() 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 */ 1099void 1100dropobj() 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 */ 1163void 1164readscr() 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 */ 1198void 1199eatcookie() 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 */ 1235void 1236quaff() 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 */ 1265int 1266whatitem(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 */ 1284unsigned long 1285readnum(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 */ 1312void 1313szero(str) 1314 char *str; 1315{ 1316 while (*str) 1317 *str++ = 0; 1318} 1319#endif /* HIDEBYLINK */ 1320