static void set_remote_float_value (entity *en, float_types type, float value) { debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_FLOAT_VALUE, en, type, value); transmit_entity_comms_message (ENTITY_COMMS_FLOAT_VALUE, en, type, value); }
static void update_time_of_day_resync (entity *en) { session *raw; ASSERT (en); raw = (session *) get_local_entity_data (en); raw->time_of_day_resync += get_delta_time (); if (raw->time_of_day_resync > SESSION_RESYNC_FREQUENCY) { transmit_entity_comms_message (ENTITY_COMMS_UPDATE, en); raw->time_of_day_resync = 0.0; #if DEBUG_MODULE debug_log ("SS_UPDT : Weather at %f, %f - radius %f", raw->weather_position.x, raw->weather_position.z, raw->weather_radius); #endif } }
entity *create_client_server_sound_effect_entity ( 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; ASSERT (get_comms_model () == COMMS_MODEL_SERVER); ASSERT (side < NUM_ENTITY_SIDES); en = create_local_sound_effect_entity ( ENTITY_INDEX_DONT_CARE, parent, side, sub_type, channel, locality, position, amp, valid, looping, sample_count, sample_indices ); transmit_entity_comms_message ( ENTITY_COMMS_CREATE_SOUND_EFFECT, NULL, get_local_entity_safe_index (en), parent, side, sub_type, channel, locality, position, amp, valid, looping, sample_count, sample_indices ); return en; }
static void destroy_client_family (entity *en) { #if DEBUG_MODULE >= 2 debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_DESTROY_FAMILY, en); #endif transmit_entity_comms_message (ENTITY_COMMS_DESTROY_FAMILY, en); }
static void set_remote_int_value (entity *en, int_types type, int value) { #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_INT_VALUE, en, type, value); #endif transmit_entity_comms_message (ENTITY_COMMS_INT_VALUE, en, type, value); }
static void destroy_remote (entity *en) { #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_DESTROY, en); #endif transmit_entity_comms_message (ENTITY_COMMS_DESTROY, en); }
static void kill_remote (entity *en) { #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_KILL, en); #endif transmit_entity_comms_message (ENTITY_COMMS_KILL, en); }
int resume_client_server_entity_sound_type (entity *en, entity_sub_types type) { int count; count = resume_local_entity_sound_type (en, type); transmit_entity_comms_message (ENTITY_COMMS_RESUME_SOUND_TYPE, en, type); return count; }
int pause_client_server_entity_sound_type (entity *en, entity_sub_types type, float delay) { int count; count = pause_local_entity_sound_type (en, type, delay); transmit_entity_comms_message (ENTITY_COMMS_PAUSE_SOUND_TYPE, en, type, delay); return count; }
static void set_remote_string (entity *en, string_types type, const char *s) { ASSERT (s); #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_STRING, en, type, s); #endif transmit_entity_comms_message (ENTITY_COMMS_STRING, en, type, s); }
static void set_remote_vec3d (entity *en, vec3d_types type, vec3d *v) { ASSERT (v); #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_VEC3D, en, type, v); #endif transmit_entity_comms_message (ENTITY_COMMS_VEC3D, en, type, v); }
void set_client_server_entity_weapon_damage (entity *en, int heading_depth, entity_sub_types weapon_sub_type, int damage) { ASSERT (en); if (get_comms_model () == COMMS_MODEL_SERVER) { //////////////////////////////////////// // // SERVER/TX and SERVER/RX // //////////////////////////////////////// set_local_entity_weapon_damage (en, heading_depth, weapon_sub_type, damage); transmit_entity_comms_message (ENTITY_COMMS_DAMAGE_WEAPON_PACKAGE, en, heading_depth, weapon_sub_type, damage); } else { if (get_comms_data_flow () == COMMS_DATA_FLOW_TX) { //////////////////////////////////////// // // CLIENT/TX // //////////////////////////////////////// transmit_entity_comms_message (ENTITY_COMMS_DAMAGE_WEAPON_PACKAGE, en, heading_depth, weapon_sub_type, damage); } else { //////////////////////////////////////// // // CLIENT/RX // //////////////////////////////////////// set_local_entity_weapon_damage (en, heading_depth, weapon_sub_type, damage); } } }
void pause_client_server_continuous_weapon_sound_effect (entity *en, entity_sub_types weapon_sub_type) { ASSERT (en); ASSERT ((get_comms_model () == COMMS_MODEL_SERVER) || (en == get_gunship_entity ())); if (weapon_sub_type != ENTITY_SUB_TYPE_WEAPON_NO_WEAPON) { pause_local_continuous_weapon_sound_effect (en, weapon_sub_type); transmit_entity_comms_message (ENTITY_COMMS_PAUSE_WEAPON_SOUND_TYPE, en, weapon_sub_type); } }
static entity *create_remote (entity_types type, int index, char *pargs) { validate_remote_create_entity_index (index); #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_CREATE, NULL, type, index); #endif transmit_entity_comms_message (ENTITY_COMMS_CREATE, NULL, type, index, pargs); return (NULL); }
void respond_to_player_task_assign_request (entity *pilot, entity *task, entity *mobile) { entity *group; ASSERT (pilot); ASSERT (mobile); ASSERT (task); ASSERT (get_comms_model () == COMMS_MODEL_SERVER); group = get_local_entity_parent (mobile, LIST_TYPE_MEMBER); if ((!get_local_entity_first_child (task, LIST_TYPE_GUIDE)) && (!get_local_group_primary_task (group))) { if (assign_primary_task_to_group (group, task)) { transmit_entity_comms_message (ENTITY_COMMS_TASK_ASSIGN_RESULT, pilot, task, mobile); return; } } else { if (get_local_group_primary_task (group)) { transmit_entity_comms_message (ENTITY_COMMS_TASK_ASSIGN_RESULT, pilot, task, mobile); return; } } transmit_entity_comms_message (ENTITY_COMMS_TASK_ASSIGN_RESULT, pilot, NULL, NULL); }
void unpack_client_server_entity_data (entity *en) { if (get_comms_model () == COMMS_MODEL_SERVER) { unpack_local_entity_data (en, get_local_entity_type (en), PACK_MODE_UPDATE_ENTITY); transmit_entity_comms_message (ENTITY_COMMS_UPDATE, en); } else { ASSERT (get_comms_model () == COMMS_MODEL_CLIENT); unpack_local_entity_data (en, get_local_entity_type (en), PACK_MODE_UPDATE_ENTITY); } }
void damage_helicopter_via_damage_level (entity *en, entity *aggressor) { int damage; float en_damage_factor; ASSERT (get_local_entity_int_value (en, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI); en_damage_factor = (float) get_local_entity_int_value (en, INT_TYPE_DAMAGE_LEVEL) / get_local_entity_int_value (en, INT_TYPE_INITIAL_DAMAGE_LEVEL); for (damage = 0; damage < sizeof (dynamics_damage_database) / sizeof (dynamics_damage_type); damage ++) { if (dynamics_damage_database [damage].kickin_value >= en_damage_factor) { if (get_gunship_entity () == en) { dynamics_damage_model (1 << damage, TRUE); } else { transmit_entity_comms_message (ENTITY_COMMS_DAMAGE_PLAYER, en, 1 << damage, TRUE); } /* if (aggressor) { if (dynamics_damage_database [damage].store_aggressor_in_debrief) { debug_log ("CO_DMG: storing in debrief that %s %s caused damage to user", entity_type_names [get_local_entity_type (aggressor)], get_local_entity_string (aggressor, STRING_TYPE_FULL_NAME)); // set_debrief_aggressor_entity (aggressor); } } */ } } }
entity *push_task_onto_group_task_stack (entity *group, entity *task, unsigned int valid_members) { entity *task_parent, *guide; list_types list_type; #ifdef DEBUG unsigned int total_members, member_number; #endif ASSERT (get_comms_model () == COMMS_MODEL_SERVER); ASSERT (group); #ifdef DEBUG total_members = 0; // // Check not already on stack // guide = get_local_entity_first_child (task, LIST_TYPE_GUIDE); while (guide) { if (get_local_entity_parent (guide, LIST_TYPE_GUIDE_STACK) == group) { member_number = get_local_entity_int_value (guide, INT_TYPE_VALID_GUIDE_MEMBERS); total_members |= member_number; } guide = get_local_entity_child_succ (guide, LIST_TYPE_GUIDE); } // // A TASK may be on the stack many times, but any one member should not have the same task duplicated // e.g. ENGAGE tasks may be duplicated many times, but their guide "valid_members" should all be exclusive // if (valid_members & total_members) { debug_filtered_log ("Trying to assign task %s (%d) to group %s - members %d", get_local_entity_string (task, STRING_TYPE_FULL_NAME), get_local_entity_index (task), get_local_entity_string (group, STRING_TYPE_FULL_NAME), valid_members); debug_filtered_log (""); dump_guide_stack (group); debug_fatal ("ASSIGN: Task %s already on Group %s guide stack", get_local_entity_string (task, STRING_TYPE_FULL_NAME), get_local_entity_string (group, STRING_TYPE_FULL_NAME)); } #endif // // create guide entity for task // guide = create_client_server_guide_entity (task, NULL, valid_members); attach_group_to_guide_entity (group, guide); // // remove task and group from lists (must be done AFTER guide is created and attached) // list_type = get_local_task_list_type (task); if (list_type == LIST_TYPE_UNASSIGNED_TASK) { task_parent = get_local_entity_parent (task, list_type); if (task_parent) { delete_local_entity_from_parents_child_list (task, list_type); // // add task to assigned task list, if not already on it. // insert_local_entity_into_parents_child_list (task, LIST_TYPE_ASSIGNED_TASK, task_parent, NULL); transmit_entity_comms_message (ENTITY_COMMS_SWITCH_LIST, task, LIST_TYPE_UNASSIGNED_TASK, task_parent, LIST_TYPE_ASSIGNED_TASK); } } return guide; }
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); } } }
void comms_process_data (void) { session_list_data_type *current_session; connection_list_type *this_connection, *connection; char *received_data; int planner_event, frame_id, packet_id, receive_flag, received_size; GUID received_id = 0; entity *member; send_types send_type; packet_types type; // receive all packets in queue current_session = get_current_game_session (); received_size = MAX_RECEIVE_SIZE; connection = get_connection_list_head (); while (connection) { this_connection = connection; connection = connection->next; send_type = SEND_TYPE_GROUP; while (send_type >= SEND_TYPE_PERSONAL) { receive_flag = TRUE; while (receive_flag) { type = process_packet_list (send_type, this_connection, &received_id, &received_data, &received_size); switch (type) { /////////////////////////////////////////////////////////////////////////////////////////////// // // System packets, used internally // /////////////////////////////////////////////////////////////////////////////////////////////// case PACKET_TYPE_INVALID: { receive_flag = FALSE; if (get_comms_model () == COMMS_MODEL_SERVER) { if (this_connection->packet_rerequested > command_line_comms_packet_rerequest_limit) { debug_log ("COMM_MAN: REJECTING CONNECTION. CONNECTION TOO BAD (re-request limit %d reached)", command_line_comms_packet_rerequest_limit); send_packet (this_connection->connection_id, PACKET_TYPE_SERVER_REJECTED, NULL, 0, SEND_TYPE_PERSONAL); } } break; } case PACKET_TYPE_RESEND_PACKET: { send_types resend_send_type; frame_id = get_list_item (received_data, int); packet_id = get_list_item (received_data, int); resend_send_type = get_list_item (received_data, send_types); #if DEBUG_MODULE if (this_connection->pilot_entity) { debug_log ("COMMS MAN: received RESEND PACKET for frame %d packet %d from %s (dpid %d)", frame_id, packet_id, get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME), received_id); } else { debug_log ("COMMS MAN: received RESEND PACKET by unknown (pdid %d)", received_id); } #endif resend_packet (received_id, frame_id, packet_id, resend_send_type); break; } /////////////////////////////////////////////////////////////////////////////////////////////// // // Packets for initialisation and joining // /////////////////////////////////////////////////////////////////////////////////////////////// case PACKET_TYPE_SESSION_QUERY: { char *ptr; int server_version_number, player_count, size; connection_list_type *new_connection; if (get_comms_model () == COMMS_MODEL_SERVER) { #if DEBUG_MODULE if (this_connection->pilot_entity) { debug_log ("COMMS MAN: RECEIVED SESSION QUERY from %s (dpid %d)", get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME), received_id); } else { debug_log ("COMMS MAN: RECEIVED SESSION QUERY from %d", received_id); } #endif new_connection = get_connection_list_item (received_id); if (!new_connection->already_sent_query_data) { new_connection->already_sent_query_data = TRUE; while (TRUE) { ptr = new_connection->connection_receive_buffer; size = 0; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Check both client and server are running same campaign data // server_version_number = get_local_entity_int_value (get_session_entity (), INT_TYPE_VERSION_NUMBER); quick_set_list_item (ptr, int, server_version_number); size += sizeof (int); // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // map details quick_set_list_item (ptr, int, NUM_MAP_X_SECTORS); quick_set_list_item (ptr, int, NUM_MAP_Z_SECTORS); quick_set_list_item (ptr, int, SECTOR_SIDE_LENGTH); size += sizeof (int) * 3; // data path strcpy (ptr, current_session->data_path); ptr += strlen (current_session->data_path) + 1; size += strlen (current_session->data_path) + 1; // population_placement filename if (population_placement_filename) { strcpy (ptr, population_placement_filename); ptr += strlen (population_placement_filename) + 1; size += strlen (population_placement_filename) + 1; } else { strcpy (ptr, "\0"); ptr += strlen ("\0") + 1; size += strlen ("\0") + 1; } // // side_data filename if (side_data_filename) { strcpy (ptr, side_data_filename); ptr += strlen (side_data_filename) + 1; size += strlen (side_data_filename) + 1; } else { strcpy (ptr, "\0"); ptr += strlen ("\0") + 1; size += strlen ("\0") + 1; } // campaign_population filename if (campaign_population_filename) { strcpy (ptr, campaign_population_filename); ptr += strlen (campaign_population_filename) + 1; size += strlen (campaign_population_filename) + 1; } else { strcpy (ptr, "\0"); ptr += strlen ("\0") + 1; size += strlen ("\0") + 1; } // // planner position and zoom // // quick_set_list_item (ptr, float, planner_map_data.centre_map_x); // quick_set_list_item (ptr, float, planner_map_data.centre_map_z); // size += sizeof (float) * 2; // quick_set_list_item (ptr, int, planner_map_data.map_zoom); // size += sizeof (int); // // Pilots // player_count = get_number_of_connected_players (); quick_set_list_item (ptr, int, player_count); size += sizeof (int); // // // #if DEBUG_MODULE debug_log ("COMM_MAN: sending data path %s, population placement %s, side data %s, campaign_pop file %s", current_session->data_path, population_placement_filename, side_data_filename, campaign_population_filename); #endif new_connection->connection_receive_buffer_size -= size; if (!pack_session (ptr, &new_connection->connection_receive_buffer_size, PACK_MODE_BROWSE_SESSION)) { break; } new_connection->connection_receive_buffer_size *= 2; #if DEBUG_MODULE debug_log ("COMMS MAN: Browse: connection_receive_buffer too small, mallocing to %d", new_connection->connection_receive_buffer_size); #endif free_mem (new_connection->connection_receive_buffer); new_connection->connection_receive_buffer = malloc_heap_mem (new_connection->connection_receive_buffer_size); } // // // send_packet (received_id, PACKET_TYPE_SESSION_INFO, new_connection->connection_receive_buffer, new_connection->connection_receive_buffer_size + size, SEND_TYPE_PERSONAL); /* { FILE *test_ptr; test_ptr = fopen ("out.txt", "wb"); fwrite (new_connection->connection_receive_buffer, 1, new_connection->connection_receive_buffer_size + size, test_ptr); fclose (test_ptr); } */ } else { debug_log ("COMM_MAN: not resending query data"); } } break; } case PACKET_TYPE_CONNECTION_VALIDATION: { debug_log ("COMM_MAN: received CONNECTION_VALIDATION, sending RESPONSE"); send_packet (received_id, PACKET_TYPE_CONNECTION_RESPONSE, NULL, 0, SEND_TYPE_PERSONAL); break; } case PACKET_TYPE_CONNECTION_RESPONSE: { connection_list_type *connection; connection = get_connection_list_item (received_id); connection->validation_count = 0; debug_log ("COMM_MAN: received CONNECTION_RESPONSE, connection still alive"); break; } case PACKET_TYPE_SESSION_INFO: { entity *force, *pilot; int client_version_number, server_version_number; int size, x_size, z_size, sector_size, player_count, loop; char *ptr, warzone_ffp_filename [256], temp_campaign_population_filename [256], temp_population_placement_filename [256], temp_side_data_filename [256], buffer [128]; session_data = FALSE; reinitialise_entity_system (); ptr = received_data; size = 0; set_ui_object_redraw (gunships_screen, TRUE); ui_force_update (); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Check both client and server are running same campaign data // client_version_number = get_global_version_number (); server_version_number = get_list_item (ptr, int); size += sizeof (int); if (client_version_number != server_version_number) { debug_fatal ("COMM_MAN: Incorrect version. Server Version No. %d, Client Version No. %d", server_version_number, client_version_number); } // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // map details x_size = get_list_item (ptr, int); z_size = get_list_item (ptr, int); sector_size = get_list_item (ptr, int); size += (sizeof (int) * 3); set_entity_world_map_size (x_size, z_size, sector_size); // data path strncpy (current_session->data_path, ptr, sizeof (current_session->data_path)); ptr += strlen (current_session->data_path) + 1; size += strlen (current_session->data_path) + 1; // population_placement_filename strncpy (temp_population_placement_filename, ptr, sizeof (temp_population_placement_filename)); ptr += strlen (temp_population_placement_filename) + 1; size += strlen (temp_population_placement_filename) + 1; if (population_placement_filename) { free_mem (population_placement_filename); } if (strlen (temp_population_placement_filename) > 0) { population_placement_filename = (char *) malloc_heap_mem (strlen (temp_population_placement_filename) + 1); sprintf (population_placement_filename, "%s", temp_population_placement_filename); } else { population_placement_filename = NULL; } // side_data filename strncpy (temp_side_data_filename, ptr, sizeof (temp_side_data_filename)); ptr += strlen (temp_side_data_filename) + 1; size += strlen (temp_side_data_filename) + 1; if (side_data_filename) { free_mem (side_data_filename); } if (strlen (temp_side_data_filename) > 0) { side_data_filename = (char *) malloc_heap_mem (strlen (temp_side_data_filename) + 1); sprintf (side_data_filename, "%s", temp_side_data_filename); } else { side_data_filename = NULL; } // campaign_population_filename strncpy (temp_campaign_population_filename, ptr, sizeof (temp_campaign_population_filename)); ptr += strlen (temp_campaign_population_filename) + 1; size += strlen (temp_campaign_population_filename) + 1; if (campaign_population_filename) { free_mem (campaign_population_filename); } if (strlen (temp_campaign_population_filename) > 0) { campaign_population_filename = (char *) malloc_heap_mem (strlen (temp_campaign_population_filename) + 1); sprintf (campaign_population_filename, "%s", temp_campaign_population_filename); } else { campaign_population_filename = NULL; } // // // player_count = get_list_item (ptr, int); size += sizeof (int); // // // received_size -= size; #if DEBUG_MODULE debug_log ("COMM_MAN: data path %s population placement filename %s, side data filename %s", current_session->data_path, population_placement_filename, side_data_filename); debug_log ("COMM_MAN: campaign data path = %s", current_session->data_path); #endif // // check we have the correct warzone locally // sprintf (warzone_ffp_filename, "%s\\terrain\\terrain.ffp", current_session->data_path); if (!file_exist (warzone_ffp_filename)) { add_to_pop_up_list_with_word_wrap (get_trans ("UNRECOGNISED_WARZONE"), session_info_list, NULL, 0, UI_FONT_ARIAL_10, sys_col_white); //add_to_pop_up_list (get_trans ("Server using unrecognised warzone"), session_info_list, NULL, 0, UI_FONT_ARIAL_10, sys_col_white); break; } // // // create_local_only_entities (PACK_MODE_BROWSE_SESSION); if (unpack_session (ptr, received_size, PACK_MODE_BROWSE_SESSION)) { debug_fatal ("COMMS MAN: browse: received size overflow"); } #if DEBUG_MODULE if (this_connection->pilot_entity) { debug_log ("COMMS MAN: received SESSION INFO from %s (dpid %d) (setting server id)", get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME), received_id); } else { debug_log ("COMMS MAN: RECEIVED SESSION INFO from %d", received_id); } debug_log ("COMMS MAN: session info: time of day = %f", get_local_entity_float_value (get_session_entity (), FLOAT_TYPE_TIME_OF_DAY)); debug_log ("COMMS MAN: map dimensions %d, %d, sector size %d", x_size, z_size, sector_size); #endif set_ui_object_drawable (session_screen_next_button, TRUE); // // Display game info // ui_object_destroy_list_items (session_info_list); if (get_local_entity_int_value (get_session_entity (), INT_TYPE_CAMPAIGN_REQUIRES_APACHE_HAVOC)) { // campaign requires apache havoc to be installed // check it is... if (!get_global_apache_havoc_installed ()) { add_to_pop_up_list_with_word_wrap (get_trans ("REQUIRES_APACHE_HAVOC"), session_info_list, NULL, 0, UI_FONT_ARIAL_10, sys_col_white); set_ui_object_drawable (session_screen_next_button, FALSE); break; } } loop = 3; sprintf (buffer, "%s : %d", get_trans ("Players"), player_count); add_to_pop_up_list_with_word_wrap (buffer, session_info_list, NULL, 0, UI_FONT_ARIAL_10, sys_col_white); force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (force) { pilot = get_local_entity_first_child (force, LIST_TYPE_PILOT); while (pilot) { { rgb_colour col; sprintf (buffer, "%2d ", loop - 2); strncat (buffer, get_local_entity_string (pilot, STRING_TYPE_PILOTS_NAME), 64); switch (get_local_entity_int_value (pilot, INT_TYPE_SIDE)) { case ENTITY_SIDE_BLUE_FORCE: { col.r = 120; col.g = 158; col.b = 255; col.a = 255; break; } case ENTITY_SIDE_RED_FORCE: { col.r = 255; col.g = 120; col.b = 80; col.a = 255; break; } default: { col = ui_colour_white; break; } } add_to_pop_up_list_with_word_wrap (buffer, session_info_list, NULL, 0, UI_FONT_ARIAL_10, col); loop ++; } pilot = get_local_entity_child_succ (pilot, LIST_TYPE_PILOT); } force = get_local_entity_child_succ (force, LIST_TYPE_FORCE); } set_server_id (received_id); // // destroy all entities created by browse info // reinitialise_entity_system (); break; } case PACKET_TYPE_CLIENT_PILOT_REQUEST: { connection_list_type *new_connection; client_pilot_request_data pilot_data; entity *new_pilot; int index; ASSERT (get_comms_model () == COMMS_MODEL_SERVER); // #if DEBUG_MODULE debug_log ("COMMS MAN: RECEIVED PILOT REQUEST from %d", received_id); // #endif // // unpack name // memcpy (&pilot_data, (client_pilot_request_data *) received_data, sizeof (client_pilot_request_data)); new_pilot = create_new_pilot_entity ( pilot_data.name, pilot_data.side, pilot_data.rank, pilot_data.sub_type, pilot_data.unique_id, pilot_data.difficulty ); ASSERT (new_pilot); index = get_local_entity_safe_index (new_pilot); new_connection = get_connection_list_item (received_id); transmit_entity_comms_message (ENTITY_COMMS_PILOT_REQUEST_ACCEPTED, NULL, received_id, index); new_connection->pilot_entity = new_pilot; break; } case PACKET_TYPE_CLIENT_GUNSHIP_REQUEST: { connection_list_type *new_connection; client_gunship_request_data pilot_data; int index_number, buffer [2]; if (get_comms_model () == COMMS_MODEL_SERVER) { // #if DEBUG_MODULE if (this_connection->pilot_entity) { debug_log ("COMMS MAN: RECEIVED GUNSHIP REQUEST from %s (dpid %d)", get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME), received_id); } else { debug_log ("COMMS MAN: RECEIVED GUNSHIP REQUEST from %d", received_id); } // #endif memcpy (&pilot_data, (client_gunship_request_data *) received_data, sizeof (client_gunship_request_data)); index_number = pilot_data.gunship_index; ASSERT (index_number != ENTITY_INDEX_DONT_CARE); member = get_local_entity_safe_ptr (index_number); if (!member) { // #if DEBUG_MODULE if (this_connection->pilot_entity) { debug_log ("COMMS MAN: REFUSING GUNSHIP FOR PLAYER %s (dpid %d) for helicopter %d", get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME), received_id, pilot_data.gunship_index); } else { debug_log ("COMMS MAN: Refusing gunship for player %d to helicopter %d", received_id, pilot_data.gunship_index); } // #endif send_packet (received_id, PACKET_TYPE_GUNSHIP_REQUEST_REFUSED, NULL, 0, SEND_TYPE_PERSONAL); break; } new_connection = get_connection_list_item (received_id); // // send acceptance // buffer [0] = index_number; // #if DEBUG_MODULE debug_log ("COMMS MAN: sending gunship request accepted for gunship %d pilot id %d", index_number, received_id); // #endif send_packet (received_id, PACKET_TYPE_GUNSHIP_REQUEST_ACCEPTED, (void *) &buffer, 4, SEND_TYPE_PERSONAL); new_connection->gunship_number = pilot_data.gunship_index; new_connection->gunship_entity = member; } break; } case PACKET_TYPE_CLIENT_CAMPAIGN_DATA_REQUEST: { connection_list_type *new_connection; int index_number; if (get_comms_model () == COMMS_MODEL_SERVER) { #if DEBUG_MODULE if (this_connection->pilot_entity) { debug_log ("COMMS MAN: RECEIVED JOIN REQUEST by %s (dpid %d)", get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME), received_id); } else { debug_log ("COMMS MAN: received JOIN REQUEST by %d", received_id); } #endif // // flush group send buffer // send_comms_data (); // // pack mission data into packet // new_connection = get_connection_list_item (received_id); // // Store entity data // while (pack_session (new_connection->connection_receive_buffer, &new_connection->connection_receive_buffer_size, PACK_MODE_CLIENT_SESSION)) { new_connection->connection_receive_buffer_size *= 2; #if DEBUG_MODULE debug_log ("COMMS MAN: Mission data: connection_receive_buffer too small, mallocing to %d", new_connection->connection_receive_buffer_size); #endif free_mem (new_connection->connection_receive_buffer); new_connection->connection_receive_buffer = malloc_heap_mem (new_connection->connection_receive_buffer_size); memset (new_connection->connection_receive_buffer, 0, new_connection->connection_receive_buffer_size); } // add frame id index_number = get_group_frame_id (); memcpy (&new_connection->connection_receive_buffer [new_connection->connection_receive_buffer_size], (void *) &index_number, sizeof (int)); new_connection->connection_receive_buffer_size += sizeof (int); send_packet (received_id, PACKET_TYPE_MISSION_DATA, new_connection->connection_receive_buffer, new_connection->connection_receive_buffer_size, SEND_TYPE_PERSONAL); memset (new_connection->connection_receive_buffer, 0, new_connection->connection_receive_buffer_size); // // send group frame id // SDL_Delay (100); index_number = get_group_frame_id (); //send_packet (received_id, PACKET_TYPE_FRAME_ID, (void *) &index_number, 4, SEND_TYPE_PERSONAL); zero_average_pack_size (); } break; } case PACKET_TYPE_CLIENT_FRAME_ID: { int loop1, loop2, index_number; stub_packet_type *stub_packet; connection_list_type *new_connection; index_number = get_list_item (received_data, int); new_connection = get_connection_list_item (received_id); //#if DEBUG_MODULE if (new_connection) { debug_log ("COMMS MAN: received CLIENT FRAME ID (%d) by %d %s", index_number, received_id, direct_play_get_player_name (received_id)); } //#endif // // send all packets between when the client started to join and when it actually joined. // for (loop1 = index_number; loop1 < get_group_frame_id () - 1; loop1 ++) { //#if DEBUG_MODULE debug_log ("COMMS MAN: sending packet %d frame %d to recently joined client", loop1, 0); //#endif stub_packet = resend_packet (received_id, loop1, 1, SEND_TYPE_GROUP); ASSERT (stub_packet); for (loop2 = 2; loop2 <= stub_packet->packet->number_of_packets; loop2 ++) { //#if DEBUG_MODULE debug_log ("COMMS MAN: sending packet %d frame %d to recently joined client", loop1, loop2); //#endif stub_packet = resend_packet (received_id, loop1, loop2, SEND_TYPE_GROUP); } } break; } case PACKET_TYPE_GUNSHIP_REQUEST_REFUSED: { // #if DEBUG_MODULE debug_log ("COMMS MAN: Gunship refused"); // #endif set_server_response (SERVER_RESPONSE_REFUSE); break; } case PACKET_TYPE_GUNSHIP_REQUEST_ACCEPTED: { entity *gunship; int index_number; // #if DEBUG_MODULE debug_log ("COMMS MAN: received GUNSHIP ACCEPTED by %d", received_id); // #endif // // set gunship // index_number = get_list_item (received_data, int); ASSERT (get_pilot_entity ()); gunship = get_local_entity_safe_ptr (index_number); debug_filtered_log ("COMM_MAN: setting gunship"); planner_event = FALSE; if (get_event_stack_head_function() == ingame_screen_set_events) { pop_event (ingame_screen_set_events); planner_event = TRUE; } assign_entity_to_user (gunship); if (planner_event) { push_event (ingame_screen_set_events, "ingame screen events"); } debug_filtered_log ("COMM_MAN: gunship set"); //////////////////////////////////////////////////////////////////////// break; } case PACKET_TYPE_PILOT_REQUEST_ACCEPTED: { int index_number; ASSERT (get_comms_model () == COMMS_MODEL_CLIENT); // #if DEBUG_MODULE debug_log ("COMMS MAN: received PILOT ACCEPTED by %d", received_id); // #endif index_number = get_list_item (received_data, int); set_pilot_entity (get_local_entity_safe_ptr (index_number)); break; } case PACKET_TYPE_MISSION_DATA: { #if DEBUG_MODULE debug_log ("COMMS MAN: received MISSION DATA by %d", received_id); #endif set_mouse_graphic_off (); // // LOAD TERRAIN DATA // load_3d_terrain_game_data (); initialise_population_name_database (); load_route_data (); // might need to send what route filename to load... // // Initialise stuff // create_local_only_entities (PACK_MODE_CLIENT_SESSION); ///////////////////////////////////////////////////////////////// if (strstr ((char*) stoupper (side_data_filename), "SID")) { read_sector_side_file (side_data_filename); } else if (strstr ((char*) stoupper (side_data_filename), "DAT")) { load_ai_sector_data (side_data_filename); } ///////////////////////////////////////////////////////////////// deinitialise_formation_database (); initialise_formation_database (); deinitialise_formation_component_database (); initialise_formation_component_database (); if (unpack_session (received_data, received_size - 4, PACK_MODE_CLIENT_SESSION)) { debug_fatal ("COMMS MAN: received size overflow"); } /* force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (force) { create_frontline (force); force = get_local_entity_child_succ (force, LIST_TYPE_FORCE); } */ { int index_number; connection_list_type *new_connection; received_data += received_size - 4; index_number = get_list_item (received_data, int); new_connection = get_connection_list_item (received_id); new_connection->receive_group_frame_id = index_number; send_packet (get_server_id (), PACKET_TYPE_CLIENT_FRAME_ID, (void *) &index_number, 4, SEND_TYPE_PERSONAL); } session_data = TRUE; //direct_play_join_group (); set_gunship_waiting_for_connection ( FALSE ); zero_average_pack_size (); set_mouse_graphic_on (); break; } case PACKET_TYPE_FRAME_ID: { int index_number; connection_list_type *new_connection; index_number = get_list_item (received_data, int); #if DEBUG_MODULE debug_log ("COMMS MAN: received FRAME ID (%d) by %d", index_number, received_id); #endif new_connection = get_connection_list_item (received_id); new_connection->receive_group_frame_id = index_number; send_packet (get_server_id (), PACKET_TYPE_CLIENT_FRAME_ID, (void *) &index_number, 4, SEND_TYPE_PERSONAL); break; } /////////////////////////////////////////////////////////////////////////////////////////////// // // In game packets // /////////////////////////////////////////////////////////////////////////////////////////////// case PACKET_TYPE_AI_DATA: { int //padding, data_size; #if DEBUG_MODULE >= 2 debug_log ("COMMS MAN: received AI DATA by %d", received_id); #endif if (get_comms_model () == COMMS_MODEL_CLIENT) { ASSERT (session_data); } data_size = get_list_item (received_data, int); //debug //padding = get_list_item (received_data, int); //end open_unpack_buffer (received_data, received_size); process_received_entity_comms_messages (); ASSERT (!get_unpack_buffer_overflow ()); close_unpack_buffer (); //debug //padding = get_list_item (received_data, int); //end memset (received_data, 0, this_connection->connection_receive_buffer_size); break; } case PACKET_TYPE_END_GAME: { debug_log ("COMMS MAN: received END GAME from %d", received_id); if (get_comms_model () == COMMS_MODEL_SERVER) { if (this_connection->gunship_entity) { set_client_server_entity_int_value (this_connection->gunship_entity, INT_TYPE_PLAYER, ENTITY_PLAYER_AI); } if (this_connection->pilot_entity) { debug_log (" from %s ", get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME)); } unregister_connection (received_id); } else { if (received_id == get_server_id ()) { //setup_campaign_over_screen (get_local_force_entity (get_global_gunship_side ()), CAMPAIGN_RESULT_STALEMATE); start_game_exit (GAME_EXIT_KICKOUT, FALSE); } } receive_flag = FALSE; break; } case PACKET_TYPE_SERVER_REJECTED: { debug_log ("COMMS MAN: received SERVER REJECTED (server id %d)", received_id); //setup_campaign_over_screen (get_local_force_entity (get_global_gunship_side ()), CAMPAIGN_RESULT_SERVER_REJECTED); start_game_exit (GAME_EXIT_KICKOUT, FALSE); break; } default: { debug_fatal ("ERROR: Data Exchange, unknown packet type %d", type); break; } } } send_type --; } } }
void data_exchange (void) { int packet_data_size; connection_data_type *this_connection; this_connection = direct_play_get_connection_data (); if ((this_connection) && (this_connection->is_initialised)) { #if DEBUG_MODULE >= 2 debug_log ("COMMS MAN: Data exchange"); #endif if (get_current_pack_buffer_bit_size () > 0) { transmit_entity_comms_message (ENTITY_COMMS_END, NULL); } ASSERT (!get_pack_buffer_overflow ()); #if DEBUG_MODULE >= 2 debug_log ("COMM_MAN: closing pack buffer line.216"); #endif packet_data_size = close_pack_buffer (); if (packet_data_size > 0) { comms_record_data (tx_pack_buffer, packet_data_size); } #if DEBUG_MODULE >= 2 debug_log ("COMM_MAN: opening pack buffer line.224"); #endif open_pack_buffer (tx_pack_buffer, command_line_comms_pack_buffer_size); // // receive all packets waiting // receive_packets (); #if COMMS_STATS debug_comms_stats (); #endif // // process all data received this frame // comms_process_data (); // // send all data for this frame // comms_send_data (); // // reset the data record for next frame // comms_clear_data_record (); // // check resend list // update_resend_packet_list (command_line_comms_resend_list_size); } }
static void update_server (entity *en) { entity *group; helicopter *raw; int loop; aircraft_damage_types damage_type; raw = get_local_entity_data (en); update_local_entity_view_interest_level (en); update_local_helicopter_rotor_sounds (en); damage_type = aircraft_critically_damaged (en); if (raw->ac.mob.alive) { switch (raw->player) { //////////////////////////////////////// case ENTITY_PLAYER_AI: //////////////////////////////////////// { //////////////////////////////////////// for (loop = 0; loop < get_entity_movement_iterations (); loop ++) { if ((damage_type == AIRCRAFT_DAMAGE_CRITICAL) || (get_local_entity_int_value (en, INT_TYPE_EJECTED))) { helicopter_death_movement (en); } else { if (!get_local_entity_int_value (en, INT_TYPE_LANDED)) { get_3d_terrain_point_data (raw->ac.mob.position.x, raw->ac.mob.position.z, &raw->ac.terrain_info); } helicopter_movement (en); } } // provide resync for AI wingmen group = get_local_entity_parent (en, LIST_TYPE_MEMBER); if (group) { if ((get_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE) != OPERATIONAL_STATE_LANDED) && (get_local_entity_int_value (group, INT_TYPE_MULTIPLAYER_GROUP))) { transmit_entity_comms_message (ENTITY_COMMS_UPDATE, en); } } //////////////////////////////////////// // // ORDER IS CRITICAL // if (raw->ac.mob.alive) { update_rotors (en); update_aircraft_loading_doors (en); update_aircraft_cargo_doors (en); update_aircraft_undercarriage (en); update_aircraft_rudder (en); update_aircraft_target_scan (en); update_aircraft_weapon_system_ready (en); update_entity_weapon_systems (en); update_entity_weapon_system_weapon_and_target_vectors (en); update_aircraft_weapon_fire (en); update_aircraft_decoy_release (en); } // //////////////////////////////////////// break; } //////////////////////////////////////// case ENTITY_PLAYER_LOCAL: //////////////////////////////////////// { ASSERT (en == get_gunship_entity ()); if (raw->invulnerable_timer > 0.0) { raw->invulnerable_timer -= get_delta_time (); } update_current_flight_dynamics_fuel_weight (); update_current_flight_dynamics_flight_time (); //////////////////////////////////////// if ((!get_local_entity_int_value (en, INT_TYPE_AUTO_PILOT)) && (!get_local_entity_int_value (en, INT_TYPE_EJECTED))) { update_flight_dynamics (); update_player_helicopter_waypoint_distance (en); } else { if ((damage_type == AIRCRAFT_DAMAGE_CRITICAL) || (get_local_entity_int_value (en, INT_TYPE_EJECTED)) || (get_local_entity_int_value (en, INT_TYPE_LANDED))) { set_current_flight_dynamics_auto_pilot (FALSE); if (get_local_entity_int_value (en, INT_TYPE_LANDED)) { set_current_flight_dynamics_rotor_brake (TRUE); current_flight_dynamics->input_data.collective.value = 0.0; } } for (loop = 0; loop < get_entity_movement_iterations (); loop ++) { if (get_local_entity_int_value (en, INT_TYPE_EJECTED)) { helicopter_death_movement (en); } else { get_3d_terrain_point_data (raw->ac.mob.position.x, raw->ac.mob.position.z, &raw->ac.terrain_info); helicopter_movement (en); if (get_local_entity_int_value (en, INT_TYPE_AUTO_PILOT)) { set_dynamics_entity_values (en); } } } } //////////////////////////////////////// transmit_entity_comms_message (ENTITY_COMMS_UPDATE, en); //////////////////////////////////////// // // ORDER IS CRITICAL // if (raw->ac.mob.alive) { update_aircraft_loading_doors (en); update_aircraft_cargo_doors (en); update_aircraft_undercarriage (en); update_aircraft_weapon_system_ready (en); update_entity_weapon_systems (en); update_entity_weapon_system_weapon_and_target_vectors (en); update_avionics (); update_cockpits (); update_aircraft_decoy_release (en); } // //////////////////////////////////////// // // Check if gunship has a task - if not then set gunship entity to NULL // if (!get_local_entity_parent (en, LIST_TYPE_FOLLOWER)) { if (!get_local_entity_int_value (en, INT_TYPE_EJECTED)) { if (en == get_gunship_entity ()) { set_gunship_entity (NULL); } } } break; } //////////////////////////////////////// case ENTITY_PLAYER_REMOTE: //////////////////////////////////////// { //////////////////////////////////////// if (raw->invulnerable_timer > 0.0) { raw->invulnerable_timer -= get_delta_time (); } if ((get_local_entity_int_value (en, INT_TYPE_AUTO_PILOT)) || (get_local_entity_int_value (en, INT_TYPE_EJECTED))) { for (loop = 0; loop < get_entity_movement_iterations (); loop ++) { if ((damage_type == AIRCRAFT_DAMAGE_CRITICAL) || (get_local_entity_int_value (en, INT_TYPE_EJECTED))) { helicopter_death_movement (en); } else { if (!get_local_entity_int_value (en, INT_TYPE_LANDED)) { get_3d_terrain_point_data (raw->ac.mob.position.x, raw->ac.mob.position.z, &raw->ac.terrain_info); } helicopter_movement (en); } } #if DEBUG_MODULE debug_log ("HC_UPDT: SERVER: moving client %d using AUTO PILOT", get_local_entity_index (en)); #endif } else { interpolate_entity_position (en); update_player_helicopter_waypoint_distance (en); } //////////////////////////////////////// // // ORDER IS CRITICAL // if (raw->ac.mob.alive) { update_aircraft_loading_doors (en); update_aircraft_cargo_doors (en); update_aircraft_undercarriage (en); update_aircraft_weapon_system_ready (en); update_entity_weapon_systems (en); update_entity_weapon_system_weapon_and_target_vectors (en); } // //////////////////////////////////////// break; } } } else { if (get_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE) == OPERATIONAL_STATE_DEAD) { raw->ac.death_timer -= get_delta_time (); if (raw->ac.death_timer <= 0.0) { if (get_local_entity_int_value (en, INT_TYPE_PLAYER) == ENTITY_PLAYER_AI) { // // don't destroy helicopters while they are still occupied by players (otherwise avionics / pilot-entity etc. don't get deinitialised) // destroy_client_server_entity_family (en); } else { raw->ac.death_timer = 0.0; } } } else { for (loop = 0; loop < get_entity_movement_iterations (); loop ++) { helicopter_death_movement (en); } } } }
static void update_client (entity *en) { helicopter *raw; int loop; aircraft_damage_types damage_type; raw = get_local_entity_data (en); update_local_entity_view_interest_level (en); update_local_helicopter_rotor_sounds (en); damage_type = aircraft_critically_damaged (en); if (raw->ac.mob.alive) { switch (raw->player) { //////////////////////////////////////// case ENTITY_PLAYER_AI: //////////////////////////////////////// { //////////////////////////////////////// for (loop = 0; loop < get_entity_movement_iterations (); loop ++) { if ((damage_type == AIRCRAFT_DAMAGE_CRITICAL) || (get_local_entity_int_value (en, INT_TYPE_EJECTED))) { helicopter_death_movement (en); } else { if (!get_local_entity_int_value (en, INT_TYPE_LANDED)) { get_3d_terrain_point_data (raw->ac.mob.position.x, raw->ac.mob.position.z, &raw->ac.terrain_info); } helicopter_movement (en); } } //////////////////////////////////////// //////////////////////////////////////// // // ORDER IS CRITICAL // if (raw->ac.mob.alive) { update_rotors (en); update_aircraft_loading_doors (en); update_aircraft_cargo_doors (en); update_aircraft_undercarriage (en); update_aircraft_weapon_system_ready (en); update_entity_weapon_systems (en); update_entity_weapon_system_weapon_and_target_vectors (en); } // //////////////////////////////////////// break; } //////////////////////////////////////// case ENTITY_PLAYER_LOCAL: //////////////////////////////////////// { if (en != get_gunship_entity ()) { // // Client might be waiting for server to set old gunship to AI controlled. // return; } if (raw->invulnerable_timer > 0.0) { raw->invulnerable_timer -= get_delta_time (); } update_current_flight_dynamics_fuel_weight (); if ((!fire_continuous_weapon) && (get_local_entity_sound_type_valid (en, weapon_database [raw->ac.selected_weapon].launch_sound_effect_sub_type))) { pause_client_server_continuous_weapon_sound_effect (en, raw->ac.selected_weapon); } //helicopter_death_movement (en); //////////////////////////////////////// if ((!get_local_entity_int_value (en, INT_TYPE_AUTO_PILOT)) && (!get_local_entity_int_value (en, INT_TYPE_EJECTED))) { update_flight_dynamics (); transmit_entity_comms_message (ENTITY_COMMS_UPDATE, en); } else { if (get_local_entity_int_value (en, INT_TYPE_LANDED)) { if (get_local_entity_int_value (en, INT_TYPE_AUTO_PILOT)) { set_current_flight_dynamics_rotor_brake (TRUE); set_current_flight_dynamics_auto_pilot (FALSE); current_flight_dynamics->input_data.collective.value = 0.0; } } if ((damage_type == AIRCRAFT_DAMAGE_CRITICAL) || (get_local_entity_int_value (en, INT_TYPE_EJECTED)) || (get_local_entity_int_value (en, INT_TYPE_LANDED))) { set_current_flight_dynamics_auto_pilot (FALSE); } for (loop = 0; loop < get_entity_movement_iterations (); loop ++) { if ((damage_type == AIRCRAFT_DAMAGE_CRITICAL) || (get_local_entity_int_value (en, INT_TYPE_EJECTED))) { helicopter_death_movement (en); } else { if (!get_local_entity_int_value (en, INT_TYPE_LANDED)) { get_3d_terrain_point_data (raw->ac.mob.position.x, raw->ac.mob.position.z, &raw->ac.terrain_info); } helicopter_movement (en); if (get_local_entity_int_value (en, INT_TYPE_AUTO_PILOT)) { set_dynamics_entity_values (get_gunship_entity ()); } } } } //////////////////////////////////////// // // ORDER IS CRITICAL // if (raw->ac.mob.alive) { update_aircraft_loading_doors (en); update_aircraft_cargo_doors (en); update_aircraft_undercarriage (en); update_aircraft_weapon_system_ready (en); update_entity_weapon_systems (en); update_entity_weapon_system_weapon_and_target_vectors (en); update_avionics (); update_cockpits (); update_aircraft_decoy_release (en); } // //////////////////////////////////////// // // Check if gunship has a task - if not then set gunship entity to NULL // if (!get_local_entity_parent (en, LIST_TYPE_FOLLOWER)) { if (!get_local_entity_int_value (en, INT_TYPE_EJECTED)) { if (en == get_gunship_entity ()) { set_gunship_entity (NULL); } } } break; } //////////////////////////////////////// case ENTITY_PLAYER_REMOTE: //////////////////////////////////////// { //////////////////////////////////////// // // ORDER IS CRITICAL // if (raw->ac.mob.alive) { update_aircraft_loading_doors (en); update_aircraft_cargo_doors (en); update_aircraft_undercarriage (en); update_aircraft_weapon_system_ready (en); update_entity_weapon_systems (en); update_entity_weapon_system_weapon_and_target_vectors (en); } if ((get_local_entity_int_value (en, INT_TYPE_AUTO_PILOT)) || (get_local_entity_int_value (en, INT_TYPE_EJECTED))) { for (loop = 0; loop < get_entity_movement_iterations (); loop ++) { // no need for death_movement as if the remote_player is damaged it will default back to manual flight. if (get_local_entity_int_value (en, INT_TYPE_EJECTED)) { helicopter_death_movement (en); } else { if (!get_local_entity_int_value (en, INT_TYPE_LANDED)) { get_3d_terrain_point_data (raw->ac.mob.position.x, raw->ac.mob.position.z, &raw->ac.terrain_info); } helicopter_movement (en); } } } else { interpolate_entity_position (en); } // //////////////////////////////////////// break; } } } else { if (get_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE) == OPERATIONAL_STATE_DEAD) { } else { for (loop = 0; loop < get_entity_movement_iterations (); loop ++) { helicopter_death_movement (en); } } } }
void update_vector_altitude_dynamics (void) { static float last_ground_height = 0; matrix3x3 attitude; float heading, pitch, roll, ground_height, centre_of_gravity_to_ground_distance; vec3d position, *face_normal; centre_of_gravity_to_ground_distance = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_CENTRE_OF_GRAVITY_TO_GROUND_DISTANCE); get_local_entity_attitude_matrix (get_gunship_entity (), attitude); ground_height = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_TERRAIN_ELEVATION); // // debug // if ((ground_height < -1000) || (ground_height > 32000)) { debug_log ("!!!!!!!!!!!!!! GROUND HEIGHT %f", ground_height); ground_height = last_ground_height; } // // end // last_ground_height = ground_height; current_flight_dynamics->altitude.value = current_flight_dynamics->position.y; current_flight_dynamics->altitude.min = ground_height; switch (get_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE)) { case OPERATIONAL_STATE_LANDED: { if (current_flight_dynamics->world_velocity_y.value > 0.0) { #if DEBUG_DYNAMICS debug_log ("VECTOR DYN: takeoff !"); #endif set_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_NAVIGATING); delete_local_entity_from_parents_child_list (get_gunship_entity (), LIST_TYPE_CURRENT_WAYPOINT); transmit_entity_comms_message (ENTITY_COMMS_MOBILE_TAKEOFF, get_gunship_entity ()); } else { entity *wp; vec3d wp_pos; wp = get_local_entity_parent (get_gunship_entity (), LIST_TYPE_CURRENT_WAYPOINT); if (wp) { get_local_waypoint_formation_position (get_local_entity_int_value (get_gunship_entity (), INT_TYPE_FORMATION_POSITION), wp, &wp_pos); ground_height = wp_pos.y; } current_flight_dynamics->world_velocity_y.value = max (current_flight_dynamics->world_velocity_y.value, 0.0); current_flight_dynamics->velocity_y.value = max (current_flight_dynamics->velocity_y.value, 0.0); memset (¤t_flight_dynamics->world_motion_vector, 0, sizeof (vec3d)); current_flight_dynamics->velocity_x.value = bound (current_flight_dynamics->velocity_x.value, knots_to_metres_per_second (-10), knots_to_metres_per_second (50)); current_flight_dynamics->velocity_y.value = 0; current_flight_dynamics->velocity_z.value = bound (current_flight_dynamics->velocity_z.value, knots_to_metres_per_second (-10), knots_to_metres_per_second (50)); current_flight_dynamics->position.y = ground_height + centre_of_gravity_to_ground_distance; current_flight_dynamics->altitude.value = ground_height + centre_of_gravity_to_ground_distance; heading = get_heading_from_attitude_matrix (attitude); //get_3d_terrain_face_normal (&n, current_flight_dynamics->position.x, current_flight_dynamics->position.z); face_normal = get_local_entity_ptr_value (get_gunship_entity (), PTR_TYPE_TERRAIN_FACE_NORMAL); get_3d_transformation_matrix_from_face_normal_and_heading (attitude, face_normal, heading); pitch = get_pitch_from_attitude_matrix (attitude); pitch += rad (aircraft_database [ENTITY_SUB_TYPE_AIRCRAFT_AH64D_APACHE_LONGBOW].fuselage_angle); roll = get_roll_from_attitude_matrix (attitude); get_3d_transformation_matrix (attitude, heading, pitch, roll); position.x = current_flight_dynamics->position.x; position.y = current_flight_dynamics->position.y; position.z = current_flight_dynamics->position.z; set_local_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &position); set_local_entity_attitude_matrix (get_gunship_entity (), attitude); } break; } default: { if (current_flight_dynamics->world_velocity_y.value < 0.0) { if (current_flight_dynamics->altitude.value < current_flight_dynamics->altitude.min + centre_of_gravity_to_ground_distance) { if (get_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE) != OPERATIONAL_STATE_LANDED) { // // need to find what wp the user is trying to land on .... // //entity //*wp; #if DEBUG_DYNAMICS debug_log ("VECTOR DYN: landed !"); #endif set_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_LANDED); //transmit_entity_comms_message (ENTITY_COMMS_MOBILE_LAND, get_gunship_entity (), wp); } } } break; } } current_flight_dynamics->altitude.value = bound ( current_flight_dynamics->altitude.value, current_flight_dynamics->altitude.min, current_flight_dynamics->altitude.max); }
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; } }
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)); } } } } }