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