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