mail(1) & battlestar(6): Rename some files.
[dragonfly.git] / games / battlestar / command4.c
1 /*-
2  * Copyright (c) 1983, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * @(#)com4.c   8.1 (Berkeley) 5/31/93
30  * $FreeBSD: src/games/battlestar/com4.c,v 1.8.2.1 2001/03/05 11:45:35 kris Exp $
31  * $DragonFly: src/games/battlestar/com4.c,v 1.3 2006/08/08 16:47:20 pavalos Exp $
32  */
33
34 #include "externs.h"
35
36 int
37 take(unsigned int from[])
38 {
39         int firstnumber, heavy, bulky, value;
40         int n;
41
42         firstnumber = wordnumber;
43         if (wordnumber < wordcount && wordvalue[wordnumber + 1] == OFF) {
44                 wordnumber++;
45                 wordvalue[wordnumber] = TAKEOFF;
46                 return (cypher());
47         } else {
48                 while (wordtype[++wordnumber] == ADJS)
49                         ; /* nothing */
50                 while (wordnumber <= wordcount && wordtype[wordnumber] ==
51                        OBJECT) {
52                         value = wordvalue[wordnumber];
53                         printf("%s:\n", objsht[value]);
54                         for (n = 0; objsht[value][n]; n++)
55                                 ; /* nothing */
56                         heavy = (carrying + objwt[value]) <= WEIGHT;
57                         bulky = (encumber + objcumber[value]) <= CUMBER;
58                         if ((testbit(from, value) || wiz || tempwiz) &&
59                             heavy && bulky && !testbit(inven, value)) {
60                                 setbit(inven, value);
61                                 carrying += objwt[value];
62                                 encumber += objcumber[value];
63                                 gtime++;
64                                 if (testbit(from, value))
65                                         printf("Taken.\n");
66                                 else
67                                         printf("Zap! Taken from thin air.\n");
68                                 clearbit(from, value);
69                                 if (value == MEDALION)
70                                         bs_win--;
71                         } else if (testbit(inven, value))
72                                 printf("You're already holding%s%s.\n",
73                                         (objsht[value][n - 1] ==
74                                          's' ? " " : " a "),
75                                         objsht[value]);
76                         else if (!heavy)
77                                 printf("The %s %s too heavy.\n", objsht[value],
78                                        (objsht[value][n - 1] ==
79                                         's' ? "are" : "is"));
80                         else if (!bulky)
81                                 printf(
82                                         "The %s %s too cumbersome to hold.\n",
83                                         objsht[value],
84                                         (objsht[value][n - 1] ==
85                                          's' ? "are" : "is"));
86                         else
87                                 printf("I dont see any %s around here.\n",
88                                        objsht[value]);
89                         if (wordnumber < wordcount - 1 &&
90                             wordvalue[++wordnumber] == AND)
91                                 wordnumber++;
92                         else
93                                 return (firstnumber);
94                 }
95         }
96         /* special cases with their own return()'s */
97         if (wordnumber <= wordcount && wordtype[wordnumber] == NOUNS)
98                 switch (wordvalue[wordnumber]) {
99                 case SWORD:
100                         if (testbit(from, SWORD)) {
101                                 wordtype[wordnumber--] = OBJECT;
102                                 return (take(from));
103                         }
104                         if (testbit(from, TWO_HANDED)) {
105                                 wordvalue[wordnumber] = TWO_HANDED;
106                                 wordtype[wordnumber--] = OBJECT;
107                                 return (take(from));
108                         }
109                         wordvalue[wordnumber] = BROAD;
110                         wordtype[wordnumber--] = OBJECT;
111                         return (take(from));
112
113                 case BODY:
114                         if (testbit(from, MAID)) {
115                                 wordvalue[wordnumber] = MAID;
116                                 wordtype[wordnumber--] = OBJECT;
117                                 return (take(from));
118                         } else if (testbit(from, DEADWOOD)) {
119                                 wordvalue[wordnumber] = DEADWOOD;
120                                 wordtype[wordnumber--] = OBJECT;
121                                 return (take(from));
122                         } else if (testbit(from, DEADNATIVE)) {
123                                 wordvalue[wordnumber] = DEADNATIVE;
124                                 wordtype[wordnumber--] = OBJECT;
125                                 return (take(from));
126                         } else {
127                                 if (testbit(from, DEADGOD)) {
128                                         wordvalue[wordnumber] = DEADGOD;
129                                         wordtype[wordnumber--] = OBJECT;
130                                         return (take(from));
131                                 } else {
132                                         wordvalue[wordnumber] = DEADTIME;
133                                         wordtype[wordnumber--] = OBJECT;
134                                         return (take(from));
135                                 }
136                         }
137                         break;
138
139                 case AMULET:
140                         if (testbit(location[position].objects, AMULET)) {
141                                 puts("The amulet is warm to the touch, and its beauty catches your breath.");
142                                 puts("A mist falls over your eyes, but then it is gone.  Sounds seem clearer");
143                                 puts("and sharper but far away as if in a dream.  The sound of purling water reaches");
144                                 puts("you from afar.  The mist falls again, and your heart leaps in horror.  The gold");
145                                 puts("freezes your hands and fathomless darkness engulfs your soul.");
146                         }
147                         wordtype[wordnumber--] = OBJECT;
148                         return (take(from));
149
150                 case MEDALION:
151                         if (testbit(location[position].objects, MEDALION)) {
152                                 puts("The medallion is warm, and it rekindles your spirit with the warmth of life.");
153                                 puts("Your amulet begins to glow as the medallion is brought near to it, and together\nthey radiate.");
154                         }
155                         wordtype[wordnumber--] = OBJECT;
156                         return (take(from));
157
158                 case TALISMAN:
159                         if (testbit(location[position].objects, TALISMAN))
160                                 puts("The talisman is cold to the touch, and it sends a chill down your spine.");
161                         wordtype[wordnumber--] = OBJECT;
162                         return (take(from));
163
164                 case NORMGOD:
165                         if (testbit(location[position].objects, BATHGOD) &&
166                             (testbit(wear, AMULET) || testbit(inven, AMULET))) {
167                                 puts("She offers a delicate hand, and you help her out of the sparkling springs.");
168                                 puts("Water droplets like liquid silver bedew her golden skin, but when they part");
169                                 puts("from her, they fall as teardrops.  She wraps a single cloth around her and");
170                                 puts("ties it at the waist.  Around her neck hangs a golden amulet.");
171                                 puts("She bids you to follow her.");
172                                 pleasure++;
173                                 followgod = gtime;
174                                 clearbit(location[position].objects, BATHGOD);
175                         } else
176                                 if (!testbit(location[position].objects, BATHGOD))
177                                         puts("You're in no position to take her.");
178                                 else
179                                         puts("She moves away from you.");
180                         break;
181
182                 default:
183                         puts("It doesn't seem to work.");
184                 }
185         else
186                 puts("You've got to be kidding.");
187         return (firstnumber);
188 }
189
190 int
191 throw(const char *name)
192 {
193         int n, deposit;
194         int first, value;
195
196         deposit = 0;
197         first = wordnumber;
198         if (drop(name) != -1) {
199                 switch (wordvalue[wordnumber]) {
200                 case AHEAD:
201                         deposit = ahead;
202                         break;
203
204                 case BACK:
205                         deposit = back;
206                         break;
207
208                 case LEFT:
209                         deposit = left;
210                         break;
211
212                 case RIGHT:
213                         deposit = right;
214                         break;
215
216                 case UP:
217                         deposit = location[position].up *
218                             (location[position].access || position == FINAL);
219                         break;
220
221                 case DOWN:
222                         deposit = location[position].down;
223                         break;
224                 }
225                 wordnumber = first;
226                 while (wordtype[++wordnumber] == ADJS)
227                         ; /* nothing */
228                 while (wordnumber <= wordcount) {
229                         value = wordvalue[wordnumber];
230                         if (deposit &&
231                             testbit(location[position].objects, value)) {
232                                 clearbit(location[position].objects, value);
233                                 if (value != GRENADE)
234                                         setbit(location[deposit].objects, value);
235                                 else {
236                                         puts("A thundering explosion nearby sends up a cloud of smoke and shrapnel.");
237                                         for (n = 0; n < NUMOFWORDS; n++)
238                                                 location[deposit].objects[n] = 0;
239                                         setbit(location[deposit].objects, CHAR);
240                                 }
241                                 if (value == ROPE && position == FINAL)
242                                         location[position].access = 1;
243                                 switch (deposit) {
244                                 case 189:
245                                 case 231:
246                                         puts("The stone door is unhinged.");
247                                         location[189].north = 231;
248                                         location[231].south = 189;
249                                         break;
250                                 case 30:
251                                         puts("The wooden door is blown open.");
252                                         location[30].west = 25;
253                                         break;
254                                 case 31:
255                                         puts("The door is not damaged.");
256                                 }
257                         } else
258                                 if (value == GRENADE &&
259                                     testbit(location[position].objects, value)) {
260                                         puts("You are blown into shreds when your grenade explodes.");
261                                         die(0);
262                                 }
263                         if (wordnumber < wordcount - 1 &&
264                             wordvalue[++wordnumber] == AND)
265                                 wordnumber++;
266                         else
267                                 return (first);
268                 }
269                 return (first);
270         }
271         return (first);
272 }
273
274 int
275 drop(const char *name)
276 {
277         int firstnumber, value;
278
279         firstnumber = wordnumber;
280         while (wordtype[++wordnumber] == ADJS)
281                 ;
282         while (wordnumber <= wordcount &&
283                (wordtype[wordnumber] == OBJECT || wordtype[wordnumber] == NOUNS)) {
284                 value = wordvalue[wordnumber];
285                 printf("%s:\n", objsht[value]);
286                 if (testbit(inven, value)) {
287                         clearbit(inven, value);
288                         carrying -= objwt[value];
289                         encumber -= objcumber[value];
290                         if (value == BOMB) {
291                                 puts("The bomb explodes.  A blinding white light and immense concussion obliterate us.");
292                                 die(0);
293                         }
294                         if (value != AMULET && value != MEDALION && value !=
295                             TALISMAN)
296                                 setbit(location[position].objects, value);
297                         else
298                                 tempwiz = 0;
299                         gtime++;
300                         if (*name == 'K')
301                                 puts("Drop kicked.");
302                         else
303                                 printf("%s.\n", name);
304                 } else {
305                         if (*name != 'K') {
306                                 printf("You aren't holding the %s.\n",
307                                        objsht[value]);
308                                 if (testbit(location[position].objects,
309                                             value)) {
310                                         if (*name == 'T')
311                                                 puts("Kicked instead.");
312                                         else if (*name == 'G')
313                                                 puts("Given anyway.");
314                                 }
315                         } else
316                                 puts("Kicked.");
317                 }
318                 if (wordnumber < wordcount - 1 &&
319                     wordvalue[++wordnumber] == AND)
320                         wordnumber++;
321                 else
322                         return (firstnumber);
323         }
324         puts("Do what?");
325         return (-1);
326 }
327
328 int
329 takeoff(void)
330 {
331         wordnumber = take(wear);
332         return (drop("Dropped"));
333 }
334
335 int
336 puton(void)
337 {
338         wordnumber = take(location[position].objects);
339         return (wearit());
340 }
341
342 int
343 eat(void)
344 {
345         int firstnumber, value;
346
347         firstnumber = wordnumber;
348         while (wordtype[++wordnumber] == ADJS)
349                 ; /* nothing */
350         while (wordnumber <= wordcount) {
351                 value = wordvalue[wordnumber];
352                 switch (value) {
353                 case -1:
354                         puts("Eat what?");
355                         return (firstnumber);
356
357                 default:
358                         printf("You can't eat%s%s!\n",
359                             wordtype[wordnumber] == OBJECT &&
360                                objsht[value]
361                                [strlen(objsht[value]) - 1] == 's' ?
362                                " " : " a ",
363                                words[wordnumber]);
364                         return (firstnumber);
365
366                 case PAPAYAS:
367                 case PINEAPPLE:
368                 case KIWI:
369                 case COCONUTS:  /* eatable things */
370                 case MANGO:
371
372                         printf("%s:\n", objsht[value]);
373                         if (testbit(inven, value) &&
374                             gtime > ate - CYCLE &&
375                             testbit(inven, KNIFE)) {
376                                 clearbit(inven, value);
377                                 carrying -= objwt[value];
378                                 encumber -= objcumber[value];
379                                 ate = max(gtime, ate) + CYCLE / 3;
380                                 snooze += CYCLE / 10;
381                                 gtime++;
382                                 puts("Eaten.  You can explore a little longer now.");
383                         } else if (gtime < ate - CYCLE)
384                                 puts("You're stuffed.");
385                         else if (!testbit(inven, KNIFE))
386                                 puts("You need a knife.");
387                         else
388                                 printf("You aren't holding the %s.\n",
389                                        objsht[value]);
390                         if (wordnumber < wordcount - 1 &&
391                             wordvalue[++wordnumber] == AND)
392                                 wordnumber++;
393                         else
394                                 return (firstnumber);
395                 }               /* end switch */
396         }                       /* end while */
397         return (firstnumber);
398 }