nrelease - fix/improve livecd
[dragonfly.git] / games / battlestar / cypher.c
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 }