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 /* Triplane Turmoil flying objects code */
22
23 #include "world/constants.h"
24 #include "triplane.h"
25 #include "tripai.h"
26 #include "util/wutil.h"
27 #include "world/plane.h"
28 #include "io/sound.h"
29 #include "world/tripaudio.h"
30
31 void do_shots(void);
32 void start_shot(int player);
33 void start_shot(int x, int y, int angle, int speed, int infan = -1);
34 void do_fobjects(void);
35 void start_smoke(int player);
36 void start_ssmoke(int x, int y);
37 void detect_damage(void);
38 void start_parts(int player);
39 void start_rifle(int x, int y);
40 void start_gun_wave(int x);
41 void drop_bomb(int player, int target = -1);
42 void do_bombs(void);
43 void start_bomb_explo(int l, int hitted = 0);
44 void start_explox(int x, int y);
45 void start_wave(int x);
46 void start_flame(int x, int y, int width);
47 void do_flames(void);
48 void start_one_flame(int x, int y);
49
50 int flame_x[MAX_FLAMES];
51 int flame_y[MAX_FLAMES];
52 int flame_width[MAX_FLAMES];
53 int flame_age[MAX_FLAMES];
54
55 /******************************************************************************/
56
start_flame(int x,int y,int width)57 void start_flame(int x, int y, int width) {
58 int l;
59
60 for (l = 0; l < MAX_FLAMES; l++)
61 if (!flame_x[l])
62 break;
63
64 if (l == MAX_FLAMES)
65 return;
66
67 flame_x[l] = x + 3;
68 flame_y[l] = y - 7;
69 flame_width[l] = width - 6;
70 flame_age[l] = FLAME_AGE;
71 }
72
do_flames(void)73 void do_flames(void) {
74 int l;
75
76 for (l = 0; l < MAX_FLAMES; l++) {
77 if (!flame_x[l])
78 continue;
79
80 if (!(--flame_age[l])) {
81 flame_x[l] = 0;
82 continue;
83
84 }
85
86
87 start_one_flame(flame_x[l] + wrandom(flame_width[l]), flame_y[l]);
88
89 }
90
91 }
92
start_one_flame(int x,int y)93 void start_one_flame(int x, int y) {
94 int l;
95
96 for (l = 0; l < MAX_FLYING_OBJECTS; l++)
97 if (!fobjects[l].x)
98 break;
99
100 if (l != MAX_FLYING_OBJECTS) {
101 fobjects[l].x = x << 8;
102 fobjects[l].y = y << 8;
103
104 fobjects[l].x_speed = 0;
105 fobjects[l].y_speed = 0;
106 fobjects[l].hit_plane = 0;
107 fobjects[l].width = 7;
108 fobjects[l].height = 14;
109 fobjects[l].type = FOBJECTS_FLAME;
110 fobjects[l].phase = 0;
111 }
112
113 }
114
115
do_shots(void)116 void do_shots(void) {
117 int l, l2;
118 unsigned char kohta;
119
120 for (l = 0; l < MAX_SHOTS; l++) {
121 if (shots_flying_x[l]) {
122
123 shots_flying_y_speed[l] -= SHOTS_GRAVITY;
124 shots_flying_x[l] += shots_flying_x_speed[l] >> 9;
125 shots_flying_y[l] -= shots_flying_y_speed[l] >> 9;
126
127 if ((shots_flying_x[l] < 0) || ((shots_flying_x[l] >> 8) >= NUMBER_OF_SCENES * 160) || shots_flying_y[l] < 0 || (shots_flying_y[l] >> 8) >= 200)
128 shots_flying_x[l] = 0;
129 else {
130 kohta = level_bitmap[(shots_flying_x[l] >> 8) + (shots_flying_y[l] >> 8) * 2400];
131 if (kohta < 112 || kohta > 119) {
132 if (kohta >= 224 && kohta <= 231)
133 start_gun_wave(shots_flying_x[l] >> 8);
134
135 shots_flying_x[l] = 0;
136 }
137 }
138
139 if ((shots_flying_age[l]++) > SHOTS_RANGE)
140 shots_flying_x[l] = 0;
141
142 for (l2 = 0; l2 < 16; l2++) {
143 if (plane_present[l2])
144 if (((player_x[l2] + 2304) > shots_flying_x[l]) &&
145 ((player_x[l2] - 2304) < shots_flying_x[l]) &&
146 ((player_y[l2] + 2304) > shots_flying_y[l]) && ((player_y[l2] - 2304) < shots_flying_y[l]))
147 if (plane_p[l2][(player_angle[l2] >> 8) / 6][player_rolling[l2]][player_upsidedown[l2]]
148 [(shots_flying_x[l] >> 8) - (player_x_8[l2]) + 10 + ((shots_flying_y[l] >> 8) - (player_y_8[l2]) + 10) * 20] != 255) {
149
150 if (config.sound_on && config.sfx_on)
151 play_2d_sample(sample_hit[wrandom(4)], player_x_8[solo_country], player_x_8[l2]);
152
153 shots_flying_x[l] = 0;
154
155 if (shots_flying_owner[l] != -1) {
156 player_hits[shots_flying_owner[l]]++;
157 player_endurance[l2] -= wrandom(12);
158 } else
159 player_endurance[l2] -= wrandom(6);
160
161 if (player_endurance[l2] < 1) {
162 if (!player_spinning[l2] && !in_closing[l2]) {
163 if (shots_flying_owner[l] != -1) {
164 if (player_sides[l2] != player_sides[shots_flying_owner[l]]) {
165 player_points[shots_flying_owner[l]]++;
166
167 } else {
168 player_points[shots_flying_owner[l]]--;
169 }
170
171 player_shots_down[shots_flying_owner[l]][l2]++;
172 }
173 }
174 if (wrandom(4) && (!player_on_airfield[l2]))
175 player_spinning[l2] = 1;
176 else {
177 in_closing[l2] = 2;
178 plane_present[l2] = 0;
179 start_parts(l2);
180 }
181 }
182 break;
183 }
184 }
185 }
186
187
188 }
189
190 }
191
start_shot(int x,int y,int angle,int speed,int infan)192 void start_shot(int x, int y, int angle, int speed, int infan) {
193 int l;
194
195 for (l = 0; l < MAX_SHOTS; l++)
196 if (!shots_flying_x[l])
197 break;
198
199 if (l != MAX_SHOTS) {
200 shots_flying_age[l] = 0;
201 shots_flying_x[l] = (x << 8);
202 shots_flying_y[l] = (y << 8);
203 shots_flying_x_speed[l] = (cosinit[angle] * speed) >> 2;
204 shots_flying_y_speed[l] = (sinit[angle] * speed) >> 2;
205 shots_flying_x[l] += shots_flying_x_speed[l] >> 6;
206 shots_flying_y[l] -= shots_flying_y_speed[l] >> 6;
207 shots_flying_owner[l] = -1;
208 shots_flying_infan[l] = infan;
209 }
210
211 }
212
213
start_shot(int player)214 void start_shot(int player) {
215 int l;
216 int plane_type = player;
217
218 player_last_shot[player] = 0;
219
220 if (in_closing[player])
221 return;
222
223 player_fired[player]++;
224 player_ammo[player]--;
225 for (l = 0; l < MAX_SHOTS; l++)
226 if (!shots_flying_x[l])
227 break;
228
229 if (l != MAX_SHOTS) {
230 shots_flying_age[l] = 0;
231 shots_flying_x[l] = player_x[player] + 12 * cosinit[player_angle[player] >> 8];
232 shots_flying_y[l] = player_y[player] - 12 * sinit[player_angle[player] >> 8];
233 shots_flying_x_speed[l] = (cosinit[player_angle[player] >> 8] * (player_speed[player] + SHOTS_SPEED)) >> 2;
234 shots_flying_y_speed[l] = (sinit[player_angle[player] >> 8] * (player_speed[player] + SHOTS_SPEED)) >> 2;
235 shots_flying_owner[l] = player;
236 shots_flying_infan[l] = -1;
237 }
238 if (config.gunshot_sounds && config.sound_on && config.sfx_on) {
239 if (plane_type == 0 || plane_type > 3)
240 plane_type = 1;
241 play_2d_sample(sample_konsu[plane_type], player_x_8[solo_country], player_x_8[player]);
242 }
243 }
244
do_fobjects(void)245 void do_fobjects(void) {
246 int l, l2;
247
248 for (l = 0; l < MAX_FLYING_OBJECTS; l++) {
249 if (fobjects[l].x) {
250
251 fobjects[l].x += fobjects[l].x_speed >> 8;
252 fobjects[l].y -= fobjects[l].y_speed >> 8;
253
254 if ((fobjects[l].y < 0) || (fobjects[l].x < 0) || ((fobjects[l].x >> 8) >= NUMBER_OF_SCENES * 160) || (fobjects[l].y >> 8) >= 200) {
255 fobjects[l].x = 0;
256 continue;
257 }
258
259 if ((level_bitmap[(fobjects[l].x >> 8) + (fobjects[l].y >> 8) * 2400]) < 112
260 || ((level_bitmap[(fobjects[l].x >> 8) + (fobjects[l].y >> 8) * 2400])) > 119) {
261 fobjects[l].x = 0;
262 continue;
263 }
264
265 if (fobjects[l].hit_plane && part_collision_detect)
266 for (l2 = 0; l2 < 16; l2++) {
267 if (plane_present[l2]) {
268 if (((player_x[l2] + 2304) > fobjects[l].x) &&
269 ((player_x[l2] - 2304) < fobjects[l].x) && ((player_y[l2] + 2304) > fobjects[l].y) && ((player_y[l2] - 2304) < fobjects[l].y))
270 if (plane_p[l2][(player_angle[l2] >> 8) / 6][player_rolling[l2]][player_upsidedown[l2]]
271 [(fobjects[l].x >> 8) - (player_x_8[l2]) + 10 + ((fobjects[l].y >> 8) - (player_y_8[l2]) + 10) * 20] != 255) {
272 fobjects[l].x = 0;
273 player_endurance[l2] -= wrandom(FOBJECTS_DAMAGE);
274 if (player_endurance[l2] < 1) {
275 if ((fobjects[l].owner != -1) && (!player_spinning[l2])) {
276 player_shots_down[fobjects[l].owner][l2]++;
277 if (player_sides[fobjects[l].owner] != player_sides[l2])
278 player_points[fobjects[l].owner]++;
279 else
280 player_points[fobjects[l].owner]--;
281 }
282
283 if (wrandom(2) == 1 && (!player_on_airfield[l2]))
284 player_spinning[l2] = 1;
285 else {
286 in_closing[l2] = 2;
287 plane_present[l2] = 0;
288 start_parts(l2);
289 }
290 }
291 break;
292 }
293 }
294 }
295
296
297
298 switch (fobjects[l].type) {
299 case FOBJECTS_SMOKE:
300 fobjects[l].phase++;
301 if (fobjects[l].phase == SMOKE_FRAMES)
302 fobjects[l].x = 0;
303 break;
304
305 case FOBJECTS_SSMOKE:
306 fobjects[l].phase++;
307 if (fobjects[l].phase == 17)
308 fobjects[l].x = 0;
309 break;
310
311
312 case FOBJECTS_RIFLE:
313 fobjects[l].phase++;
314 if (fobjects[l].phase == 12)
315 fobjects[l].phase = 0;
316 fobjects[l].y_speed -= FOBJECTS_GRAVITY;
317 break;
318
319
320 case FOBJECTS_WAVE1:
321 fobjects[l].phase++;
322 if (fobjects[l].phase == WAVE1_FRAMES)
323 fobjects[l].x = 0;
324 break;
325
326 case FOBJECTS_WAVE2:
327 fobjects[l].phase++;
328 if (fobjects[l].phase == WAVE2_FRAMES)
329 fobjects[l].x = 0;
330 break;
331
332
333 case FOBJECTS_ITEXPLOSION:
334 fobjects[l].phase++;
335 if (fobjects[l].phase == ITEXPLOSION_FRAMES)
336 fobjects[l].x = 0;
337 break;
338
339
340 case FOBJECTS_PARTS:
341 fobjects[l].y_speed -= FOBJECTS_GRAVITY;
342 break;
343
344 case FOBJECTS_EXPLOX:
345 fobjects[l].phase++;
346 if (fobjects[l].phase == EXPLOX_FRAMES)
347 fobjects[l].x = 0;
348 break;
349
350 case FOBJECTS_FLAME:
351 fobjects[l].phase++;
352 if (fobjects[l].phase == NUMBER_OF_FLAMES)
353 fobjects[l].x = 0;
354
355 if (config.structure_smoke)
356 if (fobjects[l].phase & 3)
357 start_ssmoke(fobjects[l].x, fobjects[l].y - 256);
358 break;
359 }
360 }
361 }
362 }
363
364
start_wave(int x)365 void start_wave(int x) {
366 int l;
367
368 for (l = 0; l < MAX_FLYING_OBJECTS; l++)
369 if (!fobjects[l].x)
370 break;
371
372 if (l != MAX_FLYING_OBJECTS) {
373 fobjects[l].x = (x) << 8;
374 fobjects[l].y = (terrain_level[x] - 11) << 8;
375 fobjects[l].x_speed = 0;
376 fobjects[l].y_speed = 0;
377 fobjects[l].hit_plane = 0;
378 fobjects[l].width = 23;
379 fobjects[l].height = 23;
380 fobjects[l].type = FOBJECTS_WAVE1;
381 fobjects[l].phase = 0;
382 }
383
384 }
385
start_gun_wave(int x)386 void start_gun_wave(int x) {
387 int l;
388
389 for (l = 0; l < MAX_FLYING_OBJECTS; l++)
390 if (!fobjects[l].x)
391 break;
392
393 if (l != MAX_FLYING_OBJECTS) {
394 fobjects[l].x = (x) << 8;
395 fobjects[l].y = (terrain_level[x] - 2) << 8;
396 fobjects[l].x_speed = 0;
397 fobjects[l].y_speed = 0;
398 fobjects[l].hit_plane = 0;
399 fobjects[l].width = 3;
400 fobjects[l].height = 5;
401 fobjects[l].type = FOBJECTS_WAVE2;
402 fobjects[l].phase = 0;
403 }
404
405 }
406
407
start_smoke(int player)408 void start_smoke(int player) {
409 int l;
410
411 for (l = 0; l < MAX_FLYING_OBJECTS; l++)
412 if (!fobjects[l].x)
413 break;
414
415 if (l != MAX_FLYING_OBJECTS) {
416 fobjects[l].x = player_x[player] - 12 * cosinit[player_angle[player] >> 8];
417 fobjects[l].y = player_y[player] + 12 * sinit[player_angle[player] >> 8];
418
419 fobjects[l].x_speed = 0;
420 fobjects[l].y_speed = 0;
421 fobjects[l].hit_plane = 0;
422 fobjects[l].width = 20;
423 fobjects[l].height = 20;
424 fobjects[l].type = FOBJECTS_SMOKE;
425 fobjects[l].phase = 0;
426 }
427
428 }
429
start_ssmoke(int x,int y)430 void start_ssmoke(int x, int y) {
431 int l;
432
433 for (l = 0; l < MAX_FLYING_OBJECTS; l++)
434 if (!fobjects[l].x)
435 break;
436
437 if (l != MAX_FLYING_OBJECTS) {
438
439 fobjects[l].x = x;
440 fobjects[l].y = y - 1024 + wrandom(2048);
441
442 fobjects[l].x_speed = 0;
443 fobjects[l].y_speed = 256 * 256 * 3;
444 fobjects[l].hit_plane = 0;
445 fobjects[l].width = 9;
446 fobjects[l].height = 9;
447 fobjects[l].type = FOBJECTS_SSMOKE;
448 fobjects[l].phase = 0;
449 }
450
451 }
452
453
start_explox(int x,int y)454 void start_explox(int x, int y) {
455 int l;
456 int l2;
457 int number_of_exps;
458
459 number_of_exps = wrandom(EXPLOX_RANDOM) + EXPLOX_CONST;
460
461 for (l2 = 0; l2 < number_of_exps; l2++) {
462
463
464 for (l = 0; l < MAX_FLYING_OBJECTS; l++)
465 if (!fobjects[l].x)
466 break;
467
468 if (l != MAX_FLYING_OBJECTS) {
469 fobjects[l].x = x + wrandom(EXPLOX_VARIETY) - (EXPLOX_VARIETY / 2);
470 fobjects[l].y = y + wrandom(EXPLOX_VARIETY) - (EXPLOX_VARIETY / 2);
471
472 fobjects[l].x_speed = 0;
473 fobjects[l].y_speed = 0;
474 fobjects[l].hit_plane = 0;
475 fobjects[l].width = 9;
476 fobjects[l].height = 9;
477 fobjects[l].type = FOBJECTS_EXPLOX;
478 fobjects[l].subtype = wrandom(4);
479 fobjects[l].phase = 0 - wrandom(EXPLOX_PHASE_DIFF);
480
481 }
482 }
483 }
484
detect_damage(void)485 void detect_damage(void) {
486 int l;
487
488 for (l = 0; l < 16; l++) {
489 if (!player_exists[l])
490 continue;
491
492 if (wrandom(plane_mass[l] >> 4) >= player_endurance[l])
493 if (wrandom(2))
494 start_smoke(l);
495
496 }
497 }
498
start_parts(int player)499 void start_parts(int player) {
500 int l, l2, limit;
501 int xxx, yyy;
502 int xsss;
503
504 limit = wrandom(NUMBER_OF_EXPLOSION_PARTS);
505
506 start_explox(player_x[player], player_y[player]);
507
508 xxx = player_x[player] - 12 * cosinit[player_angle[player] >> 8];
509 yyy = player_y[player] + 12 * sinit[player_angle[player] >> 8];
510 xsss = (cosinit[player_angle[player] >> 8] * (player_speed[player])) >> 2;
511
512 for (l2 = 0; l2 < limit; l2++) {
513 for (l = 0; l < MAX_FLYING_OBJECTS; l++)
514 if (!fobjects[l].x)
515 break;
516
517 if (l != MAX_FLYING_OBJECTS) {
518 fobjects[l].x = xxx;
519 fobjects[l].y = yyy;
520 fobjects[l].x_speed = xsss + wrandom(PARTS_SPEED) - (PARTS_SPEED >> 1);
521 fobjects[l].y_speed = (wrandom(PARTS_SPEED) - (PARTS_SPEED >> 1));
522 fobjects[l].hit_plane = 1;
523 fobjects[l].width = 10;
524 fobjects[l].height = 10;
525 fobjects[l].type = FOBJECTS_PARTS;
526 fobjects[l].phase = wrandom(NUMBER_OF_BITES);
527 fobjects[l].owner = -1;
528 }
529 }
530 }
531
start_rifle(int x,int y)532 void start_rifle(int x, int y) {
533 int l;
534
535 for (l = 0; l < MAX_FLYING_OBJECTS; l++)
536 if (!fobjects[l].x)
537 break;
538
539 if (l != MAX_FLYING_OBJECTS) {
540 fobjects[l].x = x << 8;
541 fobjects[l].y = y << 8;
542 fobjects[l].x_speed = 256 * 128 * 5 - wrandom(2560 * 128);
543 fobjects[l].y_speed = wrandom(256 * 5 * 128);
544 fobjects[l].hit_plane = 0;
545 fobjects[l].width = 8;
546 fobjects[l].height = 8;
547 fobjects[l].type = FOBJECTS_RIFLE;
548 fobjects[l].phase = 0;
549 fobjects[l].owner = -1;
550 }
551
552 }
553
554
drop_bomb(int player,int target)555 void drop_bomb(int player, int target) {
556 int l;
557
558 for (l = 0; l < MAX_BOMBS; l++)
559 if (!bomb_x[l])
560 break;
561
562 if (l == MAX_BOMBS)
563 return;
564
565 if (target != -1)
566 bombs_going[target] = l;
567
568 player_bombed[player]++;
569
570 bomb_speed[l] = player_speed[player];
571 bomb_angle[l] = player_angle[player];
572 bomb_x_speed[l] = (cosinit[bomb_angle[l] >> 8] * bomb_speed[l]) >> 2;
573 bomb_y_speed[l] = (sinit[bomb_angle[l] >> 8] * bomb_speed[l]) >> 2;
574 bomb_x[l] = player_x[player] + (9 - player_upsidedown[player] * 18) * sinit[player_angle[player] >> 8];
575 bomb_y[l] = player_y[player] + (9 - player_upsidedown[player] * 18) * cosinit[player_angle[player] >> 8];
576
577 bomb_owner[l] = player;
578 }
579
do_bombs(void)580 void do_bombs(void) {
581 int l2, l, tempero;
582
583 for (l = 0; l < MAX_BOMBS; l++) {
584 if (!bomb_x[l])
585 continue;
586
587 bomb_y_speed[l] -= BOMB_GRAVITY;
588 bomb_x[l] += bomb_x_speed[l] >> 9;
589 bomb_y[l] -= bomb_y_speed[l] >> 9;
590
591
592
593 if (bomb_y_speed[l] == 0) {
594 if (bomb_x_speed[l] > 0)
595 bomb_angle[l] = 0;
596 else
597 bomb_angle[l] = 46080;
598 } else {
599 if (bomb_x_speed[l] == 0) {
600 if (bomb_y_speed[l] > 0)
601 bomb_angle[l] = 23040;
602 else
603 bomb_angle[l] = 69120;
604 } else {
605 tempero = ((bomb_y_speed[l] << 7) / bomb_x_speed[l]);
606 if (tempero > 512)
607 tempero = 512;
608 if (tempero < (-512))
609 tempero = -512;
610
611 if (bomb_x_speed[l] > 0)
612 bomb_angle[l] = tempero * 45;
613 else
614 bomb_angle[l] = 46080 + tempero * 45;
615
616 }
617 }
618
619
620
621 if (bomb_angle[l] >= 92160)
622 bomb_angle[l] -= 92160;
623
624 if (bomb_angle[l] < 0)
625 bomb_angle[l] += 92160;
626
627
628 if ((bomb_x[l] < 0) || (bomb_x[l] >> 8) >= 2400 || (bomb_y[l] >> 8) > 199) {
629 bomb_x[l] = 0;
630 continue;
631 }
632
633 if (bomb_y[l] >= 0)
634 if ((level_bitmap[(bomb_x[l] >> 8) + (bomb_y[l] >> 8) * 2400]) < 112 || ((level_bitmap[(bomb_x[l] >> 8) + (bomb_y[l] >> 8) * 2400])) > 119
635 || ((bomb_y[l] >> 8) >= 200)) {
636 start_bomb_explo(l);
637
638 bomb_x[l] = 0;
639 continue;
640 }
641
642
643 for (l2 = 0; l2 < 16; l2++) {
644 if (plane_present[l2]) {
645 if (((player_x[l2] + 2304) > bomb_x[l]) &&
646 ((player_x[l2] - 2304) < bomb_x[l]) && ((player_y[l2] + 2304) > bomb_y[l]) && ((player_y[l2] - 2304) < bomb_y[l]))
647 if (plane_p[l2][(player_angle[l2] >> 8) / 6][player_rolling[l2]][player_upsidedown[l2]]
648 [(bomb_x[l] >> 8) - (player_x_8[l2]) + 10 + ((bomb_y[l] >> 8) - (player_y_8[l2]) + 10) * 20] != 255) {
649 bomb_x[l] = 0;
650 player_endurance[l2] = 0;
651 if (player_endurance[l2] < 1) {
652 if ((!player_spinning[l2]) && (!in_closing[l2])) {
653 if (player_sides[bomb_owner[l]] != player_sides[l2])
654 player_points[bomb_owner[l]]++;
655 else
656 player_points[bomb_owner[l]]--;
657
658 player_shots_down[bomb_owner[l]][l2]++;
659 }
660
661 in_closing[l2] = 2;
662 plane_present[l2] = 0;
663 start_parts(l2);
664 start_bomb_explo(l, 1);
665
666 }
667 break;
668 }
669 }
670 }
671
672
673 }
674
675
676 }
677
start_bomb_explo(int bb,int hitted)678 void start_bomb_explo(int bb, int hitted) {
679 int l, l2, limit;
680 int palasia = 0;
681
682 if (playing_solo) {
683 if (bomb_owner[bb] != solo_country) {
684 for (l = 0; l < 100; l++) {
685 if (bombs_going[l] == bb) {
686 bombs_going[l] = -1;
687 break;
688
689 }
690
691 }
692
693 }
694
695 } else {
696 if (computer_active[bomb_owner[bb]]) {
697 for (l = 0; l < 100; l++) {
698 if (bombs_going[l] == bb) {
699 bombs_going[l] = -1;
700 break;
701
702 }
703
704 }
705
706 }
707
708 }
709
710
711 limit = wrandom(MAX_BOMB_PARTS - MIN_BOMB_PARTS);
712 limit += MIN_BOMB_PARTS;
713
714
715 if ((level_bitmap[(bomb_x[bb] >> 8) + (bomb_y[bb] >> 8) * 2400] >= 224)
716 && (level_bitmap[(bomb_x[bb] >> 8) + (bomb_y[bb] >> 8) * 2400] <= 231)) {
717 start_wave(bomb_x[bb] >> 8);
718 if (config.splash && config.sound_on && config.sfx_on)
719 play_2d_sample(sample_splash[wrandom(3)], player_x_8[solo_country], bomb_x[bb] >> 8);
720 } else {
721 start_explox(bomb_x[bb], bomb_y[bb]);
722 if (config.explosion_sounds && config.sound_on && config.sfx_on)
723 play_2d_sample(sample_bomb[wrandom(3) + 1], player_x_8[solo_country], bomb_x[bb] >> 8);
724
725 }
726
727 for (l = 0; l < MAX_AA_GUNS; l++)
728 if (kkbase_x[l] && kkbase_status[l] != 2) {
729 if ((bomb_x[bb] >> 8) >= kkbase_x[l] && (bomb_x[bb] >> 8) <= (kkbase_x[l] + 25) &&
730 (bomb_y[bb] >> 8) >= (kkbase_y[l] - 5) && (bomb_y[bb] >> 8) <= (kkbase_y[l] + 30)) {
731 if (kkbase_country[l] == player_sides[bomb_owner[bb]])
732 hitted = -1;
733
734 if (config.flames)
735 start_flame(kkbase_x[l], kkbase_y[l] + 21, 26);
736
737 if (playing_solo) {
738 if (leveldata.struct_type[kkbase_number[l]] == 1)
739 solo_dest_remaining--;
740
741 if (leveldata.struct_type[kkbase_number[l]] == 2)
742 solo_failed = 1;
743
744 }
745
746 kkbase_status[l] = 2;
747 kkbase_frame[l] = 0;
748 struct_state[kkbase_number[l]] = 1;
749
750 if (hitted != -1)
751 hitted = 1;
752 }
753 }
754
755 for (l = 0; l < MAX_STRUCTURES; l++)
756 if ((structures[l][1] != NULL) && (!struct_state[l])) {
757 if ((bomb_x[bb] >> 8) >= leveldata.struct_x[l] && (bomb_x[bb] >> 8) <= (leveldata.struct_x[l] + struct_width[l]) &&
758 (bomb_y[bb] >> 8) >= (leveldata.struct_y[l] - 5) && (bomb_y[bb] >> 8) <= (leveldata.struct_y[l] + 5 + struct_heigth[l])) {
759 if (config.flames)
760 start_flame(leveldata.struct_x[l], leveldata.struct_y[l] + struct_heigth[l], struct_width[l]);
761
762
763
764 struct_state[l] = 1;
765
766 if (playing_solo) {
767 if (leveldata.struct_type[l] == 1)
768 solo_dest_remaining--;
769
770 if (leveldata.struct_type[l] == 2)
771 solo_failed = 1;
772
773 }
774
775 if (player_sides[leveldata.struct_owner[l]] == player_sides[bomb_owner[bb]])
776 hitted = -1;
777
778 if (hitted != -1)
779 hitted = 1;
780
781 if (current_mode == SVGA_MODE) {
782
783 structures[l][1]->blit_to_bitmap(standard_background, leveldata.struct_x[l] - (leveldata.struct_x[l] / 800) * 800,
784 leveldata.struct_y[l] + (leveldata.struct_x[l] / 800) * 196 - 4);
785
786 structures[l][1]->blit(leveldata.struct_x[l] - (leveldata.struct_x[l] / 800) * 800,
787 leveldata.struct_y[l] + (leveldata.struct_x[l] / 800) * 196 - 4);
788
789 if ((leveldata.struct_x[l] - (leveldata.struct_x[l] / 800) * 800) + struct_width[l] > 800)
790 structures[l][1]->blit(leveldata.struct_x[l] - (leveldata.struct_x[l] / 800) * 800 - 800,
791 leveldata.struct_y[l] + (leveldata.struct_x[l] / 800 + 1) * 196 - 4);
792 }
793
794 if (leveldata.struct_hit[l]) {
795 structures[l][1]->blit_to_bitmap(maisema, leveldata.struct_x[l], leveldata.struct_y[l]);
796 }
797
798
799
800 }
801 }
802
803 for (l = 0; l < MAX_INFANTRY; l++) {
804 if (infan_x[l] && infan_state[l] < 3) {
805 if ((bomb_x[bb] >> 8) >= (infan_x[l] - 30) && (bomb_x[bb] >> 8) <= (infan_x[l] + 44) &&
806 (bomb_y[bb] >> 8) >= (infan_y[l] - 20) && (bomb_y[bb] >> 8) <= (infan_y[l] + 30)) {
807 if (player_sides[infan_country[l]] == player_sides[bomb_owner[bb]])
808 hitted = -1;
809
810 if (hitted != -1)
811 hitted = 1;
812
813 if (playing_solo) {
814 if (leveldata.struct_type[l] == 1)
815 solo_dest_remaining--;
816
817 if (leveldata.struct_type[l] == 2)
818 solo_failed = 1;
819
820 }
821
822 start_rifle(infan_x[l], infan_y[l]);
823
824 if (infan_x[l] == (bomb_x[bb] >> 8)) {
825 infan_x[l] = 0;
826
827 }
828
829 if (infan_x[l] > (bomb_x[bb] >> 8)) {
830
831 infan_direction[l] = 1;
832 infan_frame[l] = 0;
833 infan_state[l] = 4;
834 infan_x_speed[l] = 2;
835 }
836
837 if (infan_x[l] < (bomb_x[bb] >> 8)) {
838
839 infan_direction[l] = 0;
840 infan_frame[l] = 0;
841 infan_state[l] = 4;
842 infan_x_speed[l] = -2;
843 }
844
845
846 }
847
848 }
849 }
850
851
852 if (hitted == 1) {
853 player_bomb_hits[bomb_owner[bb]]++;
854 }
855
856 if (palasia)
857 for (l2 = 0; l2 < limit; l2++) {
858 for (l = 0; l < MAX_FLYING_OBJECTS; l++)
859 if (!fobjects[l].x)
860 break;
861
862 if (l != MAX_FLYING_OBJECTS) {
863 fobjects[l].x = bomb_x[bb];
864 fobjects[l].y = bomb_y[bb];
865 fobjects[l].x_speed = wrandom(PARTS_SPEED) - PARTS_SPEED / 2;
866 fobjects[l].y_speed = (wrandom(PARTS_SPEED) - PARTS_SPEED / 2);
867 fobjects[l].hit_plane = 1;
868 fobjects[l].width = 10;
869 fobjects[l].height = 10;
870 fobjects[l].type = FOBJECTS_PARTS;
871 fobjects[l].phase = wrandom(NUMBER_OF_BITES);
872 fobjects[l].owner = bomb_owner[bb];
873 }
874 }
875 }
876