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); }
void set_chase_camera_view_target_to_source (entity *source, entity *target) { camera *raw; float length; vec3d *source_position, *target_position, direction; ASSERT (source); ASSERT (target); ASSERT (get_camera_entity ()); raw = get_local_entity_data (get_camera_entity ()); source_position = get_local_entity_vec3d_ptr (source, VEC3D_TYPE_POSITION); target_position = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION); direction.x = source_position->x - target_position->x; direction.y = source_position->y - target_position->y; direction.z = source_position->z - target_position->z; length = (direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z); if (length > 1.0) { length = sqrt (length); normalise_3d_vector_given_magnitude (&direction, length); raw->chase_camera_heading = atan2 (direction.x, direction.z); if (raw->chase_camera_lock_rotate) { raw->chase_camera_heading -= get_local_entity_float_value (target, FLOAT_TYPE_HEADING); raw->chase_camera_heading = wrap_angle (raw->chase_camera_heading); } raw->chase_camera_pitch = asin (direction.y); } }
void initialise_free_flight_screen_map_page_objects (void) { vec3d *pos; set_active_map_object (NULL); if (get_gunship_entity ()) { pos = get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION); page_map_dimensions.x = pos->x; page_map_dimensions.z = pos->z; page_map_dimensions.size = 32.0 * KILOMETRE; } else { page_map_dimensions.x = MID_MAP_X; page_map_dimensions.z = MID_MAP_Z; page_map_dimensions.size = min (MAX_MAP_X - MIN_MAP_X, MAX_MAP_Z - MIN_MAP_Z); } page_map_dimensions.selected_entity = NULL; clear_map_mouse_over_object (&page_map_dimensions); }
float adjust_radio_message_amplification (float amp, vec3d *pos) { float d, range; if (!get_gunship_entity ()) { return amp; } ASSERT (pos); range = get_approx_3d_range (get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION), pos); if (range > 120 * KILOMETRE) { return 0.0; } if (range < 1 * KILOMETRE) { return amp; } d = ((120 * KILOMETRE) - range) / ((120 * KILOMETRE) - (1 * KILOMETRE)); return (d * amp); }
static void draw_page_3d_scene (ui_object *obj, void *arg) { entity *en; viewpoint vp; vec3d *pos, vec; en = get_local_entity_safe_ptr (get_ui_object_item_number (obj)); if (en) { pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); ASSERT (pos); get_3d_unit_vector_from_heading_and_pitch (&vec, page_3d_heading, page_3d_pitch); vp.x = pos->x + (page_3d_distance * vec.x); vp.y = pos->y + (page_3d_distance * vec.y); vp.z = pos->z + (page_3d_distance * vec.z); invert_3d_vector (&vec); get_matrix3x3_from_unit_vec3d (vp.attitude, &vec); draw_campaign_screen_3d_scene (obj, &vp); } }
int check_entity_line_of_sight (entity *source, entity *target, mobile_los_check_criteria criteria) { vec3d *source_position, *target_position; ASSERT (source); ASSERT (target); source_position = get_local_entity_vec3d_ptr (source, VEC3D_TYPE_POSITION); target_position = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION); return check_position_line_of_sight (source, target, source_position, target_position, criteria); }
int clear_ship_fires (entity *ship_en, entity_sub_types type) { entity *en; vec3d *pos; en = get_local_entity_first_child (ship_en, LIST_TYPE_SPECIAL_EFFECT); while (en) { if (en->type == ENTITY_TYPE_SMOKE_LIST) { if (get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE) == type) { pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); if (pos->y < 0.0) { set_local_entity_float_value (en, FLOAT_TYPE_GENERATOR_LIFETIME, 0.0); } } } en = get_local_entity_child_succ (en, LIST_TYPE_SPECIAL_EFFECT); } return TRUE; }
static void set_eo_view_params(target_acquisition_systems system, int x_min, int y_min, int x_max, int y_max, float xfov, float yfov) { display_3d_light_levels light_level; display_3d_noise_levels noise_level; vec3d *position; weathermodes weather_mode; day_segment_types day_segment_type; display_3d_tints tint; position = get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION); weather_mode = get_simple_session_weather_at_point (position); ASSERT ((weather_mode > WEATHERMODE_INVALID) && (weather_mode < WEATHERMODE_LAST)); day_segment_type = (day_segment_types) get_local_entity_int_value (get_session_entity (), INT_TYPE_DAY_SEGMENT_TYPE); ASSERT ((day_segment_type >= 0) && (day_segment_type < NUM_DAY_SEGMENT_TYPES)); switch (system) { case TARGET_ACQUISITION_SYSTEM_FLIR: { light_level = flir_light_levels[weather_mode][day_segment_type]; noise_level = flir_noise_levels[weather_mode][day_segment_type]; tint = DISPLAY_3D_TINT_AMBER; break; } case TARGET_ACQUISITION_SYSTEM_LLLTV: { light_level = llltv_light_levels[weather_mode][day_segment_type]; noise_level = llltv_noise_levels[weather_mode][day_segment_type]; tint = DISPLAY_3D_TINT_AMBER_VISUAL; break; } default: { debug_fatal ("Invalid target acquisition system = %d", system); break; } } set_main_3d_params (tint, light_level, noise_level, x_min, y_min, x_max, y_max, xfov, yfov); }
static int response_to_unlink_child (entity_messages message, entity *receiver, entity *sender, va_list pargs) { camera *raw; list_types list_type; #if DEBUG_MODULE debug_log_entity_message (message, receiver, sender, pargs); #endif raw = get_local_entity_data (receiver); list_type = va_arg (pargs, list_types); switch (list_type) { //////////////////////////////////////// case LIST_TYPE_VIEW: //////////////////////////////////////// { if (raw->external_view_entity == sender) { raw->external_view_entity = NULL; } notify_view_menu_of_view_list_change (sender); break; } //////////////////////////////////////// case LIST_TYPE_VIEW_WEAPON: //////////////////////////////////////// { ASSERT (sender); if (get_view_mode () == VIEW_MODE_EXTERNAL) { if (get_local_entity_int_value (get_camera_entity (), INT_TYPE_CAMERA_MODE) == CAMERA_MODE_WEAPON) { notify_local_entity (ENTITY_MESSAGE_SET_CAMERA_ACTION, get_camera_entity (), NULL, CAMERA_ACTION_WEAPON_EXPLOSION); reset_weapon_explosion_camera_position (get_local_entity_vec3d_ptr (sender, VEC3D_TYPE_POSITION)); } } break; } } return (TRUE); }
static vec3d *get_local_vec3d_ptr (entity *en, vec3d_types type) { group *raw; vec3d *v; raw = (group *) get_local_entity_data (en); switch (type) { //////////////////////////////////////// case VEC3D_TYPE_POSITION: //////////////////////////////////////// { entity *member; member = (entity *) get_local_entity_ptr_value (en, PTR_TYPE_GROUP_LEADER); if (member) { v = get_local_entity_vec3d_ptr (member, type); } else { v = NULL; } break; } //////////////////////////////////////// case VEC3D_TYPE_LAST_KNOWN_POSITION: //////////////////////////////////////// { v = &raw->last_known_position; break; } //////////////////////////////////////// default: //////////////////////////////////////// { debug_fatal_invalid_vec3d_type (en, type); break; } } return (v); }
static int response_to_articulate_undercarriage (entity_messages message, entity *receiver, entity *sender, va_list pargs) { vec3d *position; object_3d_instance *inst3d; sound_sample_indices sample_index; #if DEBUG_MODULE //debug_log_entity_message (message, receiver, sender, pargs); #endif ASSERT (get_comms_model () == COMMS_MODEL_SERVER); inst3d = (object_3d_instance *) get_local_entity_ptr_value (receiver, PTR_TYPE_INSTANCE_3D_OBJECT); if (inst3d) { if (object_contains_sub_object_type (inst3d, OBJECT_3D_SUB_OBJECT_UNDERCARRIAGE, 0, NULL)) { position = get_local_entity_vec3d_ptr (receiver, VEC3D_TYPE_POSITION); sample_index = SOUND_SAMPLE_INDEX_UNDERCARRIAGE; create_client_server_sound_effect_entity ( receiver, ENTITY_SIDE_NEUTRAL, ENTITY_SUB_TYPE_EFFECT_SOUND_MISC, SOUND_CHANNEL_SOUND_EFFECT, SOUND_LOCALITY_ALL, NULL, // position 1.0, // amplification 1.0, // Werewolf pitch TRUE, // valid sound effect FALSE, // looping 1, // sample count &sample_index // sample index list ); } } return (TRUE); }
void get_mi24_map_caret_position(float *x, float *z) { if (!hind_damage.navigation_computer) { vec3d *position; float nx, nz; position = get_local_entity_vec3d_ptr (get_gunship_entity(), VEC3D_TYPE_POSITION); nx = (position->x - map_centre_position.x) * map_scale * 0.125, nz = (position->z - map_centre_position.z) * map_scale * 0.115; *x = bound(nx, -0.12, 0.12); *z = bound(nz, -0.075, 0.065); } }
void update_waypoint_shared_mem() { entity* wp; if (!gPtrSharedMemory || !get_gunship_entity()) return; wp = get_local_entity_current_waypoint(get_gunship_entity()); if (wp) { vec3d *gunship_position, waypoint_position; float dx, dz, bearing; gunship_position = get_local_entity_vec3d_ptr(get_gunship_entity(), VEC3D_TYPE_POSITION); get_waypoint_display_position (get_gunship_entity(), wp, &waypoint_position); gPtrSharedMemory->waypoint_data.waypoint = get_local_entity_char_value(wp, CHAR_TYPE_TAG); gPtrSharedMemory->waypoint_data.waypoint_range = get_2d_range (gunship_position, &waypoint_position); dx = waypoint_position.x - gunship_position->x; dz = waypoint_position.z - gunship_position->z; bearing = deg(atan2(dx, dz)); if (bearing < 0.0) bearing += 360.0; gPtrSharedMemory->waypoint_data.waypoint_bearing = bearing; } else memset(&gPtrSharedMemory->waypoint_data, 0, sizeof(waypoint_data_t)); }
void create_force_campaign_objectives (entity *force) { entity *keysite, *target_force, **list; int loop, count, side, target_side; float highest, *rating; ASSERT (get_comms_model () == COMMS_MODEL_SERVER); ASSERT (get_session_entity ()); ASSERT (force); side = get_local_entity_int_value (force, INT_TYPE_SIDE); // // count up potential objective keysites // count = 0; target_force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (target_force) { if (target_force != force) { keysite = get_local_entity_first_child (target_force, LIST_TYPE_KEYSITE_FORCE); while (keysite) { if (get_local_entity_int_value (keysite, INT_TYPE_POTENTIAL_CAMPAIGN_OBJECTIVE)) { if (get_local_entity_int_value (keysite, INT_TYPE_IN_USE)) { count ++; } } keysite = get_local_entity_child_succ (keysite, LIST_TYPE_KEYSITE_FORCE); } } target_force = get_local_entity_child_succ (target_force, LIST_TYPE_FORCE); } if (count == 0) { debug_fatal ("SETUP: No potential campaign objectives for side %s", entity_side_short_names [side]); } // // construct the list and rate each keysite according to sector importance // list = malloc_heap_mem (sizeof (entity *) * count); rating = malloc_heap_mem (sizeof (float) * count); highest = 0.0; count = 0; target_force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (target_force) { if (target_force != force) { target_side = get_local_entity_int_value (target_force, INT_TYPE_SIDE); keysite = get_local_entity_first_child (target_force, LIST_TYPE_KEYSITE_FORCE); while (keysite) { if (get_local_entity_int_value (keysite, INT_TYPE_POTENTIAL_CAMPAIGN_OBJECTIVE)) { if (get_local_entity_int_value (keysite, INT_TYPE_IN_USE)) { float actual_range; vec3d *pos; list [count] = keysite; pos = get_local_entity_vec3d_ptr (keysite, VEC3D_TYPE_POSITION); get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, target_side, pos, 1.0 * KILOMETRE, &actual_range, keysite); rating [count] = actual_range; highest = max (highest, rating [count]); count ++; } } keysite = get_local_entity_child_succ (keysite, LIST_TYPE_KEYSITE_FORCE); } } target_force = get_local_entity_child_succ (target_force, LIST_TYPE_FORCE); } // // Normalise ratings // if (highest == 0.0) { debug_fatal ("SETUP: No sector importance for side %s", entity_side_short_names [side]); } for (loop = 0; loop < count; loop ++) { rating [loop] = rating [loop] / highest; } // // obligatory random factor // for (loop = 0; loop < count; loop ++) { rating [loop] += frand1 (); } // // sort the list // quicksort_entity_list (list, count, rating); // // now find the best N targets and link them into the force // count = min (count, NUMBER_OF_CAMPAIGN_OBJECTIVES_PER_SIDE); for (loop = 0; loop < count; loop ++) { insert_local_entity_into_parents_child_list (list [loop], LIST_TYPE_CAMPAIGN_OBJECTIVE, force, NULL); debug_log ("Side %s Objective :- %s (%s)", entity_side_short_names [side], get_local_entity_string (list [loop], STRING_TYPE_KEYSITE_NAME), get_local_entity_string (list [loop], STRING_TYPE_FULL_NAME)); } free_mem (list); free_mem (rating); }
static void update_server (entity *en) { entity *parent, *next_segment, *prev_segment; entity_sub_types sub_type; vec3d *pos; float terrain_height; terrain_3d_point_data terrain_info; // // notify the segments neighbours as applicable // parent = get_local_entity_parent (en, LIST_TYPE_SEGMENT); ASSERT (parent); next_segment = get_local_entity_child_succ (en, LIST_TYPE_SEGMENT); if (next_segment) { notify_local_entity (ENTITY_MESSAGE_COLLISION, parent, next_segment); } prev_segment = get_local_entity_child_pred (en, LIST_TYPE_SEGMENT); if (prev_segment) { notify_local_entity (ENTITY_MESSAGE_COLLISION, parent, prev_segment); } sub_type = get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE); if (sub_type == ENTITY_SUB_TYPE_FIXED_BRIDGE_UNSUPPORTED_MID_SECTION) { // // make the segment drop to the floor ( removing it from the update list when it hits ) // pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); pos->y -= ( 10.0 * get_delta_time() ); memset (&terrain_info, 0, sizeof (terrain_3d_point_data)); terrain_height = get_3d_terrain_point_data (pos->x, pos->z, &terrain_info); if (get_terrain_type_class (terrain_info.terrain_type) == TERRAIN_CLASS_WATER) { terrain_height -= 1.0; } if ( pos->y <= terrain_height ) { pos->y = terrain_height; delete_local_entity_from_parents_child_list (en, LIST_TYPE_UPDATE); if (get_comms_model () == COMMS_MODEL_SERVER) { create_client_server_object_hit_ground_explosion_effect (en, terrain_info.terrain_type); } } } else { // // segment is supported, and so should be instantly removed from the update list // ( only put there in the first place so that neighbours would be notified ) // delete_local_entity_from_parents_child_list (en, LIST_TYPE_UPDATE); } }
static void display_weapon_information (void) { entity_sub_types weapon_sub_type; float x, y, angle_of_drop, drop_hud_distance, roll; weapon_sub_type = get_local_entity_int_value (get_gunship_entity (), INT_TYPE_SELECTED_WEAPON); if (weapon_sub_type != ENTITY_SUB_TYPE_WEAPON_NO_WEAPON) { // // weapon specific // if ((weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_S5) || (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_S8) || (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_S13) || (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_GSH23L_23MM_ROUND) || (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_9A642_12P7MM_ROUND && target_acquisition_system != TARGET_ACQUISITION_SYSTEM_HMS)) { float x,y; angle_of_drop = 0.0; drop_hud_distance; roll = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_ROLL); angle_of_drop = get_ballistic_weapon_drop(weapon_sub_type); drop_hud_distance = atan(angle_of_drop) * hud_position_z / (0.5 * hud_height); y = cos(roll) * -drop_hud_distance; x = sin(roll) * drop_hud_distance; draw_aim_marker(x, y, hud_aim_range, weapon_database[weapon_sub_type].min_range); // draw target marker around target if having cpg assist if (get_global_cpg_assist_type() != CPG_ASSIST_TYPE_NONE && eo_is_locked()) { float az, el; get_eo_azimuth_and_elevation(&az, &el); if (angles_to_hud_coordinates(az, el, &x, &y, TRUE)) draw_2d_circle(x, y, 0.15, hud_colour); } } else { entity* target = get_local_entity_parent (get_gunship_entity (), LIST_TYPE_TARGET); vec3d* tracking_point; // will use point lock if no target tracking_point = get_eo_tracking_point(); if (target || tracking_point) { vec3d target_position, *source_position; float elevation, azimuth; if (target) get_local_entity_target_point (target, &target_position); else target_position = *tracking_point; source_position = get_local_entity_vec3d_ptr(get_gunship_entity(), VEC3D_TYPE_POSITION); get_eo_azimuth_and_elevation(&azimuth, &elevation); hud_aim_range = get_triangulated_by_position_range(source_position, &target_position); if (angles_to_hud_coordinates(azimuth, elevation, &x, &y, TRUE)) draw_aim_marker(x, y, hud_aim_range, weapon_database[weapon_sub_type].min_range); } } } }
entity *create_local_sound_effect_entity ( int index, entity *parent, entity_sides side, entity_sub_types sub_type, sound_channel_types channel, sound_locality_types locality, vec3d *position, float amp, int valid, int looping, int sample_count, sound_sample_indices *sample_indices ) { entity *en; vec3d pos; int panning, create_stack_attributes; ASSERT (parent); create_stack_attributes = force_local_entity_create_stack_attributes; if (get_comms_data_flow () == COMMS_DATA_FLOW_RX) { set_force_local_entity_create_stack_attributes (TRUE); } panning = TRUE; if (position) { pos = *position; } else { position = get_local_entity_vec3d_ptr (parent, VEC3D_TYPE_POSITION); if (position) { pos = *position; } else { pos.x = MID_MAP_X; pos.y = MID_MAP_Y; pos.z = MID_MAP_Z; panning = FALSE; } } // // special cases for speech // switch (sub_type) { case ENTITY_SUB_TYPE_EFFECT_SOUND_RADIO_MESSAGE: { if (get_global_gunship_side () == side) { amp = adjust_radio_message_amplification (amp, &pos); } else { amp = 0.0; } panning = FALSE; break; } case ENTITY_SUB_TYPE_EFFECT_SOUND_CPG_MESSAGE: case ENTITY_SUB_TYPE_EFFECT_SOUND_WARNING_MESSAGE: { if (parent == get_gunship_entity ()) { amp = 1.0; } else { amp = 0.0; } panning = FALSE; break; } } // // create sound // en = create_local_entity ( ENTITY_TYPE_SOUND_EFFECT, index, ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, sub_type), ENTITY_ATTR_PARENT (LIST_TYPE_SPECIAL_EFFECT, parent), ENTITY_ATTR_VEC3D (VEC3D_TYPE_POSITION, pos.x, pos.y, pos.z), ENTITY_ATTR_INT_VALUE (INT_TYPE_SOUND_CHANNEL, channel), ENTITY_ATTR_INT_VALUE (INT_TYPE_SOUND_EFFECT_LOOPING, looping), ENTITY_ATTR_INT_VALUE (INT_TYPE_SOUND_EFFECT_PANNING, panning), ENTITY_ATTR_INT_VALUE (INT_TYPE_SOUND_LOCALITY, locality), ENTITY_ATTR_INT_VALUE (INT_TYPE_VALID_SOUND_EFFECT, valid), ENTITY_ATTR_FLOAT_VALUE (FLOAT_TYPE_AMPLIFICATION, amp), ENTITY_ATTR_END ); set_local_sound_effect_sample_indices (en, sample_count, sample_indices); #if DEBUG_MODULE debug_log ("SOUNDEFF : created effect %s (%d), parent %s (%d), next %d, looping %d, valid %d", application_sound_effects [sample_indices [0]].name, get_local_entity_index (en), get_local_entity_type_name (parent), get_local_entity_index (parent), looping, valid); #endif set_force_local_entity_create_stack_attributes (create_stack_attributes); return en; }
aircraft_fire_result aircraft_fire_weapon (entity *en, unsigned int check_flags) { entity *target; aircraft *raw; vec3d *target_pos, en_pos; ASSERT (en); raw = get_local_entity_data (en); // // Fire suppressed // if (check_flags & AIRCRAFT_FIRE_SUPPRESSED) { if (get_local_entity_int_value (get_session_entity (), INT_TYPE_SUPPRESS_AI_FIRE)) { return AIRCRAFT_FIRE_SUPPRESSED; } } // // check weapon // if (check_flags & AIRCRAFT_FIRE_NO_WEAPON) { if (get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON) == ENTITY_SUB_TYPE_WEAPON_NO_WEAPON) { debug_log ("AC_WPN: Fire Weapon Error - NO WEAPON"); return AIRCRAFT_FIRE_NO_WEAPON; } } // // weapon system_ready // if (check_flags & AIRCRAFT_FIRE_WEAPON_SYSTEM_NOT_READY) { if (!get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON_SYSTEM_READY)) { debug_log ("AC_WPN: Fire Weapon Error - WEAPON SYSTEM NOT READY"); return AIRCRAFT_FIRE_WEAPON_SYSTEM_NOT_READY; } } // // find target // if (check_flags & AIRCRAFT_FIRE_NO_TARGET) { target = get_local_entity_parent (en, LIST_TYPE_TARGET); if (!target) { debug_log ("AC_WPN: Fire Weapon Error - NO TARGET"); return AIRCRAFT_FIRE_NO_TARGET; } } // // line of sight checks // if (check_flags & AIRCRAFT_FIRE_NO_LOS) { int criteria; if (get_local_entity_int_value (target, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI) { criteria = MOBILE_LOS_CHECK_ALL; } else { criteria = MOBILE_LOS_CHECK_COURSE_TERRAIN; } get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &en_pos); target_pos = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION); en_pos.y -= (get_local_entity_float_value (en, FLOAT_TYPE_CENTRE_OF_GRAVITY_TO_GROUND_DISTANCE) + 2.0); if (!check_position_line_of_sight (en, target, &en_pos, target_pos, criteria)) { debug_log ("AC_WPN: Fire Weapon Error - NO LOS (Aircraft %s (%d), Target %s (%d))", get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_index (en), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target)); return AIRCRAFT_FIRE_NO_LOS; } } // // Play Speech // play_aircraft_weapon_launched_speech (en, raw->selected_weapon); // // Fire weapon // launch_client_server_weapon (en, raw->selected_weapon); return AIRCRAFT_FIRE_OK; }
void update_dynamics_at_keysite (void) { unsigned int model_damage, damage_count, this_damage; if ((!get_keysite_currently_landed_at ()) || (!get_gunship_entity ())) { return; } // // Refuel, only set if inside keysite // #if !DEMO_VERSION if (current_flight_dynamics->refuelling) { entity *keysite; float max_fuel; if (!(current_flight_dynamics->dynamics_damage & DYNAMICS_DAMAGE_FUEL_LEAK)) { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: refuelling, fuel = %f (max = %f)", current_flight_dynamics->fuel_weight.value, current_flight_dynamics->fuel_weight.max); //#endif max_fuel = current_flight_dynamics->fuel_weight.max; keysite = get_keysite_currently_landed_at (); if (keysite) { if (get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL) <= 0.0) { if (!get_connection_list_head ()) { max_fuel *= 0.25; } } } if (current_flight_dynamics->fuel_weight.value >= max_fuel) { current_flight_dynamics->refuelling = FALSE; } else { current_flight_dynamics->fuel_weight.value += REFUELLING_RATE * get_delta_time (); } current_flight_dynamics->fuel_weight.value = bound (current_flight_dynamics->fuel_weight.value, current_flight_dynamics->fuel_weight.min, current_flight_dynamics->fuel_weight.max); } else { debug_log ("DYNAMICS: can't refuel till leak is fixed"); } } #endif // // Repair, only set if inside keysite // if (current_flight_dynamics->repairing) { if (current_flight_dynamics->dynamics_damage != DYNAMICS_DAMAGE_NONE) { current_flight_dynamics->damage_repair_time -= get_delta_time (); current_flight_dynamics->damage_repair_time = max (current_flight_dynamics->damage_repair_time, 0.0); #if DYNAMICS_DEBUG debug_log ("DYNAMICS: repairing %d, repair time %f seconds", current_flight_dynamics->damage_repair_time, current_flight_dynamics->damage_repair_time); #endif // // set repair timer to time to repair each part in turn // if (current_flight_dynamics->damage_repair_time <= 0.0) { // clear repaired damage if ((current_flight_dynamics->repairing_damage != DYNAMICS_DAMAGE_NONE) && (current_flight_dynamics->dynamics_damage & current_flight_dynamics->repairing_damage)) { repair_damage_model (current_flight_dynamics->repairing_damage); } current_flight_dynamics->repairing_damage = DYNAMICS_DAMAGE_NONE; // start repairing next this_damage = DYNAMICS_DAMAGE_NONE; damage_count = 0; model_damage = current_flight_dynamics->dynamics_damage; while (this_damage < NUM_DYNAMICS_DAMAGE_TYPES) { if ((model_damage & this_damage) && (dynamics_damage_database [damage_count].repairable)) { current_flight_dynamics->damage_repair_time = dynamics_damage_database [damage_count].repair_time; current_flight_dynamics->repairing_damage = this_damage; #if DEBUG_MODULE debug_log ("DYNAMICS: repairing %s, repair time %f seconds", dynamics_damage_database [damage_count].name, current_flight_dynamics->damage_repair_time); #endif break; } damage_count ++; this_damage = this_damage << 1; } if (current_flight_dynamics->repairing_damage == DYNAMICS_DAMAGE_NONE) { #if DEBUG_MODULE debug_log ("DYNAMICS: model fully repaired"); #endif restore_helicopter_entity (get_gunship_entity (), NULL, get_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE)); set_client_server_entity_int_value (get_gunship_entity (), INT_TYPE_DAMAGE_LEVEL, get_local_entity_int_value (get_gunship_entity (), INT_TYPE_INITIAL_DAMAGE_LEVEL)); transmit_entity_comms_message (ENTITY_COMMS_RESTORE_ENTITY, get_gunship_entity (), get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION), get_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE)); } } } } }
void repair_damage_model (unsigned int damage) { unsigned int this_damage; if (!get_gunship_entity ()) { return; } this_damage = DYNAMICS_DAMAGE_NONE; while (this_damage < NUM_DYNAMICS_DAMAGE_TYPES) { if ((damage & this_damage) && ((current_flight_dynamics->dynamics_damage & this_damage))) { current_flight_dynamics->dynamics_damage -= this_damage; switch (this_damage) { case DYNAMICS_DAMAGE_NONE: { break; } case DYNAMICS_DAMAGE_MAIN_ROTOR: { #if DYNAMICS_DEBUG debug_log ("DYNAMICS: main rotor repaired"); #endif current_flight_dynamics->main_blade_pitch.damaged = FALSE; current_flight_dynamics->main_rotor_roll_angle.damaged = FALSE; current_flight_dynamics->main_rotor_pitch_angle.damaged = FALSE; current_flight_dynamics->main_rotor_rpm.damaged = FALSE; restore_helicopter_main_rotors (get_gunship_entity ()); transmit_entity_comms_message (ENTITY_COMMS_RESTORE_ENTITY, get_gunship_entity (), get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION), get_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE)); set_client_server_entity_int_value (get_gunship_entity (), INT_TYPE_MAIN_ROTOR_DAMAGED, FALSE); break; } case DYNAMICS_DAMAGE_TAIL_ROTOR: { #if DYNAMICS_DEBUG debug_log ("DYNAMICS: tail rotor repaired"); #endif current_flight_dynamics->tail_blade_pitch.damaged = FALSE; current_flight_dynamics->tail_rotor_rpm.damaged = FALSE; current_flight_dynamics->cross_coupling_effect.damaged = FALSE; restore_helicopter_tail_rotors (get_gunship_entity ()); break; } case DYNAMICS_DAMAGE_LEFT_ENGINE: { current_flight_dynamics->left_engine_torque.damaged = FALSE; current_flight_dynamics->left_engine_rpm.damaged = FALSE; #if DYNAMICS_DEBUG debug_log ("DYNAMICS: left engine repaired"); #endif break; } case DYNAMICS_DAMAGE_RIGHT_ENGINE: { current_flight_dynamics->right_engine_torque.damaged = FALSE; current_flight_dynamics->right_engine_rpm.damaged = FALSE; #if DYNAMICS_DEBUG debug_log ("DYNAMICS: right engine repaired"); #endif break; } case DYNAMICS_DAMAGE_LEFT_ENGINE_FIRE: { #if DYNAMICS_DEBUG debug_log ("DYNAMICS: left engine fire repaired"); #endif break; } case DYNAMICS_DAMAGE_RIGHT_ENGINE_FIRE: { #if DYNAMICS_DEBUG debug_log ("DYNAMICS: right engine fire repaired"); #endif break; } case DYNAMICS_DAMAGE_LOW_HYDRAULICS: { #if DYNAMICS_DEBUG debug_log ("DYNAMICS: LOW HYDRAULICS repaired"); #endif current_flight_dynamics->input_data.cyclic_x.damaged = FALSE; current_flight_dynamics->input_data.cyclic_y.damaged = FALSE; break; } case DYNAMICS_DAMAGE_STABILISER: { switch (current_flight_dynamics->sub_type) { case ENTITY_SUB_TYPE_AIRCRAFT_AH64D_APACHE_LONGBOW: { apache_restore_damage_values (); break; } case ENTITY_SUB_TYPE_AIRCRAFT_MI28N_HAVOC_B: { havoc_restore_damage_values (); break; } case ENTITY_SUB_TYPE_AIRCRAFT_RAH66_COMANCHE: { comanche_restore_damage_values (); break; } case ENTITY_SUB_TYPE_AIRCRAFT_KA52_HOKUM_B: { hokum_restore_damage_values (); break; } } #if DYNAMICS_DEBUG debug_log ("DYNAMICS: STABILISER repaired"); #endif break; } case DYNAMICS_DAMAGE_FUEL_LEAK: { #if DYNAMICS_DEBUG debug_log ("DYNAMICS: FUEL_LEAK repaired"); #endif break; } case DYNAMICS_DAMAGE_LOW_OIL_PRESSURE: { current_flight_dynamics->input_data.cyclic_y.damaged = FALSE; #if DYNAMICS_DEBUG debug_log ("DYNAMICS: LOW_OIL_PRESSURE repaired"); #endif break; } case DYNAMICS_DAMAGE_HIGH_OIL_PRESSURE: { current_flight_dynamics->input_data.collective.damaged = FALSE; #if DYNAMICS_DEBUG debug_log ("DYNAMICS: HIGH_OIL_PRESSURE repaired"); #endif break; } case DYNAMICS_DAMAGE_AVIONICS: { #if DYNAMICS_DEBUG debug_log ("DYNAMICS: AVIONICS repaired"); #endif if (get_keysite_currently_landed_at ()) { // sort out what avionics to repair. switch (get_local_entity_int_value (get_keysite_currently_landed_at (), INT_TYPE_ENTITY_SUB_TYPE)) { case ENTITY_SUB_TYPE_KEYSITE_FARP: { partially_repair_local_entity_avionics (get_gunship_entity ()); break; } default: { fully_repair_local_entity_avionics (get_gunship_entity ()); break; } } } else { fully_repair_local_entity_avionics (get_gunship_entity ()); } break; } case DYNAMICS_DAMAGE_FIRE_EXTINGUISHER: { #if DEBUG_MODULE debug_log ("DYNAMICS: FIRE EXTINGUISHER repaired"); #endif fire_extinguisher_used = FALSE; break; } case DYNAMICS_DAMAGE_UNDERCARRIAGE: { #if DEBUG_MODULE debug_log ("DYNAMICS: UNDERCARRIAGE repaired"); #endif current_flight_dynamics->undercarriage_state.damaged = FALSE; break; } default: { debug_fatal ("DYNAMICS: unknown damage %d", this_damage); } } } this_damage = this_damage << 1; } }
entity *create_engage_task (entity *group, entity *objective, entity *originator, int expire) { entity *force_en, *new_task; force *force_raw; vec3d *pos; entity_sides side; float expire_time; formation_types original_formation; ASSERT (group); ASSERT (get_local_entity_int_value (group, INT_TYPE_ENGAGE_ENEMY)); ASSERT (objective); #if DEBUG_MODULE debug_log ("ENGAGE: Trying to engage against %s (%d)", get_local_entity_string (objective, STRING_TYPE_FULL_NAME), get_local_entity_index (objective)); #endif ASSERT ((get_local_entity_int_value (objective, INT_TYPE_IDENTIFY_AIRCRAFT)) || (get_local_entity_int_value (objective, INT_TYPE_IDENTIFY_VEHICLE)) || (get_local_entity_int_value (objective, INT_TYPE_IDENTIFY_FIXED))); if (get_local_entity_int_value (get_session_entity (), INT_TYPE_SUPPRESS_AI_FIRE)) { return NULL; } force_en = get_local_force_entity ((entity_sides)get_local_entity_int_value (group, INT_TYPE_SIDE)); force_raw = (force*) get_local_entity_data (force_en); if (expire) { expire_time = (2.0 * ONE_MINUTE) + (frand1 () * ONE_MINUTE); } else { // // Max time for ENGAGE - stops attackers hanging around target area for too long (especially if they can NEVER get to their target) // expire_time = (15.0 * ONE_MINUTE) + (frand1 () * 5.0 * ONE_MINUTE); } new_task = NULL; // // Create engage task to expire in task_time seconds - debug // side = (entity_sides) get_local_entity_int_value (group, INT_TYPE_SIDE); pos = get_local_entity_vec3d_ptr (objective, VEC3D_TYPE_POSITION); ASSERT (get_local_entity_first_child (group, LIST_TYPE_MEMBER)); original_formation = FORMATION_ROW_LEFT; new_task = create_task (ENTITY_SUB_TYPE_TASK_ENGAGE, side, (movement_types) get_local_entity_int_value (group, INT_TYPE_MOVEMENT_TYPE), NULL, NULL, originator, TRUE, expire_time, 0.0, objective, task_database [ENTITY_SUB_TYPE_TASK_ENGAGE].task_priority, pos, objective, ENTITY_SUB_TYPE_WAYPOINT_TARGET, original_formation, &terminator_point, NULL, NUM_ENTITY_SUB_TYPE_WAYPOINTS, FORMATION_NONE); #if DEBUG_MODULE debug_log ("ENGAGE: Created Engage task against %s (%d)", get_local_entity_string (objective, STRING_TYPE_FULL_NAME), get_local_entity_index (objective)); #endif return new_task; }
int debug_engage_targets_in_area (entity *group, vec3d *target_point, float radius, unsigned int target_type) { // // Engages all targets in area, regardless of side // int sx, sz, min_sector_x, max_sector_x, min_sector_z, max_sector_z; entity *new_task, *objective, *target_sector; entity_sides side; sector *raw; float range, temp_x, temp_z; vec3d *pos; new_task = NULL; temp_x = target_point->x - radius; temp_z = target_point->z - radius; get_x_sector (min_sector_x, temp_x); get_z_sector (min_sector_z, temp_z); temp_x = target_point->x + radius; temp_z = target_point->z + radius; get_x_sector (max_sector_x, temp_x); get_z_sector (max_sector_z, temp_z); min_sector_x = bound (min_sector_x, MIN_MAP_X_SECTOR, MAX_MAP_X_SECTOR); max_sector_x = bound (max_sector_x, MIN_MAP_X_SECTOR, MAX_MAP_X_SECTOR); min_sector_z = bound (min_sector_z, MIN_MAP_Z_SECTOR, MAX_MAP_Z_SECTOR); max_sector_z = bound (max_sector_z, MIN_MAP_Z_SECTOR, MAX_MAP_Z_SECTOR); side = (entity_sides) get_local_entity_int_value (group, INT_TYPE_SIDE); for (sz = min_sector_z; sz <= max_sector_z; sz ++) { for (sx = min_sector_x; sx <= max_sector_x; sx ++) { target_sector = get_local_raw_sector_entity (sx, sz); raw = (sector *) get_local_entity_data (target_sector); // // search for viable targets // objective = raw->sector_root.first_child; while (objective) { // // criteria for target is that it is a valid target, and not in your group // if (get_local_entity_int_value (objective, INT_TYPE_TARGET_TYPE) == target_type) { if (get_local_entity_int_value (objective, INT_TYPE_ALIVE)) { if ((!get_local_entity_int_value (objective, INT_TYPE_IDENTIFY_MOBILE)) || (get_local_entity_parent (objective, LIST_TYPE_MEMBER) != group)) { pos = get_local_entity_vec3d_ptr (objective, VEC3D_TYPE_POSITION); range = get_approx_2d_range (target_point, pos); if (range <= radius) { new_task = create_engage_task (group, objective, group, FALSE); if (new_task) { assign_task_to_group (group, new_task, TASK_ASSIGN_NO_MEMBERS); } } } } } objective = get_local_entity_child_succ (objective, LIST_TYPE_SECTOR); } } } if (assign_engage_tasks_to_group (group, TASK_ASSIGN_ALL_MEMBERS) != TASK_ASSIGN_ALL_MEMBERS) { return TRUE; } else { return FALSE; } }
entity *free_flight_auto_assign_gunship (void) { vec3d *pos; entity *force, *new_task, *group, *member, **gunship_list, *en; entity_sub_types sub_type; int c, index, count; // // Auto assign a helicopter for free flight // ASSERT (get_comms_model () == COMMS_MODEL_SERVER); ASSERT (get_game_type () == GAME_TYPE_FREE_FLIGHT); ASSERT (get_pilot_entity ()); if (get_gunship_entity ()) { return NULL; } force = get_local_entity_parent (get_pilot_entity (), LIST_TYPE_PILOT); ASSERT (force); // // Count up candidates // count = 0; en = get_local_entity_first_child (force, LIST_TYPE_AIR_REGISTRY); while (en) { if (get_local_entity_int_value (en, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE) { member = get_local_entity_first_child (en, LIST_TYPE_MEMBER); while (member) { sub_type = get_local_entity_int_value (member, INT_TYPE_ENTITY_SUB_TYPE); if ((sub_type == ENTITY_SUB_TYPE_AIRCRAFT_RAH66_COMANCHE) || (sub_type == ENTITY_SUB_TYPE_AIRCRAFT_KA52_HOKUM_B)) { if (get_local_entity_suitable_for_player (member, get_pilot_entity ())) { count ++; } } member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); } } en = get_local_entity_child_succ (en, LIST_TYPE_AIR_REGISTRY); } if (count == 0) { return NULL; } // // Create list of candidates // gunship_list = safe_malloc (sizeof (entity *) * count); count = 0; en = get_local_entity_first_child (force, LIST_TYPE_AIR_REGISTRY); while (en) { if (get_local_entity_int_value (en, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE) { member = get_local_entity_first_child (en, LIST_TYPE_MEMBER); while (member) { sub_type = get_local_entity_int_value (member, INT_TYPE_ENTITY_SUB_TYPE); if ((sub_type == ENTITY_SUB_TYPE_AIRCRAFT_RAH66_COMANCHE) || (sub_type == ENTITY_SUB_TYPE_AIRCRAFT_KA52_HOKUM_B)) { if (get_local_entity_suitable_for_player (member, get_pilot_entity ())) { gunship_list [count] = member; count ++; } } member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); } } en = get_local_entity_child_succ (en, LIST_TYPE_AIR_REGISTRY); } // // Pick one... // ASSERT (count > 0); index = rand16 () % count; for (c = 0; c < count; c ++) { en = gunship_list [index]; group = get_local_entity_parent (en, LIST_TYPE_MEMBER); pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); new_task = create_user_task (en, ENTITY_SUB_TYPE_TASK_FREE_FLIGHT, pos, NULL, NULL); set_assign_create_waypoint_route (FALSE); if (assign_primary_task_to_group (group, new_task)) { set_gunship_entity (en); set_view_mode (VIEW_MODE_COCKPIT_PANEL_LEVEL_AHEAD); safe_free (gunship_list); initialise_free_flight_screen_map_page_objects (); return en; } else { debug_log ("FLIGHT: can't assign user to Created task"); destroy_client_server_entity (new_task); } set_assign_create_waypoint_route (TRUE); index ++; if (index == count) { index = 0; } } safe_free (gunship_list); return NULL; }
void update_aircraft_decoy_release (entity *en) { aircraft *raw; int chaff_available, flare_available, chaff_released, flare_released; float range, velocity, time_to_impact; entity_sub_types weapon_sub_type; entity *persuer; vec3d *target_position, *weapon_position; ASSERT (en); #ifdef DEBUG if (get_comms_model () == COMMS_MODEL_CLIENT) { ASSERT (en == get_gunship_entity ()); } #endif raw = get_local_entity_data (en); //////////////////////////////////////// // // update timer // //////////////////////////////////////// raw->decoy_release_timer -= get_delta_time (); if (raw->decoy_release_timer >= 0.0) { return; } raw->decoy_release_timer = 2.0 + frand1 (); //////////////////////////////////////// // // validate // //////////////////////////////////////// if (en == get_gunship_entity ()) { if (!get_global_auto_counter_measures ()) { return; } } else if (get_local_entity_int_value (en, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI) { return; } if (!get_local_entity_int_value (en, INT_TYPE_AIRBORNE_AIRCRAFT)) { return; } persuer = get_local_entity_first_child (en, LIST_TYPE_TARGET); if (!persuer) { return; } chaff_available = get_local_entity_weapon_available (en, ENTITY_SUB_TYPE_WEAPON_CHAFF); flare_available = get_local_entity_weapon_available (en, ENTITY_SUB_TYPE_WEAPON_FLARE); if (!(chaff_available || flare_available)) { return; } //////////////////////////////////////// // // check all persuers // //////////////////////////////////////// target_position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); chaff_released = FALSE; flare_released = FALSE; while (persuer) { if (get_local_entity_type (persuer) == ENTITY_TYPE_WEAPON) { if (get_local_entity_int_value (persuer, INT_TYPE_WEAPON_GUIDANCE_TYPE) != WEAPON_GUIDANCE_TYPE_NONE) { weapon_sub_type = get_decoy_type_for_weapon (persuer); if (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_CHAFF) { if (chaff_available) { if (!chaff_released) { weapon_position = get_local_entity_vec3d_ptr (persuer, VEC3D_TYPE_POSITION); range = get_approx_3d_range (weapon_position, target_position); velocity = get_local_entity_float_value (persuer, FLOAT_TYPE_VELOCITY); time_to_impact = range / max (velocity, 1.0); if (time_to_impact < 10.0) { launch_client_server_weapon (en, ENTITY_SUB_TYPE_WEAPON_CHAFF); chaff_released = TRUE; if (flare_released) { break; } } } } } else if (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_FLARE) { if (flare_available) { if (!flare_released) { weapon_position = get_local_entity_vec3d_ptr (persuer, VEC3D_TYPE_POSITION); range = get_approx_3d_range (weapon_position, target_position); velocity = get_local_entity_float_value (persuer, FLOAT_TYPE_VELOCITY); time_to_impact = range / max (velocity, 1.0); if (time_to_impact < 10.0) { launch_client_server_weapon (en, ENTITY_SUB_TYPE_WEAPON_FLARE); flare_released = TRUE; if (chaff_released) { break; } } } } } } } persuer = get_local_entity_child_succ (persuer, LIST_TYPE_TARGET); } }
static void draw_local_3d_object (entity *en, float range) { fixed_wing *raw; day_segment_types day_segment_type; raw = (fixed_wing *) get_local_entity_data (en); // // update viewpoint // raw->ac.inst3d->vp.position = raw->ac.mob.position; memcpy (&raw->ac.inst3d->vp.attitude, &raw->ac.mob.attitude, sizeof (matrix3x3)); // // animate // animate_fixed_wing_afterburners (en); animate_fixed_wing_airbrakes (en); animate_fixed_wing_flaps (en); animate_fixed_wing_propellors (en); animate_aircraft_loading_doors (en); animate_aircraft_cargo_doors (en); animate_aircraft_undercarriage (en); animate_aircraft_weapon_system_ready (en); animate_aircraft_shadow (en); animate_aircraft_rudder (en); // // draw // day_segment_type = (day_segment_types) get_local_entity_int_value (get_session_entity (), INT_TYPE_DAY_SEGMENT_TYPE); raw->ac.inst3d->object_internal_lighting = ((day_segment_type == DAY_SEGMENT_TYPE_NIGHT) || (day_segment_type == DAY_SEGMENT_TYPE_DUSK)); raw->ac.inst3d->object_sprite_lights = (raw->ac.inst3d->object_internal_lighting && sprite_light_valid (en)); animate_and_draw_entity_muzzle_flash_effect (en); insert_object_into_3d_scene (OBJECT_3D_DRAW_TYPE_OBJECT, raw->ac.inst3d); #if DEBUG_MODULE if (en == get_external_view_entity ()) { vec3d *pos, wp_pos; draw_mobile_entity_debug_info (en); if (get_local_entity_primary_task (en)) { fixed_wing_movement_get_waypoint_position (en, &wp_pos); pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); create_debug_3d_line (pos, &wp_pos, sys_col_dark_green, 0.0); } } #endif }
void kill_routed_vehicles_on_segment (entity *en) { float range, damage_radius; int sx, sz; vec3d *segment_position, *object_position; entity *sect, *object; bridge_segment_types bridge_segment_type; // // get damage radius ( plus a little overlap ) // bridge_segment_type = (bridge_segment_types) get_local_entity_int_value (en, INT_TYPE_BRIDGE_SEGMENT_TYPE); damage_radius = bridge_segment_length (bridge_segment_type); if (damage_radius == 0.0) { return; } damage_radius *= ROOT2; // // get sector which the segment is in ( don't bother with adjacent sectors for now ) // segment_position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); get_x_sector (sx, segment_position->x); get_z_sector (sz, segment_position->z); sect = get_local_raw_sector_entity (sx, sz); // // search for routed vehicles // object = get_local_entity_first_child (sect, LIST_TYPE_SECTOR); while (object) { if (object->type == ENTITY_TYPE_ROUTED_VEHICLE) { if (get_local_entity_int_value (object, INT_TYPE_ALIVE)) { object_position = get_local_entity_vec3d_ptr (object, VEC3D_TYPE_POSITION); if (object_position) { range = get_approx_3d_range (segment_position, object_position); if (range < damage_radius) { kill_client_server_entity (object); } } } } object = get_local_entity_child_succ (object, LIST_TYPE_SECTOR); } }
void show_base_page (entity *base, int force_update) { entity *previous; vec3d *pos; int x, z; char s [128]; ASSERT (base); ASSERT (get_local_entity_type (base) == ENTITY_TYPE_KEYSITE); if (force_update) { previous = NULL; } else { previous = get_local_entity_safe_ptr (get_ui_object_item_number (campaign_page [CAMPAIGN_PAGE_BASE])); } pos = get_local_entity_vec3d_ptr (base, VEC3D_TYPE_POSITION); ASSERT (pos); // // NAME // set_ui_object_text (base_page_title, get_local_entity_string (base, STRING_TYPE_KEYSITE_NAME)); // // TYPE // set_ui_object_text (base_page_type_box, get_trans (get_local_entity_string (base, STRING_TYPE_FULL_NAME))); // // LOCATION // get_x_sector (x, pos->x); get_z_sector (z, pos->z); sprintf (s, "[%03d, %03d]", x, z); set_ui_object_text (base_page_sector_box, s); // // 3D WINDOW // set_ui_object_item_number (page_3d_area, get_local_entity_index (base)); if (base != previous) { page_3d_heading = 0.0; page_3d_pitch = (PI * 0.25); page_3d_distance = max (50.0, get_local_entity_float_value (base, FLOAT_TYPE_RECON_DISTANCE)); } // // 2D MAP // set_ui_object_item_number (page_map_area, get_local_entity_index (base)); if (base != previous) { page_map_dimensions.x = pos->x; page_map_dimensions.z = pos->z; page_map_dimensions.subject_entity = base; } // display_campaign_page (CAMPAIGN_PAGE_BASE, get_local_entity_index (base), TRUE); }
int resume_local_entity_sound_type (entity *en, entity_sub_types type) { entity *spec; sound_effect *raw; int count; count = 0; spec = get_local_entity_first_child (en, LIST_TYPE_SPECIAL_EFFECT); while (spec) { if (get_local_entity_type (spec) == ENTITY_TYPE_SOUND_EFFECT) { raw = get_local_entity_data (spec); if (raw->eff.sub_type == type) { // // "unpause" sound // if (!raw->valid_sound_effect) { // // set flag and start playing // raw->valid_sound_effect = TRUE; if (en == get_session_entity ()) { play_local_entity_sound (en, &main_vp, 0); } else { vec3d *position; viewpoint *vp; float range; vp = &main_vp; position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); range = get_approx_3d_range (&vp->position, position); play_local_entity_sound (en, vp, range); } if (!get_local_entity_parent (spec, LIST_TYPE_UPDATE)) { insert_local_entity_into_parents_child_list (spec, LIST_TYPE_UPDATE, get_update_entity (), NULL); } count ++; } } } spec = get_local_entity_child_succ (spec, LIST_TYPE_SPECIAL_EFFECT); } return count; }
unsigned int assign_engage_tasks_to_group (entity *group, unsigned int valid_members) { entity *task, *guide, *target, *member, *single_member, *persuer, **guide_list; unsigned int member_number; int best_count, best_guide, loop, criteria, task_count, *assigned_count; float range, *priority; vec3d *member_pos, *target_pos; ASSERT (group); ASSERT (get_comms_model () == COMMS_MODEL_SERVER); if (!valid_members) { return valid_members; } // // count up engage tasks // task_count = 0; guide = get_local_entity_first_child (group, LIST_TYPE_GUIDE_STACK); while (guide) { if (get_local_entity_int_value (guide, INT_TYPE_VALID_GUIDE_MEMBERS) == TASK_ASSIGN_NO_MEMBERS) { task = get_local_entity_parent (guide, LIST_TYPE_GUIDE); ASSERT (task); ASSERT (get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE) == ENTITY_SUB_TYPE_TASK_ENGAGE); if (get_local_entity_int_value (task, INT_TYPE_TASK_TERMINATED) == TASK_TERMINATED_IN_PROGRESS) { task_count ++; } } guide = get_local_entity_child_succ (guide, LIST_TYPE_GUIDE_STACK); } #if DEBUG_MODULE debug_log ("ENGAGE: =========================="); debug_log ("ENGAGE: %d suitable tasks", task_count); #endif if (task_count == 0) { return valid_members; } ////////////////////////////////////////////////////////////////// // // prioritize engage tasks // ////////////////////////////////////////////////////////////////// // // get target priority // guide_list = (entity * *) malloc_fast_mem (sizeof (entity *) * task_count); priority = (float *) malloc_fast_mem (sizeof (float) * task_count); assigned_count = (int *) malloc_fast_mem (sizeof (int) * task_count); #if DEBUG_MODULE debug_log ("ENGAGE: ======RAW LIST======"); #endif single_member = NULL; // check if we have a single member, if so assign that member to single_member for (member = get_local_entity_first_child (group, LIST_TYPE_MEMBER); member; member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER)) { member_number = (1 << get_local_entity_int_value (member, INT_TYPE_GROUP_MEMBER_NUMBER)); if (member_number & valid_members) { if (single_member) // we already have a valid member, so there is more than one { single_member = NULL; break; } else single_member = member; } } loop = 0; guide = get_local_entity_first_child (group, LIST_TYPE_GUIDE_STACK); while (guide) { if (get_local_entity_int_value (guide, INT_TYPE_VALID_GUIDE_MEMBERS) == TASK_ASSIGN_NO_MEMBERS) { task = get_local_entity_parent (guide, LIST_TYPE_GUIDE); ASSERT (task); ASSERT (get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE) == ENTITY_SUB_TYPE_TASK_ENGAGE); if (get_local_entity_int_value (task, INT_TYPE_TASK_TERMINATED) == TASK_TERMINATED_IN_PROGRESS) { target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT); ASSERT (target); if (!target) { notify_local_entity (ENTITY_MESSAGE_TASK_TERMINATED, task, group, TASK_TERMINATED_ABORTED); free_mem (guide_list); free_mem (priority); free_mem (assigned_count); return valid_members; } guide_list [loop] = guide; if (get_local_entity_int_value (group, INT_TYPE_AIRCRAFT_GROUP)) { priority [loop] = get_local_entity_float_value (target, FLOAT_TYPE_TARGET_PRIORITY_AIR_ATTACK); } else { priority [loop] = get_local_entity_float_value (target, FLOAT_TYPE_TARGET_PRIORITY_GROUND_ATTACK); } #if DEBUG_MODULE debug_log ("ENGAGE: (%d) Target : %s, Priority %f", loop, get_local_entity_string (target, STRING_TYPE_FULL_NAME), priority [loop]); #endif loop ++; } } guide = get_local_entity_child_succ (guide, LIST_TYPE_GUIDE_STACK); } ASSERT (loop == task_count); // // sort the tasks according to their priority // quicksort_entity_list (guide_list, task_count, priority); #if DEBUG_MODULE debug_log ("ENGAGE: ======SORTED======"); for (loop = 0; loop < task_count; loop ++) { task = get_local_entity_parent (guide_list [loop], LIST_TYPE_GUIDE); target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT); debug_log ("ENGAGE: (%d) Target : %s (%d), Priority %f", loop, get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target), priority [loop]); } #endif // // consider other entities attacking the same targets // memset (assigned_count, 0, sizeof (int) * task_count); for (loop = 0; loop < task_count; loop ++) { task = get_local_entity_parent (guide_list [loop], LIST_TYPE_GUIDE); target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT); persuer = get_local_entity_first_child (target, LIST_TYPE_TARGET); while (persuer) { assigned_count [loop] ++; persuer = get_local_entity_child_succ (persuer, LIST_TYPE_TARGET); } } ////////////////////////////////////////////////////////////////// // // assign new engage tasks // // for each member, run through the task list (most important first) // try to assign one member per task, but as tasks run out group members can "team-up" // ////////////////////////////////////////////////////////////////// member = get_local_entity_first_child (group, LIST_TYPE_MEMBER); while ((member) && (valid_members)) { // // Only assign AI entities to ENGAGE tasks // if (get_local_entity_int_value (member, INT_TYPE_PLAYER) == ENTITY_PLAYER_AI) { if (get_local_entity_int_value (member, INT_TYPE_ENGAGE_ENEMY)) { member_number = (1 << get_local_entity_int_value (member, INT_TYPE_GROUP_MEMBER_NUMBER)); if (member_number & valid_members) { member_pos = get_local_entity_vec3d_ptr (member, VEC3D_TYPE_POSITION); if (get_local_entity_int_value (member, INT_TYPE_IDENTIFY_AIRCRAFT)) { criteria = BEST_WEAPON_CRITERIA_MINIMAL; } else { criteria = BEST_WEAPON_RANGE_CHECK | BEST_WEAPON_LOS_CHECK; } best_guide = -1; best_count = INT_MAX; for (loop = 0; loop < task_count; loop ++) { if (assigned_count [loop] < best_count) { guide = guide_list [loop]; task = get_local_entity_parent (guide, LIST_TYPE_GUIDE); target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT); if (target == member) { // // Don't try to attack yourself ! // continue; } // // Range Check // if (criteria & BEST_WEAPON_RANGE_CHECK) { // range handled by weapon selection range = 0.0; } else { target_pos = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION); range = get_sqr_2d_range (target_pos, member_pos); } if (range < MAX_ENGAGE_RANGE) { // // Weapon Check // if (get_best_weapon_for_target (member, target, criteria) != ENTITY_SUB_TYPE_WEAPON_NO_WEAPON) { best_count = assigned_count [loop]; best_guide = loop; } } } } if (best_guide != -1) { guide = guide_list [best_guide]; task = get_local_entity_parent (guide, LIST_TYPE_GUIDE); if (assign_new_task_to_group_member (group, member, task, NULL)) { valid_members &= (~member_number); assigned_count [best_guide] ++; #if DEBUG_MODULE debug_log ("ENGAGE: Assigning %s (%d) to target %s (%d)", get_local_entity_string (member, STRING_TYPE_FULL_NAME), get_local_entity_index (member), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target)); #endif } } else { #if DEBUG_MODULE debug_log ("ENGAGE: Couldn't assign %s (%d) to engage task", get_local_entity_string (member, STRING_TYPE_FULL_NAME), get_local_entity_index (member)); #endif } } } } member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); } free_mem (guide_list); free_mem (priority); free_mem (assigned_count); return valid_members; }
void interpolate_entity_position (entity *en) { vec3d new_position, *motion_vector, *position; connection_list_type *connection; float delta_time; if ((!command_line_comms_interpolate_gunships) || (get_local_entity_int_value (en, INT_TYPE_LANDED))) { return; } position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); motion_vector = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_MOTION_VECTOR); if (get_comms_model () == COMMS_MODEL_CLIENT) { connection = get_connection_list_item (get_server_id ()); } else { connection = get_gunships_connection_list_item (en); } if (connection) { delta_time = (float) (get_system_time () - connection->interpolation_time) / TIME_1_SECOND; new_position.x = position->x + motion_vector->x * delta_time; new_position.y = position->y + motion_vector->y * delta_time; new_position.z = position->z + motion_vector->z * delta_time; set_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &new_position); if (get_comms_model () == COMMS_MODEL_SERVER) { connection->interpolation_time = get_system_time (); } #if DEBUG_MODULE debug_log ("SERVER: interpolating entity %s (%d) old [%f, %f, %f], new [%f, %f, %f], motion_vector [%f, %f, %f], deltatime %f", get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_index (en), position->x, position->y, position->z, new_position.x, new_position.y, new_position.z, motion_vector->x, motion_vector->y, motion_vector->z, delta_time); #endif } }