2 * Elite - The New Kind.
4 * Reverse engineered from the BBC disk version of Elite.
5 * Additional material by C.J.Pinder.
7 * The original Elite code is (C) I.Bell & D.Braben 1984.
8 * This version re-engineered in C by C.J.Pinder 1999-2001.
10 * email: <christian@newkind.co.uk>
18 * The auto-pilot code. Used for docking computers and for
19 * flying other ships to and from the space station.
23 * In the original Elite this code was mixed in with the tactics routines.
24 * I have split it out to make it more understandable and easier to maintain.
42 * Fly to a given point in space.
45 void fly_to_vector (struct univ_object *ship, Vector vec)
58 nvec = unit_vector(&vec);
59 direction = vector_dot_product (&nvec, &ship->rotmat[2]);
61 if (direction < -0.6666)
64 dir = vector_dot_product (&nvec, &ship->rotmat[1]);
66 if (direction < -0.861)
68 ship->rotx = (dir < 0) ? 7 : -7;
75 if ((fabs(dir) * 2) >= rat2)
77 ship->rotx = (dir < 0) ? rat : -rat;
80 if (abs(ship->rotz) < 16)
82 dir = vector_dot_product (&nvec, &ship->rotmat[0]);
86 if ((fabs(dir) * 2) >= rat2)
88 ship->rotz = (dir < 0) ? rat : -rat;
91 ship->rotz = -ship->rotz;
95 if (direction <= -0.167)
97 ship->acceleration = -1;
101 if (direction >= cnt2)
103 ship->acceleration = 3;
111 * Fly towards the planet.
114 void fly_to_planet (struct univ_object *ship)
118 vec.x = universe[0].location.x - ship->location.x;
119 vec.y = universe[0].location.y - ship->location.y;
120 vec.z = universe[0].location.z - ship->location.z;
122 fly_to_vector (ship, vec);
127 * Fly to a point in front of the station docking bay.
128 * Done prior to the final stage of docking.
132 void fly_to_station_front (struct univ_object *ship)
136 vec.x = universe[1].location.x - ship->location.x;
137 vec.y = universe[1].location.y - ship->location.y;
138 vec.z = universe[1].location.z - ship->location.z;
140 vec.x += universe[1].rotmat[2].x * 768;
141 vec.y += universe[1].rotmat[2].y * 768;
142 vec.z += universe[1].rotmat[2].z * 768;
144 fly_to_vector (ship, vec);
149 * Fly towards the space station.
152 void fly_to_station (struct univ_object *ship)
156 vec.x = universe[1].location.x - ship->location.x;
157 vec.y = universe[1].location.y - ship->location.y;
158 vec.z = universe[1].location.z - ship->location.z;
160 fly_to_vector (ship, vec);
165 * Final stage of docking.
166 * Fly into the docking bay.
169 void fly_to_docking_bay (struct univ_object *ship)
175 diff.x = ship->location.x - universe[1].location.x;
176 diff.y = ship->location.y - universe[1].location.y;
177 diff.z = ship->location.z - universe[1].location.z;
179 vec = unit_vector (&diff);
186 if (((vec.x >= 0) && (vec.y >= 0)) ||
187 ((vec.x < 0) && (vec.y < 0)))
189 ship->rotz = -ship->rotz;
192 if (fabs(vec.x) >= 0.0625)
194 ship->acceleration = 0;
199 if (fabs(vec.y) > 0.002436)
200 ship->rotx = (vec.y < 0) ? -1 : 1;
202 if (fabs(vec.y) >= 0.0625)
204 ship->acceleration = 0;
212 dir = vector_dot_product (&ship->rotmat[0], &universe[1].rotmat[1]);
214 if (fabs(dir) >= 0.9166)
216 ship->acceleration++;
221 ship->acceleration = 0;
227 * Fly a ship to the planet or to the space station and dock it.
230 void auto_pilot_ship (struct univ_object *ship)
237 if ((ship->flags & FLG_FLY_TO_PLANET) ||
238 ((ship_count[SHIP_CORIOLIS] == 0) && (ship_count[SHIP_DODEC] == 0)))
240 fly_to_planet (ship);
244 diff.x = ship->location.x - universe[1].location.x;
245 diff.y = ship->location.y - universe[1].location.y;
246 diff.z = ship->location.z - universe[1].location.z;
248 dist = sqrt (diff.x * diff.x + diff.y * diff.y + diff.z * diff.z);
252 ship->flags |= FLG_REMOVE; // Ship has docked.
256 vec = unit_vector (&diff);
257 dir = vector_dot_product (&universe[1].rotmat[2], &vec);
261 fly_to_station_front (ship);
265 dir = vector_dot_product (&ship->rotmat[2], &vec);
269 fly_to_docking_bay (ship);
273 fly_to_station (ship);
277 void engage_auto_pilot (void)
279 if (auto_pilot || witchspace || hyper_ready)
283 snd_play_midi (SND_BLUE_DANUBE, 1);
287 void disengage_auto_pilot (void)