1 /*
2 * Triplane Classic - a side-scrolling dogfighting game.
3 * Copyright (C) 1996,1997,2009 Dodekaedron Software Creations Oy
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * tjt@users.sourceforge.net
19 */
20
21 #include "world/constants.h"
22 #include "world/plane.h"
23 #include "triplane.h"
24 #include "fobjects.h"
25 #include "util/wutil.h"
26 #include "io/sound.h"
27 #include "world/tripaudio.h"
28
29 #define SPEED 4
30
31
32 int infan_x[MAX_INFANTRY];
33 int infan_y[MAX_INFANTRY];
34 int infan_direction[MAX_INFANTRY];
35 int infan_last_shot[MAX_INFANTRY];
36 int infan_state[MAX_INFANTRY];
37 int infan_country[MAX_INFANTRY];
38 int infan_frame[MAX_INFANTRY];
39 int infan_stop[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
40
41 int infan_x_speed[MAX_INFANTRY];
42
43 int itgun_shot_x[MAX_ITGUN_SHOTS];
44 int itgun_shot_y[MAX_ITGUN_SHOTS];
45 int itgun_shot_x_speed[MAX_ITGUN_SHOTS];
46 int itgun_shot_y_speed[MAX_ITGUN_SHOTS];
47 int itgun_shot_age[MAX_ITGUN_SHOTS];
48
49 int bomb_target;
50
51 void do_infan(void);
52
53 void infan_to_plane(int l);
54 void infan_to_infan(int l);
55 void infan_to_struct(int l);
56 void infan_take_hits(int l);
57
58 void do_kkbase(void);
59 void start_it_shot(int x, int y, int angle);
60 void do_it_shots(void);
61 void start_itgun_explosion(int number);
62
63 void do_ai(int number);
64 void ai_turn_down(int number);
65 void ai_turn_up(int number);
66 void ai_evade_terrain(int number);
67 void ai_turnplus(int number);
68 void ai_turnminus(int number);
69 void ai_do_bombing(int number);
70 int check_structs(int x, int y, int number);
71 void do_mekan(void);
72 void do_doors(void);
73
74 #define MEKAN_DIRECTION_LEFT 0
75 #define MEKAN_DIRECTION_RIGHT 1
76
77 #define MEKAN_MISSION_IDLE 0
78 #define MEKAN_MISSION_RETURN 1
79 #define MEKAN_MISSION_PUSH_OUT 2
80 #define MEKAN_MISSION_PUSH_IN 3
81
82 /* Submissions of MEKAN_MISSION_PUSH_IN */
83 #define MEKAN_PUSH_IN_MOVE_TO_PLANE 0
84 #define MEKAN_PUSH_IN_PUSH 1
85 #define MEKAN_PUSH_IN_WAIT_DOOR_CLOSE 2
86
87 /* Submissions of MEKAN_MISSION_PUSH_OUT */
88 #define MEKAN_PUSH_OUT_WAIT_DOOR_OPEN 0
89 #define MEKAN_PUSH_OUT_MOVE_TO_PLANE 1
90 #define MEKAN_PUSH_OUT_PUSH 2
91
92 /* These only affect graphics. */
93 #define MEKAN_ANIMATION_INVISIBLE 0
94 #define MEKAN_ANIMATION_WALK 1
95 #define MEKAN_ANIMATION_PUSH_PROPELLER 2
96 #define MEKAN_ANIMATION_PUSH_TAIL 3
97
98
99 /******************************************************************************/
100
do_doors(void)101 void do_doors(void) {
102 int l;
103
104 for (l = 0; l < 4; l++) {
105 if (!hangar_x[l])
106 continue;
107
108 if (hangar_door_opening[l] && hangar_door_closing[l])
109 hangar_door_closing[l] = 0;
110
111 if (hangar_door_opening[l]) {
112 if (++hangar_door_frame[l] >= 13) {
113 hangar_door_frame[l] = 12;
114 hangar_door_opening[l] = 0;
115
116 }
117
118 }
119
120 if (hangar_door_closing[l]) {
121 if (--hangar_door_frame[l] < 0) {
122 hangar_door_frame[l] = 0;
123 hangar_door_closing[l] = 0;
124
125 }
126
127 }
128
129 }
130
131 }
132
do_mekan(void)133 void do_mekan(void) {
134 int l, l2;
135
136
137 for (l = 0; l < 4; l++) {
138 if (!hangar_x[l])
139 continue;
140
141 for (l2 = 0; l2 < 16; l2++) {
142 if (plane_wants_in[l2]) {
143 if (player_speed[l2] || (in_closing[l2])) {
144 plane_wants_in[l2] = 0;
145 }
146
147 }
148
149 }
150
151 switch (mekan_mission[l]) {
152 case MEKAN_MISSION_RETURN:
153 if (mekan_direction[l] == MEKAN_DIRECTION_RIGHT) {
154 if (mekan_x[l] >= (hangar_x[l] + 38)) {
155 mekan_mission[l] = MEKAN_MISSION_IDLE;
156 mekan_status[l] = MEKAN_ANIMATION_INVISIBLE;
157 hangar_door_closing[l] = 1;
158 }
159
160 } else {
161 if (mekan_x[l] <= (hangar_x[l] + 38)) {
162 mekan_mission[l] = MEKAN_MISSION_IDLE;
163 mekan_status[l] = MEKAN_ANIMATION_INVISIBLE;
164 hangar_door_closing[l] = 1;
165 }
166
167
168 }
169 break;
170 case MEKAN_MISSION_IDLE:
171 for (l2 = l + 8; l2 >= 0; l2 -= 4) {
172 if (plane_wants_in[l2]) {
173 mekan_mission[l] = MEKAN_MISSION_PUSH_IN;
174 mekan_target[l] = l2;
175 mekan_subtarget[l] = MEKAN_PUSH_IN_MOVE_TO_PLANE;
176 mekan_x[l] = hangar_x[l] + 38;
177 mekan_status[l] = MEKAN_ANIMATION_WALK;
178 if ((player_x_8[l2] - 38) > hangar_x[l]) {
179 mekan_direction[l] = MEKAN_DIRECTION_RIGHT;
180
181 } else {
182 mekan_direction[l] = MEKAN_DIRECTION_LEFT;
183
184 }
185 }
186
187 }
188
189 for (l2 = l + 8; l2 >= 0; l2 -= 4) {
190 if (plane_wants_out[l2]) {
191 mekan_mission[l] = MEKAN_MISSION_PUSH_OUT;
192 mekan_target[l] = l2;
193 mekan_subtarget[l] = MEKAN_PUSH_OUT_WAIT_DOOR_OPEN;
194 mekan_x[l] = hangar_x[l] + 38;
195 mekan_status[l] = MEKAN_ANIMATION_WALK;
196 if (leveldata.plane_direction[player_tsides[l2]]) {
197 mekan_direction[l] = MEKAN_DIRECTION_RIGHT;
198
199 } else {
200 mekan_direction[l] = MEKAN_DIRECTION_LEFT;
201
202 }
203 }
204
205 }
206
207 if (mekan_mission[l] == MEKAN_MISSION_IDLE)
208 hangar_door_closing[l] = 1;
209
210 break;
211
212 case MEKAN_MISSION_PUSH_IN:
213
214 if (!mekan_subtarget[l] && hangar_door_frame[l] != 12) {
215 hangar_door_opening[l] = 1;
216
217 }
218
219 if (!plane_wants_in[mekan_target[l]]) {
220 mekan_mission[l] = MEKAN_MISSION_RETURN;
221
222 mekan_status[l] = MEKAN_ANIMATION_WALK;
223
224 if (mekan_x[l] > (hangar_x[l] + 38)) {
225 mekan_direction[l] = MEKAN_DIRECTION_LEFT;
226
227 } else {
228 mekan_direction[l] = MEKAN_DIRECTION_RIGHT;
229
230 }
231 break;
232 }
233
234
235
236 switch (mekan_subtarget[l]) {
237 case MEKAN_PUSH_IN_MOVE_TO_PLANE:
238 if (mekan_direction[l] == MEKAN_DIRECTION_RIGHT && mekan_x[l] >= (player_x_8[mekan_target[l]] + 10)) {
239 mekan_x[l] = player_x_8[mekan_target[l]] + 10;
240 mekan_direction[l] = MEKAN_DIRECTION_LEFT;
241
242
243 if (player_angle[mekan_target[l]] < 90 * 256) {
244 mekan_status[l] = MEKAN_ANIMATION_PUSH_PROPELLER;
245
246 } else {
247 mekan_status[l] = MEKAN_ANIMATION_PUSH_TAIL;
248
249 }
250
251 mekan_subtarget[l] = MEKAN_PUSH_IN_PUSH;
252
253 } else if (mekan_direction[l] == MEKAN_DIRECTION_LEFT && (mekan_x[l] + 13) <= (player_x_8[mekan_target[l]] - 10)) {
254 mekan_x[l] = player_x_8[mekan_target[l]] - 10 - 13;
255 mekan_direction[l] = MEKAN_DIRECTION_RIGHT;
256
257
258 if (player_angle[mekan_target[l]] < 90 * 256) {
259 mekan_status[l] = MEKAN_ANIMATION_PUSH_TAIL;
260
261 } else {
262 mekan_status[l] = MEKAN_ANIMATION_PUSH_PROPELLER;
263
264 }
265
266 mekan_subtarget[l] = MEKAN_PUSH_IN_PUSH;
267
268 }
269
270 break;
271 case MEKAN_PUSH_IN_PUSH:
272
273 if (mekan_direction[l] == MEKAN_DIRECTION_RIGHT) {
274 player_x_8[mekan_target[l]] = (mekan_x[l] + 10 + 13);
275 player_x[mekan_target[l]] = player_x_8[mekan_target[l]] << 8;
276
277 if ((mekan_x[l] + 13) >= (hangar_x[l] + 28)) {
278
279 hangar_door_closing[l] = 1;
280 plane_present[mekan_target[l]] = 0;
281 plane_coming[mekan_target[l]] = 1;
282 mekan_subtarget[l] = MEKAN_PUSH_IN_WAIT_DOOR_CLOSE;
283 mekan_status[l] = MEKAN_ANIMATION_INVISIBLE;
284 }
285 } else {
286 player_x_8[mekan_target[l]] = (mekan_x[l] - 10);
287 player_x[mekan_target[l]] = player_x_8[mekan_target[l]] << 8;
288
289 if (mekan_x[l] <= (hangar_x[l] + 48)) {
290
291 hangar_door_closing[l] = 1;
292 plane_present[mekan_target[l]] = 0;
293 plane_coming[mekan_target[l]] = 1;
294 mekan_subtarget[l] = MEKAN_PUSH_IN_WAIT_DOOR_CLOSE;
295 mekan_status[l] = MEKAN_ANIMATION_INVISIBLE;
296 }
297
298
299
300 }
301
302 break;
303
304 case MEKAN_PUSH_IN_WAIT_DOOR_CLOSE:
305 if (!hangar_door_frame[l]) {
306 mekan_mission[l] = MEKAN_MISSION_IDLE;
307 mekan_status[l] = MEKAN_ANIMATION_INVISIBLE;
308 plane_wants_in[mekan_target[l]] = 0;
309 init_player(mekan_target[l]);
310
311
312 }
313 break;
314 }
315
316 break;
317
318 case MEKAN_MISSION_PUSH_OUT:
319
320 if (!mekan_subtarget[l] && hangar_door_frame[l] != 12) {
321 hangar_door_opening[l] = 1;
322
323 }
324
325 if (mekan_subtarget[l] && (player_speed[mekan_target[l]] || !plane_present[mekan_target[l]])) {
326
327 plane_wants_out[mekan_target[l]] = 0;
328
329 }
330
331 if (!plane_wants_out[mekan_target[l]]) {
332 mekan_mission[l] = MEKAN_MISSION_RETURN;
333
334 mekan_status[l] = MEKAN_ANIMATION_WALK;
335
336 if (mekan_x[l] > (hangar_x[l] + 38)) {
337 mekan_direction[l] = MEKAN_DIRECTION_LEFT;
338
339 } else {
340 mekan_direction[l] = MEKAN_DIRECTION_RIGHT;
341
342 }
343
344 break;
345 }
346
347
348 switch (mekan_subtarget[l]) {
349 case MEKAN_PUSH_OUT_WAIT_DOOR_OPEN:
350 if (hangar_door_frame[l] == 12) {
351 plane_present[mekan_target[l]] = 1;
352 plane_coming[mekan_target[l]] = 0;
353 mekan_subtarget[l] = MEKAN_PUSH_OUT_MOVE_TO_PLANE;
354 }
355
356 break;
357 case MEKAN_PUSH_OUT_MOVE_TO_PLANE:
358
359 if (mekan_direction[l] == MEKAN_DIRECTION_RIGHT && mekan_x[l] >= (player_x_8[mekan_target[l]] + 10)) {
360 mekan_x[l] = player_x_8[mekan_target[l]] + 10;
361 mekan_direction[l] = MEKAN_DIRECTION_LEFT;
362
363
364 if (player_angle[mekan_target[l]] < 90 * 256) {
365 mekan_status[l] = MEKAN_ANIMATION_PUSH_PROPELLER;
366
367 } else {
368 mekan_status[l] = MEKAN_ANIMATION_PUSH_TAIL;
369
370 }
371
372 mekan_subtarget[l] = MEKAN_PUSH_OUT_PUSH;
373
374 } else if (mekan_direction[l] == MEKAN_DIRECTION_LEFT && (mekan_x[l] + 13) <= (player_x_8[mekan_target[l]] - 10)) {
375 mekan_x[l] = player_x_8[mekan_target[l]] - 10 - 13;
376 mekan_direction[l] = MEKAN_DIRECTION_RIGHT;
377
378
379 if (player_angle[mekan_target[l]] < 90 * 256) {
380 mekan_status[l] = MEKAN_ANIMATION_PUSH_TAIL;
381
382 } else {
383 mekan_status[l] = MEKAN_ANIMATION_PUSH_PROPELLER;
384
385 }
386
387 mekan_subtarget[l] = MEKAN_PUSH_OUT_PUSH;
388
389 }
390 break;
391
392 case MEKAN_PUSH_OUT_PUSH:
393
394 if (mekan_direction[l] == MEKAN_DIRECTION_RIGHT) {
395 player_x_8[mekan_target[l]] = (mekan_x[l] + 10 + 13);
396 player_x[mekan_target[l]] = player_x_8[mekan_target[l]] << 8;
397
398 if ((mekan_x[l] + 13) >= (leveldata.airfield_x[l] + leveldata.airfield_lenght[l] - PLANE_AIRFIELD_POSITION - 5)) {
399
400 plane_wants_out[mekan_target[l]] = 0;
401 mekan_mission[l] = MEKAN_MISSION_RETURN;
402
403 mekan_status[l] = MEKAN_ANIMATION_WALK;
404
405 if (mekan_x[l] > (hangar_x[l] + 38)) {
406 mekan_direction[l] = MEKAN_DIRECTION_LEFT;
407
408 } else {
409 mekan_direction[l] = MEKAN_DIRECTION_RIGHT;
410
411 }
412
413
414
415 }
416 } else {
417 player_x_8[mekan_target[l]] = (mekan_x[l] - 10);
418 player_x[mekan_target[l]] = player_x_8[mekan_target[l]] << 8;
419
420 if (mekan_x[l] <= (leveldata.airfield_x[l] + PLANE_AIRFIELD_POSITION + 5)) {
421 plane_wants_out[mekan_target[l]] = 0;
422 mekan_mission[l] = MEKAN_MISSION_RETURN;
423
424 mekan_status[l] = MEKAN_ANIMATION_WALK;
425
426 if (mekan_x[l] > (hangar_x[l] + 38)) {
427 mekan_direction[l] = MEKAN_DIRECTION_LEFT;
428
429 } else {
430 mekan_direction[l] = MEKAN_DIRECTION_RIGHT;
431
432 }
433
434
435
436
437
438 }
439
440
441
442 }
443
444
445 break;
446
447
448 }
449
450 break;
451
452
453
454 }
455
456
457 if (hangar_door_frame[l] == 12 && !hangar_door_closing[l]) {
458 if (mekan_status[l] != MEKAN_ANIMATION_PUSH_TAIL) {
459 if (++mekan_frame[l] >= 14) {
460 mekan_frame[l] = 0;
461
462 }
463 } else {
464 if (++mekan_frame[l] >= 9) {
465 mekan_frame[l] = 0;
466
467 }
468 }
469
470 if (mekan_direction[l] == MEKAN_DIRECTION_RIGHT) {
471 mekan_x[l] += 2;
472
473 } else {
474 mekan_x[l] -= 2;
475
476 }
477 }
478
479 /*if(!hangar_door_opening[l] && !hangar_door_closing[l])
480 {
481 if(hangar_door_frame[l])
482 hangar_door_closing[l]=1;
483 else
484 hangar_door_opening[l]=1;
485
486 } */
487
488 }
489
490 do_doors();
491 }
492
check_structs(int x,int y,int number)493 int check_structs(int x, int y, int number) {
494 int l;
495
496 for (l = 0; l < MAX_AA_GUNS; l++)
497 if (kkbase_x[l] && player_sides[kkbase_country[l]] == number && (kkbase_status[l] != 2) && (bombs_going[kkbase_number[l]] == -1)) {
498 if (x >= kkbase_x[l] && x <= (kkbase_x[l] + 25) && y >= (kkbase_y[l] - 5) && y <= (kkbase_y[l] + 30)) {
499 bomb_target = kkbase_number[l];
500
501 return 1;
502 }
503 }
504
505 for (l = 0; l < MAX_STRUCTURES; l++)
506 if (leveldata.struct_owner[l] != 4)
507 if ((structures[l][1] != NULL) && (!struct_state[l]) && (player_sides[leveldata.struct_owner[l]] == number) && (bombs_going[l] == -1)) {
508 if (x >= leveldata.struct_x[l] && x <= (leveldata.struct_x[l] + struct_width[l]) &&
509 y >= (leveldata.struct_y[l] - 5) && y <= (leveldata.struct_y[l] + 5 + struct_heigth[l])) {
510 bomb_target = l;
511 return 1;
512
513 }
514 }
515
516 return 0;
517
518 }
519
check_multi_structs(int x,int y,int number)520 int check_multi_structs(int x, int y, int number) {
521 int l;
522
523 for (l = 0; l < MAX_AA_GUNS; l++)
524 if (kkbase_x[l] && kkbase_country[l] != 4 && player_sides[kkbase_country[l]] != player_sides[number] && (kkbase_status[l] != 2)
525 && (bombs_going[kkbase_number[l]] == -1)) {
526 if (x >= kkbase_x[l] && x <= (kkbase_x[l] + 25) && y >= (kkbase_y[l] - 5) && y <= (kkbase_y[l] + 30)) {
527 bomb_target = kkbase_number[l];
528
529 return 1;
530 }
531 }
532
533 for (l = 0; l < MAX_STRUCTURES; l++)
534 if (leveldata.struct_owner[l] != 4)
535 if ((structures[l][1] != NULL) && (!struct_state[l]) && (player_sides[leveldata.struct_owner[l]] != player_sides[number]) && (bombs_going[l] == -1)) {
536 if (x >= leveldata.struct_x[l] && x <= (leveldata.struct_x[l] + struct_width[l]) &&
537 y >= (leveldata.struct_y[l] - 5) && y <= (leveldata.struct_y[l] + 5 + struct_heigth[l])) {
538 bomb_target = l;
539 return 1;
540
541 }
542 }
543
544 return 0;
545
546 }
547
548
ai_do_bombing(int number)549 void ai_do_bombing(int number) {
550 int fake_y_speed;
551 int fake_x_speed;
552 int fake_x;
553 int fake_y;
554 int side;
555
556 if (player_sides[number] == 1)
557 side = 0;
558 else
559 side = 1;
560
561 //bomb_speed[l]=player_speed[player];
562 //bomb_angle[l]=player_angle[player];
563 fake_x_speed = (cosinit[player_angle[number] >> 8] * player_speed[number]) >> 2;
564 fake_y_speed = (sinit[player_angle[number] >> 8] * player_speed[number]) >> 2;
565 fake_x = player_x[number] + (9 - player_upsidedown[number] * 18) * sinit[player_angle[number] >> 8];
566 fake_y = player_y[number] + (9 - player_upsidedown[number] * 18) * cosinit[player_angle[number] >> 8];
567
568 while (1) {
569
570 fake_y_speed -= BOMB_GRAVITY;
571 fake_x += fake_x_speed >> 9;
572 fake_y -= fake_y_speed >> 9;
573
574 if ((fake_x < 0) | ((fake_x >> 8) >= 2400)) {
575 return;
576 }
577
578 if (fake_y >= 0)
579 if (terrain_level[fake_x >> 8] < (fake_y >> 8) || ((fake_y >> 8) >= 200)) {
580 if (fake_y >= 614400)
581 return;
582
583 if (!playing_solo) {
584 if (check_multi_structs(fake_x >> 8, fake_y >> 8, number)) {
585 player_bombs[number]--;
586 drop_bomb(number, bomb_target);
587 }
588 } else if (check_structs(fake_x >> 8, fake_y >> 8, side)) {
589 player_bombs[number]--;
590 drop_bomb(number, bomb_target);
591 }
592
593 return;
594 }
595
596 }
597
598
599
600 }
601
start_itgun_explosion(int number)602 void start_itgun_explosion(int number) {
603 int l;
604 int distance;
605
606 itgun_sound(itgun_shot_x[number] >> 8);
607
608 for (l = 0; l < MAX_FLYING_OBJECTS; l++)
609 if (!fobjects[l].x)
610 break;
611
612 if (l != MAX_FLYING_OBJECTS) {
613 fobjects[l].x = itgun_shot_x[number];
614 fobjects[l].y = itgun_shot_y[number];
615 fobjects[l].x_speed = 0;
616 fobjects[l].y_speed = 0;
617 fobjects[l].hit_plane = 0;
618 fobjects[l].width = 23;
619 fobjects[l].height = 14;
620 fobjects[l].type = FOBJECTS_ITEXPLOSION;
621 fobjects[l].phase = 0;
622 }
623
624 for (l = 0; l < 16; l++) {
625 if (!plane_present[l])
626 continue;
627
628 calculate_difference(itgun_shot_x[number] >> 8, itgun_shot_y[number] >> 8, player_x_8[l], player_y_8[l], &distance);
629
630 if (distance <= 10)
631 cause_damage(80, l);
632
633 if (distance >= 40)
634 continue;
635
636 cause_damage(40 - distance, l);
637
638 }
639
640 itgun_shot_x[number] = 0;
641
642 }
643
start_it_shot(int x,int y,int angle)644 void start_it_shot(int x, int y, int angle) {
645 int l;
646
647 for (l = 0; l < MAX_ITGUN_SHOTS; l++)
648 if (!itgun_shot_x[l])
649 break;
650
651 if (l != MAX_ITGUN_SHOTS) {
652 itgun_shot_age[l] = wrandom(ITGUN_AGE_VARIETY) + ITGUN_BASE_AGE;
653 itgun_shot_x[l] = (x << 8);
654 itgun_shot_y[l] = (y << 8);
655 itgun_shot_x_speed[l] = (cosinit[angle] * ITGUN_SHOT_SPEED) >> 2;
656 itgun_shot_y_speed[l] = (sinit[angle] * ITGUN_SHOT_SPEED) >> 2;
657 itgun_shot_x[l] += itgun_shot_x_speed[l] >> 6;
658 itgun_shot_y[l] -= itgun_shot_y_speed[l] >> 6;
659 }
660
661
662 }
663
do_it_shots(void)664 void do_it_shots(void) {
665 int l, l2;
666
667 for (l = 0; l < MAX_ITGUN_SHOTS; l++) {
668 if (itgun_shot_x[l]) {
669
670 itgun_shot_y_speed[l] -= ITGUN_SHOT_GRAVITY;
671 itgun_shot_x[l] += itgun_shot_x_speed[l] >> 9;
672 itgun_shot_y[l] -= itgun_shot_y_speed[l] >> 9;
673 if ((itgun_shot_x[l] < 0) || ((itgun_shot_x[l] >> 8) >= NUMBER_OF_SCENES * 160) || (itgun_shot_y[l] >> 8) >= 200 || itgun_shot_y[l] < 0)
674 itgun_shot_x[l] = 0;
675 else if ((level_bitmap[(itgun_shot_x[l] >> 8) + (itgun_shot_y[l] >> 8) * 2400]) < 112
676 || ((level_bitmap[(itgun_shot_x[l] >> 8) + (itgun_shot_y[l] >> 8) * 2400])) > 119)
677 itgun_shot_x[l] = 0;
678
679 if (!(itgun_shot_age[l]--))
680 start_itgun_explosion(l);
681
682 for (l2 = 0; l2 < 16; l2++) {
683 if (plane_present[l2])
684 if (((player_x[l2] + 2304) > itgun_shot_x[l]) &&
685 ((player_x[l2] - 2304) < itgun_shot_x[l]) && ((player_y[l2] + 2304) > itgun_shot_y[l]) && ((player_y[l2] - 2304) < itgun_shot_y[l]))
686 if (plane_p[l2][(player_angle[l2] >> 8) / 6][player_rolling[l2]][player_upsidedown[l2]]
687 [(itgun_shot_x[l] >> 8) - (player_x_8[l2]) + 10 + ((itgun_shot_y[l] >> 8) - (player_y_8[l2]) + 10) * 20] != 255) {
688 start_itgun_explosion(l);
689 break;
690 }
691 }
692 }
693
694 }
695 }
696
infan_to_plane(int l)697 void infan_to_plane(int l) {
698 int l2;
699 int angle;
700 int distance;
701
702 for (l2 = 0; l2 < 16; l2++) {
703 if (!plane_present[l2])
704 continue;
705
706 if (l2 == infan_country[l])
707 continue;
708
709 if (player_sides[infan_country[l]] == player_sides[l2])
710 continue;
711
712 if (abs(player_x_8[l2] - infan_x[l]) > 150)
713 continue;
714
715
716 calculate_difference(infan_x[l] + 7, infan_y[l] + 7, ((player_x[l2] + (player_x_speed[l2] >> 6)) >> 8),
717 ((player_y[l2] - (player_y_speed[l2] >> 7)) >> 8), &distance, &angle);
718
719
720 if ((player_on_airfield[infan_country[l]] || ((abs(player_x_8[l2] - player_x_8[infan_country[l]]) > 150) || !plane_present[infan_country[l]]))
721 && angle <= 180) {
722 infan_state[l] = 1;
723 if (++infan_last_shot[l] > 6) {
724 infan_last_shot[l] = 0;
725 infan_state[l] = 2;
726
727 angle += wrandom(INFANTRY_AIM_RANDOM) - (INFANTRY_AIM_RANDOM >> 1);
728
729 if (angle >= 360)
730 angle -= 360;
731 if (angle < 0)
732 angle += 360;
733
734 start_shot(infan_x[l] + 7, infan_y[l] + 7, angle, INFANT_SHOTS_SPEED, infan_country[l]);
735
736
737 }
738
739 if (angle >= 270 || angle <= 90) {
740 if (angle >= 270)
741 infan_frame[l] = 0;
742 else
743 infan_frame[l] = angle >> 4;
744
745 infan_direction[l] = 1;
746 } else {
747 if (angle > 180)
748 infan_frame[l] = 0;
749 else
750 infan_frame[l] = (180 - angle) >> 4;
751
752 infan_direction[l] = 0;
753 }
754
755 }
756
757
758
759 break;
760 }
761 }
762
infan_to_infan(int l)763 void infan_to_infan(int l) {
764 int l2;
765 int angle;
766 int distance;
767
768 for (l2 = 0; l2 < MAX_INFANTRY; l2++) {
769 if (!infan_x[l2])
770 continue;
771
772 if (infan_country[l2] == infan_country[l])
773 continue;
774
775 if (player_sides[infan_country[l]] == player_sides[infan_country[l2]])
776 continue;
777
778 if (abs(infan_x[l2] - infan_x[l]) > 50)
779 continue;
780
781 calculate_difference(infan_x[l] + 7, infan_y[l] + 7, infan_x[l2] + 7, infan_y[l2] + 7, &distance, &angle);
782
783
784
785 if (angle <= 180) {
786 infan_state[l] = 1;
787 if (++infan_last_shot[l] > 6) {
788 infan_last_shot[l] = 0;
789 infan_state[l] = 2;
790
791 angle += wrandom(INFANTRY_AIM_RANDOM) - (INFANTRY_AIM_RANDOM >> 1);
792
793 if (angle >= 360)
794 angle -= 360;
795 if (angle < 0)
796 angle += 360;
797
798 start_shot(infan_x[l] + 7, infan_y[l] + 7, angle, INFANT_SHOTS_SPEED, infan_country[l]);
799
800
801 }
802
803 if (angle >= 270 || angle <= 90) {
804 if (angle >= 270)
805 infan_frame[l] = 0;
806 else
807 infan_frame[l] = angle >> 4;
808
809 infan_direction[l] = 1;
810 } else {
811 if (angle > 180)
812 infan_frame[l] = 0;
813 else
814 infan_frame[l] = (180 - angle) >> 4;
815
816 infan_direction[l] = 0;
817 }
818
819 }
820
821
822 break;
823 }
824
825
826 }
827
828
infan_to_struct(int l)829 void infan_to_struct(int l) {
830 int l2;
831 ///
832 for (l2 = 0; l2 < MAX_AA_GUNS; l2++)
833 if (kkbase_x[l2] && kkbase_status[l2] != 2 && (leveldata.struct_owner[kkbase_number[l2]] != 4)
834 && (player_sides[leveldata.struct_owner[kkbase_number[l2]]] != player_sides[infan_country[l]])) {
835 if (infan_x[l] + 15 >= kkbase_x[l2] && infan_x[l] <= (kkbase_x[l2] + 26))
836 {
837
838 if (config.flames)
839 start_flame(kkbase_x[l2], kkbase_y[l2] + 21, 26);
840
841 if (playing_solo) {
842 if (leveldata.struct_type[kkbase_number[l2]] == 1)
843 solo_dest_remaining--;
844
845 if (leveldata.struct_type[kkbase_number[l2]] == 2)
846 solo_failed = 1;
847
848 }
849
850 kkbase_status[l2] = 2;
851 kkbase_frame[l2] = 0;
852 struct_state[kkbase_number[l2]] = 1;
853
854
855 }
856 }
857
858 for (l2 = 0; l2 < MAX_STRUCTURES; l2++)
859 if ((structures[l2][1] != NULL) && (leveldata.struct_owner[l2] != 4) && (player_sides[leveldata.struct_owner[l2]] != player_sides[infan_country[l]])
860 && (!struct_state[l2])) {
861 if (infan_x[l] + 15 >= leveldata.struct_x[l2] && infan_x[l] <= (leveldata.struct_x[l2] + struct_width[l2])) {
862 if (config.flames)
863 start_flame(leveldata.struct_x[l2], leveldata.struct_y[l2] + struct_heigth[l2], struct_width[l2]);
864
865 if (playing_solo) {
866 if (leveldata.struct_type[l2] == 1)
867 solo_dest_remaining--;
868
869 if (leveldata.struct_type[l2] == 2)
870 solo_failed = 1;
871
872 }
873
874 struct_state[l2] = 1;
875
876 if (current_mode == SVGA_MODE) {
877
878 structures[l2][1]->blit_to_bitmap(standard_background, leveldata.struct_x[l2] - (leveldata.struct_x[l2] / 800) * 800,
879 leveldata.struct_y[l2] + (leveldata.struct_x[l2] / 800) * 196 - 4);
880
881 structures[l2][1]->blit(leveldata.struct_x[l2] - (leveldata.struct_x[l2] / 800) * 800,
882 leveldata.struct_y[l2] + (leveldata.struct_x[l2] / 800) * 196 - 4);
883
884 if ((leveldata.struct_x[l2] - (leveldata.struct_x[l2] / 800) * 800) + struct_width[l2] > 800)
885 structures[l2][1]->blit(leveldata.struct_x[l2] - (leveldata.struct_x[l2] / 800) * 800 - 800,
886 leveldata.struct_y[l2] + (leveldata.struct_x[l2] / 800 + 1) * 196 - 4);
887 }
888
889 if (leveldata.struct_hit[l2]) {
890 structures[l2][1]->blit_to_bitmap(maisema, leveldata.struct_x[l2], leveldata.struct_y[l2]);
891 }
892
893
894
895 }
896 }
897
898 }
899
900
infan_take_hits(int l)901 void infan_take_hits(int l) {
902 int l2;
903 int soundi;
904
905 for (l2 = wrandom(3); l2 < MAX_SHOTS; l2 += 3) {
906 if (!shots_flying_x[l2])
907 continue;
908
909 if ((shots_flying_x[l2] >> 8) > infan_x[l] && (shots_flying_x[l2] >> 8) < (infan_x[l] + 14) &&
910 (shots_flying_y[l2] >> 8) > infan_y[l] && (shots_flying_y[l2] >> 8) < (infan_x[l] + 13) && shots_flying_infan[l2] != infan_country[l]) {
911 //if(wrandom(3))
912 // continue;
913
914 if (playing_solo) {
915 if (leveldata.struct_type[l] == 1)
916 solo_dest_remaining--;
917
918 if (leveldata.struct_type[l] == 2)
919 solo_failed = 1;
920
921 }
922
923 if (shots_flying_x_speed[l2] > 0) {
924 if (infan_direction[l])
925 infan_state[l] = 5;
926 else
927 infan_state[l] = 3;
928 } else {
929 if (!infan_direction[l])
930 infan_state[l] = 5;
931 else
932 infan_state[l] = 3;
933 }
934
935 start_rifle(infan_x[l], infan_y[l]);
936
937 if (config.infantry_sounds && config.sound_on && config.sfx_on) {
938 soundi = wrandom(18);
939 if (soundi < 9)
940 play_2d_sample(sample_die[soundi], player_x_8[solo_country], infan_x[l]);
941
942 }
943
944
945 infan_frame[l] = 0;
946 shots_flying_x[l2] = 0;
947 break;
948 }
949
950 }
951
952 }
953
954
do_infan(void)955 void do_infan(void) {
956 int l, l2;
957 int angle;
958 int distance;
959 int diff;
960
961 for (l = 0; l < MAX_INFANTRY; l++) {
962 if (!infan_x[l])
963 continue;
964
965 if (infan_state[l] == 1 || infan_state[l] == 2) {
966 infan_direction[l] = wrandom(2);
967 infan_state[l] = 0;
968 }
969
970 if (!infan_state[l] && infan_frame[l] < 12)
971 infan_to_plane(l);
972
973 if (!infan_state[l] && infan_frame[l] < 12)
974 infan_to_infan(l);
975
976 if (!infan_state[l])
977 infan_to_struct(l);
978
979 if (infan_state[l] == 5 || infan_state[l] == 4) {
980 if (++infan_frame[l] >= 20) {
981 infan_x[l] = 0;
982
983 } else {
984 if (infan_state[l] == 4)
985 infan_x[l] += infan_x_speed[l];
986
987 }
988
989 angle = terrain_level[infan_x[l] + 11] - 13;
990 distance = terrain_level[infan_x[l] + 3] - 13;
991
992 angle = ((angle < distance) ? angle : distance) - infan_y[l];
993
994 if (angle > 2)
995 angle = 2;
996
997 if (angle < -2)
998 angle = -2;
999
1000 infan_y[l] += angle;
1001
1002 continue;
1003 }
1004
1005 if (infan_state[l] == 3) {
1006 if (++infan_frame[l] >= 14) {
1007 infan_x[l] = 0;
1008
1009 }
1010
1011 continue;
1012 }
1013
1014 infan_take_hits(l);
1015
1016
1017 if (infan_state[l])
1018 continue;
1019
1020
1021 for (l2 = 0; l2 < 8; l2++) {
1022 if ((infan_x[l] + (infan_direction[l] ? 1 : -1)) == infan_stop[l2]) {
1023 wtoggle(&infan_direction[l]);
1024 break;
1025 }
1026 }
1027
1028
1029 if (l2 == 8
1030 && ((terrain_level[infan_x[l] + (infan_direction[l] ? 14 : 0)] - 2) >
1031 terrain_level[infan_x[l] + (infan_direction[l] ? 14 : 0) + (infan_direction[l] ? 1 : -1)])) {
1032 wtoggle(&infan_direction[l]);
1033
1034 } else {
1035 infan_x[l] += (infan_direction[l] ? 1 : -1);
1036 if (infan_x[l] >= 2400)
1037 infan_x[l] = 0;
1038
1039 }
1040
1041 angle = terrain_level[infan_x[l] + 11] - 13;
1042 distance = terrain_level[infan_x[l] + 3] - 13;
1043
1044 diff = ((angle < distance) ? angle : distance) - infan_y[l];
1045
1046 if (diff > 1) {
1047 infan_y[l] += 2;
1048 infan_frame[l] = 12;
1049 } else {
1050 infan_y[l] += diff;
1051
1052 if (!(++infan_frame[l] == 13)) {
1053
1054 if (infan_frame[l] >= 12)
1055 infan_frame[l] = 0;
1056
1057 }
1058
1059 }
1060
1061 //infan_y[l]=(angle<distance) ? angle : distance;
1062
1063
1064 }
1065 }
1066
do_kkbase(void)1067 void do_kkbase(void) {
1068 int l, l2;
1069 int angle, distance, tdistance;
1070 int tempframe;
1071
1072 for (l = 0; l < MAX_AA_GUNS; l++) {
1073 if (!kkbase_x[l])
1074 continue;
1075
1076 if (kkbase_status[l] == 1)
1077 kkbase_status[l] = 0;
1078
1079 if (kkbase_status[l] == 2 && kkbase_frame[l] < 9) {
1080 kkbase_frame[l]++;
1081 }
1082
1083 if (!kkbase_status[l]) {
1084 for (l2 = 0; l2 < 16; l2++) {
1085 if (kkbase_country[l] == l2)
1086 continue;
1087
1088 if (!plane_present[l2])
1089 continue;
1090
1091 if (player_sides[kkbase_country[l]] == player_sides[l2])
1092 continue;
1093
1094 if (abs(kkbase_x[l] - player_x_8[l2]) < 150) {
1095 calculate_difference(kkbase_x[l] + 13, kkbase_y[l] + 10, player_x_8[l2], player_y_8[l2], &tdistance, &angle);
1096 calculate_difference(kkbase_x[l] + 13, kkbase_y[l] + 10, ((player_x[l2] + ((player_x_speed[l2] >> 8) * (tdistance << 8) / 1700)) >> 8),
1097 ((player_y[l2] + ((player_y_speed[l2] >> 8) * (tdistance << 8) / 1700)) >> 8), &distance, &angle);
1098
1099 if (angle >= 45 && angle <= 135) {
1100 tempframe = (135 - angle) / 13;
1101
1102 if (abs(tempframe - kkbase_frame[l]) > 1) {
1103 if (tempframe > kkbase_frame[l])
1104 kkbase_frame[l]++;
1105 else
1106 kkbase_frame[l]--;
1107
1108 break;
1109 } else
1110 kkbase_frame[l] = tempframe;
1111
1112 if (++kkbase_last_shot[l] > (kkbase_type[l] ? ITGUN_SHOT_RATE : 7)) {
1113 if (++kkbase_shot_number[l] > 6) {
1114 kkbase_last_shot[l] = 0;
1115 kkbase_shot_number[l] = 0;
1116 } else {
1117 if (kkbase_shot_number[l] == 1)
1118 kkbase_sound(kkbase_type[l], kkbase_x[l]);
1119
1120 if (kkbase_type[l]) {
1121 if (kkbase_shot_number[l] == 1) {
1122 kkbase_status[l] = 1;
1123 start_it_shot(kkbase_x[l] + 13, kkbase_y[l] + 10, angle);
1124 } else
1125 kkbase_status[l] = 0;
1126
1127
1128 } else {
1129
1130 if (kkbase_shot_number[l] & 1)
1131 kkbase_status[l] = 1;
1132 else
1133 kkbase_status[l] = 0;
1134
1135 start_shot(kkbase_x[l] + 13, kkbase_y[l] + 10, angle, AA_MG_SHOT_SPEED);
1136 }
1137 }
1138
1139 }
1140
1141 break;
1142 }
1143 }
1144 }
1145
1146
1147 } else {
1148
1149 }
1150
1151
1152
1153 }
1154
1155 }
1156
ai_turn_down(int number)1157 void ai_turn_down(int number) {
1158 int flaggy;
1159
1160 if (going_left)
1161 flaggy = 1;
1162 else
1163 flaggy = 0;
1164
1165 if (!player_upsidedown[number])
1166 wtoggle(&flaggy);
1167
1168 controls_down[number] = flaggy;
1169 controls_up[number] = (1 ^ flaggy) & 1;
1170
1171 }
1172
ai_turn_up(int number)1173 void ai_turn_up(int number) {
1174 int flaggy;
1175
1176 if (going_left)
1177 flaggy = 1;
1178 else
1179 flaggy = 0;
1180
1181 if (!player_upsidedown[number])
1182 wtoggle(&flaggy);
1183
1184 controls_down[number] = (1 ^ flaggy) & 1;
1185 controls_up[number] = flaggy;
1186 }
1187
ai_evade_terrain(int number)1188 void ai_evade_terrain(int number) {
1189 int x_kohta, y_kohta;
1190
1191 x_kohta = ((((player_x_speed[number] * AVOID_TERRAIN_FRAMES) >> 8) + player_x[number]) >> 8);
1192 y_kohta = ((player_y[number] - ((player_y_speed[number] * AVOID_TERRAIN_FRAMES) >> 8)) >> 8) + PLANE_MODIFICATION * 2;
1193 if (x_kohta >= 2400)
1194 x_kohta = 2399;
1195 if (y_kohta >= 200)
1196 y_kohta = 199;
1197 if (x_kohta < 0)
1198 x_kohta = 0;
1199 if (y_kohta < 0)
1200 y_kohta = 0;
1201
1202
1203 if (wide_terrain_level[x_kohta] < y_kohta && !player_on_airfield[number]) {
1204 if (going_up > AI_GOING_UP_LIMIT - AI_ANGLE_MARGINAL)
1205 ai_turn_down(number);
1206
1207 if (going_up < AI_GOING_UP_LIMIT)
1208 ai_turn_up(number);
1209
1210 if (current_mission[number] != AIM_EVADE_TERRAIN) {
1211 current_mission[number] = AIM_EVADE_TERRAIN;
1212 mission_phase[number] = 0;
1213
1214 }
1215
1216 }
1217
1218
1219 }
1220
ai_turnplus(int number)1221 void ai_turnplus(int number) {
1222 int flaggy = 0;
1223
1224 if (player_upsidedown[number])
1225 flaggy = 1;
1226
1227 controls_up[number] = flaggy ? 0 : 1;
1228 controls_down[number] = flaggy;
1229 }
1230
ai_turnminus(int number)1231 void ai_turnminus(int number) {
1232 int flaggy = 0;
1233
1234 if (player_upsidedown[number])
1235 flaggy = 1;
1236
1237 controls_up[number] = flaggy;
1238 controls_down[number] = flaggy ? 0 : 1;
1239 }
1240
1241
do_ai(int number)1242 void do_ai(int number) {
1243 int xdistance, ydistance;
1244 int distance_enemy[16], angle_enemy[16], angle_difference[16];
1245 int flaggy;
1246 int trueangle;
1247 int l;
1248
1249 if (!player_exists[number])
1250 return;
1251
1252 for (flaggy = 0; flaggy < 16; flaggy++) {
1253 if (flaggy == number)
1254 continue;
1255
1256 if (!player_exists[flaggy])
1257 continue;
1258
1259 //calculate_difference(player_x[number]>>8,player_y_8[number]>>8,(player_x[flaggy]>>8),(player_y[flaggy]>>8),&distance_enemy[flaggy],&angle_enemy[flaggy]);
1260 calculate_difference(player_x_8[number], player_y_8[number], ((player_x[flaggy] + (player_x_speed[flaggy] >> 7)) >> 8),
1261 ((player_y[flaggy] - (player_y_speed[flaggy] >> 7)) >> 8), &distance_enemy[flaggy], &angle_enemy[flaggy]);
1262
1263 angle_difference[flaggy] = abs((player_angle[number] >> 8) - angle_enemy[flaggy]);
1264 if (angle_difference[flaggy] > 180) {
1265 angle_difference[flaggy] = abs(angle_difference[flaggy] - 360);
1266 }
1267 }
1268
1269
1270 if ((player_angle[number] <= 69120) && (player_angle[number] > 23040))
1271 going_left = 1;
1272 else
1273 going_left = 0;
1274
1275 if ((player_angle[number] < 46080)) {
1276 going_up = player_angle[number];
1277 if (going_up > 23040)
1278 going_up = 46080 - going_up;
1279 } else
1280 going_up = 0;
1281
1282 controls_down[number] = 0;
1283 controls_up[number] = 0;
1284
1285 if (player_angle[number] >= 57600 && player_angle[number] <= 80640)
1286 controls_power[number] = 0;
1287 else
1288 controls_power[number] = 1;
1289
1290
1291 switch (current_mission[number]) {
1292 case AIM_TAKEOFF:
1293 if ((player_y_8[number]) + 40 > terrain_level[player_x_8[number]])
1294 mission_phase[number] = 0;
1295 else
1296 current_mission[number] = AIM_NOMISSION;
1297
1298 ai_evade_terrain(number);
1299 break;
1300
1301 case AIM_LAND:
1302 switch (mission_phase[number]) {
1303 case 0:
1304 if ((player_upsidedown[number] && (!going_left)) || (!player_upsidedown[number] && (going_left)))
1305 if (!player_rolling[number])
1306 player_rolling[number] = 1;
1307
1308
1309
1310
1311 if (going_left) {
1312 xdistance = -((leveldata.airfield_x[player_tsides[number]] + (leveldata.airfield_lenght[player_tsides[number]] >> 1)) - player_x_8[number]);
1313
1314 } else {
1315 xdistance = ((leveldata.airfield_x[player_tsides[number]] + (leveldata.airfield_lenght[player_tsides[number]] >> 1)) - player_x_8[number]);
1316
1317 }
1318
1319 ydistance = leveldata.airfield_y[player_tsides[number]] - player_y_8[number];
1320
1321 if (xdistance < -9) {
1322 current_mission[number] = AIM_TAKEOFF;
1323 mission_phase[number] = 0;
1324
1325
1326 }
1327
1328 int initial_turn;
1329 int mass;
1330 int turn_temp;
1331 mass = plane_mass[number];
1332 mass += player_ammo[number] / 10;
1333 if (plane_bombs[number] != 6)
1334 mass += player_bombs[number] * 12;
1335 else
1336 mass += player_bombs[number] * 10;
1337
1338 mass += player_gas[number] / 160;
1339
1340 initial_turn = (plane_manover[number] << 8) / (mass + 200);
1341 turn_temp = 1 + (((player_speed[number] - 768) / 20) >> 8);
1342 if (!turn_temp)
1343 turn_temp = 1;
1344 initial_turn /= turn_temp;
1345
1346 if (going_left) {
1347 if (player_angle[number] >= ((180 + HIT_ANGLE) << 8)) {
1348 controls_up[number] = 1;
1349 controls_down[number] = 0;
1350
1351 }
1352 } else {
1353 if ((player_angle[number] <= ((360 - HIT_ANGLE) << 8)) && player_angle[number] > 50000) {
1354 controls_up[number] = 1;
1355 controls_down[number] = 0;
1356
1357 }
1358 }
1359
1360
1361
1362 if (ydistance > (xdistance / 3)) {
1363 if (going_left) {
1364 if (player_angle[number] < ((180 + HIT_ANGLE) << 8) - initial_turn) {
1365 controls_up[number] = 0;
1366 controls_down[number] = 1;
1367
1368 }
1369 } else {
1370 if ((player_angle[number] > ((360 - HIT_ANGLE) << 8) + initial_turn) || player_angle[number] < 23041) {
1371 controls_up[number] = 0;
1372 controls_down[number] = 1;
1373
1374 }
1375
1376 }
1377
1378 if (player_speed[number] < 850) {
1379 controls_power[number] = 1;
1380
1381 } else {
1382 controls_power[number] = 0;
1383 if (!controls_up[number] && !controls_down[number]) {
1384 controls_up[number] = 1;
1385 controls_down[number] = 1;
1386
1387
1388 }
1389
1390 }
1391
1392
1393
1394 } else {
1395 if (going_left) {
1396 if (player_angle[number] > ((180 - TAIL_HIT_ANGLE) << 8)) {
1397 controls_up[number] = 1;
1398 controls_down[number] = 0;
1399
1400 }
1401 } else {
1402 if (player_angle[number] < ((TAIL_HIT_ANGLE) << 8) || player_angle[number] > 69119) {
1403 controls_up[number] = 1;
1404 controls_down[number] = 0;
1405
1406 }
1407
1408 }
1409
1410 if (player_speed[number] < 2048) {
1411 controls_power[number] = 1;
1412
1413 } else {
1414 controls_power[number] = 0;
1415
1416 }
1417
1418
1419
1420
1421 }
1422
1423
1424 if (player_on_airfield[number]) {
1425 mission_phase[number] = 1;
1426
1427 }
1428
1429 break;
1430
1431 case 1:
1432
1433 controls_up[number] = 1;
1434 controls_down[number] = 1;
1435 controls_power[number] = 0;
1436
1437 break;
1438
1439 }
1440
1441
1442
1443 break;
1444
1445
1446 case AIM_IMMELMAN:
1447 switch (mission_phase[number]) {
1448 case 0:
1449 mission_phase[number] = 1;
1450 controls_power[number] = 1;
1451 controls_up[number] = 0;
1452 controls_down[number] = 1;
1453 mission_target[number] = going_left ? 0 : 1;
1454 break;
1455
1456 case 1:
1457 if (player_speed[number] > 2700 && (player_y_8[number]) > 100) {
1458 mission_phase[number] = 2;
1459
1460 }
1461 if (player_speed[number] < 4000)
1462 controls_power[number] = 1;
1463 else
1464 controls_power[number] = 0;
1465
1466 controls_up[number] = 0;
1467 controls_down[number] = 0;
1468
1469 if (going_left && (player_angle[number] < (190 * 256)))
1470 controls_down[number] = 1;
1471 else if ((!going_left) && (player_angle[number] > (350 * 256) || player_angle[number] < (90 * 256)))
1472 controls_down[number] = 1;
1473 break;
1474
1475 case 2:
1476 if (mission_target[number] == 0) {
1477 if (!going_left && player_angle[number] > 69120) {
1478 current_mission[number] = AIM_NOMISSION;
1479 break;
1480 }
1481 } else {
1482 if (going_left && player_angle[number] > 46080) {
1483 current_mission[number] = AIM_NOMISSION;
1484 break;
1485 }
1486 }
1487
1488 controls_power[number] = 1;
1489 controls_up[number] = 1;
1490 controls_down[number] = 0;
1491
1492 break;
1493
1494
1495 }
1496
1497
1498 break;
1499
1500 case AIM_SPLITS:
1501 switch (mission_phase[number]) {
1502 case 0:
1503 if ((player_upsidedown[number] && (going_left)) || (!player_upsidedown[number] && (!going_left)))
1504 if (!player_rolling[number])
1505 player_rolling[number] = 1;
1506 mission_phase[number] = 1;
1507 controls_power[number] = 0;
1508 mission_target[number] = going_left ? 0 : 1;
1509 ai_turn_up(number);
1510 break;
1511
1512 case 1:
1513 if (!player_rolling[number] && player_speed[number] < 1000) {
1514 mission_phase[number] = 2;
1515 controls_up[number] = 1;
1516 controls_down[number] = 0;
1517 }
1518
1519 if (going_up) {
1520 controls_up[number] = 1;
1521 controls_down[number] = 1;
1522 } else {
1523 ai_turn_up(number);
1524
1525 }
1526
1527 controls_power[number] = 0;
1528 break;
1529
1530 case 2:
1531 if (mission_target[number] == 0) {
1532 if (!going_left && player_angle[number] > 0) {
1533 mission_phase[number] = 3;
1534 break;
1535 }
1536 } else {
1537 if (going_left && player_angle[number] < 46080) {
1538 mission_phase[number] = 3;
1539 break;
1540 }
1541 }
1542 controls_up[number] = 1;
1543 controls_down[number] = 0;
1544 controls_power[number] = 0;
1545
1546 break;
1547
1548 case 3:
1549 if (going_up < 750)
1550 ai_turn_up(number);
1551 else
1552 current_mission[number] = AIM_NOMISSION;
1553 break;
1554
1555 }
1556
1557 break;
1558
1559 case AIM_FLY_LEVEL:
1560
1561 break;
1562
1563
1564
1565
1566 case AIM_BOMB_STRUCTURE:
1567
1568 break;
1569
1570 case AIM_CHASE_PLANE:
1571 if ((!player_ammo[number]) || distance_enemy[mission_target[number]] > AIM_GIVEUPFIGHT_DISTANCE || !plane_present[mission_target[number]]) {
1572 current_mission[number] = AIM_NOMISSION;
1573
1574 } else {
1575 distances[number] = distance_enemy[mission_target[number]];
1576 angles[number] = angle_enemy[mission_target[number]];
1577
1578 trueangle = (player_angle[number] >> 8) - angle_enemy[mission_target[number]];
1579 if (abs(trueangle) > 180) {
1580 if (trueangle < 0) {
1581 trueangle += 360;
1582 } else {
1583 trueangle -= 360;
1584
1585 }
1586 }
1587
1588
1589 if (trueangle > 0) {
1590
1591 ai_turnminus(number);
1592 }
1593 if (trueangle < 0) {
1594
1595 ai_turnplus(number);
1596 }
1597 }
1598 /// nysv�yslause
1599
1600 if (controls_up[number] && player_speed[number] < (1800)) {
1601
1602 if (going_up && (player_angle[number] > 32000 || player_angle[number] < 14080)) {
1603 ai_turn_down(number);
1604
1605 }
1606
1607
1608 } else if (controls_up[number] && player_speed[number] < (2350 + (player_bombs[number] << 6))) {
1609
1610 if (!going_up) {
1611 controls_up[number] = 0;
1612 controls_down[number] = 0;
1613
1614 }
1615
1616 }
1617
1618 case AIM_NOMISSION:
1619 if (current_mission[number] != AIM_CHASE_PLANE)
1620 for (l = 0; l < 16; l++) {
1621 if (l == number)
1622 continue;
1623
1624 if (!plane_present[l])
1625 continue;
1626
1627 if (player_sides[number] == player_sides[l])
1628 continue;
1629
1630 if (player_ammo[number] && distance_enemy[l] < AI_ATTACK_DISTANCE) {
1631 current_mission[number] = AIM_CHASE_PLANE;
1632 mission_target[number] = l;
1633
1634
1635 }
1636 }
1637
1638 if ((player_x_8[number] < (120 + ((player_speed[number]) / 40)) && going_left) ||
1639 (player_x_8[number] > (2280 - ((player_speed[number]) / 40)) && !going_left)) {
1640 if ((wide_terrain_level[player_x_8[number]] - (player_y_8[number])) > ((player_y_8[number]) + 15))
1641 current_mission[number] = AIM_SPLITS;
1642 else
1643 current_mission[number] = AIM_IMMELMAN;
1644 mission_phase[number] = 0;
1645
1646 } else if ((player_upsidedown[number] && (!going_left)) || (!player_upsidedown[number] && (going_left)))
1647 if (!player_rolling[number])
1648 player_rolling[number] = 1;
1649
1650 ai_evade_terrain(number);
1651
1652 break;
1653
1654 case AIM_EVADE_TERRAIN:
1655
1656 if ((player_x[number] < (80 + (player_speed[number] >> 5)) * 256 && going_left) ||
1657 (player_x[number] > (2320 - (player_speed[number] >> 5)) * 256 && !going_left)) {
1658 if ((wide_terrain_level[player_x_8[number]] - (player_y_8[number])) > ((player_y_8[number]) + 15))
1659 current_mission[number] = AIM_SPLITS;
1660 else
1661 current_mission[number] = AIM_IMMELMAN;
1662 mission_phase[number] = 0;
1663
1664 break;
1665 } else if ((player_upsidedown[number] && (!going_left)) || (!player_upsidedown[number] && (going_left)))
1666 if (!player_rolling[number])
1667 player_rolling[number] = 1;
1668
1669 ai_evade_terrain(number);
1670
1671 mission_phase[number]++;
1672 if (mission_phase[number] >= 24)
1673 current_mission[number] = AIM_NOMISSION;
1674 break;
1675
1676
1677 }
1678
1679
1680 if ((player_on_airfield[number] - 1) == player_tsides[number]
1681 && !player_speed[number] && (!player_gas[number] || current_mission[number] == AIM_LAND)) {
1682 plane_wants_in[number] = 1;
1683
1684 }
1685
1686 if ((!player_bombs[number] && !player_ammo[number]) || player_gas[number] < 500 || current_mission[number] == AIM_HEAD_FOR_HOME) {
1687
1688 if (leveldata.plane_direction[player_tsides[number]]) {
1689 if (going_left) {
1690
1691 xdistance = -((leveldata.airfield_x[player_tsides[number]] + (leveldata.airfield_lenght[player_tsides[number]] >> 1)) - player_x_8[number]);
1692 } else {
1693 xdistance = 600;
1694
1695 }
1696 } else {
1697 if (!going_left) {
1698 xdistance = ((leveldata.airfield_x[player_tsides[number]] + (leveldata.airfield_lenght[player_tsides[number]] >> 1)) - player_x_8[number]);
1699 } else {
1700 xdistance = 600;
1701
1702 }
1703 }
1704
1705 ydistance = leveldata.airfield_y[player_tsides[number]] - player_y_8[number];
1706
1707
1708 if ((xdistance < 600) && (xdistance > 100) && (ydistance + 5 > (xdistance / 3)) && (ydistance - 5 < (xdistance / 3))) {
1709
1710 if (player_speed[number] < 2000 || (ydistance > 130) || (ydistance - (player_speed[number] >> 6)) > 0) {
1711 current_mission[number] = AIM_LAND;
1712 mission_phase[number] = 0;
1713 }
1714 }
1715
1716
1717
1718 }
1719
1720
1721 if (going_up && player_y[number] <= 5120)
1722 ai_turn_down(number);
1723
1724
1725 if (player_bombs[number] && !in_closing[number]) {
1726
1727 if (((player_angle[number] <= 23040 || player_angle[number] >= 69120) && !player_upsidedown[number]) ||
1728 ((player_angle[number] >= 23040 && player_angle[number] <= 69120) && player_upsidedown[number]))
1729 ai_do_bombing(number);
1730
1731 }
1732
1733
1734
1735
1736 if (player_spinning[number]) {
1737 if (!player_rolling[number])
1738 player_rolling[number] = 1;
1739 }
1740
1741 if (spinning_remaining[number]) {
1742 spinning_remaining[number]--;
1743 if (!player_rolling[number])
1744 player_rolling[number] = 1;
1745 }
1746
1747 if (plane_present[number] && player_ammo[number] && (player_last_shot[number] > SHOTS_RATE)) {
1748 for (flaggy = 0; flaggy < 16; flaggy++) {
1749 if (flaggy == number)
1750 continue;
1751
1752 if (!plane_present[flaggy])
1753 continue;
1754
1755 if (player_sides[number] != player_sides[flaggy])
1756 continue;
1757
1758
1759 if (distance_enemy[flaggy] < (SHOT_AT_RANGE - 20) && angle_difference[flaggy] < 8) {
1760 return;
1761
1762 }
1763 }
1764
1765 for (flaggy = 0; flaggy < 16; flaggy++) {
1766
1767 if (!plane_present[flaggy])
1768 continue;
1769
1770 if (player_sides[number] == player_sides[flaggy])
1771 continue;
1772
1773 if (distance_enemy[flaggy] < SHOT_AT_RANGE && angle_difference[flaggy] < SHOT_AT_ANGLE) {
1774
1775 start_shot(number);
1776 break;
1777 }
1778 }
1779 }
1780 }
1781