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 *create_client_server_entity_routed_vehicle (int index, entity_sub_types sub_type, entity *group, vec3d *position) { entity *new_entity; sound_sample_indices sample_index; ASSERT (get_comms_model() == COMMS_MODEL_SERVER); // // create routed entity // new_entity = create_client_server_entity ( ENTITY_TYPE_ROUTED_VEHICLE, index, ENTITY_ATTR_PARENT (LIST_TYPE_MEMBER, group), ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, sub_type), ENTITY_ATTR_VEC3D (VEC3D_TYPE_POSITION, position->x, position->y, position->z), ENTITY_ATTR_END ); // // create and attach special effects // { // // dust trails // attach_routed_vehicle_meta_smoke_lists (new_entity); // // headlights // set_vehicle_headlight_state (new_entity, OFF); // // sound effects // sample_index = vehicle_database [sub_type].idle_sound_effect; if (sample_index != SOUND_SAMPLE_INDEX_NONE) { create_client_server_sound_effect_entity ( new_entity, ENTITY_SIDE_NEUTRAL, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1, SOUND_CHANNEL_SOUND_EFFECT, SOUND_LOCALITY_ALL, NULL, // position 1.0, // amplification TRUE, // valid sound effect TRUE, // looping 1, // sample count &sample_index // sample index list ); } sample_index = vehicle_database [sub_type].moving_sound_effect; if (sample_index != SOUND_SAMPLE_INDEX_NONE) { create_client_server_sound_effect_entity ( new_entity, ENTITY_SIDE_NEUTRAL, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING2, SOUND_CHANNEL_SOUND_EFFECT, SOUND_LOCALITY_ALL, NULL, // position 1.0, // amplification FALSE, // valid sound effect TRUE, // looping 1, // sample count &sample_index // sample index list ); } } // // // return new_entity; }
static void set_local_int_value (entity *en, int_types type, int value) { vehicle *raw; #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_INT_VALUE, en, type, value); #endif raw = (vehicle *) get_local_entity_data (en); switch (type) { //////////////////////////////////////// case INT_TYPE_CPG_IDENTIFIED: //////////////////////////////////////// { raw->cpg_identified = value; break; } //////////////////////////////////////// case INT_TYPE_DAMAGE_LEVEL: //////////////////////////////////////// { raw->damage_level = value; break; } //////////////////////////////////////// case INT_TYPE_FORMATION_POSITION: //////////////////////////////////////// { raw->formation_position = value; break; } //////////////////////////////////////// case INT_TYPE_GROUP_MEMBER_NUMBER: //////////////////////////////////////// { ASSERT (value >= 0); ASSERT (value < (1 << NUM_GROUP_MEMBER_NUMBER_BITS)); raw->group_member_number = value; break; } //////////////////////////////////////// case INT_TYPE_GUNSHIP_RADAR_LOS_CLEAR: //////////////////////////////////////// { raw->gunship_radar_los_clear = value; break; } //////////////////////////////////////// case INT_TYPE_ID_NUMBER: //////////////////////////////////////// { raw->id_number = value; break; } //////////////////////////////////////// case INT_TYPE_ID_NUMBER_SIGNIFICANT_DIGITS: //////////////////////////////////////// { raw->id_number_significant_digits = value; break; } //////////////////////////////////////// case INT_TYPE_LIGHTS_ON: //////////////////////////////////////// { raw->lights_on = value; break; } //////////////////////////////////////// case INT_TYPE_LOS_TO_TARGET: //////////////////////////////////////// { raw->los_to_target = value; break; } //////////////////////////////////////// case INT_TYPE_OBJECT_3D_SHAPE: //////////////////////////////////////// { raw->object_3d_shape = value; break; } //////////////////////////////////////// case INT_TYPE_OPERATIONAL_STATE: //////////////////////////////////////// { int state1, state2; day_segment_types day_segment_type; state1 = get_local_entity_int_value (en, INT_TYPE_MOBILE_MOVING); raw->operational_state = value; state2 = get_local_entity_int_value (en, INT_TYPE_MOBILE_MOVING); if ((state1 == FALSE) && (state2 == TRUE)) { // // wasn't moving, but is now // // vehicle wakes set_infinite_smoke_list_generating_state (en, ENTITY_SUB_TYPE_EFFECT_SMOKE_LIST_VEHICLE_WAKE, INFINITE_SMOKE_ON); // lights day_segment_type = (day_segment_types) get_local_entity_int_value (get_session_entity (), INT_TYPE_DAY_SEGMENT_TYPE); if ((day_segment_type == DAY_SEGMENT_TYPE_NIGHT) || (day_segment_type == DAY_SEGMENT_TYPE_DUSK)) { set_vehicle_headlight_state (en, ON); } // weapons if (get_comms_model () == COMMS_MODEL_SERVER) { set_client_server_entity_int_value (en, INT_TYPE_SELECTED_WEAPON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON); } // sound effects pause_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1, 0.5); resume_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING2); } else if ((state1 == TRUE) && (state2 == FALSE)) { // // was moving, but isn't anymore // set_infinite_smoke_list_generating_state (en, ENTITY_SUB_TYPE_EFFECT_SMOKE_LIST_VEHICLE_WAKE, INFINITE_SMOKE_OFF); set_vehicle_headlight_state (en, OFF); pause_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING2, 0.5); resume_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1); } break; } //////////////////////////////////////// case INT_TYPE_SELECTED_WEAPON: //////////////////////////////////////// { // // stop continuous sound effect // if (raw->selected_weapon != value) { pause_local_continuous_weapon_sound_effect (en, raw->selected_weapon); } raw->selected_weapon = value; raw->weapon_burst_timer = 0.0; break; } //////////////////////////////////////// case INT_TYPE_SELECTED_WEAPON_SYSTEM_READY: //////////////////////////////////////// { raw->selected_weapon_system_ready = value; break; } //////////////////////////////////////// case INT_TYPE_WEAPON_AND_TARGET_VECTORS_VALID: //////////////////////////////////////// { raw->weapon_and_target_vectors_valid = value; break; } //////////////////////////////////////// case INT_TYPE_WEAPON_CONFIG_TYPE: //////////////////////////////////////// { raw->weapon_config_type = (weapon_config_types) value; load_local_entity_weapon_config (en); break; } //////////////////////////////////////// default: //////////////////////////////////////// { debug_fatal_invalid_int_type (en, type); break; } } }