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