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