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