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 * $DragonFly: src/games/trek/computer.c,v 1.3 2006/09/07 21:19:44 pavalos Exp $ 32 */ 33 34 #include "trek.h" 35 #include "getpar.h" 36 37 static int kalc(int, int, int, int, double *); 38 static void prkalc(int, double); 39 40 /* 41 ** On-Board Computer 42 ** 43 ** A computer request is fetched from the captain. The requests 44 ** are: 45 ** 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. 54 ** 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. 58 ** 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. 64 ** 65 ** move -- identical to course, except that the move is performed. 66 ** 67 ** score -- prints out the current score. 68 ** 69 ** pheff -- "PHaser EFFectiveness" at a given distance. Tells 70 ** you how much stuff you need to make it work. 71 ** 72 ** warpcost -- Gives you the cost in time and units to move for 73 ** a given distance under a given warp speed. 74 ** 75 ** impcost -- Same for the impulse engines. 76 ** 77 ** distresslist -- Gives a list of the currently known starsystems 78 ** or starbases which are distressed, together with their 79 ** quadrant coordinates. 80 ** 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. 84 */ 85 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 } 97 }; 98 99 void 100 computer(int v __unused) 101 { 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; 112 113 if (check_out(COMPUTER)) 114 return; 115 while (1) { 116 r = getcodpar("\nRequest", Cputab); 117 switch ((long)r->value) { 118 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) 130 { 131 printf("$$$ "); 132 continue; 133 } 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); 146 } 147 printf("%d\n", i); 148 } 149 printf(" "); 150 /* print bottom footer */ 151 for (i = 0; i < NQUADS; i++) 152 printf("-%d- ", i); 153 printf("\n"); 154 break; 155 156 case 2: /* trajectory */ 157 if (check_out(SRSCAN)) { 158 break; 159 } 160 if (Etc.nkling <= 0) { 161 printf("No Klingons in this quadrant\n"); 162 break; 163 } 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); 169 } 170 break; 171 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; 185 } 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; 196 } 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; 201 202 case 4: /* score */ 203 score(); 204 break; 205 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; 214 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; 227 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; 237 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) { 248 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; 254 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; 261 } 262 } 263 if (j) 264 printf("No known distress calls are active\n"); 265 break; 266 267 } 268 269 /* 270 * Skip to next semicolon or newline. Semicolon 271 * means get new computer request; newline means 272 * exit computer mode. 273 */ 274 while ((i = cgetc(0)) != ';') { 275 if (i == '\0') 276 exit(1); 277 if (i == '\n') { 278 ungetc(i, stdin); 279 return; 280 } 281 } 282 } 283 } 284 285 286 /* 287 ** Course Calculation 288 ** 289 ** Computes and outputs the course and distance from position 290 ** sqx,sqy/ssx,ssy to tqx,tqy/tsx,tsy. 291 */ 292 293 static int 294 kalc(int tqx, int tqy, int tsx, int tsy, double *dist) 295 { 296 double dx, dy; 297 double quadsize; 298 double angle; 299 int course; 300 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); 305 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); 316 } 317 318 static void 319 prkalc(int course, double dist) 320 { 321 printf(": course %d dist %.3f\n", course, dist); 322 } 323