main.c revision 1.4
1#ifndef lint 2static char rcsid[] = "$Id: main.c,v 1.4 1994/10/21 21:26:10 mycroft Exp $"; 3#endif /* not lint */ 4 5/* main.c */ 6#include <sys/types.h> 7#include "header.h" 8#include <pwd.h> 9static char copyright[]="\nLarn is copyrighted 1986 by Noah Morgan.\n"; 10int srcount=0; /* line counter for showstr() */ 11int dropflag=0; /* if 1 then don't lookforobject() next round */ 12int rmst=80; /* random monster creation counter */ 13int userid; /* the players login user id number */ 14char nowelcome=0,nomove=0; /* if (nomove) then don't count next iteration as a move */ 15static char viewflag=0; 16 /* if viewflag then we have done a 99 stay here and don't showcell in the main loop */ 17char restorflag=0; /* 1 means restore has been done */ 18static char cmdhelp[] = "\ 19Cmd line format: larn [-slicnh] [-o<optsifle>] [-##] [++]\n\ 20 -s show the scoreboard\n\ 21 -l show the logfile (wizard id only)\n\ 22 -i show scoreboard with inventories of dead characters\n\ 23 -c create new scoreboard (wizard id only)\n\ 24 -n suppress welcome message on starting game\n\ 25 -## specify level of difficulty (example: -5)\n\ 26 -h print this help text\n\ 27 ++ restore game from checkpoint file\n\ 28 -o<optsfile> specify .larnopts filename to be used instead of \"~/.larnopts\"\n\ 29"; 30#ifdef VT100 31static char *termtypes[] = { "vt100", "vt101", "vt102", "vt103", "vt125", 32 "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340", 33 "vt341" }; 34#endif VT100 35/* 36 ************ 37 MAIN PROGRAM 38 ************ 39 */ 40main(argc,argv) 41 int argc; 42 char **argv; 43 { 44 register int i,j; 45 int hard; 46 char *ptr=0,*ttype; 47 struct passwd *pwe; 48 49/* 50 * first task is to identify the player 51 */ 52#ifndef VT100 53 init_term(); /* setup the terminal (find out what type) for termcap */ 54#endif VT100 55 if (((ptr = getlogin()) == 0) || (*ptr==0)) /* try to get login name */ 56 if (pwe=getpwuid(getuid())) /* can we get it from /etc/passwd? */ 57 ptr = pwe->pw_name; 58 else 59 if ((ptr = getenv("USER")) == 0) 60 if ((ptr = getenv("LOGNAME")) == 0) 61 { 62 noone: write(2, "Can't find your logname. Who Are You?\n",39); 63 exit(); 64 } 65 if (ptr==0) goto noone; 66 if (strlen(ptr)==0) goto noone; 67/* 68 * second task is to prepare the pathnames the player will need 69 */ 70 strcpy(loginname,ptr); /* save loginname of the user for logging purposes */ 71 strcpy(logname,ptr); /* this will be overwritten with the players name */ 72 if ((ptr = getenv("HOME")) == 0) ptr = "."; 73 strcpy(savefilename, ptr); 74 strcat(savefilename, "/Larn.sav"); /* save file name in home directory */ 75 sprintf(optsfile, "%s/.larnopts",ptr); /* the .larnopts filename */ 76 77/* 78 * now malloc the memory for the dungeon 79 */ 80 cell = (struct cel *)malloc(sizeof(struct cel)*(MAXLEVEL+MAXVLEVEL)*MAXX*MAXY); 81 if (cell == 0) died(-285); /* malloc failure */ 82 lpbuf = malloc((5* BUFBIG)>>2); /* output buffer */ 83 inbuffer = malloc((5*MAXIBUF)>>2); /* output buffer */ 84 if ((lpbuf==0) || (inbuffer==0)) died(-285); /* malloc() failure */ 85 86 lcreat((char*)0); newgame(); /* set the initial clock */ hard= -1; 87 88#ifdef VT100 89/* 90 * check terminal type to avoid users who have not vt100 type terminals 91 */ 92 ttype = getenv("TERM"); 93 for (j=1, i=0; i<sizeof(termtypes)/sizeof(char *); i++) 94 if (strcmp(ttype,termtypes[i]) == 0) { j=0; break; } 95 if (j) 96 { 97 lprcat("Sorry, Larn needs a VT100 family terminal for all it's features.\n"); lflush(); 98 exit(); 99 } 100#endif VT100 101 102/* 103 * now make scoreboard if it is not there (don't clear) 104 */ 105 if (access(scorefile,0) == -1) /* not there */ 106 makeboard(); 107 108/* 109 * now process the command line arguments 110 */ 111 for (i=1; i<argc; i++) 112 { 113 if (argv[i][0] == '-') 114 switch(argv[i][1]) 115 { 116 case 's': showscores(); exit(); /* show scoreboard */ 117 118 case 'l': /* show log file */ 119 diedlog(); exit(); 120 121 case 'i': showallscores(); exit(); /* show all scoreboard */ 122 123 case 'c': /* anyone with password can create scoreboard */ 124 lprcat("Preparing to initialize the scoreboard.\n"); 125 if (getpassword() != 0) /*make new scoreboard*/ 126 { 127 makeboard(); lprc('\n'); showscores(); 128 } 129 exit(); 130 131 case 'n': /* no welcome msg */ nowelcome=1; argv[i][0]=0; break; 132 133 case '0': case '1': case '2': case '3': case '4': case '5': 134 case '6': case '7': case '8': case '9': /* for hardness */ 135 sscanf(&argv[i][1],"%d",&hard); 136 break; 137 138 case 'h': /* print out command line arguments */ 139 write(1,cmdhelp,sizeof(cmdhelp)); exit(); 140 141 case 'o': /* specify a .larnopts filename */ 142 strncpy(optsfile,argv[i]+2,127); break; 143 144 default: printf("Unknown option <%s>\n",argv[i]); exit(); 145 }; 146 147 if (argv[i][0] == '+') 148 { 149 clear(); restorflag = 1; 150 if (argv[i][1] == '+') 151 { 152 hitflag=1; restoregame(ckpfile); /* restore checkpointed game */ 153 } 154 i = argc; 155 } 156 } 157 158 readopts(); /* read the options file if there is one */ 159 160 161#ifdef UIDSCORE 162 userid = geteuid(); /* obtain the user's effective id number */ 163#else UIDSCORE 164 userid = getplid(logname); /* obtain the players id number */ 165#endif UIDSCORE 166 if (userid < 0) { write(2,"Can't obtain playerid\n",22); exit(); } 167 168#ifdef HIDEBYLINK 169/* 170 * this section of code causes the program to look like something else to ps 171 */ 172 if (strcmp(psname,argv[0])) /* if a different process name only */ 173 { 174 if ((i=access(psname,1)) < 0) 175 { /* link not there */ 176 if (link(argv[0],psname)>=0) 177 { 178 argv[0] = psname; execv(psname,argv); 179 } 180 } 181 else 182 unlink(psname); 183 } 184 185 for (i=1; i<argc; i++) 186 { 187 szero(argv[i]); /* zero the argument to avoid ps snooping */ 188 } 189#endif HIDEBYLINK 190 191 if (access(savefilename,0)==0) /* restore game if need to */ 192 { 193 clear(); restorflag = 1; 194 hitflag=1; restoregame(savefilename); /* restore last game */ 195 } 196 sigsetup(); /* trap all needed signals */ 197 sethard(hard); /* set up the desired difficulty */ 198 setupvt100(); /* setup the terminal special mode */ 199 if (c[HP]==0) /* create new game */ 200 { 201 makeplayer(); /* make the character that will play */ 202 newcavelevel(0);/* make the dungeon */ 203 predostuff = 1; /* tell signals that we are in the welcome screen */ 204 if (nowelcome==0) welcome(); /* welcome the player to the game */ 205 } 206 drawscreen(); /* show the initial dungeon */ 207 predostuff = 2; /* tell the trap functions that they must do a showplayer() 208 from here on */ 209 /* nice(1); /* games should be run niced */ 210 yrepcount = hit2flag = 0; 211 while (1) 212 { 213 if (dropflag==0) lookforobject(); /* see if there is an object here */ 214 else dropflag=0; /* don't show it just dropped an item */ 215 if (hitflag==0) { if (c[HASTEMONST]) movemonst(); movemonst(); } /* move the monsters */ 216 if (viewflag==0) showcell(playerx,playery); else viewflag=0; /* show stuff around player */ 217 if (hit3flag) flushall(); 218 hitflag=hit3flag=0; nomove=1; 219 bot_linex(); /* update bottom line */ 220 while (nomove) 221 { 222 if (hit3flag) flushall(); 223 nomove=0; parse(); 224 } /* get commands and make moves */ 225 regen(); /* regenerate hp and spells */ 226 if (c[TIMESTOP]==0) 227 if (--rmst <= 0) 228 { rmst = 120-(level<<2); fillmonst(makemonst(level)); } 229 } 230 } 231 232/* 233 showstr() 234 235 show character's inventory 236 */ 237showstr() 238 { 239 register int i,number; 240 for (number=3, i=0; i<26; i++) 241 if (iven[i]) number++; /* count items in inventory */ 242 t_setup(number); qshowstr(); t_endup(number); 243 } 244 245qshowstr() 246 { 247 register int i,j,k,sigsav; 248 srcount=0; sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ 249 if (c[GOLD]) { lprintf(".) %d gold pieces",(long)c[GOLD]); srcount++; } 250 for (k=26; k>=0; k--) 251 if (iven[k]) 252 { for (i=22; i<84; i++) 253 for (j=0; j<=k; j++) if (i==iven[j]) show3(j); k=0; } 254 255 lprintf("\nElapsed time is %d. You have %d mobuls left",(long)((gtime+99)/100+1),(long)((TIMELIMIT-gtime)/100)); 256 more(); nosignal=sigsav; 257 } 258 259/* 260 * subroutine to clear screen depending on # lines to display 261 */ 262t_setup(count) 263 register int count; 264 { 265 if (count<20) /* how do we clear the screen? */ 266 { 267 cl_up(79,count); cursor(1,1); 268 } 269 else 270 { 271 resetscroll(); clear(); 272 } 273 } 274 275/* 276 * subroutine to restore normal display screen depending on t_setup() 277 */ 278t_endup(count) 279 register int count; 280 { 281 if (count<18) /* how did we clear the screen? */ 282 draws(0,MAXX,0,(count>MAXY) ? MAXY : count); 283 else 284 { 285 drawscreen(); setscroll(); 286 } 287 } 288 289/* 290 function to show the things player is wearing only 291 */ 292showwear() 293 { 294 register int i,j,sigsav,count; 295 sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ 296 srcount=0; 297 298 for (count=2,j=0; j<=26; j++) /* count number of items we will display */ 299 if (i=iven[j]) 300 switch(i) 301 { 302 case OLEATHER: case OPLATE: case OCHAIN: 303 case ORING: case OSTUDLEATHER: case OSPLINT: 304 case OPLATEARMOR: case OSSPLATE: case OSHIELD: 305 count++; 306 }; 307 308 t_setup(count); 309 310 for (i=22; i<84; i++) 311 for (j=0; j<=26; j++) 312 if (i==iven[j]) 313 switch(i) 314 { 315 case OLEATHER: case OPLATE: case OCHAIN: 316 case ORING: case OSTUDLEATHER: case OSPLINT: 317 case OPLATEARMOR: case OSSPLATE: case OSHIELD: 318 show3(j); 319 }; 320 more(); nosignal=sigsav; t_endup(count); 321 } 322 323/* 324 function to show the things player can wield only 325 */ 326showwield() 327 { 328 register int i,j,sigsav,count; 329 sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ 330 srcount=0; 331 332 for (count=2,j=0; j<=26; j++) /* count how many items */ 333 if (i=iven[j]) 334 switch(i) 335 { 336 case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE: 337 case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT: 338 case OSPIRITSCARAB: case OCUBEofUNDEAD: 339 case OPOTION: case OSCROLL: break; 340 default: count++; 341 }; 342 343 t_setup(count); 344 345 for (i=22; i<84; i++) 346 for (j=0; j<=26; j++) 347 if (i==iven[j]) 348 switch(i) 349 { 350 case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE: 351 case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT: 352 case OSPIRITSCARAB: case OCUBEofUNDEAD: 353 case OPOTION: case OSCROLL: break; 354 default: show3(j); 355 }; 356 more(); nosignal=sigsav; t_endup(count); 357 } 358 359/* 360 * function to show the things player can read only 361 */ 362showread() 363 { 364 register int i,j,sigsav,count; 365 sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ 366 srcount=0; 367 368 for (count=2,j=0; j<=26; j++) 369 switch(iven[j]) 370 { 371 case OBOOK: case OSCROLL: count++; 372 }; 373 t_setup(count); 374 375 for (i=22; i<84; i++) 376 for (j=0; j<=26; j++) 377 if (i==iven[j]) 378 switch(i) 379 { 380 case OBOOK: case OSCROLL: show3(j); 381 }; 382 more(); nosignal=sigsav; t_endup(count); 383 } 384 385/* 386 * function to show the things player can eat only 387 */ 388showeat() 389 { 390 register int i,j,sigsav,count; 391 sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ 392 srcount=0; 393 394 for (count=2,j=0; j<=26; j++) 395 switch(iven[j]) 396 { 397 case OCOOKIE: count++; 398 }; 399 t_setup(count); 400 401 for (i=22; i<84; i++) 402 for (j=0; j<=26; j++) 403 if (i==iven[j]) 404 switch(i) 405 { 406 case OCOOKIE: show3(j); 407 }; 408 more(); nosignal=sigsav; t_endup(count); 409 } 410 411/* 412 function to show the things player can quaff only 413 */ 414showquaff() 415 { 416 register int i,j,sigsav,count; 417 sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ 418 srcount=0; 419 420 for (count=2,j=0; j<=26; j++) 421 switch(iven[j]) 422 { 423 case OPOTION: count++; 424 }; 425 t_setup(count); 426 427 for (i=22; i<84; i++) 428 for (j=0; j<=26; j++) 429 if (i==iven[j]) 430 switch(i) 431 { 432 case OPOTION: show3(j); 433 }; 434 more(); nosignal=sigsav; t_endup(count); 435 } 436 437show1(idx,str2) 438 register int idx; 439 register char *str2[]; 440 { 441 lprintf("\n%c) %s",idx+'a',objectname[iven[idx]]); 442 if (str2!=0 && str2[ivenarg[idx]][0]!=0) lprintf(" of%s",str2[ivenarg[idx]]); 443 } 444 445show3(index) 446 register int index; 447 { 448 switch(iven[index]) 449 { 450 case OPOTION: show1(index,potionname); break; 451 case OSCROLL: show1(index,scrollname); break; 452 453 case OLARNEYE: case OBOOK: case OSPIRITSCARAB: 454 case ODIAMOND: case ORUBY: case OCUBEofUNDEAD: 455 case OEMERALD: case OCHEST: case OCOOKIE: 456 case OSAPPHIRE: case ONOTHEFT: show1(index,(char **)0); break; 457 458 default: lprintf("\n%c) %s",index+'a',objectname[iven[index]]); 459 if (ivenarg[index]>0) lprintf(" + %d",(long)ivenarg[index]); 460 else if (ivenarg[index]<0) lprintf(" %d",(long)ivenarg[index]); 461 break; 462 } 463 if (c[WIELD]==index) lprcat(" (weapon in hand)"); 464 if ((c[WEAR]==index) || (c[SHIELD]==index)) lprcat(" (being worn)"); 465 if (++srcount>=22) { srcount=0; more(); clear(); } 466 } 467 468/* 469 subroutine to randomly create monsters if needed 470 */ 471randmonst() 472 { 473 if (c[TIMESTOP]) return; /* don't make monsters if time is stopped */ 474 if (--rmst <= 0) 475 { 476 rmst = 120 - (level<<2); fillmonst(makemonst(level)); 477 } 478 } 479 480 481/* 482 parse() 483 484 get and execute a command 485 */ 486parse() 487 { 488 register int i,j,k,flag; 489 while (1) 490 { 491 k = yylex(); 492 switch(k) /* get the token from the input and switch on it */ 493 { 494 case 'h': moveplayer(4); return; /* west */ 495 case 'H': run(4); return; /* west */ 496 case 'l': moveplayer(2); return; /* east */ 497 case 'L': run(2); return; /* east */ 498 case 'j': moveplayer(1); return; /* south */ 499 case 'J': run(1); return; /* south */ 500 case 'k': moveplayer(3); return; /* north */ 501 case 'K': run(3); return; /* north */ 502 case 'u': moveplayer(5); return; /* northeast */ 503 case 'U': run(5); return; /* northeast */ 504 case 'y': moveplayer(6); return; /* northwest */ 505 case 'Y': run(6); return; /* northwest */ 506 case 'n': moveplayer(7); return; /* southeast */ 507 case 'N': run(7); return; /* southeast */ 508 case 'b': moveplayer(8); return; /* southwest */ 509 case 'B': run(8); return; /* southwest */ 510 511 case '.': if (yrepcount) viewflag=1; return; /* stay here */ 512 513 case 'w': yrepcount=0; wield(); return; /* wield a weapon */ 514 515 case 'W': yrepcount=0; wear(); return; /* wear armor */ 516 517 case 'r': yrepcount=0; 518 if (c[BLINDCOUNT]) { cursors(); lprcat("\nYou can't read anything when you're blind!"); } else 519 if (c[TIMESTOP]==0) readscr(); return; /* to read a scroll */ 520 521 case 'q': yrepcount=0; if (c[TIMESTOP]==0) quaff(); return; /* quaff a potion */ 522 523 case 'd': yrepcount=0; if (c[TIMESTOP]==0) dropobj(); return; /* to drop an object */ 524 525 case 'c': yrepcount=0; cast(); return; /* cast a spell */ 526 527 case 'i': yrepcount=0; nomove=1; showstr(); return; /* status */ 528 529 case 'e': yrepcount=0; 530 if (c[TIMESTOP]==0) eatcookie(); return; /* to eat a fortune cookie */ 531 532 case 'D': yrepcount=0; seemagic(0); nomove=1; return; /* list spells and scrolls */ 533 534 case '?': yrepcount=0; help(); nomove=1; return; /* give the help screen*/ 535 536 case 'S': clear(); lprcat("Saving . . ."); lflush(); 537 savegame(savefilename); wizard=1; died(-257); /* save the game - doesn't return */ 538 539 case 'Z': yrepcount=0; if (c[LEVEL]>9) { oteleport(1); return; } 540 cursors(); lprcat("\nAs yet, you don't have enough experience to use teleportation"); 541 return; /* teleport yourself */ 542 543 case '^': /* identify traps */ flag=yrepcount=0; cursors(); 544 lprc('\n'); for (j=playery-1; j<playery+2; j++) 545 { 546 if (j < 0) j=0; if (j >= MAXY) break; 547 for (i=playerx-1; i<playerx+2; i++) 548 { 549 if (i < 0) i=0; if (i >= MAXX) break; 550 switch(item[i][j]) 551 { 552 case OTRAPDOOR: case ODARTRAP: 553 case OTRAPARROW: case OTELEPORTER: 554 lprcat("\nIts "); lprcat(objectname[item[i][j]]); flag++; 555 }; 556 } 557 } 558 if (flag==0) lprcat("\nNo traps are visible"); 559 return; 560 561#if WIZID 562 case '_': /* this is the fudge player password for wizard mode*/ 563 yrepcount=0; cursors(); nomove=1; 564 if (userid!=wisid) 565 { 566 lprcat("Sorry, you are not empowered to be a wizard.\n"); 567 scbr(); /* system("stty -echo cbreak"); */ 568 lflush(); return; 569 } 570 if (getpassword()==0) 571 { 572 scbr(); /* system("stty -echo cbreak"); */ return; 573 } 574 wizard=1; scbr(); /* system("stty -echo cbreak"); */ 575 for (i=0; i<6; i++) c[i]=70; iven[0]=iven[1]=0; 576 take(OPROTRING,50); take(OLANCE,25); c[WIELD]=1; 577 c[LANCEDEATH]=1; c[WEAR] = c[SHIELD] = -1; 578 raiseexperience(6000000L); c[AWARENESS] += 25000; 579 { 580 register int i,j; 581 for (i=0; i<MAXY; i++) 582 for (j=0; j<MAXX; j++) know[j][i]=1; 583 for (i=0; i<SPNUM; i++) spelknow[i]=1; 584 for (i=0; i<MAXSCROLL; i++) scrollname[i]=scrollhide[i]; 585 for (i=0; i<MAXPOTION; i++) potionname[i]=potionhide[i]; 586 } 587 for (i=0; i<MAXSCROLL; i++) 588 if (strlen(scrollname[i])>2) /* no null items */ 589 { item[i][0]=OSCROLL; iarg[i][0]=i; } 590 for (i=MAXX-1; i>MAXX-1-MAXPOTION; i--) 591 if (strlen(potionname[i-MAXX+MAXPOTION])>2) /* no null items */ 592 { item[i][0]=OPOTION; iarg[i][0]=i-MAXX+MAXPOTION; } 593 for (i=1; i<MAXY; i++) 594 { item[0][i]=i; iarg[0][i]=0; } 595 for (i=MAXY; i<MAXY+MAXX; i++) 596 { item[i-MAXY][MAXY-1]=i; iarg[i-MAXY][MAXY-1]=0; } 597 for (i=MAXX+MAXY; i<MAXX+MAXY+MAXY; i++) 598 { item[MAXX-1][i-MAXX-MAXY]=i; iarg[MAXX-1][i-MAXX-MAXY]=0; } 599 c[GOLD]+=25000; drawscreen(); return; 600#endif 601 602 case 'T': yrepcount=0; cursors(); if (c[SHIELD] != -1) { c[SHIELD] = -1; lprcat("\nYour shield is off"); bottomline(); } else 603 if (c[WEAR] != -1) { c[WEAR] = -1; lprcat("\nYour armor is off"); bottomline(); } 604 else lprcat("\nYou aren't wearing anything"); 605 return; 606 607 case 'g': cursors(); 608 lprintf("\nThe stuff you are carrying presently weighs %d pounds",(long)packweight()); 609 case ' ': yrepcount=0; nomove=1; return; 610 611 case 'v': yrepcount=0; cursors(); 612 lprintf("\nCaverns of Larn, Version %d.%d, Diff=%d",(long)VERSION,(long)SUBVERSION,(long)c[HARDGAME]); 613 if (wizard) lprcat(" Wizard"); nomove=1; 614 if (cheat) lprcat(" Cheater"); 615 lprcat(copyright); 616 return; 617 618 case 'Q': yrepcount=0; quit(); nomove=1; return; /* quit */ 619 620 case 'L'-64: yrepcount=0; drawscreen(); nomove=1; return; /* look */ 621 622#if WIZID 623#ifdef EXTRA 624 case 'A': yrepcount=0; nomove=1; if (wizard) { diag(); return; } /* create diagnostic file */ 625 return; 626#endif 627#endif 628 case 'P': cursors(); 629 if (outstanding_taxes>0) 630 lprintf("\nYou presently owe %d gp in taxes.",(long)outstanding_taxes); 631 else 632 lprcat("\nYou do not owe any taxes."); 633 return; 634 }; 635 } 636 } 637 638parse2() 639 { 640 if (c[HASTEMONST]) movemonst(); movemonst(); /* move the monsters */ 641 randmonst(); regen(); 642 } 643 644run(dir) 645 int dir; 646 { 647 register int i; 648 i=1; while (i) 649 { 650 i=moveplayer(dir); 651 if (i>0) { if (c[HASTEMONST]) movemonst(); movemonst(); randmonst(); regen(); } 652 if (hitflag) i=0; 653 if (i!=0) showcell(playerx,playery); 654 } 655 } 656 657/* 658 function to wield a weapon 659 */ 660wield() 661 { 662 register int i; 663 while (1) 664 { 665 if ((i = whatitem("wield"))=='\33') return; 666 if (i != '.') 667 { 668 if (i=='*') showwield(); 669 else if (iven[i-'a']==0) { ydhi(i); return; } 670 else if (iven[i-'a']==OPOTION) { ycwi(i); return; } 671 else if (iven[i-'a']==OSCROLL) { ycwi(i); return; } 672 else if ((c[SHIELD]!= -1) && (iven[i-'a']==O2SWORD)) { lprcat("\nBut one arm is busy with your shield!"); return; } 673 else { c[WIELD]=i-'a'; if (iven[i-'a'] == OLANCE) c[LANCEDEATH]=1; else c[LANCEDEATH]=0; bottomline(); return; } 674 } 675 } 676 } 677 678/* 679 common routine to say you don't have an item 680 */ 681ydhi(x) 682 int x; 683 { cursors(); lprintf("\nYou don't have item %c!",x); } 684ycwi(x) 685 int x; 686 { cursors(); lprintf("\nYou can't wield item %c!",x); } 687 688/* 689 function to wear armor 690 */ 691wear() 692 { 693 register int i; 694 while (1) 695 { 696 if ((i = whatitem("wear"))=='\33') return; 697 if (i != '.') 698 { 699 if (i=='*') showwear(); else 700 switch(iven[i-'a']) 701 { 702 case 0: ydhi(i); return; 703 case OLEATHER: case OCHAIN: case OPLATE: case OSTUDLEATHER: 704 case ORING: case OSPLINT: case OPLATEARMOR: case OSSPLATE: 705 if (c[WEAR] != -1) { lprcat("\nYou're already wearing some armor"); return; } 706 c[WEAR]=i-'a'; bottomline(); return; 707 case OSHIELD: if (c[SHIELD] != -1) { lprcat("\nYou are already wearing a shield"); return; } 708 if (iven[c[WIELD]]==O2SWORD) { lprcat("\nYour hands are busy with the two handed sword!"); return; } 709 c[SHIELD] = i-'a'; bottomline(); return; 710 default: lprcat("\nYou can't wear that!"); 711 }; 712 } 713 } 714 } 715 716/* 717 function to drop an object 718 */ 719dropobj() 720 { 721 register int i; 722 register char *p; 723 long amt; 724 p = &item[playerx][playery]; 725 while (1) 726 { 727 if ((i = whatitem("drop"))=='\33') return; 728 if (i=='*') showstr(); else 729 { 730 if (i=='.') /* drop some gold */ 731 { 732 if (*p) { lprcat("\nThere's something here already!"); return; } 733 lprcat("\n\n"); 734 cl_dn(1,23); 735 lprcat("How much gold do you drop? "); 736 if ((amt=readnum((long)c[GOLD])) == 0) return; 737 if (amt>c[GOLD]) 738 { lprcat("\nYou don't have that much!"); return; } 739 if (amt<=32767) 740 { *p=OGOLDPILE; i=amt; } 741 else if (amt<=327670L) 742 { *p=ODGOLD; i=amt/10; amt = 10*i; } 743 else if (amt<=3276700L) 744 { *p=OMAXGOLD; i=amt/100; amt = 100*i; } 745 else if (amt<=32767000L) 746 { *p=OKGOLD; i=amt/1000; amt = 1000*i; } 747 else 748 { *p=OKGOLD; i=32767; amt = 32767000L; } 749 c[GOLD] -= amt; 750 lprintf("You drop %d gold pieces",(long)amt); 751 iarg[playerx][playery]=i; bottomgold(); 752 know[playerx][playery]=0; dropflag=1; return; 753 } 754 drop_object(i-'a'); 755 return; 756 } 757 } 758 } 759 760/* 761 * readscr() Subroutine to read a scroll one is carrying 762 */ 763readscr() 764 { 765 register int i; 766 while (1) 767 { 768 if ((i = whatitem("read"))=='\33') return; 769 if (i != '.') 770 { 771 if (i=='*') showread(); else 772 { 773 if (iven[i-'a']==OSCROLL) { read_scroll(ivenarg[i-'a']); iven[i-'a']=0; return; } 774 if (iven[i-'a']==OBOOK) { readbook(ivenarg[i-'a']); iven[i-'a']=0; return; } 775 if (iven[i-'a']==0) { ydhi(i); return; } 776 lprcat("\nThere's nothing on it to read"); return; 777 } 778 } 779 } 780 } 781 782/* 783 * subroutine to eat a cookie one is carrying 784 */ 785eatcookie() 786{ 787register int i; 788char *p; 789while (1) 790 { 791 if ((i = whatitem("eat"))=='\33') return; 792 if (i != '.') 793 if (i=='*') showeat(); else 794 { 795 if (iven[i-'a']==OCOOKIE) 796 { 797 lprcat("\nThe cookie was delicious."); 798 iven[i-'a']=0; 799 if (!c[BLINDCOUNT]) 800 { 801 if (p=fortune(fortfile)) 802 { 803 lprcat(" Inside you find a scrap of paper that says:\n"); 804 lprcat(p); 805 } 806 } 807 return; 808 } 809 if (iven[i-'a']==0) { ydhi(i); return; } 810 lprcat("\nYou can't eat that!"); return; 811 } 812 } 813} 814 815/* 816 * subroutine to quaff a potion one is carrying 817 */ 818quaff() 819 { 820 register int i; 821 while (1) 822 { 823 if ((i = whatitem("quaff"))=='\33') return; 824 if (i != '.') 825 { 826 if (i=='*') showquaff(); else 827 { 828 if (iven[i-'a']==OPOTION) { quaffpotion(ivenarg[i-'a']); iven[i-'a']=0; return; } 829 if (iven[i-'a']==0) { ydhi(i); return; } 830 lprcat("\nYou wouldn't want to quaff that, would you? "); return; 831 } 832 } 833 } 834 } 835 836/* 837 function to ask what player wants to do 838 */ 839whatitem(str) 840 char *str; 841 { 842 int i; 843 cursors(); lprintf("\nWhat do you want to %s [* for all] ? ",str); 844 i=0; while (i>'z' || (i<'a' && i!='*' && i!='\33' && i!='.')) i=getchar(); 845 if (i=='\33') lprcat(" aborted"); 846 return(i); 847 } 848 849/* 850 subroutine to get a number from the player 851 and allow * to mean return amt, else return the number entered 852 */ 853unsigned long readnum(mx) 854 long mx; 855 { 856 register int i; 857 register unsigned long amt=0; 858 sncbr(); 859 if ((i=getchar()) == '*') amt = mx; /* allow him to say * for all gold */ 860 else 861 while (i != '\n') 862 { 863 if (i=='\033') { scbr(); lprcat(" aborted"); return(0); } 864 if ((i <= '9') && (i >= '0') && (amt<99999999)) 865 amt = amt*10+i-'0'; 866 i = getchar(); 867 } 868 scbr(); return(amt); 869 } 870 871#ifdef HIDEBYLINK 872/* 873 * routine to zero every byte in a string 874 */ 875szero(str) 876 register char *str; 877 { 878 while (*str) 879 *str++ = 0; 880 } 881#endif HIDEBYLINK 882