Пример #1
0
static int load_local_pylon_entities (char *name)
{
	entity
		*last_entity,
		*last_last_entity,
		*new_entity;

	entity_sub_types
		sub_type;

	int
		type,
		node_count,
		*node_link_count,
		path_count,
		node_loop,
		path_loop,
		start,
		end,
		link_count,
		link_loop;

	vec3d
		*node_positions,
		pos;

	FILE
		*pylon_node_file_ptr,
		*pylon_link_file_ptr;

	char
		filename [1024];

	session_list_data_type
		*current_session;

	//
	// Create "Node" Pylons
	//

	ASSERT (get_valid_current_game_session ());

	ASSERT (name);

	current_session = get_current_game_session ();

	sprintf (filename, "%s//route//%s.nde", current_session->data_path, name);

	if (file_exist (filename))
	{
		pylon_node_file_ptr = safe_fopen (filename, "rb");

		fread (&node_count, sizeof (int), 1, pylon_node_file_ptr);

		node_positions = malloc_heap_mem (sizeof (vec3d) * node_count);

		node_link_count = malloc_heap_mem (sizeof (int) * node_count);

		for (node_loop = 0 ; node_loop < node_count ; node_loop ++)
		{
			fread (&pos, sizeof (vec3d), 1, pylon_node_file_ptr);

			node_positions [node_loop].x = pos.x;
			node_positions [node_loop].y = pos.y;
			node_positions [node_loop].z = pos.z;

			node_link_count [node_loop] = 0;
		}

		fclose (pylon_node_file_ptr);

		//
		// Create "Link" Pylons
		//

		sprintf (filename, "%s//route//%s.wp", current_session->data_path, name);

		pylon_link_file_ptr = safe_fopen (filename, "rb");

		fread (&path_count, sizeof (int), 1, pylon_link_file_ptr);

		new_entity = NULL;

		for (path_loop = 0 ; path_loop < path_count ; path_loop ++)
		{
			fread (&start, sizeof (int), 1, pylon_link_file_ptr);

			fread (&end, sizeof (int), 1, pylon_link_file_ptr);

			fread (&type, sizeof (int), 1, pylon_link_file_ptr);

			fread (&link_count, sizeof (int), 1, pylon_link_file_ptr);

			node_link_count [start] += 1;
			node_link_count [end] += 1;

			if (link_count > 0)
			{
				last_entity = NULL;

				last_last_entity = NULL;

				for (link_loop = 0 ; link_loop < link_count ; link_loop ++)
				{
					fread (&pos, sizeof (vec3d), 1, pylon_link_file_ptr);

					if (link_loop == 0)
					{
						sub_type = ENTITY_SUB_TYPE_FIXED_ELECTRICITY_PYLON_START_TERMINATOR;
					}
					else if (link_loop == link_count - 1)
					{
						sub_type = ENTITY_SUB_TYPE_FIXED_ELECTRICITY_PYLON_END_TERMINATOR;
					}
					else
					{
						sub_type = ENTITY_SUB_TYPE_FIXED_ELECTRICITY_PYLON_STANDARD;
					}

					new_entity = create_local_entity
					(
						ENTITY_TYPE_PYLON,
						ENTITY_INDEX_DONT_CARE,
						ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, sub_type),
						ENTITY_ATTR_VEC3D (VEC3D_TYPE_POSITION, pos.x, pos.y, pos.z),
						ENTITY_ATTR_FLOAT_VALUE (FLOAT_TYPE_HEADING, 0),
						ENTITY_ATTR_PTR_VALUE (PTR_TYPE_SUCC, last_entity),
						ENTITY_ATTR_END
					);

					calculate_pylon_heading (last_last_entity, last_entity, new_entity, &node_positions [start], &node_positions [end]);

					last_last_entity = last_entity;

					last_entity = new_entity;
				}

				// last pylon in the link
				calculate_pylon_heading (last_last_entity, last_entity, NULL, &node_positions [start], &node_positions [end]);
			}
		}

		for (node_loop = 0 ; node_loop < node_count ; node_loop ++)
		{
			//
			// create node entities here
			//
		}

		fclose (pylon_link_file_ptr);

		free_mem (node_positions);

		free_mem (node_link_count);

		return TRUE;
	}

	return FALSE;
}
Пример #2
0
entity *create_local_sound_effect_entity
			(
				int index,
				entity *parent,
				entity_sides side,
				entity_sub_types sub_type,
				sound_channel_types channel,
				sound_locality_types locality,
				vec3d *position,
				float amp,
				int valid,
				int looping,
				int sample_count,
				sound_sample_indices *sample_indices
			)
{
	entity
		*en;

	vec3d
		pos;

	int
		panning,
		create_stack_attributes;

	ASSERT (parent);

	create_stack_attributes = force_local_entity_create_stack_attributes;

	if (get_comms_data_flow () == COMMS_DATA_FLOW_RX)
	{
		set_force_local_entity_create_stack_attributes (TRUE);
	}

	panning = TRUE;

	if (position)
	{
		pos = *position;
	}
	else
	{
		position = get_local_entity_vec3d_ptr (parent, VEC3D_TYPE_POSITION);

		if (position)
		{
			pos = *position;
		}
		else
		{
			pos.x = MID_MAP_X;
			pos.y = MID_MAP_Y;
			pos.z = MID_MAP_Z;

			panning = FALSE;
		}
	}

	//
	// special cases for speech
	//
	
	switch (sub_type)
	{
		case ENTITY_SUB_TYPE_EFFECT_SOUND_RADIO_MESSAGE:
		{
			if (get_global_gunship_side () == side)
			{
				amp = adjust_radio_message_amplification (amp, &pos);
			}
			else
			{	
				amp = 0.0;
			}

			panning = FALSE;

			break;
		}

		case ENTITY_SUB_TYPE_EFFECT_SOUND_CPG_MESSAGE:
		case ENTITY_SUB_TYPE_EFFECT_SOUND_WARNING_MESSAGE:
		{
			if (parent == get_gunship_entity ())
			{
				amp = 1.0;
			}
			else
			{
				amp = 0.0;
			}

			panning = FALSE;

			break;
		}
	}

	//
	// create sound
	//

	en = create_local_entity
	(
		ENTITY_TYPE_SOUND_EFFECT,
		index,
		ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, sub_type),
		ENTITY_ATTR_PARENT (LIST_TYPE_SPECIAL_EFFECT, parent),
		ENTITY_ATTR_VEC3D (VEC3D_TYPE_POSITION, pos.x, pos.y, pos.z),
		ENTITY_ATTR_INT_VALUE (INT_TYPE_SOUND_CHANNEL, channel),
		ENTITY_ATTR_INT_VALUE (INT_TYPE_SOUND_EFFECT_LOOPING, looping),
		ENTITY_ATTR_INT_VALUE (INT_TYPE_SOUND_EFFECT_PANNING, panning),
		ENTITY_ATTR_INT_VALUE (INT_TYPE_SOUND_LOCALITY, locality),
		ENTITY_ATTR_INT_VALUE (INT_TYPE_VALID_SOUND_EFFECT, valid),
		ENTITY_ATTR_FLOAT_VALUE (FLOAT_TYPE_AMPLIFICATION, amp),
		ENTITY_ATTR_END
	);

	set_local_sound_effect_sample_indices (en, sample_count, sample_indices);

	#if DEBUG_MODULE

	debug_log ("SOUNDEFF : created effect %s (%d), parent %s (%d), next %d, looping %d, valid %d",
							application_sound_effects [sample_indices [0]].name,
							get_local_entity_index (en),
							get_local_entity_type_name (parent),
							get_local_entity_index (parent),
							looping,
							valid);

	#endif

	set_force_local_entity_create_stack_attributes (create_stack_attributes);

	return en;
}
Пример #3
0
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;
}