xref: /original-bsd/games/trek/move.c (revision 7cab520e)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)move.c	5.3 (Berkeley) 06/18/88";
20 #endif /* not lint */
21 
22 # include	"trek.h"
23 
24 /*
25 **  Move Under Warp or Impulse Power
26 **
27 **	`Ramflag' is set if we are to be allowed to ram stars,
28 **	Klingons, etc.  This is passed from warp(), which gets it from
29 **	either play() or ram().  Course is the course (0 -> 360) at
30 **	which we want to move.  `Speed' is the speed we
31 **	want to go, and `time' is the expected time.  It
32 **	can get cut short if a long range tractor beam is to occur.  We
33 **	cut short the move so that the user doesn't get docked time and
34 **	energy for distance which he didn't travel.
35 **
36 **	We check the course through the current quadrant to see that he
37 **	doesn't run into anything.  After that, though, space sort of
38 **	bends around him.  Note that this puts us in the awkward posi-
39 **	tion of being able to be dropped into a sector which is com-
40 **	pletely surrounded by stars.  Oh Well.
41 **
42 **	If the SINS (Space Inertial Navigation System) is out, we ran-
43 **	domize the course accordingly before ever starting to move.
44 **	We will still move in a straight line.
45 **
46 **	Note that if your computer is out, you ram things anyway.  In
47 **	other words, if your computer and sins are both out, you're in
48 **	potentially very bad shape.
49 **
50 **	Klingons get a chance to zap you as you leave the quadrant.
51 **	By the way, they also try to follow you (heh heh).
52 **
53 **	Return value is the actual amount of time used.
54 **
55 **
56 **	Uses trace flag 4.
57 */
58 
59 double move(ramflag, course, time, speed)
60 int	ramflag;
61 int	course;
62 double	time;
63 double	speed;
64 {
65 	double			angle;
66 	double			x, y, dx, dy;
67 	register int		ix, iy;
68 	double			bigger;
69 	int			n;
70 	register int		i;
71 	double			dist;
72 	double			sectsize;
73 	double			xn;
74 	double			evtime;
75 
76 #	ifdef xTRACE
77 	if (Trace)
78 		printf("move: ramflag %d course %d time %.2f speed %.2f\n",
79 			ramflag, course, time, speed);
80 #	endif
81 	sectsize = NSECTS;
82 	/* initialize delta factors for move */
83 	angle = course * 0.0174532925;
84 	if (damaged(SINS))
85 		angle += Param.navigcrud[1] * (franf() - 0.5);
86 	else
87 		if (Ship.sinsbad)
88 			angle += Param.navigcrud[0] * (franf() - 0.5);
89 	dx = -cos(angle);
90 	dy = sin(angle);
91 	bigger = fabs(dx);
92 	dist = fabs(dy);
93 	if (dist > bigger)
94 		bigger = dist;
95 	dx /= bigger;
96 	dy /= bigger;
97 
98 	/* check for long range tractor beams */
99 	/****  TEMPORARY CODE == DEBUGGING  ****/
100 	evtime = Now.eventptr[E_LRTB]->date - Now.date;
101 #	ifdef xTRACE
102 	if (Trace)
103 		printf("E.ep = %u, ->evcode = %d, ->date = %.2f, evtime = %.2f\n",
104 			Now.eventptr[E_LRTB], Now.eventptr[E_LRTB]->evcode,
105 			Now.eventptr[E_LRTB]->date, evtime);
106 #	endif
107 	if (time > evtime && Etc.nkling < 3)
108 	{
109 		/* then we got a LRTB */
110 		evtime += 0.005;
111 		time = evtime;
112 	}
113 	else
114 		evtime = -1.0e50;
115 	dist = time * speed;
116 
117 	/* move within quadrant */
118 	Sect[Ship.sectx][Ship.secty] = EMPTY;
119 	x = Ship.sectx + 0.5;
120 	y = Ship.secty + 0.5;
121 	xn = NSECTS * dist * bigger;
122 	n = xn + 0.5;
123 #	ifdef xTRACE
124 	if (Trace)
125 		printf("dx = %.2f, dy = %.2f, xn = %.2f, n = %d\n", dx, dy, xn, n);
126 #	endif
127 	Move.free = 0;
128 
129 	for (i = 0; i < n; i++)
130 	{
131 		ix = (x += dx);
132 		iy = (y += dy);
133 #		ifdef xTRACE
134 		if (Trace)
135 			printf("ix = %d, x = %.2f, iy = %d, y = %.2f\n", ix, x, iy, y);
136 #		endif
137 		if (x < 0.0 || y < 0.0 || x >= sectsize || y >= sectsize)
138 		{
139 			/* enter new quadrant */
140 			dx = Ship.quadx * NSECTS + Ship.sectx + dx * xn;
141 			dy = Ship.quady * NSECTS + Ship.secty + dy * xn;
142 			if (dx < 0.0)
143 				ix = -1;
144 			else
145 				ix = dx + 0.5;
146 			if (dy < 0.0)
147 				iy = -1;
148 			else
149 				iy = dy + 0.5;
150 #			ifdef xTRACE
151 			if (Trace)
152 				printf("New quad: ix = %d, iy = %d\n", ix, iy);
153 #			endif
154 			Ship.sectx = x;
155 			Ship.secty = y;
156 			compkldist(0);
157 			Move.newquad = 2;
158 			attack(0);
159 			checkcond();
160 			Ship.quadx = ix / NSECTS;
161 			Ship.quady = iy / NSECTS;
162 			Ship.sectx = ix % NSECTS;
163 			Ship.secty = iy % NSECTS;
164 			if (ix < 0 || Ship.quadx >= NQUADS || iy < 0 || Ship.quady >= NQUADS)
165 				if (!damaged(COMPUTER))
166 				{
167 					dumpme(0);
168 				}
169 				else
170 					lose(L_NEGENB);
171 			initquad(0);
172 			n = 0;
173 			break;
174 		}
175 		if (Sect[ix][iy] != EMPTY)
176 		{
177 			/* we just hit something */
178 			if (!damaged(COMPUTER) && ramflag <= 0)
179 			{
180 				ix = x - dx;
181 				iy = y - dy;
182 				printf("Computer reports navigation error; %s stopped at %d,%d\n",
183 					Ship.shipname, ix, iy);
184 				Ship.energy -= Param.stopengy * speed;
185 				break;
186 			}
187 			/* test for a black hole */
188 			if (Sect[ix][iy] == HOLE)
189 			{
190 				/* get dumped elsewhere in the galaxy */
191 				dumpme(1);
192 				initquad(0);
193 				n = 0;
194 				break;
195 			}
196 			ram(ix, iy);
197 			break;
198 		}
199 	}
200 	if (n > 0)
201 	{
202 		dx = Ship.sectx - ix;
203 		dy = Ship.secty - iy;
204 		dist = sqrt(dx * dx + dy * dy) / NSECTS;
205 		time = dist / speed;
206 		if (evtime > time)
207 			time = evtime;		/* spring the LRTB trap */
208 		Ship.sectx = ix;
209 		Ship.secty = iy;
210 	}
211 	Sect[Ship.sectx][Ship.secty] = Ship.ship;
212 	compkldist(0);
213 	return (time);
214 }
215