1 /* $NetBSD: computer.c,v 1.8 2000/07/03 03:57:44 matt Exp $ */ 2 3 /* 4 * Copyright (c) 1980, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include <sys/cdefs.h> 37 #ifndef lint 38 #if 0 39 static char sccsid[] = "@(#)computer.c 8.1 (Berkeley) 5/31/93"; 40 #else 41 __RCSID("$NetBSD: computer.c,v 1.8 2000/07/03 03:57:44 matt Exp $"); 42 #endif 43 #endif /* not lint */ 44 45 #include <stdio.h> 46 #include <stdlib.h> 47 #include <math.h> 48 #include "trek.h" 49 #include "getpar.h" 50 51 /* 52 ** On-Board Computer 53 ** 54 ** A computer request is fetched from the captain. The requests 55 ** are: 56 ** 57 ** chart -- print a star chart of the known galaxy. This includes 58 ** every quadrant that has ever had a long range or 59 ** a short range scan done of it, plus the location of 60 ** all starbases. This is of course updated by any sub- 61 ** space radio broadcasts (unless the radio is out). 62 ** The format is the same as that of a long range scan 63 ** except that ".1." indicates that a starbase exists 64 ** but we know nothing else. 65 ** 66 ** trajectory -- gives the course and distance to every know 67 ** Klingon in the quadrant. Obviously this fails if the 68 ** short range scanners are out. 69 ** 70 ** course -- gives a course computation from whereever you are 71 ** to any specified location. If the course begins 72 ** with a slash, the current quadrant is taken. 73 ** Otherwise the input is quadrant and sector coordi- 74 ** nates of the target sector. 75 ** 76 ** move -- identical to course, except that the move is performed. 77 ** 78 ** score -- prints out the current score. 79 ** 80 ** pheff -- "PHaser EFFectiveness" at a given distance. Tells 81 ** you how much stuff you need to make it work. 82 ** 83 ** warpcost -- Gives you the cost in time and units to move for 84 ** a given distance under a given warp speed. 85 ** 86 ** impcost -- Same for the impulse engines. 87 ** 88 ** distresslist -- Gives a list of the currently known starsystems 89 ** or starbases which are distressed, together with their 90 ** quadrant coordinates. 91 ** 92 ** If a command is terminated with a semicolon, you remain in 93 ** the computer; otherwise, you escape immediately to the main 94 ** command processor. 95 */ 96 97 struct cvntab Cputab[] = 98 { 99 { "ch", "art", (cmdfun)1, 0 }, 100 { "t", "rajectory", (cmdfun)2, 0 }, 101 { "c", "ourse", (cmdfun)3, 0 }, 102 { "m", "ove", (cmdfun)3, 1 }, 103 { "s", "core", (cmdfun)4, 0 }, 104 { "p", "heff", (cmdfun)5, 0 }, 105 { "w", "arpcost", (cmdfun)6, 0 }, 106 { "i", "mpcost", (cmdfun)7, 0 }, 107 { "d", "istresslist", (cmdfun)8, 0 }, 108 { NULL, NULL, NULL, 0 } 109 }; 110 111 static int kalc __P((int, int, int, int, double *)); 112 static void prkalc __P((int, double)); 113 114 /*ARGSUSED*/ 115 void 116 computer(v) 117 int v __attribute__((__unused__)); 118 { 119 int ix, iy; 120 int i, j; 121 int tqx, tqy; 122 const struct cvntab *r; 123 int cost; 124 int course; 125 double dist, time; 126 double warpfact; 127 struct quad *q; 128 struct event *e; 129 130 if (check_out(COMPUTER)) 131 return; 132 while (1) 133 { 134 r = getcodpar("\nRequest", Cputab); 135 switch ((long)r->value) 136 { 137 138 case 1: /* star chart */ 139 printf("Computer record of galaxy for all long range sensor scans\n\n"); 140 printf(" "); 141 /* print top header */ 142 for (i = 0; i < NQUADS; i++) 143 printf("-%d- ", i); 144 printf("\n"); 145 for (i = 0; i < NQUADS; i++) 146 { 147 printf("%d ", i); 148 for (j = 0; j < NQUADS; j++) 149 { 150 if (i == Ship.quadx && j == Ship.quady) 151 { 152 printf("$$$ "); 153 continue; 154 } 155 q = &Quad[i][j]; 156 /* 1000 or 1001 is special case */ 157 if (q->scanned >= 1000) 158 if (q->scanned > 1000) 159 printf(".1. "); 160 else 161 printf("/// "); 162 else 163 if (q->scanned < 0) 164 printf("... "); 165 else 166 printf("%3d ", q->scanned); 167 } 168 printf("%d\n", i); 169 } 170 printf(" "); 171 /* print bottom footer */ 172 for (i = 0; i < NQUADS; i++) 173 printf("-%d- ", i); 174 printf("\n"); 175 break; 176 177 case 2: /* trajectory */ 178 if (check_out(SRSCAN)) 179 { 180 break; 181 } 182 if (Etc.nkling <= 0) 183 { 184 printf("No Klingons in this quadrant\n"); 185 break; 186 } 187 /* for each Klingon, give the course & distance */ 188 for (i = 0; i < Etc.nkling; i++) 189 { 190 printf("Klingon at %d,%d", Etc.klingon[i].x, Etc.klingon[i].y); 191 course = kalc(Ship.quadx, Ship.quady, Etc.klingon[i].x, Etc.klingon[i].y, &dist); 192 prkalc(course, dist); 193 } 194 break; 195 196 case 3: /* course calculation */ 197 if (readdelim('/')) 198 { 199 tqx = Ship.quadx; 200 tqy = Ship.quady; 201 } 202 else 203 { 204 ix = getintpar("Quadrant"); 205 if (ix < 0 || ix >= NSECTS) 206 break; 207 iy = getintpar("q-y"); 208 if (iy < 0 || iy >= NSECTS) 209 break; 210 tqx = ix; 211 tqy = iy; 212 } 213 ix = getintpar("Sector"); 214 if (ix < 0 || ix >= NSECTS) 215 break; 216 iy = getintpar("s-y"); 217 if (iy < 0 || iy >= NSECTS) 218 break; 219 course = kalc(tqx, tqy, ix, iy, &dist); 220 if (r->value2) 221 { 222 warp(-1, course, dist); 223 break; 224 } 225 printf("%d,%d/%d,%d to %d,%d/%d,%d", 226 Ship.quadx, Ship.quady, Ship.sectx, Ship.secty, tqx, tqy, ix, iy); 227 prkalc(course, dist); 228 break; 229 230 case 4: /* score */ 231 score(); 232 break; 233 234 case 5: /* phaser effectiveness */ 235 dist = getfltpar("range"); 236 if (dist < 0.0) 237 break; 238 dist *= 10.0; 239 cost = pow(0.90, dist) * 98.0 + 0.5; 240 printf("Phasers are %d%% effective at that range\n", cost); 241 break; 242 243 case 6: /* warp cost (time/energy) */ 244 dist = getfltpar("distance"); 245 if (dist < 0.0) 246 break; 247 warpfact = getfltpar("warp factor"); 248 if (warpfact <= 0.0) 249 warpfact = Ship.warp; 250 cost = (dist + 0.05) * warpfact * warpfact * warpfact; 251 time = Param.warptime * dist / (warpfact * warpfact); 252 printf("Warp %.2f distance %.2f cost %.2f stardates %d (%d w/ shlds up) units\n", 253 warpfact, dist, time, cost, cost + cost); 254 break; 255 256 case 7: /* impulse cost */ 257 dist = getfltpar("distance"); 258 if (dist < 0.0) 259 break; 260 cost = 20 + 100 * dist; 261 time = dist / 0.095; 262 printf("Distance %.2f cost %.2f stardates %d units\n", 263 dist, time, cost); 264 break; 265 266 case 8: /* distresslist */ 267 j = 1; 268 printf("\n"); 269 /* scan the event list */ 270 for (i = 0; i < MAXEVENTS; i++) 271 { 272 e = &Event[i]; 273 /* ignore hidden entries */ 274 if (e->evcode & E_HIDDEN) 275 continue; 276 switch (e->evcode & E_EVENT) 277 { 278 279 case E_KDESB: 280 printf("Klingon is attacking starbase in quadrant %d,%d\n", 281 e->x, e->y); 282 j = 0; 283 break; 284 285 case E_ENSLV: 286 case E_REPRO: 287 printf("Starsystem %s in quadrant %d,%d is distressed\n", 288 Systemname[e->systemname], e->x, e->y); 289 j = 0; 290 break; 291 } 292 } 293 if (j) 294 printf("No known distress calls are active\n"); 295 break; 296 297 } 298 299 /* skip to next semicolon or newline. Semicolon 300 * means get new computer request; newline means 301 * exit computer mode. */ 302 while ((i = cgetc(0)) != ';') 303 { 304 if (i == '\0') 305 exit(1); 306 if (i == '\n') 307 { 308 ungetc(i, stdin); 309 return; 310 } 311 } 312 } 313 } 314 315 316 /* 317 ** Course Calculation 318 ** 319 ** Computes and outputs the course and distance from position 320 ** sqx,sqy/ssx,ssy to tqx,tqy/tsx,tsy. 321 */ 322 323 static int 324 kalc(tqx, tqy, tsx, tsy, dist) 325 int tqx; 326 int tqy; 327 int tsx; 328 int tsy; 329 double *dist; 330 { 331 double dx, dy; 332 double quadsize; 333 double angle; 334 int course; 335 336 /* normalize to quadrant distances */ 337 quadsize = NSECTS; 338 dx = (Ship.quadx + Ship.sectx / quadsize) - (tqx + tsx / quadsize); 339 dy = (tqy + tsy / quadsize) - (Ship.quady + Ship.secty / quadsize); 340 341 /* get the angle */ 342 angle = atan2(dy, dx); 343 /* make it 0 -> 2 pi */ 344 if (angle < 0.0) 345 angle += 6.283185307; 346 /* convert from radians to degrees */ 347 course = angle * 57.29577951 + 0.5; 348 dx = dx * dx + dy * dy; 349 *dist = sqrt(dx); 350 return (course); 351 } 352 353 static void 354 prkalc(course, dist) 355 int course; 356 double dist; 357 { 358 printf(": course %d dist %.3f\n", course, dist); 359 } 360