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