Ejemplo n.º 1
0
float get_ka50_missile_flight_time (void)
{
	entity
		*en,
		*weapon,
		*target;

	vec3d
		*weapon_position,
		*target_position;

	float
		flight_time,
		weapon_velocity,
		target_range;

	flight_time = 0.0;

	en = get_gunship_entity ();

	//
	// find most recently launched Vikhr with a target (first found on list)
	//

	weapon = get_local_entity_first_child (en, LIST_TYPE_LAUNCHED_WEAPON);

	while (weapon)
	{
		if (get_local_entity_int_value (weapon, INT_TYPE_ENTITY_SUB_TYPE) == ENTITY_SUB_TYPE_WEAPON_VIKHR)
		{
			target = get_local_entity_parent (weapon, LIST_TYPE_TARGET);

			if (target)
			{
				weapon_position = get_local_entity_vec3d_ptr (weapon, VEC3D_TYPE_POSITION);

				target_position = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION);

				target_range = get_3d_range (weapon_position, target_position);

				weapon_velocity = get_local_entity_float_value (weapon, FLOAT_TYPE_VELOCITY);

				if (weapon_velocity > 0.0)
				{
					flight_time = target_range / weapon_velocity;

					break;
				}
			}
		}

		weapon = get_local_entity_child_succ (weapon, LIST_TYPE_LAUNCHED_WEAPON);
	}

	return (flight_time);
}
Ejemplo n.º 2
0
void update_weapon_lock_type (target_acquisition_systems system)
{
	entity
		*source,
		*target;

	entity_sub_types
		selected_weapon_type;

	float
		target_range,
		theta,
		weapon_min_range,
		weapon_max_range;

	vec3d
		*source_position,
		*target_position,
		*weapon_vector,
		*weapon_to_target_vector;

	////////////////////////////////////////
	//
	// WEAPON_LOCK_NO_ACQUIRE
	//
	////////////////////////////////////////

	if (system == TARGET_ACQUISITION_SYSTEM_OFF)
	{
		weapon_lock_type = WEAPON_LOCK_NO_ACQUIRE;

		return;
	}

	////////////////////////////////////////
	//
	// WEAPON_LOCK_NO_WEAPON
	//
	////////////////////////////////////////

	source = get_gunship_entity ();

	selected_weapon_type = get_local_entity_int_value (source, INT_TYPE_SELECTED_WEAPON);

	if (selected_weapon_type == ENTITY_SUB_TYPE_WEAPON_NO_WEAPON)
	{
		weapon_lock_type = WEAPON_LOCK_NO_WEAPON;

		return;
	}

	////////////////////////////////////////
	//
	// WEAPON_LOCK_NO_TARGET
	//
	////////////////////////////////////////

	target = get_local_entity_parent (source, LIST_TYPE_TARGET);

	if (!target)
	{
		weapon_lock_type = WEAPON_LOCK_NO_TARGET;

		return;
	}

	////////////////////////////////////////
	//
	// WEAPON_LOCK_INVALID_TARGET
	//
	////////////////////////////////////////

	//
	// infra-red air-to-air weapons require an airborne target
	//

	if (weapon_database[selected_weapon_type].guidance_type == WEAPON_GUIDANCE_TYPE_PASSIVE_INFRA_RED)
	{
		if (weapon_database[selected_weapon_type].weapon_class & WEAPON_CLASS_AIR_TO_AIR)
		{
			if (!get_local_entity_int_value (target, INT_TYPE_AIRBORNE_AIRCRAFT))
			{
				weapon_lock_type = WEAPON_LOCK_INVALID_TARGET;

				return;
			}
		}
	}

	////////////////////////////////////////
	//
	// WEAPON_LOCK_SEEKER_LIMIT
	//
	////////////////////////////////////////

	//
	// if guided weapon check target is inside the seeker limit
	//

	if (weapon_database[selected_weapon_type].guidance_type != WEAPON_GUIDANCE_TYPE_NONE)
	{
		update_entity_weapon_system_weapon_and_target_vectors (source);

		if (get_local_entity_int_value (source, INT_TYPE_WEAPON_AND_TARGET_VECTORS_VALID))
		{
			weapon_vector = get_local_entity_vec3d_ptr (source, VEC3D_TYPE_WEAPON_VECTOR);

			weapon_to_target_vector = get_local_entity_vec3d_ptr (source, VEC3D_TYPE_WEAPON_TO_TARGET_VECTOR);

			theta = get_3d_unit_vector_dot_product (weapon_vector, weapon_to_target_vector);

			theta = fabs (acos (theta));

			if (theta > weapon_database[selected_weapon_type].max_launch_angle_error)
			{
				weapon_lock_type = WEAPON_LOCK_SEEKER_LIMIT;

				return;
			}
		}
		else
		{
			//
			// this should never happen
			//

			debug_colour_log (DEBUG_COLOUR_RED, "WARNING! Target and weapon vectors are not valid");
		}
	}

	////////////////////////////////////////
	//
	// WEAPON_LOCK_NO_LOS
	//
	////////////////////////////////////////

	//
	// if air or ground radar then check line of sight
	//

	if ((system == TARGET_ACQUISITION_SYSTEM_GROUND_RADAR) || (system == TARGET_ACQUISITION_SYSTEM_AIR_RADAR))
	{
		if (!get_local_entity_int_value (target, INT_TYPE_GUNSHIP_RADAR_LOS_CLEAR))
		{
			weapon_lock_type = WEAPON_LOCK_NO_LOS;

			return;
		}
	}

	////////////////////////////////////////
	//
	// WEAPON_LOCK_NO_BORESIGHT
	//
	////////////////////////////////////////

	//
	// a boresight_weapon will be an unguided weapon so the seeker limit test is not being repeated here
	//

	if (weapon_database[selected_weapon_type].boresight_weapon)
	{
		update_entity_weapon_system_weapon_and_target_vectors (source);

		if (get_local_entity_int_value (source, INT_TYPE_WEAPON_AND_TARGET_VECTORS_VALID))
		{
			weapon_vector = get_local_entity_vec3d_ptr (source, VEC3D_TYPE_WEAPON_VECTOR);

			weapon_to_target_vector = get_local_entity_vec3d_ptr (source, VEC3D_TYPE_WEAPON_TO_TARGET_VECTOR);

			theta = get_3d_unit_vector_dot_product (weapon_vector, weapon_to_target_vector);

			theta = fabs (acos (theta));

			if (theta > rad (1.0))
			{
				weapon_lock_type = WEAPON_LOCK_NO_BORESIGHT;

				return;
			}
		}
		else
		{
			//
			// this should never happen
			//

			debug_colour_log (DEBUG_COLOUR_RED, "WARNING! Target and weapon vectors are not valid");
		}
	}

	////////////////////////////////////////
	//
	// WEAPON_LOCK_MIN_RANGE
	// WEAPON_LOCK_MAX_RANGE
	//
	////////////////////////////////////////

	source_position = get_local_entity_vec3d_ptr (source, VEC3D_TYPE_POSITION);
	target_position = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION);

	target_range = get_3d_range (source_position, target_position);

	weapon_min_range = weapon_database[selected_weapon_type].min_range;

	if (weapon_database[selected_weapon_type].hellfire_flight_profile)
	{
		if (get_local_entity_int_value (source, INT_TYPE_LOCK_ON_AFTER_LAUNCH))
		{
			weapon_min_range = weapon_database[selected_weapon_type].min_range_loal;
		}
	}

	if (target_range < weapon_min_range)
	{
		weapon_lock_type = WEAPON_LOCK_MIN_RANGE;

		return;
	}

	weapon_max_range = weapon_database[selected_weapon_type].max_range;

	if (weapon_database[selected_weapon_type].hellfire_flight_profile)
	{
		if (get_local_entity_int_value (source, INT_TYPE_LOCK_ON_AFTER_LAUNCH))
		{
			weapon_max_range = weapon_database[selected_weapon_type].max_range_loal;
		}
	}

	if (target_range > weapon_max_range)
	{
		weapon_lock_type = WEAPON_LOCK_MAX_RANGE;

		return;
	}

	////////////////////////////////////////
	//
	// WEAPON_LOCK_VALID
	//
	////////////////////////////////////////

	weapon_lock_type = WEAPON_LOCK_VALID;
}
Ejemplo n.º 3
0
float get_viper_missile_flight_time (void)
{
	entity_sub_types
		weapon_sub_type;

	entity
		*en,
		*weapon,
		*target;

	vec3d
		*weapon_position,
		*target_position;

	float
		flight_time,
		weapon_velocity,
		target_range;

	flight_time = 0.0;

	en = get_gunship_entity ();

	//
	// find most recently launched Hellfire with a target (first found on list)
	//

	weapon = get_local_entity_first_child (en, LIST_TYPE_LAUNCHED_WEAPON);

	while (weapon)
	{
		weapon_sub_type = get_local_entity_int_value (weapon, INT_TYPE_ENTITY_SUB_TYPE);

		if ((weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_AGM114L_LONGBOW_HELLFIRE) || (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_AGM114K_HELLFIRE_II))
		{
			target = get_local_entity_parent (weapon, LIST_TYPE_TARGET);

			if (target)
			{
				weapon_position = get_local_entity_vec3d_ptr (weapon, VEC3D_TYPE_POSITION);

				target_position = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION);

				target_range = get_3d_range (weapon_position, target_position);

				weapon_velocity = get_local_entity_float_value (weapon, FLOAT_TYPE_VELOCITY);

				if (weapon_velocity > 0.0)
				{
					flight_time = target_range / weapon_velocity;

					break;
				}
			}
		}

		weapon = get_local_entity_child_succ (weapon, LIST_TYPE_LAUNCHED_WEAPON);
	}

	return (flight_time);
}
Ejemplo n.º 4
0
void draw_debug_guide_entity (entity *en)
{

    waypoint
    *raw;

    entity
    *member,
    *this_waypoint;

    vec3d
    direction,
    guide_pos,
    *member_pos,
    *this_waypoint_position;

    float
    length;

    ASSERT (en);

    raw = (waypoint *) get_local_entity_data (en);

    //
    // get guide position
    //

    get_local_entity_vec3d (en, VEC3D_TYPE_GUIDE_POSITION, &guide_pos);

    //
    // get waypoint position
    //

    this_waypoint_position = NULL;

    this_waypoint = get_local_entity_parent (en, LIST_TYPE_CURRENT_WAYPOINT);

    ASSERT (this_waypoint);

    //
    // draw guide position
    //

    direction.x = 0.0;
    direction.y = 1.0;
    direction.z = 0.0;

    create_vectored_debug_3d_object (&guide_pos, &direction, OBJECT_3D_SPHERICAL_TEST, 0.0, 1.0);

    if (get_local_entity_int_value (this_waypoint, INT_TYPE_POSITION_TYPE) != POSITION_TYPE_VIRTUAL)
    {
        this_waypoint_position = get_local_entity_vec3d_ptr (this_waypoint, VEC3D_TYPE_POSITION);

        length = get_3d_range (&guide_pos, this_waypoint_position);

        if (length > 0.0)
        {
            create_debug_3d_line (&guide_pos, this_waypoint_position, sys_col_yellow, 0.0);
        }
    }

    //
    // draw vector to group position
    //

    member = get_local_entity_first_child (en, LIST_TYPE_FOLLOWER);

    while (member)
    {
        member_pos = get_local_entity_vec3d_ptr (member, VEC3D_TYPE_POSITION);

        length = get_3d_range (&guide_pos, member_pos);

        if (length > 0.0)
        {
            create_debug_3d_line (&guide_pos, member_pos, sys_col_light_red, 0.0);
        }

        member = get_local_entity_child_succ (member, LIST_TYPE_FOLLOWER);
    }
}
Ejemplo n.º 5
0
int collision_test_weapon_with_given_target (entity *weapon, entity *target, vec3d *weapon_old_position, vec3d *weapon_new_position)
{
	float
		range,
		weapon_velocity,
		time_to_impact,
		sqr_velocity;

	vec3d
		*target_position,
		*target_motion_vector,
		target_old_position,
		target_new_position,
		weapon_intercept_point,
		target_intercept_point;

	ASSERT (weapon);

	ASSERT (target);

	ASSERT (weapon_old_position);

	ASSERT (weapon_new_position);

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	//
	// approximate time to impact (uses the target position rather than the intercept point)
	//

	target_position = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION);

	range = get_approx_3d_range (target_position, weapon_new_position);

	weapon_velocity = get_local_entity_float_value (weapon, FLOAT_TYPE_VELOCITY);

	time_to_impact = range / max (weapon_velocity, 1.0);

	//
	// only proceed if close to impact
	//

	if (time_to_impact > 0.5)
	{
		return (FALSE);
	}

	if (get_local_entity_int_value (target, INT_TYPE_COLLISION_TEST_MOBILE))
	{
		////////////////////////////////////////
		//
		// MOBILE TARGET
		//
		////////////////////////////////////////

		target_motion_vector = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_MOTION_VECTOR);

		sqr_velocity =
		(
			target_motion_vector->x * target_motion_vector->x +
			target_motion_vector->y * target_motion_vector->y +
			target_motion_vector->z * target_motion_vector->z
		);

		if (sqr_velocity > 1.0)
		{
			//
			// moving mobile
			//

			if (get_local_entity_int_value (target, INT_TYPE_UPDATED))
			{
				get_local_entity_target_point (target, &target_new_position);

				target_old_position.x = target_new_position.x - target_motion_vector->x * get_delta_time ();
				target_old_position.y = target_new_position.y - target_motion_vector->y * get_delta_time ();
				target_old_position.z = target_new_position.z - target_motion_vector->z * get_delta_time ();
			}
			else
			{
				get_local_entity_target_point (target, &target_old_position);

				target_new_position.x = target_old_position.x + target_motion_vector->x * get_delta_time ();
				target_new_position.y = target_old_position.y + target_motion_vector->y * get_delta_time ();
				target_new_position.z = target_old_position.z + target_motion_vector->z * get_delta_time ();
			}

			if (get_3d_vector_cube_cube_intersect (weapon_old_position, weapon_new_position, &target_old_position, &target_new_position))
			{
				line_line_3d_intercept
				(
					weapon_old_position,
					weapon_new_position,
					&target_old_position,
					&target_new_position,
					&weapon_intercept_point,
					&target_intercept_point
				);

				range = get_3d_range (&weapon_intercept_point, &target_intercept_point);

				if (range < COLLISION_THRESHOLD)
				{
					*weapon_new_position = weapon_intercept_point;

					return (TRUE);
				}
			}
		}
		else
		{
			//
			// stationary mobile
			//

			get_local_entity_target_point (target, &target_new_position);

			range = get_3d_perp_dist_of_point_from_line (weapon_old_position, weapon_new_position, &target_new_position, &weapon_intercept_point);

			if (range < COLLISION_THRESHOLD)
			{
				*weapon_new_position = weapon_intercept_point;

				return (TRUE);
			}
		}
	}
	else if (get_local_entity_int_value (target, INT_TYPE_COLLISION_TEST_FIXED))
	{
		////////////////////////////////////////
		//
		// FIXED TARGET
		//
		////////////////////////////////////////

		get_local_entity_target_point (target, &target_new_position);

		range = get_3d_perp_dist_of_point_from_line (weapon_old_position, weapon_new_position, &target_new_position, &weapon_intercept_point);

		if (range < COLLISION_THRESHOLD)
		{
			*weapon_new_position = weapon_intercept_point;

			return (TRUE);
		}
	}

	return (FALSE);
}