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