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)