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