111663Smckusick #ifndef lint 2*12737Slayer static char sccsid[] = "@(#)computer.c 4.2 (Berkeley) 05/27/83"; 311663Smckusick #endif not lint 411663Smckusick 511663Smckusick # include "trek.h" 611663Smckusick # include "getpar.h" 7*12737Slayer # include <stdio.h> 811663Smckusick /* 911663Smckusick ** On-Board Computer 1011663Smckusick ** 1111663Smckusick ** A computer request is fetched from the captain. The requests 1211663Smckusick ** are: 1311663Smckusick ** 1411663Smckusick ** chart -- print a star chart of the known galaxy. This includes 1511663Smckusick ** every quadrant that has ever had a long range or 1611663Smckusick ** a short range scan done of it, plus the location of 1711663Smckusick ** all starbases. This is of course updated by any sub- 1811663Smckusick ** space radio broadcasts (unless the radio is out). 1911663Smckusick ** The format is the same as that of a long range scan 2011663Smckusick ** except that ".1." indicates that a starbase exists 2111663Smckusick ** but we know nothing else. 2211663Smckusick ** 2311663Smckusick ** trajectory -- gives the course and distance to every know 2411663Smckusick ** Klingon in the quadrant. Obviously this fails if the 2511663Smckusick ** short range scanners are out. 2611663Smckusick ** 2711663Smckusick ** course -- gives a course computation from whereever you are 2811663Smckusick ** to any specified location. If the course begins 2911663Smckusick ** with a slash, the current quadrant is taken. 3011663Smckusick ** Otherwise the input is quadrant and sector coordi- 3111663Smckusick ** nates of the target sector. 3211663Smckusick ** 3311663Smckusick ** move -- identical to course, except that the move is performed. 3411663Smckusick ** 3511663Smckusick ** score -- prints out the current score. 3611663Smckusick ** 3711663Smckusick ** pheff -- "PHaser EFFectiveness" at a given distance. Tells 3811663Smckusick ** you how much stuff you need to make it work. 3911663Smckusick ** 4011663Smckusick ** warpcost -- Gives you the cost in time and units to move for 4111663Smckusick ** a given distance under a given warp speed. 4211663Smckusick ** 4311663Smckusick ** impcost -- Same for the impulse engines. 4411663Smckusick ** 4511663Smckusick ** distresslist -- Gives a list of the currently known starsystems 4611663Smckusick ** or starbases which are distressed, together with their 4711663Smckusick ** quadrant coordinates. 4811663Smckusick ** 4911663Smckusick ** If a command is terminated with a semicolon, you remain in 5011663Smckusick ** the computer; otherwise, you escape immediately to the main 5111663Smckusick ** command processor. 5211663Smckusick */ 5311663Smckusick 54*12737Slayer struct cvntab Cputab[] = 5511663Smckusick { 56*12737Slayer "ch", "art", (int (*)())1, 0, 57*12737Slayer "t", "rajectory", (int (*)())2, 0, 58*12737Slayer "c", "ourse", (int (*)())3, 0, 59*12737Slayer "m", "ove", (int (*)())3, 1, 60*12737Slayer "s", "core", (int (*)())4, 0, 61*12737Slayer "p", "heff", (int (*)())5, 0, 62*12737Slayer "w", "arpcost", (int (*)())6, 0, 63*12737Slayer "i", "mpcost", (int (*)())7, 0, 64*12737Slayer "d", "istresslist", (int (*)())8, 0, 6511663Smckusick 0 6611663Smckusick }; 6711663Smckusick 6811663Smckusick computer() 6911663Smckusick { 7011663Smckusick int ix, iy; 7111663Smckusick register int i, j; 7211663Smckusick int numout; 7311663Smckusick int tqx, tqy; 7411663Smckusick struct cvntab *r; 7511663Smckusick int cost; 7611663Smckusick int course; 77*12737Slayer double dist, time; 78*12737Slayer double warpfact; 7911663Smckusick struct quad *q; 8011663Smckusick register struct event *e; 8111663Smckusick 8211663Smckusick if (check_out(COMPUTER)) 8311663Smckusick return; 8411663Smckusick while (1) 8511663Smckusick { 8611663Smckusick r = getcodpar("\nRequest", Cputab); 8711663Smckusick switch (r->value) 8811663Smckusick { 8911663Smckusick 9011663Smckusick case 1: /* star chart */ 9111663Smckusick printf("Computer record of galaxy for all long range sensor scans\n\n"); 9211663Smckusick printf(" "); 9311663Smckusick /* print top header */ 9411663Smckusick for (i = 0; i < NQUADS; i++) 9511663Smckusick printf("-%d- ", i); 9611663Smckusick printf("\n"); 9711663Smckusick for (i = 0; i < NQUADS; i++) 9811663Smckusick { 9911663Smckusick printf("%d ", i); 10011663Smckusick for (j = 0; j < NQUADS; j++) 10111663Smckusick { 10211663Smckusick if (i == Ship.quadx && j == Ship.quady) 10311663Smckusick { 10411663Smckusick printf("$$$ "); 10511663Smckusick continue; 10611663Smckusick } 10711663Smckusick q = &Quad[i][j]; 10811663Smckusick /* 1000 or 1001 is special case */ 10911663Smckusick if (q->scanned >= 1000) 11011663Smckusick if (q->scanned > 1000) 11111663Smckusick printf(".1. "); 11211663Smckusick else 11311663Smckusick printf("/// "); 11411663Smckusick else 11511663Smckusick if (q->scanned < 0) 11611663Smckusick printf("... "); 11711663Smckusick else 11811663Smckusick printf("%3d ", q->scanned); 11911663Smckusick } 12011663Smckusick printf("%d\n", i); 12111663Smckusick } 12211663Smckusick printf(" "); 12311663Smckusick /* print bottom footer */ 12411663Smckusick for (i = 0; i < NQUADS; i++) 12511663Smckusick printf("-%d- ", i); 12611663Smckusick printf("\n"); 12711663Smckusick break; 12811663Smckusick 12911663Smckusick case 2: /* trajectory */ 13011663Smckusick if (check_out(SRSCAN)) 13111663Smckusick { 13211663Smckusick break; 13311663Smckusick } 13411663Smckusick if (Etc.nkling <= 0) 13511663Smckusick { 13611663Smckusick printf("No Klingons in this quadrant\n"); 13711663Smckusick break; 13811663Smckusick } 13911663Smckusick /* for each Klingon, give the course & distance */ 14011663Smckusick for (i = 0; i < Etc.nkling; i++) 14111663Smckusick { 14211663Smckusick printf("Klingon at %d,%d", Etc.klingon[i].x, Etc.klingon[i].y); 14311663Smckusick course = kalc(Ship.quadx, Ship.quady, Etc.klingon[i].x, Etc.klingon[i].y, &dist); 14411663Smckusick prkalc(course, dist); 14511663Smckusick } 14611663Smckusick break; 14711663Smckusick 14811663Smckusick case 3: /* course calculation */ 14911663Smckusick if (readdelim('/')) 15011663Smckusick { 15111663Smckusick tqx = Ship.quadx; 15211663Smckusick tqy = Ship.quady; 15311663Smckusick } 15411663Smckusick else 15511663Smckusick { 15611663Smckusick ix = getintpar("Quadrant"); 15711663Smckusick if (ix < 0 || ix >= NSECTS) 15811663Smckusick break; 15911663Smckusick iy = getintpar("q-y"); 16011663Smckusick if (iy < 0 || iy >= NSECTS) 16111663Smckusick break; 16211663Smckusick tqx = ix; 16311663Smckusick tqy = iy; 16411663Smckusick } 16511663Smckusick ix = getintpar("Sector"); 16611663Smckusick if (ix < 0 || ix >= NSECTS) 16711663Smckusick break; 16811663Smckusick iy = getintpar("s-y"); 16911663Smckusick if (iy < 0 || iy >= NSECTS) 17011663Smckusick break; 17111663Smckusick course = kalc(tqx, tqy, ix, iy, &dist); 17211663Smckusick if (r->value2) 17311663Smckusick { 17411663Smckusick warp(-1, course, dist); 17511663Smckusick break; 17611663Smckusick } 17711663Smckusick printf("%d,%d/%d,%d to %d,%d/%d,%d", 17811663Smckusick Ship.quadx, Ship.quady, Ship.sectx, Ship.secty, tqx, tqy, ix, iy); 17911663Smckusick prkalc(course, dist); 18011663Smckusick break; 18111663Smckusick 18211663Smckusick case 4: /* score */ 18311663Smckusick score(); 18411663Smckusick break; 18511663Smckusick 18611663Smckusick case 5: /* phaser effectiveness */ 18711663Smckusick dist = getfltpar("range"); 18811663Smckusick if (dist < 0.0) 18911663Smckusick break; 190*12737Slayer dist *= 10.0; 19111663Smckusick cost = pow(0.90, dist) * 98.0 + 0.5; 19211663Smckusick printf("Phasers are %d%% effective at that range\n", cost); 19311663Smckusick break; 19411663Smckusick 19511663Smckusick case 6: /* warp cost (time/energy) */ 19611663Smckusick dist = getfltpar("distance"); 19711663Smckusick if (dist < 0.0) 19811663Smckusick break; 19911663Smckusick warpfact = getfltpar("warp factor"); 20011663Smckusick if (warpfact <= 0.0) 20111663Smckusick warpfact = Ship.warp; 20211663Smckusick cost = (dist + 0.05) * warpfact * warpfact * warpfact; 20311663Smckusick time = Param.warptime * dist / (warpfact * warpfact); 20411663Smckusick printf("Warp %.2f distance %.2f cost %.2f stardates %d (%d w/ shlds up) units\n", 20511663Smckusick warpfact, dist, time, cost, cost + cost); 20611663Smckusick break; 20711663Smckusick 20811663Smckusick case 7: /* impulse cost */ 20911663Smckusick dist = getfltpar("distance"); 21011663Smckusick if (dist < 0.0) 21111663Smckusick break; 21211663Smckusick cost = 20 + 100 * dist; 21311663Smckusick time = dist / 0.095; 21411663Smckusick printf("Distance %.2f cost %.2f stardates %d units\n", 21511663Smckusick dist, time, cost); 21611663Smckusick break; 21711663Smckusick 21811663Smckusick case 8: /* distresslist */ 21911663Smckusick j = 1; 22011663Smckusick printf("\n"); 22111663Smckusick /* scan the event list */ 22211663Smckusick for (i = 0; i < MAXEVENTS; i++) 22311663Smckusick { 22411663Smckusick e = &Event[i]; 22511663Smckusick /* ignore hidden entries */ 22611663Smckusick if (e->evcode & E_HIDDEN) 22711663Smckusick continue; 22811663Smckusick switch (e->evcode & E_EVENT) 22911663Smckusick { 23011663Smckusick 23111663Smckusick case E_KDESB: 23211663Smckusick printf("Klingon is attacking starbase in quadrant %d,%d\n", 23311663Smckusick e->x, e->y); 23411663Smckusick j = 0; 23511663Smckusick break; 23611663Smckusick 23711663Smckusick case E_ENSLV: 23811663Smckusick case E_REPRO: 23911663Smckusick printf("Starsystem %s in quadrant %d,%d is distressed\n", 24011663Smckusick systemname(e), e->x, e->y); 24111663Smckusick j = 0; 24211663Smckusick break; 24311663Smckusick } 24411663Smckusick } 24511663Smckusick if (j) 24611663Smckusick printf("No known distress calls are active\n"); 24711663Smckusick break; 24811663Smckusick 24911663Smckusick } 25011663Smckusick 25111663Smckusick /* skip to next semicolon or newline. Semicolon 25211663Smckusick * means get new computer request; newline means 25311663Smckusick * exit computer mode. */ 25411663Smckusick while ((i = cgetc(0)) != ';') 25511663Smckusick { 25611663Smckusick if (i == '\0') 25711663Smckusick exit(1); 25811663Smckusick if (i == '\n') 25911663Smckusick { 260*12737Slayer ungetc(i, stdin); 26111663Smckusick return; 26211663Smckusick } 26311663Smckusick } 26411663Smckusick } 26511663Smckusick } 26611663Smckusick 26711663Smckusick 26811663Smckusick /* 26911663Smckusick ** Course Calculation 27011663Smckusick ** 27111663Smckusick ** Computes and outputs the course and distance from position 27211663Smckusick ** sqx,sqy/ssx,ssy to tqx,tqy/tsx,tsy. 27311663Smckusick */ 27411663Smckusick 27511663Smckusick kalc(tqx, tqy, tsx, tsy, dist) 27611663Smckusick int tqx; 27711663Smckusick int tqy; 27811663Smckusick int tsx; 27911663Smckusick int tsy; 280*12737Slayer double *dist; 28111663Smckusick { 28211663Smckusick double dx, dy; 283*12737Slayer double quadsize; 28411663Smckusick double angle; 28511663Smckusick register int course; 28611663Smckusick 28711663Smckusick /* normalize to quadrant distances */ 28811663Smckusick quadsize = NSECTS; 28911663Smckusick dx = (Ship.quadx + Ship.sectx / quadsize) - (tqx + tsx / quadsize); 29011663Smckusick dy = (tqy + tsy / quadsize) - (Ship.quady + Ship.secty / quadsize); 29111663Smckusick 29211663Smckusick /* get the angle */ 29311663Smckusick angle = atan2(dy, dx); 29411663Smckusick /* make it 0 -> 2 pi */ 29511663Smckusick if (angle < 0.0) 296*12737Slayer angle += 6.283185307; 29711663Smckusick /* convert from radians to degrees */ 29811663Smckusick course = angle * 57.29577951 + 0.5; 29911663Smckusick dx = dx * dx + dy * dy; 30011663Smckusick *dist = sqrt(dx); 30111663Smckusick return (course); 30211663Smckusick } 30311663Smckusick 30411663Smckusick 30511663Smckusick prkalc(course, dist) 30611663Smckusick int course; 307*12737Slayer double dist; 30811663Smckusick { 30911663Smckusick printf(": course %d dist %.3f\n", course, dist); 31011663Smckusick } 311