void handle_collision()

in procgen/src/games/bossfight.cpp [129:191]


    void handle_collision(const std::shared_ptr<Entity> &src, const std::shared_ptr<Entity> &target) override {
        if (src->type == PLAYER_BULLET) {
            bool will_erase = false;

            if (target->type == SHIELDS) {
                if (shields_are_up) {
                    src->type = REFLECTED_BULLET;

                    float theta = PI * (1.25 + .5 * rand_pct);
                    src->vy = PLAYER_BULLET_VEL * sin(theta) * .5;
                    src->vx = PLAYER_BULLET_VEL * cos(theta) * .5;
                    src->expire_time = 4;
                    src->life_time = 0;
                    src->alpha_decay = 0.8f;
                }
            } else if (target->type == BOSS) {
                if (!shields_are_up) {
                    target->health -= 1;
                    will_erase = true;

                    if (int(target->health) % round_health == 0) {
                        step_data.reward += POSITIVE_REWARD;

                        if (target->health == 0) {
                            step_data.done = true;
                            step_data.reward += COMPLETION_BONUS;
                            step_data.level_complete = true;
                        } else {
                            round_num++;
                            prepare_boss();
                            curr_vel_timeout = BOSS_DAMAGED_TIMEOUT;
                            damaged_until_time = cur_time + BOSS_DAMAGED_TIMEOUT;
                        }
                    }
                }
            }

            if (will_erase && !src->will_erase) {
                src->will_erase = true;

                auto explosion = spawn_child(src, EXPLOSION, .5 * src->rx);
                explosion->vx = target->vx;
                explosion->vy = target->vy;
            }
        } else if (src->type == BARRIER) {
            if (target->type == ENEMY_BULLET || target->type == PLAYER_BULLET) {
                target->will_erase = true;
                spawn_child(target, EXPLOSION, .5 * target->rx);
            } else if (target->type == LASER_TRAIL) {
                target->will_erase = true;
            }

            if (src->health <= 0) {
                if (!src->will_erase) {
                    auto explosion = spawn_child(src, EXPLOSION, .5 * src->rx);
                    explosion->vx = src->vx;
                    explosion->vy = src->vy;
                }

                src->will_erase = true;
            }
        }
    }