]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - battlestar/cypher.c
Prevent CUMBER from going negative; avoid division by zero if it is
[bsdgames-darwin.git] / battlestar / cypher.c
1 /* $NetBSD: cypher.c,v 1.18 2000/09/24 09:41:53 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.18 2000/09/24 09:41:53 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 switch (wordvalue[wordnumber]) {
59
60 case UP:
61 if (location[position].access || wiz || tempwiz) {
62 if (!location[position].access)
63 puts("Zap! A gust of wind lifts you up.");
64 if (!moveplayer(location[position].up, AHEAD))
65 return (-1);
66 } else {
67 puts("There is no way up.");
68 return (-1);
69 }
70 lflag = 0;
71 break;
72
73 case DOWN:
74 if (!moveplayer(location[position].down, AHEAD))
75 return (-1);
76 lflag = 0;
77 break;
78
79 case LEFT:
80 if (!moveplayer(left, LEFT))
81 return (-1);
82 lflag = 0;
83 break;
84
85 case RIGHT:
86 if (!moveplayer(right, RIGHT))
87 return (-1);
88 lflag = 0;
89 break;
90
91 case AHEAD:
92 if (!moveplayer(ahead, AHEAD))
93 return (-1);
94 lflag = 0;
95 break;
96
97 case BACK:
98 if (!moveplayer(back, BACK))
99 return (-1);
100 lflag = 0;
101 break;
102
103 case SHOOT:
104 if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
105 int things;
106 things = 0;
107 for (n = 0; n < NUMOFOBJECTS; n++)
108 if (testbit(location[position].objects, n) && objsht[n]) {
109 things++;
110 wordvalue[wordnumber + 1] = n;
111 wordnumber = shoot();
112 }
113 if (!things)
114 puts("Nothing to shoot at!");
115 wordnumber++;
116 wordnumber++;
117 } else
118 shoot();
119 break;
120
121 case TAKE:
122 if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
123 int things;
124 things = 0;
125 for (n = 0; n < NUMOFOBJECTS; n++)
126 if (testbit(location[position].objects, n) && objsht[n]) {
127 things++;
128 wordvalue[wordnumber + 1] = n;
129 /* Some objects (type NOUNS)
130 * have special treatment in
131 * take(). For these we
132 * must set the type to NOUNS.
133 * However for SWORD and BODY
134 * all it does is find which
135 * of many objects is meant,
136 * so we need do nothing here.
137 * BATHGOD must become
138 * NORMGOD as well. NOUNS
139 * with no special case
140 * must be included here to
141 * get the right error. DOOR
142 * cannot occur as an object
143 * so need not be included. */
144 switch(n) {
145 case BATHGOD:
146 wordvalue[wordnumber + 1] = NORMGOD;
147 /* FALLTHROUGH */
148 case NORMGOD:
149 case AMULET:
150 case MEDALION:
151 case TALISMAN:
152 case MAN:
153 case TIMER:
154 case NATIVE:
155 wordtype[wordnumber + 1] = NOUNS;
156 break;
157 default:
158 wordtype[wordnumber + 1] = OBJECT;
159 }
160 wordnumber = take(location[position].objects);
161 }
162 wordnumber++;
163 wordnumber++;
164 if (!things)
165 puts("Nothing to take!");
166 } else
167 take(location[position].objects);
168 break;
169
170 case DROP:
171
172 if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
173 int things;
174 things = 0;
175 for (n = 0; n < NUMOFOBJECTS; n++)
176 if (testbit(inven, n)) {
177 things++;
178 wordvalue[wordnumber + 1] = n;
179 wordnumber = drop("Dropped");
180 }
181 wordnumber++;
182 wordnumber++;
183 if (!things)
184 puts("Nothing to drop!");
185 } else
186 drop("Dropped");
187 break;
188
189
190 case KICK:
191 case THROW:
192 if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
193 int things, wv;
194 things = 0;
195 wv = wordvalue[wordnumber];
196 for (n = 0; n < NUMOFOBJECTS; n++)
197 if (testbit(inven, n) ||
198 (testbit(location[position].objects, n) && objsht[n])) {
199 things++;
200 wordvalue[wordnumber + 1] = n;
201 wordnumber = throw(wordvalue[wordnumber] == KICK ? "Kicked" : "Thrown");
202 }
203 wordnumber += 2;
204 if (!things)
205 printf("Nothing to %s!\n", wv == KICK ? "kick" : "throw");
206 } else
207 throw(wordvalue[wordnumber] == KICK ? "Kicked" : "Thrown");
208 break;
209
210 case TAKEOFF:
211 if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
212 int things;
213 things = 0;
214 for (n = 0; n < NUMOFOBJECTS; n++)
215 if (testbit(wear, n)) {
216 things++;
217 wordvalue[wordnumber + 1] = n;
218 wordnumber = takeoff();
219 }
220 wordnumber += 2;
221 if (!things)
222 puts("Nothing to take off!");
223 } else
224 takeoff();
225 break;
226
227
228 case DRAW:
229
230 if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
231 int things;
232 things = 0;
233 for (n = 0; n < NUMOFOBJECTS; n++)
234 if (testbit(wear, n)) {
235 things++;
236 wordvalue[wordnumber + 1] = n;
237 wordnumber = draw();
238 }
239 wordnumber += 2;
240 if (!things)
241 puts("Nothing to draw!");
242 } else
243 draw();
244 break;
245
246
247 case PUTON:
248
249 if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
250 int things;
251 things = 0;
252 for (n = 0; n < NUMOFOBJECTS; n++)
253 if (testbit(location[position].objects, n) && objsht[n]) {
254 things++;
255 wordvalue[wordnumber + 1] = n;
256 wordnumber = puton();
257 }
258 wordnumber += 2;
259 if (!things)
260 puts("Nothing to put on!");
261 } else
262 puton();
263 break;
264
265 case WEARIT:
266
267 if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
268 int things;
269 things = 0;
270 for (n = 0; n < NUMOFOBJECTS; n++)
271 if (testbit(inven, n)) {
272 things++;
273 wordvalue[wordnumber + 1] = n;
274 wordnumber = wearit();
275 }
276 wordnumber += 2;
277 if (!things)
278 puts("Nothing to wear!");
279 } else
280 wearit();
281 break;
282
283
284 case EAT:
285
286 if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
287 int things;
288 things = 0;
289 for (n = 0; n < NUMOFOBJECTS; n++)
290 if (testbit(inven, n)) {
291 things++;
292 wordvalue[wordnumber + 1] = n;
293 wordnumber = eat();
294 }
295 wordnumber += 2;
296 if (!things)
297 puts("Nothing to eat!");
298 } else
299 eat();
300 break;
301
302
303 case PUT:
304 put();
305 break;
306
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 printf("\n= %d kilogram%s (%d%%)\n", carrying, (carrying == 1 ? "." : "s."), (WEIGHT ? carrying * 100 / WEIGHT : -1));
315 printf("Your arms are %d%% full.\n",
316 (CUMBER ? encumber * 100 / CUMBER : -1));
317 } else
318 puts("You aren't carrying anything.");
319
320 if (ucard(wear)) {
321 puts("\nYou are wearing:\n");
322 for (n = 0; n < NUMOFOBJECTS; n++)
323 if (testbit(wear, n))
324 printf("\t%s\n", objsht[n]);
325 } else
326 puts("\nYou are stark naked.");
327 if (card(injuries, NUMOFINJURIES)) {
328 puts("\nYou have suffered:\n");
329 for (n = 0; n < NUMOFINJURIES; n++)
330 if (injuries[n])
331 printf("\t%s\n", ouch[n]);
332 printf("\nYou can still carry up to %d kilogram%s\n", WEIGHT, (WEIGHT == 1 ? "." : "s."));
333 } else
334 puts("\nYou are in perfect health.");
335 wordnumber++;
336 break;
337
338 case USE:
339 lflag = use();
340 break;
341
342 case OPEN:
343 if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
344 int things;
345 things = 0;
346 for (n = 0; n < NUMOFOBJECTS; n++)
347 if (testbit(inven, n)) {
348 things++;
349 wordvalue[wordnumber + 1] = n;
350 dooropen();
351 }
352 wordnumber += 2;
353 if (!things)
354 puts("Nothing to open!");
355 } else
356 dooropen();
357 break;
358
359 case LOOK:
360 if (!notes[CANTSEE] || testbit(inven, LAMPON) ||
361 testbit(location[position].objects, LAMPON)
362 || matchlight) {
363 beenthere[position] = 2;
364 writedes();
365 printobjs();
366 if (matchlight) {
367 puts("\nYour match splutters out.");
368 matchlight = 0;
369 }
370 } else
371 puts("I can't see anything.");
372 return (-1);
373 break;
374
375 case SU:
376 if (wiz || tempwiz) {
377 printf("\nRoom (was %d) = ", position);
378 fgets(buffer, 10, stdin);
379 if (*buffer != '\n')
380 sscanf(buffer, "%d", &position);
381 printf("Time (was %d) = ", ourtime);
382 fgets(buffer, 10, stdin);
383 if (*buffer != '\n')
384 sscanf(buffer, "%d", &ourtime);
385 printf("Fuel (was %d) = ", fuel);
386 fgets(buffer, 10, stdin);
387 if (*buffer != '\n')
388 sscanf(buffer, "%d", &fuel);
389 printf("Torps (was %d) = ", torps);
390 fgets(buffer, 10, stdin);
391 if (*buffer != '\n')
392 sscanf(buffer, "%d", &torps);
393 printf("CUMBER (was %d) = ", CUMBER);
394 fgets(buffer, 10, stdin);
395 if (*buffer != '\n')
396 sscanf(buffer, "%d", &CUMBER);
397 printf("WEIGHT (was %d) = ", WEIGHT);
398 fgets(buffer, 10, stdin);
399 if (*buffer != '\n')
400 sscanf(buffer, "%d", &WEIGHT);
401 printf("Clock (was %d) = ", ourclock);
402 fgets(buffer, 10, stdin);
403 if (*buffer != '\n')
404 sscanf(buffer, "%d", &ourclock);
405 printf("Wizard (was %d, %d) = ", wiz, tempwiz);
406 fgets(buffer, 10, stdin);
407 if (*buffer != '\n') {
408 sscanf(buffer, "%d", &junk);
409 if (!junk)
410 tempwiz = wiz = 0;
411 }
412 printf("\nDONE.\n");
413 return (0);
414 } else
415 puts("You aren't a wizard.");
416 break;
417
418 case SCORE:
419 printf("\tPLEASURE\tPOWER\t\tEGO\n");
420 printf("\t%3d\t\t%3d\t\t%3d\n\n", pleasure, power, ego);
421 printf("This gives you the rating of %s in %d turns.\n", rate(), ourtime);
422 printf("You have visited %d out of %d rooms this run (%d%%).\n", card(beenthere, NUMOFROOMS), NUMOFROOMS, card(beenthere, NUMOFROOMS) * 100 / NUMOFROOMS);
423 break;
424
425 case KNIFE:
426 case KILL:
427 murder();
428 break;
429
430 case UNDRESS:
431 case RAVAGE:
432 ravage();
433 break;
434
435 case SAVE:
436 printf("\nSave file name (default %s): ",
437 DEFAULT_SAVE_FILE);
438 filename = fgetln(stdin, &filename_len);
439 if (filename_len == 0
440 || (filename_len == 1 && filename[0] == '\n'))
441 rfilename = save_file_name(DEFAULT_SAVE_FILE,
442 strlen(DEFAULT_SAVE_FILE));
443 else {
444 if (filename[filename_len - 1] == '\n')
445 filename_len--;
446 rfilename = save_file_name(filename,
447 filename_len);
448 }
449 save(rfilename);
450 free(rfilename);
451 break;
452
453 case VERBOSE:
454 verbose = 1;
455 printf("[Maximum verbosity]\n");
456 break;
457
458 case BRIEF:
459 verbose = 0;
460 printf("[Standard verbosity]\n");
461 break;
462
463 case FOLLOW:
464 lflag = follow();
465 break;
466
467 case GIVE:
468 give();
469 break;
470
471 case KISS:
472 kiss();
473 break;
474
475 case LOVE:
476 love();
477 break;
478
479 case RIDE:
480 lflag = ride();
481 break;
482
483 case DRIVE:
484 lflag = drive();
485 break;
486
487 case LIGHT:
488 light();
489 break;
490
491 case LAUNCH:
492 if (!launch())
493 return (-1);
494 else
495 lflag = 0;
496 break;
497
498 case LANDIT:
499 if (!land())
500 return (-1);
501 else
502 lflag = 0;
503 break;
504
505 case TIME:
506 chime();
507 break;
508
509 case SLEEP:
510 zzz();
511 break;
512
513 case DIG:
514 dig();
515 break;
516
517 case JUMP:
518 lflag = jump();
519 break;
520
521 case BURY:
522 bury();
523 break;
524
525 case SWIM:
526 puts("Surf's up!");
527 break;
528
529 case DRINK:
530 drink();
531 break;
532
533 case QUIT:
534 die();
535
536 default:
537 puts("How's that?");
538 return (-1);
539 break;
540
541
542 }
543 if (wordnumber < wordcount && *words[wordnumber++] == ',')
544 continue;
545 else
546 return (lflag);
547 }
548 return (lflag);
549 }