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