125989Smckusick /*
2*60857Sbostic * Copyright (c) 1980, 1993
3*60857Sbostic * The Regents of the University of California. All rights reserved.
434205Sbostic *
542605Sbostic * %sccs.include.redist.c%
625989Smckusick */
725989Smckusick
811663Smckusick #ifndef lint
9*60857Sbostic static char sccsid[] = "@(#)computer.c 8.1 (Berkeley) 05/31/93";
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
computer()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
kalc(tqx,tqy,tsx,tsy,dist)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
prkalc(course,dist)31211663Smckusick prkalc(course, dist)
31311663Smckusick int course;
31412737Slayer double dist;
31511663Smckusick {
31611663Smckusick printf(": course %d dist %.3f\n", course, dist);
31711663Smckusick }
318