// Checks debris-weapon collisions. pair->a is debris and pair->b is weapon. // Returns 1 if all future collisions between these can be ignored int collide_debris_weapon( obj_pair * pair ) { vector hitpos; int hit; object *pdebris = pair->a; object *weapon = pair->b; Assert( pdebris->type == OBJ_DEBRIS ); Assert( weapon->type == OBJ_WEAPON ); // first check the bounding spheres of the two objects. hit = fvi_segment_sphere(&hitpos, &weapon->last_pos, &weapon->pos, &pdebris->pos, pdebris->radius); if (hit) { hit = debris_check_collision(pdebris, weapon, &hitpos ); if ( !hit ) return 0; weapon_hit( weapon, pdebris, &hitpos ); debris_hit( pdebris, weapon, &hitpos, Weapon_info[Weapons[weapon->instance].weapon_info_index].damage ); return 0; } else { return weapon_will_never_hit( weapon, pdebris, pair ); } }
// Checks debris-weapon collisions. pair->a is debris and pair->b is weapon. // Returns 1 if all future collisions between these can be ignored int collide_asteroid_weapon( obj_pair * pair ) { #if !(defined(FS2_DEMO) || defined(FS1_DEMO)) if (!Asteroids_enabled) return 0; vector hitpos; int hit; object *pasteroid = pair->a; object *weapon = pair->b; Assert( pasteroid->type == OBJ_ASTEROID); Assert( weapon->type == OBJ_WEAPON ); // first check the bounding spheres of the two objects. hit = fvi_segment_sphere(&hitpos, &weapon->last_pos, &weapon->pos, &pasteroid->pos, pasteroid->radius); if (hit) { hit = asteroid_check_collision(pasteroid, weapon, &hitpos ); if ( !hit ) return 0; weapon_hit( weapon, pasteroid, &hitpos ); asteroid_hit( pasteroid, weapon, &hitpos, Weapon_info[Weapons[weapon->instance].weapon_info_index].damage ); return 0; } else { return weapon_will_never_hit( weapon, pasteroid, pair ); } #else return 0; #endif }
/** * Checks debris-weapon collisions. * @param pair obj_pair pointer to the two objects. pair->a is debris and pair->b is weapon. * @return 1 if all future collisions between these can be ignored */ int collide_asteroid_weapon( obj_pair * pair ) { if (!Asteroids_enabled) return 0; vec3d hitpos, hitnormal; int hit; object *pasteroid = pair->a; object *weapon_obj = pair->b; Assert( pasteroid->type == OBJ_ASTEROID); Assert( weapon_obj->type == OBJ_WEAPON ); // first check the bounding spheres of the two objects. hit = fvi_segment_sphere(&hitpos, &weapon_obj->last_pos, &weapon_obj->pos, &pasteroid->pos, pasteroid->radius); if (hit) { hit = asteroid_check_collision(pasteroid, weapon_obj, &hitpos, NULL, &hitnormal); if ( !hit ) return 0; Script_system.SetHookObjects(4, "Weapon", weapon_obj, "Asteroid", pasteroid, "Self", weapon_obj, "Object", pasteroid); bool weapon_override = Script_system.IsConditionOverride(CHA_COLLIDEASTEROID, weapon_obj); Script_system.SetHookObjects(2, "Self",pasteroid, "Object", weapon_obj); bool asteroid_override = Script_system.IsConditionOverride(CHA_COLLIDEWEAPON, pasteroid); if(!weapon_override && !asteroid_override) { weapon_hit( weapon_obj, pasteroid, &hitpos, -1, &hitnormal); asteroid_hit( pasteroid, weapon_obj, &hitpos, Weapon_info[Weapons[weapon_obj->instance].weapon_info_index].damage ); } Script_system.SetHookObjects(2, "Self", weapon_obj, "Object", pasteroid); if(!(asteroid_override && !weapon_override)) Script_system.RunCondition(CHA_COLLIDEASTEROID, '\0', NULL, weapon_obj); Script_system.SetHookObjects(2, "Self", pasteroid, "Object", weapon_obj); if((asteroid_override && !weapon_override) || (!asteroid_override && !weapon_override)) Script_system.RunCondition(CHA_COLLIDEWEAPON, '\0', NULL, pasteroid, Weapons[weapon_obj->instance].weapon_info_index); Script_system.RemHookVars(4, "Weapon", "Asteroid", "Self", "Object"); return 0; } else { return weapon_will_never_hit( weapon_obj, pasteroid, pair ); } }
/** * Checks ship-weapon collisions. * @param pair obj_pair pointer to the two objects. pair->a is ship and pair->b is weapon. * @return 1 if all future collisions between these can be ignored */ int collide_ship_weapon( obj_pair * pair ) { int did_hit; object *ship = pair->a; object *weapon_obj = pair->b; Assert( ship->type == OBJ_SHIP ); Assert( weapon_obj->type == OBJ_WEAPON ); ship_info *sip = &Ship_info[Ships[ship->instance].ship_info_index]; // Don't check collisions for player if past first warpout stage. if ( Player->control_mode > PCM_WARPOUT_STAGE1) { if ( ship == Player_obj ) return 0; } if (reject_due_collision_groups(ship, weapon_obj)) return 0; // Cull lasers within big ship spheres by casting a vector forward for (1) exit sphere or (2) lifetime of laser // If it does hit, don't check the pair until about 200 ms before collision. // If it does not hit and is within error tolerance, cull the pair. if ( (sip->is_big_or_huge()) && (Weapon_info[Weapons[weapon_obj->instance].weapon_info_index].subtype == WP_LASER) ) { // Check when within ~1.1 radii. // This allows good transition between sphere checking (leaving the laser about 200 ms from radius) and checking // within the sphere with little time between. There may be some time for "small" big ships // Note: culling ships with auto spread shields seems to waste more performance than it saves, // so we're not doing that here if ( !(sip->flags[Ship::Info_Flags::Auto_spread_shields]) && vm_vec_dist_squared(&ship->pos, &weapon_obj->pos) < (1.2f*ship->radius*ship->radius) ) { return check_inside_radius_for_big_ships( ship, weapon_obj, pair ); } } did_hit = ship_weapon_check_collision( ship, weapon_obj ); if ( !did_hit ) { // Since we didn't hit, check to see if we can disable all future collisions // between these two. return weapon_will_never_hit( weapon_obj, ship, pair ); } return 0; }
/** * Checks debris-weapon collisions. * @param pair obj_pair pointer to the two objects. pair->a is debris and pair->b is weapon. * @return 1 if all future collisions between these can be ignored */ int collide_debris_weapon( obj_pair * pair ) { vec3d hitpos, hitnormal; int hit; object *pdebris = pair->a; object *weapon_obj = pair->b; Assert( pdebris->type == OBJ_DEBRIS ); Assert( weapon_obj->type == OBJ_WEAPON ); // first check the bounding spheres of the two objects. hit = fvi_segment_sphere(&hitpos, &weapon_obj->last_pos, &weapon_obj->pos, &pdebris->pos, pdebris->radius); if (hit) { hit = debris_check_collision(pdebris, weapon_obj, &hitpos, NULL, &hitnormal ); if ( !hit ) return 0; Script_system.SetHookObjects(4, "Weapon", weapon_obj, "Debris", pdebris, "Self", weapon_obj, "Object", pdebris); bool weapon_override = Script_system.IsConditionOverride(CHA_COLLIDEDEBRIS, weapon_obj); Script_system.SetHookObjects(2, "Self", pdebris, "Object", weapon_obj); bool debris_override = Script_system.IsConditionOverride(CHA_COLLIDEWEAPON, pdebris); if(!weapon_override && !debris_override) { weapon_hit( weapon_obj, pdebris, &hitpos, -1, &hitnormal ); debris_hit( pdebris, weapon_obj, &hitpos, Weapon_info[Weapons[weapon_obj->instance].weapon_info_index].damage ); } Script_system.SetHookObjects(2, "Self", weapon_obj, "Object", pdebris); if(!(debris_override && !weapon_override)) Script_system.RunCondition(CHA_COLLIDEDEBRIS, '\0', NULL, weapon_obj); Script_system.SetHookObjects(2, "Self", pdebris, "Object", weapon_obj); if((debris_override && !weapon_override) || (!debris_override && !weapon_override)) Script_system.RunCondition(CHA_COLLIDEWEAPON, '\0', NULL, pdebris, Weapons[weapon_obj->instance].weapon_info_index); Script_system.RemHookVars(4, "Weapon", "Debris", "Self", "Object"); return 0; } else { return weapon_will_never_hit( weapon_obj, pdebris, pair ); } }
// Checks ship-weapon collisions. pair->a is ship and pair->b is weapon. // Returns 1 if all future collisions between these can be ignored int collide_ship_weapon( obj_pair * pair ) { int did_hit; object *ship = pair->a; object *weapon = pair->b; Assert( ship->type == OBJ_SHIP ); Assert( weapon->type == OBJ_WEAPON ); // Don't check collisions for player if past first warpout stage. if ( Player->control_mode > PCM_WARPOUT_STAGE1) { if ( ship == Player_obj ) return 0; } // Cull lasers within big ship spheres by casting a vector forward for (1) exit sphere or (2) lifetime of laser // If it does hit, don't check the pair until about 200 ms before collision. // If it does not hit and is within error tolerance, cull the pair. if ( (Ship_info[Ships[ship->instance].ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP)) && (Weapon_info[Weapons[weapon->instance].weapon_info_index].subtype == WP_LASER) ) { // if ( (ship->radius > 50) && (Weapon_info[Weapons[weapon->instance].weapon_info_index].subtype == WP_LASER) ) { // Check when within ~1.1 radii. // This allows good transition between sphere checking (leaving the laser about 200 ms from radius) and checking // within the sphere with little time between. There may be some time for "small" big ships if ( vm_vec_dist_squared(&ship->pos, &weapon->pos) < (1.2f*ship->radius*ship->radius) ) { return check_inside_radius_for_big_ships( ship, weapon, pair ); } } // demo_do_rand_test(); did_hit = ship_weapon_check_collision( ship, weapon ); // demo_do_rand_test(); if ( !did_hit ) { // Since we didn't hit, check to see if we can disable all future collisions // between these two. return weapon_will_never_hit( weapon, ship, pair ); } return 0; }