entity *create_new_pilot_entity (const char *name, entity_sides side, int rank, entity_sub_types sub_type, int unique_id, int difficulty) { entity *en, *force; ASSERT (get_comms_model () == COMMS_MODEL_SERVER); ASSERT (name); force = get_local_force_entity (side); ASSERT (force); en = create_client_server_entity ( ENTITY_TYPE_PILOT, ENTITY_INDEX_DONT_CARE, ENTITY_ATTR_PARENT (LIST_TYPE_PILOT, force), ENTITY_ATTR_STRING (STRING_TYPE_PILOTS_NAME, name), ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, sub_type), ENTITY_ATTR_INT_VALUE (INT_TYPE_UNIQUE_ID, unique_id), ENTITY_ATTR_INT_VALUE (INT_TYPE_SIDE, side), ENTITY_ATTR_INT_VALUE (INT_TYPE_PILOT_RANK, rank), ENTITY_ATTR_INT_VALUE (INT_TYPE_DIFFICULTY_LEVEL, difficulty), ENTITY_ATTR_END ); send_pilot_joined_message (en); return en; }
void reinitialise_client_ai_system (void) { comms_model_types temp_comms_model; comms_data_flow_types temp_comms_data_flow; temp_comms_model = get_comms_model (); temp_comms_data_flow = get_comms_data_flow (); // // set comms model and data flow to SERVER/TX // set_comms_model (COMMS_MODEL_SERVER); set_comms_data_flow (COMMS_DATA_FLOW_TX); if (population_placement_filename) { read_population_placement_file (population_placement_filename); } set_comms_model (temp_comms_model); set_comms_data_flow (temp_comms_data_flow); initialise_keysite_farp_enable (get_local_force_entity (ENTITY_SIDE_BLUE_FORCE)); initialise_keysite_farp_enable (get_local_force_entity (ENTITY_SIDE_RED_FORCE)); initialise_briefing_parser (); set_assign_create_waypoint_route (TRUE); }
static void unpack_local_data (entity *en, entity_types type, pack_modes mode) { ASSERT ((mode >= 0) && (mode < NUM_PACK_MODES)); switch (mode) { //////////////////////////////////////// case PACK_MODE_SERVER_SESSION: case PACK_MODE_CLIENT_SESSION: //////////////////////////////////////// { int index; routed_vehicle *raw; node_link_data *route_data; // // create entity // index = unpack_entity_safe_index (); en = get_free_entity (index); set_local_entity_type (en, type); raw = (routed_vehicle *) malloc_fast_mem (sizeof (routed_vehicle)); set_local_entity_data (en, raw); memset (raw, 0, sizeof (routed_vehicle)); // // unpack vehicle data (in exactly the same order as the data was packed) // unpack_vehicle_data (en, &raw->vh, mode); if (unpack_int_value (en, INT_TYPE_VALID)) { raw->vh.mob.velocity = 0.0; raw->desired_velocity = 0.0; } else { raw->vh.mob.velocity = unpack_float_value (en, FLOAT_TYPE_LOW_VELOCITY); raw->desired_velocity = unpack_float_value (en, FLOAT_TYPE_DESIRED_VELOCITY); } // // unpack routed data // if (unpack_int_value (en, INT_TYPE_VALID)) { raw->sub_waypoint_count = unpack_int_value (en, INT_TYPE_SUB_WAYPOINT_COUNT); raw->waypoint_next_index = unpack_int_value (en, INT_TYPE_WAYPOINT_NEXT_INDEX); raw->waypoint_this_index = unpack_int_value (en, INT_TYPE_WAYPOINT_THIS_INDEX); } // // turn lights on if necessary // set_vehicle_headlight_state (en, raw->vh.lights_on); // // setup waypoint route pointer // #if DEBUG_MODULE debug_log ("ROUTED ENTITY PACK: client setting up waypoint list pointer"); #endif route_data = get_road_sub_route (raw->waypoint_this_index, raw->waypoint_next_index, &index, NULL); if ((route_data) && (route_data->link_positions)) { raw->sub_route = route_data; } else { if ((raw->waypoint_this_index + raw->waypoint_next_index) != 0) { debug_log ("RV_PACK: WARNING NO SUB ROUTE FOUND BETWEEN %d AND %d", raw->waypoint_this_index, raw->waypoint_next_index); } } // // radar dish rotation (ok to use a random number as this is for visual effect only) // raw->vh.radar_rotation_state = frand1 (); set_routed_vehicle_id_number (en); set_initial_rotation_angle_of_routed_vehicle_wheels (raw->vh.inst3d); // // link into system // insert_local_entity_into_parents_child_list (en, LIST_TYPE_VIEW, get_camera_entity (), NULL); insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->vh.mob.position), NULL); insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL); add_to_force_info (get_local_force_entity ((entity_sides) raw->vh.mob.side), en); // // attached smoke lists must be unpacked after the entity is linked into the world // unpack_routed_vehicle_meta_smoke_lists (en, mode); unpack_mobile_local_sound_effects (en, mode); break; } //////////////////////////////////////// case PACK_MODE_BROWSE_SESSION: //////////////////////////////////////// { break; } //////////////////////////////////////// case PACK_MODE_UPDATE_ENTITY: //////////////////////////////////////// { // // always use access functions to set the data // vec3d position; matrix3x3 attitude; int sub_waypoint_count; // // unpack all data (even if the echoed data is to be ignored) // unpack_vec3d (en, VEC3D_TYPE_POSITION, &position); unpack_attitude_matrix (en, attitude); sub_waypoint_count = unpack_int_value (en, INT_TYPE_SUB_WAYPOINT_COUNT); set_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &position); set_local_entity_attitude_matrix (en, attitude); set_local_entity_int_value (en, INT_TYPE_SUB_WAYPOINT_COUNT, sub_waypoint_count); // Vehicle is moving so sleep must equal 0 set_local_entity_float_value (en, FLOAT_TYPE_SLEEP, 0.0); break; } } }
entity *add_group_to_division (entity *group, entity *specified_division) { entity_sides side; int count, max_count, group_type, keysite_type, division_type, main_division_type; entity *en, *force, *keysite, *division; vec3d *group_pos; ASSERT (group); ASSERT (get_comms_model () == COMMS_MODEL_SERVER); ASSERT (!get_local_entity_parent (group, LIST_TYPE_DIVISION)); group_type = get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE); group_pos = get_local_entity_vec3d_ptr (group, VEC3D_TYPE_POSITION); if (specified_division) { division = specified_division; } else { side = (entity_sides) get_local_entity_int_value (group, INT_TYPE_SIDE); force = get_local_force_entity (side); ASSERT (force); division_type = group_database [group_type].default_group_division; ASSERT (entity_sub_type_division_valid (division_type)); main_division_type = division_database [division_type].default_group_division; ASSERT (entity_sub_type_division_valid (main_division_type)); // // Find the keysite the company should be attached to // keysite = NULL; if (get_local_entity_int_value (group, INT_TYPE_GROUP_LIST_TYPE) == LIST_TYPE_KEYSITE_GROUP) { keysite = get_local_entity_parent (group, LIST_TYPE_KEYSITE_GROUP); if (!keysite) { keysite = get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, side, group_pos, 1.0 * KILOMETRE, NULL, NULL); } ASSERT (keysite); keysite_type = get_local_entity_int_value (keysite, INT_TYPE_ENTITY_SUB_TYPE); if ((keysite_type == ENTITY_SUB_TYPE_KEYSITE_AIRBASE) || (keysite_type == ENTITY_SUB_TYPE_KEYSITE_ANCHORAGE)) { // // Use keysite landed at // } else { // // Find nearest keysite (below) // keysite = NULL; } } else { if (group_database [group_type].movement_type == MOVEMENT_TYPE_SEA) { // // Find nearest carrier // keysite = get_closest_keysite (ENTITY_SUB_TYPE_KEYSITE_ANCHORAGE, side, group_pos, 0.0, NULL, NULL); } } if (!keysite) { // // Find nearest airbase // keysite = get_closest_keysite (ENTITY_SUB_TYPE_KEYSITE_AIRBASE, side, group_pos, 0.0, NULL, NULL); if (!keysite) { // // Find nearest military base // keysite = get_closest_keysite (ENTITY_SUB_TYPE_KEYSITE_MILITARY_BASE, side, group_pos, 0.0, NULL, NULL); if (!keysite) { // // Find nearest FARP // keysite = get_closest_keysite (ENTITY_SUB_TYPE_KEYSITE_FARP, side, group_pos, 0.0, NULL, NULL); } } } ASSERT (keysite); // // Check all companies at this keysite to see if they have vacancies.... // max_count = group_database [group_type].maximum_groups_per_division; division = get_local_entity_first_child (keysite, LIST_TYPE_DIVISION_HEADQUARTERS); while (division) { if (get_local_entity_int_value (division, INT_TYPE_ENTITY_SUB_TYPE) == division_type) { if (max_count == 0) { break; } count = 0; en = get_local_entity_first_child (division, LIST_TYPE_DIVISION); while (en) { ASSERT (get_local_entity_type (en) == ENTITY_TYPE_GROUP); count ++; en = get_local_entity_child_succ (en, LIST_TYPE_DIVISION); } if (count < max_count) { break; } } division = get_local_entity_child_succ (division, LIST_TYPE_DIVISION_HEADQUARTERS); } if (division) { // // found an existing division with space available // } else { // // create a new division // entity *main_division; max_count = division_database [division_type].maximum_groups_per_division; main_division = get_local_entity_first_child (force, LIST_TYPE_DIVISION); while (main_division) { if (get_local_entity_int_value (main_division, INT_TYPE_ENTITY_SUB_TYPE) == main_division_type) { // // check division for vacancies // if (max_count == 0) { break; } count = 0; en = get_local_entity_first_child (main_division, LIST_TYPE_DIVISION); while (en) { ASSERT (get_local_entity_type (en) == ENTITY_TYPE_DIVISION); if (get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE) == division_type) { count ++; } en = get_local_entity_child_succ (en, LIST_TYPE_DIVISION); } if (count < max_count) { break; } } main_division = get_local_entity_child_succ (main_division, LIST_TYPE_DIVISION); } if (main_division) { // // found an existing division with space available // } else { // // create a new division // main_division = create_new_division (main_division_type, side, force, NULL, FALSE); } ASSERT (main_division); division = create_new_division (division_type, side, main_division, keysite, FALSE); } } ASSERT (division); set_client_server_entity_parent (group, LIST_TYPE_DIVISION, division); return division; }
void display_campaign_criteria_time_remaining (void) { #if 0 entity *force_en; force *force_raw; //session //*session_raw; //campaign_criteria_type //*this_campaign_criteria; //float //elapsed_hours, //elapsed_minutes, //elapsed_seconds; //int //remaining_hours, //remaining_minutes, //remaining_seconds; //int //x, y; //char //s [20]; // // display count down timer until campaign completiion (NOT "tour of duty" timer) // // // currently used only for special games, so I have tailored it to suit :- // only displays minutes and seconds, // doesn't display on the clients until after first time-of-day resync // if ((get_game_type () != GAME_TYPE_SPECIAL) && (get_game_type () != GAME_TYPE_MAGAZINE_DEMO)) { return; } ASSERT (get_session_entity ()); force_en = get_local_force_entity (get_global_gunship_side ()); ASSERT (force_en); force_raw = (force *) get_local_entity_data (force_en); /* this_campaign_criteria = force_raw->campaign_criteria; while (this_campaign_criteria) { if (this_campaign_criteria->criteria_type == CAMPAIGN_CRITERIA_TIME_DURATION) { break; } this_campaign_criteria = this_campaign_criteria->next; } if (this_campaign_criteria) { if (this_campaign_criteria->valid) { session_raw = (force *) get_local_entity_data (get_session_entity ()); // // clients don't display until AFTER first resync (otherwise time will be wrong) // if (get_comms_model () == COMMS_MODEL_CLIENT) { if (!display_timer_valid) { return; } } // // get time remaining // get_digital_clock_values (session_raw->elapsed_time_of_day, &elapsed_hours, &elapsed_minutes, &elapsed_seconds); remaining_seconds = (this_campaign_criteria->days - session_raw->elapsed_days) * ONE_DAY; remaining_seconds += (this_campaign_criteria->hours - elapsed_hours) * ONE_HOUR; remaining_seconds += (this_campaign_criteria->minutes - elapsed_minutes) * ONE_MINUTE; remaining_seconds += (this_campaign_criteria->seconds - elapsed_seconds) * ONE_SECOND; if ((remaining_seconds > 0.0) && (remaining_seconds < ONE_HOUR)) { if (remaining_seconds < ONE_MINUTE) { if (remaining_seconds < 10.0) { // // flash if < 10 seconds // if (frac (session_raw->elapsed_time_of_day) < 0.5) { return; } } set_ui_font (UI_FONT_ADS_15_ORANGE); } else { set_ui_font (UI_FONT_ADS_15_WHITE); } get_digital_clock_int_values (remaining_seconds, &remaining_hours, &remaining_minutes, &remaining_seconds); if (lock_screen (active_screen)) { set_full_screen_viewport (); sprintf (s, "T-%02d:%02d", remaining_minutes, remaining_seconds); // string WAS right-justified, but looked bad due to proportional fonts changing the width every second ! // x = get_screen_width (active_screen) - ui_get_string_length (s); x = get_screen_width (active_screen) - 62; y = ui_get_font_height () + 2; ui_display_text (s, x, y); unlock_screen (active_screen); } } } } */ #endif }
void unpack_local_keysite_data (pack_modes mode) { entity *en, *landing_en; landing *landing_raw; keysite *raw; int side, landing_lock, landed_lock, takeoff_lock, in_use, index; ASSERT (mode != PACK_MODE_UPDATE_ENTITY); if (mode == PACK_MODE_BROWSE_SESSION) { return; } en = get_local_entity_list (); while (en) { if (get_local_entity_type (en) == ENTITY_TYPE_KEYSITE) { // // unpack keysite // index = unpack_entity_safe_index (); raw = (keysite *) get_local_entity_data (en); raw->supplies.ammo_supply_level = unpack_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL); raw->supplies.fuel_supply_level = unpack_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL); raw->keysite_strength = unpack_float_value (en, FLOAT_TYPE_KEYSITE_STRENGTH); raw->keysite_maximum_strength = unpack_float_value (en, FLOAT_TYPE_KEYSITE_MAXIMUM_STRENGTH); raw->alive = unpack_int_value (en, INT_TYPE_ALIVE); side = unpack_int_value (en, INT_TYPE_SIDE); if (side != raw->side) { // // update I-Maps (remove old side) // if (raw->in_use) { update_imap_sector_side (en, FALSE); if (mode == PACK_MODE_SERVER_SESSION) { update_imap_importance_level (en, FALSE); } } // // change side of keysite buildings // change_local_keysite_building_sides (en, (entity_sides) side); // // place into other sides force // delete_local_entity_from_parents_child_list (en, LIST_TYPE_KEYSITE_FORCE); insert_local_entity_into_parents_child_list (en, LIST_TYPE_KEYSITE_FORCE, get_local_force_entity ((entity_sides) side), NULL); if (mode == PACK_MODE_SERVER_SESSION) { // Must be done after removed from force update_imap_distance_to_friendly_base ((entity_sides) raw->side); } // // switch sides // raw->side = side; // // update I-Maps (add new side) // if (raw->in_use) { update_imap_sector_side (en, TRUE); if (mode == PACK_MODE_SERVER_SESSION) { update_imap_importance_level (en, TRUE); update_keysite_distance_to_friendly_base (en, (entity_sides) side); } } } in_use = unpack_int_value (en, INT_TYPE_IN_USE); raw->keysite_id = unpack_int_value (en, INT_TYPE_KEYSITE_ID); raw->keysite_usable_state = unpack_int_value (en, INT_TYPE_KEYSITE_USABLE_STATE); if (raw->in_use != in_use) { // // Update I-Maps (in use flag changed) // raw->in_use = in_use; update_imap_sector_side (en, in_use); if (mode == PACK_MODE_SERVER_SESSION) { update_imap_importance_level (en, in_use); if (in_use) { update_keysite_distance_to_friendly_base (en, (entity_sides) side); } else { update_imap_distance_to_friendly_base ((entity_sides) side); } } } unpack_list_root (en, LIST_TYPE_UNASSIGNED_TASK, &raw->unassigned_task_root); unpack_list_root (en, LIST_TYPE_ASSIGNED_TASK, &raw->assigned_task_root); unpack_list_root (en, LIST_TYPE_COMPLETED_TASK, &raw->completed_task_root); // unpack_list_root (en, LIST_TYPE_KEYSITE_GROUP, &raw->keysite_group_root); unpack_list_root (en, LIST_TYPE_DIVISION_HEADQUARTERS, &raw->division_headquarters_root); if (unpack_int_value (en, INT_TYPE_VALID)) { unpack_list_link (en, LIST_TYPE_CAMPAIGN_OBJECTIVE, &raw->campaign_objective_link); } #if DEBUG_MODULE debug_log ("KS_PACK: unpacking keysite %s", raw->keysite_name); #endif if (mode == PACK_MODE_SERVER_SESSION) { raw->repair_timer = unpack_float_value (en, FLOAT_TYPE_REPAIR_TIMER); raw->sleep = unpack_float_value (en, FLOAT_TYPE_SLEEP); raw->assist_timer = unpack_float_value (en, FLOAT_TYPE_ASSIST_TIMER); raw->assign_timer = unpack_float_value (en, FLOAT_TYPE_ASSIGN_TIMER); // // unpack landing data // landing_en = get_local_entity_first_child (en, LIST_TYPE_LANDING_SITE); while (landing_en) { landing_raw = (landing *) get_local_entity_data (landing_en); landing_raw->reserved_landing_sites = unpack_int_value (landing_en, INT_TYPE_RESERVED_LANDING_SITES); //landing_raw->free_landing_sites = unpack_int_value (en, INT_TYPE_FREE_LANDING_SITES); landing_raw->free_landing_sites = landing_raw->total_landing_sites; landing_lock = unpack_int_value (landing_en, INT_TYPE_LANDING_LOCK); landed_lock = unpack_int_value (landing_en, INT_TYPE_LANDED_LOCK); takeoff_lock = unpack_int_value (landing_en, INT_TYPE_TAKEOFF_LOCK); #if DEBUG_MODULE debug_log ("KS_PACK: %s (%d) unpacking %s landing entity, reserved %d, free %d, locks (saved :landing %d, landed %d, takeoff %d, calc landing %d, landed %d, takeoff %d)", raw->keysite_name, get_local_entity_index (en), entity_sub_type_landing_names [landing_raw->sub_type], landing_raw->reserved_landing_sites, landing_raw->free_landing_sites, landing_lock, landed_lock, takeoff_lock, landing_raw->landing_lock, landing_raw->landed_lock, landing_raw->takeoff_lock); if (landing_raw->landing_lock != landing_lock) { debug_log ("KS_PACK: %s %s landing entity needs landing_lock repairing", raw->keysite_name, entity_sub_type_landing_names [landing_raw->sub_type]); } if (landing_raw->landed_lock != landed_lock) { debug_log ("KS_PACK: %s %s landing entity needs landed_lock repairing", raw->keysite_name, entity_sub_type_landing_names [landing_raw->sub_type]); } if (landing_raw->takeoff_lock != takeoff_lock) { debug_log ("KS_PACK: %s %s landing entity needs takeoff_lock repairing", raw->keysite_name, entity_sub_type_landing_names [landing_raw->sub_type]); } #endif unpack_list_root (landing_en, LIST_TYPE_TAKEOFF_QUEUE, &landing_raw->takeoff_queue_root); landing_en = get_local_entity_child_succ (landing_en, LIST_TYPE_LANDING_SITE); } } } en = get_local_entity_succ (en); } }
void assess_group_supplies (entity *en) { entity *keysite, *force; group *raw; float required, level; raw = get_local_entity_data (en); if (get_local_entity_int_value (en, INT_TYPE_RESUPPLY_SOURCE) == RESUPPLY_SOURCE_GROUP) { // // Check if Group needs to request Supplies via Mission... // if (raw->supplies.ammo_supply_level < 100.0) { force = get_local_force_entity (get_local_entity_int_value (en, INT_TYPE_SIDE)); #if DEBUG_MODULE || DEBUG_SUPPLY debug_log ("GROUP: SUPPLY_INFO: ground group %s low on ammo, requesting Supply mission", get_local_entity_string (en, STRING_TYPE_FULL_NAME)); #endif notify_local_entity (ENTITY_MESSAGE_FORCE_LOW_ON_SUPPLIES, force, en, ENTITY_SUB_TYPE_CARGO_AMMO); } else if (raw->supplies.fuel_supply_level < 100.0) { force = get_local_force_entity (get_local_entity_int_value (en, INT_TYPE_SIDE)); #if DEBUG_MODULE || DEBUG_SUPPLY debug_log ("GROUP: SUPPLY_INFO: ground group %s low on fuel, requesting Supply mission", get_local_entity_string (en, STRING_TYPE_FULL_NAME)); #endif notify_local_entity (ENTITY_MESSAGE_FORCE_LOW_ON_SUPPLIES, force, en, ENTITY_SUB_TYPE_CARGO_FUEL); } } else if (get_local_entity_int_value (en, INT_TYPE_RESUPPLY_SOURCE) == RESUPPLY_SOURCE_KEYSITE) { // // check all group is landed. If so refuel/rearm group via keysite supplies // if (get_local_entity_int_value (en, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE) { if (raw->supplies.ammo_supply_level < 100.0) { // // re-arm // keysite = get_local_entity_parent (en, LIST_TYPE_KEYSITE_GROUP); if ((!keysite) || (get_local_entity_type (keysite) != ENTITY_TYPE_KEYSITE)) { keysite = get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, raw->side, get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION), 1.0 * KILOMETRE, NULL, NULL); } ASSERT (keysite); level = get_local_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL); required = 100.0 - (raw->supplies.ammo_supply_level * AMMO_USAGE_ACCELERATOR); required = bound (required, 0.0, level); level -= required; set_client_server_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL, level); set_client_server_entity_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL, raw->supplies.ammo_supply_level + required); #if DEBUG_MODULE || DEBUG_SUPPLY debug_log ("GROUP: SUPPLY_INFO: Air group %s members landed, rearming group (now ammo = %f, fuel = %f) from keysite %s (%d) (now ammo = %f, fuel = %f)", get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL), get_local_entity_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL), get_local_entity_string (keysite, STRING_TYPE_FULL_NAME), get_local_entity_index (keysite), get_local_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL), get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL)); #endif } if (raw->supplies.fuel_supply_level < 100.0) { // // re-fuel // keysite = get_local_entity_parent (en, LIST_TYPE_KEYSITE_GROUP); if ((!keysite) || (get_local_entity_type (keysite) != ENTITY_TYPE_KEYSITE)) { keysite = get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, raw->side, get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION), 1.0 * KILOMETRE, NULL, NULL); } ASSERT (keysite); level = get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL); required = 100.0 - (raw->supplies.fuel_supply_level * FUEL_USAGE_ACCELERATOR); required = bound (required, 0.0, level); level -= required; set_client_server_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL, level); set_client_server_entity_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL, raw->supplies.fuel_supply_level + required); #if DEBUG_MODULE || DEBUG_SUPPLY debug_log ("GROUP: SUPPLY_INFO: Air group %s members landed, refuelling group (now ammo = %f, fuel = %f) from keysite %s (%d) (now ammo = %f, fuel = %f)", get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL), get_local_entity_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL), get_local_entity_string (keysite, STRING_TYPE_FULL_NAME), get_local_entity_index (keysite), get_local_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL), get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL)); #endif } } } }
static entity *create_local (entity_types type, int index, char *pargs) { entity *en; fixed_wing *raw; entity_sub_types group_sub_type; //////////////////////////////////////// // // VALIDATE // //////////////////////////////////////// validate_local_create_entity_index (index); #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_CREATE, NULL, type, index); #endif en = get_free_entity (index); if (en) { //////////////////////////////////////// // // MALLOC ENTITY DATA // //////////////////////////////////////// set_local_entity_type (en, type); raw = malloc_fast_mem (sizeof (fixed_wing)); set_local_entity_data (en, raw); //////////////////////////////////////// // // INITIALISE ALL ENTITY DATA TO 'WORKING' DEFAULT VALUES // // DO NOT USE ACCESS FUNCTIONS // // DO NOT USE RANDOM VALUES // //////////////////////////////////////// memset (raw, 0, sizeof (fixed_wing)); // // mobile // raw->ac.mob.sub_type = ENTITY_SUB_TYPE_UNINITIALISED; raw->ac.mob.position.x = MID_MAP_X; raw->ac.mob.position.y = MID_MAP_Y; raw->ac.mob.position.z = MID_MAP_Z; get_identity_matrix3x3 (raw->ac.mob.attitude); raw->ac.mob.alive = TRUE; raw->ac.mob.side = ENTITY_SIDE_UNINITIALISED; raw->ac.operational_state = OPERATIONAL_STATE_UNKNOWN; // // aircraft // raw->ac.object_3d_shape = OBJECT_3D_INVALID_OBJECT_INDEX; raw->ac.weapon_config_type = WEAPON_CONFIG_TYPE_UNINITIALISED; raw->ac.selected_weapon = ENTITY_SUB_TYPE_WEAPON_NO_WEAPON; raw->ac.weapon_vector.x = 0.0; raw->ac.weapon_vector.y = 0.0; raw->ac.weapon_vector.z = 1.0; raw->ac.weapon_to_target_vector.x = 0.0; raw->ac.weapon_to_target_vector.y = 0.0; raw->ac.weapon_to_target_vector.z = -1.0; raw->ac.loading_door_state = AIRCRAFT_LOADING_DOORS_OPEN_FLOAT_VALUE; raw->ac.undercarriage_state = AIRCRAFT_UNDERCARRIAGE_DOWN_FLOAT_VALUE; raw->ac.air_radar_contact_timeout = AIR_RADAR_CONTACT_TIMEOUT_INVALID; // // fixed_wing // //////////////////////////////////////// // // OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES // //////////////////////////////////////// set_local_entity_attributes (en, pargs); //////////////////////////////////////// // // CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN // //////////////////////////////////////// ASSERT (raw->ac.member_link.parent); ASSERT (get_local_entity_type (raw->ac.member_link.parent) == ENTITY_TYPE_GROUP); //////////////////////////////////////// // // RESOLVE DEFAULT VALUES // //////////////////////////////////////// // // side // if (raw->ac.mob.side == ENTITY_SIDE_UNINITIALISED) { raw->ac.mob.side = get_local_entity_int_value (raw->ac.member_link.parent, INT_TYPE_SIDE); } ASSERT (raw->ac.mob.side != ENTITY_SIDE_NEUTRAL); // // sub_type // if (raw->ac.mob.sub_type == ENTITY_SUB_TYPE_UNINITIALISED) { group_sub_type = get_local_entity_int_value (raw->ac.member_link.parent, INT_TYPE_ENTITY_SUB_TYPE); if (raw->ac.mob.side == ENTITY_SIDE_BLUE_FORCE) { raw->ac.mob.sub_type = group_database[group_sub_type].default_blue_force_sub_type; } else { raw->ac.mob.sub_type = group_database[group_sub_type].default_red_force_sub_type; } } ASSERT (entity_sub_type_aircraft_valid (raw->ac.mob.sub_type)); // // 3D shape // if (raw->ac.object_3d_shape == OBJECT_3D_INVALID_OBJECT_INDEX) { raw->ac.object_3d_shape = aircraft_database[raw->ac.mob.sub_type].default_3d_shape; } // // weapon config // if (raw->ac.weapon_config_type == WEAPON_CONFIG_TYPE_UNINITIALISED) { raw->ac.weapon_config_type = aircraft_database[raw->ac.mob.sub_type].default_weapon_config_type; } ASSERT (weapon_config_type_valid (raw->ac.weapon_config_type)); // // damage levels // raw->ac.damage_level = aircraft_database[raw->ac.mob.sub_type].initial_damage_level; //////////////////////////////////////// // // BUILD COMPONENTS // //////////////////////////////////////// // // 3D object // raw->ac.inst3d = construct_3d_object (raw->ac.object_3d_shape); set_fixed_wing_id_number (en); initialise_fixed_wing_propellors (en); #if RECOGNITION_GUIDE raw->ac.loading_door_state = AIRCRAFT_LOADING_DOORS_CLOSED_FLOAT_VALUE; #endif // // weapon config // raw->ac.weapon_package_status_array = malloc_fast_mem (SIZE_WEAPON_PACKAGE_STATUS_ARRAY); memset (raw->ac.weapon_package_status_array, 0, SIZE_WEAPON_PACKAGE_STATUS_ARRAY); load_local_entity_weapon_config (en); // // update force info // add_to_force_info (get_local_force_entity (raw->ac.mob.side), en); //////////////////////////////////////// // // LINK INTO SYSTEM // //////////////////////////////////////// insert_local_entity_into_parents_child_list (en, LIST_TYPE_MEMBER, raw->ac.member_link.parent, raw->ac.member_link.child_pred); // // insert into LIST_TYPE_MEMBER before LIST_TYPE_VIEW // insert_local_entity_into_parents_child_list (en, LIST_TYPE_VIEW, get_camera_entity (), get_local_entity_view_list_pred (en)); insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->ac.mob.position), NULL); insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL); } return (en); }
static entity *create_local (entity_types type, int index, char *pargs) { entity *en; routed_vehicle *raw; entity_sub_types group_sub_type; float heading; vec3d *face_normal; //////////////////////////////////////// // // VALIDATE // //////////////////////////////////////// validate_local_create_entity_index (index); #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_CREATE, NULL, type, index); #endif en = get_free_entity (index); if (en) { //////////////////////////////////////// // // MALLOC ENTITY DATA // //////////////////////////////////////// set_local_entity_type (en, type); raw = malloc_fast_mem (sizeof (routed_vehicle)); set_local_entity_data (en, raw); //////////////////////////////////////// // // INITIALISE ALL ENTITY DATA TO 'WORKING' DEFAULT VALUES // // DO NOT USE ACCESS FUNCTIONS // // DO NOT USE RANDOM VALUES // //////////////////////////////////////// memset (raw, 0, sizeof (routed_vehicle)); // // mobile // raw->vh.mob.sub_type = ENTITY_SUB_TYPE_UNINITIALISED; raw->vh.mob.position.x = MID_MAP_X; raw->vh.mob.position.y = MID_MAP_Y; raw->vh.mob.position.z = MID_MAP_Z; get_identity_matrix3x3 (raw->vh.mob.attitude); raw->vh.mob.alive = TRUE; raw->vh.mob.side = ENTITY_SIDE_UNINITIALISED; raw->vh.operational_state = OPERATIONAL_STATE_UNKNOWN; // // vehicle // raw->vh.object_3d_shape = OBJECT_3D_INVALID_OBJECT_INDEX; raw->vh.weapon_config_type = WEAPON_CONFIG_TYPE_UNINITIALISED; raw->vh.selected_weapon = ENTITY_SUB_TYPE_WEAPON_NO_WEAPON; raw->vh.weapon_vector.x = 0.0; raw->vh.weapon_vector.y = 0.0; raw->vh.weapon_vector.z = 1.0; raw->vh.weapon_to_target_vector.x = 0.0; raw->vh.weapon_to_target_vector.y = 0.0; raw->vh.weapon_to_target_vector.z = -1.0; raw->vh.loading_door_state = VEHICLE_LOADING_DOORS_OPEN_FLOAT_VALUE; // // routed // //////////////////////////////////////// // // OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES // //////////////////////////////////////// set_local_entity_attributes (en, pargs); //////////////////////////////////////// // // CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN // //////////////////////////////////////// ASSERT (raw->vh.member_link.parent); ASSERT (get_local_entity_type (raw->vh.member_link.parent) == ENTITY_TYPE_GROUP); //////////////////////////////////////// // // RESOLVE DEFAULT VALUES // //////////////////////////////////////// raw->sub_route = NULL; // // side // if (raw->vh.mob.side == ENTITY_SIDE_UNINITIALISED) { raw->vh.mob.side = get_local_entity_int_value (raw->vh.member_link.parent, INT_TYPE_SIDE); } ASSERT (raw->vh.mob.side != ENTITY_SIDE_NEUTRAL); // // sub_type // if (raw->vh.mob.sub_type == ENTITY_SUB_TYPE_UNINITIALISED) { group_sub_type = get_local_entity_int_value (raw->vh.member_link.parent, INT_TYPE_ENTITY_SUB_TYPE); if (raw->vh.mob.side == ENTITY_SIDE_BLUE_FORCE) { raw->vh.mob.sub_type = group_database[group_sub_type].default_blue_force_sub_type; } else { raw->vh.mob.sub_type = group_database[group_sub_type].default_red_force_sub_type; } } ASSERT (entity_sub_type_vehicle_valid (raw->vh.mob.sub_type)); // // 3D shape // if (raw->vh.object_3d_shape == OBJECT_3D_INVALID_OBJECT_INDEX) { raw->vh.object_3d_shape = vehicle_database[raw->vh.mob.sub_type].default_3d_shape; } // // weapon config // if (raw->vh.weapon_config_type == WEAPON_CONFIG_TYPE_UNINITIALISED) { raw->vh.weapon_config_type = vehicle_database[raw->vh.mob.sub_type].default_weapon_config_type; } ASSERT (weapon_config_type_valid (raw->vh.weapon_config_type)); // // damage levels // raw->vh.damage_level = vehicle_database[raw->vh.mob.sub_type].initial_damage_level; // // radar dish rotation (ok to use a random number as this is for visual effect only) // raw->vh.radar_rotation_state = frand1 (); //////////////////////////////////////// // // BUILD COMPONENTS // //////////////////////////////////////// // // 3D object // raw->vh.inst3d = construct_3d_object (raw->vh.object_3d_shape); set_routed_vehicle_id_number (en); set_initial_rotation_angle_of_routed_vehicle_wheels (raw->vh.inst3d); // // align with terrain // get_3d_terrain_point_data (raw->vh.mob.position.x, raw->vh.mob.position.z, &raw->vh.terrain_info); heading = get_heading_from_attitude_matrix (raw->vh.mob.attitude); face_normal = get_3d_terrain_point_data_normal (&raw->vh.terrain_info); get_3d_transformation_matrix_from_face_normal_and_heading (raw->vh.mob.attitude, face_normal, heading); // // weapon config // raw->vh.weapon_package_status_array = malloc_fast_mem (SIZE_WEAPON_PACKAGE_STATUS_ARRAY); memset (raw->vh.weapon_package_status_array, 0, SIZE_WEAPON_PACKAGE_STATUS_ARRAY); load_local_entity_weapon_config (en); // // update force info // add_to_force_info (get_local_force_entity (raw->vh.mob.side), en); //////////////////////////////////////// // // LINK INTO SYSTEM // //////////////////////////////////////// insert_local_entity_into_parents_child_list (en, LIST_TYPE_MEMBER, raw->vh.member_link.parent, raw->vh.member_link.child_pred); // // insert into LIST_TYPE_MEMBER before LIST_TYPE_VIEW // insert_local_entity_into_parents_child_list (en, LIST_TYPE_VIEW, get_camera_entity (), get_local_entity_view_list_pred (en)); insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->vh.mob.position), NULL); insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL); } return (en); }
static void kill_local (entity *en) { int losses; routed_vehicle *raw; entity *task, *destroy_task, *group; //////////////////////////////////////// // // PRE-AMBLE // //////////////////////////////////////// #if DEBUG_MODULE >= 2 debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en); #endif if (!get_local_entity_int_value (en, INT_TYPE_ALIVE)) { return; } raw = get_local_entity_data (en); group = get_local_entity_parent (en, LIST_TYPE_MEMBER); ASSERT (group); // // update force info // remove_from_force_info (get_local_force_entity (raw->vh.mob.side), en); //////////////////////////////////////// // // VALIDATE // //////////////////////////////////////// //////////////////////////////////////// // // DESTROY COMPONENTS // //////////////////////////////////////// if (get_comms_model () == COMMS_MODEL_SERVER) { //////////////////////////////////////// // // SEND NOTIFY MESSAGES // //////////////////////////////////////// // notify regen of kill add_entity_to_regen_queue ( get_local_entity_int_value(en, INT_TYPE_SIDE), get_local_entity_type(en), get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE), get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE) ); // // // task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT); while (task) { destroy_task = task; task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT); if (get_local_entity_type (destroy_task) == ENTITY_TYPE_TASK) { #if DEBUG_MODULE debug_log ("RV_DSTRY: killing routed vehicle, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]); #endif notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE); } } // // Release landing lock (if any) // release_mobile_entity_landing_locks (en); } //////////////////////////////////////// // // UNLINK FROM SYSTEM // //////////////////////////////////////// // // routed_vehicle // // // vehicle // unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT); unlink_local_entity_children (en, LIST_TYPE_MOVEMENT_DEPENDENT); #if DEBUG_MODULE debug_log ("RV_DSTRY: removing member %d from group %d", get_local_entity_index (en), get_local_entity_index (raw->vh.member_link.parent)); #endif delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER); delete_local_entity_from_parents_child_list (en, LIST_TYPE_MOVEMENT_DEPENDENT); delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER); // gunship_target_link // member_link // view_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE); // // mobile // // // kill weapon sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN); // // kill engine sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING2); unlink_local_entity_children (en, LIST_TYPE_TARGET); delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK); // sector_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET); // update_link set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DYING); //////////////////////////////////////// // // KILL // //////////////////////////////////////// // must be done before alive flag set to FALSE remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en); set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE); damage_routed_vehicle_3d_object (en); // // group losses // losses = get_local_entity_int_value (group, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (group, INT_TYPE_LOSSES, losses); // // task losses // task = get_local_group_primary_task (group); if (task) { losses = get_local_entity_int_value (task, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (task, INT_TYPE_LOSSES, losses); } // // Notify Campaign Screen // notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group); // // Notify the GROUP that the mobile has been killed (N.B. must be done AFTER mobile is unlinked from member list) // if (get_comms_model () == COMMS_MODEL_SERVER) { notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en); } //////////////////////////////////////// // // SPECIAL EFFECTS // //////////////////////////////////////// set_local_entity_float_value (en, FLOAT_TYPE_DEATH_TIMER, calculate_mobile_death_timer_value (en)); routed_vehicle_impact_movement (en); if (get_comms_model () == COMMS_MODEL_SERVER) { create_client_server_object_killed_explosion_effect (en); } #if LANDING_ROUTE_CHECK destroy_debug_entity_landing_route_check (en); #endif ///////////////////////////////////////////////////////////////// // // SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED // //////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////////////// }
int assign_task_to_group (entity *group, entity *task_en, unsigned int valid_members) { int sites_required; entity_sub_types sub_type, group_type; entity *force, *landing, *end_keysite, *start_keysite, *guide, *member; vec3d *pos; task *task_raw; debug_assert (get_comms_model () == COMMS_MODEL_SERVER); ASSERT (task_en); ASSERT (group); ASSERT (!(get_local_group_primary_task (group) && (get_local_entity_int_value (task_en, INT_TYPE_PRIMARY_TASK)))); task_raw = ( task * ) get_local_entity_data (task_en); group_type = get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE); member = get_local_entity_first_child (group, LIST_TYPE_MEMBER); // don't if no members or if the group is a CARRIER if (!member) { return FALSE; } if (get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE) == ENTITY_SUB_TYPE_GROUP_ASSAULT_SHIP) { if (task_raw->sub_type != ENTITY_SUB_TYPE_TASK_ENGAGE) { return FALSE; } } // // check for invalid tasks // switch (task_raw->sub_type) { case ENTITY_SUB_TYPE_TASK_LANDING: case ENTITY_SUB_TYPE_TASK_LANDING_HOLDING: case ENTITY_SUB_TYPE_TASK_TAKEOFF: case ENTITY_SUB_TYPE_TASK_TAKEOFF_HOLDING: { #ifdef DEBUG debug_fatal ("ASSIGN: Invalid task type (%s) for assign_task_to_group", get_local_entity_string (task_en, STRING_TYPE_FULL_NAME)); #endif return FALSE; } } // // Create route // if (get_local_entity_int_value (group, INT_TYPE_GROUP_LIST_TYPE) == LIST_TYPE_KEYSITE_GROUP) { start_keysite = get_local_entity_parent (group, LIST_TYPE_KEYSITE_GROUP); } else { // start_keysite = get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, task_raw->side, get_local_entity_vec3d_ptr (group, VEC3D_TYPE_POSITION), 1.0 * KILOMETRE, NULL); start_keysite = NULL; } pos = get_local_entity_vec3d_ptr (task_en, VEC3D_TYPE_STOP_POSITION); force = get_local_force_entity ( ( entity_sides ) get_local_entity_int_value (task_en, INT_TYPE_SIDE) ); sub_type = group_database [group_type].default_landing_type; landing = NULL; end_keysite = NULL; if (get_local_entity_int_value (task_en, INT_TYPE_ASSESS_LANDING)) { ASSERT (start_keysite); end_keysite = ( entity * ) get_local_entity_ptr_value (task_en, PTR_TYPE_RETURN_KEYSITE); if (end_keysite) { // // check end keysite has suitble free landing sites // if (start_keysite != end_keysite) { // // if end keysite == start keysite then keysite MUST have enough sites because the aircraft are already there // sites_required = get_local_group_member_count (group); if (get_keysite_landing_sites_available (end_keysite, sub_type) < sites_required) { // // END keysite was specified - but no free landing sites for this group // return FALSE; } } } else { // // No END keysite specified so return to start keysite // end_keysite = start_keysite; set_local_entity_ptr_value (task_en, PTR_TYPE_RETURN_KEYSITE, end_keysite); } ASSERT (end_keysite); landing = get_local_entity_landing_entity (end_keysite, group_database [get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)].default_landing_type); } if (create_generic_waypoint_route (group, task_en, end_keysite, NULL, NULL, NULL, 0)) { #if DEBUG_MODULE debug_log ("ASSIGN: group %s (%d) assigned to task %s (%d)", get_local_entity_string (group, STRING_TYPE_FULL_NAME), get_local_entity_index (group), get_local_entity_string (task_en, STRING_TYPE_FULL_NAME), get_local_entity_index (task_en)); #endif // // Assign task // guide = push_task_onto_group_task_stack (group, task_en, valid_members); assign_task_to_group_members (group, guide, valid_members); return TRUE; } return FALSE; }
int assign_primary_task_to_group (entity *group_en, entity *task_en) { entity_sub_types task_type, group_type; entity *force, *keysite; int side, formation, air_threat, enemy_sectors; unsigned int threat; ASSERT (get_comms_model () == COMMS_MODEL_SERVER); task_type = get_local_entity_int_value (task_en, INT_TYPE_ENTITY_SUB_TYPE); ASSERT (task_database [task_type].primary_task); group_type = get_local_entity_int_value (group_en, INT_TYPE_ENTITY_SUB_TYPE); ASSERT (!get_local_group_primary_task (group_en)); if (assign_task_to_group (group_en, task_en, TASK_ASSIGN_ALL_MEMBERS)) { // // set default group formation // formation = get_local_entity_int_value (group_en, INT_TYPE_GROUP_DEFAULT_FORMATION); if (formation != get_local_entity_int_value (group_en, INT_TYPE_GROUP_FORMATION)) { set_client_server_entity_int_value (group_en, INT_TYPE_GROUP_FORMATION, formation); } // // Link to new keysite // if (get_local_entity_int_value (group_en, INT_TYPE_GROUP_LIST_TYPE) == LIST_TYPE_KEYSITE_GROUP) { keysite = ( entity * ) get_local_entity_ptr_value (task_en, PTR_TYPE_RETURN_KEYSITE); if (keysite) { set_client_server_entity_parent (group_en, LIST_TYPE_KEYSITE_GROUP, keysite); } } // // Notify Force // side = get_local_entity_int_value (group_en, INT_TYPE_SIDE); force = get_local_force_entity ( ( entity_sides ) side ); ASSERT (force); notify_local_entity (ENTITY_MESSAGE_TASK_ASSIGNED, force, task_en); // // Assess for Escort task // if (task_database [task_type].escort_required_threshold != ESCORT_NEVER) { threat = assess_task_difficulty (task_en, &air_threat, &enemy_sectors); #if DEBUG_ESCORT_TASK_CREATION debug_filtered_log ("(ASSIGN) Side %s: Assigned %s to %s, objective %s", entity_side_short_names [side], get_local_entity_string (group_en, STRING_TYPE_FULL_NAME), get_local_entity_string (task_en, STRING_TYPE_FULL_NAME), get_task_objective_string (task_en) ); debug_filtered_log ("Threat: %d (air_threat: %d, enemy_sectors: %d) - Threshold %d", threat, air_threat, enemy_sectors, task_database [task_type].escort_required_threshold); #endif if (threat >= task_database [task_type].escort_required_threshold) { create_escort_task (group_en, (threat >= ESCORT_CRITICAL), task_database [ENTITY_SUB_TYPE_TASK_ESCORT].task_priority, NULL, NULL); ai_log ("(ASSIGN) Created Escort Task for %s :- Threat %d / Threshold %d", get_local_entity_string (task_en, STRING_TYPE_FULL_NAME), threat, task_database [task_type].escort_required_threshold ); } } // // Store Start Time // set_client_server_entity_float_value (task_en, FLOAT_TYPE_START_TIME, get_local_entity_float_value (get_session_entity (), FLOAT_TYPE_ELAPSED_TIME)); // // Clear Expire Timer (now also used for destroying completed tasks) // set_local_entity_float_value (task_en, FLOAT_TYPE_EXPIRE_TIMER, 0.0); ai_log ("(ASSIGN) Side %s: Assigned %s (%d) to %s (%d) - Priority %f", entity_side_short_names [side], get_local_entity_string (group_en, STRING_TYPE_FULL_NAME), get_local_entity_safe_index (group_en), get_local_entity_string (task_en, STRING_TYPE_FULL_NAME), get_local_entity_safe_index (task_en), get_local_entity_float_value (task_en, FLOAT_TYPE_TASK_PRIORITY)); return TRUE; } return FALSE; }
static void kill_local (entity *en) { int losses; entity *task, *group, *destroy_task; fixed_wing *raw; //////////////////////////////////////// // // PRE-AMBLE // //////////////////////////////////////// #if DEBUG_MODULE >= 2 debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en); #endif if (!get_local_entity_int_value (en, INT_TYPE_ALIVE)) { return; } raw = (fixed_wing *) get_local_entity_data (en); group = get_local_entity_parent (en, LIST_TYPE_MEMBER); ASSERT (group); // // update force info // remove_from_force_info (get_local_force_entity ((entity_sides) raw->ac.mob.side), en); if (tacview_is_logging()) write_tacview_unit_event(en, TACVIEW_UNIT_DESTROYED, NULL); //////////////////////////////////////// // // VALIDATE // //////////////////////////////////////// //////////////////////////////////////// // // SEND NOTIFY MESSAGES // //////////////////////////////////////// if (get_comms_model () == COMMS_MODEL_SERVER) { // notify regen of kill add_entity_to_regen_queue ( (entity_sides) get_local_entity_int_value(en, INT_TYPE_SIDE), get_local_entity_type(en), get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE), get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE) ); task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT); while (task) { destroy_task = task; task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT); if (destroy_task->type == ENTITY_TYPE_TASK) { #if DEBUG_MODULE debug_log ("FW_DSTRY: killing fixed wing, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]); #endif notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE); } } // // Release landing lock (if any) // release_mobile_entity_landing_locks (en); } //////////////////////////////////////// // // UNLINK FROM SYSTEM // //////////////////////////////////////// // // fixed_wing // // // aircraft // // aircrew_root unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT); // unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON); delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER); delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER); // gunship_target_link // member_link // view_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE); // // mobile // // // kill weapon sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN); // // kill engine sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING2); // // Kill speech // notify_speech_buffers_entity_killed (en); // special_effect root unlink_local_entity_children (en, LIST_TYPE_TARGET); delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK); // sector_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET); // update_link set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DYING); // // death timer (set time after which entity is totally destroyed) // set_local_entity_float_value (en, FLOAT_TYPE_DEATH_TIMER, calculate_mobile_death_timer_value (en)); //////////////////////////////////////// // // KILL // //////////////////////////////////////// damage_fixed_wing_3d_object (en); // must be done before alive flag set to FALSE remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en); set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE); // // group losses // losses = get_local_entity_int_value (group, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (group, INT_TYPE_LOSSES, losses); // // task losses // task = get_local_group_primary_task (group); if (task) { losses = get_local_entity_int_value (task, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (task, INT_TYPE_LOSSES, losses); } // // Notify Campaign Screen // notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group); // // Notify the GROUP that the mobile has been killed (N.B. must be done AFTER mobile is unlinked from member list) // if (get_comms_model () == COMMS_MODEL_SERVER) { notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en); } //////////////////////////////////////// // // SPECIAL EFFECTS // //////////////////////////////////////// set_local_fixed_wing_afterburner_state (en, OFF); fixed_wing_impact_movement (en); if (get_comms_model () == COMMS_MODEL_SERVER) { vec3d *position; sound_sample_indices sound_sample_index; create_client_server_object_killed_explosion_effect (en); position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); sound_sample_index = SOUND_SAMPLE_INDEX_SHOT_DOWN_AIRCRAFT; create_client_server_sound_effect_entity ( en, ENTITY_SIDE_NEUTRAL, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1, SOUND_CHANNEL_SOUND_EFFECT, SOUND_LOCALITY_ALL, NULL, // position 1.0, // amplification 1.0, // Werewolf pitch TRUE, // valid sound effect TRUE, // looping 1, // sample count &sound_sample_index // sample index list ); } #if LANDING_ROUTE_CHECK destroy_debug_entity_landing_route_check (en); #endif ///////////////////////////////////////////////////////////////// // // SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED // ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////////////// }
void create_client_server_entity_weapon (entity *launcher, entity_sub_types weapon_sub_type, int weapon_index, int burst_size, int *smoke_trail_indices) { entity *force, *target, *weapon; meta_smoke_list_types smoke_trail_type; int i, num_smoke_trail_entities, valid_sound_effect, current_weapon_count, new_weapon_count; ASSERT (launcher); ASSERT (entity_sub_type_weapon_valid (weapon_sub_type)); // // get target // if (!(weapon_database[weapon_sub_type].weapon_class & (WEAPON_CLASS_DECOY | WEAPON_CLASS_CARGO | WEAPON_CLASS_DEBRIS))) { target = get_local_entity_parent (launcher, LIST_TYPE_TARGET); /* if (weapon_database[weapon_sub_type].hellfire_flight_profile) { if (get_local_entity_int_value (launcher, INT_TYPE_LOCK_ON_AFTER_LAUNCH)) { target = NULL; } } */ } else { target = NULL; } if (get_comms_model () == COMMS_MODEL_SERVER) { //////////////////////////////////////// // // SERVER/TX and SERVER/RX // //////////////////////////////////////// ASSERT (weapon_index == ENTITY_INDEX_DONT_CARE); ASSERT (burst_size == BURST_SIZE_DONT_CARE); ASSERT (!smoke_trail_indices); // NOTE: The clients' weapon counters lag the servers' so it is possible that the // client may unknowingly attempt to create more weapons than are available. // This is prone to happen during rapid firing. current_weapon_count = get_local_entity_weapon_count (launcher, weapon_sub_type); if (current_weapon_count > 0) { int loal_mode = weapon_database[weapon_sub_type].hellfire_flight_profile && get_local_entity_int_value (launcher, INT_TYPE_LOCK_ON_AFTER_LAUNCH); if (get_comms_data_flow () == COMMS_DATA_FLOW_RX) { set_force_local_entity_create_stack_attributes (TRUE); } // // get burst size wrt rate of fire // if (weapon_database[weapon_sub_type].rate_of_fire != FIRE_SINGLE_WEAPON) { float time_per_shot = weapon_database[weapon_sub_type].inverse_rate_of_fire * ONE_MINUTE; unsigned int* last_shot = NULL; switch (launcher->type) { case ENTITY_TYPE_HELICOPTER: last_shot = &((helicopter*)get_local_entity_data(launcher))->ac.weapon_salvo_timer; break; case ENTITY_TYPE_FIXED_WING: last_shot = &((fixed_wing*)get_local_entity_data(launcher))->ac.weapon_salvo_timer; break; case ENTITY_TYPE_ANTI_AIRCRAFT: last_shot = &((anti_aircraft*)get_local_entity_data(launcher))->vh.weapon_salvo_timer; break; case ENTITY_TYPE_PERSON: last_shot = &((person*)get_local_entity_data(launcher))->vh.weapon_salvo_timer; break; case ENTITY_TYPE_ROUTED_VEHICLE: last_shot = &((routed_vehicle*)get_local_entity_data(launcher))->vh.weapon_salvo_timer; break; case ENTITY_TYPE_SHIP_VEHICLE: last_shot = &((ship_vehicle*)get_local_entity_data(launcher))->vh.weapon_salvo_timer; break; } if (last_shot) { unsigned int current_time = get_system_time(); float elapsed_time = 1; if (*last_shot > 0) { if (current_time < *last_shot) return; elapsed_time = (current_time - *last_shot) * 0.001; } else elapsed_time = get_delta_time(); burst_size = (int)(weapon_database[weapon_sub_type].rate_of_fire * ONE_OVER_ONE_MINUTE * elapsed_time); if (burst_size < 1) { if (*last_shot == 0) // first shot in salvo always get fired burst_size = 1; else return; } if (*last_shot) *last_shot += (int)(burst_size * time_per_shot * 1000.0); else *last_shot = current_time; } else { ASSERT(FALSE); burst_size = 1; } } else { burst_size = 1; } // // set burst timer // valid_sound_effect = FALSE; if (get_local_entity_float_value (launcher, FLOAT_TYPE_WEAPON_BURST_TIMER) == 0.0) { set_local_entity_float_value (launcher, FLOAT_TYPE_WEAPON_BURST_TIMER, weapon_database[weapon_sub_type].burst_duration); valid_sound_effect = TRUE; } // // create weapon // weapon = create_local_entity ( ENTITY_TYPE_WEAPON, ENTITY_INDEX_DONT_CARE, ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, weapon_sub_type), ENTITY_ATTR_INT_VALUE (INT_TYPE_WEAPON_BURST_SIZE, burst_size), ENTITY_ATTR_INT_VALUE (INT_TYPE_WEAPON_MISSILE_PHASE, MISSILE_PHASE1), ENTITY_ATTR_INT_VALUE (INT_TYPE_LOCK_ON_AFTER_LAUNCH, loal_mode), ENTITY_ATTR_PARENT (LIST_TYPE_LAUNCHED_WEAPON, launcher), ENTITY_ATTR_PARENT (LIST_TYPE_TARGET, target), ENTITY_ATTR_END ); if (weapon) { // // send FIRE message to force (unless it's a decoy/cargo/debris being launched) // if ((target) && (!(weapon_database[weapon_sub_type].weapon_class & (WEAPON_CLASS_DECOY | WEAPON_CLASS_CARGO | WEAPON_CLASS_DEBRIS)))) { force = get_local_force_entity ((entity_sides) get_local_entity_int_value (target, INT_TYPE_SIDE)); if (force) { notify_local_entity (ENTITY_MESSAGE_ENTITY_FIRED_AT, force, launcher, target); } } // // create sound effect(s) // if (valid_sound_effect) { create_weapon_launched_sound_effects (launcher, weapon_sub_type); } // // create smoke trail // smoke_trail_type = (meta_smoke_list_types) get_local_entity_int_value (weapon, INT_TYPE_WEAPON_SMOKE_TRAIL_TYPE); if (smoke_trail_type != META_SMOKE_LIST_TYPE_NONE) { struct OBJECT_3D_BOUNDS *bounding_box; vec3d exhaust_offset; num_smoke_trail_entities = count_entities_in_meta_smoke_list (smoke_trail_type); ASSERT (num_smoke_trail_entities > 0); smoke_trail_indices = (int *) malloc_fast_mem (sizeof (int) * num_smoke_trail_entities); for (i = 0; i < num_smoke_trail_entities; i++) { smoke_trail_indices[i] = ENTITY_INDEX_DONT_CARE; } bounding_box = get_object_3d_bounding_box (get_local_entity_int_value (weapon, INT_TYPE_DEFAULT_3D_SHAPE)); if ((weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_HOKUM_PILOT) ||(weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_HOKUM_CO_PILOT)) { exhaust_offset.x = 0.0; exhaust_offset.y = 0.0; exhaust_offset.z = 0.0; } else { exhaust_offset.x = 0.0; exhaust_offset.y = 0.0; exhaust_offset.z = bounding_box->zmin; } create_meta_smoke_list_specified_offset (smoke_trail_type, weapon, &exhaust_offset, smoke_trail_indices); } transmit_entity_comms_message ( ENTITY_COMMS_CREATE_WEAPON, NULL, launcher, weapon_sub_type, get_local_entity_safe_index (weapon), burst_size, smoke_trail_indices ); if (smoke_trail_indices) { free_mem (smoke_trail_indices); } // // out of weapons (if infinite weapons then reload else select next weapon) // new_weapon_count = get_local_entity_weapon_count (launcher, weapon_sub_type); if (new_weapon_count <= 0) { #if !DEMO_VERSION if (get_local_entity_int_value (get_session_entity (), INT_TYPE_INFINITE_WEAPONS)) { weapon_config_types config_type; config_type = (weapon_config_types) get_local_entity_int_value (launcher, INT_TYPE_WEAPON_CONFIG_TYPE); set_client_server_entity_int_value (launcher, INT_TYPE_WEAPON_CONFIG_TYPE, config_type); } else #endif { // // play weapon out of ammo speech // play_entity_weapon_out_speech (launcher, weapon_sub_type); // // select next weapon // /* if (!(weapon_database[weapon_sub_type].weapon_class & (WEAPON_CLASS_DECOY | WEAPON_CLASS_CARGO | WEAPON_CLASS_DEBRIS))) { entity_sub_types next_weapon_sub_type; if (get_local_entity_int_value (launcher, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI) { next_weapon_sub_type = get_next_available_weapon_sub_type (launcher); } else { next_weapon_sub_type = ENTITY_SUB_TYPE_WEAPON_NO_WEAPON; } set_client_server_entity_int_value (launcher, INT_TYPE_SELECTED_WEAPON, next_weapon_sub_type); } */ } } else { int report_ammo_low_count; report_ammo_low_count = weapon_database[weapon_sub_type].report_ammo_low_count; if ((current_weapon_count > report_ammo_low_count) && (new_weapon_count <= report_ammo_low_count)) { // // play weapon low speech // play_entity_weapon_low_speech (launcher, weapon_sub_type); } else { // // weapon launch speech // play_entity_weapon_launched_speech (launcher, weapon_sub_type); } } } set_force_local_entity_create_stack_attributes (FALSE); } else { pause_client_server_continuous_weapon_sound_effect (launcher, weapon_sub_type); } } else { if (get_comms_data_flow () == COMMS_DATA_FLOW_TX) { //////////////////////////////////////// // // CLIENT/TX // //////////////////////////////////////// ASSERT (weapon_index == ENTITY_INDEX_DONT_CARE); ASSERT (burst_size == BURST_SIZE_DONT_CARE); ASSERT (!smoke_trail_indices); // NOTE: The clients' weapon counters lag the servers' so it is possible that the // client may unknowingly attempt to create more weapons than are available. // This is prone to happen during rapid firing. if (get_local_entity_weapon_available (launcher, weapon_sub_type)) { transmit_entity_comms_message ( ENTITY_COMMS_CREATE_WEAPON, NULL, launcher, weapon_sub_type, ENTITY_INDEX_DONT_CARE, burst_size, NULL ); } } else { //////////////////////////////////////// // // CLIENT/RX // //////////////////////////////////////// ASSERT (weapon_index != ENTITY_INDEX_DONT_CARE); ASSERT (burst_size > 0); set_force_local_entity_create_stack_attributes (TRUE); weapon = create_local_entity ( ENTITY_TYPE_WEAPON, weapon_index, ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, weapon_sub_type), ENTITY_ATTR_INT_VALUE (INT_TYPE_WEAPON_BURST_SIZE, burst_size), ENTITY_ATTR_PARENT (LIST_TYPE_LAUNCHED_WEAPON, launcher), ENTITY_ATTR_PARENT (LIST_TYPE_TARGET, target), ENTITY_ATTR_END ); ASSERT (weapon); // // create smoke trail // smoke_trail_type = (meta_smoke_list_types) get_local_entity_int_value (weapon, INT_TYPE_WEAPON_SMOKE_TRAIL_TYPE); if (smoke_trail_type != META_SMOKE_LIST_TYPE_NONE) { struct OBJECT_3D_BOUNDS *bounding_box; vec3d exhaust_offset; ASSERT (smoke_trail_indices); bounding_box = get_object_3d_bounding_box (get_local_entity_int_value (weapon, INT_TYPE_DEFAULT_3D_SHAPE)); if ((weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_HOKUM_PILOT) ||(weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_HOKUM_CO_PILOT)) { exhaust_offset.x = 0.0; exhaust_offset.y = 0.0; exhaust_offset.z = 0.0; } else { exhaust_offset.x = 0.0; exhaust_offset.y = 0.0; exhaust_offset.z = bounding_box->zmin; } create_meta_smoke_list_specified_offset (smoke_trail_type, weapon, &exhaust_offset, smoke_trail_indices); } else { ASSERT (!smoke_trail_indices); } set_force_local_entity_create_stack_attributes (FALSE); } } }
static void kill_local (entity *en) { int losses; helicopter *raw; entity *task, *group, *member, *destroy_task; //////////////////////////////////////// // // PRE-AMBLE // //////////////////////////////////////// #if DEBUG_MODULE >= 2 debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en); #endif if (!get_local_entity_int_value (en, INT_TYPE_ALIVE)) { return; } raw = get_local_entity_data (en); group = get_local_entity_parent (en, LIST_TYPE_MEMBER); ASSERT (group); // // update force info // remove_from_force_info (get_local_force_entity (raw->ac.mob.side), en); if (en == get_gunship_entity ()) { // // Award Points for mission // task = get_local_entity_primary_task (en); if (task) { if (get_local_entity_int_value (task, INT_TYPE_TASK_STATE) == TASK_STATE_COMPLETED) { // // Only award points for COMPLETE missions (also means player can't rejoin that mission and get points again) // notify_gunship_entity_mission_terminated (en, task); } } } //////////////////////////////////////// // // VALIDATE // //////////////////////////////////////// //////////////////////////////////////// // // DESTROY COMPONENTS // //////////////////////////////////////// #if DEBUG_MODULE debug_log ("HC_DSTRY: killing helicopter %s", entity_sub_type_aircraft_names [raw->ac.mob.sub_type]); #endif if (get_comms_model () == COMMS_MODEL_SERVER) { // notify regen of kill add_entity_to_regen_queue ( get_local_entity_int_value(en, INT_TYPE_SIDE), get_local_entity_type(en), get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE), get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE) ); // // notify task dependents // task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT); while (task) { destroy_task = task; task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT); if (destroy_task->type == ENTITY_TYPE_TASK) { #if DEBUG_MODULE debug_log ("HC_DSTRY: killing helicopter, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]); #endif notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE); } } // // Release landing lock (if any) // release_mobile_entity_landing_locks (en); // // if group contains player, set all helicopters in group to "weapons free", and clear "hold position" flag // if (get_local_entity_int_value (en, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI) { member = get_local_entity_first_child (group, LIST_TYPE_MEMBER); while (member) { set_client_server_entity_int_value (member, INT_TYPE_WEAPONS_HOLD, FALSE); set_client_server_entity_int_value (member, INT_TYPE_POSITION_HOLD, FALSE); member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); } } } //////////////////////////////////////// // // UNLINK FROM SYSTEM // //////////////////////////////////////// // // helicopter // unlink_local_entity_children (en, LIST_TYPE_GUNSHIP_TARGET); unlink_local_entity_children (en, LIST_TYPE_PADLOCK); // // aircraft // // aircrew_root unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT); //////////////////////////////////////// // // the eject sequence relies on launched weapons NOT being unlinked // // unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON); // //////////////////////////////////////// delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER); delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER); // gunship_target_link // member_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_MOVEMENT_DEPENDENT); // view_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE); // // mobile // // // kill weapon sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN); // // kill engine sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_LOOPING); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_WIND_UP); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_WIND_DOWN); // // kill radio / warning effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_INCOMING_MISSILE_WARNING); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_LOCK_ON_TONE); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_MCA); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_RADAR_LOCKED); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_RADAR_TRACKED); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CPG_MESSAGE); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_RADIO_MESSAGE); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_WARNING_MESSAGE); notify_speech_buffers_entity_killed (en); unlink_local_entity_children (en, LIST_TYPE_TARGET); delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK); // sector_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET); // update_link // // death timer (set time after which entity is totally destroyed) // set_local_entity_float_value (en, FLOAT_TYPE_DEATH_TIMER, calculate_mobile_death_timer_value (en)); //////////////////////////////////////// // // KILL // //////////////////////////////////////// damage_helicopter_3d_object (en); // must be done before alive flag set to FALSE remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en); set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE); // // group losses // losses = get_local_entity_int_value (group, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (group, INT_TYPE_LOSSES, losses); // // task losses // task = get_local_group_primary_task (group); if (task) { losses = get_local_entity_int_value (task, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (task, INT_TYPE_LOSSES, losses); } // // Notify Campaign Screen // notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group); // // Notify the GROUP that the mobile has been killed (N.B. must be done AFTER mobile is unlinked from member list) // if (get_comms_model () == COMMS_MODEL_SERVER) { notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en); } // // Notify force to check campaign criteria // if (get_comms_model () == COMMS_MODEL_SERVER) { entity *force; force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (force) { notify_local_entity (ENTITY_MESSAGE_CHECK_CAMPAIGN_OBJECTIVES, force, en); force = get_local_entity_child_succ (force, LIST_TYPE_FORCE); } } //////////////////////////////////////// // // SPECIAL EFFECTS // //////////////////////////////////////// helicopter_impact_movement (en); if (get_comms_model () == COMMS_MODEL_SERVER) { vec3d *position; sound_sample_indices sound_sample_index; set_client_server_entity_int_value (en, INT_TYPE_MAIN_ROTOR_DAMAGED, TRUE); set_client_server_entity_int_value (en, INT_TYPE_TAIL_ROTOR_DAMAGED, TRUE); create_client_server_object_killed_explosion_effect (en); position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); sound_sample_index = SOUND_SAMPLE_INDEX_SHOT_DOWN_HELICOPTER; create_client_server_sound_effect_entity ( en, ENTITY_SIDE_NEUTRAL, ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_LOOPING, SOUND_CHANNEL_SOUND_EFFECT, SOUND_LOCALITY_ALL, NULL, // position 1.0, // amplification TRUE, // valid sound effect TRUE, // looping 1, // sample count &sound_sample_index // sample index list ); } set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DYING); //////////////////////////////////////// // // VIEWS // //////////////////////////////////////// if ((en == get_gunship_entity ()) && (!get_local_entity_int_value (en, INT_TYPE_EJECTED))) { set_gunship_entity (NULL); } #if LANDING_ROUTE_CHECK destroy_debug_entity_landing_route_check (en); #endif ///////////////////////////////////////////////////////////////// // // SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED // ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////////////// }
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; }
static void kill_local (entity *en) { int losses; entity *task, *group, *keysite, *destroy_task; ship_vehicle *raw; //////////////////////////////////////// // // PRE-AMBLE // //////////////////////////////////////// #if DEBUG_MODULE >= 2 debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en); #endif if (!get_local_entity_int_value (en, INT_TYPE_ALIVE)) { return; } raw = (ship_vehicle *) get_local_entity_data (en); group = get_local_entity_parent (en, LIST_TYPE_MEMBER); ASSERT (group); keysite = NULL; if (tacview_is_logging()) write_tacview_unit_event(en, TACVIEW_UNIT_DESTROYED, NULL); // // update force info // remove_from_force_info (get_local_force_entity ((entity_sides) raw->vh.mob.side), en); //////////////////////////////////////// // // VALIDATE // //////////////////////////////////////// //////////////////////////////////////// // // DESTROY COMPONENTS // //////////////////////////////////////// if (get_comms_model () == COMMS_MODEL_SERVER) { task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT); while (task) { destroy_task = task; task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT); if (destroy_task->type == ENTITY_TYPE_TASK) { #if DEBUG_MODULE debug_log ("SH_DSTRY: killing ship, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]); #endif notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE); } } // // Release landing lock (if any) // release_mobile_entity_landing_locks (en); //////////////////////////////////////// // // UNLINK FROM SYSTEM // //////////////////////////////////////// // // Destroy keysite entity if ship is carrier // keysite = get_local_entity_first_child (en, LIST_TYPE_MOVEMENT_DEPENDENT); while (keysite) { if (get_local_entity_type (keysite) == ENTITY_TYPE_KEYSITE) { break; } keysite = get_local_entity_child_succ (keysite, LIST_TYPE_MOVEMENT_DEPENDENT); } } // // ship_vehicle // // // vehicle // unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT); unlink_local_entity_children (en, LIST_TYPE_MOVEMENT_DEPENDENT); delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER); delete_local_entity_from_parents_child_list (en, LIST_TYPE_MOVEMENT_DEPENDENT); delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER); // gunship_target_link // member_link // view_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE); // // mobile // // // kill weapon sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN); // // kill engine sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING2); unlink_local_entity_children (en, LIST_TYPE_TARGET); delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK); // sector_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET); // update_link set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_STOPPED); //////////////////////////////////////// // // KILL // //////////////////////////////////////// // must be done before alive flag set remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en); set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE); damage_ship_3d_object (en); // // group losses // losses = get_local_entity_int_value (group, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (group, INT_TYPE_LOSSES, losses); // // task losses // task = get_local_group_primary_task (group); if (task) { losses = get_local_entity_int_value (task, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (task, INT_TYPE_LOSSES, losses); } // // Notify Campaign Screen // notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group); if (get_comms_model () == COMMS_MODEL_SERVER) { // // Notify the GROUP that the mobile has been killed (N.B. must be done AFTER mobile is unlinked from member list) // notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en); // // Kill the keysite if ship is the carrier (N.B. must be done AFTER ships alive flag cleared) // if (keysite) { kill_client_server_entity (keysite); } } //////////////////////////////////////// // // SPECIAL EFFECTS // //////////////////////////////////////// if (get_comms_model () == COMMS_MODEL_SERVER) { create_client_server_object_killed_explosion_effect (en); } #if LANDING_ROUTE_CHECK destroy_debug_entity_landing_route_check (en); #endif ///////////////////////////////////////////////////////////////// // // SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED // ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////////////// }
static void kill_local (entity *en) { anti_aircraft *raw; int losses; entity *task, *destroy_task, *group; //////////////////////////////////////// // // PRE-AMBLE // //////////////////////////////////////// #if DEBUG_MODULE >= 2 debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en); #endif if (!get_local_entity_int_value (en, INT_TYPE_ALIVE)) { return; } raw = (anti_aircraft *) get_local_entity_data (en); group = get_local_entity_parent (en, LIST_TYPE_MEMBER); ASSERT (group); if (tacview_is_logging()) write_tacview_unit_event(en, TACVIEW_UNIT_DESTROYED, NULL); // // update force info // remove_from_force_info (get_local_force_entity ((entity_sides) raw->vh.mob.side), en); //////////////////////////////////////// // // VALIDATE // //////////////////////////////////////// //////////////////////////////////////// // // DESTROY COMPONENTS // //////////////////////////////////////// if (get_comms_model () == COMMS_MODEL_SERVER) { //////////////////////////////////////// // // SEND NOTIFY MESSAGES // //////////////////////////////////////// // // // task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT); while (task) { destroy_task = task; task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT); if (get_local_entity_type (destroy_task) == ENTITY_TYPE_TASK) { #if DEBUG_MODULE debug_log ("AA_DSTRY: killing routed vehicle, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]); #endif notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE); } } // // Release landing lock (if any) // release_mobile_entity_landing_locks (en); } //////////////////////////////////////// // // UNLINK FROM SYSTEM // //////////////////////////////////////// // // anti_aircraft // // // vehicle // unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT); // unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON); delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER); delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER); // gunship_target_link // member_link // view_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE); // // mobile // // // kill weapon sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN); //unlink_local_entity_children (en, LIST_TYPE_SPECIAL_EFFECT); unlink_local_entity_children (en, LIST_TYPE_TARGET); delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK); // sector_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET); delete_local_entity_from_parents_child_list (en, LIST_TYPE_UPDATE); set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DEAD); //////////////////////////////////////// // // KILL // //////////////////////////////////////// // must be done before alive flag set to FALSE remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en); set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE); damage_anti_aircraft_3d_object (en); // // group losses // losses = get_local_entity_int_value (group, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (group, INT_TYPE_LOSSES, losses); // // Notify Campaign Screen // notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group); // // Notify the GROUP that the mobile has been killed (N.B. must be done AFTER mobile is unlinked from member list) // if (get_comms_model () == COMMS_MODEL_SERVER) { notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en); } //////////////////////////////////////// // // SPECIAL EFFECTS // //////////////////////////////////////// if (get_comms_model () == COMMS_MODEL_SERVER) { create_client_server_object_killed_explosion_effect (en); } }
int create_group_emergency_transfer_task (entity *en) { entity *landing, *new_keysite, *new_task; int side, landing_type, sites_required; vec3d *pos; ASSERT (en); ASSERT (get_comms_model () == COMMS_MODEL_SERVER); side = get_local_entity_int_value (en, INT_TYPE_SIDE); pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); group_terminate_all_tasks (en); sites_required = get_local_group_member_count (en); landing_type = group_database [get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE)].default_landing_type; landing = get_closest_free_landing_site (landing_type, get_local_force_entity (side), pos, 0.0, NULL, sites_required); if (landing) { // // Found new keysite // new_keysite = get_local_entity_parent (landing, LIST_TYPE_LANDING_SITE); if (landing_type == ENTITY_SUB_TYPE_LANDING_HELICOPTER) { new_task = create_transfer_task (side, ENTITY_SUB_TYPE_TASK_TRANSFER_HELICOPTER, 10.0, new_keysite, new_keysite); } else { new_task = create_transfer_task (side, ENTITY_SUB_TYPE_TASK_TRANSFER_FIXED_WING, 10.0, new_keysite, new_keysite); } ASSERT (new_task); if (!assign_primary_task_to_group (en, new_task)) { // // Failed to assign transfer task // ai_log ("(TRANSFER) Failed to assign Emergency Transfer to %s", get_local_entity_string (en, STRING_TYPE_FULL_NAME)); group_kill_all_members (en); return FALSE; } else { ai_log ("(TRANSFER) Successfully assigned Emergency Transfer to %s", get_local_entity_string (en, STRING_TYPE_FULL_NAME)); return TRUE; } } else { // // Failed to find alternate keysite // ai_log ("(TRANSFER) Failed to find Emergency Transfer keysite for %s", get_local_entity_string (en, STRING_TYPE_FULL_NAME)); group_kill_all_members (en); return FALSE; } }
entity *regen_update (entity *en) { regen_management_element *m1; entity_sub_types member_type, group_type; entity *wp, *task, *group, *member, *building, *force_en, *landing, *keysite; unsigned int member_number; int reserve_count; force *force_raw; regen *raw; regen_list_element *e1; raw = (regen *) get_local_entity_data (en); wp = get_local_entity_parent (en, LIST_TYPE_CURRENT_WAYPOINT); task = get_local_entity_parent (wp, LIST_TYPE_WAYPOINT); landing = get_local_entity_parent (task, LIST_TYPE_UNASSIGNED_TASK); keysite = get_local_entity_parent (landing, LIST_TYPE_LANDING_SITE); force_en = get_local_force_entity ((entity_sides) raw->side); force_raw = (force *) get_local_entity_data (force_en); group_type = NUM_ENTITY_SUB_TYPE_GROUPS; m1 = ®en_manager [raw->side][raw->sub_type]; // // is there anything in the regen queues? // if (m1->count == 0) { return NULL; } // // Can regen operate // building = raw->member_root.first_child; if ((!get_local_entity_int_value (building, INT_TYPE_ALIVE)) || (get_local_entity_int_value (keysite, INT_TYPE_KEYSITE_USABLE_STATE) != KEYSITE_STATE_USABLE)) { #if DEBUG_MODULE debug_log ("RG_UPDT: keysite %s too damaged to regen", get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME)); #endif return NULL; } e1 = ®en_queue [raw->side][raw->sub_type][m1->front]; ASSERT (e1->type != -1); ASSERT (e1->sub_type != -1); ASSERT (e1->group != -1); // is there a reserve of this type? if ((e1->type == ENTITY_TYPE_FIXED_WING) || (e1->type == ENTITY_TYPE_HELICOPTER)) { reserve_count = force_raw->force_info_reserve_hardware[aircraft_database[e1->sub_type].force_info_catagory]; } else { reserve_count = force_raw->force_info_reserve_hardware[vehicle_database[e1->sub_type].force_info_catagory]; } if (reserve_count <= 0) { return NULL; } #if DEBUG_MODULE debug_log ("RG_UPDT: Trying to Regen %s Sub Type %d at %s - reserve count %d", get_entity_type_name (e1->type), e1->sub_type, get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), reserve_count); #endif // // Don't regen if PLAYER landed there // group = get_local_entity_first_child (keysite, LIST_TYPE_KEYSITE_GROUP); while (group) { member = get_local_entity_first_child (group, LIST_TYPE_MEMBER); while (member) { if (get_local_entity_int_value (member, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI) { if (get_local_entity_int_value (member, INT_TYPE_LANDED)) { #if DEBUG_MODULE debug_log ("RG_UPDT: PLAYER landed at keysite %s, can't regen", get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME)); #endif return NULL; } } member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); } group = get_local_entity_child_succ (group, LIST_TYPE_KEYSITE_GROUP); } group_type = e1->group; member_type = e1->sub_type; //////////////////////////////////////////////////////////////////////////// // Dont regen people or transport aircraft in apache havoc campaign as airport might not be correct (landing routes etc) //////////////////////////////////////////////////////////////////////////// if (get_local_entity_int_value (get_session_entity (), INT_TYPE_CAMPAIGN_REQUIRES_APACHE_HAVOC)) { switch (get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE)) { case ENTITY_SUB_TYPE_REGEN_PEOPLE: { #if DEBUG_MODULE debug_log ("RG_UPDT: Stopping Regening People - wrong warzone"); #endif return NULL; } case ENTITY_SUB_TYPE_REGEN_FIXED_WING: { if (group_database [group_type].default_landing_type == ENTITY_SUB_TYPE_LANDING_FIXED_WING_TRANSPORT) { #if DEBUG_MODULE debug_log ("RG_UPDT: Stopping Regening Transport aircraft - wrong warzone"); #endif return NULL; } } } } //////////////////////////////////////////////////////////////////////////// // Dont regen people or transport aircraft in apache havoc campaign as airport might not be correct (landing routes etc) //////////////////////////////////////////////////////////////////////////// if (group_type != NUM_ENTITY_SUB_TYPE_GROUPS) { int route_node; entity *building, *member, *guide, *group = NULL; group = create_landing_faction_members (keysite, member_type, group_type, 1, wp, &raw->position); if (group) { // // Assign closest route_node (only needed for routed vehicles) // if (get_local_entity_int_value (group, INT_TYPE_FRONTLINE)) { route_node = get_closest_side_road_node ((entity_sides) get_local_entity_int_value (group, INT_TYPE_SIDE), &raw->position, 5 * KILOMETRE); set_client_server_entity_int_value (group, INT_TYPE_ROUTE_NODE, route_node); } // // // member = get_local_entity_first_child (group, LIST_TYPE_MEMBER); // // close members doors // close_client_server_entity_cargo_doors (member); close_client_server_entity_loading_doors (member); // // open building doors // building = get_local_entity_first_child (en, LIST_TYPE_MEMBER); open_client_server_entity_loading_doors (building); set_local_entity_float_value (building, FLOAT_TYPE_LOADING_DOOR_TIMER, 30.0); // // create guide entity for task (TEST) // // Debug for Transport aircraft. // Locate nearest Transport landing wp and insert into it if (group_database [group_type].default_landing_type == ENTITY_SUB_TYPE_LANDING_FIXED_WING_TRANSPORT) { float range, best_range; entity *transport_wp, *transport_task, *transport_landing; best_range = 999999999.0; transport_landing = get_local_entity_landing_entity (keysite, ENTITY_SUB_TYPE_LANDING_FIXED_WING_TRANSPORT); if (transport_landing) { transport_task = get_local_landing_entity_task (transport_landing, ENTITY_SUB_TYPE_TASK_LANDING); ASSERT (transport_task); transport_wp = get_local_entity_first_child (transport_task, LIST_TYPE_WAYPOINT); ASSERT (transport_wp); while (transport_wp) { range = get_sqr_2d_range (get_local_entity_vec3d_ptr (transport_wp, VEC3D_TYPE_POSITION), get_local_entity_vec3d_ptr (building, VEC3D_TYPE_POSITION)); if (range < best_range) { wp = transport_wp; task = transport_task; best_range = range; } transport_wp = get_local_entity_child_succ (transport_wp, LIST_TYPE_WAYPOINT); } } } // Debug for Transport aircraft. member_number = get_local_entity_int_value (member, INT_TYPE_GROUP_MEMBER_NUMBER); guide = create_client_server_guide_entity (task, wp, (1 << member_number)); attach_group_to_guide_entity (group, guide); attach_group_member_to_guide_entity (member, guide); //#if DEBUG_MODULE { entity *keysite; keysite = get_local_entity_parent (landing, LIST_TYPE_LANDING_SITE); member = get_local_entity_first_child (group, LIST_TYPE_MEMBER); debug_log ("RG_UPDT: %s creating %s (%d) at keysite %s free landing sites %d, reserved %d, lock %d, available lock: %d", entity_side_names [get_local_entity_int_value (keysite, INT_TYPE_SIDE)], get_local_entity_type_name (member), get_local_entity_index (member), get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), get_local_entity_int_value (landing, INT_TYPE_FREE_LANDING_SITES), get_local_entity_int_value (landing, INT_TYPE_RESERVED_LANDING_SITES), get_local_entity_int_value (landing, INT_TYPE_LANDING_LOCK), check_available_landing_route_lock (landing) ); if ((e1->type == ENTITY_TYPE_FIXED_WING) || (e1->type == ENTITY_TYPE_HELICOPTER)) { debug_log("%s reserves left: %d", force_info_catagory_names[aircraft_database[e1->sub_type].force_info_catagory], force_raw->force_info_reserve_hardware[aircraft_database[e1->sub_type].force_info_catagory] ); } else { debug_log("%s reserves left: %d", force_info_catagory_names[vehicle_database[e1->sub_type].force_info_catagory], force_raw->force_info_reserve_hardware[vehicle_database[e1->sub_type].force_info_catagory] ); } } //#endif #if DEBUG_MODULE switch (e1->type) { case ENTITY_TYPE_FIXED_WING: case ENTITY_TYPE_HELICOPTER: { ASSERT (regen_ac_debug[e1->sub_type] > 0); break; } case ENTITY_TYPE_ROUTED_VEHICLE: case ENTITY_TYPE_SHIP_VEHICLE: case ENTITY_TYPE_PERSON: { ASSERT (regen_vh_debug[e1->sub_type] > 0); break; } default: { debug_fatal ("RG_UPDT: Unknown entity type for debug"); } } #endif // update markers regen_queue_use ((entity_sides) raw->side, (raw->sub_type)); return member; } } else { #if DEBUG_MODULE >= 2 debug_log ("RG_UPDT: not creating anything at keysite %s free landing sites %d, reserved %d, lock %d", get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), get_local_entity_int_value (landing, INT_TYPE_FREE_LANDING_SITES), get_local_entity_int_value (landing, INT_TYPE_RESERVED_LANDING_SITES), check_available_landing_route_lock (landing)); #endif } return NULL; }