Пример #1
0
//	See if two lines intersect by doing recursive subdivision.
//	Bails out if larger distance traveled is less than sum of radii + 1.0f.
int collide_subdivide(vec3d *p0, vec3d *p1, float prad, vec3d *q0, vec3d *q1, float qrad)
{
	float	a_dist, b_dist, ab_dist;

	a_dist = vm_vec_dist(p0, p1);
	b_dist = vm_vec_dist(q0, q1);

	ab_dist = vm_vec_dist(p1, q1);

	//	See if their spheres intersect
	if (ab_dist < a_dist + b_dist + prad + qrad) {
		if (ab_dist  < prad + qrad)
			return 1;
		else if (vm_vec_dist(p0, q0) < prad + qrad)
			return 1;
		else if (MAX(a_dist, b_dist) < prad + qrad + 1.0f)
			return 0;
		else {
			int	r1, r2 = 0;
			vec3d	pa, qa;

			vm_vec_avg(&pa, p0, p1);
			vm_vec_avg(&qa, q0, q1);
			r1 = collide_subdivide(p0, &pa, prad, q0, &qa, qrad);
			if (!r1)
				r2 = collide_subdivide(&pa, p1, prad, &qa, q1, qrad);

			return r1 | r2;
		}
	} else
		return 0;
}
// Checks weapon-weapon collisions.  pair->a and pair->b are weapons.
// Returns 1 if all future collisions between these can be ignored
int collide_weapon_weapon( obj_pair * pair )
{
	float A_radius, B_radius;
	object *A = pair->a;
	object *B = pair->b;

	Assert( A->type == OBJ_WEAPON );
	Assert( B->type == OBJ_WEAPON );
	
	//	Don't allow ship to shoot down its own missile.
	if (A->parent_sig == B->parent_sig)
		return 1;

	//	Only shoot down teammate's missile if not traveling in nearly same direction.
	if (Weapons[A->instance].team == Weapons[B->instance].team)
		if (vm_vec_dot(&A->orient.vec.fvec, &B->orient.vec.fvec) > 0.7f)
			return 1;

	//	Ignore collisions involving a bomb if the bomb is not yet armed.
	weapon	*wpA, *wpB;
	weapon_info	*wipA, *wipB;

	wpA = &Weapons[A->instance];
	wpB = &Weapons[B->instance];
	wipA = &Weapon_info[wpA->weapon_info_index];
	wipB = &Weapon_info[wpB->weapon_info_index];

	A_radius = A->radius;
	B_radius = B->radius;

	// UnknownPlayer : Should we even be bothering with collision detection is neither one of these is a bomb?

	if (wipA->wi_flags & WIF_BOMB) {
		A_radius *= 2;		// Makes bombs easier to hit
		if (wipA->lifetime - wpA->lifeleft < BOMB_ARM_TIME)
			return 0;
	}

	if (wipB->wi_flags & WIF_BOMB) {
		B_radius *= 2;		// Makes bombs easier to hit
		if (wipB->lifetime - wpB->lifeleft < BOMB_ARM_TIME)
			return 0;
	}

	//	Rats, do collision detection.
	if (collide_subdivide(&A->last_pos, &A->pos, A_radius, &B->last_pos, &B->pos, B_radius)) {
		ship	*sap, *sbp;

		sap = &Ships[Objects[A->parent].instance];
		sbp = &Ships[Objects[B->parent].instance];
		// MWA -- commented out next line because it was too long for output window on occation.
		// Yes -- I should fix the output window, but I don't have time to do it now.
		//nprintf(("AI", "[%s] %s's missile %i shot down by [%s] %s's laser %i\n", lTeamNames[sbp->team], sbp->ship_name, B->instance, lTeamNames[sap->team], sap->ship_name, A->instance));
		if (wipA->wi_flags & WIF_BOMB) {
			if (wipB->wi_flags & WIF_BOMB) {		//	Two bombs collide, detonate both.
				Weapons[A->instance].lifeleft = 0.01f;
				Weapons[B->instance].lifeleft = 0.01f;
				Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
				Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
			} else {
				A->hull_strength -= wipB->damage;
				if (A->hull_strength < 0.0f) {
					Weapons[A->instance].lifeleft = 0.01f;
					Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
				}
			}
		} else if (wipB->wi_flags & WIF_BOMB) {
			B->hull_strength -= wipA->damage;
			if (B->hull_strength < 0.0f) {
				Weapons[B->instance].lifeleft = 0.01f;
				Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
			}
		}

		float dist = 0.0f;
		if (Weapons[A->instance].lifeleft == 0.01f) {
			dist = vm_vec_dist_quick(&A->pos, &wpA->homing_pos);
			nprintf(("AI", "Frame %i: Weapon %s shot down. Dist: %.1f, inner: %.0f, outer: %.0f\n", Framecount, wipA->name, dist, wipA->inner_radius, wipA->outer_radius));
		}
		if (Weapons[B->instance].lifeleft == 0.01f) {
			dist = vm_vec_dist_quick(&A->pos, &wpB->homing_pos);
			nprintf(("AI", "Frame %i: Weapon %s shot down. Dist: %.1f, inner: %.0f, outer: %.0f\n", Framecount, wipB->name, dist, wipB->inner_radius, wipB->outer_radius));
		}
		return 1;
	}

	return 0;
}
Пример #3
0
// Checks weapon-weapon collisions.  pair->a and pair->b are weapons.
// Returns 1 if all future collisions between these can be ignored
int collide_weapon_weapon(obj_pair* pair)
{
	float A_radius, B_radius;
	object* A = pair->a;
	object* B = pair->b;

	Assert(A->type == OBJ_WEAPON);
	Assert(B->type == OBJ_WEAPON);

	//	Don't allow ship to shoot down its own missile.
	if (A->parent_sig == B->parent_sig)
		return 1;

	//	Only shoot down teammate's missile if not traveling in nearly same direction.
	if (Weapons[A->instance].team == Weapons[B->instance].team)
		if (vm_vec_dot(&A->orient.vec.fvec, &B->orient.vec.fvec) > 0.7f)
			return 1;

	//	Ignore collisions involving a bomb if the bomb is not yet armed.
	weapon* wpA, *wpB;
	weapon_info* wipA, *wipB;

	wpA = &Weapons[A->instance];
	wpB = &Weapons[B->instance];
	wipA = &Weapon_info[wpA->weapon_info_index];
	wipB = &Weapon_info[wpB->weapon_info_index];

	A_radius = A->radius;
	B_radius = B->radius;

	// UnknownPlayer : Should we even be bothering with collision detection is neither one of these is a bomb?

	//WMC - Here's a reason why...scripting now!

	if (wipA->weapon_hitpoints > 0)
	{
		if (!(wipA->wi_flags2 & WIF2_HARD_TARGET_BOMB))
		{
			A_radius *= 2;		// Makes bombs easier to hit
		}
		if ((wipA->lifetime - wpA->lifeleft) < The_mission.ai_profile->delay_bomb_arm_timer[Game_skill_level])
			return 0;
	}

	if (wipB->weapon_hitpoints > 0)
	{
		if (!(wipB->wi_flags2 & WIF2_HARD_TARGET_BOMB))
		{
			B_radius *= 2;		// Makes bombs easier to hit
		}
		if ((wipB->lifetime - wpB->lifeleft) < The_mission.ai_profile->delay_bomb_arm_timer[Game_skill_level])
			return 0;
	}

	//	Rats, do collision detection.
	if (collide_subdivide(&A->last_pos, &A->pos, A_radius, &B->last_pos, &B->pos, B_radius))
	{
		Script_system.SetHookObjects(4, "Weapon", A, "WeaponB", B, "Self", A, "Object", B);
		bool a_override = Script_system.IsConditionOverride(CHA_COLLIDEWEAPON, A);

		//Should be reversed
		Script_system.SetHookObjects(4, "Weapon", B, "WeaponB", A, "Self", B, "Object", A);
		bool b_override = Script_system.IsConditionOverride(CHA_COLLIDEWEAPON, B);

		if (!a_override && !b_override)
		{
			//Do the normal stuff if no override -C
			ship* sap, *sbp;

			sap = &Ships[Objects[A->parent].instance];
			sbp = &Ships[Objects[B->parent].instance];

			// MWA -- commented out next line because it was too long for output window on occation.
			// Yes -- I should fix the output window, but I don't have time to do it now.
			//nprintf(("AI", "[%s] %s's missile %i shot down by [%s] %s's laser %i\n", Iff_info[sbp->team].iff_name, sbp->ship_name, B->instance, Iff_info[sap->team].iff_name, sap->ship_name, A->instance));
			if (wipA->weapon_hitpoints > 0)
			{
				if (wipB->weapon_hitpoints > 0)
				{		//	Two bombs collide, detonate both.
					Weapons[A->instance].lifeleft = 0.01f;
					Weapons[B->instance].lifeleft = 0.01f;
					Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
					Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
				}
				else
				{
					A->hull_strength -= wipB->damage;
					if (A->hull_strength < 0.0f)
					{
						Weapons[A->instance].lifeleft = 0.01f;
						Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
					}
				}
			}
			else if (wipB->weapon_hitpoints > 0)
			{
				B->hull_strength -= wipA->damage;
				if (B->hull_strength < 0.0f)
				{
					Weapons[B->instance].lifeleft = 0.01f;
					Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
				}
			}
#ifndef NDEBUG
			float dist = 0.0f;

			if (Weapons[A->instance].lifeleft == 0.01f)
			{
				dist = vm_vec_dist_quick(&A->pos, &wpA->homing_pos);
				//nprintf(("AI", "Frame %i: Weapon %s shot down. Dist: %.1f, inner: %.0f, outer: %.0f\n", Framecount, wipA->name, dist, wipA->inner_radius, wipA->outer_radius));
			}
			if (Weapons[B->instance].lifeleft == 0.01f)
			{
				dist = vm_vec_dist_quick(&A->pos, &wpB->homing_pos);
				//nprintf(("AI", "Frame %i: Weapon %s shot down. Dist: %.1f, inner: %.0f, outer: %.0f\n", Framecount, wipB->name, dist, wipB->inner_radius, wipB->outer_radius));
			}
#endif
		}

		if (!(b_override && !a_override))
		{
			Script_system.SetHookObjects(4, "Weapon", A, "WeaponB", B, "Self", A, "Object", B);
			Script_system.RunCondition(CHA_COLLIDEWEAPON, '\0', NULL, A);
		}
		if ((b_override && !a_override) || (!b_override && !a_override))
		{
			//SHould be reversed
			Script_system.SetHookObjects(4, "Weapon", B, "WeaponB", A, "Self", B, "Object", A);
			Script_system.RunCondition(CHA_COLLIDEWEAPON, '\0', NULL, B);
		}

		Script_system.RemHookVars(4, "Weapon", "WeaponB", "Self", "ObjectB");
		return 1;
	}

	return 0;
}
/**
 * Checks weapon-weapon collisions.  
 * @param pair obj_pair pointer to the two objects. pair->a and pair->b are weapons.
 * @return 1 if all future collisions between these can be ignored
 */
int collide_weapon_weapon( obj_pair * pair )
{
	float A_radius, B_radius;
	object *A = pair->a;
	object *B = pair->b;

	Assert( A->type == OBJ_WEAPON );
	Assert( B->type == OBJ_WEAPON );
	
	//	Don't allow ship to shoot down its own missile.
	if (A->parent_sig == B->parent_sig)
		return 1;

	//	Only shoot down teammate's missile if not traveling in nearly same direction.
	if (Weapons[A->instance].team == Weapons[B->instance].team)
		if (vm_vec_dot(&A->orient.vec.fvec, &B->orient.vec.fvec) > 0.7f)
			return 1;

	//	Ignore collisions involving a bomb if the bomb is not yet armed.
	weapon	*wpA, *wpB;
	weapon_info	*wipA, *wipB;

	wpA = &Weapons[A->instance];
	wpB = &Weapons[B->instance];
	wipA = &Weapon_info[wpA->weapon_info_index];
	wipB = &Weapon_info[wpB->weapon_info_index];

	A_radius = A->radius;
	B_radius = B->radius;

	if (wipA->weapon_hitpoints > 0) {
		if (!(wipA->wi_flags2 & WIF2_HARD_TARGET_BOMB)) {
			A_radius *= 2;		// Makes bombs easier to hit
		}
		
		if (wipA->wi_flags & WIF_LOCKED_HOMING) {
			if ( (wipA->max_lifetime - wpA->lifeleft) < The_mission.ai_profile->delay_bomb_arm_timer[Game_skill_level] )
				return 0;
		}
		else if ( (wipA->lifetime - wpA->lifeleft) < The_mission.ai_profile->delay_bomb_arm_timer[Game_skill_level] )
			return 0;
	}

	if (wipB->weapon_hitpoints > 0) {
		if (!(wipB->wi_flags2 & WIF2_HARD_TARGET_BOMB)) {
			B_radius *= 2;		// Makes bombs easier to hit
		}
		if (wipB->wi_flags & WIF_LOCKED_HOMING) {
			if ( (wipB->max_lifetime - wpB->lifeleft) < The_mission.ai_profile->delay_bomb_arm_timer[Game_skill_level] )
				return 0;
		}
		else if ( (wipB->lifetime - wpB->lifeleft) < The_mission.ai_profile->delay_bomb_arm_timer[Game_skill_level] )
			return 0;
	}

	//	Rats, do collision detection.
	if (collide_subdivide(&A->last_pos, &A->pos, A_radius, &B->last_pos, &B->pos, B_radius))
	{
		Script_system.SetHookObjects(4, "Weapon", A, "WeaponB", B, "Self",A, "Object", B);
		bool a_override = Script_system.IsConditionOverride(CHA_COLLIDEWEAPON, A);
		
		//Should be reversed
		Script_system.SetHookObjects(4, "Weapon", B, "WeaponB", A, "Self",B, "Object", A);
		bool b_override = Script_system.IsConditionOverride(CHA_COLLIDEWEAPON, B);

		if(!a_override && !b_override)
		{
			float aDamage = wipA->damage;
			if (wipB->armor_type_idx >= 0)
				aDamage = Armor_types[wipB->armor_type_idx].GetDamage(aDamage, wipA->damage_type_idx, 1.0f);

			float bDamage = wipB->damage;
			if (wipA->armor_type_idx >= 0)
				bDamage = Armor_types[wipA->armor_type_idx].GetDamage(bDamage, wipB->damage_type_idx, 1.0f);

			if (wipA->weapon_hitpoints > 0) {
				if (wipB->weapon_hitpoints > 0) {		//	Two bombs collide, detonate both.
					if ((wipA->wi_flags & WIF_BOMB) && (wipB->wi_flags & WIF_BOMB)) {
						Weapons[A->instance].lifeleft = 0.01f;
						Weapons[B->instance].lifeleft = 0.01f;
						Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
						Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
					} else {
						A->hull_strength -= bDamage;
						B->hull_strength -= aDamage;

						// safety to make sure either of the weapons die - allow 'bulkier' to keep going
						if ((A->hull_strength > 0.0f) && (B->hull_strength > 0.0f)) {
							if (wipA->weapon_hitpoints > wipB->weapon_hitpoints) {
								B->hull_strength = -1.0f;
							} else {
								A->hull_strength = -1.0f;
							}
						}
						
						if (A->hull_strength < 0.0f) {
							Weapons[A->instance].lifeleft = 0.01f;
							Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
						}
						if (B->hull_strength < 0.0f) {
							Weapons[B->instance].lifeleft = 0.01f;
							Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
						}
					}
				} else {
					A->hull_strength -= bDamage;
					Weapons[B->instance].lifeleft = 0.01f;
					Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
					if (A->hull_strength < 0.0f) {
						Weapons[A->instance].lifeleft = 0.01f;
						Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
					}
				}
			} else if (wipB->weapon_hitpoints > 0) {
				B->hull_strength -= aDamage;
				Weapons[A->instance].lifeleft = 0.01f;
				Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
				if (B->hull_strength < 0.0f) {
					Weapons[B->instance].lifeleft = 0.01f;
					Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
				}
			}

			// single player and multiplayer masters evaluate the scoring and kill stuff
			if (!MULTIPLAYER_CLIENT) {

				//Save damage for bomb so we can do scoring once it's destroyed. -Halleck
				if (wipA->wi_flags & WIF_BOMB) {
					scoring_add_damage_to_weapon(A, B, wipB->damage);
					//Update stats. -Halleck
					scoring_eval_hit(A, B, 0);
				}
				if (wipB->wi_flags & WIF_BOMB) {
					scoring_add_damage_to_weapon(B, A, wipA->damage);
					//Update stats. -Halleck
					scoring_eval_hit(B, A, 0);
				}
			}

	#ifndef NDEBUG
			float dist = 0.0f;

			if (Weapons[A->instance].lifeleft == 0.01f) {
				dist = vm_vec_dist_quick(&A->pos, &wpA->homing_pos);
			}
			if (Weapons[B->instance].lifeleft == 0.01f) {
				dist = vm_vec_dist_quick(&B->pos, &wpB->homing_pos);
			}
	#endif
		}

		if(!(b_override && !a_override))
		{
			Script_system.SetHookObjects(4, "Weapon", A, "WeaponB", B, "Self",A, "Object", B);
			Script_system.RunCondition(CHA_COLLIDEWEAPON, '\0', NULL, A, wpA->weapon_info_index);
		}
		if((b_override && !a_override) || (!b_override && !a_override))
		{
			//Should be reversed
			Script_system.SetHookObjects(4, "Weapon", B, "WeaponB", A, "Self",B, "Object", A);
			Script_system.RunCondition(CHA_COLLIDEWEAPON, '\0', NULL, B, wpB->weapon_info_index);
		}

		Script_system.RemHookVars(4, "Weapon", "WeaponB", "Self","ObjectB");
		return 1;
	}

	return 0;
}
/**
 * Checks weapon-weapon collisions.  
 * @param pair obj_pair pointer to the two objects. pair->a and pair->b are weapons.
 * @return 1 if all future collisions between these can be ignored
 */
int collide_weapon_weapon( obj_pair * pair )
{
	float A_radius, B_radius;
	object *A = pair->a;
	object *B = pair->b;

	Assert( A->type == OBJ_WEAPON );
	Assert( B->type == OBJ_WEAPON );
	
	//	Don't allow ship to shoot down its own missile.
	if (A->parent_sig == B->parent_sig)
		return 1;

	//	Only shoot down teammate's missile if not traveling in nearly same direction.
	if (Weapons[A->instance].team == Weapons[B->instance].team)
		if (vm_vec_dot(&A->orient.vec.fvec, &B->orient.vec.fvec) > 0.7f)
			return 1;

	//	Ignore collisions involving a bomb if the bomb is not yet armed.
	weapon	*wpA, *wpB;
	weapon_info	*wipA, *wipB;

	wpA = &Weapons[A->instance];
	wpB = &Weapons[B->instance];
	wipA = &Weapon_info[wpA->weapon_info_index];
	wipB = &Weapon_info[wpB->weapon_info_index];

	A_radius = A->radius;
	B_radius = B->radius;

	if (wipA->weapon_hitpoints > 0) {
		if (!(wipA->wi_flags[Weapon::Info_Flags::Hard_target_bomb])) {
			A_radius *= 2;		// Makes bombs easier to hit
		}
		
		if ((The_mission.ai_profile->flags[AI::Profile_Flags::Aspect_invulnerability_fix]) && (wipA->is_locked_homing()) && (wpA->homing_object != &obj_used_list)) {
			if ( (wipA->max_lifetime - wpA->lifeleft) < The_mission.ai_profile->delay_bomb_arm_timer[Game_skill_level] )
				return 0;
		}
		else if ( (wipA->lifetime - wpA->lifeleft) < The_mission.ai_profile->delay_bomb_arm_timer[Game_skill_level] )
			return 0;
	}

	if (wipB->weapon_hitpoints > 0) {
		if (!(wipB->wi_flags[Weapon::Info_Flags::Hard_target_bomb])) {
			B_radius *= 2;		// Makes bombs easier to hit
		}
		if ((The_mission.ai_profile->flags[AI::Profile_Flags::Aspect_invulnerability_fix]) && (wipB->is_locked_homing()) && (wpB->homing_object != &obj_used_list)) {
			if ( (wipB->max_lifetime - wpB->lifeleft) < The_mission.ai_profile->delay_bomb_arm_timer[Game_skill_level] )
				return 0;
		}
		else if ( (wipB->lifetime - wpB->lifeleft) < The_mission.ai_profile->delay_bomb_arm_timer[Game_skill_level] )
			return 0;
	}

	//	Rats, do collision detection.
	if (collide_subdivide(&A->last_pos, &A->pos, A_radius, &B->last_pos, &B->pos, B_radius))
	{
		Script_system.SetHookObjects(4, "Weapon", A, "WeaponB", B, "Self",A, "Object", B);
		bool a_override = Script_system.IsConditionOverride(CHA_COLLIDEWEAPON, A);
		
		//Should be reversed
		Script_system.SetHookObjects(4, "Weapon", B, "WeaponB", A, "Self",B, "Object", A);
		bool b_override = Script_system.IsConditionOverride(CHA_COLLIDEWEAPON, B);

		if(!a_override && !b_override)
		{
			float aDamage = wipA->damage;
			if (wipB->armor_type_idx >= 0)
				aDamage = Armor_types[wipB->armor_type_idx].GetDamage(aDamage, wipA->damage_type_idx, 1.0f);

			float bDamage = wipB->damage;
			if (wipA->armor_type_idx >= 0)
				bDamage = Armor_types[wipA->armor_type_idx].GetDamage(bDamage, wipB->damage_type_idx, 1.0f);

			if (wipA->weapon_hitpoints > 0) {
				if (wipB->weapon_hitpoints > 0) {		//	Two bombs collide, detonate both.
					if ((wipA->wi_flags[Weapon::Info_Flags::Bomb]) && (wipB->wi_flags[Weapon::Info_Flags::Bomb])) {
						wpA->lifeleft = 0.01f;
						wpB->lifeleft = 0.01f;
						wpA->weapon_flags.set(Weapon::Weapon_Flags::Destroyed_by_weapon);
						wpB->weapon_flags.set(Weapon::Weapon_Flags::Destroyed_by_weapon);
					} else {
						A->hull_strength -= bDamage;
						B->hull_strength -= aDamage;

						// safety to make sure either of the weapons die - allow 'bulkier' to keep going
						if ((A->hull_strength > 0.0f) && (B->hull_strength > 0.0f)) {
							if (wipA->weapon_hitpoints > wipB->weapon_hitpoints) {
								B->hull_strength = -1.0f;
							} else {
								A->hull_strength = -1.0f;
							}
						}
						
						if (A->hull_strength < 0.0f) {
							wpA->lifeleft = 0.01f;
							wpA->weapon_flags.set(Weapon::Weapon_Flags::Destroyed_by_weapon);
						}
						if (B->hull_strength < 0.0f) {
							wpB->lifeleft = 0.01f;
							wpB->weapon_flags.set(Weapon::Weapon_Flags::Destroyed_by_weapon);
						}
					}
				} else {
					A->hull_strength -= bDamage;
					wpB->lifeleft = 0.01f;
					wpB->weapon_flags.set(Weapon::Weapon_Flags::Destroyed_by_weapon);
					if (A->hull_strength < 0.0f) {
						wpA->lifeleft = 0.01f;
						wpA->weapon_flags.set(Weapon::Weapon_Flags::Destroyed_by_weapon);
					}
				}
			} else if (wipB->weapon_hitpoints > 0) {
				B->hull_strength -= aDamage;
				wpA->lifeleft = 0.01f;
				wpA->weapon_flags.set(Weapon::Weapon_Flags::Destroyed_by_weapon);
				if (B->hull_strength < 0.0f) {
					wpB->lifeleft = 0.01f;
					wpB->weapon_flags.set(Weapon::Weapon_Flags::Destroyed_by_weapon);
				}
			}

			// single player and multiplayer masters evaluate the scoring and kill stuff
			if (!MULTIPLAYER_CLIENT) {

				// If bomb was destroyed, do scoring
				if (wipA->wi_flags[Weapon::Info_Flags::Bomb]) {
					//Update stats. -Halleck
					scoring_eval_hit(A, B, 0);
					if (wpA->weapon_flags[Weapon::Weapon_Flags::Destroyed_by_weapon]) {
						scoring_eval_kill_on_weapon(A, B);
					}
				}
				if (wipB->wi_flags[Weapon::Info_Flags::Bomb]) {
					//Update stats. -Halleck
					scoring_eval_hit(B, A, 0);
					if (wpB->weapon_flags[Weapon::Weapon_Flags::Destroyed_by_weapon]) {
						scoring_eval_kill_on_weapon(B, A);
					}
				}
			}
		}

		if(!(b_override && !a_override))
		{
			Script_system.SetHookObjects(4, "Weapon", A, "WeaponB", B, "Self",A, "Object", B);
			Script_system.RunCondition(CHA_COLLIDEWEAPON, A, wpA->weapon_info_index);
		}
		else
		{
			//Should be reversed
			Script_system.SetHookObjects(4, "Weapon", B, "WeaponB", A, "Self",B, "Object", A);
			Script_system.RunCondition(CHA_COLLIDEWEAPON, B, wpB->weapon_info_index);
		}

		Script_system.RemHookVars(4, "Weapon", "WeaponB", "Self", "Object");
		return 1;
	}

	return 0;
}