static void select_cannon_event (event *ev) { if (get_local_entity_weapon_available (get_gunship_entity (), ENTITY_SUB_TYPE_WEAPON_2A42_30MM_HE_ROUND)) { set_gunship_weapon (ENTITY_SUB_TYPE_WEAPON_2A42_30MM_HE_ROUND); } else if (get_local_entity_weapon_available (get_gunship_entity (), ENTITY_SUB_TYPE_WEAPON_2A42_30MM_AP_ROUND)) { set_gunship_weapon (ENTITY_SUB_TYPE_WEAPON_2A42_30MM_AP_ROUND); } }
void set_kiowa_weapon_damage_status (void) { entity *en; entity_sub_types weapon_sub_type; en = get_gunship_entity (); set_client_server_entity_weapon_damage (en, KIOWA_LHS_PYLON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, kiowa_damage.lh_pylon); set_client_server_entity_weapon_damage (en, KIOWA_RHS_PYLON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, kiowa_damage.rh_pylon); set_client_server_entity_weapon_damage (en, KIOWA_CHAFF_DISPENSER, ENTITY_SUB_TYPE_WEAPON_CHAFF, kiowa_damage.chaff_dispenser); set_client_server_entity_weapon_damage (en, KIOWA_FLARE_DISPENSER, ENTITY_SUB_TYPE_WEAPON_FLARE, kiowa_damage.flare_dispenser); // // check if selected weapon is still available, if not, select next // weapon_sub_type = get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON); if (weapon_sub_type != ENTITY_SUB_TYPE_WEAPON_NO_WEAPON) { if (!get_local_entity_weapon_available (en, weapon_sub_type)) { weapon_sub_type = get_next_available_weapon_sub_type (en); set_gunship_weapon (weapon_sub_type); } } }
void set_ka50_weapon_damage_status (void) { entity *en; entity_sub_types weapon_sub_type; en = get_gunship_entity (); set_client_server_entity_weapon_damage (en, KA50_CANNON_TURRET, ENTITY_SUB_TYPE_WEAPON_2A42_30MM_HE_ROUND, ka50_damage.gun_jammed); set_client_server_entity_weapon_damage (en, KA50_CANNON_TURRET, ENTITY_SUB_TYPE_WEAPON_2A42_30MM_AP_ROUND, ka50_damage.gun_jammed); set_client_server_entity_weapon_damage (en, KA50_LHS_OUTER_PYLON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, ka50_damage.lh_outer_pylon); set_client_server_entity_weapon_damage (en, KA50_LHS_INNER_PYLON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, ka50_damage.lh_inner_pylon); set_client_server_entity_weapon_damage (en, KA50_RHS_OUTER_PYLON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, ka50_damage.rh_outer_pylon); set_client_server_entity_weapon_damage (en, KA50_RHS_INNER_PYLON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, ka50_damage.rh_inner_pylon); set_client_server_entity_weapon_damage (en, KA50_LHS_CHAFF_DISPENSER, ENTITY_SUB_TYPE_WEAPON_CHAFF, ka50_damage.lh_chaff_dispensers); set_client_server_entity_weapon_damage (en, KA50_RHS_CHAFF_DISPENSER, ENTITY_SUB_TYPE_WEAPON_CHAFF, ka50_damage.rh_chaff_dispensers); set_client_server_entity_weapon_damage (en, KA50_LHS_FLARE_DISPENSER, ENTITY_SUB_TYPE_WEAPON_FLARE, ka50_damage.lh_flare_dispensers); set_client_server_entity_weapon_damage (en, KA50_RHS_FLARE_DISPENSER, ENTITY_SUB_TYPE_WEAPON_FLARE, ka50_damage.rh_flare_dispensers); // // check if selected weapon is still available, if not, select next // weapon_sub_type = get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON); if (weapon_sub_type != ENTITY_SUB_TYPE_WEAPON_NO_WEAPON) { if (!get_local_entity_weapon_available (en, weapon_sub_type)) { weapon_sub_type = get_next_available_weapon_sub_type (en); set_gunship_weapon (weapon_sub_type); } } }
void set_apache_weapon_damage_status (void) { entity *en; entity_sub_types weapon_sub_type; en = get_gunship_entity (); set_client_server_entity_weapon_damage (en, APACHE_CHAIN_GUN_TURRET, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, apache_damage.gun_jammed); set_client_server_entity_weapon_damage (en, APACHE_LHS_WING_TIP_MOUNT, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, apache_damage.lh_wing_tip_mount); set_client_server_entity_weapon_damage (en, APACHE_LHS_OUTER_PYLON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, apache_damage.lh_outer_pylon); set_client_server_entity_weapon_damage (en, APACHE_LHS_INNER_PYLON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, apache_damage.lh_inner_pylon); set_client_server_entity_weapon_damage (en, APACHE_RHS_WING_TIP_MOUNT, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, apache_damage.rh_wing_tip_mount); set_client_server_entity_weapon_damage (en, APACHE_RHS_OUTER_PYLON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, apache_damage.rh_outer_pylon); set_client_server_entity_weapon_damage (en, APACHE_RHS_INNER_PYLON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, apache_damage.rh_inner_pylon); set_client_server_entity_weapon_damage (en, APACHE_CHAFF_DISPENSER, ENTITY_SUB_TYPE_WEAPON_CHAFF, apache_damage.chaff_dispenser); set_client_server_entity_weapon_damage (en, APACHE_FLARE_DISPENSER, ENTITY_SUB_TYPE_WEAPON_FLARE, apache_damage.flare_dispenser); // // check if selected weapon is still available, if not, select next // weapon_sub_type = get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON); if (weapon_sub_type != ENTITY_SUB_TYPE_WEAPON_NO_WEAPON) { if (!get_local_entity_weapon_available (en, weapon_sub_type)) { weapon_sub_type = get_next_available_weapon_sub_type (en); set_gunship_weapon (weapon_sub_type); } } }
void update_aircraft_decoy_release (entity *en) { aircraft *raw; int chaff_available, flare_available, chaff_released, flare_released; float range, velocity, time_to_impact; entity_sub_types weapon_sub_type; entity *persuer; vec3d *target_position, *weapon_position; ASSERT (en); #ifdef DEBUG if (get_comms_model () == COMMS_MODEL_CLIENT) { ASSERT (en == get_gunship_entity ()); } #endif raw = get_local_entity_data (en); //////////////////////////////////////// // // update timer // //////////////////////////////////////// raw->decoy_release_timer -= get_delta_time (); if (raw->decoy_release_timer >= 0.0) { return; } raw->decoy_release_timer = 2.0 + frand1 (); //////////////////////////////////////// // // validate // //////////////////////////////////////// if (en == get_gunship_entity ()) { if (!get_global_auto_counter_measures ()) { return; } } else if (get_local_entity_int_value (en, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI) { return; } if (!get_local_entity_int_value (en, INT_TYPE_AIRBORNE_AIRCRAFT)) { return; } persuer = get_local_entity_first_child (en, LIST_TYPE_TARGET); if (!persuer) { return; } chaff_available = get_local_entity_weapon_available (en, ENTITY_SUB_TYPE_WEAPON_CHAFF); flare_available = get_local_entity_weapon_available (en, ENTITY_SUB_TYPE_WEAPON_FLARE); if (!(chaff_available || flare_available)) { return; } //////////////////////////////////////// // // check all persuers // //////////////////////////////////////// target_position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); chaff_released = FALSE; flare_released = FALSE; while (persuer) { if (get_local_entity_type (persuer) == ENTITY_TYPE_WEAPON) { if (get_local_entity_int_value (persuer, INT_TYPE_WEAPON_GUIDANCE_TYPE) != WEAPON_GUIDANCE_TYPE_NONE) { weapon_sub_type = get_decoy_type_for_weapon (persuer); if (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_CHAFF) { if (chaff_available) { if (!chaff_released) { weapon_position = get_local_entity_vec3d_ptr (persuer, VEC3D_TYPE_POSITION); range = get_approx_3d_range (weapon_position, target_position); velocity = get_local_entity_float_value (persuer, FLOAT_TYPE_VELOCITY); time_to_impact = range / max (velocity, 1.0); if (time_to_impact < 10.0) { launch_client_server_weapon (en, ENTITY_SUB_TYPE_WEAPON_CHAFF); chaff_released = TRUE; if (flare_released) { break; } } } } } else if (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_FLARE) { if (flare_available) { if (!flare_released) { weapon_position = get_local_entity_vec3d_ptr (persuer, VEC3D_TYPE_POSITION); range = get_approx_3d_range (weapon_position, target_position); velocity = get_local_entity_float_value (persuer, FLOAT_TYPE_VELOCITY); time_to_impact = range / max (velocity, 1.0); if (time_to_impact < 10.0) { launch_client_server_weapon (en, ENTITY_SUB_TYPE_WEAPON_FLARE); flare_released = TRUE; if (chaff_released) { break; } } } } } } } persuer = get_local_entity_child_succ (persuer, LIST_TYPE_TARGET); } }
void set_default_weapon_damage_status (void) { entity *en; entity_sub_types weapon_sub_type; en = get_gunship_entity (); switch (get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE)) { case ENTITY_SUB_TYPE_AIRCRAFT_AH1T_SEACOBRA: case ENTITY_SUB_TYPE_AIRCRAFT_AH1W_SUPERCOBRA: { set_client_server_entity_weapon_damage (en, COBRA_CANNON_TURRET, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, default_damage.gun_jammed); //set_client_server_entity_weapon_damage (en, APACHE_LHS_WING_TIP_MOUNT, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, default_damage.lh_wing_tip_mount); set_client_server_entity_weapon_damage (en, COBRA_LHS_OUTER_PYLON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, default_damage.lh_outer_pylon); set_client_server_entity_weapon_damage (en, COBRA_LHS_INNER_PYLON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, default_damage.lh_inner_pylon); //set_client_server_entity_weapon_damage (en, APACHE_RHS_WING_TIP_MOUNT, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, default_damage.rh_wing_tip_mount); set_client_server_entity_weapon_damage (en, COBRA_RHS_OUTER_PYLON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, default_damage.rh_outer_pylon); set_client_server_entity_weapon_damage (en, COBRA_RHS_INNER_PYLON, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, default_damage.rh_inner_pylon); set_client_server_entity_weapon_damage (en, COBRA_LHS_CHAFF_DISPENSER, ENTITY_SUB_TYPE_WEAPON_CHAFF, default_damage.chaff_dispenser); set_client_server_entity_weapon_damage (en, COBRA_LHS_FLARE_DISPENSER, ENTITY_SUB_TYPE_WEAPON_FLARE, default_damage.flare_dispenser); } case ENTITY_SUB_TYPE_AIRCRAFT_KA29_HELIX_B: { //set_client_server_entity_weapon_damage (en, COBRA_CANNON_TURRET, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, default_damage.gun_jammed); //set_client_server_entity_weapon_damage (en, APACHE_LHS_WING_TIP_MOUNT, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, default_damage.lh_wing_tip_mount); set_client_server_entity_weapon_damage (en, 2, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, default_damage.lh_outer_pylon); set_client_server_entity_weapon_damage (en, 0, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, default_damage.lh_inner_pylon); //set_client_server_entity_weapon_damage (en, APACHE_RHS_WING_TIP_MOUNT, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, default_damage.rh_wing_tip_mount); set_client_server_entity_weapon_damage (en, 3, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, default_damage.rh_outer_pylon); set_client_server_entity_weapon_damage (en, 1, ENTITY_SUB_TYPE_WEAPON_NO_WEAPON, default_damage.rh_inner_pylon); set_client_server_entity_weapon_damage (en, HELIX_CHAFF_DISPENSER, ENTITY_SUB_TYPE_WEAPON_CHAFF, default_damage.chaff_dispenser); set_client_server_entity_weapon_damage (en, HELIX_FLARE_DISPENSER, ENTITY_SUB_TYPE_WEAPON_FLARE, default_damage.flare_dispenser); } } // // check if selected weapon is still available, if not, select next // weapon_sub_type = get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON); if (weapon_sub_type != ENTITY_SUB_TYPE_WEAPON_NO_WEAPON) { if (!get_local_entity_weapon_available (en, weapon_sub_type)) { weapon_sub_type = get_next_available_weapon_sub_type (en); set_gunship_weapon (weapon_sub_type); } } }
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); } } }