static int response_to_articulate_undercarriage (entity_messages message, entity *receiver, entity *sender, va_list pargs) { vec3d *position; object_3d_instance *inst3d; sound_sample_indices sample_index; #if DEBUG_MODULE //debug_log_entity_message (message, receiver, sender, pargs); #endif ASSERT (get_comms_model () == COMMS_MODEL_SERVER); inst3d = (object_3d_instance *) get_local_entity_ptr_value (receiver, PTR_TYPE_INSTANCE_3D_OBJECT); if (inst3d) { if (object_contains_sub_object_type (inst3d, OBJECT_3D_SUB_OBJECT_UNDERCARRIAGE, 0, NULL)) { position = get_local_entity_vec3d_ptr (receiver, VEC3D_TYPE_POSITION); sample_index = SOUND_SAMPLE_INDEX_UNDERCARRIAGE; create_client_server_sound_effect_entity ( receiver, ENTITY_SIDE_NEUTRAL, ENTITY_SUB_TYPE_EFFECT_SOUND_MISC, SOUND_CHANNEL_SOUND_EFFECT, SOUND_LOCALITY_ALL, NULL, // position 1.0, // amplification 1.0, // Werewolf pitch TRUE, // valid sound effect FALSE, // looping 1, // sample count &sample_index // sample index list ); } } return (TRUE); }
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; }
void update_lightning_effect (entity *en) { session *raw; int lightning_flag = FALSE; float new_time; ASSERT (en); raw = (session *) get_local_entity_data (en); if (get_comms_model () == COMMS_MODEL_SERVER) { // // SERVER : decrease timer, if timer reaches zero create a strike, and reset timer (c/s) // raw->lightning_timer -= get_delta_time (); if (raw->lightning_timer <= 0.0) { lightning_flag = TRUE; new_time = LIGHTNING_EFFECT_MINIMUM_TIMER + ((LIGHTNING_EFFECT_MAXIMUM_TIMER - LIGHTNING_EFFECT_MINIMUM_TIMER) * frand1 ()); #if DEBUG_MODULES debug_log ("SS_UPDT : Set lightning timer %.2f", new_time); #endif set_client_server_entity_float_value (en, FLOAT_TYPE_LIGHTNING_TIMER, new_time); } } else { // // CLIENT : decrease timer only if non-zero and create strike if zero reached ( new timer will be set by server ) // if (raw->lightning_timer > 0.0) { raw->lightning_timer -= get_delta_time (); if (raw->lightning_timer <= 0.0) { lightning_flag = TRUE; raw->lightning_timer = 0.0; } } } if (lightning_flag) { // // create lightning // env_3d *current_3d_env; current_3d_env = get_3d_active_environment (); if (current_3d_env == main_3d_env) { current_3d_env = NULL; } else { set_3d_active_environment (main_3d_env); } add_3d_lightning_strike (LIGHTNING_TYPE_CLOUD_BURST, 0.3, raw->weather_position.x, raw->weather_position.z); add_3d_lightning_strike (LIGHTNING_TYPE_FORKED_1, 0.3, raw->weather_position.x, raw->weather_position.z); if (current_3d_env) { set_3d_active_environment (current_3d_env); } if (get_comms_model () == COMMS_MODEL_SERVER) { sound_sample_indices sound_effect_index; // // lightning sound effect // sound_effect_index = SOUND_SAMPLE_INDEX_AMBIENT_LIGHTNING; create_client_server_sound_effect_entity ( get_local_sector_entity (&(raw->weather_position)), ENTITY_SIDE_NEUTRAL, ENTITY_SUB_TYPE_EFFECT_SOUND_MISC, SOUND_CHANNEL_SOUND_EFFECT, SOUND_LOCALITY_ALL, &raw->weather_position, // position 1.0, // amplification 0.85+(0.3* frand1 ()), //pitch TRUE, // valid sound effect FALSE, // looping 1, // sample count &sound_effect_index // sample index list ); // // thunder sound effect // sound_effect_index = SOUND_SAMPLE_INDEX_AMBIENT_THUNDER; create_client_server_sound_effect_entity ( get_local_sector_entity (&(raw->weather_position)), ENTITY_SIDE_NEUTRAL, ENTITY_SUB_TYPE_EFFECT_SOUND_MISC, SOUND_CHANNEL_SOUND_EFFECT, SOUND_LOCALITY_ALL, &raw->weather_position, // position 1.0, // amplification 0.85+(0.3* frand1 ()), //pitch TRUE, // valid sound effect FALSE, // looping 1, // sample count &sound_effect_index // sample index list ); } } }
static void kill_local (entity *en) { int losses; entity *task, *group, *destroy_task; fixed_wing *raw; //////////////////////////////////////// // // PRE-AMBLE // //////////////////////////////////////// #if DEBUG_MODULE >= 2 debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en); #endif if (!get_local_entity_int_value (en, INT_TYPE_ALIVE)) { return; } raw = (fixed_wing *) get_local_entity_data (en); group = get_local_entity_parent (en, LIST_TYPE_MEMBER); ASSERT (group); // // update force info // remove_from_force_info (get_local_force_entity ((entity_sides) raw->ac.mob.side), en); if (tacview_is_logging()) write_tacview_unit_event(en, TACVIEW_UNIT_DESTROYED, NULL); //////////////////////////////////////// // // VALIDATE // //////////////////////////////////////// //////////////////////////////////////// // // SEND NOTIFY MESSAGES // //////////////////////////////////////// if (get_comms_model () == COMMS_MODEL_SERVER) { // notify regen of kill add_entity_to_regen_queue ( (entity_sides) get_local_entity_int_value(en, INT_TYPE_SIDE), get_local_entity_type(en), get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE), get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE) ); task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT); while (task) { destroy_task = task; task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT); if (destroy_task->type == ENTITY_TYPE_TASK) { #if DEBUG_MODULE debug_log ("FW_DSTRY: killing fixed wing, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]); #endif notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE); } } // // Release landing lock (if any) // release_mobile_entity_landing_locks (en); } //////////////////////////////////////// // // UNLINK FROM SYSTEM // //////////////////////////////////////// // // fixed_wing // // // aircraft // // aircrew_root unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT); // unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON); delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER); delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER); // gunship_target_link // member_link // view_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE); // // mobile // // // kill weapon sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN); // // kill engine sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING2); // // Kill speech // notify_speech_buffers_entity_killed (en); // special_effect root unlink_local_entity_children (en, LIST_TYPE_TARGET); delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK); // sector_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET); // update_link set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DYING); // // death timer (set time after which entity is totally destroyed) // set_local_entity_float_value (en, FLOAT_TYPE_DEATH_TIMER, calculate_mobile_death_timer_value (en)); //////////////////////////////////////// // // KILL // //////////////////////////////////////// damage_fixed_wing_3d_object (en); // must be done before alive flag set to FALSE remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en); set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE); // // group losses // losses = get_local_entity_int_value (group, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (group, INT_TYPE_LOSSES, losses); // // task losses // task = get_local_group_primary_task (group); if (task) { losses = get_local_entity_int_value (task, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (task, INT_TYPE_LOSSES, losses); } // // Notify Campaign Screen // notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group); // // Notify the GROUP that the mobile has been killed (N.B. must be done AFTER mobile is unlinked from member list) // if (get_comms_model () == COMMS_MODEL_SERVER) { notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en); } //////////////////////////////////////// // // SPECIAL EFFECTS // //////////////////////////////////////// set_local_fixed_wing_afterburner_state (en, OFF); fixed_wing_impact_movement (en); if (get_comms_model () == COMMS_MODEL_SERVER) { vec3d *position; sound_sample_indices sound_sample_index; create_client_server_object_killed_explosion_effect (en); position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); sound_sample_index = SOUND_SAMPLE_INDEX_SHOT_DOWN_AIRCRAFT; create_client_server_sound_effect_entity ( en, ENTITY_SIDE_NEUTRAL, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1, SOUND_CHANNEL_SOUND_EFFECT, SOUND_LOCALITY_ALL, NULL, // position 1.0, // amplification 1.0, // Werewolf pitch TRUE, // valid sound effect TRUE, // looping 1, // sample count &sound_sample_index // sample index list ); } #if LANDING_ROUTE_CHECK destroy_debug_entity_landing_route_check (en); #endif ///////////////////////////////////////////////////////////////// // // SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED // ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////////////// }
static void kill_local (entity *en) { int losses; helicopter *raw; entity *task, *group, *member, *destroy_task; //////////////////////////////////////// // // PRE-AMBLE // //////////////////////////////////////// #if DEBUG_MODULE >= 2 debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en); #endif if (!get_local_entity_int_value (en, INT_TYPE_ALIVE)) { return; } raw = get_local_entity_data (en); group = get_local_entity_parent (en, LIST_TYPE_MEMBER); ASSERT (group); // // update force info // remove_from_force_info (get_local_force_entity (raw->ac.mob.side), en); if (en == get_gunship_entity ()) { // // Award Points for mission // task = get_local_entity_primary_task (en); if (task) { if (get_local_entity_int_value (task, INT_TYPE_TASK_STATE) == TASK_STATE_COMPLETED) { // // Only award points for COMPLETE missions (also means player can't rejoin that mission and get points again) // notify_gunship_entity_mission_terminated (en, task); } } } //////////////////////////////////////// // // VALIDATE // //////////////////////////////////////// //////////////////////////////////////// // // DESTROY COMPONENTS // //////////////////////////////////////// #if DEBUG_MODULE debug_log ("HC_DSTRY: killing helicopter %s", entity_sub_type_aircraft_names [raw->ac.mob.sub_type]); #endif if (get_comms_model () == COMMS_MODEL_SERVER) { // notify regen of kill add_entity_to_regen_queue ( get_local_entity_int_value(en, INT_TYPE_SIDE), get_local_entity_type(en), get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE), get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE) ); // // notify task dependents // task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT); while (task) { destroy_task = task; task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT); if (destroy_task->type == ENTITY_TYPE_TASK) { #if DEBUG_MODULE debug_log ("HC_DSTRY: killing helicopter, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]); #endif notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE); } } // // Release landing lock (if any) // release_mobile_entity_landing_locks (en); // // if group contains player, set all helicopters in group to "weapons free", and clear "hold position" flag // if (get_local_entity_int_value (en, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI) { member = get_local_entity_first_child (group, LIST_TYPE_MEMBER); while (member) { set_client_server_entity_int_value (member, INT_TYPE_WEAPONS_HOLD, FALSE); set_client_server_entity_int_value (member, INT_TYPE_POSITION_HOLD, FALSE); member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); } } } //////////////////////////////////////// // // UNLINK FROM SYSTEM // //////////////////////////////////////// // // helicopter // unlink_local_entity_children (en, LIST_TYPE_GUNSHIP_TARGET); unlink_local_entity_children (en, LIST_TYPE_PADLOCK); // // aircraft // // aircrew_root unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT); //////////////////////////////////////// // // the eject sequence relies on launched weapons NOT being unlinked // // unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON); // //////////////////////////////////////// delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER); delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER); // gunship_target_link // member_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_MOVEMENT_DEPENDENT); // view_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE); // // mobile // // // kill weapon sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN); // // kill engine sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_LOOPING); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_WIND_UP); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_WIND_DOWN); // // kill radio / warning effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_INCOMING_MISSILE_WARNING); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_LOCK_ON_TONE); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_MCA); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_RADAR_LOCKED); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_RADAR_TRACKED); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CPG_MESSAGE); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_RADIO_MESSAGE); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_WARNING_MESSAGE); notify_speech_buffers_entity_killed (en); unlink_local_entity_children (en, LIST_TYPE_TARGET); delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK); // sector_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET); // update_link // // death timer (set time after which entity is totally destroyed) // set_local_entity_float_value (en, FLOAT_TYPE_DEATH_TIMER, calculate_mobile_death_timer_value (en)); //////////////////////////////////////// // // KILL // //////////////////////////////////////// damage_helicopter_3d_object (en); // must be done before alive flag set to FALSE remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en); set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE); // // group losses // losses = get_local_entity_int_value (group, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (group, INT_TYPE_LOSSES, losses); // // task losses // task = get_local_group_primary_task (group); if (task) { losses = get_local_entity_int_value (task, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (task, INT_TYPE_LOSSES, losses); } // // Notify Campaign Screen // notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group); // // Notify the GROUP that the mobile has been killed (N.B. must be done AFTER mobile is unlinked from member list) // if (get_comms_model () == COMMS_MODEL_SERVER) { notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en); } // // Notify force to check campaign criteria // if (get_comms_model () == COMMS_MODEL_SERVER) { entity *force; force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (force) { notify_local_entity (ENTITY_MESSAGE_CHECK_CAMPAIGN_OBJECTIVES, force, en); force = get_local_entity_child_succ (force, LIST_TYPE_FORCE); } } //////////////////////////////////////// // // SPECIAL EFFECTS // //////////////////////////////////////// helicopter_impact_movement (en); if (get_comms_model () == COMMS_MODEL_SERVER) { vec3d *position; sound_sample_indices sound_sample_index; set_client_server_entity_int_value (en, INT_TYPE_MAIN_ROTOR_DAMAGED, TRUE); set_client_server_entity_int_value (en, INT_TYPE_TAIL_ROTOR_DAMAGED, TRUE); create_client_server_object_killed_explosion_effect (en); position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); sound_sample_index = SOUND_SAMPLE_INDEX_SHOT_DOWN_HELICOPTER; create_client_server_sound_effect_entity ( en, ENTITY_SIDE_NEUTRAL, ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_LOOPING, SOUND_CHANNEL_SOUND_EFFECT, SOUND_LOCALITY_ALL, NULL, // position 1.0, // amplification TRUE, // valid sound effect TRUE, // looping 1, // sample count &sound_sample_index // sample index list ); } set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DYING); //////////////////////////////////////// // // VIEWS // //////////////////////////////////////// if ((en == get_gunship_entity ()) && (!get_local_entity_int_value (en, INT_TYPE_EJECTED))) { set_gunship_entity (NULL); } #if LANDING_ROUTE_CHECK destroy_debug_entity_landing_route_check (en); #endif ///////////////////////////////////////////////////////////////// // // SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED // ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////////////// }
entity *create_client_server_entity_fixed_wing (int index, entity_sub_types sub_type, entity *group, vec3d *position) { entity *new_entity; fixed_wing *raw; ASSERT (get_comms_model() == COMMS_MODEL_SERVER); // // create fixed wing entity // new_entity = create_client_server_entity ( ENTITY_TYPE_FIXED_WING, 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 // { sound_sample_indices sound_sample_index; // // damage smoke // attach_fixed_wing_meta_smoke_lists (new_entity); // // sound effects // sound_sample_index = aircraft_database [sub_type].continuous_sound_effect_index; 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 FALSE, // valid sound effect TRUE, // looping 1, // sample count &sound_sample_index // sample index list ); sound_sample_index = SOUND_SAMPLE_INDEX_JET_AFTERBURNER; 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 &sound_sample_index // sample index list ); } // // initialise terrain elevation cache // raw = get_local_entity_data (new_entity); get_3d_terrain_point_data (position->x, position->z, &raw->ac.terrain_info); return new_entity; }