1 /* @(#)cypher.c 8.2 (Berkeley) 4/28/95 */ 2 /* $NetBSD: cypher.c,v 1.23 2005/07/01 06:04:54 jmc Exp $ */ 3 4 /* 5 * Copyright (c) 1983, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include "extern.h" 34 35 int 36 cypher(void) 37 { 38 int n; 39 int junk; 40 int lflag = -1; 41 char buffer[10]; 42 char *filename, *rfilename; 43 size_t filename_len; 44 45 while (wordnumber <= wordcount) { 46 if (wordtype[wordnumber] != VERB && 47 !(wordtype[wordnumber] == OBJECT && 48 wordvalue[wordnumber] == KNIFE)) { 49 printf("%s: How's that?\n", 50 (wordnumber == wordcount) ? words[0] : 51 words[wordnumber]); 52 return (-1); 53 } 54 55 switch (wordvalue[wordnumber]) { 56 57 case AUXVERB: 58 /* 59 * Take the following word as the verb (e.g. 60 * "make love", "climb up"). 61 */ 62 wordnumber++; 63 continue; 64 65 case UP: 66 if (location[position].access || wiz || tempwiz) { 67 if (!location[position].access) { 68 printf("Zap! A gust of wind lifts "); 69 puts("you up."); 70 } 71 if (!moveplayer(location[position].up, AHEAD)) 72 return (-1); 73 } else { 74 puts("There is no way up."); 75 return (-1); 76 } 77 lflag = 0; 78 break; 79 80 case DOWN: 81 if (!moveplayer(location[position].down, AHEAD)) 82 return (-1); 83 lflag = 0; 84 break; 85 86 case LEFT: 87 if (!moveplayer(left, LEFT)) 88 return (-1); 89 lflag = 0; 90 break; 91 92 case RIGHT: 93 if (!moveplayer(right, RIGHT)) 94 return (-1); 95 lflag = 0; 96 break; 97 98 case AHEAD: 99 if (!moveplayer(ahead, AHEAD)) 100 return (-1); 101 lflag = 0; 102 break; 103 104 case BACK: 105 if (!moveplayer(back, BACK)) 106 return (-1); 107 lflag = 0; 108 break; 109 110 case SHOOT: 111 if (wordnumber < wordcount && 112 wordvalue[wordnumber + 1] == EVERYTHING) { 113 int things; 114 things = 0; 115 for (n = 0; n < NUMOFOBJECTS; n++) 116 if (testbit(location[position].objects, 117 n) && objsht[n]) { 118 things++; 119 wordvalue[wordnumber + 1] = n; 120 wordnumber = shoot(); 121 } 122 if (!things) 123 puts("Nothing to shoot at!"); 124 wordnumber++; 125 wordnumber++; 126 } else 127 shoot(); 128 break; 129 130 case TAKE: 131 if (wordnumber < wordcount && 132 wordvalue[wordnumber + 1] == EVERYTHING) { 133 int things; 134 things = 0; 135 for (n = 0; n < NUMOFOBJECTS; n++) 136 if (testbit(location[position].objects, 137 n) && objsht[n]) { 138 things++; 139 wordvalue[wordnumber + 1] = n; 140 /* Some objects (type NOUNS) 141 * have special treatment in 142 * take(). For these we 143 * must set the type to NOUNS. 144 * However for SWORD and BODY 145 * all it does is find which 146 * of many objects is meant, 147 * so we need do nothing here. 148 * BATHGOD must become 149 * NORMGOD as well. NOUNS 150 * with no special case 151 * must be included here to 152 * get the right error. DOOR 153 * cannot occur as an object 154 * so need not be included. */ 155 switch(n) { 156 case BATHGOD: 157 wordvalue[wordnumber + 1] = NORMGOD; 158 /* FALLTHROUGH */ 159 case NORMGOD: 160 case AMULET: 161 case MEDALION: 162 case TALISMAN: 163 case MAN: 164 case TIMER: 165 case NATIVE: 166 wordtype[wordnumber + 1] = NOUNS; 167 break; 168 default: 169 wordtype[wordnumber + 1] = OBJECT; 170 } 171 wordnumber = take(location[position].objects); 172 } 173 wordnumber++; 174 wordnumber++; 175 if (!things) 176 puts("Nothing to take!"); 177 } else 178 take(location[position].objects); 179 break; 180 181 case DROP: 182 if (wordnumber < wordcount && 183 wordvalue[wordnumber + 1] == EVERYTHING) { 184 int things; 185 things = 0; 186 for (n = 0; n < NUMOFOBJECTS; n++) 187 if (testbit(inven, n)) { 188 things++; 189 wordvalue[wordnumber + 1] = n; 190 wordnumber = drop("Dropped"); 191 } 192 wordnumber++; 193 wordnumber++; 194 if (!things) 195 puts("Nothing to drop!"); 196 } else 197 drop("Dropped"); 198 break; 199 200 case KICK: 201 case THROW: 202 if (wordnumber < wordcount && 203 wordvalue[wordnumber + 1] == EVERYTHING) { 204 int things, wv; 205 things = 0; 206 wv = wordvalue[wordnumber]; 207 for (n = 0; n < NUMOFOBJECTS; n++) 208 if (testbit(inven, n) || 209 (testbit(location[position].objects, n) && objsht[n])) { 210 things++; 211 wordvalue[wordnumber + 1] = n; 212 wordnumber = throw(wordvalue[wordnumber] == KICK ? "Kicked" : "Thrown"); 213 } 214 wordnumber += 2; 215 if (!things) 216 printf("Nothing to %s!\n", 217 wv == KICK ? "kick" : "throw"); 218 } else 219 throw(wordvalue[wordnumber] == 220 KICK ? "Kicked" : "Thrown"); 221 break; 222 223 case TAKEOFF: 224 if (wordnumber < wordcount && 225 wordvalue[wordnumber + 1] == EVERYTHING) { 226 int things; 227 things = 0; 228 for (n = 0; n < NUMOFOBJECTS; n++) 229 if (testbit(wear, n)) { 230 things++; 231 wordvalue[wordnumber + 1] = n; 232 wordnumber = takeoff(); 233 } 234 wordnumber += 2; 235 if (!things) 236 puts("Nothing to take off!"); 237 } else 238 takeoff(); 239 break; 240 241 case DRAW: 242 if (wordnumber < wordcount && 243 wordvalue[wordnumber + 1] == EVERYTHING) { 244 int things; 245 things = 0; 246 for (n = 0; n < NUMOFOBJECTS; n++) 247 if (testbit(wear, n)) { 248 things++; 249 wordvalue[wordnumber + 1] = n; 250 wordnumber = draw(); 251 } 252 wordnumber += 2; 253 if (!things) 254 puts("Nothing to draw!"); 255 } else 256 draw(); 257 break; 258 259 case PUTON: 260 if (wordnumber < wordcount && 261 wordvalue[wordnumber + 1] == EVERYTHING) { 262 int things; 263 things = 0; 264 for (n = 0; n < NUMOFOBJECTS; n++) 265 if (testbit(location[position].objects, 266 n) && objsht[n]) { 267 things++; 268 wordvalue[wordnumber + 1] = n; 269 wordnumber = puton(); 270 } 271 wordnumber += 2; 272 if (!things) 273 puts("Nothing to put on!"); 274 } else 275 puton(); 276 break; 277 278 case WEARIT: 279 if (wordnumber < wordcount && 280 wordvalue[wordnumber + 1] == EVERYTHING) { 281 int things; 282 things = 0; 283 for (n = 0; n < NUMOFOBJECTS; n++) 284 if (testbit(inven, n)) { 285 things++; 286 wordvalue[wordnumber + 1] = n; 287 wordnumber = wearit(); 288 } 289 wordnumber += 2; 290 if (!things) 291 puts("Nothing to wear!"); 292 } else 293 wearit(); 294 break; 295 296 case EAT: 297 if (wordnumber < wordcount && 298 wordvalue[wordnumber + 1] == EVERYTHING) { 299 int things; 300 things = 0; 301 for (n = 0; n < NUMOFOBJECTS; n++) 302 if (testbit(inven, n)) { 303 things++; 304 wordvalue[wordnumber + 1] = n; 305 wordnumber = eat(); 306 } 307 wordnumber += 2; 308 if (!things) 309 puts("Nothing to eat!"); 310 } else 311 eat(); 312 break; 313 314 case PUT: 315 put(); 316 break; 317 318 case INVEN: 319 if (ucard(inven)) { 320 puts("You are holding:\n"); 321 for (n = 0; n < NUMOFOBJECTS; n++) 322 if (testbit(inven, n)) 323 printf("\t%s\n", objsht[n]); 324 if (WEIGHT == 0) { 325 printf("\n= %d kilogram%s", 326 carrying, 327 (carrying == 1 ? "." : "s.")); 328 printf(" (can't lift any weight%s)\n", 329 (carrying ? 330 " or move with what you have" : 331 "")); 332 } else 333 printf("\n= %d kilogram%s (%d%%)\n", 334 carrying, 335 (carrying == 1 ? "." : "s."), 336 carrying * 100 / WEIGHT); 337 if (CUMBER == 0) { 338 printf("Your arms can't pick "); 339 printf("anything up.\n"); 340 } else 341 printf("Your arms are %d%% full.\n", 342 encumber * 100 / CUMBER); 343 } else 344 puts("You aren't carrying anything."); 345 346 if (ucard(wear)) { 347 puts("\nYou are wearing:\n"); 348 for (n = 0; n < NUMOFOBJECTS; n++) 349 if (testbit(wear, n)) 350 printf("\t%s\n", objsht[n]); 351 } else 352 puts("\nYou are stark naked."); 353 if (card(injuries, NUMOFINJURIES)) { 354 puts("\nYou have suffered:\n"); 355 for (n = 0; n < NUMOFINJURIES; n++) 356 if (injuries[n]) 357 printf("\t%s\n", ouch[n]); 358 printf("\nYou can still carry up to "); 359 printf("%d kilogram%s\n", WEIGHT, 360 (WEIGHT == 1 ? "." : "s.")); 361 } else 362 puts("\nYou are in perfect health."); 363 wordnumber++; 364 break; 365 366 case USE: 367 lflag = use(); 368 break; 369 370 case OPEN: 371 if (wordnumber < wordcount && 372 wordvalue[wordnumber + 1] == EVERYTHING) { 373 int things; 374 things = 0; 375 for (n = 0; n < NUMOFOBJECTS; n++) 376 if (testbit(inven, n)) { 377 things++; 378 wordvalue[wordnumber + 1] = n; 379 dooropen(); 380 } 381 wordnumber += 2; 382 if (!things) 383 puts("Nothing to open!"); 384 } else 385 dooropen(); 386 break; 387 388 case LOOK: 389 if (!notes[CANTSEE] || testbit(inven, LAMPON) || 390 testbit(location[position].objects, LAMPON) 391 || matchlight) { 392 beenthere[position] = 2; 393 writedes(); 394 printobjs(); 395 if (matchlight) { 396 puts("\nYour match splutters out."); 397 matchlight = 0; 398 } 399 } else 400 puts("I can't see anything."); 401 return (-1); 402 break; 403 404 case SU: 405 if (wiz || tempwiz) { 406 printf("\nRoom (was %d) = ", position); 407 fgets(buffer, 10, stdin); 408 if (*buffer != '\n') 409 sscanf(buffer, "%d", &position); 410 printf("Time (was %d) = ", ourtime); 411 fgets(buffer, 10, stdin); 412 if (*buffer != '\n') 413 sscanf(buffer, "%d", &ourtime); 414 printf("Fuel (was %d) = ", fuel); 415 fgets(buffer, 10, stdin); 416 if (*buffer != '\n') 417 sscanf(buffer, "%d", &fuel); 418 printf("Torps (was %d) = ", torps); 419 fgets(buffer, 10, stdin); 420 if (*buffer != '\n') 421 sscanf(buffer, "%d", &torps); 422 printf("CUMBER (was %d) = ", CUMBER); 423 fgets(buffer, 10, stdin); 424 if (*buffer != '\n') 425 sscanf(buffer, "%d", &CUMBER); 426 printf("WEIGHT (was %d) = ", WEIGHT); 427 fgets(buffer, 10, stdin); 428 if (*buffer != '\n') 429 sscanf(buffer, "%d", &WEIGHT); 430 printf("Clock (was %d) = ", ourclock); 431 fgets(buffer, 10, stdin); 432 if (*buffer != '\n') 433 sscanf(buffer, "%d", &ourclock); 434 printf("Wizard (was %d, %d) = ", wiz, tempwiz); 435 fgets(buffer, 10, stdin); 436 if (*buffer != '\n') { 437 sscanf(buffer, "%d", &junk); 438 if (!junk) 439 tempwiz = wiz = 0; 440 } 441 printf("\nDONE.\n"); 442 return (0); 443 } else 444 puts("You aren't a wizard."); 445 break; 446 447 case SCORE: 448 printf("\tPLEASURE\tPOWER\t\tEGO\n"); 449 printf("\t%3d\t\t%3d\t\t%3d\n\n", pleasure, power, ego); 450 printf("This gives you the rating of "); 451 printf("%s in %d turns.\n", rate(), ourtime); 452 printf("You have visited %d out of %d rooms ", 453 card(beenthere, NUMOFROOMS), NUMOFROOMS); 454 printf("this run (%d%%).\n", 455 card(beenthere, NUMOFROOMS) * 100 / NUMOFROOMS); 456 break; 457 458 case KNIFE: 459 case KILL: 460 murder(); 461 break; 462 463 case UNDRESS: 464 case RAVAGE: 465 ravage(); 466 break; 467 468 case SAVE: 469 printf("\nSave file name (default %s): ", 470 DEFAULT_SAVE_FILE); 471 filename = fgetln(stdin, &filename_len); 472 if (filename_len == 0 473 || (filename_len == 1 && filename[0] == '\n')) 474 rfilename = save_file_name(DEFAULT_SAVE_FILE, 475 strlen(DEFAULT_SAVE_FILE)); 476 else { 477 if (filename[filename_len - 1] == '\n') 478 filename_len--; 479 rfilename = save_file_name(filename, 480 filename_len); 481 } 482 save(rfilename); 483 free(rfilename); 484 break; 485 486 case VERBOSE: 487 verbose = 1; 488 printf("[Maximum verbosity]\n"); 489 break; 490 491 case BRIEF: 492 verbose = 0; 493 printf("[Standard verbosity]\n"); 494 break; 495 496 case FOLLOW: 497 lflag = follow(); 498 break; 499 500 case GIVE: 501 give(); 502 break; 503 504 case KISS: 505 kiss(); 506 break; 507 508 case LOVE: 509 love(); 510 break; 511 512 case RIDE: 513 lflag = ride(); 514 break; 515 516 case DRIVE: 517 lflag = drive(); 518 break; 519 520 case LIGHT: 521 light(); 522 break; 523 524 case LAUNCH: 525 if (!launch()) 526 return (-1); 527 else 528 lflag = 0; 529 break; 530 531 case LANDIT: 532 if (!land()) 533 return (-1); 534 else 535 lflag = 0; 536 break; 537 538 case TIME: 539 chime(); 540 break; 541 542 case SLEEP: 543 zzz(); 544 break; 545 546 case DIG: 547 dig(); 548 break; 549 550 case JUMP: 551 lflag = jump(); 552 break; 553 554 case BURY: 555 bury(); 556 break; 557 558 case SWIM: 559 puts("Surf's up!"); 560 break; 561 562 case DRINK: 563 drink(); 564 break; 565 566 case QUIT: 567 die(); 568 569 default: 570 puts("How's that?"); 571 return (-1); 572 break; 573 574 } 575 if (wordnumber < wordcount && *words[wordnumber++] == ',') 576 continue; 577 else 578 return (lflag); 579 } 580 return (lflag); 581 } 582