xref: /csrg-svn/games/trek/computer.c (revision 11663)
1*11663Smckusick #ifndef lint
2*11663Smckusick static char sccsid[] = "@(#)computer.c	4.1	(Berkeley)	03/23/83";
3*11663Smckusick #endif not lint
4*11663Smckusick 
5*11663Smckusick # include	"trek.h"
6*11663Smckusick # include	"getpar.h"
7*11663Smckusick 
8*11663Smckusick /*
9*11663Smckusick **  On-Board Computer
10*11663Smckusick **
11*11663Smckusick **	A computer request is fetched from the captain.  The requests
12*11663Smckusick **	are:
13*11663Smckusick **
14*11663Smckusick **	chart -- print a star chart of the known galaxy.  This includes
15*11663Smckusick **		every quadrant that has ever had a long range or
16*11663Smckusick **		a short range scan done of it, plus the location of
17*11663Smckusick **		all starbases.  This is of course updated by any sub-
18*11663Smckusick **		space radio broadcasts (unless the radio is out).
19*11663Smckusick **		The format is the same as that of a long range scan
20*11663Smckusick **		except that ".1." indicates that a starbase exists
21*11663Smckusick **		but we know nothing else.
22*11663Smckusick **
23*11663Smckusick **	trajectory -- gives the course and distance to every know
24*11663Smckusick **		Klingon in the quadrant.  Obviously this fails if the
25*11663Smckusick **		short range scanners are out.
26*11663Smckusick **
27*11663Smckusick **	course -- gives a course computation from whereever you are
28*11663Smckusick **		to any specified location.  If the course begins
29*11663Smckusick **		with a slash, the current quadrant is taken.
30*11663Smckusick **		Otherwise the input is quadrant and sector coordi-
31*11663Smckusick **		nates of the target sector.
32*11663Smckusick **
33*11663Smckusick **	move -- identical to course, except that the move is performed.
34*11663Smckusick **
35*11663Smckusick **	score -- prints out the current score.
36*11663Smckusick **
37*11663Smckusick **	pheff -- "PHaser EFFectiveness" at a given distance.  Tells
38*11663Smckusick **		you how much stuff you need to make it work.
39*11663Smckusick **
40*11663Smckusick **	warpcost -- Gives you the cost in time and units to move for
41*11663Smckusick **		a given distance under a given warp speed.
42*11663Smckusick **
43*11663Smckusick **	impcost -- Same for the impulse engines.
44*11663Smckusick **
45*11663Smckusick **	distresslist -- Gives a list of the currently known starsystems
46*11663Smckusick **		or starbases which are distressed, together with their
47*11663Smckusick **		quadrant coordinates.
48*11663Smckusick **
49*11663Smckusick **	If a command is terminated with a semicolon, you remain in
50*11663Smckusick **	the computer; otherwise, you escape immediately to the main
51*11663Smckusick **	command processor.
52*11663Smckusick */
53*11663Smckusick 
54*11663Smckusick struct cvntab	Cputab[]
55*11663Smckusick {
56*11663Smckusick 	"ch",			"art",			1,		0,
57*11663Smckusick 	"t",			"rajectory",		2,		0,
58*11663Smckusick 	"c",			"ourse",		3,		0,
59*11663Smckusick 	"m",			"ove",			3,		1,
60*11663Smckusick 	"s",			"core",			4,		0,
61*11663Smckusick 	"p",			"heff",			5,		0,
62*11663Smckusick 	"w",			"arpcost",		6,		0,
63*11663Smckusick 	"i",			"mpcost",		7,		0,
64*11663Smckusick 	"d",			"istresslist",		8,		0,
65*11663Smckusick 	0
66*11663Smckusick };
67*11663Smckusick 
68*11663Smckusick computer()
69*11663Smckusick {
70*11663Smckusick 	int			ix, iy;
71*11663Smckusick 	register int		i, j;
72*11663Smckusick 	int			numout;
73*11663Smckusick 	int			tqx, tqy;
74*11663Smckusick 	struct cvntab		*r;
75*11663Smckusick 	int			cost;
76*11663Smckusick 	int			course;
77*11663Smckusick 	float			dist, time;
78*11663Smckusick 	float			warpfact;
79*11663Smckusick 	struct quad		*q;
80*11663Smckusick 	register struct event	*e;
81*11663Smckusick 
82*11663Smckusick 	if (check_out(COMPUTER))
83*11663Smckusick 		return;
84*11663Smckusick 	while (1)
85*11663Smckusick 	{
86*11663Smckusick 		r = getcodpar("\nRequest", Cputab);
87*11663Smckusick 		switch (r->value)
88*11663Smckusick 		{
89*11663Smckusick 
90*11663Smckusick 		  case 1:			/* star chart */
91*11663Smckusick 			printf("Computer record of galaxy for all long range sensor scans\n\n");
92*11663Smckusick 			printf("  ");
93*11663Smckusick 			/* print top header */
94*11663Smckusick 			for (i = 0; i < NQUADS; i++)
95*11663Smckusick 				printf("-%d- ", i);
96*11663Smckusick 			printf("\n");
97*11663Smckusick 			for (i = 0; i < NQUADS; i++)
98*11663Smckusick 			{
99*11663Smckusick 				printf("%d ", i);
100*11663Smckusick 				for (j = 0; j < NQUADS; j++)
101*11663Smckusick 				{
102*11663Smckusick 					if (i == Ship.quadx && j == Ship.quady)
103*11663Smckusick 					{
104*11663Smckusick 						printf("$$$ ");
105*11663Smckusick 						continue;
106*11663Smckusick 					}
107*11663Smckusick 					q = &Quad[i][j];
108*11663Smckusick 					/* 1000 or 1001 is special case */
109*11663Smckusick 					if (q->scanned >= 1000)
110*11663Smckusick 						if (q->scanned > 1000)
111*11663Smckusick 							printf(".1. ");
112*11663Smckusick 						else
113*11663Smckusick 							printf("/// ");
114*11663Smckusick 					else
115*11663Smckusick 						if (q->scanned < 0)
116*11663Smckusick 							printf("... ");
117*11663Smckusick 						else
118*11663Smckusick 							printf("%3d ", q->scanned);
119*11663Smckusick 				}
120*11663Smckusick 				printf("%d\n", i);
121*11663Smckusick 			}
122*11663Smckusick 			printf("  ");
123*11663Smckusick 			/* print bottom footer */
124*11663Smckusick 			for (i = 0; i < NQUADS; i++)
125*11663Smckusick 				printf("-%d- ", i);
126*11663Smckusick 			printf("\n");
127*11663Smckusick 			break;
128*11663Smckusick 
129*11663Smckusick 		  case 2:			/* trajectory */
130*11663Smckusick 			if (check_out(SRSCAN))
131*11663Smckusick 			{
132*11663Smckusick 				break;
133*11663Smckusick 			}
134*11663Smckusick 			if (Etc.nkling <= 0)
135*11663Smckusick 			{
136*11663Smckusick 				printf("No Klingons in this quadrant\n");
137*11663Smckusick 				break;
138*11663Smckusick 			}
139*11663Smckusick 			/* for each Klingon, give the course & distance */
140*11663Smckusick 			for (i = 0; i < Etc.nkling; i++)
141*11663Smckusick 			{
142*11663Smckusick 				printf("Klingon at %d,%d", Etc.klingon[i].x, Etc.klingon[i].y);
143*11663Smckusick 				course = kalc(Ship.quadx, Ship.quady, Etc.klingon[i].x, Etc.klingon[i].y, &dist);
144*11663Smckusick 				prkalc(course, dist);
145*11663Smckusick 			}
146*11663Smckusick 			break;
147*11663Smckusick 
148*11663Smckusick 		  case 3:			/* course calculation */
149*11663Smckusick 			if (readdelim('/'))
150*11663Smckusick 			{
151*11663Smckusick 				tqx = Ship.quadx;
152*11663Smckusick 				tqy = Ship.quady;
153*11663Smckusick 			}
154*11663Smckusick 			else
155*11663Smckusick 			{
156*11663Smckusick 				ix = getintpar("Quadrant");
157*11663Smckusick 				if (ix < 0 || ix >= NSECTS)
158*11663Smckusick 					break;
159*11663Smckusick 				iy = getintpar("q-y");
160*11663Smckusick 				if (iy < 0 || iy >= NSECTS)
161*11663Smckusick 					break;
162*11663Smckusick 				tqx = ix;
163*11663Smckusick 				tqy = iy;
164*11663Smckusick 			}
165*11663Smckusick 			ix = getintpar("Sector");
166*11663Smckusick 			if (ix < 0 || ix >= NSECTS)
167*11663Smckusick 				break;
168*11663Smckusick 			iy = getintpar("s-y");
169*11663Smckusick 			if (iy < 0 || iy >= NSECTS)
170*11663Smckusick 				break;
171*11663Smckusick 			course = kalc(tqx, tqy, ix, iy, &dist);
172*11663Smckusick 			if (r->value2)
173*11663Smckusick 			{
174*11663Smckusick 				warp(-1, course, dist);
175*11663Smckusick 				break;
176*11663Smckusick 			}
177*11663Smckusick 			printf("%d,%d/%d,%d to %d,%d/%d,%d",
178*11663Smckusick 				Ship.quadx, Ship.quady, Ship.sectx, Ship.secty, tqx, tqy, ix, iy);
179*11663Smckusick 			prkalc(course, dist);
180*11663Smckusick 			break;
181*11663Smckusick 
182*11663Smckusick 		  case 4:			/* score */
183*11663Smckusick 			score();
184*11663Smckusick 			break;
185*11663Smckusick 
186*11663Smckusick 		  case 5:			/* phaser effectiveness */
187*11663Smckusick 			dist = getfltpar("range");
188*11663Smckusick 			if (dist < 0.0)
189*11663Smckusick 				break;
190*11663Smckusick 			dist =* 10.0;
191*11663Smckusick 			cost = pow(0.90, dist) * 98.0 + 0.5;
192*11663Smckusick 			printf("Phasers are %d%% effective at that range\n", cost);
193*11663Smckusick 			break;
194*11663Smckusick 
195*11663Smckusick 		  case 6:			/* warp cost (time/energy) */
196*11663Smckusick 			dist = getfltpar("distance");
197*11663Smckusick 			if (dist < 0.0)
198*11663Smckusick 				break;
199*11663Smckusick 			warpfact = getfltpar("warp factor");
200*11663Smckusick 			if (warpfact <= 0.0)
201*11663Smckusick 				warpfact = Ship.warp;
202*11663Smckusick 			cost = (dist + 0.05) * warpfact * warpfact * warpfact;
203*11663Smckusick 			time = Param.warptime * dist / (warpfact * warpfact);
204*11663Smckusick 			printf("Warp %.2f distance %.2f cost %.2f stardates %d (%d w/ shlds up) units\n",
205*11663Smckusick 				warpfact, dist, time, cost, cost + cost);
206*11663Smckusick 			break;
207*11663Smckusick 
208*11663Smckusick 		  case 7:			/* impulse cost */
209*11663Smckusick 			dist = getfltpar("distance");
210*11663Smckusick 			if (dist < 0.0)
211*11663Smckusick 				break;
212*11663Smckusick 			cost = 20 + 100 * dist;
213*11663Smckusick 			time = dist / 0.095;
214*11663Smckusick 			printf("Distance %.2f cost %.2f stardates %d units\n",
215*11663Smckusick 				dist, time, cost);
216*11663Smckusick 			break;
217*11663Smckusick 
218*11663Smckusick 		  case 8:			/* distresslist */
219*11663Smckusick 			j = 1;
220*11663Smckusick 			printf("\n");
221*11663Smckusick 			/* scan the event list */
222*11663Smckusick 			for (i = 0; i < MAXEVENTS; i++)
223*11663Smckusick 			{
224*11663Smckusick 				e = &Event[i];
225*11663Smckusick 				/* ignore hidden entries */
226*11663Smckusick 				if (e->evcode & E_HIDDEN)
227*11663Smckusick 					continue;
228*11663Smckusick 				switch (e->evcode & E_EVENT)
229*11663Smckusick 				{
230*11663Smckusick 
231*11663Smckusick 				  case E_KDESB:
232*11663Smckusick 					printf("Klingon is attacking starbase in quadrant %d,%d\n",
233*11663Smckusick 						e->x, e->y);
234*11663Smckusick 					j = 0;
235*11663Smckusick 					break;
236*11663Smckusick 
237*11663Smckusick 				  case E_ENSLV:
238*11663Smckusick 				  case E_REPRO:
239*11663Smckusick 					printf("Starsystem %s in quadrant %d,%d is distressed\n",
240*11663Smckusick 						systemname(e), e->x, e->y);
241*11663Smckusick 					j = 0;
242*11663Smckusick 					break;
243*11663Smckusick 				}
244*11663Smckusick 			}
245*11663Smckusick 			if (j)
246*11663Smckusick 				printf("No known distress calls are active\n");
247*11663Smckusick 			break;
248*11663Smckusick 
249*11663Smckusick 		}
250*11663Smckusick 
251*11663Smckusick 		/* skip to next semicolon or newline.  Semicolon
252*11663Smckusick 		 * means get new computer request; newline means
253*11663Smckusick 		 * exit computer mode. */
254*11663Smckusick 		while ((i = cgetc(0)) != ';')
255*11663Smckusick 		{
256*11663Smckusick 			if (i == '\0')
257*11663Smckusick 				exit(1);
258*11663Smckusick 			if (i == '\n')
259*11663Smckusick 			{
260*11663Smckusick 				ungetc(i, 0);
261*11663Smckusick 				return;
262*11663Smckusick 			}
263*11663Smckusick 		}
264*11663Smckusick 	}
265*11663Smckusick }
266*11663Smckusick 
267*11663Smckusick 
268*11663Smckusick /*
269*11663Smckusick **  Course Calculation
270*11663Smckusick **
271*11663Smckusick **	Computes and outputs the course and distance from position
272*11663Smckusick **	sqx,sqy/ssx,ssy to tqx,tqy/tsx,tsy.
273*11663Smckusick */
274*11663Smckusick 
275*11663Smckusick kalc(tqx, tqy, tsx, tsy, dist)
276*11663Smckusick int	tqx;
277*11663Smckusick int	tqy;
278*11663Smckusick int	tsx;
279*11663Smckusick int	tsy;
280*11663Smckusick float	*dist;
281*11663Smckusick {
282*11663Smckusick 	double			dx, dy;
283*11663Smckusick 	float			quadsize;
284*11663Smckusick 	double			angle;
285*11663Smckusick 	register int		course;
286*11663Smckusick 
287*11663Smckusick 	/* normalize to quadrant distances */
288*11663Smckusick 	quadsize = NSECTS;
289*11663Smckusick 	dx = (Ship.quadx + Ship.sectx / quadsize) - (tqx + tsx / quadsize);
290*11663Smckusick 	dy = (tqy + tsy / quadsize) - (Ship.quady + Ship.secty / quadsize);
291*11663Smckusick 
292*11663Smckusick 	/* get the angle */
293*11663Smckusick 	angle = atan2(dy, dx);
294*11663Smckusick 	/* make it 0 -> 2 pi */
295*11663Smckusick 	if (angle < 0.0)
296*11663Smckusick 		angle =+ 6.283185307;
297*11663Smckusick 	/* convert from radians to degrees */
298*11663Smckusick 	course = angle * 57.29577951 + 0.5;
299*11663Smckusick 	dx = dx * dx + dy * dy;
300*11663Smckusick 	*dist = sqrt(dx);
301*11663Smckusick 	return (course);
302*11663Smckusick }
303*11663Smckusick 
304*11663Smckusick 
305*11663Smckusick prkalc(course, dist)
306*11663Smckusick int	course;
307*11663Smckusick float	dist;
308*11663Smckusick {
309*11663Smckusick 	printf(": course %d  dist %.3f\n", course, dist);
310*11663Smckusick }
311