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