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