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