xref: /dragonfly/games/battlestar/command4.c (revision 91dc43dd)
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 }
399