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