1 /* @(#)computer.c 8.1 (Berkeley) 5/31/93 */ 2 /* $NetBSD: computer.c,v 1.16 2009/08/12 08:54:54 dholland Exp $ */ 3 4 /* 5 * Copyright (c) 1980, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <math.h> 36 #include "trek.h" 37 #include "getpar.h" 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 static 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 static int kalc(int, int, int, int, double *); 99 static void prkalc(int, double); 100 101 /*ARGSUSED*/ 102 void 103 computer(int v __unused) 104 { 105 int ix, iy; 106 int i, j; 107 int tqx, tqy; 108 const struct cvntab *r; 109 int cost; 110 int course; 111 double dist, time; 112 double warpfact; 113 struct quad *q; 114 struct event *e; 115 116 if (check_out(COMPUTER)) 117 return; 118 while (1) { 119 r = getcodpar("\nRequest", Cputab); 120 switch ((long)r->value) { 121 122 case 1: /* star chart */ 123 printf("Computer record of galaxy for all long range " 124 "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 printf("%d ", i); 132 for (j = 0; j < NQUADS; j++) { 133 if (i == Ship.quadx && 134 j == Ship.quady) { 135 printf("$$$ "); 136 continue; 137 } 138 q = &Quad[i][j]; 139 /* 1000 or 1001 is special case */ 140 if (q->scanned >= 1000) 141 if (q->scanned > 1000) 142 printf(".1. "); 143 else 144 printf("/// "); 145 else 146 if (q->scanned < 0) 147 printf("... "); 148 else 149 printf("%3d ", 150 q->scanned); 151 } 152 printf("%d\n", i); 153 } 154 printf(" "); 155 /* print bottom footer */ 156 for (i = 0; i < NQUADS; i++) 157 printf("-%d- ", i); 158 printf("\n"); 159 break; 160 161 case 2: /* trajectory */ 162 if (check_out(SRSCAN)) { 163 break; 164 } 165 if (Etc.nkling <= 0) { 166 printf("No Klingons in this quadrant\n"); 167 break; 168 } 169 /* for each Klingon, give the course & distance */ 170 for (i = 0; i < Etc.nkling; i++) { 171 printf("Klingon at %d,%d", 172 Etc.klingon[i].x, Etc.klingon[i].y); 173 course = kalc(Ship.quadx, Ship.quady, 174 Etc.klingon[i].x, 175 Etc.klingon[i].y, &dist); 176 prkalc(course, dist); 177 } 178 break; 179 180 case 3: /* course calculation */ 181 if (readdelim('/')) { 182 tqx = Ship.quadx; 183 tqy = Ship.quady; 184 } else { 185 ix = getintpar("Quadrant"); 186 if (ix < 0 || ix >= NSECTS) 187 break; 188 iy = getintpar("q-y"); 189 if (iy < 0 || iy >= NSECTS) 190 break; 191 tqx = ix; 192 tqy = iy; 193 } 194 ix = getintpar("Sector"); 195 if (ix < 0 || ix >= NSECTS) 196 break; 197 iy = getintpar("s-y"); 198 if (iy < 0 || iy >= NSECTS) 199 break; 200 course = kalc(tqx, tqy, ix, iy, &dist); 201 if (r->value2) { 202 warp(-1, course, dist); 203 break; 204 } 205 printf("%d,%d/%d,%d to %d,%d/%d,%d", 206 Ship.quadx, Ship.quady, Ship.sectx, Ship.secty, 207 tqx, tqy, ix, iy); 208 prkalc(course, dist); 209 break; 210 211 case 4: /* score */ 212 score(); 213 break; 214 215 case 5: /* phaser effectiveness */ 216 dist = getfltpar("range"); 217 if (dist < 0.0) 218 break; 219 dist *= 10.0; 220 cost = pow(0.90, dist) * 98.0 + 0.5; 221 printf("Phasers are %d%% effective at that range\n", 222 cost); 223 break; 224 225 case 6: /* warp cost (time/energy) */ 226 dist = getfltpar("distance"); 227 if (dist < 0.0) 228 break; 229 warpfact = getfltpar("warp factor"); 230 if (warpfact <= 0.0) 231 warpfact = Ship.warp; 232 cost = (dist + 0.05) * warpfact * warpfact * warpfact; 233 time = Param.warptime * dist / (warpfact * warpfact); 234 printf("Warp %.2f distance %.2f cost %.2f " 235 "stardates %d (%d w/ shlds up) units\n", 236 warpfact, dist, time, cost, cost + cost); 237 break; 238 239 case 7: /* impulse cost */ 240 dist = getfltpar("distance"); 241 if (dist < 0.0) 242 break; 243 cost = 20 + 100 * dist; 244 time = dist / 0.095; 245 printf("Distance %.2f cost %.2f stardates %d units\n", 246 dist, time, cost); 247 break; 248 249 case 8: /* distresslist */ 250 j = 1; 251 printf("\n"); 252 /* scan the event list */ 253 for (i = 0; i < MAXEVENTS; i++) { 254 e = &Event[i]; 255 /* ignore hidden entries */ 256 if (e->evcode & E_HIDDEN) 257 continue; 258 switch (e->evcode & E_EVENT) { 259 260 case E_KDESB: 261 printf("Klingon is attacking starbase " 262 "in quadrant %d,%d\n", 263 e->x, e->y); 264 j = 0; 265 break; 266 267 case E_ENSLV: 268 case E_REPRO: 269 printf("Starsystem %s in quadrant " 270 "%d,%d is distressed\n", 271 Systemname[e->systemname], 272 e->x, e->y); 273 j = 0; 274 break; 275 } 276 } 277 if (j) 278 printf("No known distress calls are active\n"); 279 break; 280 281 } 282 283 /* 284 * Skip to next semicolon or newline. Semicolon 285 * means get new computer request; newline means 286 * exit computer mode. 287 */ 288 while ((i = getchar()) != ';') { 289 if (i == EOF) 290 exit(1); 291 if (i == '\n') { 292 ungetc(i, stdin); 293 return; 294 } 295 } 296 } 297 } 298 299 300 /* 301 ** Course Calculation 302 ** 303 ** Computes and outputs the course and distance from position 304 ** sqx,sqy/ssx,ssy to tqx,tqy/tsx,tsy. 305 */ 306 307 static int 308 kalc(int tqx, int tqy, int tsx, int tsy, double *dist) 309 { 310 double dx, dy; 311 double quadsize; 312 double angle; 313 int course; 314 315 /* normalize to quadrant distances */ 316 quadsize = NSECTS; 317 dx = (Ship.quadx + Ship.sectx / quadsize) - (tqx + tsx / quadsize); 318 dy = (tqy + tsy / quadsize) - (Ship.quady + Ship.secty / quadsize); 319 320 /* get the angle */ 321 angle = atan2(dy, dx); 322 /* make it 0 -> 2 pi */ 323 if (angle < 0.0) 324 angle += 6.283185307; 325 /* convert from radians to degrees */ 326 course = angle * 57.29577951 + 0.5; 327 dx = dx * dx + dy * dy; 328 *dist = sqrt(dx); 329 return (course); 330 } 331 332 static void 333 prkalc(int course, double dist) 334 { 335 printf(": course %d dist %.3f\n", course, dist); 336 } 337