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