1*166ddc28Sdaniel /* $OpenBSD: command6.c,v 1.1 2020/12/15 00:38:18 daniel Exp $ */
2*166ddc28Sdaniel /* $NetBSD: com6.c,v 1.5 1995/04/27 21:30:23 mycroft Exp $ */
3*166ddc28Sdaniel
4*166ddc28Sdaniel /*
5*166ddc28Sdaniel * Copyright (c) 1983, 1993
6*166ddc28Sdaniel * The Regents of the University of California. All rights reserved.
7*166ddc28Sdaniel *
8*166ddc28Sdaniel * Redistribution and use in source and binary forms, with or without
9*166ddc28Sdaniel * modification, are permitted provided that the following conditions
10*166ddc28Sdaniel * are met:
11*166ddc28Sdaniel * 1. Redistributions of source code must retain the above copyright
12*166ddc28Sdaniel * notice, this list of conditions and the following disclaimer.
13*166ddc28Sdaniel * 2. Redistributions in binary form must reproduce the above copyright
14*166ddc28Sdaniel * notice, this list of conditions and the following disclaimer in the
15*166ddc28Sdaniel * documentation and/or other materials provided with the distribution.
16*166ddc28Sdaniel * 3. Neither the name of the University nor the names of its contributors
17*166ddc28Sdaniel * may be used to endorse or promote products derived from this software
18*166ddc28Sdaniel * without specific prior written permission.
19*166ddc28Sdaniel *
20*166ddc28Sdaniel * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21*166ddc28Sdaniel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22*166ddc28Sdaniel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23*166ddc28Sdaniel * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24*166ddc28Sdaniel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25*166ddc28Sdaniel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26*166ddc28Sdaniel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*166ddc28Sdaniel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28*166ddc28Sdaniel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29*166ddc28Sdaniel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30*166ddc28Sdaniel * SUCH DAMAGE.
31*166ddc28Sdaniel */
32*166ddc28Sdaniel
33*166ddc28Sdaniel #include <err.h>
34*166ddc28Sdaniel #include <errno.h>
35*166ddc28Sdaniel #include <limits.h>
36*166ddc28Sdaniel #include <signal.h>
37*166ddc28Sdaniel #include <stdio.h>
38*166ddc28Sdaniel #include <stdlib.h>
39*166ddc28Sdaniel #include <time.h>
40*166ddc28Sdaniel
41*166ddc28Sdaniel #include "extern.h"
42*166ddc28Sdaniel
43*166ddc28Sdaniel int
launch(void)44*166ddc28Sdaniel launch(void)
45*166ddc28Sdaniel {
46*166ddc28Sdaniel if (TestBit(location[position].objects, VIPER) && !notes[CANTLAUNCH]) {
47*166ddc28Sdaniel if (fuel > 4) {
48*166ddc28Sdaniel ClearBit(location[position].objects, VIPER);
49*166ddc28Sdaniel position = location[position].up;
50*166ddc28Sdaniel notes[LAUNCHED] = 1;
51*166ddc28Sdaniel ourtime++;
52*166ddc28Sdaniel fuel -= 4;
53*166ddc28Sdaniel puts("You climb into the viper and prepare for launch.");
54*166ddc28Sdaniel puts("With a touch of your thumb the turbo engines ignite, thrusting you back into\nyour seat.");
55*166ddc28Sdaniel return (1);
56*166ddc28Sdaniel } else
57*166ddc28Sdaniel puts("Not enough fuel to launch.");
58*166ddc28Sdaniel } else
59*166ddc28Sdaniel puts("Can't launch.");
60*166ddc28Sdaniel return (0);
61*166ddc28Sdaniel }
62*166ddc28Sdaniel
63*166ddc28Sdaniel int
land(void)64*166ddc28Sdaniel land(void)
65*166ddc28Sdaniel {
66*166ddc28Sdaniel if (notes[LAUNCHED] && TestBit(location[position].objects, LAND) &&
67*166ddc28Sdaniel location[position].down) {
68*166ddc28Sdaniel notes[LAUNCHED] = 0;
69*166ddc28Sdaniel position = location[position].down;
70*166ddc28Sdaniel SetBit(location[position].objects, VIPER);
71*166ddc28Sdaniel fuel -= 2;
72*166ddc28Sdaniel ourtime++;
73*166ddc28Sdaniel puts("You are down.");
74*166ddc28Sdaniel return (1);
75*166ddc28Sdaniel } else
76*166ddc28Sdaniel puts("You can't land here.");
77*166ddc28Sdaniel return (0);
78*166ddc28Sdaniel }
79*166ddc28Sdaniel
80*166ddc28Sdaniel /* endgame */
81*166ddc28Sdaniel void
die(int sigraised)82*166ddc28Sdaniel die(int sigraised)
83*166ddc28Sdaniel {
84*166ddc28Sdaniel printf("bye.\nYour rating was %s.\n", rate());
85*166ddc28Sdaniel post(' ');
86*166ddc28Sdaniel exit(0);
87*166ddc28Sdaniel }
88*166ddc28Sdaniel
89*166ddc28Sdaniel void
live(void)90*166ddc28Sdaniel live(void)
91*166ddc28Sdaniel {
92*166ddc28Sdaniel puts("\nYou win!");
93*166ddc28Sdaniel post('!');
94*166ddc28Sdaniel exit(0);
95*166ddc28Sdaniel }
96*166ddc28Sdaniel
97*166ddc28Sdaniel static FILE *score_fp;
98*166ddc28Sdaniel
99*166ddc28Sdaniel void
open_score_file(void)100*166ddc28Sdaniel open_score_file(void)
101*166ddc28Sdaniel {
102*166ddc28Sdaniel char scorefile[PATH_MAX];
103*166ddc28Sdaniel const char *home;
104*166ddc28Sdaniel int ret;
105*166ddc28Sdaniel
106*166ddc28Sdaniel home = getenv("HOME");
107*166ddc28Sdaniel if (home == NULL || *home == '\0')
108*166ddc28Sdaniel err(1, "getenv");
109*166ddc28Sdaniel ret = snprintf(scorefile, sizeof(scorefile), "%s/%s", home,
110*166ddc28Sdaniel ".battlestar.scores");
111*166ddc28Sdaniel if (ret < 0 || ret >= PATH_MAX)
112*166ddc28Sdaniel errc(1, ENAMETOOLONG, "%s/%s", home, ".battlestar.scores");
113*166ddc28Sdaniel if ((score_fp = fopen(scorefile, "a")) == NULL)
114*166ddc28Sdaniel warn("can't append to high scores file (%s)", scorefile);
115*166ddc28Sdaniel }
116*166ddc28Sdaniel
117*166ddc28Sdaniel void
post(char ch)118*166ddc28Sdaniel post(char ch)
119*166ddc28Sdaniel {
120*166ddc28Sdaniel time_t tv;
121*166ddc28Sdaniel char *date;
122*166ddc28Sdaniel sigset_t sigset, osigset;
123*166ddc28Sdaniel
124*166ddc28Sdaniel sigemptyset(&sigset);
125*166ddc28Sdaniel sigaddset(&sigset, SIGINT);
126*166ddc28Sdaniel sigprocmask(SIG_BLOCK, &sigset, &osigset);
127*166ddc28Sdaniel tv = time(NULL);
128*166ddc28Sdaniel date = ctime(&tv);
129*166ddc28Sdaniel date[24] = '\0';
130*166ddc28Sdaniel
131*166ddc28Sdaniel if (score_fp != NULL) {
132*166ddc28Sdaniel fprintf(score_fp, "%s %31s %c%20s", date, username, ch, rate());
133*166ddc28Sdaniel if (tempwiz)
134*166ddc28Sdaniel fprintf(score_fp, " WIZARD!\n");
135*166ddc28Sdaniel else
136*166ddc28Sdaniel fprintf(score_fp, "\n");
137*166ddc28Sdaniel }
138*166ddc28Sdaniel sigprocmask(SIG_SETMASK, &osigset, (sigset_t *)0);
139*166ddc28Sdaniel }
140*166ddc28Sdaniel
141*166ddc28Sdaniel const char *
rate(void)142*166ddc28Sdaniel rate(void)
143*166ddc28Sdaniel {
144*166ddc28Sdaniel int score;
145*166ddc28Sdaniel
146*166ddc28Sdaniel score = max(max(pleasure, power), ego);
147*166ddc28Sdaniel if (score == pleasure) {
148*166ddc28Sdaniel if (score < 5)
149*166ddc28Sdaniel return ("novice");
150*166ddc28Sdaniel else if (score < 20)
151*166ddc28Sdaniel return ("junior voyeur");
152*166ddc28Sdaniel else if (score < 35)
153*166ddc28Sdaniel return ("Don Juan");
154*166ddc28Sdaniel else
155*166ddc28Sdaniel return ("Marquis De Sade");
156*166ddc28Sdaniel } else
157*166ddc28Sdaniel if (score == power) {
158*166ddc28Sdaniel if (score < 5)
159*166ddc28Sdaniel return ("serf");
160*166ddc28Sdaniel else if (score < 8)
161*166ddc28Sdaniel return ("Samurai");
162*166ddc28Sdaniel else if (score < 13)
163*166ddc28Sdaniel return ("Klingon");
164*166ddc28Sdaniel else if (score < 22)
165*166ddc28Sdaniel return ("Darth Vader");
166*166ddc28Sdaniel else
167*166ddc28Sdaniel return ("Sauron the Great");
168*166ddc28Sdaniel } else{
169*166ddc28Sdaniel if (score < 5)
170*166ddc28Sdaniel return ("Polyanna");
171*166ddc28Sdaniel else if (score < 10)
172*166ddc28Sdaniel return ("philanthropist");
173*166ddc28Sdaniel else if (score < 20)
174*166ddc28Sdaniel return ("Tattoo");
175*166ddc28Sdaniel else
176*166ddc28Sdaniel return ("Mr. Roarke");
177*166ddc28Sdaniel }
178*166ddc28Sdaniel }
179*166ddc28Sdaniel
180*166ddc28Sdaniel int
drive(void)181*166ddc28Sdaniel drive(void)
182*166ddc28Sdaniel {
183*166ddc28Sdaniel if (TestBit(location[position].objects, CAR)) {
184*166ddc28Sdaniel puts("You hop in the car and turn the key. There is a perceptible grating noise,");
185*166ddc28Sdaniel puts("and an explosion knocks you unconscious...");
186*166ddc28Sdaniel ClearBit(location[position].objects, CAR);
187*166ddc28Sdaniel SetBit(location[position].objects, CRASH);
188*166ddc28Sdaniel injuries[5] = injuries[6] = injuries[7] = injuries[8] = 1;
189*166ddc28Sdaniel ourtime += 15;
190*166ddc28Sdaniel zzz();
191*166ddc28Sdaniel return (0);
192*166ddc28Sdaniel } else
193*166ddc28Sdaniel puts("There is nothing to drive here.");
194*166ddc28Sdaniel return (-1);
195*166ddc28Sdaniel }
196*166ddc28Sdaniel
197*166ddc28Sdaniel int
ride(void)198*166ddc28Sdaniel ride(void)
199*166ddc28Sdaniel {
200*166ddc28Sdaniel if (TestBit(location[position].objects, HORSE)) {
201*166ddc28Sdaniel puts("You climb onto the stallion and kick it in the guts. The stupid steed launches");
202*166ddc28Sdaniel puts("forward through bush and fern. You are thrown and the horse gallops off.");
203*166ddc28Sdaniel ClearBit(location[position].objects, HORSE);
204*166ddc28Sdaniel while (!(position = rnd(NUMOFROOMS + 1)) || !OUTSIDE ||
205*166ddc28Sdaniel !beenthere[position] || location[position].flyhere)
206*166ddc28Sdaniel continue;
207*166ddc28Sdaniel SetBit(location[position].objects, HORSE);
208*166ddc28Sdaniel if (location[position].north)
209*166ddc28Sdaniel position = location[position].north;
210*166ddc28Sdaniel else if (location[position].south)
211*166ddc28Sdaniel position = location[position].south;
212*166ddc28Sdaniel else if (location[position].east)
213*166ddc28Sdaniel position = location[position].east;
214*166ddc28Sdaniel else
215*166ddc28Sdaniel position = location[position].west;
216*166ddc28Sdaniel return (0);
217*166ddc28Sdaniel }
218*166ddc28Sdaniel else puts("There is no horse here.");
219*166ddc28Sdaniel return (-1);
220*166ddc28Sdaniel }
221*166ddc28Sdaniel
222*166ddc28Sdaniel void
light(void)223*166ddc28Sdaniel light(void)
224*166ddc28Sdaniel { /* synonyms = {strike, smoke} */
225*166ddc28Sdaniel if (TestBit(inven, MATCHES) && matchcount) {
226*166ddc28Sdaniel puts("Your match splutters to life.");
227*166ddc28Sdaniel ourtime++;
228*166ddc28Sdaniel matchlight = 1;
229*166ddc28Sdaniel matchcount--;
230*166ddc28Sdaniel if (position == 217) {
231*166ddc28Sdaniel puts("The whole bungalow explodes with an intense blast.");
232*166ddc28Sdaniel die(0);
233*166ddc28Sdaniel }
234*166ddc28Sdaniel } else
235*166ddc28Sdaniel puts("You're out of matches.");
236*166ddc28Sdaniel }
237*166ddc28Sdaniel
238*166ddc28Sdaniel void
dooropen(void)239*166ddc28Sdaniel dooropen(void)
240*166ddc28Sdaniel { /* synonyms = {open, unlock} */
241*166ddc28Sdaniel wordnumber++;
242*166ddc28Sdaniel if (wordnumber <= wordcount && wordtype[wordnumber] == NOUNS
243*166ddc28Sdaniel && wordvalue[wordnumber] == DOOR) {
244*166ddc28Sdaniel switch(position) {
245*166ddc28Sdaniel case 189:
246*166ddc28Sdaniel case 231:
247*166ddc28Sdaniel if (location[189].north == 231)
248*166ddc28Sdaniel puts("The door is already open.");
249*166ddc28Sdaniel else
250*166ddc28Sdaniel puts("The door does not budge.");
251*166ddc28Sdaniel break;
252*166ddc28Sdaniel case 30:
253*166ddc28Sdaniel if (location[30].west == 25)
254*166ddc28Sdaniel puts("The door is gone.");
255*166ddc28Sdaniel else
256*166ddc28Sdaniel puts("The door is locked tight.");
257*166ddc28Sdaniel break;
258*166ddc28Sdaniel case 31:
259*166ddc28Sdaniel puts("That's one immovable door.");
260*166ddc28Sdaniel break;
261*166ddc28Sdaniel case 20:
262*166ddc28Sdaniel puts("The door is already ajar.");
263*166ddc28Sdaniel break;
264*166ddc28Sdaniel default:
265*166ddc28Sdaniel puts("What door?");
266*166ddc28Sdaniel }
267*166ddc28Sdaniel } else
268*166ddc28Sdaniel puts("That doesn't open.");
269*166ddc28Sdaniel }
270