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