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