125989Smckusick /* 225989Smckusick * Copyright (c) 1980 Regents of the University of California. 334205Sbostic * All rights reserved. 434205Sbostic * 534205Sbostic * Redistribution and use in source and binary forms are permitted 634789Sbostic * provided that the above copyright notice and this paragraph are 734789Sbostic * duplicated in all such forms and that any documentation, 834789Sbostic * advertising materials, and other materials related to such 934789Sbostic * distribution and use acknowledge that the software was developed 1034789Sbostic * by the University of California, Berkeley. The name of the 1134789Sbostic * University may not be used to endorse or promote products derived 1234789Sbostic * from this software without specific prior written permission. 1334789Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434789Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534789Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1625989Smckusick */ 1725989Smckusick 1811663Smckusick #ifndef lint 19*38205Sbostic static char sccsid[] = "@(#)computer.c 4.7 (Berkeley) 05/30/89"; 2034205Sbostic #endif /* not lint */ 2111663Smckusick 2211663Smckusick # include "trek.h" 2311663Smckusick # include "getpar.h" 2412737Slayer # include <stdio.h> 2511663Smckusick /* 2611663Smckusick ** On-Board Computer 2711663Smckusick ** 2811663Smckusick ** A computer request is fetched from the captain. The requests 2911663Smckusick ** are: 3011663Smckusick ** 3111663Smckusick ** chart -- print a star chart of the known galaxy. This includes 3211663Smckusick ** every quadrant that has ever had a long range or 3311663Smckusick ** a short range scan done of it, plus the location of 3411663Smckusick ** all starbases. This is of course updated by any sub- 3511663Smckusick ** space radio broadcasts (unless the radio is out). 3611663Smckusick ** The format is the same as that of a long range scan 3711663Smckusick ** except that ".1." indicates that a starbase exists 3811663Smckusick ** but we know nothing else. 3911663Smckusick ** 4011663Smckusick ** trajectory -- gives the course and distance to every know 4111663Smckusick ** Klingon in the quadrant. Obviously this fails if the 4211663Smckusick ** short range scanners are out. 4311663Smckusick ** 4411663Smckusick ** course -- gives a course computation from whereever you are 4511663Smckusick ** to any specified location. If the course begins 4611663Smckusick ** with a slash, the current quadrant is taken. 4711663Smckusick ** Otherwise the input is quadrant and sector coordi- 4811663Smckusick ** nates of the target sector. 4911663Smckusick ** 5011663Smckusick ** move -- identical to course, except that the move is performed. 5111663Smckusick ** 5211663Smckusick ** score -- prints out the current score. 5311663Smckusick ** 5411663Smckusick ** pheff -- "PHaser EFFectiveness" at a given distance. Tells 5511663Smckusick ** you how much stuff you need to make it work. 5611663Smckusick ** 5711663Smckusick ** warpcost -- Gives you the cost in time and units to move for 5811663Smckusick ** a given distance under a given warp speed. 5911663Smckusick ** 6011663Smckusick ** impcost -- Same for the impulse engines. 6111663Smckusick ** 6211663Smckusick ** distresslist -- Gives a list of the currently known starsystems 6311663Smckusick ** or starbases which are distressed, together with their 6411663Smckusick ** quadrant coordinates. 6511663Smckusick ** 6611663Smckusick ** If a command is terminated with a semicolon, you remain in 6711663Smckusick ** the computer; otherwise, you escape immediately to the main 6811663Smckusick ** command processor. 6911663Smckusick */ 7011663Smckusick 7112737Slayer struct cvntab Cputab[] = 7211663Smckusick { 7312737Slayer "ch", "art", (int (*)())1, 0, 7412737Slayer "t", "rajectory", (int (*)())2, 0, 7512737Slayer "c", "ourse", (int (*)())3, 0, 7612737Slayer "m", "ove", (int (*)())3, 1, 7712737Slayer "s", "core", (int (*)())4, 0, 7812737Slayer "p", "heff", (int (*)())5, 0, 7912737Slayer "w", "arpcost", (int (*)())6, 0, 8012737Slayer "i", "mpcost", (int (*)())7, 0, 8112737Slayer "d", "istresslist", (int (*)())8, 0, 8211663Smckusick 0 8311663Smckusick }; 8411663Smckusick 8511663Smckusick computer() 8611663Smckusick { 8711663Smckusick int ix, iy; 8811663Smckusick register int i, j; 8911663Smckusick int numout; 9011663Smckusick int tqx, tqy; 9111663Smckusick struct cvntab *r; 9211663Smckusick int cost; 9311663Smckusick int course; 9412737Slayer double dist, time; 9512737Slayer double warpfact; 9611663Smckusick struct quad *q; 9711663Smckusick register struct event *e; 9811663Smckusick 9911663Smckusick if (check_out(COMPUTER)) 10011663Smckusick return; 10111663Smckusick while (1) 10211663Smckusick { 10311663Smckusick r = getcodpar("\nRequest", Cputab); 10432357Sbostic switch ((int)r->value) 10511663Smckusick { 10611663Smckusick 10711663Smckusick case 1: /* star chart */ 10811663Smckusick printf("Computer record of galaxy for all long range sensor scans\n\n"); 10911663Smckusick printf(" "); 11011663Smckusick /* print top header */ 11111663Smckusick for (i = 0; i < NQUADS; i++) 11211663Smckusick printf("-%d- ", i); 11311663Smckusick printf("\n"); 11411663Smckusick for (i = 0; i < NQUADS; i++) 11511663Smckusick { 11611663Smckusick printf("%d ", i); 11711663Smckusick for (j = 0; j < NQUADS; j++) 11811663Smckusick { 11911663Smckusick if (i == Ship.quadx && j == Ship.quady) 12011663Smckusick { 12111663Smckusick printf("$$$ "); 12211663Smckusick continue; 12311663Smckusick } 12411663Smckusick q = &Quad[i][j]; 12511663Smckusick /* 1000 or 1001 is special case */ 12611663Smckusick if (q->scanned >= 1000) 12711663Smckusick if (q->scanned > 1000) 12811663Smckusick printf(".1. "); 12911663Smckusick else 13011663Smckusick printf("/// "); 13111663Smckusick else 13211663Smckusick if (q->scanned < 0) 13311663Smckusick printf("... "); 13411663Smckusick else 13511663Smckusick printf("%3d ", q->scanned); 13611663Smckusick } 13711663Smckusick printf("%d\n", i); 13811663Smckusick } 13911663Smckusick printf(" "); 14011663Smckusick /* print bottom footer */ 14111663Smckusick for (i = 0; i < NQUADS; i++) 14211663Smckusick printf("-%d- ", i); 14311663Smckusick printf("\n"); 14411663Smckusick break; 14511663Smckusick 14611663Smckusick case 2: /* trajectory */ 14711663Smckusick if (check_out(SRSCAN)) 14811663Smckusick { 14911663Smckusick break; 15011663Smckusick } 15111663Smckusick if (Etc.nkling <= 0) 15211663Smckusick { 15311663Smckusick printf("No Klingons in this quadrant\n"); 15411663Smckusick break; 15511663Smckusick } 15611663Smckusick /* for each Klingon, give the course & distance */ 15711663Smckusick for (i = 0; i < Etc.nkling; i++) 15811663Smckusick { 15911663Smckusick printf("Klingon at %d,%d", Etc.klingon[i].x, Etc.klingon[i].y); 16011663Smckusick course = kalc(Ship.quadx, Ship.quady, Etc.klingon[i].x, Etc.klingon[i].y, &dist); 16111663Smckusick prkalc(course, dist); 16211663Smckusick } 16311663Smckusick break; 16411663Smckusick 16511663Smckusick case 3: /* course calculation */ 16611663Smckusick if (readdelim('/')) 16711663Smckusick { 16811663Smckusick tqx = Ship.quadx; 16911663Smckusick tqy = Ship.quady; 17011663Smckusick } 17111663Smckusick else 17211663Smckusick { 17311663Smckusick ix = getintpar("Quadrant"); 17411663Smckusick if (ix < 0 || ix >= NSECTS) 17511663Smckusick break; 17611663Smckusick iy = getintpar("q-y"); 17711663Smckusick if (iy < 0 || iy >= NSECTS) 17811663Smckusick break; 17911663Smckusick tqx = ix; 18011663Smckusick tqy = iy; 18111663Smckusick } 18211663Smckusick ix = getintpar("Sector"); 18311663Smckusick if (ix < 0 || ix >= NSECTS) 18411663Smckusick break; 18511663Smckusick iy = getintpar("s-y"); 18611663Smckusick if (iy < 0 || iy >= NSECTS) 18711663Smckusick break; 18811663Smckusick course = kalc(tqx, tqy, ix, iy, &dist); 18911663Smckusick if (r->value2) 19011663Smckusick { 19111663Smckusick warp(-1, course, dist); 19211663Smckusick break; 19311663Smckusick } 19411663Smckusick printf("%d,%d/%d,%d to %d,%d/%d,%d", 19511663Smckusick Ship.quadx, Ship.quady, Ship.sectx, Ship.secty, tqx, tqy, ix, iy); 19611663Smckusick prkalc(course, dist); 19711663Smckusick break; 19811663Smckusick 19911663Smckusick case 4: /* score */ 20011663Smckusick score(); 20111663Smckusick break; 20211663Smckusick 20311663Smckusick case 5: /* phaser effectiveness */ 20411663Smckusick dist = getfltpar("range"); 20511663Smckusick if (dist < 0.0) 20611663Smckusick break; 20712737Slayer dist *= 10.0; 20811663Smckusick cost = pow(0.90, dist) * 98.0 + 0.5; 20911663Smckusick printf("Phasers are %d%% effective at that range\n", cost); 21011663Smckusick break; 21111663Smckusick 21211663Smckusick case 6: /* warp cost (time/energy) */ 21311663Smckusick dist = getfltpar("distance"); 21411663Smckusick if (dist < 0.0) 21511663Smckusick break; 21611663Smckusick warpfact = getfltpar("warp factor"); 21711663Smckusick if (warpfact <= 0.0) 21811663Smckusick warpfact = Ship.warp; 21911663Smckusick cost = (dist + 0.05) * warpfact * warpfact * warpfact; 22011663Smckusick time = Param.warptime * dist / (warpfact * warpfact); 22111663Smckusick printf("Warp %.2f distance %.2f cost %.2f stardates %d (%d w/ shlds up) units\n", 22211663Smckusick warpfact, dist, time, cost, cost + cost); 22311663Smckusick break; 22411663Smckusick 22511663Smckusick case 7: /* impulse cost */ 22611663Smckusick dist = getfltpar("distance"); 22711663Smckusick if (dist < 0.0) 22811663Smckusick break; 22911663Smckusick cost = 20 + 100 * dist; 23011663Smckusick time = dist / 0.095; 23111663Smckusick printf("Distance %.2f cost %.2f stardates %d units\n", 23211663Smckusick dist, time, cost); 23311663Smckusick break; 23411663Smckusick 23511663Smckusick case 8: /* distresslist */ 23611663Smckusick j = 1; 23711663Smckusick printf("\n"); 23811663Smckusick /* scan the event list */ 23911663Smckusick for (i = 0; i < MAXEVENTS; i++) 24011663Smckusick { 24111663Smckusick e = &Event[i]; 24211663Smckusick /* ignore hidden entries */ 24311663Smckusick if (e->evcode & E_HIDDEN) 24411663Smckusick continue; 24511663Smckusick switch (e->evcode & E_EVENT) 24611663Smckusick { 24711663Smckusick 24811663Smckusick case E_KDESB: 24911663Smckusick printf("Klingon is attacking starbase in quadrant %d,%d\n", 25011663Smckusick e->x, e->y); 25111663Smckusick j = 0; 25211663Smckusick break; 25311663Smckusick 25411663Smckusick case E_ENSLV: 25511663Smckusick case E_REPRO: 25611663Smckusick printf("Starsystem %s in quadrant %d,%d is distressed\n", 257*38205Sbostic Systemname[e->systemname], e->x, e->y); 25811663Smckusick j = 0; 25911663Smckusick break; 26011663Smckusick } 26111663Smckusick } 26211663Smckusick if (j) 26311663Smckusick printf("No known distress calls are active\n"); 26411663Smckusick break; 26511663Smckusick 26611663Smckusick } 26711663Smckusick 26811663Smckusick /* skip to next semicolon or newline. Semicolon 26911663Smckusick * means get new computer request; newline means 27011663Smckusick * exit computer mode. */ 27111663Smckusick while ((i = cgetc(0)) != ';') 27211663Smckusick { 27311663Smckusick if (i == '\0') 27411663Smckusick exit(1); 27511663Smckusick if (i == '\n') 27611663Smckusick { 27712737Slayer ungetc(i, stdin); 27811663Smckusick return; 27911663Smckusick } 28011663Smckusick } 28111663Smckusick } 28211663Smckusick } 28311663Smckusick 28411663Smckusick 28511663Smckusick /* 28611663Smckusick ** Course Calculation 28711663Smckusick ** 28811663Smckusick ** Computes and outputs the course and distance from position 28911663Smckusick ** sqx,sqy/ssx,ssy to tqx,tqy/tsx,tsy. 29011663Smckusick */ 29111663Smckusick 29211663Smckusick kalc(tqx, tqy, tsx, tsy, dist) 29311663Smckusick int tqx; 29411663Smckusick int tqy; 29511663Smckusick int tsx; 29611663Smckusick int tsy; 29712737Slayer double *dist; 29811663Smckusick { 29911663Smckusick double dx, dy; 30012737Slayer double quadsize; 30111663Smckusick double angle; 30211663Smckusick register int course; 30311663Smckusick 30411663Smckusick /* normalize to quadrant distances */ 30511663Smckusick quadsize = NSECTS; 30611663Smckusick dx = (Ship.quadx + Ship.sectx / quadsize) - (tqx + tsx / quadsize); 30711663Smckusick dy = (tqy + tsy / quadsize) - (Ship.quady + Ship.secty / quadsize); 30811663Smckusick 30911663Smckusick /* get the angle */ 31011663Smckusick angle = atan2(dy, dx); 31111663Smckusick /* make it 0 -> 2 pi */ 31211663Smckusick if (angle < 0.0) 31312737Slayer angle += 6.283185307; 31411663Smckusick /* convert from radians to degrees */ 31511663Smckusick course = angle * 57.29577951 + 0.5; 31611663Smckusick dx = dx * dx + dy * dy; 31711663Smckusick *dist = sqrt(dx); 31811663Smckusick return (course); 31911663Smckusick } 32011663Smckusick 32111663Smckusick 32211663Smckusick prkalc(course, dist) 32311663Smckusick int course; 32412737Slayer double dist; 32511663Smckusick { 32611663Smckusick printf(": course %d dist %.3f\n", course, dist); 32711663Smckusick } 328