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