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); } } }
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); }