Esempio n. 1
0
static int response_to_unlink_child (entity_messages message, entity *receiver, entity *sender, va_list pargs)
{
	camera
		*raw;

	list_types
		list_type;

	#if DEBUG_MODULE

	debug_log_entity_message (message, receiver, sender, pargs);

	#endif

	raw = get_local_entity_data (receiver);

	list_type = va_arg (pargs, list_types);

	switch (list_type)
	{
		////////////////////////////////////////
		case LIST_TYPE_VIEW:
		////////////////////////////////////////
		{
			if (raw->external_view_entity == sender)
			{
				raw->external_view_entity = NULL;
			}

			notify_view_menu_of_view_list_change (sender);

			break;
		}
		////////////////////////////////////////
		case LIST_TYPE_VIEW_WEAPON:
		////////////////////////////////////////
		{
			ASSERT (sender);

			if (get_view_mode () == VIEW_MODE_EXTERNAL)
			{
				if (get_local_entity_int_value (get_camera_entity (), INT_TYPE_CAMERA_MODE) == CAMERA_MODE_WEAPON)
				{
					notify_local_entity (ENTITY_MESSAGE_SET_CAMERA_ACTION, get_camera_entity (), NULL, CAMERA_ACTION_WEAPON_EXPLOSION);

					reset_weapon_explosion_camera_position (get_local_entity_vec3d_ptr (sender, VEC3D_TYPE_POSITION));
				}
			}

			break;
		}
	}

	return (TRUE);
}
Esempio n. 2
0
void set_chase_camera_view_target_to_source (entity *source, entity *target)
{
	camera
		*raw;

	float
		length;

	vec3d
		*source_position,
		*target_position,
		direction;

	ASSERT (source);

	ASSERT (target);

	ASSERT (get_camera_entity ());

	raw = get_local_entity_data (get_camera_entity ());

	source_position = get_local_entity_vec3d_ptr (source, VEC3D_TYPE_POSITION);

	target_position = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION);

	direction.x = source_position->x - target_position->x;
	direction.y = source_position->y - target_position->y;
	direction.z = source_position->z - target_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);

		raw->chase_camera_heading = atan2 (direction.x, direction.z);

		if (raw->chase_camera_lock_rotate)
		{
			raw->chase_camera_heading -= get_local_entity_float_value (target, FLOAT_TYPE_HEADING);

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

		raw->chase_camera_pitch = asin (direction.y);
	}
}
Esempio n. 3
0
void restore_reverse_tactical_camera_values (void)
{
	camera
		*raw;

	ASSERT (get_camera_entity ());

	raw = get_local_entity_data (get_camera_entity ());

	raw->position = raw->stored_reverse_tactical_position;

	raw->motion_vector = raw->stored_reverse_tactical_motion_vector;

	memcpy (raw->attitude, raw->stored_reverse_tactical_attitude, sizeof (matrix3x3));
}
Esempio n. 4
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);
}
Esempio n. 5
0
static entity *create_local (entity_types type, int index, char *pargs)
{
	entity
		*en;

	camera
		*raw;

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

	ASSERT (!get_camera_entity ());

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

		set_local_entity_type (en, type);

		raw = (camera *) malloc_fast_mem (sizeof (camera));

		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 (camera));

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

		raw->offset.x = 0;
		raw->offset.y = 0;
		raw->offset.z = 0;

		raw->offset_movement.x = 0;
		raw->offset_movement.y = 0;
		raw->offset_movement.z = 0;

	
		raw->turbulence_offset.x = 0.0;
		raw->turbulence_offset.y = 0.0;
		raw->turbulence_offset.z = 0.0;
	
		raw->turbulence_movement.x = 0.0;
		raw->turbulence_movement.y = 0.0;
		raw->turbulence_movement.z = 0.0;
	
		get_identity_matrix3x3 (raw->attitude);

		raw->camera_mode = CAMERA_MODE_CHASE;

		raw->chase_camera_lock_rotate = TRUE;

		reset_chase_camera_position (raw);

		reset_cinematic_camera_for_new_view_entity (raw);

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

		set_local_entity_attributes (en, pargs);

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

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

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

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL);

		set_camera_entity (en);
	}

	return (en);
}
Esempio n. 6
0
static void unpack_local_data (entity *en, entity_types type, pack_modes mode)
{
	ASSERT ((mode >= 0) && (mode < NUM_PACK_MODES));

	switch (mode)
	{
		////////////////////////////////////////
		case PACK_MODE_SERVER_SESSION:
		case PACK_MODE_CLIENT_SESSION:
		////////////////////////////////////////
		{

			int
				index;

			routed_vehicle
				*raw;

			node_link_data
				*route_data;

			//
			// create entity
			//

			index = unpack_entity_safe_index ();

			en = get_free_entity (index);

			set_local_entity_type (en, type);

			raw = (routed_vehicle *) malloc_fast_mem (sizeof (routed_vehicle));

			set_local_entity_data (en, raw);

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

			//
			// unpack vehicle data (in exactly the same order as the data was packed)
			//

			unpack_vehicle_data (en, &raw->vh, mode);

			if (unpack_int_value (en, INT_TYPE_VALID))
			{

				raw->vh.mob.velocity = 0.0;

				raw->desired_velocity = 0.0;
			}
			else
			{

				raw->vh.mob.velocity = unpack_float_value (en, FLOAT_TYPE_LOW_VELOCITY);

				raw->desired_velocity = unpack_float_value (en, FLOAT_TYPE_DESIRED_VELOCITY);
			}

			//
			// unpack routed data
			//

			if (unpack_int_value (en, INT_TYPE_VALID))
			{
	
				raw->sub_waypoint_count = unpack_int_value (en, INT_TYPE_SUB_WAYPOINT_COUNT);
	
				raw->waypoint_next_index = unpack_int_value (en, INT_TYPE_WAYPOINT_NEXT_INDEX);
	
				raw->waypoint_this_index = unpack_int_value (en, INT_TYPE_WAYPOINT_THIS_INDEX);
			}

			//
			// turn lights on if necessary
			//

			set_vehicle_headlight_state (en, raw->vh.lights_on);

			//
			// setup waypoint route pointer
			//

			#if DEBUG_MODULE

			debug_log ("ROUTED ENTITY PACK: client setting up waypoint list pointer");

			#endif

			route_data = get_road_sub_route (raw->waypoint_this_index, raw->waypoint_next_index, &index, NULL);

			if ((route_data) && (route_data->link_positions))
			{

				raw->sub_route = route_data;
			}
			else
			{

				if ((raw->waypoint_this_index + raw->waypoint_next_index) != 0)
				{

					debug_log ("RV_PACK: WARNING NO SUB ROUTE FOUND BETWEEN %d AND %d", raw->waypoint_this_index, raw->waypoint_next_index);
				}
			}

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

			raw->vh.radar_rotation_state = frand1 ();

			set_routed_vehicle_id_number (en);

			set_initial_rotation_angle_of_routed_vehicle_wheels (raw->vh.inst3d);

			//
			// link into system
			//

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

			insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->vh.mob.position), NULL);

			insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL);

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

			//
			// attached smoke lists must be unpacked after the entity is linked into the world
			//

			unpack_routed_vehicle_meta_smoke_lists (en, mode);
	
			unpack_mobile_local_sound_effects (en, mode);

			break;
		}
		////////////////////////////////////////
		case PACK_MODE_BROWSE_SESSION:
		////////////////////////////////////////
		{

			break;
		}
		////////////////////////////////////////
		case PACK_MODE_UPDATE_ENTITY:
		////////////////////////////////////////
		{
			//
			// always use access functions to set the data
			//

			vec3d
				position;

			matrix3x3
				attitude;

			int
				sub_waypoint_count;

			//
			// unpack all data (even if the echoed data is to be ignored)
			//

			unpack_vec3d (en, VEC3D_TYPE_POSITION, &position);

			unpack_attitude_matrix (en, attitude);

			sub_waypoint_count = unpack_int_value (en, INT_TYPE_SUB_WAYPOINT_COUNT);

			set_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &position);

			set_local_entity_attitude_matrix (en, attitude);

			set_local_entity_int_value (en, INT_TYPE_SUB_WAYPOINT_COUNT, sub_waypoint_count);

			// Vehicle is moving so sleep must equal 0
			set_local_entity_float_value (en, FLOAT_TYPE_SLEEP, 0.0);

			break;
		}
	}
}
Esempio n. 7
0
void update_session_sound_effects (entity *en)
{
	session
		*raw;

	entity
		*spec;

	vec3d
		*camera_pos;

	weathermodes
		current_weather_mode,
		target_weather_mode;

	float
		alt,
		trans,
		value,
		light_wind_sound_level,
		heavy_wind_sound_level,
		rain_sound_levels [WEATHERMODE_LAST];

	ASSERT (en);

	raw = (session *) get_local_entity_data (en);

	if (in_cockpit)
	{
		camera_pos = get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION);

		alt = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_RADAR_ALTITUDE);
	}
	else
	{
		camera_pos = get_local_entity_vec3d_ptr (get_camera_entity (), VEC3D_TYPE_POSITION);

		alt = get_local_entity_float_value (get_camera_entity (), FLOAT_TYPE_RADAR_ALTITUDE);
	}

	//
	// rain
	//

	memset (rain_sound_levels, 0, sizeof (float) * WEATHERMODE_LAST);

	if (camera_pos->y < get_cloud_3d_base_height ())
	{
		if ((!in_cockpit) && (alt >= SESSION_RAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE))
		{
			//
			// rain should only make a sound when it hits either the cockpit, or the ground
			//
		}
		else
		{
			get_session_weather_at_point (camera_pos, &current_weather_mode, &target_weather_mode, &trans);

			if (target_weather_mode == current_weather_mode)
			{
				rain_sound_levels [target_weather_mode] = 1.0;
				rain_sound_levels [current_weather_mode] = 1.0;
			}
			else
			{
				rain_sound_levels [target_weather_mode] = trans;
				rain_sound_levels [current_weather_mode] = (1.0 - trans);
			}

			if (!in_cockpit)
			{
				rain_sound_levels [target_weather_mode] *= (1.0 - (alt / SESSION_RAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE));
				rain_sound_levels [current_weather_mode] *= (1.0 - (alt / SESSION_RAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE));
			}
		}
	}
	
	//
	// wind
	//
	{
		float
			r,
			wind_speed;
	
		wind_speed = get_session_wind_velocity_at_point (camera_pos, NULL);

		if (wind_speed <= raw->wind_minimum_speed)
		{
			r = 0.0;
		}
		else if (wind_speed >= raw->wind_maximum_speed)
		{
			r = 1.0;
		}
		else
		{
			r = (wind_speed - raw->wind_minimum_speed) / (raw->wind_maximum_speed - raw->wind_minimum_speed);
		}
		
		ASSERT ((r >= 0.0) && (r <= 1.0));

		if (r == 0.0)
		{
			light_wind_sound_level = 0.0;

			heavy_wind_sound_level = 0.0;
		}
		else if (r < 0.5)
		{
			light_wind_sound_level = r * 2.0;

			heavy_wind_sound_level = 0.0;
		}
		else
		{
			light_wind_sound_level = 1.0 - ((r - 0.5) * 2.0);

			heavy_wind_sound_level = (r - 0.5) * 2.0;
		}
	}

	//
	// terrain
	//
	{
		float
			xpos,
			zpos;

		xpos = bound (camera_pos->x, MIN_MAP_X, MAX_MAP_X);
		zpos = bound (camera_pos->z, MIN_MAP_Z, MAX_MAP_Z);
		
		get_terrain_3d_types_in_sector (xpos, zpos);
	}

	//
	// set new values
	//

	spec = get_local_entity_first_child (en, LIST_TYPE_SPECIAL_EFFECT);

	while (spec)
	{
		switch (get_local_entity_int_value (spec, INT_TYPE_ENTITY_SUB_TYPE))
		{
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_LIGHT_RAIN:
			{
				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, rain_sound_levels [WEATHERMODE_LIGHT_RAIN]);

				break;
			}
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_HEAVY_RAIN:
			{
				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, rain_sound_levels [WEATHERMODE_HEAVY_RAIN]);

				break;
			}
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_LIGHT_WIND:
			{
				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, light_wind_sound_level);

				break;
			}
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_HEAVY_WIND:
			{
				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, heavy_wind_sound_level);

				break;
			}
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_SEA:
			{
				if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)
				{
					value = 0.0;
				}
				else
				{
					value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION);
	

					if (terrain_types_in_sector [TERRAIN_TYPE_SEA])
					{
						value += (0.5 * get_delta_time ());
					}
					else
					{
						value -= (0.5 * get_delta_time ());
					}

					value = bound (value, 0.0, 0.3);

					value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0);

					if (in_cockpit)
					{
						value *= 0.75;
					}
				}

				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value);

				break;
			}
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_JUNGLE:
			{
				if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)
				{
					value = 0.0;
				}
				else
				{
					value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION);


					if (terrain_types_in_sector [TERRAIN_TYPE_FOREST_TOP])
					{
						value += (0.5 * get_delta_time ());
					}
					else
					{
						value -= (0.5 * get_delta_time ());
					}

					value = bound (value, 0.0, 0.3);
					value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0);

					if (in_cockpit)
					{
						value *= 0.75;
					}
				}

				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value);

				break;
	        }
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMB1:
			{
				if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)
				{
					value = 0.0;
				}
				else
				{
					value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION);
	
					if (terrain_types_in_sector [TERRAIN_TYPE_RIVER])
					{
						value += (0.5 * get_delta_time ());
					}
					else
					{
						value -= (0.5 * get_delta_time ());
					}
	
					value = bound (value, 0.0, 0.3);

					value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0);

					if (in_cockpit)
					{
						value *= 0.75;
					}
				}

				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value);

				break;
            }
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMB2:
			{
				if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)
				{
					value = 0.0;
				}
				else
				{
					value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION);
	
					if (terrain_types_in_sector [TERRAIN_TYPE_RESERVOIR])
					{
						value += (0.5 * get_delta_time ());
					}
					else
					{
						value -= (0.5 * get_delta_time ());
					}
	
					value = bound (value, 0.0, 0.3);

					value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0);

					if (in_cockpit)
					{
						value *= 0.75;
					}
				}

				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value);

				break;
            }
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMB3:
			{
				if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)
				{
					value = 0.0;
				}
				else
				{
					value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION);
	
					if (terrain_types_in_sector [TERRAIN_TYPE_ALTERED_LAND1])
					{
						value += (0.5 * get_delta_time ());
					}
					else
					{
						value -= (0.5 * get_delta_time ());
					}
	
					value = bound (value, 0.0, 0.3);

					value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0);

					if (in_cockpit)
					{
						value *= 0.75;
					}
				}

				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value);

				break;
            }
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMB4:
			{
				if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)
				{
					value = 0.0;
				}
				else
				{
					value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION);
	
					if (terrain_types_in_sector [TERRAIN_TYPE_ALTERED_LAND2])
					{
						value += (0.5 * get_delta_time ());
					}
					else
					{
						value -= (0.5 * get_delta_time ());
					}
	
					value = bound (value, 0.0, 0.3);

					value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0);

					if (in_cockpit)
					{
						value *= 0.75;
					}
				}

				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value);

				break;
			}
		}

		spec = get_local_entity_child_succ (spec, LIST_TYPE_SPECIAL_EFFECT);
	}
}
Esempio n. 8
0
void update_transitional_weather (entity *en)
{
	vec3d
		*camera_pos;

	session
		*raw;

	ASSERT (en);

	raw = (session *) get_local_entity_data (en);

	if (raw->local_weather_model)
	{
		//
		// local weather model
		//

		if (raw->weather_radius == 0.0)
		{
			//
			// weather is fine all across the map
			//
	
			raw->weather_mode = WEATHERMODE_DRY;
			raw->target_weather_mode = WEATHERMODE_DRY;
	
			raw->weather_mode_transitional_status = 1.0;
		}
		else
		{
			//
			// there is some bad weather somewhere on the map
			//

			if (in_cockpit)
			{
				camera_pos = get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION);
			}
			else
			{
				camera_pos = get_local_entity_vec3d_ptr (get_camera_entity (), VEC3D_TYPE_POSITION);
			}

			get_session_weather_at_point (camera_pos, &(raw->weather_mode), &(raw->target_weather_mode), &(raw->weather_mode_transitional_status));

			//
			// lightning effect
			//

			update_lightning_effect (en);
		}
		
		//
		// move weather
		//
	
		raw->weather_position.x += (raw->weather_velocity.x * get_delta_time ());
		raw->weather_position.z += (raw->weather_velocity.z * get_delta_time ());
	
		//
		// "bounce" weather of sides of map
		//
	
		if (raw->weather_position.x < MIN_MAP_X)
		{
			raw->weather_position.x = MIN_MAP_X;
	
			raw->weather_velocity.x = -raw->weather_velocity.x;
		}
		else if (raw->weather_position.x >= MAX_MAP_X)
		{
			raw->weather_position.x = MAX_MAP_X - 1.0;
	
			raw->weather_velocity.x = -raw->weather_velocity.x;
		}
	
		if (raw->weather_position.z < MIN_MAP_Z)
		{
			raw->weather_position.z = MIN_MAP_Z;
	
			raw->weather_velocity.z = -raw->weather_velocity.z;
		}
		else if (raw->weather_position.z >= MAX_MAP_Z)
		{
			raw->weather_position.z = MAX_MAP_Z - 1.0;
	
			raw->weather_velocity.z = -raw->weather_velocity.z;
		}

		//
		// expand / contract weather radius
		//

		if (raw->weather_increasing)
		{
			raw->weather_radius += (WEATHER_EXPANSION_RATE * get_delta_time ());

			if (raw->weather_radius > MAX_WEATHER_RADIUS)
			{
				raw->weather_increasing = FALSE;

				raw->weather_radius = MAX_WEATHER_RADIUS;
			}
		}
		else
		{
			raw->weather_radius -= (WEATHER_EXPANSION_RATE * get_delta_time ());

			if (raw->weather_radius < MIN_WEATHER_RADIUS)
			{
				raw->weather_increasing = TRUE;

				raw->weather_radius = MIN_WEATHER_RADIUS;
			}
		}
	}
	else
	{
		//
		// global weather model
		//
			
		if (raw->weather_mode != raw->target_weather_mode)
		{
			raw->weather_mode_transitional_status += get_delta_time () / raw->weather_mode_transitional_period;
	
			if (raw->weather_mode_transitional_status >= 1.0)
			{
				raw->weather_mode = raw->target_weather_mode;
	
				raw->weather_mode_transitional_status = 0.0;
			}
		}
		else
		{
			raw->weather_mode_transitional_status = 0.0;
		}
	}

	//
	// move wind
	//
	
	raw->wind_effect_position.x += (raw->wind_effect_velocity.x * get_delta_time ());
	raw->wind_effect_position.z += (raw->wind_effect_velocity.z * get_delta_time ());

	//
	// "bounce" wind_effect of sides of map
	//

	if (raw->wind_effect_position.x < MIN_MAP_X)
	{
		raw->wind_effect_position.x = MIN_MAP_X;

		raw->wind_effect_velocity.x = -raw->wind_effect_velocity.x;
	}
	else if (raw->wind_effect_position.x >= MAX_MAP_X)
	{
		raw->wind_effect_position.x = MAX_MAP_X - 1.0;

		raw->wind_effect_velocity.x = -raw->wind_effect_velocity.x;
	}

	if (raw->wind_effect_position.z < MIN_MAP_Z)
	{
		raw->wind_effect_position.z = MIN_MAP_Z;

		raw->wind_effect_velocity.z = -raw->wind_effect_velocity.z;
	}
	else if (raw->wind_effect_position.z >= MAX_MAP_Z)
	{
		raw->wind_effect_position.z = MAX_MAP_Z - 1.0;

		raw->wind_effect_velocity.z = -raw->wind_effect_velocity.z;
	}

	//
	// increase gusting value
	//

	raw->wind_gusting_value += (get_delta_time () * WIND_GUST_FREQUENCY);

	while (raw->wind_gusting_value >= 1.0)
	{
		raw->wind_gusting_value -= 1.0;
	}

	//
	// expand / contract wind_effect radius
	//

	if (raw->wind_increasing)
	{
		raw->wind_effect_radius += (WIND_EXPANSION_RATE * get_delta_time ());

		if (raw->wind_effect_radius > MAX_WIND_RADIUS)
		{
			raw->wind_increasing = FALSE;

			raw->wind_effect_radius = MAX_WIND_RADIUS;
		}
	}
	else
	{
		raw->wind_effect_radius -= (WIND_EXPANSION_RATE * get_delta_time ());

		if (raw->wind_effect_radius < MIN_WIND_RADIUS)
		{
			raw->wind_increasing = TRUE;

			raw->wind_effect_radius = MIN_WIND_RADIUS;
		}
	}

	//
	// set wind direction
	//

	raw->wind_direction_vector.x = raw->wind_effect_position.x - MID_MAP_X;
	raw->wind_direction_vector.y = 0.0;
	raw->wind_direction_vector.z = raw->wind_effect_position.z - MID_MAP_Z;

	normalise_any_3d_vector (&raw->wind_direction_vector);
}
Esempio n. 9
0
void unpack_local_session_data (pack_modes mode)
{
	session
		*raw;

	entity
		*en;

	int
		index;

   ASSERT ((mode >= 0) && (mode < NUM_PACK_MODES));

   switch (mode)
   {
      ////////////////////////////////////////
      case PACK_MODE_SERVER_SESSION:
      ////////////////////////////////////////
		{
			en = get_session_entity ();

			ASSERT (en);
			
			raw = (session *) get_local_entity_data (en);

			raw->version_number = unpack_int_value (en, INT_TYPE_VERSION_NUMBER);
		
			unpack_list_root (en, LIST_TYPE_FORCE, &raw->force_root);
		
			// special_effect_root
		
			// update_link
		
			raw->elapsed_time = unpack_float_value (en, FLOAT_TYPE_ELAPSED_TIME);
		
			raw->lightning_timer = unpack_float_value (en, FLOAT_TYPE_LIGHTNING_TIMER);
		
			raw->start_time = unpack_float_value (en, FLOAT_TYPE_START_TIME);
		
			// time_of_day_resync
		
			raw->time_of_day_acceleration = unpack_float_value (en, FLOAT_TYPE_TIME_OF_DAY_ACCELERATION);
		
			raw->fog_of_war_maximum_value = unpack_float_value (en, FLOAT_TYPE_FOG_OF_WAR_MAXIMUM_VALUE);
		
			//
			// rain effect
			//
		
			raw->weather_radius = unpack_float_value (en, FLOAT_TYPE_WEATHER_RADIUS);
			raw->weather_mode_transitional_period = unpack_float_value (en, FLOAT_TYPE_WEATHER_MODE_TRANSITIONAL_PERIOD);
			raw->weather_mode_transitional_status = unpack_float_value (en, FLOAT_TYPE_WEATHER_MODE_TRANSITIONAL_STATUS);
		
			raw->weather_mode = (weathermodes) unpack_int_value (en, INT_TYPE_WEATHER_MODE);
			raw->target_weather_mode = (weathermodes) unpack_int_value (en, INT_TYPE_TARGET_WEATHER_MODE);
		
			unpack_vec3d (en, VEC3D_TYPE_WEATHER_POSITION, &raw->weather_position);
			unpack_vec3d (en, VEC3D_TYPE_WEATHER_VELOCITY, &raw->weather_velocity);
		
			//
			// wind effect
			//
		
			raw->wind_effect_radius = unpack_float_value (en, FLOAT_TYPE_WIND_EFFECT_RADIUS);
			raw->wind_gusting_value = unpack_float_value (en, FLOAT_TYPE_WIND_GUSTING_VALUE);
			raw->wind_minimum_speed = unpack_float_value (en, FLOAT_TYPE_WIND_MINIMUM_SPEED);
			raw->wind_maximum_speed = unpack_float_value (en, FLOAT_TYPE_WIND_MAXIMUM_SPEED);
		
			unpack_vec3d (en, VEC3D_TYPE_WIND_DIRECTION_VECTOR, &raw->wind_direction_vector);
			unpack_vec3d (en, VEC3D_TYPE_WIND_EFFECT_POSITION, &raw->wind_effect_position);
			unpack_vec3d (en, VEC3D_TYPE_WIND_EFFECT_VELOCITY, &raw->wind_effect_velocity);
		
			//
		
			raw->day_segment_type = (day_segment_types) unpack_int_value (en, INT_TYPE_DAY_SEGMENT_TYPE);

			raw->population_x_min = unpack_float_value (en, FLOAT_TYPE_POPULATION_X_MIN);
			raw->population_x_max = unpack_float_value (en, FLOAT_TYPE_POPULATION_X_MAX);
			raw->population_z_min = unpack_float_value (en, FLOAT_TYPE_POPULATION_Z_MIN);
			raw->population_z_max = unpack_float_value (en, FLOAT_TYPE_POPULATION_Z_MAX);
		
			raw->campaign_medal = unpack_int_value (en, INT_TYPE_CAMPAIGN_MEDAL);
		
			raw->campaign_requires_apache_havoc = unpack_int_value (en, INT_TYPE_CAMPAIGN_REQUIRES_APACHE_HAVOC);
		
			raw->auto_assign_gunship = unpack_int_value (en, INT_TYPE_AUTO_ASSIGN_GUNSHIP);
		
			raw->infinite_fuel = unpack_int_value (en, INT_TYPE_INFINITE_FUEL);
		
			raw->infinite_weapons = unpack_int_value (en, INT_TYPE_INFINITE_WEAPONS);
		
			raw->suppress_ai_fire = unpack_int_value (en, INT_TYPE_SUPPRESS_AI_FIRE);
		
			raw->invulnerable_from_collisions = unpack_int_value (en, INT_TYPE_INVULNERABLE_FROM_COLLISIONS);

			raw->invulnerable_from_weapons = unpack_int_value (en, INT_TYPE_INVULNERABLE_FROM_WEAPONS);
		
			raw->cheats_enabled = unpack_int_value (en, INT_TYPE_CHEATS_ENABLED);
		
			raw->skip_night_time = unpack_int_value (en, INT_TYPE_SKIP_NIGHT_TIME);
		
			raw->weather_increasing = unpack_int_value (en, INT_TYPE_WEATHER_INCREASING);
		
			raw->wind_increasing = unpack_int_value (en, INT_TYPE_WIND_INCREASING);
		
			raw->local_weather_model = unpack_int_value (en, INT_TYPE_LOCAL_WEATHER_MODEL);

			break;
		}
      ////////////////////////////////////////
      case PACK_MODE_CLIENT_SESSION:
      ////////////////////////////////////////
      {
         //
         // create entity
         //

			ASSERT (!get_session_entity ());

			index = unpack_entity_safe_index ();

			en = get_free_entity (index);

			set_local_entity_type (en, ENTITY_TYPE_SESSION);

			raw = (session *) malloc_fast_mem (sizeof (session));

			set_local_entity_data (en, raw);

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

			//
			// unpack data (in exactly the same order as the data was packed)
			//

			raw->version_number = unpack_int_value (en, INT_TYPE_VERSION_NUMBER);

			raw->session_complete = unpack_int_value (en, INT_TYPE_SESSION_COMPLETE);
		
			unpack_list_root (en, LIST_TYPE_FORCE, &raw->force_root);

			unpack_list_root (en, LIST_TYPE_SPECIAL_EFFECT, &raw->special_effect_root);

			// update_link

			raw->elapsed_time = unpack_float_value (en, FLOAT_TYPE_ELAPSED_TIME);

         raw->lightning_timer = unpack_float_value (en, FLOAT_TYPE_LIGHTNING_TIMER);

			raw->start_time = unpack_float_value (en, FLOAT_TYPE_START_TIME);

			// time_of_day_resync

			raw->time_of_day_acceleration = unpack_float_value (en, FLOAT_TYPE_TIME_OF_DAY_ACCELERATION);

			raw->fog_of_war_maximum_value = unpack_float_value (en, FLOAT_TYPE_FOG_OF_WAR_MAXIMUM_VALUE);
		
			//
			// rain effect
			//

         raw->weather_radius = unpack_float_value (en, FLOAT_TYPE_WEATHER_RADIUS);
         raw->weather_mode_transitional_period = unpack_float_value (en, FLOAT_TYPE_WEATHER_MODE_TRANSITIONAL_PERIOD);
         raw->weather_mode_transitional_status = unpack_float_value (en, FLOAT_TYPE_WEATHER_MODE_TRANSITIONAL_STATUS);

         raw->weather_mode = (weathermodes) unpack_int_value (en, INT_TYPE_WEATHER_MODE);
         raw->target_weather_mode = (weathermodes) unpack_int_value (en, INT_TYPE_TARGET_WEATHER_MODE);

			unpack_vec3d (en, VEC3D_TYPE_WEATHER_POSITION, &raw->weather_position);
			unpack_vec3d (en, VEC3D_TYPE_WEATHER_VELOCITY, &raw->weather_velocity);

			//
			// wind effect
			//

			raw->wind_effect_radius = unpack_float_value (en, FLOAT_TYPE_WIND_EFFECT_RADIUS);
         raw->wind_gusting_value = unpack_float_value (en, FLOAT_TYPE_WIND_GUSTING_VALUE);
			raw->wind_minimum_speed = unpack_float_value (en, FLOAT_TYPE_WIND_MINIMUM_SPEED);
			raw->wind_maximum_speed = unpack_float_value (en, FLOAT_TYPE_WIND_MAXIMUM_SPEED);

			unpack_vec3d (en, VEC3D_TYPE_WIND_DIRECTION_VECTOR, &raw->wind_direction_vector);
			unpack_vec3d (en, VEC3D_TYPE_WIND_EFFECT_POSITION, &raw->wind_effect_position);
			unpack_vec3d (en, VEC3D_TYPE_WIND_EFFECT_VELOCITY, &raw->wind_effect_velocity);

			//

			raw->day_segment_type = (day_segment_types) unpack_int_value (en, INT_TYPE_DAY_SEGMENT_TYPE);

			raw->population_x_min = unpack_float_value (en, FLOAT_TYPE_POPULATION_X_MIN);
			raw->population_x_max = unpack_float_value (en, FLOAT_TYPE_POPULATION_X_MAX);
			raw->population_z_min = unpack_float_value (en, FLOAT_TYPE_POPULATION_Z_MIN);
			raw->population_z_max = unpack_float_value (en, FLOAT_TYPE_POPULATION_Z_MAX);
		
			raw->campaign_medal = unpack_int_value (en, INT_TYPE_CAMPAIGN_MEDAL);
		
			raw->campaign_requires_apache_havoc = unpack_int_value (en, INT_TYPE_CAMPAIGN_REQUIRES_APACHE_HAVOC);

			raw->auto_assign_gunship = unpack_int_value (en, INT_TYPE_AUTO_ASSIGN_GUNSHIP);

         raw->infinite_fuel = unpack_int_value (en, INT_TYPE_INFINITE_FUEL);

         raw->infinite_weapons = unpack_int_value (en, INT_TYPE_INFINITE_WEAPONS);

         raw->suppress_ai_fire = unpack_int_value (en, INT_TYPE_SUPPRESS_AI_FIRE);
		
			raw->invulnerable_from_collisions = unpack_int_value (en, INT_TYPE_INVULNERABLE_FROM_COLLISIONS);

			raw->invulnerable_from_weapons = unpack_int_value (en, INT_TYPE_INVULNERABLE_FROM_WEAPONS);

			raw->cheats_enabled = unpack_int_value (en, INT_TYPE_CHEATS_ENABLED);
		
         raw->skip_night_time = unpack_int_value (en, INT_TYPE_SKIP_NIGHT_TIME);

         raw->weather_increasing = unpack_int_value (en, INT_TYPE_WEATHER_INCREASING);

         raw->wind_increasing = unpack_int_value (en, INT_TYPE_WIND_INCREASING);

         raw->local_weather_model = unpack_int_value (en, INT_TYPE_LOCAL_WEATHER_MODEL);

			//
			// link into system
			//

			//
			// need to insert session into update list after camera entity
			//

			ASSERT (get_camera_entity ());

         insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), get_camera_entity ());

			set_session_entity (en);

			set_display_campaign_timer_valid (FALSE);

			break;
		}

		////////////////////////////////////////
		case PACK_MODE_BROWSE_SESSION:
		////////////////////////////////////////
		{
			//
			// create entity
			//

			ASSERT (!get_session_entity ());

			index = unpack_entity_safe_index ();

			en = get_free_entity (index);

			set_local_entity_type (en, ENTITY_TYPE_SESSION);

			raw = (session *) malloc_fast_mem (sizeof (session));

			set_local_entity_data (en, raw);

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

			//
			// unpack data (in exactly the same order as the data was packed)
			//

         raw->version_number = unpack_int_value (en, INT_TYPE_VERSION_NUMBER);

			unpack_list_root (en, LIST_TYPE_FORCE, &raw->force_root);

			// update_link

			// tour of duty time

			raw->elapsed_time = unpack_float_value (en, FLOAT_TYPE_ELAPSED_TIME);

			raw->start_time = unpack_float_value (en, FLOAT_TYPE_START_TIME);

			// time_of_day_resync

			// time_of_day_acceleration

			// weather radius

			// weather_mode_transitional_period

			// weather_mode_transitional_status

			raw->weather_mode = (weathermodes) unpack_int_value (en, INT_TYPE_WEATHER_MODE);

			// target_weather_mode

			// weather position

			// weather velocity

			raw->day_segment_type = (day_segment_types) unpack_int_value (en, INT_TYPE_DAY_SEGMENT_TYPE);

			raw->population_x_min = unpack_float_value (en, FLOAT_TYPE_POPULATION_X_MIN);
			raw->population_x_max = unpack_float_value (en, FLOAT_TYPE_POPULATION_X_MAX);
			raw->population_z_min = unpack_float_value (en, FLOAT_TYPE_POPULATION_Z_MIN);
			raw->population_z_max = unpack_float_value (en, FLOAT_TYPE_POPULATION_Z_MAX);
		
			raw->campaign_requires_apache_havoc = unpack_int_value (en, INT_TYPE_CAMPAIGN_REQUIRES_APACHE_HAVOC);

			// infinite_weapons

			// skip_night_time

			// weather increasing

			set_session_entity (en);

			break;
		}
	}
}
Esempio n. 10
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);
}
Esempio n. 11
0
static entity *create_local (entity_types type, int index, char *pargs)
{
	entity
		*en;

	weapon
		*raw;

	int
		seed;

	viewpoint
		vp;

	////////////////////////////////////////
  	//
  	// 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)
	{
		float dispersion;

		////////////////////////////////////////
   	//
   	// MALLOC ENTITY DATA
   	//
		////////////////////////////////////////

		set_local_entity_type (en, type);

		raw = (weapon *) malloc_fast_mem (sizeof (weapon));

		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 (weapon));

		//
		// mobile
		//

		raw->mob.sub_type = ENTITY_SUB_TYPE_UNINITIALISED;

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

		get_identity_matrix3x3 (raw->mob.attitude);

		raw->mob.alive = TRUE;

		//
		// weapon
		//

		raw->kill_code = WEAPON_KILL_CODE_OK;

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

		set_local_entity_attributes (en, pargs);

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

		ASSERT (entity_sub_type_weapon_valid (raw->mob.sub_type));

		ASSERT (raw->launched_weapon_link.parent);

		ASSERT (raw->burst_size > 0);

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

		if (weapon_database[raw->mob.sub_type].acquire_parent_forward_velocity)
		{
			raw->mob.velocity = get_local_entity_float_value (raw->launched_weapon_link.parent, FLOAT_TYPE_VELOCITY);
		}
		else
		{
			//
			// overwrite attribute
			//

			raw->mob.velocity = 0.0;
		}

		raw->mob.velocity += weapon_database[raw->mob.sub_type].muzzle_velocity;

		seed = get_client_server_entity_random_number_seed (en);

		raw->mob.velocity += weapon_database[raw->mob.sub_type].muzzle_velocity_max_error * frand1x (&seed);

		raw->weapon_lifetime = weapon_database[raw->mob.sub_type].burn_time;

		raw->decoy_timer = get_decoy_timer_start_value (weapon_database[raw->mob.sub_type].decoy_type);

		//
		// detach weapon from launcher (get position and attitude)
		//

		detach_local_entity_weapon (raw->launched_weapon_link.parent, raw->mob.sub_type, raw->burst_size, &vp);

		raw->mob.position = vp.position;

		// arneh - add dispersion as random rotation in heading and pitch up to max error angle
		dispersion = weapon_database[raw->mob.sub_type].max_range_error_ratio;
		if (dispersion > 0.0)
		{
			matrix3x3
				m;

			float
				heading = dispersion * sfrand1norm(),
				pitch = dispersion * sfrand1norm();

			get_3d_transformation_matrix(m, heading, pitch, 0.0);
			multiply_matrix3x3_matrix3x3(raw->mob.attitude, vp.attitude, m);
		}
		else
			memcpy (raw->mob.attitude, vp.attitude, sizeof (matrix3x3));

		//
		// interest level
		//

		set_local_entity_float_value (raw->launched_weapon_link.parent, FLOAT_TYPE_VIEW_INTEREST_LEVEL, DEFAULT_VIEW_INTEREST_LEVEL);

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

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_LAUNCHED_WEAPON, raw->launched_weapon_link.parent, NULL);

		if (raw->mob.target_link.parent)
		{
			insert_local_entity_into_parents_child_list (en, LIST_TYPE_TARGET, raw->mob.target_link.parent, NULL);
		}

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->mob.position), NULL);

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL);

		if (tacview_is_logging())
			write_tacview_new_unit(en);

		//
		// check if the weapon camera is primed and this weapon has been launched by the external view entity
		//

		if (get_camera_entity ())
		{
			if (get_local_entity_int_value (get_camera_entity (), INT_TYPE_WEAPON_CAMERA_PRIMED))
			{
				if (raw->launched_weapon_link.parent == get_external_view_entity ())
				{
					if (get_local_entity_int_value (en, INT_TYPE_VIEWABLE_WEAPON))
					{
						notify_local_entity (ENTITY_MESSAGE_SET_CAMERA_ACTION, get_camera_entity (), NULL, CAMERA_ACTION_WEAPON);

						set_local_entity_int_value (get_camera_entity (), INT_TYPE_WEAPON_CAMERA_PRIMED, FALSE);
					}
				}
			}
		}
	}

	return (en);
}
Esempio n. 12
0
static entity *create_local (entity_types type, int index, char *pargs)
{
	entity
		*en;

	fixed_wing
		*raw;

	entity_sub_types
		group_sub_type;

	////////////////////////////////////////
  	//
  	// 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 (fixed_wing));

		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 (fixed_wing));

		//
		// mobile
		//

		raw->ac.mob.sub_type = ENTITY_SUB_TYPE_UNINITIALISED;

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

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

		raw->ac.mob.alive = TRUE;

		raw->ac.mob.side = ENTITY_SIDE_UNINITIALISED;

		raw->ac.operational_state = OPERATIONAL_STATE_UNKNOWN;

		//
		// aircraft
		//

		raw->ac.object_3d_shape = OBJECT_3D_INVALID_OBJECT_INDEX;

		raw->ac.weapon_config_type = WEAPON_CONFIG_TYPE_UNINITIALISED;

		raw->ac.selected_weapon = ENTITY_SUB_TYPE_WEAPON_NO_WEAPON;

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

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

		raw->ac.loading_door_state = AIRCRAFT_LOADING_DOORS_OPEN_FLOAT_VALUE;
		raw->ac.undercarriage_state = AIRCRAFT_UNDERCARRIAGE_DOWN_FLOAT_VALUE;

		raw->ac.air_radar_contact_timeout = AIR_RADAR_CONTACT_TIMEOUT_INVALID;

		//
		// fixed_wing
		//

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

		set_local_entity_attributes (en, pargs);

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

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

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

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

		//
		// side
		//

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

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

		//
		// sub_type
		//

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

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

		ASSERT (entity_sub_type_aircraft_valid (raw->ac.mob.sub_type));

		//
		// 3D shape
		//

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

		//
		// weapon config
		//

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

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

		//
		// damage levels
		//

		raw->ac.damage_level = aircraft_database[raw->ac.mob.sub_type].initial_damage_level;

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

		//
		// 3D object
		//

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

		set_fixed_wing_id_number (en);

		initialise_fixed_wing_propellors (en);

		#if RECOGNITION_GUIDE

		raw->ac.loading_door_state = AIRCRAFT_LOADING_DOORS_CLOSED_FLOAT_VALUE;

		#endif

		//
		// weapon config
		//

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

		memset (raw->ac.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->ac.mob.side), en);

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

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_MEMBER, raw->ac.member_link.parent, raw->ac.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->ac.mob.position), NULL);

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL);
	}

	return (en);
}