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