/** * Collision between shockwave and an enemy * @param enemy_num enemy element index * @return TRUE if collision occurs, otherwise FALSE */ bool shockwave_collision (enemy * foe) { shockwave_struct *shock; Sint32 i, centerx, centery, dist; Sint32 dx, dy, resultat; shock = shockwave_first; if (shock == NULL) { return FALSE; } if (num_of_shockwaves == 0) { return FALSE; } centerx = (Sint32) (foe->spr.xcoord + foe->spr.img[foe->spr.current_image]->x_gc); centery = (Sint32) (foe->spr.ycoord + foe->spr.img[foe->spr.current_image]->y_gc); /* process each shockwave */ for (i = 0; i < num_of_shockwaves; i++, shock = shock->next) { if (shock == NULL && i < (num_of_shockwaves - 1)) { LOG_ERR ("shock->next is null %i/%i", i, num_of_shockwaves); break; } /* calculate the distance between shockwave center and enemy center */ dx = centerx - shock->center_x; dy = centery - shock->center_y; resultat = (dx * dx) + (dy * dy); dist = (Sint32) sqrt (resultat); /* collision detected? */ if (dist >= (27 + (shock->ring_index * 5)) && dist <= (43 + (shock->ring_index * 5))) { /* add a bonus gem or a lonely foe */ bonus_add (foe); /* collision between the enemy an a shockwave */ return TRUE; } } /* no collision between the enemy an a shockwave */ return FALSE; }
/** * Collisions between satellite protections and an enemy * @param foe pointer to the structure of an enemy * @param num_of_fragments number of fragments to add if enemy is destroyed * @return TRUE if enemy is destroyed */ bool satellites_enemy_collisions (enemy * foe, Sint32 num_of_fragments) { Sint32 i, l, m, x1, y1, x2, y2; satellite_struct *sat; sat = satellite_first; if (sat == NULL) { return FALSE; } /* process each protection satellite */ for (i = 0; i < num_of_satellites; i++, sat = sat->next) { #ifdef UNDER_DEVELOPMENT if (sat == NULL && i < (num_of_satellites - 1)) { LOG_ERR ("sat->next is null %i/%i", i, num_of_satellites); break; } #endif /* if satellite is invisible, don't perform the tests of collision */ if (!sat->is_visible) { continue; } /* for each collision point of the satellite */ for (l = 0; l < sat->img[sat->current_image]->numof_collisions_points; l++) { /* coordinates of the collision point of the satellite */ x1 = sat->xcoord + sat->img[sat->current_image]->collisions_points[l][XCOORD]; y1 = sat->ycoord + sat->img[sat->current_image]->collisions_points[l][YCOORD]; /* for each collision zone of the enemy */ for (m = 0; m < foe->spr.img[foe->spr.current_image]->numof_collisions_zones; m++) { /* coordinates of the collision zone of the enemy */ x2 = (Sint32) foe->spr.xcoord + foe->spr.img[foe->spr. current_image]->collisions_coords[m][XCOORD]; y2 = (Sint32) foe->spr.ycoord + foe->spr.img[foe->spr. current_image]->collisions_coords[m][YCOORD]; /* check if satellite collision point is into enemy collision zone */ if (x1 >= x2 && y1 >= y2 && x1 < (x2 + foe->spr.img[foe->spr. current_image]->collisions_sizes[m] [IMAGE_WIDTH]) && y1 < (y2 + foe->spr.img[foe->spr.current_image]-> collisions_sizes[m][IMAGE_HEIGHT])) { /* decrease energy level of enemy */ foe->spr.energy_level = (Sint16) (foe->spr.energy_level - sat->pow_of_dest); if (foe->type >= THANIKEE) { energy_gauge_guard_is_update = TRUE; } /* decrease energy level of satellite */ sat->energy_level = (Sint16) (sat->energy_level - foe->spr.pow_of_dest); /* check if satellite is destroyed */ if (sat->energy_level <= 0) { /* remove satellite from the list */ satellite_del (sat); /* positioning the satellites around the spaceship */ satellites_setup (); goto next_satellite; } else { /* satellite not destroyed, display white mask */ sat->is_mask = TRUE; } /* check if enemy is destroyed */ if (foe->spr.energy_level <= 0) { /* check if the enemy is a meteor */ if ((foe->type >= BIGMETEOR && foe->type <= SMALLMETEOR) || foe->type >= THANIKEE) { /* add a bonus gem or a lonely foe */ bonus_meteor_add (foe); if (num_of_fragments > 0) { explosions_fragments_add (foe->spr.xcoord + foe->spr.img[foe-> spr.current_image]-> x_gc - 8, foe->spr.ycoord + foe->spr.img[foe-> spr.current_image]-> y_gc - 8, 1.0, num_of_fragments, 0, 2); } } else { /* add a bonus gem or a lonely foe */ bonus_add (foe); } player_score += foe->spr.pow_of_dest << 2 << score_multiplier; return TRUE; } else { /* enemy not destroyed, display white mask */ foe->is_white_mask_displayed = TRUE; } explosion_add ((float) x1, (float) y1, 0.3f, EXPLOSION_SMALL, 0); goto next_satellite; } } } next_satellite:; } return FALSE; }