xref: /dragonfly/games/battlestar/cypher.c (revision 5fb3968e)
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