예제 #1
0
static void update_server (entity *en)
{
	cargo
		*raw;

	int
		loop;

	raw = get_local_entity_data (en);

	if (raw->mob.alive)
	{

		////////////////////////////////////////

		for (loop = 0; loop < get_entity_movement_iterations (); loop ++)
		{

			get_3d_terrain_point_data (raw->mob.position.x, raw->mob.position.z, &raw->terrain_info);

			basic_cargo_movement (en);
		}

		////////////////////////////////////////
	}
	else
	{

		for (loop = 0; loop < get_entity_movement_iterations (); loop ++)
		{

			basic_cargo_death_movement (en);
		}
	}
}
예제 #2
0
파일: cm_recog.c 프로젝트: Comanche93/eech
static void update_recognition_guide_camera (camera *raw, object_3d_camera_index_numbers index)
{
	entity
		*en;

	object_3d_instance
		*inst3d;

	viewpoint
		vp;

	//
	// pre-amble
	//

	ASSERT (raw);

	ASSERT (raw->external_view_entity);

	en = raw->external_view_entity;

	//
	// get camera position and attitude
	//

	inst3d = (object_3d_instance *) get_local_entity_ptr_value (en, PTR_TYPE_INSTANCE_3D_OBJECT);

	ASSERT (inst3d);

	set_3d_exclusive_instance ( inst3d );

	get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &inst3d->vp.position);

	get_local_entity_attitude_matrix (en, inst3d->vp.attitude);

	get_object_3d_camera_position (inst3d, index, 0, 0.0, &vp);

	raw->position = vp.position;

	memcpy (raw->attitude, vp.attitude, sizeof (matrix3x3));

	//
	// keep point above ground (unless point off map)
	//

	if (point_inside_map_area (&raw->position))
	{
		raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + 0.5f);
	}

	//
	// motion vector
	//

	get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector);
}
예제 #3
0
파일: cm_over.c 프로젝트: Comanche93/eech
void update_overview_camera (camera *raw)
{
	entity
		*en;

	vec3d
		rel_camera_position;

	//
	// pre-amble
	//

	ASSERT (raw);

	ASSERT (raw->external_view_entity);

	en = raw->external_view_entity;

	//
	// get camera attitude
	//

	get_3d_transformation_matrix (raw->attitude, get_local_entity_float_value (en, FLOAT_TYPE_HEADING) + rad (180.0), rad (-15.0), 0.0);

	//
	// get camera position
	//

	rel_camera_position.x = 0.0;
	rel_camera_position.y = 0.0;
	rel_camera_position.z = -get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE);

	multiply_matrix3x3_vec3d (&rel_camera_position, raw->attitude, &rel_camera_position);

	get_local_entity_target_point (en, &raw->position);

	raw->position.x += rel_camera_position.x;
	raw->position.y += rel_camera_position.y;
	raw->position.z += rel_camera_position.z;

	//
	// keep point above ground (unless point off map)
	//

	if (point_inside_map_area (&raw->position))
	{
		raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + 0.5f);
	}

	//
	// motion vector
	//

	get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector);
}
예제 #4
0
파일: sg_updt.c 프로젝트: Comanche93/eech
static void update_server (entity *en)
{
	entity
		*parent,
		*next_segment,
		*prev_segment;

	entity_sub_types
		sub_type;

	vec3d
		*pos;

	float
		terrain_height;

	terrain_3d_point_data
		terrain_info;

	//
	// notify the segments neighbours as applicable
	//

	parent = get_local_entity_parent (en, LIST_TYPE_SEGMENT);

	ASSERT (parent);

	next_segment = get_local_entity_child_succ (en, LIST_TYPE_SEGMENT);

	if (next_segment)
	{
		notify_local_entity (ENTITY_MESSAGE_COLLISION, parent, next_segment);
	}

	prev_segment = get_local_entity_child_pred (en, LIST_TYPE_SEGMENT);

	if (prev_segment)
	{
		notify_local_entity (ENTITY_MESSAGE_COLLISION, parent, prev_segment);
	}

	sub_type = get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE);

	if (sub_type == ENTITY_SUB_TYPE_FIXED_BRIDGE_UNSUPPORTED_MID_SECTION)
	{
		//
		// make the segment drop to the floor ( removing it from the update list when it hits )
		//
	
		pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);
	
		pos->y -= ( 10.0 * get_delta_time() );
	
		memset (&terrain_info, 0, sizeof (terrain_3d_point_data));
	
		terrain_height = get_3d_terrain_point_data (pos->x, pos->z, &terrain_info);

		if (get_terrain_type_class (terrain_info.terrain_type) == TERRAIN_CLASS_WATER)
		{
			terrain_height -= 1.0;
		}
	
		if ( pos->y <= terrain_height )
		{
			pos->y = terrain_height;
	
			delete_local_entity_from_parents_child_list (en, LIST_TYPE_UPDATE);
	
			if (get_comms_model () == COMMS_MODEL_SERVER)
			{
				create_client_server_object_hit_ground_explosion_effect (en, terrain_info.terrain_type);
			}
		}
	}
	else
	{
		//
		// segment is supported, and so should be instantly removed from the update list
		// ( only put there in the first place so that neighbours would be notified )
		//

		delete_local_entity_from_parents_child_list (en, LIST_TYPE_UPDATE);
	}
}
예제 #5
0
파일: cm_stat.c 프로젝트: Comanche93/eech
void reset_static_camera (camera *raw)
{
	entity
		*en;

	vec3d
		pos,
		v;

	matrix3x3
		m;

	float
		heading,
		z_min,
		z_max,
		radius,
		length;

	int
		fast_airborne;

	ASSERT (raw);

	ASSERT (raw->external_view_entity);

	en = raw->external_view_entity;

	z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE);
	z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE);

	ASSERT (z_min < z_max);

	radius = -(((z_max - z_min) * CHASE_CAMERA_RESET_ZOOM * CHASE_CAMERA_RESET_ZOOM) + z_min);

	fast_airborne = FALSE;

	if (get_local_entity_int_value (en, INT_TYPE_AIRBORNE_AIRCRAFT))
	{
		if (get_local_entity_vec3d_magnitude (en, VEC3D_TYPE_MOTION_VECTOR) >= knots_to_metres_per_second (10.0))
		{
			fast_airborne = TRUE;
		}
	}

	if (fast_airborne)
	{
		get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &v);

		normalise_3d_vector (&v);

		v.x *= radius;
		v.y *= radius;
		v.z *= radius;
	}
	else
	{
		heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING);

		get_3d_transformation_matrix (m, heading, CHASE_CAMERA_RESET_PITCH, 0.0);

		v.x = 0.0;
		v.y = 0.0;
		v.z = radius;

		multiply_matrix3x3_vec3d (&v, m, &v);
	}

	get_local_entity_target_point (en, &pos);

	raw->position.x = pos.x + v.x;
	raw->position.y = pos.y + v.y;
	raw->position.z = pos.z + v.z;

	//
	// keep point above ground (unless point off map)
	//

	if (point_inside_map_area (&raw->position))
	{
		raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND);
	}

	//
	// attitude
	//

	v.x = pos.x - raw->position.x;
	v.y = pos.y - raw->position.y;
	v.z = pos.z - raw->position.z;

	length = (v.x * v.x) + (v.y * v.y) + (v.z * v.z);

	if (length > 1.0)
	{
		length = sqrt (length);

		normalise_3d_vector_given_magnitude (&v, length);

		get_matrix3x3_from_unit_vec3d (raw->attitude, &v);
	}
	else
	{
		get_identity_matrix3x3 (raw->attitude);
	}

	//
	// motion vector
	//

	raw->motion_vector.x = 0.0;
	raw->motion_vector.y = 0.0;
	raw->motion_vector.z = 0.0;
}
예제 #6
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);
			}
		}
	}
}
예제 #7
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);
			}
		}
	}
}
예제 #8
0
void update_cinematic_camera_continued (camera *raw)
{
	entity
		*en;

	object_3d_instance
		*inst3d;

	viewpoint
		vp;

	float
		normalised_timer;

	//
	// pre-amble
	//

	ASSERT (raw);

	ASSERT (raw->external_view_entity);

	en = raw->external_view_entity;

	//
	// get camera position and attitude
	//

	switch (raw->cinematic_camera_index)
	{
		////////////////////////////////////////
		case OBJECT_3D_INVALID_CAMERA_INDEX:
		////////////////////////////////////////
		{
			float
				combined_heading,
				z_min,
				z_max;

			vec3d
				rel_camera_position;

			combined_heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING);

			combined_heading += raw->cinematic_camera_heading;

			get_3d_transformation_matrix (raw->attitude, combined_heading, raw->cinematic_camera_pitch, 0.0);

			z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE);
			z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE);

			ASSERT (z_min < z_max);

			rel_camera_position.x = 0.0;
			rel_camera_position.y = 0.0;
			rel_camera_position.z = -(((z_max - z_min) * 0.1) + z_min);

			multiply_matrix3x3_vec3d (&rel_camera_position, raw->attitude, &rel_camera_position);

			get_local_entity_target_point (en, &raw->position);

			raw->position.x += rel_camera_position.x;
			raw->position.y += rel_camera_position.y;
			raw->position.z += rel_camera_position.z;

			break;
		}
		////////////////////////////////////////
		case OBJECT_3D_CAMERA_SCENIC_MOVING:
		////////////////////////////////////////
		{
			normalised_timer = raw->cinematic_camera_timer / raw->cinematic_camera_lifetime;

			inst3d = get_local_entity_ptr_value (en, PTR_TYPE_INSTANCE_3D_OBJECT);

			get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &inst3d->vp.position);

			get_local_entity_attitude_matrix (en, inst3d->vp.attitude);

			get_object_3d_camera_position (inst3d, raw->cinematic_camera_index, raw->cinematic_camera_depth, normalised_timer, &vp);

			raw->position = vp.position;

			memcpy (raw->attitude, vp.attitude, sizeof (matrix3x3));

			break;
		}
		////////////////////////////////////////
		case OBJECT_3D_CAMERA_SCENIC_STATIC:
		////////////////////////////////////////
		{
			normalised_timer = 0.0;

			inst3d = get_local_entity_ptr_value (en, PTR_TYPE_INSTANCE_3D_OBJECT);

			get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &inst3d->vp.position);

			get_local_entity_attitude_matrix (en, inst3d->vp.attitude);

			get_object_3d_camera_position (inst3d, raw->cinematic_camera_index, raw->cinematic_camera_depth, normalised_timer, &vp);

			raw->position = vp.position;

			memcpy (raw->attitude, vp.attitude, sizeof (matrix3x3));

			break;
		}
	}

	//
	// keep point above ground (unless point off map)
	//

	if (point_inside_map_area (&raw->position))
	{
		raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + 0.5);
	}

	//
	// motion vector
	//

	get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector);
}
예제 #9
0
void reset_drop_camera (camera *raw)
{
	entity
		*en;

	vec3d
		pos,
		v;

	matrix3x3
		m;

	float
		heading,
		z_min,
		z_max;

	//
	// pre-amble
	//

	ASSERT (raw);

	ASSERT (raw->external_view_entity);

	en = raw->external_view_entity;

	//
	// place camera behind object to prevent going inside object (especially when the object is stationary)
	//

	heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING);

	get_3d_transformation_matrix (m, heading, CHASE_CAMERA_RESET_PITCH, 0.0);

	z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE);
	z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE);

	ASSERT (z_min < z_max);

	v.x = 0.0;
	v.y = 0.0;
	v.z = -(((z_max - z_min) * CHASE_CAMERA_RESET_ZOOM * CHASE_CAMERA_RESET_ZOOM) + z_min);

	multiply_matrix3x3_vec3d (&v, m, &v);

	get_local_entity_target_point (en, &pos);

	raw->position.x = pos.x + v.x;
	raw->position.y = pos.y + v.y;
	raw->position.z = pos.z + v.z;

	//
	// keep point above ground (unless point off map)
	//

	if (point_inside_map_area (&raw->position))
	{
		raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND);
	}

	//
	// motion vector
	//

	raw->motion_vector.x = 0.0;
	raw->motion_vector.y = 0.0;
	raw->motion_vector.z = 0.0;
}
예제 #10
0
파일: downwash.c 프로젝트: Comanche93/eech
void draw_downwash_effect(entity *en)
{

	vec3d
		*position,
		pos;

	terrain_3d_point_data
		terrain_info;

	float
		main_rotor_radius,
		main_rotor_rpm,
		min_altitude;

	int
		number_of_main_rotors;

	terrain_types
		type_of_terrain;

	downwash_types
		type_of_downwash;


	ASSERT( en );

	ASSERT (get_local_entity_type (en) == ENTITY_TYPE_HELICOPTER);

	if (!get_local_entity_int_value (en, INT_TYPE_ALIVE))
	{
		return;
	}

	if (get_local_entity_int_value (en, INT_TYPE_OBJECT_DRAWN_ONCE_THIS_FRAME))
	{
		return;
	}

	if (get_time_acceleration () == TIME_ACCELERATION_PAUSE)
	{
		return;
	}

	memset (&terrain_info, 0, sizeof (terrain_3d_point_data));

	main_rotor_rpm = get_local_entity_float_value (en, FLOAT_TYPE_MAIN_ROTOR_RPM);

	position = get_local_entity_vec3d_ptr(en, VEC3D_TYPE_POSITION);

	pos.x = position->x;
	pos.y = position->y - aircraft_database [get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE)].centre_of_gravity_to_ground_distance;
	pos.z = position->z;

	get_3d_terrain_point_data (pos.x, pos.z, &terrain_info);
	min_altitude = get_3d_terrain_point_data_elevation (&terrain_info);

	//Xhit: main_rotor_radius is got here because DOWNWASH_EFFECT_MAX_ALTITUDE depends on it. (030328)
	main_rotor_radius = aircraft_database [get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE)].main_rotor_radius;

	if((main_rotor_rpm > 1.0) && ((pos.y - min_altitude) < DOWNWASH_EFFECT_MAX_ALTITUDE))
	{
		
		number_of_main_rotors = (int) aircraft_database [get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE)].number_of_main_rotors;

		type_of_terrain = get_3d_terrain_point_data_type(&terrain_info);

		switch( get_terrain_type_class(type_of_terrain) )
		{
			case TERRAIN_CLASS_LAND: 
			{

				if(number_of_main_rotors > 1)
					type_of_downwash = DOWNWASH_TYPE_LAND_DUAL_ROTORS;
				else
					type_of_downwash = DOWNWASH_TYPE_LAND;
				
				create_downwash_effect(type_of_downwash, &pos, main_rotor_radius, main_rotor_rpm, min_altitude);
				break;
			}
			case TERRAIN_CLASS_WATER:
			{
				
				if(number_of_main_rotors > 1)
					type_of_downwash = DOWNWASH_TYPE_WATER_DUAL_ROTORS;
				else
					type_of_downwash = DOWNWASH_TYPE_WATER;

				create_downwash_effect(type_of_downwash, &pos, main_rotor_radius, main_rotor_rpm, min_altitude);
				break;
			}
			//Xhit: No downwash effect for FORESTS. (030328)
			case TERRAIN_CLASS_FOREST:
			default:
			{
				break;
			}
		}
	}
	
	return;
}
예제 #11
0
파일: downwash.c 프로젝트: Comanche93/eech
int create_downwash_effect_component(downwash_component *this_downwash_component, downwash_types downwash_type, vec3d *position, int *entity_index_list, float main_rotor_radius, float main_rotor_rpm, float min_altitude)
{
	int
		loop,
		count,
		terrain_type,
		trail_type;

	short int
		quadrant_x,
		quadrant_z;
	
	unsigned char
		alpha_percentage;

	float
		lifetime,
		lifetime_min,
		lifetime_max,
		scale_min,
		scale_max,
		scale,
		angle,
		radius,
		relative_radius,
		height,
		altitude,
		half_altitude,
		main_rotor_radius_minus_altitude;

	vec3d
		pos,
		offset,
		iv;

	terrain_3d_point_data
		terrain_info;

	entity
		*new_entity;

	memset (&terrain_info, 0, sizeof (terrain_3d_point_data));

	count = this_downwash_component->trail_count;

	if ( count < 1 )
	{
		return 0;
	}

	// Xhit: This is the altitude of the helicopter relative to the ground level. (030328)
	altitude = position->y - min_altitude;
	half_altitude = (altitude / 2.0);

	main_rotor_radius_minus_altitude = main_rotor_radius - altitude;

	scale_min = this_downwash_component->scale_min;
	scale_max = this_downwash_component->scale_max;

	lifetime_min = this_downwash_component->lifetime_min;
	lifetime_max = this_downwash_component->lifetime_max;

	// Xhit: initialising quadrant variables (030328)
	quadrant_x = 1;
	quadrant_z = 1;

	//
	// create smoke trails
	//

	for ( loop = 0 ; loop < count ; loop ++ )
	{
		lifetime = lifetime_min + fabs( ( lifetime_max - lifetime_min ) * sfrand1() );

		angle = frand1() * PI_OVER_TWO;

		relative_radius = main_rotor_radius * frand1();

		scale = relative_radius + scale_min;
		if(scale > scale_max)
				scale = scale_max;

		switch(downwash_type)
		{
			case DOWNWASH_TYPE_LAND:
			case DOWNWASH_TYPE_LAND_DUAL_ROTORS:
			{
				//Xhit: If altitude bigger than main rotor radius then the smoke should be centered beneath the helicopter. (030328)
				if(altitude >= main_rotor_radius)
				{
					radius = relative_radius;
					height = (half_altitude * (radius / main_rotor_radius) + half_altitude) * frand1();
			
				}else
				{
					radius = relative_radius + main_rotor_radius_minus_altitude;
					height = (half_altitude * ((radius - main_rotor_radius_minus_altitude) / main_rotor_radius) + half_altitude + scale ) * frand1();
				}
				break;
			}
			case DOWNWASH_TYPE_WATER:
			case DOWNWASH_TYPE_WATER_DUAL_ROTORS:
			{
				if(altitude >= main_rotor_radius)
				{
					radius = relative_radius;
			
				}else
				{
					radius = relative_radius + main_rotor_radius_minus_altitude;
				}

				// Xhit: Changed to 2 instead of main_rotor_radius so smoke is created just over water level (030515)
				height =  2 * frand1();
				break;
			}
			default:
			{
				debug_fatal("DOWNWASH : trying to create an unrecogniseable downwash effect");
				break;
			}
		}


		//Xhit: If main rotor(s) only (not displaced main rotors) then. (030328)
		if((this_downwash_component->create_in_all_quadrants) && (loop < 4))
		{
			//Xhit:	This cryptical thing is to determine in which quadrant this sprite is going to be created. (030328)
			//		 ^z
			//		 |
			//		1|0  x
			//		-+--->
			//		3|2
			//
			//		loop = 0 -> x=	1,	z=	1; loop = 1 -> x=	-1, z=	 1;
			//		loop = 2 -> x=   1,	z= -1; loop = 3 -> x=	-1, z=	-1;
			quadrant_x = 1 | -(loop & 1);
			quadrant_z = 1 | -(loop & 2);
						
			offset.x = quadrant_x * radius * ( cos ( angle ) );
			offset.y = height;
			offset.z = quadrant_z * radius * ( sin ( angle ) );

		}else
		//Xhit:	If scattered downwash effect and if the heli got more than one main rotor (on different axis) then 
		//			add two more trails at the sides of the heli. (030328)
		if((this_downwash_component->create_in_all_quadrants) && (loop >= 4) && (count == 6))
		{
			//Xhit: loop = 4 -> x=	1; loop = 5 -> x=	-1; (030328)
			quadrant_x = 1 | -(loop & 1);

			relative_radius = main_rotor_radius * frand1();

			offset.x = quadrant_x * radius;
			offset.y = height;
			offset.z = frand1() * (main_rotor_radius / 2);
		}else
		{
			debug_fatal("DOWNWASH : trying to create an unrecogniseable downwash effect");
		}

		pos.x = position->x + offset.x ;
		pos.z = position->z + offset.z;

		//Xhit: This is necessary if it's going to work on tilting terrain. (030328)
		get_3d_terrain_point_data (pos.x, pos.z, &terrain_info);
		pos.y = get_3d_terrain_point_data_elevation (&terrain_info);

		pos.y = pos.y + offset.y;

		bound_position_to_map_volume( &pos );

		//Xhit: Decide which trail type is going to be used, this makes mapping to type of downwash effect fast. (030328)
		terrain_type = get_3d_terrain_point_data_type(&terrain_info);
		trail_type = get_terrain_surface_type(terrain_type) + SMOKE_LIST_TYPE_DOWNWASH_START;

		#if DEBUG_MODULE
		
		debug_log("DOWNWASH.C: terrain_type: %d, trail_type: %d", terrain_type, trail_type);

		#endif		

		iv.x = pos.x - position->x;
		iv.y = relative_radius;
		iv.z = pos.z - position->z;

		//Xhit:	If heli on ground then let the dust-smoke fade in according to increasing main_rotor_rpm
		//		otherwise set it according to the altitude of the heli (higher = less dust smoke) (030328)
		if(altitude < 1.0)
		{
			alpha_percentage = (unsigned char)(main_rotor_rpm);
		}else
		{
			//Xhit: "+ 1.0" is to guarantee that alpha_percentage > 0. (030328)
			alpha_percentage = (unsigned char)((1.0 - (altitude / (DOWNWASH_EFFECT_MAX_ALTITUDE + 1.0))) * 100);
		}

		new_entity = create_local_entity
		(
			ENTITY_TYPE_SMOKE_LIST,
			entity_index_list[ loop ],
			ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, ENTITY_SUB_TYPE_EFFECT_SMOKE_LIST_DOWNWASH),
			ENTITY_ATTR_INT_VALUE (INT_TYPE_SMOKE_TYPE, trail_type),
			ENTITY_ATTR_INT_VALUE (INT_TYPE_COLOUR_ALPHA, alpha_percentage),
			ENTITY_ATTR_FLOAT_VALUE (FLOAT_TYPE_GENERATOR_LIFETIME, this_downwash_component->generator_lifetime),
			ENTITY_ATTR_FLOAT_VALUE (FLOAT_TYPE_FREQUENCY, this_downwash_component->frequency),
			ENTITY_ATTR_FLOAT_VALUE (FLOAT_TYPE_SMOKE_LIFETIME, lifetime),
			ENTITY_ATTR_FLOAT_VALUE (FLOAT_TYPE_SCALE, scale),
			ENTITY_ATTR_VEC3D (VEC3D_TYPE_INITIAL_VELOCITY, iv.x, iv.y, iv.z),
			ENTITY_ATTR_VEC3D (VEC3D_TYPE_POSITION, pos.x, pos.y, pos.z),
			ENTITY_ATTR_END
		);

		entity_index_list[ loop ] = get_local_entity_index( new_entity );
	}

	return count;
}
예제 #12
0
파일: mb_tgt.c 프로젝트: Comanche93/eech
int check_position_line_of_sight (entity *source, entity *target, vec3d *source_position, vec3d *target_position, mobile_los_check_criteria criteria)
{

	entity
		*collision_en;

	vec3d
		increment,
		collision_point,
		normal,
		#if LINE_DEBUG_MODULE
		old_position,
		#endif
		check_position,
		direction;

	float
		target_range,
		collision_distance,
		number_of_terrain_checks,
		terrain_elevation;

	terrain_3d_point_data
		terrain_info;

	ASSERT (source);

	ASSERT (target);

	ASSERT (source_position);

	ASSERT (target_position);

	direction.x = target_position->x - source_position->x;
	direction.y = target_position->y - source_position->y;
	direction.z = target_position->z - source_position->z;

	target_range = sqrt ((direction.x * direction.x) + (direction.z * direction.z));

	normalise_3d_vector (&direction);
	
	////////////////////////////////////////////////////////////////
	// COARSE line of sight check with terrain
	////////////////////////////////////////////////////////////////

	if (criteria &	MOBILE_LOS_CHECK_COURSE_TERRAIN)
	{
		number_of_terrain_checks = target_range / LOS_COARSE_CHECK_DISTANCE;
	
		increment.x = direction.x * LOS_COARSE_CHECK_DISTANCE;
		increment.y = direction.y * LOS_COARSE_CHECK_DISTANCE;
		increment.z = direction.z * LOS_COARSE_CHECK_DISTANCE;
	
		check_position = *source_position;
	
		memset (&terrain_info, 0, sizeof (terrain_3d_point_data));
	
		while (number_of_terrain_checks > 1.0)
		{
			#if LINE_DEBUG_MODULE
	
			old_position = check_position;
	
			#endif
	
			check_position.x += increment.x;
			check_position.y += increment.y;
			check_position.z += increment.z;
	
			get_3d_terrain_point_data (check_position.x, check_position.z, &terrain_info);
	
			terrain_elevation = get_3d_terrain_point_data_elevation (&terrain_info);
	
			if (terrain_elevation > check_position.y)
			{
	
				#if TEXT_DEBUG_MODULE
	
				debug_log ("MB_TGT: (%s -> %s) failed COURSE terrain LOS", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME));
	
				#endif
	
				return FALSE;
			}
	
			#if LINE_DEBUG_MODULE
	
			create_debug_3d_line (&old_position, &check_position, sys_col_yellow, 10.0);
	
			#endif
	
			number_of_terrain_checks --;
		}
	}
	
	////////////////////////////////////////////////////////////////
	// SOURCE END FINE line of sight check with terrain
	////////////////////////////////////////////////////////////////

	if (criteria &	MOBILE_LOS_CHECK_SOURCE_END_TERRAIN)
	{
		number_of_terrain_checks = target_range / LOS_FINE_CHECK_DISTANCE_SOURCE_END;
	
		number_of_terrain_checks = min (number_of_terrain_checks, LOS_NUMBER_OF_FINE_CHECKS_SOURCE_END);
	
		increment.x = direction.x * LOS_FINE_CHECK_DISTANCE_SOURCE_END;
		increment.y = direction.y * LOS_FINE_CHECK_DISTANCE_SOURCE_END;
		increment.z = direction.z * LOS_FINE_CHECK_DISTANCE_SOURCE_END;
	
		check_position = *source_position;
	
		while (number_of_terrain_checks > 1.0)
		{
			#if LINE_DEBUG_MODULE
	
			old_position = check_position;
	
			#endif
	
			check_position.x += increment.x;
			check_position.y += increment.y;
			check_position.z += increment.z;
	
			get_3d_terrain_point_data (check_position.x, check_position.z, &terrain_info);
	
			terrain_elevation = get_3d_terrain_point_data_elevation (&terrain_info);
	
			if (terrain_elevation > check_position.y)
			{
	
				#if TEXT_DEBUG_MODULE
	
				debug_log ("MB_TGT: (%s -> %s) failed FINE terrain LOS (source end)", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME));
	
				#endif
	
				return FALSE;
			}
	
			#if LINE_DEBUG_MODULE
	
			create_debug_3d_line (&old_position, &check_position, sys_col_yellow, 10.0);
	
			#endif
	
			number_of_terrain_checks --;
		}
	}
	
	////////////////////////////////////////////////////////////////
	// TARGET END FINE line of sight check with terrain
	////////////////////////////////////////////////////////////////

	if (criteria &	MOBILE_LOS_CHECK_TARGET_END_TERRAIN)
	{
		number_of_terrain_checks = target_range / LOS_FINE_CHECK_DISTANCE_TARGET_END;
	
		number_of_terrain_checks = min (number_of_terrain_checks, LOS_NUMBER_OF_FINE_CHECKS_TARGET_END);
	
		increment.x = direction.x * LOS_FINE_CHECK_DISTANCE_TARGET_END;
		increment.y = direction.y * LOS_FINE_CHECK_DISTANCE_TARGET_END;
		increment.z = direction.z * LOS_FINE_CHECK_DISTANCE_TARGET_END;
	
		check_position = *target_position;
	
		while (number_of_terrain_checks > 1.0)
		{
			#if LINE_DEBUG_MODULE
	
			old_position = check_position;
	
			#endif
	
			check_position.x -= increment.x;
			check_position.y -= increment.y;
			check_position.z -= increment.z;
	
			get_3d_terrain_point_data (check_position.x, check_position.z, &terrain_info);
	
			terrain_elevation = get_3d_terrain_point_data_elevation (&terrain_info);
	
			if (terrain_elevation > check_position.y)
			{
	
				#if TEXT_DEBUG_MODULE
	
				debug_log ("MB_TGT: (%s -> %s) failed FINE terrain LOS (target end)", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME));
	
				#endif
	
				return FALSE;
			}
	
			#if LINE_DEBUG_MODULE
	
			create_debug_3d_line (&old_position, &check_position, sys_col_yellow, 10.0);
	
			#endif
	
			number_of_terrain_checks --;
		}
	}

	////////////////////////////////////////////////////////////////
	// SOURCE END line of sight check with objects
	////////////////////////////////////////////////////////////////

	if (criteria &	MOBILE_LOS_CHECK_SOURCE_END_OBJECTS)
	{
		check_position.x = source_position->x + (direction.x * LOS_OBJECT_CHECK_DISTANCE_TARGET_END);
		check_position.y = source_position->y + (direction.y * LOS_OBJECT_CHECK_DISTANCE_TARGET_END);
		check_position.z = source_position->z + (direction.z * LOS_OBJECT_CHECK_DISTANCE_TARGET_END);

		collision_en = get_line_of_sight_collision_entity
							(
								source,
								target,
								source_position,
								&check_position,
								&collision_point,
								&normal
							);
	
		if (collision_en)
		{
	
			#if TEXT_DEBUG_MODULE

			debug_log ("MB_TGT: (%s -> %s) failed OBJECT LOS with %s (source end)", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_type_name (collision_en));
			
			#endif
	
			return FALSE;
		}
	}
	
	////////////////////////////////////////////////////////////////
	// TARGET END line of sight check with objects
	////////////////////////////////////////////////////////////////

	if (criteria &	MOBILE_LOS_CHECK_TARGET_END_OBJECTS)
	{	
		check_position.x = target_position->x - (direction.x * LOS_OBJECT_CHECK_DISTANCE_TARGET_END);
		check_position.y = target_position->y - (direction.y * LOS_OBJECT_CHECK_DISTANCE_TARGET_END);
		check_position.z = target_position->z - (direction.z * LOS_OBJECT_CHECK_DISTANCE_TARGET_END);

		collision_en = get_line_of_sight_collision_entity
							(
								source,
								target,
								target_position,
								&check_position,
								&collision_point,
								&normal
							);
	
		if (collision_en)
		{
			collision_distance = get_sqr_3d_range (&collision_point, target_position);

			if (collision_distance > (LOS_OBJECT_EXCLUDE_DISTANCE_TARGET_END * LOS_OBJECT_EXCLUDE_DISTANCE_TARGET_END))
			{
				#if TEXT_DEBUG_MODULE
			
				debug_log ("MB_TGT: (%s -> %s) failed OBJECT LOS with %s (target end)", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_type_name (collision_en));
			
				#endif
	
				return FALSE;
			}
		}
	}

	return TRUE;
}
예제 #13
0
void set_reverse_tactical_camera_values (entity *source, entity *target)
{
	camera
		*raw;

	int
		airborne;

	object_3d_index_numbers
		object_3d_index;

	object_3d_bounds
		*bounding_box;

	float
		length,
		radius,
		z_min,
		z_max,
		rad_alt,
		dx,
		dy,
		dz;

	vec3d
		source_position,
		target_position,
		direction;

	ASSERT (source);

	ASSERT (target);

	ASSERT (get_camera_entity ());

	raw = get_local_entity_data (get_camera_entity ());

	//
	// get camera position
	//

	if (get_local_entity_int_value (target, INT_TYPE_IDENTIFY_FIXED))
	{
		object_3d_index = get_local_entity_int_value (target, INT_TYPE_OBJECT_3D_SHAPE);

		bounding_box = get_object_3d_bounding_box (object_3d_index);

		dx = bounding_box->xmax - bounding_box->xmin;
		dy = bounding_box->ymax;
		dz = bounding_box->zmax - bounding_box->zmin;

		radius = sqrt ((dx * dx) + (dy * dy) + (dz * dz)) * 2.0;
	}
	else
	{
		z_min = get_local_entity_float_value (target, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE);
		z_max = get_local_entity_float_value (target, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE);

		ASSERT (z_min < z_max);

		radius = ((z_max - z_min) * 0.05) + z_min;
	}

	get_local_entity_target_point (source, &source_position);

	get_local_entity_target_point (target, &target_position);

	airborne = FALSE;

	if (get_local_entity_int_value (target, INT_TYPE_AIRBORNE_AIRCRAFT))
	{
		if (point_inside_map_area (&target_position))
		{
			rad_alt = max (target_position.y - get_3d_terrain_elevation (target_position.x, target_position.z), 0.0);

			if (rad_alt > z_min)
			{
				airborne = TRUE;
			}
		}
	}

	if (airborne)
	{
		direction.x = target_position.x - source_position.x;
		direction.y = target_position.y - source_position.y;
		direction.z = target_position.z - source_position.z;

		length = (direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z);

		if (length > 1.0)
		{
			length = sqrt (length);

			normalise_3d_vector_given_magnitude (&direction, length);
		}
		else
		{
			direction.x = 0.0;
			direction.y = 0.0;
			direction.z = -1.0;
		}
	}
	else
	{
		direction.x = target_position.x - source_position.x;
		direction.y = 0.0;
		direction.z = target_position.z - source_position.z;

		length = (direction.x * direction.x) + (direction.z * direction.z);

		if (length > 1.0)
		{
			length = sqrt (length);

			normalise_3d_vector_given_magnitude (&direction, length);
		}
		else
		{
			direction.x = 0.0;
			direction.z = -1.0;
		}

		direction.y = 0.5;

		normalise_3d_vector (&direction);
	}

	raw->position.x = target_position.x + (direction.x * radius);
	raw->position.y = target_position.y + (direction.y * radius);
	raw->position.z = target_position.z + (direction.z * radius);

	//
	// keep point above ground (unless point off map)
	//

	if (point_inside_map_area (&raw->position))
	{
		raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND);
	}

	//
	// get camera attitude
	//

	direction.x = target_position.x - raw->position.x;
	direction.y = target_position.y - raw->position.y;
	direction.z = target_position.z - raw->position.z;

	length = (direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z);

	if (length > 1.0)
	{
		length = sqrt (length);

		normalise_3d_vector_given_magnitude (&direction, length);

		get_matrix3x3_from_unit_vec3d (raw->attitude, &direction);
	}
	else
	{
		get_identity_matrix3x3 (raw->attitude);
	}

	//
	// motion vector
	//

	get_local_entity_vec3d (target, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector);
}
예제 #14
0
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;
}
예제 #15
0
void update_chase_camera (camera *raw)
{
	entity
		*en;

	float
		combined_heading,
		z_min,
		z_max;

	vec3d
		rel_camera_position;

	//
	// pre-amble
	//

	ASSERT (raw);

	ASSERT (raw->external_view_entity);

	en = raw->external_view_entity;

	//
	// adjust camera heading
	//

	if (adjust_view_left_key || joystick_pov_left)
	{
		raw->chase_camera_heading += CHASE_CAMERA_ROTATE_RATE * get_delta_time ();
	}
	else if (adjust_view_right_key || joystick_pov_right)
	{
		raw->chase_camera_heading -= CHASE_CAMERA_ROTATE_RATE * get_delta_time ();
	}

	raw->chase_camera_heading = wrap_angle (raw->chase_camera_heading);

	//
	// adjust camera pitch
	//

	if (adjust_view_up_key || joystick_pov_up)
	{
		raw->chase_camera_pitch -= CHASE_CAMERA_ROTATE_RATE * get_delta_time ();

		raw->chase_camera_pitch = max (CHASE_CAMERA_ROTATE_DOWN_LIMIT, raw->chase_camera_pitch);
	}
	else if (adjust_view_down_key || joystick_pov_down)
	{
		raw->chase_camera_pitch += CHASE_CAMERA_ROTATE_RATE * get_delta_time ();

		raw->chase_camera_pitch = min (CHASE_CAMERA_ROTATE_UP_LIMIT, raw->chase_camera_pitch);
	}

	if (adjust_view_zoom_in_key)
	{
		raw->chase_camera_zoom -= CHASE_CAMERA_ZOOM_RATE * get_delta_time ();

		raw->chase_camera_zoom = max (CHASE_CAMERA_ZOOM_IN_LIMIT, raw->chase_camera_zoom);
	}
	else if (adjust_view_zoom_out_key)
	{
		raw->chase_camera_zoom += CHASE_CAMERA_ZOOM_RATE * get_delta_time ();

		raw->chase_camera_zoom = min (CHASE_CAMERA_ZOOM_OUT_LIMIT, raw->chase_camera_zoom);
	}

	//
	// get camera attitude
	//

	if (get_local_entity_int_value (en, INT_TYPE_ALIVE) && raw->chase_camera_lock_rotate)
	{
		combined_heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING);
	}
	else
	{
		combined_heading = 0.0;
	}

	combined_heading += raw->chase_camera_heading;

	get_3d_transformation_matrix (raw->attitude, combined_heading, raw->chase_camera_pitch, 0.0);

	//
	// get camera position
	//

	if (in_flight_zoom_test)
	{
		z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE_TEST);
		z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE_TEST);
	}
	else
	{
		z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE);
		z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE);
	}

	ASSERT (z_min < z_max);

	rel_camera_position.x = 0.0;
	rel_camera_position.y = 0.0;
	rel_camera_position.z = -(((z_max - z_min) * raw->chase_camera_zoom * raw->chase_camera_zoom) + z_min);

	multiply_matrix3x3_vec3d (&rel_camera_position, raw->attitude, &rel_camera_position);

	get_local_entity_target_point (en, &raw->position);

	raw->position.x += rel_camera_position.x;
	raw->position.y += rel_camera_position.y;
	raw->position.z += rel_camera_position.z;

	//
	// keep point above ground (unless point off map)
	//

	if (point_inside_map_area (&raw->position))
	{
		raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND);
	}

	//
	// motion vector
	//

	get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector);
}
예제 #16
0
static entity *create_local (entity_types type, int index, char *pargs)
{
	entity
		*en;

	routed_vehicle
		*raw;

	entity_sub_types
		group_sub_type;

	float
		heading;

	vec3d
		*face_normal;

	////////////////////////////////////////
  	//
  	// VALIDATE
  	//
	////////////////////////////////////////

	validate_local_create_entity_index (index);

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_CREATE, NULL, type, index);

	#endif

	en = get_free_entity (index);

	if (en)
	{
		////////////////////////////////////////
   	//
   	// MALLOC ENTITY DATA
   	//
		////////////////////////////////////////

		set_local_entity_type (en, type);

		raw = malloc_fast_mem (sizeof (routed_vehicle));

		set_local_entity_data (en, raw);

		////////////////////////////////////////
   	//
   	// INITIALISE ALL ENTITY DATA TO 'WORKING' DEFAULT VALUES
		//
		// DO NOT USE ACCESS FUNCTIONS
		//
		// DO NOT USE RANDOM VALUES
		//
		////////////////////////////////////////

		memset (raw, 0, sizeof (routed_vehicle));

		//
		// mobile
		//

		raw->vh.mob.sub_type = ENTITY_SUB_TYPE_UNINITIALISED;

		raw->vh.mob.position.x = MID_MAP_X;
		raw->vh.mob.position.y = MID_MAP_Y;
		raw->vh.mob.position.z = MID_MAP_Z;

		get_identity_matrix3x3 (raw->vh.mob.attitude);

		raw->vh.mob.alive = TRUE;

		raw->vh.mob.side = ENTITY_SIDE_UNINITIALISED;

		raw->vh.operational_state = OPERATIONAL_STATE_UNKNOWN;

		//
		// vehicle
		//

		raw->vh.object_3d_shape = OBJECT_3D_INVALID_OBJECT_INDEX;

		raw->vh.weapon_config_type = WEAPON_CONFIG_TYPE_UNINITIALISED;

		raw->vh.selected_weapon = ENTITY_SUB_TYPE_WEAPON_NO_WEAPON;

		raw->vh.weapon_vector.x = 0.0;
		raw->vh.weapon_vector.y = 0.0;
		raw->vh.weapon_vector.z = 1.0;

		raw->vh.weapon_to_target_vector.x = 0.0;
		raw->vh.weapon_to_target_vector.y = 0.0;
		raw->vh.weapon_to_target_vector.z = -1.0;

		raw->vh.loading_door_state = VEHICLE_LOADING_DOORS_OPEN_FLOAT_VALUE;

		//
		// routed
		//

		////////////////////////////////////////
		//
		// OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES
		//
		////////////////////////////////////////

		set_local_entity_attributes (en, pargs);

		////////////////////////////////////////
		//
		// CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN
		//
		////////////////////////////////////////

		ASSERT (raw->vh.member_link.parent);

		ASSERT (get_local_entity_type (raw->vh.member_link.parent) == ENTITY_TYPE_GROUP);

		////////////////////////////////////////
		//
		// RESOLVE DEFAULT VALUES
		//
		////////////////////////////////////////

		raw->sub_route = NULL;

		//
		// side
		//

		if (raw->vh.mob.side == ENTITY_SIDE_UNINITIALISED)
		{
			raw->vh.mob.side = get_local_entity_int_value (raw->vh.member_link.parent, INT_TYPE_SIDE);
		}

		ASSERT (raw->vh.mob.side != ENTITY_SIDE_NEUTRAL);

		//
		// sub_type
		//

		if (raw->vh.mob.sub_type == ENTITY_SUB_TYPE_UNINITIALISED)
		{
			group_sub_type = get_local_entity_int_value (raw->vh.member_link.parent, INT_TYPE_ENTITY_SUB_TYPE);

			if (raw->vh.mob.side == ENTITY_SIDE_BLUE_FORCE)
			{
				raw->vh.mob.sub_type = group_database[group_sub_type].default_blue_force_sub_type;
			}
			else
			{
				raw->vh.mob.sub_type = group_database[group_sub_type].default_red_force_sub_type;
			}
		}

		ASSERT (entity_sub_type_vehicle_valid (raw->vh.mob.sub_type));

		//
		// 3D shape
		//

		if (raw->vh.object_3d_shape == OBJECT_3D_INVALID_OBJECT_INDEX)
		{
			raw->vh.object_3d_shape = vehicle_database[raw->vh.mob.sub_type].default_3d_shape;
		}

		//
		// weapon config
		//

		if (raw->vh.weapon_config_type == WEAPON_CONFIG_TYPE_UNINITIALISED)
		{
			raw->vh.weapon_config_type = vehicle_database[raw->vh.mob.sub_type].default_weapon_config_type;
		}

		ASSERT (weapon_config_type_valid (raw->vh.weapon_config_type));

		//
		// damage levels
		//

		raw->vh.damage_level = vehicle_database[raw->vh.mob.sub_type].initial_damage_level;

		//
		// radar dish rotation (ok to use a random number as this is for visual effect only)
		//

		raw->vh.radar_rotation_state = frand1 ();

		////////////////////////////////////////
		//
		// BUILD COMPONENTS
		//
		////////////////////////////////////////

		//
		// 3D object
		//

		raw->vh.inst3d = construct_3d_object (raw->vh.object_3d_shape);

		set_routed_vehicle_id_number (en);

		set_initial_rotation_angle_of_routed_vehicle_wheels (raw->vh.inst3d);

		//
		// align with terrain
		//

		get_3d_terrain_point_data (raw->vh.mob.position.x, raw->vh.mob.position.z, &raw->vh.terrain_info);

		heading = get_heading_from_attitude_matrix (raw->vh.mob.attitude);

		face_normal = get_3d_terrain_point_data_normal (&raw->vh.terrain_info);

		get_3d_transformation_matrix_from_face_normal_and_heading (raw->vh.mob.attitude, face_normal, heading);

		//
		// weapon config
		//

		raw->vh.weapon_package_status_array = malloc_fast_mem (SIZE_WEAPON_PACKAGE_STATUS_ARRAY);

		memset (raw->vh.weapon_package_status_array, 0, SIZE_WEAPON_PACKAGE_STATUS_ARRAY);

		load_local_entity_weapon_config (en);

		//
		// update force info
		//

		add_to_force_info (get_local_force_entity (raw->vh.mob.side), en);

		////////////////////////////////////////
		//
		// LINK INTO SYSTEM
		//
		////////////////////////////////////////

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_MEMBER, raw->vh.member_link.parent, raw->vh.member_link.child_pred);

		//
		// insert into LIST_TYPE_MEMBER before LIST_TYPE_VIEW
		//

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_VIEW, get_camera_entity (), get_local_entity_view_list_pred (en));

		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);
	}

	return (en);
}
예제 #17
0
파일: cm_satel.c 프로젝트: Comanche93/eech
void reset_satellite_camera (camera *raw)
{
	entity
		*en;

	vec3d
		pos,
		v;

	matrix3x3
		m;

	float
		heading,
		z_min,
		z_max,
		length;

	ASSERT (raw);

	ASSERT (raw->external_view_entity);

	en = raw->external_view_entity;

	z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE);
	z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE);

	//ASSERT (z_min < z_max);

	heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING);

	get_3d_transformation_matrix (m, heading, CHASE_CAMERA_RESET_PITCH, 0.0);

	v.x = 0.0;
	v.y = 0.0;
	v.z = 0.0;

	multiply_matrix3x3_vec3d (&v, m, &v);

	get_local_entity_target_point (en, &pos);

	raw->position.x = pos.x + v.x;
	raw->position.y = pos.y + v.y;
	raw->position.z = pos.z + v.z;
	
	//
	// keep point above ground (unless point off map)
	//
	
		if (point_inside_map_area (&raw->position))
		{
			raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND);
		}

	
	raw->motion_vector.y = raw->position.y;
	
	raw->position.y += 5000;
		
	//
	// attitude
	//

	v.x = pos.x - raw->position.x;
	v.y = pos.y - raw->position.y;
	v.z = pos.z - raw->position.z;

	length = (v.x * v.x) + (v.y * v.y) + (v.z * v.z);

	if (length > 1.0)
	{
		length = sqrt (length);

		normalise_3d_vector_given_magnitude (&v, length);

		get_matrix3x3_from_unit_vec3d (raw->attitude, &v);
	}
	else
	{
		get_identity_matrix3x3 (raw->attitude);
	}

	//
	// motion vector
	//

	raw->motion_vector.x = 0.0;
	raw->motion_vector.z = 0.0;
	
	raw->fly_by_camera_timer = frand1() * 150 + 80; // parasiting on the struct, can't get my own data...

}