Exemplo n.º 1
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);
		}
	}
}
Exemplo n.º 2
0
float get_local_entity_armour_thickness (entity *target, entity *weapon)
{
	float
		armour_thickness;

	entity_sub_types
		sub_type;

	ASSERT (target);

	ASSERT (weapon);

	ASSERT (get_local_entity_int_value (weapon, INT_TYPE_IDENTIFY_WEAPON));

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	armour_thickness = 0.0;

	////////////////////////////////////////
	//
	// only vehicles are armoured
	//
	////////////////////////////////////////

	if (!get_local_entity_int_value (target, INT_TYPE_IDENTIFY_VEHICLE))
	{
		return (armour_thickness);
	}

	sub_type = get_local_entity_int_value (target, INT_TYPE_ENTITY_SUB_TYPE);

	////////////////////////////////////////
	//
	// only some vehicles are armoured
	//
	////////////////////////////////////////
	{
		int
			armoured;

		armoured =
		(
			(vehicle_database[sub_type].armour_front > 0.0) ||
			(vehicle_database[sub_type].armour_side > 0.0) ||
			(vehicle_database[sub_type].armour_rear > 0.0)
		);

		if (!armoured)
		{
			return (armour_thickness);
		}
	}

	////////////////////////////////////////
	//
	// get game difficulty level (use player's own level)
	//
	////////////////////////////////////////
	{
		game_difficulty_settings
			difficulty;

		entity
			*launcher,
			*pilot;

		difficulty = get_global_difficulty_level ();

		launcher = get_local_entity_parent (weapon, LIST_TYPE_LAUNCHED_WEAPON);

		if (launcher)
		{
			if (get_local_entity_int_value (launcher, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
			{
				pilot = get_local_entity_first_child (launcher, LIST_TYPE_AIRCREW);

				if (pilot)
				{
					difficulty = get_local_entity_int_value (pilot, INT_TYPE_DIFFICULTY_LEVEL);
				}
			}
		}

		if (difficulty == GAME_DIFFICULTY_EASY)
		{
			return (armour_thickness);
		}
	}

	////////////////////////////////////////
	//
	// get armour thickness
	//
	////////////////////////////////////////
	{
		float
			target_zvx,
			target_zvz,
			weapon_zvx,
			weapon_zvz,
			cos_theta,
			theta;

		matrix3x3
			*target_attitude,
			*weapon_attitude;

		target_attitude = get_local_entity_attitude_matrix_ptr (target);
		weapon_attitude = get_local_entity_attitude_matrix_ptr (weapon);

		target_zvx = (*target_attitude)[2][0];
		target_zvz = (*target_attitude)[2][2];
		weapon_zvx = -(*weapon_attitude)[2][0];
		weapon_zvz = -(*weapon_attitude)[2][2];

		cos_theta = (target_zvx * weapon_zvx) + (target_zvz * weapon_zvz);

		cos_theta = bound (cos_theta, -1.0, 1.0);

		theta = acos (cos_theta);

		if (theta <= rad (45.0))
		{
			armour_thickness = vehicle_database[sub_type].armour_front;
		}
		else if (theta <= rad (135.0))
		{
			armour_thickness = vehicle_database[sub_type].armour_side;
		}
		else
		{
			armour_thickness = vehicle_database[sub_type].armour_rear;
		}
	}

	return (armour_thickness);
}