wbsio(4): convert to Newbus and DragonFly -- welcome wbsio(4)!
[dragonfly.git] / games / trek / computer.c
blobd929dd0745d06bff8fbbae5815cac52cd3592e03
1 /*-
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
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. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
29 * @(#)computer.c 8.1 (Berkeley) 5/31/93
30 * $FreeBSD: src/games/trek/computer.c,v 1.5 1999/11/30 03:49:45 billf Exp $
31 * $DragonFly: src/games/trek/computer.c,v 1.3 2006/09/07 21:19:44 pavalos Exp $
34 #include "trek.h"
35 #include "getpar.h"
37 static int kalc(int, int, int, int, double *);
38 static void prkalc(int, double);
41 ** On-Board Computer
43 ** A computer request is fetched from the captain. The requests
44 ** are:
46 ** chart -- print a star chart of the known galaxy. This includes
47 ** every quadrant that has ever had a long range or
48 ** a short range scan done of it, plus the location of
49 ** all starbases. This is of course updated by any sub-
50 ** space radio broadcasts (unless the radio is out).
51 ** The format is the same as that of a long range scan
52 ** except that ".1." indicates that a starbase exists
53 ** but we know nothing else.
55 ** trajectory -- gives the course and distance to every know
56 ** Klingon in the quadrant. Obviously this fails if the
57 ** short range scanners are out.
59 ** course -- gives a course computation from whereever you are
60 ** to any specified location. If the course begins
61 ** with a slash, the current quadrant is taken.
62 ** Otherwise the input is quadrant and sector coordi-
63 ** nates of the target sector.
65 ** move -- identical to course, except that the move is performed.
67 ** score -- prints out the current score.
69 ** pheff -- "PHaser EFFectiveness" at a given distance. Tells
70 ** you how much stuff you need to make it work.
72 ** warpcost -- Gives you the cost in time and units to move for
73 ** a given distance under a given warp speed.
75 ** impcost -- Same for the impulse engines.
77 ** distresslist -- Gives a list of the currently known starsystems
78 ** or starbases which are distressed, together with their
79 ** quadrant coordinates.
81 ** If a command is terminated with a semicolon, you remain in
82 ** the computer; otherwise, you escape immediately to the main
83 ** command processor.
86 struct cvntab Cputab[] = {
87 { "ch", "art", (cmdfun)1, 0 },
88 { "t", "rajectory", (cmdfun)2, 0 },
89 { "c", "ourse", (cmdfun)3, 0 },
90 { "m", "ove", (cmdfun)3, 1 },
91 { "s", "core", (cmdfun)4, 0 },
92 { "p", "heff", (cmdfun)5, 0 },
93 { "w", "arpcost", (cmdfun)6, 0 },
94 { "i", "mpcost", (cmdfun)7, 0 },
95 { "d", "istresslist", (cmdfun)8, 0 },
96 { NULL, NULL, NULL, 0 }
99 void
100 computer(int v __unused)
102 int ix, iy;
103 int i, j;
104 int tqx, tqy;
105 struct cvntab *r;
106 int cost;
107 int course;
108 double dist, p_time;
109 double warpfact;
110 struct quad *q;
111 struct event *e;
113 if (check_out(COMPUTER))
114 return;
115 while (1) {
116 r = getcodpar("\nRequest", Cputab);
117 switch ((long)r->value) {
119 case 1: /* star chart */
120 printf("Computer record of galaxy for all long range sensor scans\n\n");
121 printf(" ");
122 /* print top header */
123 for (i = 0; i < NQUADS; i++)
124 printf("-%d- ", i);
125 printf("\n");
126 for (i = 0; i < NQUADS; i++) {
127 printf("%d ", i);
128 for (j = 0; j < NQUADS; j++) {
129 if (i == Ship.quadx && j == Ship.quady)
131 printf("$$$ ");
132 continue;
134 q = &Quad[i][j];
135 /* 1000 or 1001 is special case */
136 if (q->scanned >= 1000)
137 if (q->scanned > 1000)
138 printf(".1. ");
139 else
140 printf("/// ");
141 else
142 if (q->scanned < 0)
143 printf("... ");
144 else
145 printf("%3d ", q->scanned);
147 printf("%d\n", i);
149 printf(" ");
150 /* print bottom footer */
151 for (i = 0; i < NQUADS; i++)
152 printf("-%d- ", i);
153 printf("\n");
154 break;
156 case 2: /* trajectory */
157 if (check_out(SRSCAN)) {
158 break;
160 if (Etc.nkling <= 0) {
161 printf("No Klingons in this quadrant\n");
162 break;
164 /* for each Klingon, give the course & distance */
165 for (i = 0; i < Etc.nkling; i++) {
166 printf("Klingon at %d,%d", Etc.klingon[i].x, Etc.klingon[i].y);
167 course = kalc(Ship.quadx, Ship.quady, Etc.klingon[i].x, Etc.klingon[i].y, &dist);
168 prkalc(course, dist);
170 break;
172 case 3: /* course calculation */
173 if (readdelim('/')) {
174 tqx = Ship.quadx;
175 tqy = Ship.quady;
176 } else {
177 ix = getintpar("Quadrant");
178 if (ix < 0 || ix >= NSECTS)
179 break;
180 iy = getintpar("q-y");
181 if (iy < 0 || iy >= NSECTS)
182 break;
183 tqx = ix;
184 tqy = iy;
186 ix = getintpar("Sector");
187 if (ix < 0 || ix >= NSECTS)
188 break;
189 iy = getintpar("s-y");
190 if (iy < 0 || iy >= NSECTS)
191 break;
192 course = kalc(tqx, tqy, ix, iy, &dist);
193 if (r->value2) {
194 warp(-1, course, dist);
195 break;
197 printf("%d,%d/%d,%d to %d,%d/%d,%d",
198 Ship.quadx, Ship.quady, Ship.sectx, Ship.secty, tqx, tqy, ix, iy);
199 prkalc(course, dist);
200 break;
202 case 4: /* score */
203 score();
204 break;
206 case 5: /* phaser effectiveness */
207 dist = getfltpar("range");
208 if (dist < 0.0)
209 break;
210 dist *= 10.0;
211 cost = pow(0.90, dist) * 98.0 + 0.5;
212 printf("Phasers are %d%% effective at that range\n", cost);
213 break;
215 case 6: /* warp cost (time/energy) */
216 dist = getfltpar("distance");
217 if (dist < 0.0)
218 break;
219 warpfact = getfltpar("warp factor");
220 if (warpfact <= 0.0)
221 warpfact = Ship.warp;
222 cost = (dist + 0.05) * warpfact * warpfact * warpfact;
223 p_time = Param.warptime * dist / (warpfact * warpfact);
224 printf("Warp %.2f distance %.2f cost %.2f stardates %d (%d w/ shlds up) units\n",
225 warpfact, dist, p_time, cost, cost + cost);
226 break;
228 case 7: /* impulse cost */
229 dist = getfltpar("distance");
230 if (dist < 0.0)
231 break;
232 cost = 20 + 100 * dist;
233 p_time = dist / 0.095;
234 printf("Distance %.2f cost %.2f stardates %d units\n",
235 dist, p_time, cost);
236 break;
238 case 8: /* distresslist */
239 j = 1;
240 printf("\n");
241 /* scan the event list */
242 for (i = 0; i < MAXEVENTS; i++) {
243 e = &Event[i];
244 /* ignore hidden entries */
245 if (e->evcode & E_HIDDEN)
246 continue;
247 switch (e->evcode & E_EVENT) {
249 case E_KDESB:
250 printf("Klingon is attacking starbase in quadrant %d,%d\n",
251 e->x, e->y);
252 j = 0;
253 break;
255 case E_ENSLV:
256 case E_REPRO:
257 printf("Starsystem %s in quadrant %d,%d is distressed\n",
258 Systemname[e->systemname], e->x, e->y);
259 j = 0;
260 break;
263 if (j)
264 printf("No known distress calls are active\n");
265 break;
270 * Skip to next semicolon or newline. Semicolon
271 * means get new computer request; newline means
272 * exit computer mode.
274 while ((i = cgetc(0)) != ';') {
275 if (i == '\0')
276 exit(1);
277 if (i == '\n') {
278 ungetc(i, stdin);
279 return;
287 ** Course Calculation
289 ** Computes and outputs the course and distance from position
290 ** sqx,sqy/ssx,ssy to tqx,tqy/tsx,tsy.
293 static int
294 kalc(int tqx, int tqy, int tsx, int tsy, double *dist)
296 double dx, dy;
297 double quadsize;
298 double angle;
299 int course;
301 /* normalize to quadrant distances */
302 quadsize = NSECTS;
303 dx = (Ship.quadx + Ship.sectx / quadsize) - (tqx + tsx / quadsize);
304 dy = (tqy + tsy / quadsize) - (Ship.quady + Ship.secty / quadsize);
306 /* get the angle */
307 angle = atan2(dy, dx);
308 /* make it 0 -> 2 pi */
309 if (angle < 0.0)
310 angle += 6.283185307;
311 /* convert from radians to degrees */
312 course = angle * 57.29577951 + 0.5;
313 dx = dx * dx + dy * dy;
314 *dist = sqrt(dx);
315 return (course);
318 static void
319 prkalc(int course, double dist)
321 printf(": course %d dist %.3f\n", course, dist);