OSDN Git Service

全て日本語訳
[starfighter-jp/starfighter-jp.git] / src / alien.cpp
1 /*
2 Copyright (C) 2003 Parallel Realities
3 Copyright (C) 2011, 2012 Guus Sliepen
4 Copyright (C) 2012, 2015 Julian Marchant
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 3
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "Starfighter.h"
21
22 object alien_defs[CD_MAX];
23 object aliens[ALIEN_MAX];
24
25 /*
26 This simply pulls back an alien from the array that is
27 "dead" (no shield) and returns the index number so we can have
28 a new one.
29 */
30 static int alien_getFreeIndex()
31 {
32         for (int i = 0 ; i < engine.maxAliens ; i++)
33         {
34                 if (!aliens[i].active)
35                 {
36                         return i;
37                 }
38         }
39
40         return -1;
41 }
42
43 void alien_defs_init()
44 {
45         // Dual Plasma Fighter.
46         alien_defs[CD_DUALFIGHTER].classDef = CD_DUALFIGHTER;
47         alien_defs[CD_DUALFIGHTER].AIType = AI_NORMAL;
48         alien_defs[CD_DUALFIGHTER].speed = 4;
49         alien_defs[CD_DUALFIGHTER].maxShield = 5;
50         alien_defs[CD_DUALFIGHTER].shield = 5;
51         alien_defs[CD_DUALFIGHTER].imageIndex[0] = 2;
52         alien_defs[CD_DUALFIGHTER].imageIndex[1] = 3;
53         alien_defs[CD_DUALFIGHTER].weaponType[0] = W_DOUBLE_SHOT;
54         alien_defs[CD_DUALFIGHTER].weaponType[1] = W_ROCKETS;
55         alien_defs[CD_DUALFIGHTER].chance[0] = 100;
56         alien_defs[CD_DUALFIGHTER].chance[1] = 1;
57         alien_defs[CD_DUALFIGHTER].collectChance = 50;
58         alien_defs[CD_DUALFIGHTER].collectType = P_ANYTHING;
59         alien_defs[CD_DUALFIGHTER].collectValue = 50;
60         alien_defs[CD_DUALFIGHTER].flags = FL_WEAPCO;
61
62         // Missile Boat
63         alien_defs[CD_MISSILEBOAT].classDef = CD_MISSILEBOAT;
64         alien_defs[CD_MISSILEBOAT].AIType = AI_DEFENSIVE;
65         alien_defs[CD_MISSILEBOAT].speed = 2;
66         alien_defs[CD_MISSILEBOAT].maxShield = 50;
67         alien_defs[CD_MISSILEBOAT].shield = 50;
68         alien_defs[CD_MISSILEBOAT].imageIndex[0] = 4;
69         alien_defs[CD_MISSILEBOAT].imageIndex[1] = 5;
70         alien_defs[CD_MISSILEBOAT].weaponType[0] = W_ROCKETS;
71         alien_defs[CD_MISSILEBOAT].weaponType[1] = W_DOUBLE_ROCKETS;
72         alien_defs[CD_MISSILEBOAT].chance[0] = 25;
73         alien_defs[CD_MISSILEBOAT].chance[1] = 4;
74         alien_defs[CD_MISSILEBOAT].collectChance = 25;
75         alien_defs[CD_MISSILEBOAT].collectType = P_ANYTHING;
76         alien_defs[CD_MISSILEBOAT].collectValue = 75;
77         alien_defs[CD_MISSILEBOAT].flags = FL_WEAPCO;
78
79         //Prototype fighter
80         alien_defs[CD_PROTOFIGHTER].classDef = CD_PROTOFIGHTER;
81         alien_defs[CD_PROTOFIGHTER].AIType = AI_DEFENSIVE;
82         alien_defs[CD_PROTOFIGHTER].speed = 5;
83         alien_defs[CD_PROTOFIGHTER].maxShield = 15;
84         alien_defs[CD_PROTOFIGHTER].shield = 15;
85         alien_defs[CD_PROTOFIGHTER].imageIndex[0] = 6;
86         alien_defs[CD_PROTOFIGHTER].imageIndex[1] = 7;
87         alien_defs[CD_PROTOFIGHTER].weaponType[0] = W_TRIPLE_SHOT;
88         alien_defs[CD_PROTOFIGHTER].weaponType[1] = P_ANYTHING;
89         alien_defs[CD_PROTOFIGHTER].chance[0] = 100;
90         alien_defs[CD_PROTOFIGHTER].chance[1] = 1;
91         alien_defs[CD_PROTOFIGHTER].collectChance = 50;
92         alien_defs[CD_PROTOFIGHTER].collectType = P_ANYTHING;
93         alien_defs[CD_PROTOFIGHTER].collectValue = 50;
94         alien_defs[CD_PROTOFIGHTER].flags = FL_WEAPCO;
95
96         // Phoebe and Ursula
97         alien_defs[CD_FRIEND].classDef = CD_FRIEND;
98         alien_defs[CD_FRIEND].AIType = AI_OFFENSIVE;
99         alien_defs[CD_FRIEND].speed = 3;
100         alien_defs[CD_FRIEND].maxShield = 50;
101         alien_defs[CD_FRIEND].shield = 50;
102         alien_defs[CD_FRIEND].imageIndex[0] = 20;
103         alien_defs[CD_FRIEND].imageIndex[1] = 21;
104         alien_defs[CD_FRIEND].weaponType[0] = W_DOUBLE_SHOT;
105         alien_defs[CD_FRIEND].weaponType[1] = W_HOMING_MISSILE;
106         alien_defs[CD_FRIEND].chance[0] = 100;
107         alien_defs[CD_FRIEND].chance[1] = 5;
108         alien_defs[CD_FRIEND].collectChance = 0;
109         alien_defs[CD_FRIEND].collectType = P_CASH;
110         alien_defs[CD_FRIEND].collectValue = 0;
111         alien_defs[CD_FRIEND].flags = FL_FRIEND;
112
113         // Boss 1
114         alien_defs[CD_FRIGATE].classDef = CD_BOSS;
115         alien_defs[CD_FRIGATE].AIType = AI_NORMAL;
116         alien_defs[CD_FRIGATE].speed = 2;
117         alien_defs[CD_FRIGATE].maxShield = 550;
118         alien_defs[CD_FRIGATE].shield = 550;
119         alien_defs[CD_FRIGATE].imageIndex[0] = 8;
120         alien_defs[CD_FRIGATE].imageIndex[1] = 9;
121         alien_defs[CD_FRIGATE].weaponType[0] = W_MICRO_ROCKETS;
122         alien_defs[CD_FRIGATE].weaponType[1] = W_ENERGYRAY;
123         alien_defs[CD_FRIGATE].chance[0] = 100;
124         alien_defs[CD_FRIGATE].chance[1] = 85;
125         alien_defs[CD_FRIGATE].collectChance = 100;
126         alien_defs[CD_FRIGATE].collectType = P_CASH;
127         alien_defs[CD_FRIGATE].collectValue = 500;
128         alien_defs[CD_FRIGATE].flags = FL_WEAPCO;
129
130         alien_defs[CD_FRIGATE_WING1].classDef = CD_FRIGATE_WING1;
131         alien_defs[CD_FRIGATE_WING1].AIType = AI_NORMAL;
132         alien_defs[CD_FRIGATE_WING1].speed = 2;
133         alien_defs[CD_FRIGATE_WING1].maxShield = 100;
134         alien_defs[CD_FRIGATE_WING1].shield = 100;
135         alien_defs[CD_FRIGATE_WING1].imageIndex[0] = 10;
136         alien_defs[CD_FRIGATE_WING1].imageIndex[1] = 11;
137         alien_defs[CD_FRIGATE_WING1].weaponType[0] = W_TRIPLE_SHOT;
138         alien_defs[CD_FRIGATE_WING1].weaponType[1] = W_ROCKETS;
139         alien_defs[CD_FRIGATE_WING1].chance[0] = 100;
140         alien_defs[CD_FRIGATE_WING1].chance[1] = 10;
141         alien_defs[CD_FRIGATE_WING1].collectChance = 100;
142         alien_defs[CD_FRIGATE_WING1].collectType = P_ANYTHING;
143         alien_defs[CD_FRIGATE_WING1].collectValue = 250;
144         alien_defs[CD_FRIGATE_WING1].flags = FL_WEAPCO | FL_DAMAGEOWNER;
145
146         alien_defs[CD_FRIGATE_WING2].classDef = CD_FRIGATE_WING2;
147         alien_defs[CD_FRIGATE_WING2].AIType = AI_NORMAL;
148         alien_defs[CD_FRIGATE_WING2].speed = 2;
149         alien_defs[CD_FRIGATE_WING2].maxShield = 100;
150         alien_defs[CD_FRIGATE_WING2].shield = 100;
151         alien_defs[CD_FRIGATE_WING2].imageIndex[0] = 12;
152         alien_defs[CD_FRIGATE_WING2].imageIndex[1] = 13;
153         alien_defs[CD_FRIGATE_WING2].weaponType[0] = W_TRIPLE_SHOT;
154         alien_defs[CD_FRIGATE_WING2].weaponType[1] = W_ROCKETS;
155         alien_defs[CD_FRIGATE_WING2].chance[0] = 100;
156         alien_defs[CD_FRIGATE_WING2].chance[1] = 10;
157         alien_defs[CD_FRIGATE_WING2].collectChance = 100;
158         alien_defs[CD_FRIGATE_WING2].collectType = P_ANYTHING;
159         alien_defs[CD_FRIGATE_WING2].collectValue = 250;
160         alien_defs[CD_FRIGATE_WING2].flags = FL_WEAPCO | FL_DAMAGEOWNER;
161
162         // Transport ship
163         alien_defs[CD_TRANSPORTSHIP].classDef = CD_TRANSPORTSHIP;
164         alien_defs[CD_TRANSPORTSHIP].AIType = AI_EVASIVE;
165         alien_defs[CD_TRANSPORTSHIP].speed = 4;
166         alien_defs[CD_TRANSPORTSHIP].maxShield = 10;
167         alien_defs[CD_TRANSPORTSHIP].shield = 10;
168         alien_defs[CD_TRANSPORTSHIP].imageIndex[0] = 14;
169         alien_defs[CD_TRANSPORTSHIP].imageIndex[1] = 15;
170         alien_defs[CD_TRANSPORTSHIP].weaponType[0] = W_DOUBLE_SHOT;
171         alien_defs[CD_TRANSPORTSHIP].weaponType[1] = W_DOUBLE_SHOT;
172         alien_defs[CD_TRANSPORTSHIP].chance[0] = 0;
173         alien_defs[CD_TRANSPORTSHIP].chance[1] = 0;
174         alien_defs[CD_TRANSPORTSHIP].collectChance = 100;
175         alien_defs[CD_TRANSPORTSHIP].collectType = P_WEAPONS;
176         alien_defs[CD_TRANSPORTSHIP].collectValue = 40;
177         alien_defs[CD_TRANSPORTSHIP].flags = FL_WEAPCO | FL_NOFIRE;
178
179         // Cargo ship
180         alien_defs[CD_CARGOSHIP].classDef = CD_CARGOSHIP;
181         alien_defs[CD_CARGOSHIP].AIType = AI_EVASIVE;
182         alien_defs[CD_CARGOSHIP].speed = 4;
183         alien_defs[CD_CARGOSHIP].maxShield = 10;
184         alien_defs[CD_CARGOSHIP].shield = 10;
185         alien_defs[CD_CARGOSHIP].imageIndex[0] = 22;
186         alien_defs[CD_CARGOSHIP].imageIndex[1] = 23;
187         alien_defs[CD_CARGOSHIP].weaponType[0] = W_DOUBLE_SHOT;
188         alien_defs[CD_CARGOSHIP].weaponType[1] = W_DOUBLE_SHOT;
189         alien_defs[CD_CARGOSHIP].chance[0] = 0;
190         alien_defs[CD_CARGOSHIP].chance[1] = 0;
191         alien_defs[CD_CARGOSHIP].collectChance = 50;
192         alien_defs[CD_CARGOSHIP].collectType = P_ANYTHING;
193         alien_defs[CD_CARGOSHIP].collectValue = 100;
194         alien_defs[CD_CARGOSHIP].flags = FL_WEAPCO | FL_NOFIRE;
195
196         // Weapco Miner
197         alien_defs[CD_MINER].classDef = CD_MINER;
198         alien_defs[CD_MINER].AIType = AI_EVASIVE;
199         alien_defs[CD_MINER].speed = 4;
200         alien_defs[CD_MINER].maxShield = 25;
201         alien_defs[CD_MINER].shield = 25;
202         alien_defs[CD_MINER].imageIndex[0] = 16;
203         alien_defs[CD_MINER].imageIndex[1] = 17;
204         alien_defs[CD_MINER].weaponType[0] = W_DOUBLE_SHOT;
205         alien_defs[CD_MINER].weaponType[1] = W_DOUBLE_SHOT;
206         alien_defs[CD_MINER].chance[0] = 0;
207         alien_defs[CD_MINER].chance[1] = 0;
208         alien_defs[CD_MINER].collectChance = 100;
209         alien_defs[CD_MINER].collectType = P_ANYTHING;
210         alien_defs[CD_MINER].collectValue = 30;
211         alien_defs[CD_MINER].flags = FL_WEAPCO | FL_NOFIRE | FL_DROPMINES;
212
213         // Kline
214         alien_defs[CD_KLINE].classDef = CD_KLINE;
215         alien_defs[CD_KLINE].AIType = AI_OFFENSIVE;
216         alien_defs[CD_KLINE].speed = 5;
217         alien_defs[CD_KLINE].maxShield = 2000;
218         alien_defs[CD_KLINE].shield = 2000;
219         alien_defs[CD_KLINE].imageIndex[0] = 18;
220         alien_defs[CD_KLINE].imageIndex[1] = 19;
221         alien_defs[CD_KLINE].weaponType[0] = W_TRIPLE_SHOT;
222         alien_defs[CD_KLINE].weaponType[1] = W_MICRO_ROCKETS;
223         alien_defs[CD_KLINE].chance[0] = 100;
224         alien_defs[CD_KLINE].chance[1] = 2;
225         alien_defs[CD_KLINE].collectChance = 0;
226         alien_defs[CD_KLINE].collectType = P_ANYTHING;
227         alien_defs[CD_KLINE].collectValue = 0;
228         alien_defs[CD_KLINE].flags = FL_WEAPCO | FL_ALWAYSFACE | FL_CIRCLES;
229
230         // Aim Fighter
231         alien_defs[CD_AIMFIGHTER].classDef = CD_AIMFIGHTER;
232         alien_defs[CD_AIMFIGHTER].AIType = AI_NORMAL;
233         alien_defs[CD_AIMFIGHTER].speed = 3;
234         alien_defs[CD_AIMFIGHTER].maxShield = 15;
235         alien_defs[CD_AIMFIGHTER].shield = 15;
236         alien_defs[CD_AIMFIGHTER].imageIndex[0] = 8;
237         alien_defs[CD_AIMFIGHTER].imageIndex[1] = 9;
238         alien_defs[CD_AIMFIGHTER].weaponType[0] = W_AIMED_SHOT;
239         alien_defs[CD_AIMFIGHTER].weaponType[1] = W_AIMED_SHOT;
240         alien_defs[CD_AIMFIGHTER].chance[0] = 7;
241         alien_defs[CD_AIMFIGHTER].chance[1] = 1;
242         alien_defs[CD_AIMFIGHTER].collectChance = 75;
243         alien_defs[CD_AIMFIGHTER].collectType = P_ANYTHING;
244         alien_defs[CD_AIMFIGHTER].collectValue = 100;
245         alien_defs[CD_AIMFIGHTER].flags = FL_WEAPCO | FL_AIMS;
246
247         // Slave ship
248         alien_defs[CD_SLAVETRANSPORT].classDef = CD_SLAVETRANSPORT;
249         alien_defs[CD_SLAVETRANSPORT].AIType = AI_EVASIVE;
250         alien_defs[CD_SLAVETRANSPORT].speed = 2;
251         alien_defs[CD_SLAVETRANSPORT].maxShield = 10;
252         alien_defs[CD_SLAVETRANSPORT].shield = 20;
253         alien_defs[CD_SLAVETRANSPORT].imageIndex[0] = 10;
254         alien_defs[CD_SLAVETRANSPORT].imageIndex[1] = 11;
255         alien_defs[CD_SLAVETRANSPORT].weaponType[0] = W_DOUBLE_SHOT;
256         alien_defs[CD_SLAVETRANSPORT].weaponType[1] = W_DOUBLE_SHOT;
257         alien_defs[CD_SLAVETRANSPORT].chance[0] = 0;
258         alien_defs[CD_SLAVETRANSPORT].chance[1] = 0;
259         alien_defs[CD_SLAVETRANSPORT].collectChance = 100;
260         alien_defs[CD_SLAVETRANSPORT].collectType = P_SLAVES;
261         alien_defs[CD_SLAVETRANSPORT].collectValue = 25;
262         alien_defs[CD_SLAVETRANSPORT].flags = FL_WEAPCO | FL_NOFIRE;
263
264         // Good Transport
265         alien_defs[CD_GOODTRANSPORT].classDef = CD_GOODTRANSPORT;
266         alien_defs[CD_GOODTRANSPORT].AIType = AI_EVASIVE;
267         alien_defs[CD_GOODTRANSPORT].speed = 3;
268         alien_defs[CD_GOODTRANSPORT].maxShield = 75;
269         alien_defs[CD_GOODTRANSPORT].shield = 75;
270         alien_defs[CD_GOODTRANSPORT].imageIndex[0] = 12;
271         alien_defs[CD_GOODTRANSPORT].imageIndex[1] = 13;
272         alien_defs[CD_GOODTRANSPORT].weaponType[0] = W_AIMED_SHOT;
273         alien_defs[CD_GOODTRANSPORT].weaponType[1] = W_AIMED_SHOT;
274         alien_defs[CD_GOODTRANSPORT].chance[0] = 100;
275         alien_defs[CD_GOODTRANSPORT].chance[1] = 100;
276         alien_defs[CD_GOODTRANSPORT].collectChance = 0;
277         alien_defs[CD_GOODTRANSPORT].collectType = P_ANYTHING;
278         alien_defs[CD_GOODTRANSPORT].collectValue = 0;
279         alien_defs[CD_GOODTRANSPORT].flags = FL_FRIEND | FL_NOFIRE | FL_AIMS;
280
281         // Sid Wilson
282         alien_defs[CD_SID].classDef = CD_SID;
283         alien_defs[CD_SID].AIType = AI_NORMAL;
284         alien_defs[CD_SID].speed = 3;
285         alien_defs[CD_SID].maxShield = 50;
286         alien_defs[CD_SID].shield = 50;
287         alien_defs[CD_SID].imageIndex[0] = 24;
288         alien_defs[CD_SID].imageIndex[1] = 25;
289         alien_defs[CD_SID].weaponType[0] = W_IONCANNON;
290         alien_defs[CD_SID].weaponType[1] = W_IONCANNON;
291         alien_defs[CD_SID].chance[0] = 100;
292         alien_defs[CD_SID].chance[1] = 0;
293         alien_defs[CD_SID].collectChance = 0;
294         alien_defs[CD_SID].collectType = P_ANYTHING;
295         alien_defs[CD_SID].collectValue = 0;
296         alien_defs[CD_SID].flags = FL_FRIEND | FL_AIMS;
297
298         // Mining Vessel Boss
299         alien_defs[CD_MINEBOSS].classDef = CD_BOSS;
300         alien_defs[CD_MINEBOSS].AIType = AI_NORMAL;
301         alien_defs[CD_MINEBOSS].speed = 3;
302         alien_defs[CD_MINEBOSS].maxShield = 1000;
303         alien_defs[CD_MINEBOSS].shield = 1000;
304         alien_defs[CD_MINEBOSS].imageIndex[0] = 26;
305         alien_defs[CD_MINEBOSS].imageIndex[1] = 27;
306         alien_defs[CD_MINEBOSS].weaponType[0] = W_TRIPLE_SHOT;
307         alien_defs[CD_MINEBOSS].weaponType[1] = W_SPREADSHOT;
308         alien_defs[CD_MINEBOSS].chance[0] = 0;
309         alien_defs[CD_MINEBOSS].chance[1] = 0;
310         alien_defs[CD_MINEBOSS].collectChance = 100;
311         alien_defs[CD_MINEBOSS].collectType = P_ANYTHING;
312         alien_defs[CD_MINEBOSS].collectValue = 1000;
313         alien_defs[CD_MINEBOSS].flags = FL_WEAPCO | FL_IMMORTAL;
314
315         alien_defs[CD_BOSS2_WING1].classDef = CD_BOSS2_WING1;
316         alien_defs[CD_BOSS2_WING1].AIType = AI_NORMAL;
317         alien_defs[CD_BOSS2_WING1].speed = 1;
318         alien_defs[CD_BOSS2_WING1].maxShield = 250;
319         alien_defs[CD_BOSS2_WING1].shield = 250;
320         alien_defs[CD_BOSS2_WING1].imageIndex[0] = 28;
321         alien_defs[CD_BOSS2_WING1].imageIndex[1] = 29;
322         alien_defs[CD_BOSS2_WING1].weaponType[0] = W_TRIPLE_SHOT;
323         alien_defs[CD_BOSS2_WING1].weaponType[1] = W_SPREADSHOT;
324         alien_defs[CD_BOSS2_WING1].chance[0] = 0;
325         alien_defs[CD_BOSS2_WING1].chance[1] = 0;
326         alien_defs[CD_BOSS2_WING1].collectChance = 100;
327         alien_defs[CD_BOSS2_WING1].collectType = P_ANYTHING;
328         alien_defs[CD_BOSS2_WING1].collectValue = 250;
329         alien_defs[CD_BOSS2_WING1].flags = FL_WEAPCO | FL_DAMAGEOWNER;
330
331         alien_defs[CD_BOSS2_WING2].classDef = CD_BOSS2_WING2;
332         alien_defs[CD_BOSS2_WING2].AIType = AI_NORMAL;
333         alien_defs[CD_BOSS2_WING2].speed = 1;
334         alien_defs[CD_BOSS2_WING2].maxShield = 500;
335         alien_defs[CD_BOSS2_WING2].shield = 500;
336         alien_defs[CD_BOSS2_WING2].imageIndex[0] = 30;
337         alien_defs[CD_BOSS2_WING2].imageIndex[1] = 31;
338         alien_defs[CD_BOSS2_WING2].weaponType[0] = W_TRIPLE_SHOT;
339         alien_defs[CD_BOSS2_WING2].weaponType[1] = W_SPREADSHOT;
340         alien_defs[CD_BOSS2_WING2].chance[0] = 0;
341         alien_defs[CD_BOSS2_WING2].chance[1] = 0;
342         alien_defs[CD_BOSS2_WING2].collectChance = 100;
343         alien_defs[CD_BOSS2_WING2].collectType = P_ANYTHING;
344         alien_defs[CD_BOSS2_WING2].collectValue = 250;
345         alien_defs[CD_BOSS2_WING2].flags = FL_WEAPCO | FL_DEPLOYDRONES | FL_DAMAGEOWNER;
346
347         alien_defs[CD_BOSS2_WING3].classDef = CD_BOSS2_WING3;
348         alien_defs[CD_BOSS2_WING3].AIType = AI_NORMAL;
349         alien_defs[CD_BOSS2_WING3].speed = 1;
350         alien_defs[CD_BOSS2_WING3].maxShield = 500;
351         alien_defs[CD_BOSS2_WING3].shield = 500;
352         alien_defs[CD_BOSS2_WING3].imageIndex[0] = 32;
353         alien_defs[CD_BOSS2_WING3].imageIndex[1] = 33;
354         alien_defs[CD_BOSS2_WING3].weaponType[0] = W_TRIPLE_SHOT;
355         alien_defs[CD_BOSS2_WING3].weaponType[1] = W_SPREADSHOT;
356         alien_defs[CD_BOSS2_WING3].chance[0] = 0;
357         alien_defs[CD_BOSS2_WING3].chance[1] = 0;
358         alien_defs[CD_BOSS2_WING3].collectChance = 100;
359         alien_defs[CD_BOSS2_WING3].collectType = P_ANYTHING;
360         alien_defs[CD_BOSS2_WING3].collectValue = 250;
361         alien_defs[CD_BOSS2_WING3].flags = FL_WEAPCO | FL_DEPLOYDRONES | FL_DAMAGEOWNER;
362
363         alien_defs[CD_BOSS2_WING4].classDef = CD_BOSS2_WING4;
364         alien_defs[CD_BOSS2_WING4].AIType = AI_NORMAL;
365         alien_defs[CD_BOSS2_WING4].speed = 1;
366         alien_defs[CD_BOSS2_WING4].maxShield = 250;
367         alien_defs[CD_BOSS2_WING4].shield = 250;
368         alien_defs[CD_BOSS2_WING4].imageIndex[0] = 34;
369         alien_defs[CD_BOSS2_WING4].imageIndex[1] = 35;
370         alien_defs[CD_BOSS2_WING4].weaponType[0] = W_TRIPLE_SHOT;
371         alien_defs[CD_BOSS2_WING4].weaponType[1] = W_SPREADSHOT;
372         alien_defs[CD_BOSS2_WING4].chance[0] = 0;
373         alien_defs[CD_BOSS2_WING4].chance[1] = 0;
374         alien_defs[CD_BOSS2_WING4].collectChance = 100;
375         alien_defs[CD_BOSS2_WING4].collectType = P_ANYTHING;
376         alien_defs[CD_BOSS2_WING4].collectValue = 250;
377         alien_defs[CD_BOSS2_WING4].flags = FL_WEAPCO | FL_DAMAGEOWNER;
378
379         // Drone
380         alien_defs[CD_DRONE].classDef = CD_DRONE;
381         alien_defs[CD_DRONE].AIType = AI_OFFENSIVE;
382         alien_defs[CD_DRONE].speed = 8;
383         alien_defs[CD_DRONE].maxShield = 5;
384         alien_defs[CD_DRONE].shield = 5;
385         alien_defs[CD_DRONE].imageIndex[0] = 36;
386         alien_defs[CD_DRONE].imageIndex[1] = 37;
387         alien_defs[CD_DRONE].weaponType[0] = W_DOUBLE_SHOT;
388         alien_defs[CD_DRONE].weaponType[1] = W_LASER;
389         alien_defs[CD_DRONE].chance[0] = 100;
390         alien_defs[CD_DRONE].chance[1] = 0;
391         alien_defs[CD_DRONE].collectChance = 10;
392         alien_defs[CD_DRONE].collectType = P_SHIELD;
393         alien_defs[CD_DRONE].collectValue = 1;
394         alien_defs[CD_DRONE].flags = FL_WEAPCO;
395
396         // Experimental Fighter
397         alien_defs[CD_CLOAKFIGHTER].classDef = CD_CLOAKFIGHTER;
398         alien_defs[CD_CLOAKFIGHTER].AIType = AI_OFFENSIVE;
399         alien_defs[CD_CLOAKFIGHTER].speed = 6;
400         alien_defs[CD_CLOAKFIGHTER].maxShield = 1000;
401         alien_defs[CD_CLOAKFIGHTER].shield = 1000;
402         alien_defs[CD_CLOAKFIGHTER].imageIndex[0] = 10;
403         alien_defs[CD_CLOAKFIGHTER].imageIndex[1] = 11;
404         alien_defs[CD_CLOAKFIGHTER].weaponType[0] = W_SPREADSHOT;
405         alien_defs[CD_CLOAKFIGHTER].weaponType[1] = W_DOUBLE_ROCKETS;
406         alien_defs[CD_CLOAKFIGHTER].chance[0] = 100;
407         alien_defs[CD_CLOAKFIGHTER].chance[1] = 5;
408         alien_defs[CD_CLOAKFIGHTER].collectChance = 100;
409         alien_defs[CD_CLOAKFIGHTER].collectType = P_CASH;
410         alien_defs[CD_CLOAKFIGHTER].collectValue = 250;
411         alien_defs[CD_CLOAKFIGHTER].flags = FL_WEAPCO | FL_CANCLOAK | FL_RUNSAWAY;
412
413         // Evil Ursula
414         alien_defs[CD_EVILURSULA].classDef = CD_EVILURSULA;
415         alien_defs[CD_EVILURSULA].AIType = AI_OFFENSIVE;
416         alien_defs[CD_EVILURSULA].speed = 5;
417         alien_defs[CD_EVILURSULA].maxShield = 500;
418         alien_defs[CD_EVILURSULA].shield = 500;
419         alien_defs[CD_EVILURSULA].imageIndex[0] = 12;
420         alien_defs[CD_EVILURSULA].imageIndex[1] = 13;
421         alien_defs[CD_EVILURSULA].weaponType[0] = W_TRIPLE_SHOT;
422         alien_defs[CD_EVILURSULA].weaponType[1] = W_HOMING_MISSILE;
423         alien_defs[CD_EVILURSULA].chance[0] = 100;
424         alien_defs[CD_EVILURSULA].chance[1] = 100;
425         alien_defs[CD_EVILURSULA].collectChance = 100;
426         alien_defs[CD_EVILURSULA].collectType = P_ESCAPEPOD;
427         alien_defs[CD_EVILURSULA].collectValue = 1;
428         alien_defs[CD_EVILURSULA].flags = FL_WEAPCO;
429
430         // Mercenary
431         alien_defs[CD_KRASS].classDef = CD_KRASS;
432         alien_defs[CD_KRASS].AIType = AI_OFFENSIVE;
433         alien_defs[CD_KRASS].speed = 5;
434         alien_defs[CD_KRASS].maxShield = 1000;
435         alien_defs[CD_KRASS].shield = 1000;
436         alien_defs[CD_KRASS].imageIndex[0] = 26;
437         alien_defs[CD_KRASS].imageIndex[1] = 27;
438         alien_defs[CD_KRASS].weaponType[0] = W_SPREADSHOT;
439         alien_defs[CD_KRASS].weaponType[1] = W_CHARGER;
440         alien_defs[CD_KRASS].chance[0] = 100;
441         alien_defs[CD_KRASS].chance[1] = 0;
442         alien_defs[CD_KRASS].collectChance = 100;
443         alien_defs[CD_KRASS].collectType = P_ANYTHING;
444         alien_defs[CD_KRASS].collectValue = 2250;
445         alien_defs[CD_KRASS].flags = FL_FRIEND | FL_IMMORTAL;
446
447         // Executive Transport
448         alien_defs[CD_EXEC].classDef = CD_BOSS;
449         alien_defs[CD_EXEC].AIType = AI_NORMAL;
450         alien_defs[CD_EXEC].speed = 5;
451         alien_defs[CD_EXEC].maxShield = 1000;
452         alien_defs[CD_EXEC].shield = 1000;
453         alien_defs[CD_EXEC].imageIndex[0] = 28;
454         alien_defs[CD_EXEC].imageIndex[1] = 28;
455         alien_defs[CD_EXEC].weaponType[0] = W_SPREADSHOT;
456         alien_defs[CD_EXEC].weaponType[1] = W_HOMING_MISSILE;
457         alien_defs[CD_EXEC].chance[0] = 0;
458         alien_defs[CD_EXEC].chance[1] = 0;
459         alien_defs[CD_EXEC].collectChance = 0;
460         alien_defs[CD_EXEC].collectType = P_ANYTHING;
461         alien_defs[CD_EXEC].collectValue = 2000;
462         alien_defs[CD_EXEC].flags = FL_WEAPCO | FL_NOFIRE;
463
464         // Asteroid
465         alien_defs[CD_ASTEROID].classDef = CD_ASTEROID;
466         alien_defs[CD_ASTEROID].AIType = AI_WANDER;
467         alien_defs[CD_ASTEROID].speed = 1;
468         alien_defs[CD_ASTEROID].maxShield = 50;
469         alien_defs[CD_ASTEROID].shield = 50;
470         alien_defs[CD_ASTEROID].imageIndex[0] = 38;
471         alien_defs[CD_ASTEROID].imageIndex[1] = 38;
472         alien_defs[CD_ASTEROID].weaponType[0] = W_SPREADSHOT;
473         alien_defs[CD_ASTEROID].weaponType[1] = W_HOMING_MISSILE;
474         alien_defs[CD_ASTEROID].chance[0] = 0;
475         alien_defs[CD_ASTEROID].chance[1] = 0;
476         alien_defs[CD_ASTEROID].collectChance = 25;
477         alien_defs[CD_ASTEROID].collectType = P_ORE;
478         alien_defs[CD_ASTEROID].collectValue = 1;
479         alien_defs[CD_ASTEROID].flags = FL_WEAPCO;
480
481         alien_defs[CD_ASTEROID2].classDef = CD_ASTEROID2;
482         alien_defs[CD_ASTEROID2].AIType = AI_WANDER;
483         alien_defs[CD_ASTEROID2].speed = 1;
484         alien_defs[CD_ASTEROID2].maxShield = 10;
485         alien_defs[CD_ASTEROID2].shield = 10;
486         alien_defs[CD_ASTEROID2].imageIndex[0] = 39;
487         alien_defs[CD_ASTEROID2].imageIndex[1] = 40;
488         alien_defs[CD_ASTEROID2].weaponType[0] = W_SPREADSHOT;
489         alien_defs[CD_ASTEROID2].weaponType[1] = W_HOMING_MISSILE;
490         alien_defs[CD_ASTEROID2].chance[0] = 0;
491         alien_defs[CD_ASTEROID2].chance[1] = 0;
492         alien_defs[CD_ASTEROID2].collectChance = 25;
493         alien_defs[CD_ASTEROID2].collectType = P_ORE;
494         alien_defs[CD_ASTEROID2].collectValue = 1;
495         alien_defs[CD_ASTEROID2].flags = FL_WEAPCO;
496
497         // Escort
498         alien_defs[CD_ESCORT].classDef = CD_ESCORT;
499         alien_defs[CD_ESCORT].AIType = AI_NORMAL;
500         alien_defs[CD_ESCORT].speed = 3;
501         alien_defs[CD_ESCORT].maxShield = 200;
502         alien_defs[CD_ESCORT].shield = 200;
503         alien_defs[CD_ESCORT].imageIndex[0] = 30;
504         alien_defs[CD_ESCORT].imageIndex[1] = 31;
505         alien_defs[CD_ESCORT].weaponType[0] = W_LASER;
506         alien_defs[CD_ESCORT].weaponType[1] = W_LASER;
507         alien_defs[CD_ESCORT].chance[0] = 25;
508         alien_defs[CD_ESCORT].chance[1] = 25;
509         alien_defs[CD_ESCORT].collectChance = 100;
510         alien_defs[CD_ESCORT].collectType = P_ANYTHING;
511         alien_defs[CD_ESCORT].collectValue = 100;
512         alien_defs[CD_ESCORT].flags = FL_WEAPCO;
513
514         // Mobile Ray Cannon
515         alien_defs[CD_MOBILE_RAY].classDef = CD_MOBILE_RAY;
516         alien_defs[CD_MOBILE_RAY].AIType = AI_OFFENSIVE;
517         alien_defs[CD_MOBILE_RAY].speed = 5;
518         alien_defs[CD_MOBILE_RAY].maxShield = 250;
519         alien_defs[CD_MOBILE_RAY].shield = 250;
520         alien_defs[CD_MOBILE_RAY].imageIndex[0] = 10;
521         alien_defs[CD_MOBILE_RAY].imageIndex[1] = 11;
522         alien_defs[CD_MOBILE_RAY].weaponType[0] = W_ENERGYRAY;
523         alien_defs[CD_MOBILE_RAY].weaponType[1] = W_ENERGYRAY;
524         alien_defs[CD_MOBILE_RAY].chance[0] = 50;
525         alien_defs[CD_MOBILE_RAY].chance[1] = 50;
526         alien_defs[CD_MOBILE_RAY].collectChance = 75;
527         alien_defs[CD_MOBILE_RAY].collectType = P_ANYTHING;
528         alien_defs[CD_MOBILE_RAY].collectValue = 100;
529         alien_defs[CD_MOBILE_RAY].flags = FL_WEAPCO;
530
531         // Rebel Carrier
532         alien_defs[CD_REBELCARRIER].classDef = CD_REBELCARRIER;
533         alien_defs[CD_REBELCARRIER].AIType = AI_OFFENSIVE;
534         alien_defs[CD_REBELCARRIER].speed = 2;
535         alien_defs[CD_REBELCARRIER].maxShield = 100;
536         alien_defs[CD_REBELCARRIER].shield = 100;
537         alien_defs[CD_REBELCARRIER].imageIndex[0] = 32;
538         alien_defs[CD_REBELCARRIER].imageIndex[1] = 33;
539         alien_defs[CD_REBELCARRIER].weaponType[0] = W_DOUBLE_ROCKETS;
540         alien_defs[CD_REBELCARRIER].weaponType[1] = W_MICRO_ROCKETS;
541         alien_defs[CD_REBELCARRIER].chance[0] = 50;
542         alien_defs[CD_REBELCARRIER].chance[1] = 2;
543         alien_defs[CD_REBELCARRIER].collectChance = 0;
544         alien_defs[CD_REBELCARRIER].collectType = P_SHIELD;
545         alien_defs[CD_REBELCARRIER].collectValue = 0;
546         alien_defs[CD_REBELCARRIER].flags = FL_FRIEND;
547
548         // Pluto Boss
549         alien_defs[CD_PLUTOBOSS].classDef = CD_PLUTOBOSS;
550         alien_defs[CD_PLUTOBOSS].AIType = AI_OFFENSIVE;
551         alien_defs[CD_PLUTOBOSS].speed = 4;
552         alien_defs[CD_PLUTOBOSS].maxShield = 500;
553         alien_defs[CD_PLUTOBOSS].shield = 500;
554         alien_defs[CD_PLUTOBOSS].imageIndex[0] = 12;
555         alien_defs[CD_PLUTOBOSS].imageIndex[1] = 13;
556         alien_defs[CD_PLUTOBOSS].weaponType[0] = W_DOUBLE_ROCKETS;
557         alien_defs[CD_PLUTOBOSS].weaponType[1] = W_MICRO_ROCKETS;
558         alien_defs[CD_PLUTOBOSS].chance[0] = 50;
559         alien_defs[CD_PLUTOBOSS].chance[1] = 2;
560         alien_defs[CD_PLUTOBOSS].collectChance = 0;
561         alien_defs[CD_PLUTOBOSS].collectType = P_ANYTHING;
562         alien_defs[CD_PLUTOBOSS].collectValue = 1000;
563         alien_defs[CD_PLUTOBOSS].flags = FL_WEAPCO;
564
565         // Pluto Boss Barrier
566         alien_defs[CD_BARRIER].classDef = CD_BARRIER;
567         alien_defs[CD_BARRIER].AIType = AI_OFFENSIVE;
568         alien_defs[CD_BARRIER].speed = 1;
569         alien_defs[CD_BARRIER].maxShield = 250;
570         alien_defs[CD_BARRIER].shield = 250;
571         alien_defs[CD_BARRIER].imageIndex[0] = 32;
572         alien_defs[CD_BARRIER].imageIndex[1] = 33;
573         alien_defs[CD_BARRIER].weaponType[0] = W_DOUBLE_SHOT;
574         alien_defs[CD_BARRIER].weaponType[1] = W_MICRO_ROCKETS;
575         alien_defs[CD_BARRIER].chance[0] = 0;
576         alien_defs[CD_BARRIER].chance[1] = 0;
577         alien_defs[CD_BARRIER].collectChance = 100;
578         alien_defs[CD_BARRIER].collectType = P_ANYTHING;
579         alien_defs[CD_BARRIER].collectValue = 25;
580         alien_defs[CD_BARRIER].flags = FL_WEAPCO | FL_NOFIRE;
581
582         // Neptune Boss
583         alien_defs[CD_NEPTUNEBOSS].classDef = CD_NEPTUNEBOSS;
584         alien_defs[CD_NEPTUNEBOSS].AIType = AI_OFFENSIVE;
585         alien_defs[CD_NEPTUNEBOSS].speed = 4;
586         alien_defs[CD_NEPTUNEBOSS].maxShield = 800;
587         alien_defs[CD_NEPTUNEBOSS].shield = 800;
588         alien_defs[CD_NEPTUNEBOSS].imageIndex[0] = 12;
589         alien_defs[CD_NEPTUNEBOSS].imageIndex[1] = 13;
590         alien_defs[CD_NEPTUNEBOSS].weaponType[0] = W_DOUBLE_SHOT;
591         alien_defs[CD_NEPTUNEBOSS].weaponType[1] = W_MICRO_ROCKETS;
592         alien_defs[CD_NEPTUNEBOSS].chance[0] = 100;
593         alien_defs[CD_NEPTUNEBOSS].chance[1] = 0;
594         alien_defs[CD_NEPTUNEBOSS].collectChance = 100;
595         alien_defs[CD_NEPTUNEBOSS].collectType = P_ANYTHING;
596         alien_defs[CD_NEPTUNEBOSS].collectValue = 1000;
597         alien_defs[CD_NEPTUNEBOSS].flags = FL_WEAPCO;
598
599         // Mobile Shield
600         alien_defs[CD_MOBILESHIELD].classDef = CD_MOBILESHIELD;
601         alien_defs[CD_MOBILESHIELD].AIType = AI_EVASIVE;
602         alien_defs[CD_MOBILESHIELD].speed = 6;
603         alien_defs[CD_MOBILESHIELD].maxShield = 150;
604         alien_defs[CD_MOBILESHIELD].shield = 150;
605         alien_defs[CD_MOBILESHIELD].imageIndex[0] = 34;
606         alien_defs[CD_MOBILESHIELD].imageIndex[1] = 35;
607         alien_defs[CD_MOBILESHIELD].weaponType[0] = W_DOUBLE_SHOT;
608         alien_defs[CD_MOBILESHIELD].weaponType[1] = W_MICRO_ROCKETS;
609         alien_defs[CD_MOBILESHIELD].chance[0] = 0;
610         alien_defs[CD_MOBILESHIELD].chance[1] = 0;
611         alien_defs[CD_MOBILESHIELD].collectChance = 100;
612         alien_defs[CD_MOBILESHIELD].collectType = P_ANYTHING;
613         alien_defs[CD_MOBILESHIELD].collectValue = 25;
614         alien_defs[CD_MOBILESHIELD].flags = FL_WEAPCO | FL_NOFIRE;
615
616         // Firefly
617         alien_defs[CD_FIREFLY].classDef = CD_FIREFLY;
618         alien_defs[CD_FIREFLY].AIType = AI_OFFENSIVE;
619         alien_defs[CD_FIREFLY].speed = 5;
620         alien_defs[CD_FIREFLY].maxShield = 250;
621         alien_defs[CD_FIREFLY].shield = 250;
622         alien_defs[CD_FIREFLY].imageIndex[0] = 0;
623         alien_defs[CD_FIREFLY].imageIndex[1] = 1;
624         alien_defs[CD_FIREFLY].weaponType[0] = W_TRIPLE_SHOT;
625         alien_defs[CD_FIREFLY].weaponType[1] = W_DOUBLE_ROCKETS;
626         alien_defs[CD_FIREFLY].chance[0] = 100;
627         alien_defs[CD_FIREFLY].chance[1] = 5;
628         alien_defs[CD_FIREFLY].collectChance = 100;
629         alien_defs[CD_FIREFLY].collectType = P_ANYTHING;
630         alien_defs[CD_FIREFLY].collectValue = 250;
631         alien_defs[CD_FIREFLY].flags = FL_WEAPCO;
632
633         // Uranus Boss
634         alien_defs[CD_URANUSBOSS].classDef = CD_URANUSBOSS;
635         alien_defs[CD_URANUSBOSS].AIType = AI_OFFENSIVE;
636         alien_defs[CD_URANUSBOSS].speed = 4;
637         alien_defs[CD_URANUSBOSS].maxShield = 750;
638         alien_defs[CD_URANUSBOSS].shield = 750;
639         alien_defs[CD_URANUSBOSS].imageIndex[0] = 41;
640         alien_defs[CD_URANUSBOSS].imageIndex[1] = 42;
641         alien_defs[CD_URANUSBOSS].weaponType[0] = W_SPREADSHOT;
642         alien_defs[CD_URANUSBOSS].weaponType[1] = W_DOUBLE_ROCKETS;
643         alien_defs[CD_URANUSBOSS].chance[0] = 100;
644         alien_defs[CD_URANUSBOSS].chance[1] = 5;
645         alien_defs[CD_URANUSBOSS].collectChance = 100;
646         alien_defs[CD_URANUSBOSS].collectType = P_ANYTHING;
647         alien_defs[CD_URANUSBOSS].collectValue = 500;
648         alien_defs[CD_URANUSBOSS].flags = FL_WEAPCO;
649
650         // Uranus Boss Wing 1
651         alien_defs[CD_URANUSBOSSWING1].classDef = CD_URANUSBOSSWING1;
652         alien_defs[CD_URANUSBOSSWING1].AIType = AI_OFFENSIVE;
653         alien_defs[CD_URANUSBOSSWING1].speed = 4;
654         alien_defs[CD_URANUSBOSSWING1].maxShield = 250;
655         alien_defs[CD_URANUSBOSSWING1].shield = 250;
656         alien_defs[CD_URANUSBOSSWING1].imageIndex[0] = 43;
657         alien_defs[CD_URANUSBOSSWING1].imageIndex[1] = 44;
658         alien_defs[CD_URANUSBOSSWING1].weaponType[0] = W_DOUBLE_ROCKETS;
659         alien_defs[CD_URANUSBOSSWING1].weaponType[1] = W_DOUBLE_ROCKETS;
660         alien_defs[CD_URANUSBOSSWING1].chance[0] = 5;
661         alien_defs[CD_URANUSBOSSWING1].chance[1] = 0;
662         alien_defs[CD_URANUSBOSSWING1].collectChance = 100;
663         alien_defs[CD_URANUSBOSSWING1].collectType = P_ANYTHING;
664         alien_defs[CD_URANUSBOSSWING1].collectValue = 250;
665         alien_defs[CD_URANUSBOSSWING1].flags = FL_WEAPCO | FL_IMMORTAL | FL_DAMAGEOWNER;
666
667         // Uranus Boss Wing 2
668         alien_defs[CD_URANUSBOSSWING2].classDef = CD_URANUSBOSSWING2;
669         alien_defs[CD_URANUSBOSSWING2].AIType = AI_OFFENSIVE;
670         alien_defs[CD_URANUSBOSSWING2].speed = 4;
671         alien_defs[CD_URANUSBOSSWING2].maxShield = 250;
672         alien_defs[CD_URANUSBOSSWING2].shield = 250;
673         alien_defs[CD_URANUSBOSSWING2].imageIndex[0] = 45;
674         alien_defs[CD_URANUSBOSSWING2].imageIndex[1] = 46;
675         alien_defs[CD_URANUSBOSSWING2].weaponType[0] = W_DOUBLE_ROCKETS;
676         alien_defs[CD_URANUSBOSSWING2].weaponType[1] = W_DOUBLE_ROCKETS;
677         alien_defs[CD_URANUSBOSSWING2].chance[0] = 5;
678         alien_defs[CD_URANUSBOSSWING2].chance[1] = 0;
679         alien_defs[CD_URANUSBOSSWING2].collectChance = 100;
680         alien_defs[CD_URANUSBOSSWING2].collectType = P_ANYTHING;
681         alien_defs[CD_URANUSBOSSWING2].collectValue = 250;
682         alien_defs[CD_URANUSBOSSWING2].flags = FL_WEAPCO | FL_IMMORTAL | FL_DAMAGEOWNER;
683 }
684
685 void aliens_init()
686 {
687         FILE *fp;
688         char string[255];
689         int index;
690         int alienType;
691         int placeAttempt;
692         int barrierSpeed;
693
694         for (int i = 0 ; i < ALIEN_MAX ; i++)
695         {
696                 aliens[i].active = false;
697                 aliens[i].shield = -1;
698                 aliens[i].flags = 0;
699         }
700
701         engine.targetIndex = -1;
702
703         strcpy(string, "");
704         barrierSpeed = 1;
705
706         sprintf(string, "data/aliens%d.dat", game.area);
707         fp = fopen(string, "rb");
708
709         if (fp != NULL)
710         {
711                 while (fscanf(fp, "%d %d ", &index, &alienType) == 2)
712                 {
713                         placeAttempt = 0;
714
715                         aliens[index] = alien_defs[alienType];
716                         aliens[index].owner = &aliens[index];
717                         aliens[index].target = &aliens[index];
718                         aliens[index].face = rand() % 2;
719                         aliens[index].active = true;
720
721                         /*
722                         we make 1000 attempts to place this enemy since it is required. If after
723                         1000 attempts we still haven't managed to place the alien, then it
724                         simply isn't going to happen and we will just exit the game. The chances
725                         of this happening are very very low!
726                         */
727                         while (true)
728                         {
729                                 placeAttempt++;
730
731                                 if (alien_place(&aliens[index]))
732                                         break;
733
734                                 if (placeAttempt > 1000)
735                                         showErrorAndExit(2, "");
736                         }
737
738                         if (game.area == MISN_CERADSE)
739                                 cargo_add(&aliens[index], P_CARGO);
740                         else if (game.area == MISN_NEROD)
741                                 cargo_add(&aliens[index], P_PHOEBE);
742
743                         if (index == ALIEN_KLINE)
744                         {
745                                 aliens[ALIEN_KLINE].target = &player;
746                         }
747
748                         if (aliens[index].classDef == CD_CLOAKFIGHTER)
749                         {
750                                 aliens[index].active = false;
751                                 aliens[index].maxShield = aliens[index].shield = 400;
752                                 aliens[index].flags &= ~FL_RUNSAWAY;
753                                 aliens[index].speed = 3;
754                         }
755
756                         if ((aliens[index].classDef == CD_MOBILE_RAY) && (index >= 11))
757                         {
758                                 aliens[index].active = false;
759                         }
760
761                         if (aliens[index].classDef == CD_FIREFLY)
762                         {
763                                 aliens[index].active = false;
764                         }
765
766                         if (aliens[index].classDef == CD_BARRIER)
767                         {
768                                 aliens[index].owner = &aliens[ALIEN_BOSS];
769                                 aliens[index].speed = barrierSpeed;
770                                 barrierSpeed++;
771                         }
772
773                         if ((game.area == MISN_POSWIC) &&
774                                 (aliens[index].classDef == CD_BOSS))
775                         {
776                                 aliens[index].imageIndex[1] = 29;
777                                 aliens[index].flags |= FL_IMMORTAL;
778                         }
779
780                         if (game.area == MISN_ELLESH)
781                                 aliens[index].flags |= FL_HASMINIMUMSPEED;
782
783                         if (game.area == MISN_JUPITER)
784                         {
785                                 aliens[index].flags = FL_WEAPCO;
786                                 if (index == ALIEN_BOSS)
787                                         aliens[index].chance[1] = 5;
788                         }
789                 }
790
791                 fclose(fp);
792
793                 if (game.area == MISN_MOEBO)
794                 {
795                         aliens[ALIEN_BOSS].target = &player;
796                         aliens[ALIEN_BOSS].x = -screen->w / 2;
797                         aliens[ALIEN_BOSS].y = screen->h / 2;
798
799                         aliens[ALIEN_BOSS_PART1].owner = &aliens[ALIEN_BOSS];
800                         aliens[ALIEN_BOSS_PART1].target = &player;
801                         aliens[ALIEN_BOSS_PART1].dx = -25;
802                         aliens[ALIEN_BOSS_PART1].dy = -21;
803
804                         aliens[ALIEN_BOSS_PART2].owner = &aliens[ALIEN_BOSS];
805                         aliens[ALIEN_BOSS_PART2].target = &player;
806                         aliens[ALIEN_BOSS_PART2].dx = -20;
807                         aliens[ALIEN_BOSS_PART2].dy = 37;
808                 }
809                 else if ((game.area == MISN_ELAMALE) ||
810                         (game.area == MISN_FELLON))
811                 {
812                         aliens[ALIEN_BOSS].target = &player;
813                         aliens[ALIEN_BOSS].x = -screen->w / 2;
814                         aliens[ALIEN_BOSS].y = screen->h / 2;
815
816                         aliens[ALIEN_BOSS_PART1].owner = &aliens[ALIEN_BOSS];
817                         aliens[ALIEN_BOSS_PART1].target = &player;
818                         aliens[ALIEN_BOSS_PART1].dx = 15;
819                         aliens[ALIEN_BOSS_PART1].dy = -22;
820
821                         aliens[ALIEN_BOSS_PART2].owner = &aliens[ALIEN_BOSS];
822                         aliens[ALIEN_BOSS_PART2].target = &player;
823                         aliens[ALIEN_BOSS_PART2].dx = 15;
824                         aliens[ALIEN_BOSS_PART2].dy = 22;
825
826                         aliens[ALIEN_BOSS_PART3].owner = &aliens[ALIEN_BOSS_PART1];
827                         aliens[ALIEN_BOSS_PART3].target = &player;
828                         aliens[ALIEN_BOSS_PART3].dx = -35;
829                         aliens[ALIEN_BOSS_PART3].dy = -12;
830
831                         aliens[ALIEN_BOSS_PART4].owner = &aliens[ALIEN_BOSS_PART2];
832                         aliens[ALIEN_BOSS_PART4].target = &player;
833                         aliens[ALIEN_BOSS_PART4].dx = -35;
834                         aliens[ALIEN_BOSS_PART4].dy = 20;
835
836                         if (game.area == MISN_FELLON)
837                         {
838                                 aliens[ALIEN_BOSS].AIType = AI_EVASIVE;
839
840                                 for (int i = 10 ; i < 15 ; i++)
841                                 {
842                                         aliens[i].imageIndex[0] += 15;
843                                         aliens[i].imageIndex[1] += 15;
844
845                                         aliens[i].image[0] = shipShape[aliens[i].imageIndex[0]];
846                                         aliens[i].image[1] = shipShape[aliens[i].imageIndex[1]];
847                                 }
848                         }
849                 }
850                 else if (game.area == MISN_URANUS)
851                 {
852                         aliens[ALIEN_BOSS].target = &player;
853                         aliens[ALIEN_BOSS].x = -screen->w / 2;
854                         aliens[ALIEN_BOSS].y = screen->h / 2;
855
856                         aliens[ALIEN_BOSS_PART1].owner = &aliens[ALIEN_BOSS];
857                         aliens[ALIEN_BOSS_PART1].dy = 20;
858
859                         aliens[ALIEN_BOSS_PART2].owner = &aliens[ALIEN_BOSS];
860                         aliens[ALIEN_BOSS_PART2].dy = -16;
861                 }
862         }
863 }
864
865 bool alien_add()
866 {
867         int index = alien_getFreeIndex();
868
869         if ((index == -1) || (game.area == MISN_JUPITER) ||
870                         (game.area == MISN_VENUS))
871                 return 0;
872
873         signed char *alienArray;
874         signed char numberOfAliens = 1;
875
876         alienArray = new signed char[8];
877
878         switch(game.area)
879         {
880                 case MISN_START:
881                 case MISN_HINSTAG:
882                 case MISN_ELAMALE:
883                         numberOfAliens = 1;
884                         alienArray[0] = CD_DUALFIGHTER;
885                         break;
886                 case MISN_HAIL:
887                 case MISN_CERADSE:
888                 case MISN_JOLDAR:
889                 case MISN_MOEBO:
890                         numberOfAliens = 2;
891                         alienArray[0] = CD_DUALFIGHTER;
892                         alienArray[1] = CD_PROTOFIGHTER;
893                         break;
894                 case MISN_NEROD:
895                 case MISN_ALLEZ:
896                         numberOfAliens = 3;
897                         alienArray[0] = CD_DUALFIGHTER;
898                         alienArray[1] = CD_PROTOFIGHTER;
899                         alienArray[2] = CD_AIMFIGHTER;
900                         break;
901                 case MISN_URUSOR:
902                         // This is the mission where you need to disable cargo ships.
903                         // Missiles are extremely bad in this mission, not because
904                         // of the damage they do to you, but because they tend to
905                         // accidentally destroy the cargo ships. Therefore, ships
906                         // with missiles (dual fighters and missile boats) are
907                         // excluded from this mission.
908                         numberOfAliens = 2;
909                         alienArray[0] = CD_PROTOFIGHTER;
910                         alienArray[1] = CD_AIMFIGHTER;
911                         break;
912                 case MISN_DORIM:
913                 case MISN_SIVEDI:
914                         numberOfAliens = 1;
915                         alienArray[0] = CD_ASTEROID;
916                         break;
917                 case MISN_ODEON:
918                 case MISN_FELLON:
919                 case MISN_ALMARTHA:
920                         numberOfAliens = 4;
921                         alienArray[0] = CD_DUALFIGHTER;
922                         alienArray[1] = CD_PROTOFIGHTER;
923                         alienArray[2] = CD_MISSILEBOAT;
924                         alienArray[3] = CD_AIMFIGHTER;
925                         break;
926                 case MISN_ELLESH:
927                         numberOfAliens = 2;
928                         alienArray[0] = CD_DUALFIGHTER;
929                         alienArray[1] = CD_MINER;
930                         break;
931                 case MISN_SATURN:
932                         numberOfAliens = 2;
933                         alienArray[0] = CD_AIMFIGHTER;
934                         alienArray[1] = CD_DUALFIGHTER;
935                         break;
936                 case MISN_MARS:
937                         numberOfAliens = 2;
938                         alienArray[0] = CD_ASTEROID;
939                         alienArray[1] = CD_ASTEROID2;
940                         break;
941                 case MISN_EARTH:
942                         numberOfAliens = 6;
943                         alienArray[0] = CD_DUALFIGHTER;
944                         alienArray[1] = CD_PROTOFIGHTER;
945                         alienArray[2] = CD_MISSILEBOAT;
946                         alienArray[3] = CD_AIMFIGHTER;
947                         alienArray[4] = CD_ESCORT;
948                         alienArray[5] = CD_MOBILE_RAY;
949                         break;
950                 case MISN_INTERCEPTION:
951                         numberOfAliens = 3;
952                         alienArray[0] = CD_DUALFIGHTER;
953                         alienArray[1] = CD_MISSILEBOAT;
954                         alienArray[2] = CD_AIMFIGHTER;
955                         if (game.system == 2)
956                         {
957                                 numberOfAliens = 4;
958                                 alienArray[3] = CD_PROTOFIGHTER;
959                         }
960                         break;
961                 default:
962                         numberOfAliens = 1;
963                         alienArray[0] = CD_DUALFIGHTER;
964                         break;
965         }
966
967         signed char randEnemy = alienArray[rand() % numberOfAliens];
968
969         if ((game.area != MISN_DORIM) &&
970                 (game.area != MISN_SIVEDI) &&
971                 (game.area != MISN_MARS))
972         {
973                 if ((game.system == 1) && (game.area == MISN_INTERCEPTION))
974                 {
975                         if ((rand() % 5) == 0)
976                                 randEnemy = CD_SLAVETRANSPORT;
977                 }
978
979                 if ((rand() % 6) == 0)
980                         randEnemy = CD_TRANSPORTSHIP;
981         }
982
983         delete[] alienArray;
984
985         aliens[index] = alien_defs[randEnemy];
986         aliens[index].active = true;
987         aliens[index].face = rand() % 2;
988         aliens[index].owner = &aliens[index]; // Most enemies will own themselves
989         aliens[index].target = &aliens[index];
990         aliens[index].thinktime = (50 + rand() % 50);
991         aliens[index].systemPower = aliens[index].maxShield;
992         aliens[index].deathCounter = 0 - (aliens[index].maxShield * 3);
993         aliens[index].hit = 0;
994
995         LIMIT(aliens[index].deathCounter, -250, 0);
996
997         // Attempts to place an alien. If it fails, the alien is deactivated.
998         for (int i = 0 ; i < 100 ; i++)
999         {
1000                 if (alien_place(&aliens[index]))
1001                         break;
1002                 aliens[index].active = false;
1003
1004                 return false;
1005         }
1006
1007         if (aliens[index].classDef == CD_CARGOSHIP)
1008                 cargo_add(&aliens[index], P_CARGO);
1009
1010         if (aliens[index].classDef == CD_MOBILE_RAY)
1011                 aliens[index].shield = 25;
1012
1013         if (aliens[index].classDef == CD_ESCORT)
1014                 aliens[index].shield = 50;
1015
1016         aliens[index].dx = RANDRANGE(-2, 2);
1017         aliens[index].dy = RANDRANGE(-2, 2);
1018
1019         aliens[index].ammo[0] = 0;
1020
1021         if (game.area == MISN_ELLESH)
1022                 aliens[index].flags |= FL_HASMINIMUMSPEED;
1023
1024         return true;
1025 }
1026
1027 void alien_addDrone(object *hostAlien)
1028 {
1029         int index = alien_getFreeIndex();
1030
1031         if (index == -1)
1032                 return;
1033
1034         aliens[index] = alien_defs[CD_DRONE];
1035         aliens[index].active = true;
1036         aliens[index].face = rand() % 2;
1037         aliens[index].owner = &aliens[index]; // Most enemies will own themselves
1038         aliens[index].target = &aliens[index];
1039         aliens[index].thinktime = (50 + rand() % 50);
1040         aliens[index].systemPower = aliens[index].maxShield;
1041         aliens[index].deathCounter = 0 - (aliens[index].maxShield * 3);
1042         aliens[index].hit = 0;
1043
1044         aliens[index].x = hostAlien->x + rand() % 50;
1045         aliens[index].y = hostAlien->y + rand() % 50;
1046 }
1047
1048 void alien_addSmallAsteroid(object *hostAlien)
1049 {
1050         if (engine.missionCompleteTimer != 0)
1051                 return;
1052
1053         int index = -1;
1054         int debris = RANDRANGE(1, 10);
1055
1056         for (int i = 0 ; i < debris ; i++)
1057                 bullet_add(&weapon[W_ROCKETS], hostAlien, 0, 0);
1058
1059         for (int i = 10 ; i < 20 ; i++)
1060                 if (!aliens[i].active)
1061                         index = i;
1062
1063         if (index == -1)
1064                 return;
1065
1066         if ((rand() % 10) > 3)
1067         {
1068                 aliens[index] = alien_defs[CD_ASTEROID2];
1069                 aliens[index].imageIndex[0] = aliens[index].imageIndex[1] = 39 + rand() % 2;
1070                 aliens[index].image[0] = shipShape[aliens[index].imageIndex[0]];
1071                 aliens[index].image[1] = shipShape[aliens[index].imageIndex[1]];
1072         }
1073         else
1074         {
1075                 aliens[index] = alien_defs[CD_DRONE];
1076         }
1077
1078         aliens[index].owner = &aliens[index]; // Most enemies will own themselves
1079         aliens[index].target = &aliens[index];
1080         aliens[index].thinktime = 1;
1081         aliens[index].systemPower = aliens[index].maxShield;
1082         aliens[index].deathCounter = 0 - (aliens[index].maxShield * 3);
1083         aliens[index].hit = 0;
1084
1085         aliens[index].x = hostAlien->x;
1086         aliens[index].y = hostAlien->y;
1087         aliens[index].active = true;
1088 }
1089
1090 void alien_addFriendly(int type)
1091 {
1092         if (type != ALIEN_SID)
1093                 aliens[type] = alien_defs[CD_FRIEND];
1094         else
1095                 aliens[type] = alien_defs[CD_SID];
1096
1097         aliens[type].owner = &aliens[type];
1098         aliens[type].target = &aliens[type];
1099         aliens[type].active = true;
1100         aliens[type].x = RANDRANGE((screen->w / 2) - 150, (screen->w / 2) + 150);
1101         aliens[type].y = RANDRANGE((screen->h / 2) - 150, (screen->h / 2) + 150);
1102
1103         if (type == ALIEN_PHOEBE)
1104                 aliens[type].classDef = CD_PHOEBE;
1105
1106         if (type == ALIEN_URSULA)
1107                 aliens[type].classDef = CD_URSULA;
1108
1109         // For the sake of it being the final battle :)
1110         if (game.area == MISN_EARTH)
1111                 aliens[type].flags |= FL_IMMORTAL;
1112 }
1113
1114 bool alien_place(object *alien)
1115 {
1116         if (rand() % 2 == 0)
1117                 alien->x = RANDRANGE(screen->w, screen->w * 2);
1118         else
1119                 alien->x = RANDRANGE(-screen->w, 0);
1120
1121         if (rand() % 2 == 0)
1122                 alien->y = RANDRANGE(screen->h, screen->h * 2);
1123         else
1124                 alien->y = RANDRANGE(-screen->h, 0);
1125
1126         if (game.area == MISN_MARS)
1127         {
1128                 alien->x = screen->w + RANDRANGE(0, 400);
1129                 alien->y = RANDRANGE(-screen->h / 3, (4 * screen->h) / 3);
1130         }
1131
1132         for (int i = 0 ; i < ALIEN_MAX ; i++)
1133         {
1134                 if ((aliens[i].owner != alien) && (aliens[i].shield > 0))
1135                 {
1136                         if (collision(alien->x, alien->y, alien->image[0]->w,
1137                                         alien->image[0]->h, aliens[i].x, aliens[i].y,
1138                                         aliens[i].image[0]->w, aliens[i].image[0]->h))
1139                                 return false;
1140                 }
1141         }
1142
1143         return true;
1144 }
1145
1146 void alien_setAI(object *alien)
1147 {
1148         // Make friendly craft generally concentrate on smaller fighters
1149         if ((alien->flags & FL_FRIEND) && (alien->target == &aliens[ALIEN_BOSS]))
1150         {
1151                 if ((rand() % 5) == 0)
1152                 {
1153                         alien->target = alien;
1154                         alien->thinktime = 0;
1155                         return;
1156                 }
1157         }
1158
1159         int i = rand() % 10;
1160         float tx = alien->target->x;
1161         float ty = alien->target->y;
1162
1163         int chase = 0; // Chance in 10 of chasing player
1164         int area = 0; // Chance in 10 of moving to an area around the player
1165         int stop = 0; // Chance in 10 of hanging back
1166         int point = 0; // Size of area alien will move into
1167
1168         switch (alien->AIType)
1169         {
1170                 case AI_NORMAL:
1171                         chase = 3;
1172                         point = 6;
1173                         stop = 9;
1174                         area = 250;
1175                         break;
1176                 case AI_OFFENSIVE:
1177                         chase = 7;
1178                         point = 8;
1179                         stop = 9;
1180                         area = 50;
1181                         break;
1182                 case AI_DEFENSIVE:
1183                         chase = 2;
1184                         point = 6;
1185                         stop = 8;
1186                         area = 300;
1187                         break;
1188                 case AI_EVASIVE:
1189                         chase = 1;
1190                         point = 8;
1191                         stop = 9;
1192                         area = 600;
1193                         break;
1194                 case AI_WANDER:
1195                         chase = -1;
1196                         point = 0;
1197                         stop = 10;
1198                         area = 1200;
1199                         break;
1200         }
1201
1202         if (i <= chase)
1203         {
1204                 // Chase the target
1205                 alien->dx = ((alien->x - tx) / ((300 / alien->speed) + rand() % 100));
1206                 alien->dy = ((alien->y - ty) / ((300 / alien->speed) + rand() % 100));
1207                 return;
1208         }
1209         else if ((i >= point) && (i <= stop))
1210         {
1211                 // Fly to a random point around the target
1212                 tx += (rand() % area - (rand() % area * 2));
1213                 ty += (rand() % area - (rand() % area * 2));
1214                 alien->dx = ((alien->x - tx) / ((300 / alien->speed) + rand() % 100));
1215                 alien->dy = ((alien->y - ty) / ((300 / alien->speed) + rand() % 100));
1216                 return;
1217         }
1218         else
1219         {
1220                 // Hang back
1221                 alien->dx = 0;
1222                 alien->dy = 0;
1223                 return;
1224         }
1225 }
1226
1227 void alien_setKlineAttackMethod(object *alien)
1228 {
1229         if (alien->shield <= 500)
1230         {
1231                 setRadioMessage(FACE_KLINE, "¤â¤¦¤è¤¤!! ¤³¤ì¤Ç½ª¤ï¤ê¤À!!!", 1);
1232                 alien->weaponType[0] = W_AIMED_SHOT;
1233                 alien->weaponType[1] = W_MICRO_HOMING_MISSILES;
1234                 alien->flags |= FL_CANCLOAK;
1235                 alien->chance[0] = 100;
1236                 alien->chance[1] = 2;
1237                 alien->flags &= ~FL_CANNOTDIE;
1238         }
1239         else if (alien->shield <= 1000)
1240         {
1241                 setRadioMessage(FACE_KLINE, "¤¢¤­¤ì¤ë¤è¤¦¤Ê ¤·¤Ö¤È¤µ¤À! ¤³¤ì¤Ç¤â¿©¤é¤¨!!", 1);
1242                 alien->weaponType[0] = W_DIRSHOCKMISSILE;
1243                 alien->weaponType[1] = W_DIRSHOCKMISSILE;
1244                 alien->chance[0] = 2;
1245                 alien->chance[1] = 2;
1246                 alien->flags |= FL_AIMS;
1247         }
1248         else
1249         {
1250                 setRadioMessage(FACE_KLINE, "¤¹¤Ð¤é¤·¤¤¤¾¥Ð¥ó¥Õ¥£¡¼¥ë¥É¡£¾¯¤·Ëܵ¤¤ò½Ð¤·¤Æ¤ä¤í¤¦¡Ä", 1);
1251                 alien->weaponType[0] = W_SPREADSHOT;
1252                 alien->chance[1] = 40;
1253         }
1254 }
1255
1256 /*
1257 This AI is exclusively for Kline.
1258 */
1259 void alien_setKlineAI(object *alien)
1260 {
1261         // Weapon type change
1262         if ((rand() % 3) == 0)
1263         {
1264                 if (game.area != MISN_VENUS)
1265                 {
1266                         alien->flags &= ~FL_AIMS;
1267
1268                         switch(rand() % 2)
1269                         {
1270                                 case 0:
1271                                         alien->weaponType[0] = W_TRIPLE_SHOT;
1272                                         break;
1273                                 case 1:
1274                                         alien->weaponType[0] = W_AIMED_SHOT;
1275                                         alien->flags |= FL_AIMS;
1276                                         break;
1277                         }
1278                 }
1279         }
1280
1281         alien->flags &= ~(FL_CIRCLES | FL_CONTINUOUS_FIRE | FL_DROPMINES);
1282
1283         switch(rand() % 10)
1284         {
1285                 case 0:
1286                         if ((alien->weaponType[0] != W_DIRSHOCKMISSILE) &&
1287                                         (alien->weaponType[1] != W_MICRO_HOMING_MISSILES))
1288                                 alien->flags |= FL_CONTINUOUS_FIRE;
1289                         alien->dx = ((alien->x - alien->target->x) /
1290                                 ((300 / alien->speed)  + rand() % 100));
1291                         alien->dy = ((alien->y - alien->target->y) /
1292                                 ((300 / alien->speed)  + rand() % 100));
1293                         break;
1294                 case 1:
1295                 case 2:
1296                         // Kline only attacks then he is ready!
1297                         if ((!(alien->flags & FL_NOFIRE)) &&
1298                                         (game.area == MISN_MOEBO))
1299                                 alien->flags |= FL_DROPMINES;
1300                         break;
1301                 case 3:
1302                 case 4:
1303                         alien->flags |= FL_CIRCLES;
1304                         break;
1305                 default:
1306                         alien_setAI(alien);
1307                         break;
1308         }
1309 }
1310
1311 /*
1312 "Looks" for an enemy by picking a randomly active enemy and using them
1313 as a target. If the target is too far away, it will be ignored.
1314 */
1315 void alien_searchForTarget(object *alien)
1316 {
1317         int i;
1318
1319         if (alien->flags & FL_WEAPCO)
1320         {
1321                 i = (rand() % 10);
1322
1323                 if (i == 0)
1324                 {
1325                         alien->target = &player;
1326                         return;
1327                 }
1328         }
1329
1330         i = rand() % ALIEN_MAX;
1331
1332         object *targetEnemy = &aliens[i];
1333
1334         // Tell Sid not to attack craft that are already disabled or can
1335         // return fire. This will save him from messing about (unless we're on the last mission)
1336         if ((alien->classDef == CD_SID) && (game.area != MISN_EARTH))
1337         {
1338                 if ((targetEnemy->flags & FL_DISABLED) || (!(targetEnemy->flags & FL_NOFIRE)))
1339                         return;
1340         }
1341
1342         // Tell Phoebe and Ursula not to attack ships that cannot fire or are disabled (unless we're on the last mission)
1343         if (game.area != MISN_EARTH)
1344         {
1345                 if ((alien->classDef == CD_PHOEBE) || (alien->classDef == CD_URSULA))
1346                 {
1347                         // Don't attack the boss or we could be here all day(!)
1348                         if (targetEnemy->classDef == CD_BOSS)
1349                                 return;
1350
1351                         if ((targetEnemy->flags & FL_DISABLED) ||
1352                                         (targetEnemy->flags & FL_NOFIRE))
1353                                 return;
1354                 }
1355         }
1356
1357         if ((targetEnemy->shield < 1) || (!targetEnemy->active))
1358                 return;
1359
1360         if ((targetEnemy->flags & FL_WEAPCO) && (alien->flags & FL_WEAPCO))
1361                 return;
1362
1363         if ((targetEnemy->flags & FL_FRIEND) && (alien->flags & FL_FRIEND))
1364                 return;
1365
1366         if (abs((int)alien->x - (int)alien->target->x) > 550)
1367                 return;
1368
1369         if (abs((int)alien->y - (int)alien->target->y) > 400)
1370                 return;
1371
1372         alien->target = targetEnemy;
1373 }
1374
1375 /*
1376 Do various checks to see if the alien can fire at the target.
1377 */
1378 int alien_checkTarget(object *alien)
1379 {
1380         // No target
1381         if (alien->target == alien)
1382                 return 0;
1383
1384         // Whilst firing a Ray, no other weapons can be fired!
1385         if (alien->flags & FL_FIRERAY)
1386                 return 0;
1387
1388         // The target is on the same side as you!
1389         if ((alien->flags & FL_WEAPCO) && (alien->target->flags & FL_WEAPCO))
1390                 return 0;
1391         if ((alien->flags & FL_FRIEND) && (alien->target->flags & FL_FRIEND))
1392                 return 0;
1393
1394         // You're facing the wrong way
1395         if ((alien->face == 0) && (alien->target->x < alien->x))
1396                 return 0;
1397         if ((alien->face == 1) && (alien->target->x > alien->x))
1398                 return 0;
1399
1400         // Slightly more than half a screen away from you
1401         if (abs((int)alien->x - (int)alien->target->x) > 550)
1402                 return 0;
1403
1404         if ((alien->flags & FL_AIMS) || (alien->flags & FL_CONTINUOUS_FIRE))
1405                 return 1;
1406
1407         // Not at the correct vertical height
1408         if ((alien->y < alien->target->y - 15) ||
1409                         (alien->y > alien->target->y + alien->target->image[0]->h + 15))
1410                 return 0;
1411
1412         return 1;
1413 }
1414
1415 /*
1416 Currently only used for the allies. Whilst flying around, the allies will fire on
1417 any enemy craft that enter their line of sight.
1418 */
1419 int alien_enemiesInFront(object *alien)
1420 {
1421         for (int i = 0 ; i < ALIEN_MAX ; i++)
1422         {
1423                 if ((alien != &aliens[i]) && (aliens[i].flags & FL_WEAPCO) &&
1424                         (aliens[i].shield > 0))
1425                 {
1426                         if ((alien->y > aliens[i].y - 15) &&
1427                                 (alien->y < aliens[i].y + aliens[i].image[0]->h + 15))
1428                         {
1429                                 if ((alien->face == 1) && (aliens[i].x < alien->x))
1430                                         return 1;
1431                                 if ((alien->face == 0) && (aliens[i].x > alien->x))
1432                                         return 1;
1433                         }
1434                 }
1435         }
1436
1437         return 0;
1438 }
1439
1440 void alien_move(object *alien)
1441 {
1442         bool checkCollisions;
1443
1444         if ((alien->flags & FL_LEAVESECTOR) || (alien->shield < 1))
1445                 checkCollisions = false;
1446         else
1447                 checkCollisions = true;
1448
1449         if (alien->owner == alien)
1450         {
1451                 if (alien->flags & FL_CIRCLES)
1452                 {
1453                         if (alien->face == 0)
1454                         {
1455                                 alien->dx += 0.02;
1456                                 alien->dy += 0.02;
1457                         }
1458                         else
1459                         {
1460                                 alien->dx -= 0.02;
1461                                 alien->dy -= 0.02;
1462                         }
1463
1464                         alien->x -= (sinf(alien->dx) * 4);
1465                         alien->y -= (cosf(alien->dy) * 4);
1466                 }
1467                 else
1468                 {
1469                         alien->x -= alien->dx;
1470                         alien->y -= alien->dy;
1471                 }
1472         }
1473
1474         if (checkCollisions)
1475         {
1476                 for (int i = 0 ; i < ALIEN_MAX ; i++)
1477                 {
1478                         if ((alien->flags & FL_LEAVESECTOR) ||
1479                                 (alien->classDef == CD_DRONE) ||
1480                                 (alien->classDef == CD_ASTEROID2) ||
1481                                 (alien->owner == aliens[i].owner) ||
1482                                 (alien->owner->owner == aliens[i].owner) ||
1483                                 (aliens[i].shield < 1))
1484                         {
1485                                 continue;
1486                         }
1487
1488                         if (collision(alien, &aliens[i]))
1489                         {
1490                                 if ((aliens[i].classDef == CD_BARRIER) &&
1491                                         (aliens[i].owner != alien))
1492                                 {
1493                                         alien->shield--;
1494                                         alien->hit = 3;
1495                                         alien->dx *= -1;
1496                                         alien->dy *= -1;
1497                                         audio_playSound(SFX_HIT, alien->x);
1498                                 }
1499                         }
1500                 }
1501         }
1502
1503         // Handle a collision with the player
1504         if ((player.shield > 0) && (alien->shield > 0) && (checkCollisions))
1505         {
1506                 if (collision(alien, &player))
1507                 {
1508                         if (alien->classDef == CD_ASTEROID)
1509                         {
1510                                 if (!engine.cheatShield)
1511                                         player.shield -= alien->shield;
1512                                 alien->shield = 0;
1513                                 audio_playSound(SFX_EXPLOSION, alien->x);
1514                                 player.hit = 5;
1515                                 audio_playSound(SFX_HIT, player.x);
1516                         }
1517
1518                         if (alien->classDef == CD_ASTEROID2)
1519                         {
1520                                 if (!engine.cheatShield)
1521                                         player.shield -= alien->shield;
1522                                 alien->shield = 0;
1523                                 audio_playSound(SFX_EXPLOSION, alien->x);
1524                                 player.hit = 5;
1525                                 audio_playSound(SFX_HIT, player.x);
1526                         }
1527
1528                         if (alien->classDef == CD_BARRIER)
1529                         {
1530                                 if (!engine.cheatShield)
1531                                         player.shield--;
1532                                 player.hit = 5;
1533                                 audio_playSound(SFX_HIT, player.x);
1534                         }
1535                 }
1536         }
1537 }
1538
1539 /*
1540 Fill in later...
1541 */
1542 void alien_destroy(object *alien, object *attacker)
1543 {
1544         audio_playSound(SFX_EXPLOSION, alien->x);
1545
1546         if (alien->flags & FL_FRIEND)
1547         {
1548                 if (alien->classDef == CD_PHOEBE)
1549                         game.wingMate1Ejects++;
1550                 else if (alien->classDef == CD_URSULA)
1551                         game.wingMate2Ejects++;
1552
1553                 // Phoebe cannot eject on the rescue mission
1554                 if (game.area != MISN_NEROD)
1555                 {
1556                         if ((alien->classDef == CD_PHOEBE) || (alien->classDef == CD_URSULA))
1557                                 setInfoLine(">> Ãç´Ö¤ÏΥ椷¤¿! <<\n", FONT_RED);
1558                         else
1559                                 setInfoLine(">> Í§·³¤Î´ÏÁ¥¤¬Ç˲õ¤µ¤ì¤¿! <<\n", FONT_RED);
1560                 }
1561         }
1562
1563         if (attacker != NULL)
1564         {
1565                 if (attacker == &player)
1566                 {
1567                         game.totalKills++;
1568                 }
1569                 else if (attacker->classDef == CD_PHOEBE)
1570                 {
1571                         game.wingMate1Kills++;
1572                 }
1573                 else if (attacker->classDef == CD_URSULA)
1574                 {
1575                         game.wingMate2Kills++;
1576                 }
1577                 else
1578                 {
1579                         game.totalOtherKills++;
1580                 }
1581
1582                 if ((attacker->classDef == CD_PHOEBE) || (attacker->classDef == CD_URSULA))
1583                 {
1584                         if ((rand() % 8) == 0)
1585                         {
1586                                 getKillMessage(attacker);
1587                         }
1588                 }
1589         }
1590
1591         updateMissionRequirements(M_DESTROY_TARGET_TYPE, alien->classDef, 1);
1592         updateMissionRequirements(M_PROTECT_TARGET, alien->classDef, 1);
1593
1594         if (rand() % 100 <= alien->collectChance)
1595         {
1596                 unsigned char value;
1597
1598                 if ((rand() % 10) == 0)
1599                         alien->collectValue *= 2;
1600
1601                 while (alien->collectValue > 0)
1602                 {
1603                         value = (10 + (rand() % alien->collectValue));
1604                         if (value > alien->collectValue)
1605                                 value = alien->collectValue;
1606                         collectable_add(alien->x, alien->y, alien->collectType, value, 600);
1607                         alien->collectValue -= value;
1608                 }
1609         }
1610
1611         // Make it explode immediately
1612         if (alien->classDef == CD_ASTEROID)
1613         {
1614                 alien->shield = -999;
1615         }
1616
1617         if ((alien->classDef == CD_KRASS) && (attacker == &player))
1618                 setRadioMessage(FACE_CHRIS, "²¶¤Ï¥¯¥ê¥¹¤À¡£ºÇ´ü¤Ë³Ð¤¨¤Æ¤ª¤±¡£", 1);
1619
1620         if (alien->classDef == CD_KLINE)
1621         {
1622                 setRadioMessage(FACE_KLINE, "¸÷±É¤Ë»×¤¦¤¾¡Äµ®ÍͤÈÀ廊¤¿¤³¤È¤ò¡Ä", 1);
1623                 alien->dx = alien->dy = 0;
1624                 alien->shield = -150;
1625         }
1626 }
1627
1628 void alien_hurt(object *alien, object *attacker, int damage, bool ion)
1629 {
1630         if (ion)
1631                 alien->systemPower -= damage;
1632         else
1633                 alien->shield -= damage;
1634
1635         // Chain reaction damage if needed
1636         if ((alien->owner != alien) && (alien->flags & FL_DAMAGEOWNER))
1637         {
1638                 alien_hurt(alien->owner, attacker, damage, ion);
1639         }
1640
1641         if (alien->classDef == CD_KLINE)
1642         {
1643                 if (game.area == MISN_ELAMALE)
1644                 {
1645                         if ((alien->shield <= alien->maxShield - 500) &&
1646                                 !(alien->flags & FL_LEAVESECTOR))
1647                         {
1648                                 alien->flags |= FL_LEAVESECTOR;
1649                                 alien->flags &= ~FL_CIRCLES;
1650                                 setRadioMessage(FACE_KLINE, "¤ªÁ°¤ò¸«¤¯¤Ó¤Ã¤Æ¤¤¤¿¤è¤¦¤À¡¢¥Ð¥ó¥Õ¥£¡¼¥ë¥É¡£¤Þ¤¿²ñ¤¦¤³¤È¤Ë¤Ê¤ë¤À¤í¤¦!", 1);
1651                         }
1652                 }
1653                 else if (game.area == MISN_EARTH)
1654                 {
1655                         if ((alien->shield <= alien->maxShield - 750) &&
1656                                 !(alien->flags & FL_LEAVESECTOR))
1657                         {
1658                                 alien->flags |= FL_LEAVESECTOR;
1659                                 alien->flags &= ~FL_CIRCLES;
1660                                 setRadioMessage(FACE_SID, "¥¯¥ê¥¹¡¢¥±¥¹¥é¥ó¤¬Æ¨¤²¤ë¤¾!", 1);
1661                         }
1662                 }
1663                 else if (game.area == MISN_VENUS)
1664                 {
1665                         if (alien->shield + damage > 1500 &&
1666                                         alien->shield <= 1500)
1667                                 alien_setKlineAttackMethod(alien);
1668                         else if (alien->shield + damage > 1000 &&
1669                                         alien->shield <= 1000)
1670                                 alien_setKlineAttackMethod(alien);
1671                         else if (alien->shield + damage > 500 &&
1672                                         alien->shield <= 500)
1673                                 alien_setKlineAttackMethod(alien);
1674                 }
1675                 else
1676                 {
1677                         if ((alien->shield <= alien->maxShield - 100) &&
1678                                 !(alien->flags & FL_LEAVESECTOR))
1679                         {
1680                                 alien->flags |= FL_LEAVESECTOR;
1681                                 alien->flags &= ~FL_CIRCLES;
1682                         }
1683                 }
1684         }
1685
1686         if ((alien->flags & FL_RUNSAWAY) && ((rand() % 50) == 0))
1687         {
1688                 alien->flags |= FL_LEAVESECTOR;
1689         }
1690
1691         audio_playSound(SFX_HIT, alien->x);
1692         if (alien->AIType == AI_EVASIVE)
1693                 alien->thinktime = 0;
1694         
1695         if (alien->shield < 1)
1696                 alien_destroy(alien, attacker);
1697
1698         if (alien->systemPower < 1)
1699         {
1700                 if (!(alien->flags & FL_DISABLED))
1701                 {
1702                         alien->flags += FL_DISABLED;
1703                         updateMissionRequirements(M_DISABLE_TARGET,
1704                                 alien->classDef, 1);
1705                 }
1706
1707                 alien->systemPower = 0;
1708                 if (alien->classDef == CD_KLINE)
1709                         alien->systemPower = alien->maxShield;
1710         }
1711 }