xref: /netbsd/games/battlestar/command5.c (revision abca1099)
1 /*	$NetBSD: command5.c,v 1.6 2021/05/02 12:50:43 rillig Exp $	*/
2 
3 /*
4  * Copyright (c) 1983, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)com5.c	8.2 (Berkeley) 4/28/95";
36 #else
37 __RCSID("$NetBSD: command5.c,v 1.6 2021/05/02 12:50:43 rillig Exp $");
38 #endif
39 #endif				/* not lint */
40 
41 #include "extern.h"
42 
43 void
kiss(void)44 kiss(void)
45 {
46 	while (wordtype[++wordnumber] != NOUNS && wordnumber <= wordcount)
47 		continue;
48 	/* The goddess must be "taken" first if bathing. */
49 	if (wordtype[wordnumber] == NOUNS && wordvalue[wordnumber] == NORMGOD
50 	    && testbit(location[position].objects, BATHGOD)) {
51 		wordvalue[--wordnumber] = TAKE;
52 		cypher();
53 		return;
54 	}
55 	if (wordtype[wordnumber] == NOUNS) {
56 		if (testbit(location[position].objects,
57 		    wordvalue[wordnumber])) {
58 			pleasure++;
59 			printf("Kissed.\n");
60 			switch (wordvalue[wordnumber]) {
61 			case NORMGOD:
62 				switch (godready++) {
63 				case 0:
64 					printf("She squirms and avoids your ");
65 					puts("advances.");
66 					break;
67 				case 1:
68 					puts("She is coming around; she ");
69 					puts("didn't fight it as much.");
70 					break;
71 				case 2:
72 					puts("She's beginning to like it.");
73 					break;
74 				default:
75 					puts("She's gone limp.");
76 
77 				}
78 				break;
79 			case NATIVE:
80 				printf("Her lips are warm and her body ");
81 				printf("robust.  She pulls you down to ");
82 				puts("the ground.");
83 				break;
84 			case TIMER:
85 				puts("The old man blushes.");
86 				break;
87 			case MAN:
88 				puts("The dwarf punches you in the kneecap.");
89 				break;
90 			default:
91 				pleasure--;
92 			}
93 		} else
94 			puts("I see nothing like that here.");
95 	} else
96 		puts("I'd prefer not to.");
97 }
98 
99 void
love(void)100 love(void)
101 {
102 	int     n;
103 
104 	while (wordtype[++wordnumber] != NOUNS && wordnumber <= wordcount)
105 		continue;
106 	if (wordtype[wordnumber] == NOUNS) {
107 		if ((testbit(location[position].objects, BATHGOD) ||
108 		    testbit(location[position].objects, NORMGOD)) &&
109 		    wordvalue[wordnumber] == NORMGOD) {
110 			if (loved) {
111 				printf("Loved.\n");
112 				return;
113 			}
114 			if (godready >= 2) {
115 				printf("She cuddles up to you, and her mouth ");
116 				printf("starts to work:\n'That was my ");
117 				printf("sister's amulet.  The lovely ");
118 				printf("goddess, Purl, was she.  The Empire\n");
119 				printf("captured her just after the Darkness ");
120 				printf("came.  My other sister, Vert, was ");
121 				printf("killed\nby the Dark Lord himself.  ");
122 				printf("He took her amulet and warped its ");
123 				printf("power.\nYour quest was foretold by ");
124 				printf("my father before he died, but to get ");
125 				printf("the Dark Lord's\namulet you must use ");
126 				printf("cunning and skill.  I will leave you ");
127 				puts("my amulet,");
128 				printf("which you may use as you wish.  As ");
129 				printf("for me, I am the last goddess of ");
130 				printf("the\nwaters.  My father was the ");
131 				printf("Island King, and the rule is ");
132 				printf("rightfully mine.'\n\nShe pulls the ");
133 				puts("throne out into a large bed.");
134 				power++;
135 				pleasure += 15;
136 				ego++;
137 				if (card(injuries, NUMOFINJURIES)) {
138 					printf("Her kisses revive you; your ");
139 					printf("wounds are healed.\n");
140 					for (n = 0; n < NUMOFINJURIES; n++)
141 						injuries[n] = 0;
142 					WEIGHT = MAXWEIGHT;
143 					CUMBER = MAXCUMBER;
144 				}
145 				printf("Goddess:\n");
146 				if (!loved)
147 					setbit(location[position].objects,
148 					    MEDALION);
149 				loved = 1;
150 				ourtime += 10;
151 				printf("Loved.\n");
152 				zzz();
153 				return;
154 			} else {
155 				puts("You wish!");
156 				return;
157 			}
158 		}
159 		if (testbit(location[position].objects,
160 		    wordvalue[wordnumber])) {
161 			if (wordvalue[wordnumber] == NATIVE) {
162 				printf("The girl is easy prey.  She peels ");
163 				puts("off her sarong and indulges you.");
164 				power++;
165 				pleasure += 5;
166 				printf("Girl:\n");
167 				ourtime += 10;
168 				printf("Loved.\n");
169 				zzz();
170 			}
171 			if (wordvalue[wordnumber] == MAN ||
172 			    wordvalue[wordnumber] == BODY ||
173 			    wordvalue[wordnumber] == ELF ||
174 			    wordvalue[wordnumber] == TIMER)
175 				puts("Kinky!");
176 			else
177 				puts("It doesn't seem to work.");
178 		} else
179 			puts("Where's your lover?");
180 	} else
181 		puts("It doesn't seem to work.");
182 }
183 
184 int
zzz(void)185 zzz(void)
186 {
187 	int     oldtime;
188 	int     n;
189 	int zzztime;
190 
191 	zzztime = (3 * CYCLE) / 4;
192 
193 	oldtime = ourtime;
194 	if ((snooze - ourtime) < zzztime) {
195 		ourtime += zzztime - (snooze - ourtime);
196 		printf("<zzz>");
197 		for (n = 0; n < ourtime - oldtime; n++)
198 			printf(".");
199 		printf("\n");
200 		snooze += 3 * (ourtime - oldtime);
201 		if (notes[LAUNCHED]) {
202 			fuel -= (ourtime - oldtime);
203 			if (location[position].down) {
204 				position = location[position].down;
205 				crash();
206 			} else
207 				notes[LAUNCHED] = 0;
208 		}
209 		if (OUTSIDE && rnd(100) < 50) {
210 			printf("You are awakened abruptly by the sound ");
211 			puts("of someone nearby.");
212 			switch (rnd(4)) {
213 			case 0:
214 				if (ucard(inven)) {
215 					n = rnd(NUMOFOBJECTS);
216 					while (!testbit(inven, n))
217 						n = rnd(NUMOFOBJECTS);
218 					clearbit(inven, n);
219 					if (n != AMULET && n != MEDALION &&
220 					    n != TALISMAN)
221 						setbit(
222 						    location[position].objects,
223 						    n);
224 					carrying -= objwt[n];
225 					encumber -= objcumber[n];
226 				}
227 				printf("A fiendish little Elf is stealing ");
228 				puts("your treasures!");
229 				fight(ELF, 10);
230 				break;
231 			case 1:
232 				setbit(location[position].objects, DEADWOOD);
233 				break;
234 			case 2:
235 				setbit(location[position].objects, HALBERD);
236 				break;
237 			default:
238 				break;
239 			}
240 		}
241 	} else
242 		return (0);
243 	return (1);
244 }
245 
246 void
chime(void)247 chime(void)
248 {
249 	if ((ourtime / CYCLE + 1) % 2 && OUTSIDE)
250 		switch ((ourtime % CYCLE) / (CYCLE / 7)) {
251 		case 0:
252 			puts("It is just after sunrise.");
253 			break;
254 		case 1:
255 			puts("It is early morning.");
256 			break;
257 		case 2:
258 			puts("It is late morning.");
259 			break;
260 		case 3:
261 			puts("It is near noon.");
262 			break;
263 		case 4:
264 			puts("It is early afternoon.");
265 			break;
266 		case 5:
267 			puts("It is late afternoon.");
268 			break;
269 		case 6:
270 			puts("It is near sunset.");
271 			break;
272 		}
273 	else if (OUTSIDE)
274 		switch ((ourtime % CYCLE) / (CYCLE / 7)) {
275 		case 0:
276 			puts("It is just after sunset.");
277 			break;
278 		case 1:
279 			puts("It is early evening.");
280 			break;
281 		case 2:
282 			puts("The evening is getting old.");
283 			break;
284 		case 3:
285 			puts("It is near midnight.");
286 			break;
287 		case 4:
288 			puts("These are the wee hours of the morning.");
289 			break;
290 		case 5:
291 			puts("The night is waning.");
292 			break;
293 		case 6:
294 			puts("It is almost morning.");
295 			break;
296 		}
297 	else
298 		puts("I can't tell the time in here.");
299 }
300 
301 int
give(void)302 give(void)
303 {
304 	int     obj = -1, result = -1, person = 0, firstnumber, last1, last2;
305 
306 	last1 = last2 = 0;
307 	firstnumber = wordnumber;
308 	while (wordtype[++wordnumber] != OBJECT &&
309 	    wordvalue[wordnumber] != AMULET &&
310 	    wordvalue[wordnumber] != MEDALION &&
311 	    wordvalue[wordnumber] != TALISMAN && wordnumber <= wordcount)
312 		continue;
313 	if (wordnumber <= wordcount) {
314 		obj = wordvalue[wordnumber];
315 		if (obj == EVERYTHING)
316 			wordtype[wordnumber] = -1;
317 		last1 = wordnumber;
318 	}
319 	wordnumber = firstnumber;
320 	while ((wordtype[++wordnumber] != NOUNS ||
321 	    wordvalue[wordnumber] == obj) && wordnumber <= wordcount);
322 	if (wordtype[wordnumber] == NOUNS) {
323 		person = wordvalue[wordnumber];
324 		last2 = wordnumber;
325 	}
326 	/* Setting wordnumber to last1 - 1 looks wrong if last1 is 0, e.g.,
327 	 * plain `give'.  However, detecting this case is liable to detect
328 	 * `give foo' as well, which would give a confusing error.  We
329 	 * need to make sure the -1 value can cause no problems if it arises.
330 	 * If in the below we get to the drop("Given") then drop will look
331 	 * at word 0 for an object to give, and fail, which is OK; then
332 	 * result will be -1 and we get to the end, where wordnumber gets
333 	 * set to something more sensible.  If we get to "I don't think
334 	 * that is possible" then again wordnumber is set to something
335 	 * sensible.  The wordnumber we leave with still isn't right if
336 	 * you include words the game doesn't know in your command, but
337 	 * that's no worse than what other commands than give do in
338 	 * the same place.  */
339 	wordnumber = last1 - 1;
340 	if (person && testbit(location[position].objects, person)) {
341 		if (person == NORMGOD && godready < 2 &&
342 		    !(obj == RING || obj == BRACELET))
343 			puts("The goddess won't look at you.");
344 		else
345 			result = drop("Given");
346 	} else {
347 		puts("I don't think that is possible.");
348 		wordnumber = max(last1, last2) + 1;
349 		return (0);
350 	}
351 	if (result != -1 && (testbit(location[position].objects, obj) ||
352 	    obj == AMULET || obj == MEDALION || obj == TALISMAN)) {
353 		clearbit(location[position].objects, obj);
354 		ourtime++;
355 		ego++;
356 		switch (person) {
357 		case NATIVE:
358 			puts("She accepts it shyly.");
359 			ego += 2;
360 			break;
361 		case NORMGOD:
362 			if (obj == RING || obj == BRACELET) {
363 				printf("She takes the charm and puts it on.");
364 				puts("  A little kiss on the cheek is");
365 				puts("your reward.");
366 				ego += 5;
367 				godready += 3;
368 			}
369 			if (obj == AMULET || obj == MEDALION ||
370 			    obj == TALISMAN) {
371 				win++;
372 				ego += 5;
373 				power -= 5;
374 				if (win >= 3) {
375 					printf("The powers of the earth are ");
376 					printf("now legitimate.  You have ");
377 					puts("destroyed the Darkness");
378 					printf("and restored the goddess to ");
379 					printf("her throne.  The entire ");
380 					puts("island celebrates with");
381 					printf("dancing and spring feasts.  ");
382 					printf("As a measure of her ");
383 					puts("gratitude, the goddess weds you");
384 					printf("in the late summer and ");
385 					printf("crowns you Prince Liverwort, ");
386 					puts("Lord of Fungus.");
387 					printf("\nBut, as the year wears on ");
388 					printf("and autumn comes along, you ");
389 					puts("become restless and");
390 					printf("yearn for adventure.  The ");
391 					printf("goddess, too, realizes that ");
392 					puts("the marriage can't last.");
393 					printf("She becomes bored and takes ");
394 					printf("several more natives as ");
395 					puts("husbands.  One evening,");
396 					printf("after having been out ");
397 					printf("drinking with the girls, she ");
398 					puts("kicks the throne particularly");
399 					printf("hard and wakes you up.  (If ");
400 					printf("you want to win this game, ");
401 					printf("you're going to have to\n");
402 					puts("shoot her!)");
403 					clearbit(location[position].objects,
404 					    MEDALION);
405 					wintime = ourtime;
406 				}
407 			}
408 			break;
409 		case TIMER:
410 			if (obj == COINS) {
411 				printf("He fingers the coins for a moment ");
412 				printf("and then looks up agape.  `Kind you ");
413 				puts("are and");
414 				printf("I mean to repay you as best I can.'  ");
415 				printf("Grabbing a pencil and cocktail ");
416 				puts("napkin...\n");
417 				printf("+-----------------------------------");
418 				printf("------------------------------------");
419 				printf("------+\n");
420 				printf("|				   xxxxxxxx\\				      |\n");
421 				printf("|				       xxxxx\\	CLIFFS			      |\n");
422 				printf("|		FOREST			  xxx\\				      |\n");
423 				printf("|				\\\\	     x\\        	OCEAN		      |\n");
424 				printf("|				||	       x\\			      |\n");
425 				printf("|				||  ROAD	x\\			      |\n");
426 				printf("|				||		x\\			      |\n");
427 				printf("|		SECRET		||	  .........			      |\n");
428 				printf("|		 - + -		||	   ........			      |\n");
429 				printf("|		ENTRANCE	||		...      BEACH		      |\n");
430 				printf("|				||		...		  E	      |\n");
431 				printf("|				||		...		  |	      |\n");
432 				printf("|				//		...	    N <-- + --- S     |\n");
433 				printf("|		PALM GROVE     //		...		  |	      |\n");
434 				printf("|			      //		...		  W	      |\n");
435 				printf("+");
436 				printf("---------------------------------");
437 				printf("---------------------------------");
438 				printf("-----------+\n");
439 				printf("\n`This map shows a secret entrance ");
440 				puts("to the catacombs.");
441 				printf("You will know when you arrive ");
442 				printf("because I left an old pair of shoes ");
443 				puts("there.'");
444 			}
445 			break;
446 		}
447 	}
448 	wordnumber = max(last1, last2) + 1;
449 	return (firstnumber);
450 }
451