xref: /dragonfly/games/battlestar/command4.c (revision 4318c66eac379e15105fe145d406dfef81b795f6)
1 /*        @(#)com4.c          8.2 (Berkeley) 4/28/95                            */
2 /*        $NetBSD: command4.c,v 1.3 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
take(unsigned int from[])36 take(unsigned int from[])
37 {
38           int     firstnumber, heavy, bulky, value;
39 
40           firstnumber = wordnumber;
41           if (wordnumber < wordcount && wordvalue[wordnumber + 1] == OFF) {
42                     wordnumber++;
43                     wordvalue[wordnumber] = TAKEOFF;
44                     wordtype[wordnumber] = VERB;
45                     return (cypher());
46           } else {
47                     wordnumber++;
48                     while (wordnumber <= wordcount && wordtype[wordnumber] ==
49                         OBJECT) {
50                               value = wordvalue[wordnumber];
51                               printf("%s:\n", objsht[value]);
52                               heavy = (carrying + objwt[value]) <= WEIGHT;
53                               bulky = (encumber + objcumber[value]) <= CUMBER;
54                               if ((testbit(from, value) || wiz || tempwiz) &&
55                                   heavy && bulky && !testbit(inven, value)) {
56                                         setbit(inven, value);
57                                         carrying += objwt[value];
58                                         encumber += objcumber[value];
59                                         ourtime++;
60                                         if (testbit(from, value))
61                                                   printf("Taken.\n");
62                                         else
63                                                   printf("Zap! Taken from thin air.\n");
64                                         clearbit(from, value);
65                                         if (value == MEDALION)
66                                                   win--;
67                               } else if (testbit(inven, value))
68                                         printf("You're already holding %s%s.\n",
69                                             A_OR_AN_OR_BLANK(value),
70                                             objsht[value]);
71                               else if (!testbit(from, value))
72                                         printf("I don't see any %s around here.\n",
73                                             objsht[value]);
74                               else if (!heavy)
75                                         printf("The %s %stoo heavy.\n", objsht[value],
76                                             IS_OR_ARE(value));
77                               else
78                                         printf("The %s %stoo cumbersome to hold.\n",
79                                             objsht[value], IS_OR_ARE(value));
80                               if (wordnumber < wordcount - 1 &&
81                                   wordvalue[++wordnumber] == AND)
82                                         wordnumber++;
83                               else
84                                         return (firstnumber);
85                     }
86           }
87           /* special cases with their own return()'s */
88 
89           if (wordnumber <= wordcount && wordtype[wordnumber] == NOUNS)
90                     switch (wordvalue[wordnumber]) {
91 
92                     case SWORD:
93                               if (testbit(from, SWORD)) {
94                                         wordtype[wordnumber--] = OBJECT;
95                                         return (take(from));
96                               }
97                               if (testbit(from, TWO_HANDED)) {
98                                         wordvalue[wordnumber] = TWO_HANDED;
99                                         wordtype[wordnumber--] = OBJECT;
100                                         return (take(from));
101                               }
102                               wordvalue[wordnumber] = BROAD;
103                               wordtype[wordnumber--] = OBJECT;
104                               return (take(from));
105 
106                     case BODY:
107                               if (testbit(from, MAID)) {
108                                         wordvalue[wordnumber] = MAID;
109                                         wordtype[wordnumber--] = OBJECT;
110                                         return (take(from));
111                               } else if (testbit(from, DEADWOOD)) {
112                                         wordvalue[wordnumber] = DEADWOOD;
113                                         wordtype[wordnumber--] = OBJECT;
114                                         return (take(from));
115                               } else if (testbit(from, DEADNATIVE)) {
116                                         wordvalue[wordnumber] = DEADNATIVE;
117                                         wordtype[wordnumber--] = OBJECT;
118                                         return (take(from));
119                               } else {
120                                         if (testbit(from, DEADGOD)) {
121                                                   wordvalue[wordnumber] = DEADGOD;
122                                                   wordtype[wordnumber--] = OBJECT;
123                                                   return (take(from));
124                                         } else {
125                                                   wordvalue[wordnumber] = DEADTIME;
126                                                   wordtype[wordnumber--] = OBJECT;
127                                                   return (take(from));
128                                         }
129                               }
130                               break;
131 
132                     case AMULET:
133                               if (testbit(location[position].objects, AMULET)) {
134                                         printf("The amulet is warm to the touch, and ");
135                                         puts("its beauty catches your breath.");
136                                         printf("A mist falls over your eyes, but ");
137                                         puts("then it is gone.  Sounds seem clearer");
138                                         printf("and sharper but far away as if in a ");
139                                         puts("dream.  The sound of purling water");
140                                         printf("reaches you from afar.  The mist ");
141                                         printf("falls again, and your heart leaps in ");
142                                         puts("horror.");
143                                         printf("The gold freezes your hands and ");
144                                         puts("fathomless darkness engulfs your soul.");
145                               }
146                               wordtype[wordnumber--] = OBJECT;
147                               return (take(from));
148 
149                     case MEDALION:
150                               if (testbit(location[position].objects, MEDALION)) {
151                                         printf("The medallion is warm, and it ");
152                                         printf("rekindles your spirit with the ");
153                                         puts("warmth of life.");
154                                         printf("Your amulet begins to glow as the ");
155                                         printf("medallion is brought near to it, ");
156                                         printf("and together\nthey radiate.\n");
157                               }
158                               wordtype[wordnumber--] = OBJECT;
159                               return (take(from));
160 
161                     case TALISMAN:
162                               if (testbit(location[position].objects, TALISMAN)) {
163                                         printf("The talisman is cold to the touch, ");
164                                         puts("and it sends a chill down your spine.");
165                               }
166                               wordtype[wordnumber--] = OBJECT;
167                               return (take(from));
168 
169                     case NORMGOD:
170                               if (testbit(location[position].objects, BATHGOD) &&
171                                   (testbit(wear, AMULET) || testbit(inven, AMULET))) {
172                                         printf("She offers a delicate hand, and you ");
173                                         puts("help her out of the sparkling springs.");
174                                         printf("Water droplets like liquid silver ");
175                                         printf("bedew her golden skin, but when ");
176                                         puts("they part");
177                                         printf("from her, they fall as teardrops.  ");
178                                         puts("She wraps a single cloth around her and");
179                                         printf("ties it at the waist.  Around her ");
180                                         puts("neck hangs a golden amulet.");
181                                         printf("She bids you to follow her, and ");
182                                         puts("walks away.");
183                                         pleasure++;
184                                         followgod = ourtime;
185                                         clearbit(location[position].objects, BATHGOD);
186                               } else
187                                         if (!testbit(location[position].objects,
188                                             BATHGOD)) {
189                                                   printf("You're in no position to ");
190                                                   puts("take her.");
191                                         } else
192                                                   puts("She moves away from you.");
193                               break;
194 
195                     default:
196                               puts("It doesn't seem to work.");
197                     }
198           else
199                     puts("You've got to be kidding.");
200           return (firstnumber);
201 }
202 
203 int
throw(const char * name)204 throw(const char *name)
205 {
206           unsigned int     n;
207           int     deposit = 0;
208           int     first, value;
209 
210           first = wordnumber;
211           if (drop(name) != -1) {
212                     switch (wordvalue[wordnumber]) {
213 
214                     case AHEAD:
215                               deposit = ahead;
216                               break;
217 
218                     case BACK:
219                               deposit = back;
220                               break;
221 
222                     case LEFT:
223                               deposit = left;
224                               break;
225 
226                     case RIGHT:
227                               deposit = right;
228                               break;
229 
230                     case UP:
231                               deposit = location[position].up *
232                                   (location[position].access || position == FINAL);
233                               break;
234 
235                     case DOWN:
236                               deposit = location[position].down;
237                               break;
238                     }
239                     wordnumber = first + 1;
240                     while (wordnumber <= wordcount) {
241                               value = wordvalue[wordnumber];
242                               if (deposit &&
243                                   testbit(location[position].objects, value)) {
244                                         clearbit(location[position].objects, value);
245                                         if (value != GRENADE)
246                                                   setbit(location[deposit].objects,
247                                                       value);
248                                         else {
249                                                   printf("A thundering explosion ");
250                                                   printf("nearby sends up a cloud of ");
251                                                   puts("smoke and shrapnel.");
252                                                   for (n = 0; n < NUMOFWORDS; n++)
253                                                             location[deposit].objects[n] =
254                                                                 0;
255                                                   setbit(location[deposit].objects, CHAR);
256                                         }
257                                         if (value == ROPE && position == FINAL)
258                                                   location[position].access = 1;
259                                         switch (deposit) {
260                                         case 189:
261                                         case 231:
262                                                   puts("The stone door is unhinged.");
263                                                   location[189].north = 231;
264                                                   location[231].south = 189;
265                                                   break;
266                                         case 30:
267                                                   puts("The wooden door is blown open.");
268                                                   location[30].west = 25;
269                                                   break;
270                                         case 31:
271                                                   puts("The door is not damaged.");
272                                         }
273                               } else
274                                         if (value == GRENADE &&
275                                             testbit(location[position].objects,
276                                             value)) {
277                                                   printf("You are blown into shreds ");
278                                                   puts("when your grenade explodes.");
279                                                   die();
280                                         }
281                               if (wordnumber < wordcount - 1 &&
282                                   wordvalue[++wordnumber] == AND)
283                                         wordnumber++;
284                               else
285                                         return (first);
286                     }
287                     return (first);
288           }
289           return (first);
290 }
291 
292 int
drop(const char * name)293 drop(const char *name)
294 {
295 
296           int     firstnumber, value;
297 
298           firstnumber = wordnumber;
299           wordnumber++;
300           while (wordnumber <= wordcount &&
301               (wordtype[wordnumber] == OBJECT || wordtype[wordnumber] == NOUNS)) {
302                     value = wordvalue[wordnumber];
303                     if (value == BODY) {          /* special case */
304                               wordtype[wordnumber] = OBJECT;
305                               if (testbit(inven, MAID) ||
306                                   testbit(location[position].objects, MAID))
307                                         value = MAID;
308                               else if (testbit(inven, DEADWOOD) ||
309                                   testbit(location[position].objects, DEADWOOD))
310                                         value = DEADWOOD;
311                               else if (testbit(inven, DEADGOD) ||
312                                   testbit(location[position].objects, DEADGOD))
313                                         value = DEADGOD;
314                               else if (testbit(inven, DEADTIME) ||
315                                   testbit(location[position].objects, DEADTIME))
316                                         value = DEADTIME;
317                               else if (testbit(inven, DEADNATIVE) ||
318                                   testbit(location[position].objects, DEADNATIVE))
319                                         value = DEADNATIVE;
320                     }
321                     if (wordtype[wordnumber] == NOUNS && value == DOOR) {
322                               if (*name == 'K')
323                                         puts("You hurt your foot.");
324                               else
325                                         puts("You're not holding a door.");
326                     } else if (objsht[value] == NULL) {
327                               if (*name == 'K')
328                                         puts("That's not for kicking!");
329                               else
330                                         puts("You don't have that.");
331                     } else {
332                               printf("%s:\n", objsht[value]);
333                               if (testbit(inven, value)) {
334                                         clearbit(inven, value);
335                                         carrying -= objwt[value];
336                                         encumber -= objcumber[value];
337                                         if (value == BOMB) {
338                                                   printf("The bomb explodes.  A ");
339                                                   printf("blinding white light and ");
340                                                   printf("immense concussion ");
341                                                   puts("obliterate us.");
342                                                   die();
343                                         }
344                                         if (value != AMULET && value != MEDALION &&
345                                             value != TALISMAN)
346                                                   setbit(location[position].objects,
347                                                       value);
348                                         else
349                                                   tempwiz = 0;
350                                         ourtime++;
351                                         if (*name == 'K')
352                                                   puts("Drop kicked.");
353                                         else
354                                                   printf("%s.\n", name);
355                               } else {
356                                         if (*name != 'K') {
357                                                   printf("You aren't holding the %s.\n",
358                                                       objsht[value]);
359                                                   if (testbit(location[position].objects,
360                                                       value)) {
361                                                             if (*name == 'T')
362                                                                       puts("Kicked instead.");
363                                                             else if (*name == 'G')
364                                                                       puts("Given anyway.");
365                                                   }
366                                         } else if (testbit(location[position].objects,
367                                             value))
368                                                   puts("Kicked.");
369                                         else if (testbit(wear, value))
370                                                   puts("Not while it's being worn.");
371                                         else
372                                                   puts("Not found.");
373                               }
374                     }
375                     if (wordnumber < wordcount - 1 &&
376                         wordvalue[++wordnumber] == AND)
377                               wordnumber++;
378                     else
379                               return (firstnumber);
380           }
381           puts("Do what?");
382           return (-1);
383 }
384 
385 int
takeoff(void)386 takeoff(void)
387 {
388           wordnumber = take(wear);
389           return (drop("Dropped"));
390 }
391 
392 int
puton(void)393 puton(void)
394 {
395           wordnumber = take(location[position].objects);
396           return (wearit());
397 }
398 
399 int
eat(void)400 eat(void)
401 {
402           int     firstnumber, value;
403 
404           firstnumber = wordnumber;
405           wordnumber++;
406           while (wordnumber <= wordcount) {
407                     value = wordvalue[wordnumber];
408                     if (wordtype[wordnumber] != OBJECT || objsht[value] == NULL)
409                               value = -2;
410                     switch (value) {
411 
412                     case -2:
413                               puts("You can't eat that!");
414                               return (firstnumber);
415 
416                     case -1:
417                               puts("Eat what?");
418                               return (firstnumber);
419 
420                     default:
421                               printf("You can't eat %s%s!\n",
422                                   A_OR_AN_OR_BLANK(value), objsht[value]);
423                               return (firstnumber);
424 
425                     case PAPAYAS:
426                     case PINEAPPLE:
427                     case KIWI:
428                     case COCONUTS:      /* eatable things */
429                     case MANGO:
430 
431                               printf("%s:\n", objsht[value]);
432                               if (testbit(inven, value) &&
433                                   ourtime > ate - CYCLE &&
434                                   testbit(inven, KNIFE)) {
435                                         clearbit(inven, value);
436                                         carrying -= objwt[value];
437                                         encumber -= objcumber[value];
438                                         ate = max(ourtime, ate) + CYCLE / 3;
439                                         snooze += CYCLE / 10;
440                                         ourtime++;
441                                         printf("Eaten.  You can explore a little ");
442                                         puts("longer now.");
443                               } else if (!testbit(inven, value)) {
444                                         printf("You aren't holding the %s.\n",
445                                             objsht[value]);
446                               } else if (!testbit(inven, KNIFE))
447                                         puts("You need a knife.");
448                               else
449                                         puts("You're stuffed.");
450                               if (wordnumber < wordcount - 1 &&
451                                   wordvalue[++wordnumber] == AND)
452                                         wordnumber++;
453                               else
454                                         return (firstnumber);
455                     }                   /* end switch */
456           }                             /* end while */
457           return (firstnumber);
458 }
459