示例#1
0
文件: aa_wpn.c 项目: Comanche93/eech
void update_anti_aircraft_weapon_fire (entity *en)
{
   anti_aircraft
      *raw;

	int
		continue_burst_fire;

	float
		launch_angle_error;

	vec3d
		*weapon_vector,
		*weapon_to_target_vector;

	ASSERT (en);

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

   raw = get_local_entity_data (en);

	//
	// check valid selected weapon
	//

	if (raw->vh.selected_weapon == ENTITY_SUB_TYPE_WEAPON_NO_WEAPON)
	{
		raw->vh.weapon_burst_timer = 0.0;

		return;
	}

	//
	// check selected weapon is ready
	//

	if (!raw->vh.selected_weapon_system_ready)
	{
		if (raw->vh.weapon_burst_timer > 0.0)
		{
			pause_client_server_continuous_weapon_sound_effect (en, raw->vh.selected_weapon);
		}

		return;
	}

	//
	// check valid target
	//

	if (!raw->vh.mob.target_link.parent)
	{
		if (raw->vh.weapon_burst_timer > 0.0)
		{
			pause_client_server_continuous_weapon_sound_effect (en, raw->vh.selected_weapon);
		}

		return;
	}

	//
	// check within max launch angle error
	//

	if (!get_local_entity_int_value (en, INT_TYPE_WEAPON_AND_TARGET_VECTORS_VALID))
	{
		if (raw->vh.weapon_burst_timer > 0.0)
		{
			pause_client_server_continuous_weapon_sound_effect (en, raw->vh.selected_weapon);
		}

		return;
	}

	weapon_vector = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_WEAPON_VECTOR);

	ASSERT (weapon_vector);

	weapon_to_target_vector = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_WEAPON_TO_TARGET_VECTOR);

	ASSERT (weapon_to_target_vector);

	launch_angle_error = acos (get_3d_unit_vector_dot_product (weapon_vector, weapon_to_target_vector));

	if (fabs (launch_angle_error) > weapon_database[raw->vh.selected_weapon].max_launch_angle_error)
	{
		if (raw->vh.weapon_burst_timer > 0.0)
		{
			pause_client_server_continuous_weapon_sound_effect (en, raw->vh.selected_weapon);
		}

		return;
	}

	//
	// update burst
	//

	continue_burst_fire = FALSE;

	if (raw->vh.weapon_burst_timer > 0.0)
	{
		raw->vh.weapon_burst_timer -= get_delta_time ();

		if (raw->vh.weapon_burst_timer > 0.0)
		{
			continue_burst_fire = TRUE;
		}
		else
		{
			pause_client_server_continuous_weapon_sound_effect (en, raw->vh.selected_weapon);
		}
	}

	//
	// fire weapon
	//

	if (raw->vh.ready_to_fire || continue_burst_fire)
	{
		if (!get_local_entity_int_value (get_session_entity (), INT_TYPE_SUPPRESS_AI_FIRE))
		{
			launch_client_server_weapon (en, raw->vh.selected_weapon);
		}
	}
}
示例#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;
}
示例#3
0
static void update_threat_warning_display (void)
{
	entity
		*source,
		*threat;

	int
		above = FALSE,
		overshot,
		threat_active;

	float
		dx,
		dy,
		dz,
		theta,
		threat_bearing,
		threat_range,
		threat_velocity,
		time_to_impact,
		source_heading,
		length,
		cos_error;

	threat_types
		threat_type;

	vec3d
		*source_position,
		*threat_position,
		uvec_threat_to_target;

	matrix3x3
		*attitude;

	clear_threat_warning_display_lamps ();

	if (hind_damage.threat_warning_display || hind_damage.radar_warning_system)
	{
		return;
	}

	threat = get_local_entity_first_child (get_gunship_entity (), LIST_TYPE_TARGET);

	if (threat)
	{
		source = get_gunship_entity ();

		source_position = get_local_entity_vec3d_ptr (source, VEC3D_TYPE_POSITION);

		source_heading = get_local_entity_float_value (source, FLOAT_TYPE_HEADING);

		while (threat)
		{
			entity_sub_types sub_type = get_local_entity_int_value(threat, INT_TYPE_ENTITY_SUB_TYPE);
			float max_range = 10.0;

			threat_type = (threat_types) get_local_entity_int_value (threat, INT_TYPE_THREAT_TYPE);

			//
			// check threat is active
			//

			if (get_local_entity_int_value (threat, INT_TYPE_IDENTIFY_VEHICLE))
			{
				max_range = vehicle_database[sub_type].air_scan_range;
				threat_active = get_local_entity_int_value (threat, INT_TYPE_RADAR_ON);
			}
			else if (get_local_entity_int_value (threat, INT_TYPE_IDENTIFY_AIRCRAFT))
			{
				max_range = aircraft_database[sub_type].air_scan_range;
				threat_active = get_local_entity_int_value (threat, INT_TYPE_RADAR_ON);
			}
			else if (get_local_entity_int_value (threat, INT_TYPE_IDENTIFY_WEAPON))
			{
				weapon_guidance_types guidance = weapon_database[sub_type].guidance_type;

				threat_active = guidance == WEAPON_GUIDANCE_TYPE_ACTIVE_RADAR;
				if (guidance == WEAPON_GUIDANCE_TYPE_ACTIVE_RADAR || guidance == WEAPON_GUIDANCE_TYPE_SEMI_ACTIVE_RADAR)
				{
					hind_lamps.threat_warning_missile_lh_lock = 1;
					hind_lamps.threat_warning_missile_rh_lock = 1;
				}

				max_range = weapon_database[sub_type].max_range;
			}

#if 0
			switch (threat_type)
			{
				////////////////////////////////////////
				case THREAT_TYPE_INVALID:
				////////////////////////////////////////
				{
					threat_active = FALSE;

					break;
				}
				////////////////////////////////////////
				case THREAT_TYPE_RF_MISSILE:
				////////////////////////////////////////
				{
					ASSERT(get_local_entity_int_value (threat, INT_TYPE_IDENTIFY_WEAPON));

					if (!hind_damage.radar_warning_system)
					{
						threat_active = TRUE;
					}
					else
					{
						threat_active = FALSE;
					}

					break;
				}
				////////////////////////////////////////
				case THREAT_TYPE_IR_MISSILE:
				////////////////////////////////////////
				{
					threat_active = FALSE;

					break;
				}
				////////////////////////////////////////
				case THREAT_TYPE_LASER_MISSILE:
				////////////////////////////////////////
				{
					threat_active = FALSE;

					break;
				}
				////////////////////////////////////////
				case THREAT_TYPE_AIRBORNE_RADAR:
				////////////////////////////////////////
				{
					if (!hind_damage.radar_warning_system)
					{
						threat_active = get_local_entity_int_value (threat, INT_TYPE_RADAR_ON);
					}
					else
					{
						threat_active = FALSE;
					}

					break;
				}
				////////////////////////////////////////
				case THREAT_TYPE_SAM:
				////////////////////////////////////////
				{
					if (!hind_damage.radar_warning_system)
					{
						threat_active = get_local_entity_int_value (threat, INT_TYPE_RADAR_ON);
					}
					else
					{
						threat_active = FALSE;
					}

					break;
				}
				////////////////////////////////////////
				case THREAT_TYPE_AAA:
				////////////////////////////////////////
				{
					if (!hind_damage.radar_warning_system)
					{
						threat_active = get_local_entity_int_value (threat, INT_TYPE_RADAR_ON);
					}
					else
					{
						threat_active = FALSE;
					}

					break;
				}
				////////////////////////////////////////
				case THREAT_TYPE_EARLY_WARNING_RADAR:
				////////////////////////////////////////
				{
					if (!hind_damage.radar_warning_system)
					{
						threat_active = get_local_entity_int_value (threat, INT_TYPE_RADAR_ON);
					}
					else
					{
						threat_active = FALSE;
					}

					break;
				}
				////////////////////////////////////////
				default:
				////////////////////////////////////////
				{
					debug_fatal ("Invalid threat type = %d", threat_type);

					break;
				}
			}
#endif

			if (threat_active)
			{
				//
				// get threat direction wrt aircraft datum
				//

				threat_position = get_local_entity_vec3d_ptr (threat, VEC3D_TYPE_POSITION);

				dx = threat_position->x - source_position->x;
				dy = threat_position->y - source_position->y;
				dz = threat_position->z - source_position->z;

				threat_range = sqrt ((dx * dx) + (dy * dy) + (dz * dz));
				above = dy > 0.0;
				threat_bearing = atan2 (dx, dz);
				theta = threat_bearing - source_heading;

				if (theta > rad (180.0))
				{
					theta -= rad (360.0);
				}
				else if (theta < rad (-180.0))
				{
					theta += rad (360.0);
				}

				//
				// if missile threat then guard against 'overshot target' to prevent spurious indications
				//

				if ((threat_type == THREAT_TYPE_RF_MISSILE) || (threat_type == THREAT_TYPE_IR_MISSILE) || (threat_type == THREAT_TYPE_LASER_MISSILE))
				{
					threat_velocity = get_local_entity_float_value (threat, FLOAT_TYPE_VELOCITY);

					time_to_impact = threat_range / max (threat_velocity, 1.0f);

					overshot = FALSE;

					if (time_to_impact < 1.0)
					{
						uvec_threat_to_target.x = source_position->x - threat_position->x;
						uvec_threat_to_target.y = source_position->y - threat_position->y;
						uvec_threat_to_target.z = source_position->z - threat_position->z;

						length = get_3d_vector_magnitude (&uvec_threat_to_target);

						if (length > 1.0)
						{
							normalise_3d_vector_given_magnitude (&uvec_threat_to_target, length);

							attitude = get_local_entity_attitude_matrix_ptr (threat);

							cos_error = get_3d_unit_vector_dot_product ((vec3d *) &((*attitude) [2][0]), &uvec_threat_to_target);

							if (cos_error < 0.0)
							{
								overshot = TRUE;
							}
						}
						else
						{
							overshot = TRUE;
						}
					}

					if (!overshot)
					{
						light_threat_bearing_lamp (theta);
						light_signal_strength_lamps(threat_range, max_range);

						hind_lamps.threat_warning_radar_type_1 = 1;

						if (above)
							hind_lamps.threat_warning_missile_above = 1;
						else
							hind_lamps.threat_warning_missile_below = 1;
					}
				}
				else
				{
					light_threat_bearing_lamp (theta);
					light_signal_strength_lamps(threat_range, max_range);

					if (above)
						hind_lamps.threat_warning_missile_above = 1;
					else
						hind_lamps.threat_warning_missile_below = 1;

					if (threat_type == THREAT_TYPE_AIRBORNE_RADAR)
						hind_lamps.threat_warning_radar_type_1 = 1;
					else
					{
						if (max_range <= 4000.0)  // short range
							hind_lamps.threat_warning_radar_type_4 = 1;
						else if (max_range <= 10000.0)   // medium range
							hind_lamps.threat_warning_radar_type_3 = 1;
						else  // long range
							hind_lamps.threat_warning_radar_type_2 = 1;
					}

				}
			}

			threat = get_local_entity_child_succ (threat, LIST_TYPE_TARGET);
		}
	}
}