1 /*        $NetBSD: command6.c,v 1.9 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[] = "@(#)com6.c      8.2 (Berkeley) 4/28/95";
36 #else
37 __RCSID("$NetBSD: command6.c,v 1.9 2021/05/02 12:50:43 rillig Exp $");
38 #endif
39 #endif                                  /* not lint */
40 
41 #include "extern.h"
42 #include "pathnames.h"
43 
44 static void post(int);
45 
46 int
launch(void)47 launch(void)
48 {
49           if (testbit(location[position].objects, VIPER) && !notes[CANTLAUNCH]) {
50                     if (fuel > 4) {
51                               clearbit(location[position].objects, VIPER);
52                               position = location[position].up;
53                               notes[LAUNCHED] = 1;
54                               ourtime++;
55                               fuel -= 4;
56                               printf("You climb into the viper and prepare for ");
57                               puts("launch.");
58                               printf("With a touch of your thumb the turbo engines ");
59                               printf("ignite, thrusting you back into\nyour seat.\n");
60                               return (1);
61                     } else
62                               puts("Not enough fuel to launch.");
63           } else
64                     puts("Can't launch.");
65           return (0);
66 }
67 
68 int
land(void)69 land(void)
70 {
71           if (notes[LAUNCHED] && testbit(location[position].objects, LAND) &&
72               location[position].down) {
73                     notes[LAUNCHED] = 0;
74                     position = location[position].down;
75                     setbit(location[position].objects, VIPER);
76                     fuel -= 2;
77                     ourtime++;
78                     puts("You are down.");
79                     return (1);
80           } else
81                     puts("You can't land here.");
82           return (0);
83 }
84 
85 void
die(void)86 die(void)
87 {                                       /* endgame */
88           printf("bye.\nYour rating was %s.\n", rate());
89           post(' ');
90           exit(0);
91 }
92 
93 void
diesig(int dummy __unused)94 diesig(int dummy __unused)
95 {
96           die();
97 }
98 
99 void
live(void)100 live(void)
101 {
102           puts("\nYou win!");
103           post('!');
104           exit(0);
105 }
106 
107 static FILE *score_fp;
108 
109 void
open_score_file(void)110 open_score_file(void)
111 {
112           score_fp = fopen(_PATH_SCORE, "a");
113           if (score_fp == NULL)
114                     warn("open %s for append", _PATH_SCORE);
115           if (score_fp != NULL && fileno(score_fp) < 3)
116                     exit(1);
117 }
118 
119 static void
post(int ch)120 post(int ch)
121 {
122           time_t tv;
123           sigset_t isigset, osigset;
124 
125           sigemptyset(&isigset);
126           sigaddset(&isigset, SIGINT);
127           sigprocmask(SIG_BLOCK, &isigset, &osigset);
128           tv = time(NULL);
129           if (score_fp != NULL) {
130                     fprintf(score_fp, "%24.24s  %8s  %c%20s", ctime(&tv), username,
131                         ch, rate());
132                     if (wiz)
133                               fprintf(score_fp, "   wizard\n");
134                     else
135                               if (tempwiz)
136                                         fprintf(score_fp, "   WIZARD!\n");
137                               else
138                                         fprintf(score_fp, "\n");
139           }
140           fflush(score_fp);
141           sigprocmask(SIG_SETMASK, &osigset, (sigset_t *) 0);
142 }
143 
144 const char *
rate(void)145 rate(void)
146 {
147           int     score;
148 
149           score = max(max(pleasure, power), ego);
150           if (score == pleasure) {
151                     if (score < 5)
152                               return ("novice");
153                     else if (score < 20)
154                               return ("junior voyeur");
155                     else if (score < 35)
156                               return ("Don Juan");
157                     else
158                               return ("Marquis De Sade");
159           } else if (score == power) {
160                     if (score < 5)
161                               return ("serf");
162                     else if (score < 8)
163                               return ("Samurai");
164                     else if (score < 13)
165                               return ("Klingon");
166                     else if (score < 22)
167                               return ("Darth Vader");
168                     else
169                               return ("Sauron the Great");
170           } else {
171                     if (score < 5)
172                               return ("Polyanna");
173                     else if (score < 10)
174                               return ("philanthropist");
175                     else if (score < 20)
176                               return ("Tattoo");
177                     else
178                               return ("Mr. Roarke");
179           }
180 }
181 
182 int
drive(void)183 drive(void)
184 {
185           if (testbit(location[position].objects, CAR)) {
186                     printf("You hop in the car and turn the key.  There is ");
187                     puts("a perceptible grating noise,");
188                     puts("and an explosion knocks you unconscious...");
189                     clearbit(location[position].objects, CAR);
190                     setbit(location[position].objects, CRASH);
191                     injuries[5] = injuries[6] = injuries[7] = injuries[8] = 1;
192                     ourtime += 15;
193                     zzz();
194                     return (0);
195           } else
196                     puts("There is nothing to drive here.");
197           return (-1);
198 }
199 
200 int
ride(void)201 ride(void)
202 {
203           if (testbit(location[position].objects, HORSE)) {
204                     printf("You climb onto the stallion and kick it in the guts.");
205                     puts("  The stupid steed launches");
206                     printf("forward through bush and fern.  You are thrown and ");
207                     puts("the horse gallops off.");
208                     clearbit(location[position].objects, HORSE);
209                     while (!(position = rnd(NUMOFROOMS + 1)) || !OUTSIDE ||
210                         !beenthere[position] || location[position].flyhere)
211                               continue;
212                     setbit(location[position].objects, HORSE);
213                     if (location[position].north)
214                               position = location[position].north;
215                     else if (location[position].south)
216                               position = location[position].south;
217                     else if (location[position].east)
218                               position = location[position].east;
219                     else
220                               position = location[position].west;
221                     return (0);
222           } else
223                     puts("There is no horse here.");
224           return (-1);
225 }
226 
227 void
light(void)228 light(void)
229 {                                       /* synonyms = {strike, smoke} *//* for
230                                          * matches, cigars */
231           if (testbit(inven, MATCHES) && matchcount) {
232                     puts("Your match splutters to life.");
233                     ourtime++;
234                     matchlight = 1;
235                     matchcount--;
236                     if (position == 217) {
237                               printf("The whole bungalow explodes with an ");
238                               puts("intense blast.");
239                               die();
240                     }
241           } else
242                     puts("You're out of matches.");
243 }
244 
245 void
dooropen(void)246 dooropen(void)
247 {                                       /* synonyms = {open, unlock} */
248           wordnumber++;
249           if (wordnumber <= wordcount && wordtype[wordnumber] == NOUNS
250               && wordvalue[wordnumber] == DOOR) {
251                     switch(position) {
252                     case 189:
253                     case 231:
254                               if (location[189].north == 231)
255                                         puts("The door is already open.");
256                               else
257                                         puts("The door does not budge.");
258                               break;
259                     case 30:
260                               if (location[30].west == 25)
261                                         puts("The door is gone.");
262                               else
263                                         puts("The door is locked tight.");
264                               break;
265                     case 31:
266                               puts("That's one immovable door.");
267                               break;
268                     case 20:
269                               puts("The door is already ajar.");
270                               break;
271                     default:
272                               puts("What door?");
273                     }
274           } else
275                     puts("That doesn't open.");
276 }
277