Пример #1
0
void dynamics_damage_model (unsigned int damage, int random)
{

	dynamics_damage_types
		damage_array [NUM_DYNAMIC_DAMAGES];

	int
		count;

	dynamics_damage_types
		this_damage;

	if (!get_session_entity ())
	{

		return;
	}

	if (get_local_entity_int_value (get_gunship_entity (), INT_TYPE_INVULNERABLE_FROM_COLLISIONS))
	{

		// if invulnerable only allow damage/use of fire extinguisher

		damage = damage & DYNAMICS_DAMAGE_FIRE_EXTINGUISHER;
	}

	if (random)
	{

		damage_array [0] = DYNAMICS_DAMAGE_NONE;

		this_damage = DYNAMICS_DAMAGE_NONE;

		count = 1;

		while (this_damage < NUM_DYNAMICS_DAMAGE_TYPES)
		{

			if (damage & this_damage)
			{

				damage_array [count] = this_damage;

				count ++;
			}

			this_damage = this_damage << 1;
		}

		damage = damage_array [rand16 () % count];

		#if DYNAMICS_DEBUG

		debug_log ("DYNAMICS: randomly selecting damage %d", damage);

		#endif
	}

	notify_avionics_of_dynamics_fault (damage);

	this_damage = DYNAMICS_DAMAGE_NONE;

	while (this_damage < NUM_DYNAMICS_DAMAGE_TYPES)
	{

		if ((damage & this_damage) && (!(current_flight_dynamics->dynamics_damage & this_damage)))
		{

			switch (this_damage)
			{

				case DYNAMICS_DAMAGE_NONE:
				{

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: no damage");

					#endif

					current_flight_dynamics->dynamics_damage = DYNAMICS_DAMAGE_NONE;

					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;

					current_flight_dynamics->tail_blade_pitch.damaged = FALSE;

					current_flight_dynamics->tail_rotor_rpm.damaged = FALSE;

					current_flight_dynamics->left_engine_torque.damaged = FALSE;

					current_flight_dynamics->left_engine_rpm.damaged = FALSE;

					current_flight_dynamics->right_engine_torque.damaged = FALSE;

					current_flight_dynamics->right_engine_rpm.damaged = FALSE;

					current_flight_dynamics->cross_coupling_effect.damaged = FALSE;

					current_flight_dynamics->input_data.cyclic_x.damaged = FALSE;

					current_flight_dynamics->input_data.cyclic_y.damaged = FALSE;

					current_flight_dynamics->input_data.cyclic_x_trim.damaged = FALSE;

					current_flight_dynamics->input_data.cyclic_y_trim.damaged = FALSE;

					break;
				}
				case DYNAMICS_DAMAGE_MAIN_ROTOR:
				{

					//#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: main rotor damage");

					//#endif

					current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_MAIN_ROTOR;

					current_flight_dynamics->main_blade_pitch.damaged = TRUE;

					current_flight_dynamics->main_rotor_roll_angle.damaged = TRUE;

					current_flight_dynamics->main_rotor_pitch_angle.damaged = TRUE;

					current_flight_dynamics->main_rotor_rpm.damaged = TRUE;

					set_client_server_entity_int_value (get_gunship_entity (), INT_TYPE_MAIN_ROTOR_DAMAGED, TRUE);

					play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_MAIN_ROTOR_DAMAGED);

					set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);

					set_current_flight_dynamics_auto_pilot (FALSE);

					break;
				}
				case DYNAMICS_DAMAGE_TAIL_ROTOR:
				{

					//#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: tail rotor damage");

					//#endif

					current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_TAIL_ROTOR;

					current_flight_dynamics->tail_blade_pitch.damaged = TRUE;

					current_flight_dynamics->tail_rotor_rpm.damaged = TRUE;

					current_flight_dynamics->cross_coupling_effect.damaged = TRUE;

					set_client_server_entity_int_value (get_gunship_entity (), INT_TYPE_TAIL_ROTOR_DAMAGED, TRUE);

					play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_TAIL_ROTOR_DAMAGED);

					set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);

					set_current_flight_dynamics_auto_pilot (FALSE);

					break;
				}
				case DYNAMICS_DAMAGE_LEFT_ENGINE:
				{

					//#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: left engine damage");

					//#endif

					current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_LEFT_ENGINE;

					current_flight_dynamics->left_engine_torque.damaged = TRUE;

					current_flight_dynamics->left_engine_rpm.damaged = TRUE;

					play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_LEFT_ENGINE_FAILURE);

					set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);

					set_current_flight_dynamics_auto_pilot (FALSE);

					break;
				}
				case DYNAMICS_DAMAGE_RIGHT_ENGINE:
				{

					//#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: right engine damage");

					//#endif

					current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_RIGHT_ENGINE;

					current_flight_dynamics->right_engine_torque.damaged = TRUE;

					current_flight_dynamics->right_engine_rpm.damaged = TRUE;

					play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_RIGHT_ENGINE_FAILURE);

					set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);

					set_current_flight_dynamics_auto_pilot (FALSE);

					break;
				}
				case DYNAMICS_DAMAGE_LEFT_ENGINE_FIRE:
				{

					//#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: left engine fire damage");

					//#endif

					current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_LEFT_ENGINE_FIRE;

					play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_LEFT_ENGINE_FIRE);

					set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);

					set_current_flight_dynamics_auto_pilot (FALSE);

					break;
				}
				case DYNAMICS_DAMAGE_RIGHT_ENGINE_FIRE:
				{

					//#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: right engine fire damage");

					//#endif

					current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_RIGHT_ENGINE_FIRE;

					play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_RIGHT_ENGINE_FIRE);

					set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);

					set_current_flight_dynamics_auto_pilot (FALSE);

					break;
				}
				case DYNAMICS_DAMAGE_LOW_HYDRAULICS:
				{

					//#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: LOW HYDRAULICS damage");

					//#endif

					current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_LOW_HYDRAULICS;

					current_flight_dynamics->input_data.cyclic_x.damaged = TRUE;

					current_flight_dynamics->input_data.cyclic_y.damaged = TRUE;

					if (sfrand1 () < 0.0)
					{

						play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_HYDRAULIC_PRESSURE_FAILURE);
					}
					else
					{

						play_client_server_cpg_message (get_gunship_entity (), 0.5, 1.0, SPEECH_CATEGORY_CPG_SYSTEMS, 1.0, SPEECH_CPG_CONTROL_SYSTEMS_DAMAGED);
					}

					set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);

					set_current_flight_dynamics_auto_pilot (FALSE);

					break;
				}
				case DYNAMICS_DAMAGE_STABILISER:
				{

					//#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: STABILISER damage");

					//#endif

					current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_STABILISER;

					set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);

					set_current_flight_dynamics_auto_pilot (FALSE);

					if (sfrand1 () < 0.0)
					{

						play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_STABILISER_DAMAGED);
					}
					else
					{

						play_client_server_cpg_message (get_gunship_entity (), 0.5, 1.0, SPEECH_CATEGORY_CPG_SYSTEMS, 1.0, SPEECH_CPG_CONTROL_SYSTEMS_DAMAGED);
					}

					break;
				}
				case DYNAMICS_DAMAGE_FUEL_LEAK:
				{

					//#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: FUEL_LEAK damage");

					//#endif

					current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_FUEL_LEAK;

					play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_FUEL_LEAK);

					break;
				}
				case DYNAMICS_DAMAGE_LOW_OIL_PRESSURE:
				{

					//#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: LOW_OIL_PRESSURE damage");

					//#endif

					current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_LOW_OIL_PRESSURE;

					current_flight_dynamics->input_data.cyclic_y.damaged = TRUE;

					if (sfrand1 () < 0.0)
					{

						play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_LOW_ENGINE_OIL_PRESSURE);
					}
					else
					{

						play_client_server_cpg_message (get_gunship_entity (), 0.5, 1.0, SPEECH_CATEGORY_CPG_SYSTEMS, 1.0, SPEECH_CPG_CONTROL_SYSTEMS_DAMAGED);
					}

					set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);

					set_current_flight_dynamics_auto_pilot (FALSE);

					break;
				}
				case DYNAMICS_DAMAGE_HIGH_OIL_PRESSURE:
				{

					//#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: HIGH_OIL_PRESSURE damage");

					//#endif

					current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_HIGH_OIL_PRESSURE;

					current_flight_dynamics->input_data.collective.damaged = TRUE;

					if (sfrand1 () < 0.0)
					{

						play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_HIGH_ENGINE_OIL_TEMPERATURE);
					}
					else
					{

						play_client_server_cpg_message (get_gunship_entity (), 0.5, 1.0, SPEECH_CATEGORY_CPG_SYSTEMS, 1.0, SPEECH_CPG_CONTROL_SYSTEMS_DAMAGED);
					}

					set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);

					set_current_flight_dynamics_auto_pilot (FALSE);

					break;
				}
				case DYNAMICS_DAMAGE_AVIONICS:
				{

					//#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: AVIONICS damage");

					//#endif

					current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_AVIONICS;

					break;
				}
				case DYNAMICS_DAMAGE_FIRE_EXTINGUISHER:
				{

					//#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: FIRE_EXTINGUISHER damage");

					//#endif

					current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_FIRE_EXTINGUISHER;

					break;
				}
				case DYNAMICS_DAMAGE_UNDERCARRIAGE:
				{

					//#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: UNDERCARRIAGE damage");

					//#endif

					current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_UNDERCARRIAGE;

					current_flight_dynamics->undercarriage_state.damaged = TRUE;

					play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_GEAR_DAMAGED);

					break;
				}
				default:
				{

					debug_fatal ("DYNAMICS: unknown damage %d", this_damage);
				}
			}
		}

		this_damage = this_damage << 1;
	}
}
Пример #2
0
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);
			}
		}
	}
}
Пример #3
0
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);
			}
		}
	}
}
Пример #4
0
void update_cyclic_pressure_inputs (void)
{

	float
		trim_x,
		trim_y;

	if (!current_flight_dynamics)
	{

		return;
	}

	if (hydraulic_pressure_loss_rate && hydraulic_pressure > 0.0)
	{
		hydraulic_pressure -= hydraulic_pressure_loss_rate * get_delta_time();

		if (hydraulic_pressure < 0.0)
			hydraulic_pressure = 0.0;
	}

	trim_x = current_flight_dynamics->input_data.cyclic_x_trim.value;
	trim_y = current_flight_dynamics->input_data.cyclic_y_trim.value;

	if (trim_button_held)
	{
		current_flight_dynamics->input_data.cyclic_x.value = current_flight_dynamics->input_data.cyclic_x_trim.value;
		current_flight_dynamics->input_data.cyclic_y.value = current_flight_dynamics->input_data.cyclic_y_trim.value;
	}
	else
		switch (get_global_cyclic_input ())
		{

			case KEYBOARD_INPUT:
			case MOUSE_INPUT:
			{

				if (current_flight_dynamics->input_data.cyclic_input_pressure & CYCLIC_PRESSURE_LEFT)
				{

					current_flight_dynamics->input_data.cyclic_horizontal_pressure.value = min (0.0f, current_flight_dynamics->input_data.cyclic_horizontal_pressure.value);

					current_flight_dynamics->input_data.cyclic_x.value = min ((current_flight_dynamics->input_data.cyclic_x.value) / 2.0f, current_flight_dynamics->input_data.cyclic_x.value);

					current_flight_dynamics->input_data.cyclic_horizontal_pressure.value -= MODEL_FRAME_RATE * get_model_delta_time ();

					if ((current_flight_dynamics->auto_hover == HOVER_HOLD_NORMAL) ||
						(current_flight_dynamics->auto_hover == HOVER_HOLD_STABLE))
					{

						set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);
						set_current_flight_dynamics_auto_pilot (FALSE);
					}
				}
				else if (current_flight_dynamics->input_data.cyclic_input_pressure & CYCLIC_PRESSURE_RIGHT)
				{

					current_flight_dynamics->input_data.cyclic_horizontal_pressure.value = max (0.0f, current_flight_dynamics->input_data.cyclic_horizontal_pressure.value);

					current_flight_dynamics->input_data.cyclic_x.value = max ((current_flight_dynamics->input_data.cyclic_x.value) / 2.0f, current_flight_dynamics->input_data.cyclic_x.value);

					current_flight_dynamics->input_data.cyclic_horizontal_pressure.value += MODEL_FRAME_RATE * get_model_delta_time ();

					if ((current_flight_dynamics->auto_hover == HOVER_HOLD_NORMAL) ||
						(current_flight_dynamics->auto_hover == HOVER_HOLD_STABLE))
					{

						set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);
						set_current_flight_dynamics_auto_pilot (FALSE);
					}
				}
				else
				{

					if (fabs (current_flight_dynamics->input_data.cyclic_horizontal_pressure.value) < 1.0)
					{

						current_flight_dynamics->input_data.cyclic_horizontal_pressure.value = 0.0;
					}
					else
					{

						current_flight_dynamics->input_data.cyclic_horizontal_pressure.value -= ((MODEL_FRAME_RATE * get_model_delta_time ()) / 2.0) * (current_flight_dynamics->input_data.cyclic_horizontal_pressure.value);
					}
				}



				if (current_flight_dynamics->input_data.cyclic_input_pressure & CYCLIC_PRESSURE_BACKWARD)
				{

					current_flight_dynamics->input_data.cyclic_vertical_pressure.value = min (0.0f, current_flight_dynamics->input_data.cyclic_vertical_pressure.value);

					current_flight_dynamics->input_data.cyclic_y.value = min (current_flight_dynamics->input_data.cyclic_y.value / 2.0f, current_flight_dynamics->input_data.cyclic_y.value);

					current_flight_dynamics->input_data.cyclic_vertical_pressure.value -= MODEL_FRAME_RATE * get_model_delta_time ();

					if ((current_flight_dynamics->auto_hover == HOVER_HOLD_NORMAL) ||
						(current_flight_dynamics->auto_hover == HOVER_HOLD_STABLE))
					{

						set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);
						set_current_flight_dynamics_auto_pilot (FALSE);
					}
				}
				else if (current_flight_dynamics->input_data.cyclic_input_pressure & CYCLIC_PRESSURE_FORWARD)
				{

					current_flight_dynamics->input_data.cyclic_vertical_pressure.value = max (0.0f, current_flight_dynamics->input_data.cyclic_vertical_pressure.value);

					current_flight_dynamics->input_data.cyclic_y.value = max (current_flight_dynamics->input_data.cyclic_y.value / 2.0f, current_flight_dynamics->input_data.cyclic_y.value);

					current_flight_dynamics->input_data.cyclic_vertical_pressure.value += MODEL_FRAME_RATE * get_model_delta_time ();

					if ((current_flight_dynamics->auto_hover == HOVER_HOLD_NORMAL) ||
						(current_flight_dynamics->auto_hover == HOVER_HOLD_STABLE))
					{

						set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);
						set_current_flight_dynamics_auto_pilot (FALSE);
					}
				}
				else
				{

					if (fabs (current_flight_dynamics->input_data.cyclic_vertical_pressure.value) < 1.0)
					{

						current_flight_dynamics->input_data.cyclic_vertical_pressure.value = 0.0;
					}
					else
					{

						current_flight_dynamics->input_data.cyclic_vertical_pressure.value -= ((MODEL_FRAME_RATE * get_model_delta_time ()) / 2.0) * (current_flight_dynamics->input_data.cyclic_vertical_pressure.value);
					}
				}

				// limit pressure inputs

				current_flight_dynamics->input_data.cyclic_horizontal_pressure.value = bound (
																					current_flight_dynamics->input_data.cyclic_horizontal_pressure.value,
																					current_flight_dynamics->input_data.cyclic_horizontal_pressure.min,
																					current_flight_dynamics->input_data.cyclic_horizontal_pressure.max
																					);

				current_flight_dynamics->input_data.cyclic_vertical_pressure.value = bound (current_flight_dynamics->input_data.cyclic_vertical_pressure.value,
																					current_flight_dynamics->input_data.cyclic_vertical_pressure.min,
																					current_flight_dynamics->input_data.cyclic_vertical_pressure.max
																					);

				// recalculate cyclic position

				if (current_flight_dynamics->input_data.cyclic_horizontal_pressure.value)
				{

					current_flight_dynamics->input_data.cyclic_x.value += (MODEL_FRAME_RATE * get_model_delta_time ()) * current_flight_dynamics->input_data.cyclic_horizontal_pressure.value;
					//current_flight_dynamics->input_data.cyclic_x.value += (MODEL_FRAME_RATE * get_model_delta_time ()) * (current_flight_dynamics->input_data.cyclic_horizontal_pressure.value);// + current_flight_dynamics->input_data.cyclic_x_trim.value);
				}
				else
				{

					// restore x
					//Werewolf: Removed old debug code, removed redundant multiplications

					if (get_global_cyclic_input () == KEYBOARD_INPUT)
					{
						if (get_current_dynamics_options (DYNAMICS_OPTIONS_KEYBOARD_ASSISTANCE))
						{
							current_flight_dynamics->input_data.cyclic_x.value += ((1.0 / 16.0) * MODEL_FRAME_RATE * get_model_delta_time ()) * (current_flight_dynamics->input_data.cyclic_x_trim.value - current_flight_dynamics->input_data.cyclic_x.value);
						}
						else
						{
							current_flight_dynamics->input_data.cyclic_x.value += ((3.0 / 4.0) * MODEL_FRAME_RATE * get_model_delta_time ()) * (current_flight_dynamics->input_data.cyclic_x_trim.value - current_flight_dynamics->input_data.cyclic_x.value);
						}
					}
					else if (get_global_cyclic_input () == MOUSE_INPUT)
					{
						if (fabs (current_flight_dynamics->input_data.cyclic_x.value) < 5.0)
						{
							current_flight_dynamics->input_data.cyclic_x.value *= 0.8;
						}
					}
				}

				if (current_flight_dynamics->input_data.cyclic_vertical_pressure.value)
				{
					//current_flight_dynamics->input_data.cyclic_y.value += (MODEL_FRAME_RATE * get_model_delta_time ()) * (current_flight_dynamics->input_data.cyclic_vertical_pressure.value + current_flight_dynamics->input_data.cyclic_y_trim.value);
					current_flight_dynamics->input_data.cyclic_y.value += (MODEL_FRAME_RATE * get_model_delta_time ()) * (current_flight_dynamics->input_data.cyclic_vertical_pressure.value);// + current_flight_dynamics->input_data.cyclic_y_trim.value);
				}
				else
				{

					// restore y

					if (get_global_cyclic_input () == KEYBOARD_INPUT)
					{
						if (get_current_dynamics_options (DYNAMICS_OPTIONS_KEYBOARD_ASSISTANCE))
						{
							current_flight_dynamics->input_data.cyclic_y.value += ((1.0 / 16.0) * MODEL_FRAME_RATE * get_model_delta_time ()) * (current_flight_dynamics->input_data.cyclic_y_trim.value - current_flight_dynamics->input_data.cyclic_y.value);
						}
						else
						{
							current_flight_dynamics->input_data.cyclic_y.value += ((3.0 / 4.0) * MODEL_FRAME_RATE * get_model_delta_time ()) * (current_flight_dynamics->input_data.cyclic_y_trim.value - current_flight_dynamics->input_data.cyclic_y.value);
						}
					}
					else if (get_global_cyclic_input () == MOUSE_INPUT)
					{
						if (fabs (current_flight_dynamics->input_data.cyclic_y.value) < 5.0)
						{
							debug_fatal ("CYCLIC: code with delta time");
							current_flight_dynamics->input_data.cyclic_y.value *= 0.8;
						}
					}
				}

				break;
			}

			case JOYSTICK_INPUT:
			{

				int
					joyval;

				float
					input;

				// 030418 loke
				// implemented multiple joystick device selection

				// x

				if (command_line_cyclic_joystick_index == -1)
				{
					joyval = get_joystick_axis (current_flight_dynamics->input_data.cyclic_joystick_device_index, JOYSTICK_DEFAULT_AXIS_ROLL);
				}
				else
				{
					joyval = get_joystick_axis (command_line_cyclic_joystick_index, command_line_cyclic_joystick_x_axis);
				}

				if (command_line_nonlinear_cyclic)
				{
					// in non-linear mode it uses a curve described by f(x) = x*x + x
					// gives a not so sensitive control around centre
					input = (2.0 * (float) joyval ) / ((float) JOYSTICK_AXIS_MAXIMUM - (float) JOYSTICK_AXIS_MINIMUM);
					if (input >= 0)
						input *= input;
					else
						input *= -input;
					input += input;
					input *= 50;
				}
				else
					input = (float) (200.0 * (float) joyval ) / ((float) JOYSTICK_AXIS_MAXIMUM - (float) JOYSTICK_AXIS_MINIMUM);

				if (fabs (input) < command_line_dynamics_cyclic_dead_zone)
				{

					input = 0.0;
				}

				current_flight_dynamics->input_data.cyclic_x.value = input;
        
        //ataribaby 1/1/2009 allow trim with ALT HOLD
				if (current_flight_dynamics->auto_hover == HOVER_HOLD_NONE || current_flight_dynamics->auto_hover == HOVER_HOLD_ALTITUDE_LOCK)
					current_flight_dynamics->input_data.cyclic_x.value += current_flight_dynamics->input_data.cyclic_x_trim.value;

				// y

				if (command_line_cyclic_joystick_index == -1)
				{
					joyval = get_joystick_axis (current_flight_dynamics->input_data.cyclic_joystick_device_index, JOYSTICK_DEFAULT_AXIS_PITCH);
				}
				else
				{
					joyval = get_joystick_axis (command_line_cyclic_joystick_index, command_line_cyclic_joystick_y_axis);
				}

				if (command_line_nonlinear_cyclic)
				{
					// in non-linear mode it uses a curve described by f(x) = x*x + x
					// gives a not so sensitive control around centre
					input = -2.0 * ((float) joyval ) / ((float) JOYSTICK_AXIS_MAXIMUM - (float) JOYSTICK_AXIS_MINIMUM);
					if (input >= 0)
						input *= input;
					else
						input *= -input;
					input += input;
					input *= 50.0;
				}
				else
					input = -(float) (200.0 * joyval) / (JOYSTICK_AXIS_MAXIMUM - JOYSTICK_AXIS_MINIMUM);

				if (fabs (input) < command_line_dynamics_cyclic_dead_zone)
				{

					input = 0.0;
				}

				current_flight_dynamics->input_data.cyclic_y.value = input;
        
        //ataribaby 1/1/2009 allow trim with ALT HOLD 
				if (current_flight_dynamics->auto_hover == HOVER_HOLD_NONE || current_flight_dynamics->auto_hover == HOVER_HOLD_ALTITUDE_LOCK)
					current_flight_dynamics->input_data.cyclic_y.value += current_flight_dynamics->input_data.cyclic_y_trim.value;

				/*
				debug_log ("CYCLIC: x %f, y %f", ((float) fabs (200.0 * get_joystick_axis(current_flight_dynamics->input_data.cyclic_joystick_device_index, JOYSTICK_DEFAULT_AXIS_ROLL) / (JOYSTICK_AXIS_MAXIMUM - JOYSTICK_AXIS_MINIMUM)),
					((float) fabs (200.0 * get_joystick_axis(current_flight_dynamics->input_data.cyclic_joystick_device_index, JOYSTICK_DEFAULT_AXIS_PITCH)) / (JOYSTICK_AXIS_MAXIMUM - JOYSTICK_AXIS_MINIMUM)));
				*/

				{
					// 030418 loke
					// implemented multiple joystick device selection

					int
						joystick_x_pos,
						joystick_y_pos;

					if (command_line_cyclic_joystick_index == -1)
					{
						joystick_x_pos = get_joystick_axis (current_flight_dynamics->input_data.cyclic_joystick_device_index, JOYSTICK_DEFAULT_AXIS_ROLL);
						joystick_y_pos = get_joystick_axis (current_flight_dynamics->input_data.cyclic_joystick_device_index, JOYSTICK_DEFAULT_AXIS_PITCH);
					}
					else
					{
						joystick_x_pos = get_joystick_axis (command_line_cyclic_joystick_index, command_line_cyclic_joystick_x_axis);
						joystick_y_pos = get_joystick_axis (command_line_cyclic_joystick_index, command_line_cyclic_joystick_y_axis);
					}

					if (((float) fabs (200.0 * joystick_x_pos) / (JOYSTICK_AXIS_MAXIMUM - JOYSTICK_AXIS_MINIMUM) > 10.0) ||
						((float) fabs (200.0 * joystick_y_pos) / (JOYSTICK_AXIS_MAXIMUM - JOYSTICK_AXIS_MINIMUM) > 10.0))
					{

						if ((current_flight_dynamics->auto_hover == HOVER_HOLD_NORMAL) ||
							(current_flight_dynamics->auto_hover == HOVER_HOLD_STABLE))
						{

							set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE);
							set_current_flight_dynamics_auto_pilot (FALSE);
						}
					}
				}

				break;
			}
		}

	//
	// DEBUG - to get the coolie hat working
	//
	#if 0
	{

		joystick_hat_position
			coolie_position;

		coolie_position = get_joystick_hat( &joystick_devices [current_flight_dynamics->input_data.cyclic_joystick_device_index], 0 );

		switch( coolie_position ) {
		case HAT_CENTERED:
			debug_log ("CYCLIC: coolie centered");
			break;
		case HAT_UP:
			debug_log ("CYCLIC: coolie up");
			break;
		case HAT_LEFT:
			debug_log ("CYCLIC: coolie left");
			break;
		case HAT_DOWN:
			debug_log ("CYCLIC: coolie down");
			break;
		case HAT_RIGHT:
			debug_log ("CYCLIC: coolie right");
			break;
		case HAT_LEFTUP:
			debug_log ("CYCLIC: coolie left+up");
			break;
		case HAT_LEFTDOWN:
			debug_log ("CYCLIC: coolie left+down");
			break;
		case HAT_RIGHTUP:
			debug_log ("CYCLIC: coolie right+up");
			break;
		case HAT_RIGHTDOWN:
			debug_log ("CYCLIC: coolie right+down");
			break;
		default:
			debug_log ("CYCLIC: coolie is on fire");
		}
	}
	#endif

	//
	// Damaged hydraulics
	//

	if (current_flight_dynamics->input_data.cyclic_x.damaged)
	{
		current_flight_dynamics->input_data.cyclic_x.value *= hydraulic_pressure;
		current_flight_dynamics->input_data.cyclic_x.value += damaged_lock_x_pos * (1.0 - hydraulic_pressure);
	}

	if (current_flight_dynamics->input_data.cyclic_y.damaged)
	{
		current_flight_dynamics->input_data.cyclic_y.value *= hydraulic_pressure;
		current_flight_dynamics->input_data.cyclic_y.value += damaged_lock_y_pos * (1.0 - hydraulic_pressure);
	}

	//
	// Damaged Stabaliser
	//

	if (current_flight_dynamics->input_data.cyclic_x_trim.damaged)
		current_flight_dynamics->input_data.cyclic_x_trim.value += (MODEL_FRAME_RATE * get_model_delta_time ()) * (0.5 * sfrand1 () * current_flight_dynamics->input_data.cyclic_x_trim.value);

	if (current_flight_dynamics->input_data.cyclic_y_trim.damaged)
		current_flight_dynamics->input_data.cyclic_y_trim.value += (MODEL_FRAME_RATE * get_model_delta_time ()) * (0.5 * sfrand1 () * current_flight_dynamics->input_data.cyclic_y_trim.value);

	// limit cyclic position

	current_flight_dynamics->input_data.cyclic_x.value = bound (
												//current_flight_dynamics->input_data.cyclic_x.value + current_flight_dynamics->input_data.cyclic_x_trim.value,
												current_flight_dynamics->input_data.cyclic_x.value,
												current_flight_dynamics->input_data.cyclic_x.min,
												current_flight_dynamics->input_data.cyclic_x.max
												);

	current_flight_dynamics->input_data.cyclic_y.value = bound (
												//current_flight_dynamics->input_data.cyclic_y.value + current_flight_dynamics->input_data.cyclic_y_trim.value,
												current_flight_dynamics->input_data.cyclic_y.value,
												current_flight_dynamics->input_data.cyclic_y.min,
												current_flight_dynamics->input_data.cyclic_y.max
												);
}