Commit | Line | Data |
---|---|---|
15637ed4 RG |
1 | /* |
2 | * Copyright (c) 1980 Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
13 | * 3. All advertising materials mentioning features or use of this software | |
14 | * must display the following acknowledgement: | |
15 | * This product includes software developed by the University of | |
16 | * California, Berkeley and its contributors. | |
17 | * 4. Neither the name of the University nor the names of its contributors | |
18 | * may be used to endorse or promote products derived from this software | |
19 | * without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
31 | * SUCH DAMAGE. | |
32 | */ | |
33 | ||
34 | #ifndef lint | |
35 | static char sccsid[] = "@(#)computer.c 4.8 (Berkeley) 6/1/90"; | |
36 | #endif /* not lint */ | |
37 | ||
38 | # include "trek.h" | |
39 | # include "getpar.h" | |
40 | # include <stdio.h> | |
41 | /* | |
42 | ** On-Board Computer | |
43 | ** | |
44 | ** A computer request is fetched from the captain. The requests | |
45 | ** are: | |
46 | ** | |
47 | ** chart -- print a star chart of the known galaxy. This includes | |
48 | ** every quadrant that has ever had a long range or | |
49 | ** a short range scan done of it, plus the location of | |
50 | ** all starbases. This is of course updated by any sub- | |
51 | ** space radio broadcasts (unless the radio is out). | |
52 | ** The format is the same as that of a long range scan | |
53 | ** except that ".1." indicates that a starbase exists | |
54 | ** but we know nothing else. | |
55 | ** | |
56 | ** trajectory -- gives the course and distance to every know | |
57 | ** Klingon in the quadrant. Obviously this fails if the | |
58 | ** short range scanners are out. | |
59 | ** | |
60 | ** course -- gives a course computation from whereever you are | |
61 | ** to any specified location. If the course begins | |
62 | ** with a slash, the current quadrant is taken. | |
63 | ** Otherwise the input is quadrant and sector coordi- | |
64 | ** nates of the target sector. | |
65 | ** | |
66 | ** move -- identical to course, except that the move is performed. | |
67 | ** | |
68 | ** score -- prints out the current score. | |
69 | ** | |
70 | ** pheff -- "PHaser EFFectiveness" at a given distance. Tells | |
71 | ** you how much stuff you need to make it work. | |
72 | ** | |
73 | ** warpcost -- Gives you the cost in time and units to move for | |
74 | ** a given distance under a given warp speed. | |
75 | ** | |
76 | ** impcost -- Same for the impulse engines. | |
77 | ** | |
78 | ** distresslist -- Gives a list of the currently known starsystems | |
79 | ** or starbases which are distressed, together with their | |
80 | ** quadrant coordinates. | |
81 | ** | |
82 | ** If a command is terminated with a semicolon, you remain in | |
83 | ** the computer; otherwise, you escape immediately to the main | |
84 | ** command processor. | |
85 | */ | |
86 | ||
87 | struct cvntab Cputab[] = | |
88 | { | |
89 | "ch", "art", (int (*)())1, 0, | |
90 | "t", "rajectory", (int (*)())2, 0, | |
91 | "c", "ourse", (int (*)())3, 0, | |
92 | "m", "ove", (int (*)())3, 1, | |
93 | "s", "core", (int (*)())4, 0, | |
94 | "p", "heff", (int (*)())5, 0, | |
95 | "w", "arpcost", (int (*)())6, 0, | |
96 | "i", "mpcost", (int (*)())7, 0, | |
97 | "d", "istresslist", (int (*)())8, 0, | |
98 | 0 | |
99 | }; | |
100 | ||
101 | computer() | |
102 | { | |
103 | int ix, iy; | |
104 | register int i, j; | |
105 | int numout; | |
106 | int tqx, tqy; | |
107 | struct cvntab *r; | |
108 | int cost; | |
109 | int course; | |
110 | double dist, time; | |
111 | double warpfact; | |
112 | struct quad *q; | |
113 | register struct event *e; | |
114 | ||
115 | if (check_out(COMPUTER)) | |
116 | return; | |
117 | while (1) | |
118 | { | |
119 | r = getcodpar("\nRequest", Cputab); | |
120 | switch ((int)r->value) | |
121 | { | |
122 | ||
123 | case 1: /* star chart */ | |
124 | printf("Computer record of galaxy for all long range sensor scans\n\n"); | |
125 | printf(" "); | |
126 | /* print top header */ | |
127 | for (i = 0; i < NQUADS; i++) | |
128 | printf("-%d- ", i); | |
129 | printf("\n"); | |
130 | for (i = 0; i < NQUADS; i++) | |
131 | { | |
132 | printf("%d ", i); | |
133 | for (j = 0; j < NQUADS; j++) | |
134 | { | |
135 | if (i == Ship.quadx && j == Ship.quady) | |
136 | { | |
137 | printf("$$$ "); | |
138 | continue; | |
139 | } | |
140 | q = &Quad[i][j]; | |
141 | /* 1000 or 1001 is special case */ | |
142 | if (q->scanned >= 1000) | |
143 | if (q->scanned > 1000) | |
144 | printf(".1. "); | |
145 | else | |
146 | printf("/// "); | |
147 | else | |
148 | if (q->scanned < 0) | |
149 | printf("... "); | |
150 | else | |
151 | printf("%3d ", q->scanned); | |
152 | } | |
153 | printf("%d\n", i); | |
154 | } | |
155 | printf(" "); | |
156 | /* print bottom footer */ | |
157 | for (i = 0; i < NQUADS; i++) | |
158 | printf("-%d- ", i); | |
159 | printf("\n"); | |
160 | break; | |
161 | ||
162 | case 2: /* trajectory */ | |
163 | if (check_out(SRSCAN)) | |
164 | { | |
165 | break; | |
166 | } | |
167 | if (Etc.nkling <= 0) | |
168 | { | |
169 | printf("No Klingons in this quadrant\n"); | |
170 | break; | |
171 | } | |
172 | /* for each Klingon, give the course & distance */ | |
173 | for (i = 0; i < Etc.nkling; i++) | |
174 | { | |
175 | printf("Klingon at %d,%d", Etc.klingon[i].x, Etc.klingon[i].y); | |
176 | course = kalc(Ship.quadx, Ship.quady, Etc.klingon[i].x, Etc.klingon[i].y, &dist); | |
177 | prkalc(course, dist); | |
178 | } | |
179 | break; | |
180 | ||
181 | case 3: /* course calculation */ | |
182 | if (readdelim('/')) | |
183 | { | |
184 | tqx = Ship.quadx; | |
185 | tqy = Ship.quady; | |
186 | } | |
187 | else | |
188 | { | |
189 | ix = getintpar("Quadrant"); | |
190 | if (ix < 0 || ix >= NSECTS) | |
191 | break; | |
192 | iy = getintpar("q-y"); | |
193 | if (iy < 0 || iy >= NSECTS) | |
194 | break; | |
195 | tqx = ix; | |
196 | tqy = iy; | |
197 | } | |
198 | ix = getintpar("Sector"); | |
199 | if (ix < 0 || ix >= NSECTS) | |
200 | break; | |
201 | iy = getintpar("s-y"); | |
202 | if (iy < 0 || iy >= NSECTS) | |
203 | break; | |
204 | course = kalc(tqx, tqy, ix, iy, &dist); | |
205 | if (r->value2) | |
206 | { | |
207 | warp(-1, course, dist); | |
208 | break; | |
209 | } | |
210 | printf("%d,%d/%d,%d to %d,%d/%d,%d", | |
211 | Ship.quadx, Ship.quady, Ship.sectx, Ship.secty, tqx, tqy, ix, iy); | |
212 | prkalc(course, dist); | |
213 | break; | |
214 | ||
215 | case 4: /* score */ | |
216 | score(); | |
217 | break; | |
218 | ||
219 | case 5: /* phaser effectiveness */ | |
220 | dist = getfltpar("range"); | |
221 | if (dist < 0.0) | |
222 | break; | |
223 | dist *= 10.0; | |
224 | cost = pow(0.90, dist) * 98.0 + 0.5; | |
225 | printf("Phasers are %d%% effective at that range\n", cost); | |
226 | break; | |
227 | ||
228 | case 6: /* warp cost (time/energy) */ | |
229 | dist = getfltpar("distance"); | |
230 | if (dist < 0.0) | |
231 | break; | |
232 | warpfact = getfltpar("warp factor"); | |
233 | if (warpfact <= 0.0) | |
234 | warpfact = Ship.warp; | |
235 | cost = (dist + 0.05) * warpfact * warpfact * warpfact; | |
236 | time = Param.warptime * dist / (warpfact * warpfact); | |
237 | printf("Warp %.2f distance %.2f cost %.2f stardates %d (%d w/ shlds up) units\n", | |
238 | warpfact, dist, time, cost, cost + cost); | |
239 | break; | |
240 | ||
241 | case 7: /* impulse cost */ | |
242 | dist = getfltpar("distance"); | |
243 | if (dist < 0.0) | |
244 | break; | |
245 | cost = 20 + 100 * dist; | |
246 | time = dist / 0.095; | |
247 | printf("Distance %.2f cost %.2f stardates %d units\n", | |
248 | dist, time, cost); | |
249 | break; | |
250 | ||
251 | case 8: /* distresslist */ | |
252 | j = 1; | |
253 | printf("\n"); | |
254 | /* scan the event list */ | |
255 | for (i = 0; i < MAXEVENTS; i++) | |
256 | { | |
257 | e = &Event[i]; | |
258 | /* ignore hidden entries */ | |
259 | if (e->evcode & E_HIDDEN) | |
260 | continue; | |
261 | switch (e->evcode & E_EVENT) | |
262 | { | |
263 | ||
264 | case E_KDESB: | |
265 | printf("Klingon is attacking starbase in quadrant %d,%d\n", | |
266 | e->x, e->y); | |
267 | j = 0; | |
268 | break; | |
269 | ||
270 | case E_ENSLV: | |
271 | case E_REPRO: | |
272 | printf("Starsystem %s in quadrant %d,%d is distressed\n", | |
273 | Systemname[e->systemname], e->x, e->y); | |
274 | j = 0; | |
275 | break; | |
276 | } | |
277 | } | |
278 | if (j) | |
279 | printf("No known distress calls are active\n"); | |
280 | break; | |
281 | ||
282 | } | |
283 | ||
284 | /* skip to next semicolon or newline. Semicolon | |
285 | * means get new computer request; newline means | |
286 | * exit computer mode. */ | |
287 | while ((i = cgetc(0)) != ';') | |
288 | { | |
289 | if (i == '\0') | |
290 | exit(1); | |
291 | if (i == '\n') | |
292 | { | |
293 | ungetc(i, stdin); | |
294 | return; | |
295 | } | |
296 | } | |
297 | } | |
298 | } | |
299 | ||
300 | ||
301 | /* | |
302 | ** Course Calculation | |
303 | ** | |
304 | ** Computes and outputs the course and distance from position | |
305 | ** sqx,sqy/ssx,ssy to tqx,tqy/tsx,tsy. | |
306 | */ | |
307 | ||
308 | kalc(tqx, tqy, tsx, tsy, dist) | |
309 | int tqx; | |
310 | int tqy; | |
311 | int tsx; | |
312 | int tsy; | |
313 | double *dist; | |
314 | { | |
315 | double dx, dy; | |
316 | double quadsize; | |
317 | double angle; | |
318 | register int course; | |
319 | ||
320 | /* normalize to quadrant distances */ | |
321 | quadsize = NSECTS; | |
322 | dx = (Ship.quadx + Ship.sectx / quadsize) - (tqx + tsx / quadsize); | |
323 | dy = (tqy + tsy / quadsize) - (Ship.quady + Ship.secty / quadsize); | |
324 | ||
325 | /* get the angle */ | |
326 | angle = atan2(dy, dx); | |
327 | /* make it 0 -> 2 pi */ | |
328 | if (angle < 0.0) | |
329 | angle += 6.283185307; | |
330 | /* convert from radians to degrees */ | |
331 | course = angle * 57.29577951 + 0.5; | |
332 | dx = dx * dx + dy * dy; | |
333 | *dist = sqrt(dx); | |
334 | return (course); | |
335 | } | |
336 | ||
337 | ||
338 | prkalc(course, dist) | |
339 | int course; | |
340 | double dist; | |
341 | { | |
342 | printf(": course %d dist %.3f\n", course, dist); | |
343 | } |