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