Example #1
0
float get_ka50_missile_flight_time (void)
{
	entity
		*en,
		*weapon,
		*target;

	vec3d
		*weapon_position,
		*target_position;

	float
		flight_time,
		weapon_velocity,
		target_range;

	flight_time = 0.0;

	en = get_gunship_entity ();

	//
	// find most recently launched Vikhr with a target (first found on list)
	//

	weapon = get_local_entity_first_child (en, LIST_TYPE_LAUNCHED_WEAPON);

	while (weapon)
	{
		if (get_local_entity_int_value (weapon, INT_TYPE_ENTITY_SUB_TYPE) == ENTITY_SUB_TYPE_WEAPON_VIKHR)
		{
			target = get_local_entity_parent (weapon, LIST_TYPE_TARGET);

			if (target)
			{
				weapon_position = get_local_entity_vec3d_ptr (weapon, VEC3D_TYPE_POSITION);

				target_position = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION);

				target_range = get_3d_range (weapon_position, target_position);

				weapon_velocity = get_local_entity_float_value (weapon, FLOAT_TYPE_VELOCITY);

				if (weapon_velocity > 0.0)
				{
					flight_time = target_range / weapon_velocity;

					break;
				}
			}
		}

		weapon = get_local_entity_child_succ (weapon, LIST_TYPE_LAUNCHED_WEAPON);
	}

	return (flight_time);
}
Example #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);
	}
}
Example #3
0
void initialise_free_flight_screen_map_page_objects (void)
{
	vec3d
		*pos;
		
	set_active_map_object (NULL);

	if (get_gunship_entity ())
	{
		pos = get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION);

		page_map_dimensions.x = pos->x;
		page_map_dimensions.z = pos->z;

		page_map_dimensions.size = 32.0 * KILOMETRE;
	}
	else
	{
		page_map_dimensions.x = MID_MAP_X;
		page_map_dimensions.z = MID_MAP_Z;

		page_map_dimensions.size = min (MAX_MAP_X - MIN_MAP_X, MAX_MAP_Z - MIN_MAP_Z);
	}
	
	page_map_dimensions.selected_entity = NULL;

	clear_map_mouse_over_object (&page_map_dimensions);
}
Example #4
0
float adjust_radio_message_amplification (float amp, vec3d *pos)
{
	float
		d,
		range;

	if (!get_gunship_entity ())
	{
		return amp;
	}

	ASSERT (pos);

	range = get_approx_3d_range (get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION), pos);

	if (range > 120 * KILOMETRE)
	{
		return 0.0;
	}

	if (range < 1 * KILOMETRE)
	{
		return amp;
	}

	d = ((120 * KILOMETRE) - range) / ((120 * KILOMETRE) - (1 * KILOMETRE));

	return (d * amp);
}
Example #5
0
static void draw_page_3d_scene (ui_object *obj, void *arg)
{
    entity
    *en;

    viewpoint
    vp;

    vec3d
    *pos,
    vec;

    en = get_local_entity_safe_ptr (get_ui_object_item_number (obj));

    if (en)
    {
        pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

        ASSERT (pos);

        get_3d_unit_vector_from_heading_and_pitch (&vec, page_3d_heading, page_3d_pitch);

        vp.x = pos->x + (page_3d_distance * vec.x);
        vp.y = pos->y + (page_3d_distance * vec.y);
        vp.z = pos->z + (page_3d_distance * vec.z);

        invert_3d_vector (&vec);

        get_matrix3x3_from_unit_vec3d (vp.attitude, &vec);

        draw_campaign_screen_3d_scene (obj, &vp);
    }
}
Example #6
0
int check_entity_line_of_sight (entity *source, entity *target, mobile_los_check_criteria criteria)
{
	vec3d
		*source_position,
		*target_position;

	ASSERT (source);

	ASSERT (target);

	source_position = get_local_entity_vec3d_ptr (source, VEC3D_TYPE_POSITION);

	target_position = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION);

	return check_position_line_of_sight (source, target, source_position, target_position, criteria);
}
Example #7
0
int clear_ship_fires (entity *ship_en, entity_sub_types type)
{
	entity
		*en;

	vec3d
		*pos;

	en = get_local_entity_first_child (ship_en, LIST_TYPE_SPECIAL_EFFECT);

	while (en)
	{
		if (en->type == ENTITY_TYPE_SMOKE_LIST)
		{
			if (get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE) == type)
			{
				pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

				if (pos->y < 0.0)
				{
					set_local_entity_float_value (en, FLOAT_TYPE_GENERATOR_LIFETIME, 0.0);
				}
			}
      }

		en = get_local_entity_child_succ (en, LIST_TYPE_SPECIAL_EFFECT);
	}

	return TRUE;
}
Example #8
0
static void set_eo_view_params(target_acquisition_systems system, int x_min, int y_min, int x_max, int y_max, float xfov, float yfov)
{
	display_3d_light_levels
		light_level;

	display_3d_noise_levels
		noise_level;

	vec3d
		*position;

	weathermodes
		weather_mode;

	day_segment_types
		day_segment_type;

	display_3d_tints
		tint;

	position = get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION);

	weather_mode = get_simple_session_weather_at_point (position);
	ASSERT ((weather_mode > WEATHERMODE_INVALID) && (weather_mode < WEATHERMODE_LAST));

	day_segment_type = (day_segment_types) get_local_entity_int_value (get_session_entity (), INT_TYPE_DAY_SEGMENT_TYPE);
	ASSERT ((day_segment_type >= 0) && (day_segment_type < NUM_DAY_SEGMENT_TYPES));

	switch (system)
	{
		case TARGET_ACQUISITION_SYSTEM_FLIR:
		{
			light_level = flir_light_levels[weather_mode][day_segment_type];
			noise_level = flir_noise_levels[weather_mode][day_segment_type];
			tint = DISPLAY_3D_TINT_AMBER;

			break;
		}
		case TARGET_ACQUISITION_SYSTEM_LLLTV:
		{
			light_level = llltv_light_levels[weather_mode][day_segment_type];
			noise_level = llltv_noise_levels[weather_mode][day_segment_type];
			tint = DISPLAY_3D_TINT_AMBER_VISUAL;

			break;
		}
		default:
		{
			debug_fatal ("Invalid target acquisition system = %d", system);

			break;
		}
	}

	set_main_3d_params (tint, light_level, noise_level, x_min, y_min, x_max, y_max, xfov, yfov);
}
Example #9
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);
}
Example #10
0
static vec3d *get_local_vec3d_ptr (entity *en, vec3d_types type)
{
	group
		*raw;

	vec3d
		*v;

	raw = (group *) get_local_entity_data (en);

	switch (type)
	{
		////////////////////////////////////////
		case VEC3D_TYPE_POSITION:
		////////////////////////////////////////
		{
			entity
				*member;

			member = (entity *) get_local_entity_ptr_value (en, PTR_TYPE_GROUP_LEADER);

			if (member)
			{
				v = get_local_entity_vec3d_ptr (member, type);
			}
			else
			{
				v = NULL;
			}

			break;
		}
		////////////////////////////////////////
		case VEC3D_TYPE_LAST_KNOWN_POSITION:
		////////////////////////////////////////
		{
			v = &raw->last_known_position;

			break;
		}
		////////////////////////////////////////
		default:
		////////////////////////////////////////
		{
			debug_fatal_invalid_vec3d_type (en, type);

			break;
		}
	}

	return (v);
}
Example #11
0
static int response_to_articulate_undercarriage (entity_messages message, entity *receiver, entity *sender, va_list pargs)
{
	vec3d
		*position;

	object_3d_instance
		*inst3d;

	sound_sample_indices
		sample_index;

	#if DEBUG_MODULE

	//debug_log_entity_message (message, receiver, sender, pargs);

	#endif

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

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

	if (inst3d)
	{
		if (object_contains_sub_object_type (inst3d, OBJECT_3D_SUB_OBJECT_UNDERCARRIAGE, 0, NULL))
		{
			position = get_local_entity_vec3d_ptr (receiver, VEC3D_TYPE_POSITION);

			sample_index = SOUND_SAMPLE_INDEX_UNDERCARRIAGE;

			create_client_server_sound_effect_entity
			(
				receiver,
				ENTITY_SIDE_NEUTRAL,
				ENTITY_SUB_TYPE_EFFECT_SOUND_MISC,
				SOUND_CHANNEL_SOUND_EFFECT,
				SOUND_LOCALITY_ALL,
				NULL, 											// position
				1.0,												// amplification
				1.0,												// Werewolf pitch
				TRUE,												// valid sound effect
				FALSE,											// looping
				1,													// sample count
				&sample_index									// sample index list
			);
		}
	}

	return (TRUE);
}
Example #12
0
void get_mi24_map_caret_position(float *x, float *z)
{
	if (!hind_damage.navigation_computer)
	{
		vec3d
			*position;
		float
			nx,
			nz;

		position = get_local_entity_vec3d_ptr (get_gunship_entity(), VEC3D_TYPE_POSITION);

		nx = (position->x - map_centre_position.x) * map_scale * 0.125,
		nz = (position->z - map_centre_position.z) * map_scale * 0.115;

		*x = bound(nx, -0.12, 0.12);
		*z = bound(nz, -0.075, 0.065);
	}
}
Example #13
0
void update_waypoint_shared_mem()
{
	entity* wp;

	if (!gPtrSharedMemory || !get_gunship_entity())
		return;

	wp = get_local_entity_current_waypoint(get_gunship_entity());

	if (wp)
	{
		vec3d
			*gunship_position,
			waypoint_position;

		float
			dx,
			dz,
			bearing;

		gunship_position = get_local_entity_vec3d_ptr(get_gunship_entity(), VEC3D_TYPE_POSITION);
		get_waypoint_display_position (get_gunship_entity(), wp, &waypoint_position);

		gPtrSharedMemory->waypoint_data.waypoint = get_local_entity_char_value(wp, CHAR_TYPE_TAG);
		gPtrSharedMemory->waypoint_data.waypoint_range = get_2d_range (gunship_position, &waypoint_position);

		dx = waypoint_position.x - gunship_position->x;
		dz = waypoint_position.z - gunship_position->z;

		bearing = deg(atan2(dx, dz));
		if (bearing < 0.0)
			bearing += 360.0;

		gPtrSharedMemory->waypoint_data.waypoint_bearing = bearing;
	}
	else
		memset(&gPtrSharedMemory->waypoint_data, 0, sizeof(waypoint_data_t));
}
Example #14
0
void create_force_campaign_objectives (entity *force)
{
	entity
		*keysite,
		*target_force,
		**list;

	int
		loop,
		count,
		side,
		target_side;

	float
		highest,
		*rating;

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	ASSERT (get_session_entity ());

	ASSERT (force);

	side = get_local_entity_int_value (force, INT_TYPE_SIDE);

	//
	// count up potential objective keysites
	//

	count = 0;

	target_force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE);

	while (target_force)
	{
		if (target_force != force)
		{
			keysite = get_local_entity_first_child (target_force, LIST_TYPE_KEYSITE_FORCE);

			while (keysite)
			{
				if (get_local_entity_int_value (keysite, INT_TYPE_POTENTIAL_CAMPAIGN_OBJECTIVE))
				{
					if (get_local_entity_int_value (keysite, INT_TYPE_IN_USE))
					{
						count ++;
					}
				}

				keysite = get_local_entity_child_succ (keysite, LIST_TYPE_KEYSITE_FORCE);
			}
		}

		target_force = get_local_entity_child_succ (target_force, LIST_TYPE_FORCE);
	}

	if (count == 0)
	{
		debug_fatal ("SETUP: No potential campaign objectives for side %s", entity_side_short_names [side]);
	}

	//
	// construct the list and rate each keysite according to sector importance
	//

	list = malloc_heap_mem (sizeof (entity *) * count);

	rating = malloc_heap_mem (sizeof (float) * count);

	highest = 0.0;

	count = 0;

	target_force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE);

	while (target_force)
	{
		if (target_force != force)
		{
			target_side = get_local_entity_int_value (target_force, INT_TYPE_SIDE);

			keysite = get_local_entity_first_child (target_force, LIST_TYPE_KEYSITE_FORCE);

			while (keysite)
			{
				if (get_local_entity_int_value (keysite, INT_TYPE_POTENTIAL_CAMPAIGN_OBJECTIVE))
				{
					if (get_local_entity_int_value (keysite, INT_TYPE_IN_USE))
					{
						float
							actual_range;
	
						vec3d
							*pos;
	
						list [count] = keysite;
	
						pos = get_local_entity_vec3d_ptr (keysite, VEC3D_TYPE_POSITION);
	
						get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, target_side, pos, 1.0 * KILOMETRE, &actual_range, keysite);
	
						rating [count] = actual_range;
	
						highest = max (highest, rating [count]);
		
						count ++;
					}
				}

				keysite = get_local_entity_child_succ (keysite, LIST_TYPE_KEYSITE_FORCE);
			}
		}

		target_force = get_local_entity_child_succ (target_force, LIST_TYPE_FORCE);
	}

	//
	// Normalise ratings
	//

	if (highest == 0.0)
	{
		debug_fatal ("SETUP: No sector importance for side %s", entity_side_short_names [side]);
	}
	
	for (loop = 0; loop < count; loop ++)
	{
		rating [loop] = rating [loop] / highest;
	}

	//
	// obligatory random factor
	//

	for (loop = 0; loop < count; loop ++)
	{
		rating [loop] += frand1 ();
	}

	//
	// sort the list
	//

	quicksort_entity_list (list, count, rating);

	//
	// now find the best N targets and link them into the force
	//

	count = min (count, NUMBER_OF_CAMPAIGN_OBJECTIVES_PER_SIDE);

	for (loop = 0; loop < count; loop ++)
	{
		insert_local_entity_into_parents_child_list (list [loop], LIST_TYPE_CAMPAIGN_OBJECTIVE, force, NULL);

		debug_log ("Side %s Objective :- %s (%s)", entity_side_short_names [side],
						get_local_entity_string (list [loop], STRING_TYPE_KEYSITE_NAME),
						get_local_entity_string (list [loop], STRING_TYPE_FULL_NAME));
	}

	free_mem (list);

	free_mem (rating);
}
Example #15
0
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);
	}
}
Example #16
0
static void display_weapon_information (void)
{
	entity_sub_types
		weapon_sub_type;

	float
		x,
		y,
		angle_of_drop,
		drop_hud_distance,
		roll;

	weapon_sub_type = get_local_entity_int_value (get_gunship_entity (), INT_TYPE_SELECTED_WEAPON);

	if (weapon_sub_type != ENTITY_SUB_TYPE_WEAPON_NO_WEAPON)
	{
		//
		// weapon specific
		//

		if ((weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_S5)
			|| (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_S8)
			|| (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_S13)
			|| (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_GSH23L_23MM_ROUND)
			|| (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_9A642_12P7MM_ROUND && target_acquisition_system != TARGET_ACQUISITION_SYSTEM_HMS))
		{
			float
				x,y;
				angle_of_drop = 0.0;
				drop_hud_distance;
				roll = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_ROLL);

			angle_of_drop = get_ballistic_weapon_drop(weapon_sub_type);
			drop_hud_distance = atan(angle_of_drop) * hud_position_z / (0.5 * hud_height);

			y = cos(roll) * -drop_hud_distance;
			x = sin(roll) * drop_hud_distance;

			draw_aim_marker(x, y, hud_aim_range, weapon_database[weapon_sub_type].min_range);

			// draw target marker around target if having cpg assist
			if (get_global_cpg_assist_type() != CPG_ASSIST_TYPE_NONE && eo_is_locked())
			{
				float az, el;

				get_eo_azimuth_and_elevation(&az, &el);
				if (angles_to_hud_coordinates(az, el, &x, &y, TRUE))
					draw_2d_circle(x, y, 0.15, hud_colour);
			}
		}
		else
		{
			entity* target = get_local_entity_parent (get_gunship_entity (), LIST_TYPE_TARGET);
			vec3d* tracking_point;

			// will use point lock if no target
			tracking_point = get_eo_tracking_point();
			if (target || tracking_point)
			{
				vec3d
					target_position,
					*source_position;

				float
					elevation,
					azimuth;

				if (target)
					get_local_entity_target_point (target, &target_position);
				else
					target_position = *tracking_point;

				source_position = get_local_entity_vec3d_ptr(get_gunship_entity(), VEC3D_TYPE_POSITION);

				get_eo_azimuth_and_elevation(&azimuth, &elevation);

				hud_aim_range = get_triangulated_by_position_range(source_position, &target_position);

				if (angles_to_hud_coordinates(azimuth, elevation, &x, &y, TRUE))
					draw_aim_marker(x, y, hud_aim_range, weapon_database[weapon_sub_type].min_range);
			}
		}
	}
}
Example #17
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;
}
Example #18
0
aircraft_fire_result aircraft_fire_weapon (entity *en, unsigned int check_flags)
{
	entity
		*target;
	
	aircraft
		*raw;

	vec3d
		*target_pos,
		en_pos;

	ASSERT (en);

	raw = get_local_entity_data (en);

	//
	// Fire suppressed
	//

	if (check_flags & AIRCRAFT_FIRE_SUPPRESSED)
	{
		if (get_local_entity_int_value (get_session_entity (), INT_TYPE_SUPPRESS_AI_FIRE))
		{
			return AIRCRAFT_FIRE_SUPPRESSED;
		}
	}

	//
	// check weapon
	//

	if (check_flags & AIRCRAFT_FIRE_NO_WEAPON)
	{
		if (get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON) == ENTITY_SUB_TYPE_WEAPON_NO_WEAPON)
		{
			debug_log ("AC_WPN: Fire Weapon Error - NO WEAPON");
	
			return AIRCRAFT_FIRE_NO_WEAPON;
		}
	}

	//
	// weapon system_ready
	//

	if (check_flags & AIRCRAFT_FIRE_WEAPON_SYSTEM_NOT_READY)
	{
		if (!get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON_SYSTEM_READY))
		{
			debug_log ("AC_WPN: Fire Weapon Error - WEAPON SYSTEM NOT READY");
	
			return AIRCRAFT_FIRE_WEAPON_SYSTEM_NOT_READY;
		}
	}

	//
	// find target
	//

	if (check_flags & AIRCRAFT_FIRE_NO_TARGET)
	{
		target = get_local_entity_parent (en, LIST_TYPE_TARGET);
	
		if (!target)
		{
			debug_log ("AC_WPN: Fire Weapon Error - NO TARGET");
	
			return AIRCRAFT_FIRE_NO_TARGET;
		}
	}

	//
	// line of sight checks
	//

	if (check_flags & AIRCRAFT_FIRE_NO_LOS)
	{
		int
			criteria;

		if (get_local_entity_int_value (target, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
		{
			criteria = MOBILE_LOS_CHECK_ALL;
		}
		else
		{
			criteria = MOBILE_LOS_CHECK_COURSE_TERRAIN;
		}

		get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &en_pos);

		target_pos = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION);

		en_pos.y -= (get_local_entity_float_value (en, FLOAT_TYPE_CENTRE_OF_GRAVITY_TO_GROUND_DISTANCE) + 2.0);

		if (!check_position_line_of_sight (en, target, &en_pos, target_pos, criteria))
		{
			debug_log ("AC_WPN: Fire Weapon Error - NO LOS (Aircraft %s (%d), Target %s (%d))",
								get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_index (en),
								get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target));
	
			return AIRCRAFT_FIRE_NO_LOS;
		}
	}

	//
	// Play Speech
	//

	play_aircraft_weapon_launched_speech (en, raw->selected_weapon);

	//
	// Fire weapon
	//

	launch_client_server_weapon (en, raw->selected_weapon);

	return AIRCRAFT_FIRE_OK;
}
Example #19
0
void update_dynamics_at_keysite (void)
{

	unsigned int
		model_damage,
		damage_count,
		this_damage;

	if ((!get_keysite_currently_landed_at ()) || (!get_gunship_entity ()))
	{

		return;
	}

	//
	// Refuel, only set if inside keysite
	//

	#if !DEMO_VERSION

	if (current_flight_dynamics->refuelling)
	{
		entity
			*keysite;

		float
			max_fuel;

		if (!(current_flight_dynamics->dynamics_damage & DYNAMICS_DAMAGE_FUEL_LEAK))
		{

			//#if DYNAMICS_DEBUG

			debug_log ("DYNAMICS: refuelling, fuel = %f (max = %f)", current_flight_dynamics->fuel_weight.value, current_flight_dynamics->fuel_weight.max);

			//#endif

			max_fuel = current_flight_dynamics->fuel_weight.max;

			keysite = get_keysite_currently_landed_at ();

			if (keysite)
			{

				if (get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL) <= 0.0)
				{

					if (!get_connection_list_head ())
					{

						max_fuel *= 0.25;
					}
				}
			}

			if (current_flight_dynamics->fuel_weight.value >= max_fuel)
			{

				current_flight_dynamics->refuelling = FALSE;
			}
			else
			{

				current_flight_dynamics->fuel_weight.value += REFUELLING_RATE * get_delta_time ();
			}

			current_flight_dynamics->fuel_weight.value = bound (current_flight_dynamics->fuel_weight.value,
																				current_flight_dynamics->fuel_weight.min,
																				current_flight_dynamics->fuel_weight.max);
		}
		else
		{

			debug_log ("DYNAMICS: can't refuel till leak is fixed");
		}
	}

	#endif

	//
	// Repair, only set if inside keysite
	//

	if (current_flight_dynamics->repairing)
	{

		if (current_flight_dynamics->dynamics_damage != DYNAMICS_DAMAGE_NONE)
		{

			current_flight_dynamics->damage_repair_time -= get_delta_time ();

			current_flight_dynamics->damage_repair_time = max (current_flight_dynamics->damage_repair_time, 0.0);

			#if DYNAMICS_DEBUG

			debug_log ("DYNAMICS: repairing %d, repair time %f seconds", current_flight_dynamics->damage_repair_time, current_flight_dynamics->damage_repair_time);

			#endif

			//
			// set repair timer to time to repair each part in turn
			//

			if (current_flight_dynamics->damage_repair_time <= 0.0)
			{

				// clear repaired damage
				if ((current_flight_dynamics->repairing_damage != DYNAMICS_DAMAGE_NONE) &&
					(current_flight_dynamics->dynamics_damage & current_flight_dynamics->repairing_damage))
				{

					repair_damage_model (current_flight_dynamics->repairing_damage);
				}

				current_flight_dynamics->repairing_damage = DYNAMICS_DAMAGE_NONE;

				// start repairing next
				this_damage = DYNAMICS_DAMAGE_NONE;

				damage_count = 0;

				model_damage = current_flight_dynamics->dynamics_damage;

				while (this_damage < NUM_DYNAMICS_DAMAGE_TYPES)
				{

					if ((model_damage & this_damage) && (dynamics_damage_database [damage_count].repairable))
					{

						current_flight_dynamics->damage_repair_time = dynamics_damage_database [damage_count].repair_time;

						current_flight_dynamics->repairing_damage = this_damage;

						#if DEBUG_MODULE

						debug_log ("DYNAMICS: repairing %s, repair time %f seconds", dynamics_damage_database [damage_count].name, current_flight_dynamics->damage_repair_time);

						#endif

						break;
					}

					damage_count ++;

					this_damage = this_damage << 1;
				}

				if (current_flight_dynamics->repairing_damage == DYNAMICS_DAMAGE_NONE)
				{

					#if DEBUG_MODULE

					debug_log ("DYNAMICS: model fully repaired");

					#endif

					restore_helicopter_entity (get_gunship_entity (), NULL, get_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE));

					set_client_server_entity_int_value (get_gunship_entity (), INT_TYPE_DAMAGE_LEVEL, get_local_entity_int_value (get_gunship_entity (), INT_TYPE_INITIAL_DAMAGE_LEVEL));

					transmit_entity_comms_message (ENTITY_COMMS_RESTORE_ENTITY, get_gunship_entity (), get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION), get_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE));
				}
			}
		}
	}
}
Example #20
0
void repair_damage_model (unsigned int damage)
{

	unsigned int
		this_damage;

	if (!get_gunship_entity ())
	{

		return;
	}

	this_damage = DYNAMICS_DAMAGE_NONE;

	while (this_damage < NUM_DYNAMICS_DAMAGE_TYPES)
	{

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

			current_flight_dynamics->dynamics_damage -= this_damage;

			switch (this_damage)
			{

				case DYNAMICS_DAMAGE_NONE:
				{

					break;
				}
				case DYNAMICS_DAMAGE_MAIN_ROTOR:
				{

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: main rotor repaired");

					#endif

					current_flight_dynamics->main_blade_pitch.damaged = FALSE;

					current_flight_dynamics->main_rotor_roll_angle.damaged = FALSE;

					current_flight_dynamics->main_rotor_pitch_angle.damaged = FALSE;

					current_flight_dynamics->main_rotor_rpm.damaged = FALSE;

					restore_helicopter_main_rotors (get_gunship_entity ());
	
					transmit_entity_comms_message (ENTITY_COMMS_RESTORE_ENTITY, get_gunship_entity (), get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION), get_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE));

					set_client_server_entity_int_value (get_gunship_entity (), INT_TYPE_MAIN_ROTOR_DAMAGED, FALSE);

					break;
				}
				case DYNAMICS_DAMAGE_TAIL_ROTOR:
				{

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: tail rotor repaired");

					#endif

					current_flight_dynamics->tail_blade_pitch.damaged = FALSE;

					current_flight_dynamics->tail_rotor_rpm.damaged = FALSE;

					current_flight_dynamics->cross_coupling_effect.damaged = FALSE;

					restore_helicopter_tail_rotors (get_gunship_entity ());

					break;
				}
				case DYNAMICS_DAMAGE_LEFT_ENGINE:
				{

					current_flight_dynamics->left_engine_torque.damaged = FALSE;

					current_flight_dynamics->left_engine_rpm.damaged = FALSE;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: left engine repaired");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_RIGHT_ENGINE:
				{

					current_flight_dynamics->right_engine_torque.damaged = FALSE;

					current_flight_dynamics->right_engine_rpm.damaged = FALSE;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: right engine repaired");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_LEFT_ENGINE_FIRE:
				{

					#if DYNAMICS_DEBUG

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

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_RIGHT_ENGINE_FIRE:
				{

					#if DYNAMICS_DEBUG

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

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_LOW_HYDRAULICS:
				{

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: LOW HYDRAULICS repaired");

					#endif

					current_flight_dynamics->input_data.cyclic_x.damaged = FALSE;

					current_flight_dynamics->input_data.cyclic_y.damaged = FALSE;

					break;
				}
				case DYNAMICS_DAMAGE_STABILISER:
				{

					switch (current_flight_dynamics->sub_type)
					{

						case ENTITY_SUB_TYPE_AIRCRAFT_AH64D_APACHE_LONGBOW:
						{

							apache_restore_damage_values ();

							break;
						}
						case ENTITY_SUB_TYPE_AIRCRAFT_MI28N_HAVOC_B:
						{

							havoc_restore_damage_values ();

							break;
						}
						case ENTITY_SUB_TYPE_AIRCRAFT_RAH66_COMANCHE:
						{

							comanche_restore_damage_values ();

							break;
						}
						case ENTITY_SUB_TYPE_AIRCRAFT_KA52_HOKUM_B:
						{

							hokum_restore_damage_values ();

							break;
						}
					}

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: STABILISER repaired");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_FUEL_LEAK:
				{

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: FUEL_LEAK repaired");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_LOW_OIL_PRESSURE:
				{

					current_flight_dynamics->input_data.cyclic_y.damaged = FALSE;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: LOW_OIL_PRESSURE repaired");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_HIGH_OIL_PRESSURE:
				{

					current_flight_dynamics->input_data.collective.damaged = FALSE;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: HIGH_OIL_PRESSURE repaired");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_AVIONICS:
				{

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: AVIONICS repaired");

					#endif

					if (get_keysite_currently_landed_at ())
					{
	
						// sort out what avionics to repair.
						switch (get_local_entity_int_value (get_keysite_currently_landed_at (), INT_TYPE_ENTITY_SUB_TYPE))
						{
	
							case ENTITY_SUB_TYPE_KEYSITE_FARP:
							{
	
								partially_repair_local_entity_avionics (get_gunship_entity ());
	
								break;
							}
							default:
							{
	
								fully_repair_local_entity_avionics (get_gunship_entity ());
	
								break;
							}
						}
					}
					else
					{
	
						fully_repair_local_entity_avionics (get_gunship_entity ());
					}

					break;
				}
				case DYNAMICS_DAMAGE_FIRE_EXTINGUISHER:
				{

					#if DEBUG_MODULE

					debug_log ("DYNAMICS: FIRE EXTINGUISHER repaired");

					#endif

					fire_extinguisher_used = FALSE;

					break;
				}
				case DYNAMICS_DAMAGE_UNDERCARRIAGE:
				{

					#if DEBUG_MODULE

					debug_log ("DYNAMICS: UNDERCARRIAGE repaired");

					#endif

					current_flight_dynamics->undercarriage_state.damaged = FALSE;

					break;
				}
				default:
				{

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

		this_damage = this_damage << 1;
	}
}
Example #21
0
entity *create_engage_task (entity *group, entity *objective, entity *originator, int expire)
{
	entity
		*force_en,
		*new_task;

	force
		*force_raw;

	vec3d
		*pos;

	entity_sides
		side;

	float
		expire_time;

	formation_types
		original_formation;

	ASSERT (group);

	ASSERT (get_local_entity_int_value (group, INT_TYPE_ENGAGE_ENEMY));

	ASSERT (objective);

	#if DEBUG_MODULE
	
	debug_log ("ENGAGE: Trying to engage against %s (%d)",
									get_local_entity_string (objective, STRING_TYPE_FULL_NAME),
									get_local_entity_index (objective));

	#endif

	ASSERT ((get_local_entity_int_value (objective, INT_TYPE_IDENTIFY_AIRCRAFT)) ||
				(get_local_entity_int_value (objective, INT_TYPE_IDENTIFY_VEHICLE)) ||
				(get_local_entity_int_value (objective, INT_TYPE_IDENTIFY_FIXED)));

	if (get_local_entity_int_value (get_session_entity (), INT_TYPE_SUPPRESS_AI_FIRE))
	{
		return NULL;
	}

	force_en = get_local_force_entity ((entity_sides)get_local_entity_int_value (group, INT_TYPE_SIDE));

	force_raw = (force*) get_local_entity_data (force_en);

	if (expire)
	{
		expire_time = (2.0 * ONE_MINUTE) + (frand1 () * ONE_MINUTE);
	}
	else
	{
		//
		// Max time for ENGAGE - stops attackers hanging around target area for too long (especially if they can NEVER get to their target)
		//
		
		expire_time = (15.0 * ONE_MINUTE) + (frand1 () * 5.0 * ONE_MINUTE);
	}

	new_task = NULL;

	//
	// Create engage task to expire in task_time seconds - debug
	//

	side = (entity_sides) get_local_entity_int_value (group, INT_TYPE_SIDE);

	pos = get_local_entity_vec3d_ptr (objective, VEC3D_TYPE_POSITION);

	ASSERT (get_local_entity_first_child (group, LIST_TYPE_MEMBER));

	original_formation = FORMATION_ROW_LEFT;

	new_task = create_task (ENTITY_SUB_TYPE_TASK_ENGAGE,
									side,
									(movement_types) get_local_entity_int_value (group, INT_TYPE_MOVEMENT_TYPE),
									NULL,
									NULL,
									originator,
									TRUE,
									expire_time,
									0.0,
									objective,
									task_database [ENTITY_SUB_TYPE_TASK_ENGAGE].task_priority,
									pos, objective, ENTITY_SUB_TYPE_WAYPOINT_TARGET, original_formation,
									&terminator_point, NULL, NUM_ENTITY_SUB_TYPE_WAYPOINTS, FORMATION_NONE);

	#if DEBUG_MODULE
	
	debug_log ("ENGAGE: Created Engage task against %s (%d)",
									get_local_entity_string (objective, STRING_TYPE_FULL_NAME),
									get_local_entity_index (objective));

	#endif

	return new_task;
}
Example #22
0
int debug_engage_targets_in_area (entity *group, vec3d *target_point, float radius, unsigned int target_type)
{
	//
	// Engages all targets in area, regardless of side 
	//

	int
		sx,
		sz,
		min_sector_x,
		max_sector_x,
		min_sector_z,
		max_sector_z;

	entity
		*new_task,
		*objective,
		*target_sector;

	entity_sides
		side;

	sector
		*raw;

	float
		range,
		temp_x,
		temp_z;

	vec3d
		*pos;

	new_task = NULL;

	temp_x = target_point->x - radius;
	temp_z = target_point->z - radius;

	get_x_sector (min_sector_x, temp_x);
	get_z_sector (min_sector_z, temp_z);

	temp_x = target_point->x + radius;
	temp_z = target_point->z + radius;

	get_x_sector (max_sector_x, temp_x);
	get_z_sector (max_sector_z, temp_z);

	min_sector_x = bound (min_sector_x, MIN_MAP_X_SECTOR, MAX_MAP_X_SECTOR);
	max_sector_x = bound (max_sector_x, MIN_MAP_X_SECTOR, MAX_MAP_X_SECTOR);

	min_sector_z = bound (min_sector_z, MIN_MAP_Z_SECTOR, MAX_MAP_Z_SECTOR);
	max_sector_z = bound (max_sector_z, MIN_MAP_Z_SECTOR, MAX_MAP_Z_SECTOR);

	side = (entity_sides) get_local_entity_int_value (group, INT_TYPE_SIDE);

	for (sz = min_sector_z; sz <= max_sector_z; sz ++)
	{
		for (sx = min_sector_x; sx <= max_sector_x; sx ++)
		{
			target_sector = get_local_raw_sector_entity (sx, sz);

			raw = (sector *) get_local_entity_data (target_sector);

			//
			// search for viable targets
			//

			objective = raw->sector_root.first_child;

			while (objective)
			{
				//
				// criteria for target is that it is a valid target, and not in your group
				//

				if (get_local_entity_int_value (objective, INT_TYPE_TARGET_TYPE) == target_type)
				{
					if (get_local_entity_int_value (objective, INT_TYPE_ALIVE))
					{
						if ((!get_local_entity_int_value (objective, INT_TYPE_IDENTIFY_MOBILE)) || (get_local_entity_parent (objective, LIST_TYPE_MEMBER) != group))
						{
							pos = get_local_entity_vec3d_ptr (objective, VEC3D_TYPE_POSITION);
	
							range = get_approx_2d_range (target_point, pos);
	
							if (range <= radius)
							{
	
								new_task = create_engage_task (group, objective, group, FALSE);
	
								if (new_task)
								{
									assign_task_to_group (group, new_task, TASK_ASSIGN_NO_MEMBERS);
								}
							}
						}
					}
				}

				objective = get_local_entity_child_succ (objective, LIST_TYPE_SECTOR);
			}
		}
	}

	if (assign_engage_tasks_to_group (group, TASK_ASSIGN_ALL_MEMBERS) != TASK_ASSIGN_ALL_MEMBERS)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
Example #23
0
entity *free_flight_auto_assign_gunship (void)
{
	vec3d
		*pos;

	entity
		*force,
		*new_task,
		*group,
		*member,
		**gunship_list,
		*en;

	entity_sub_types
		sub_type;

	int
		c,
		index,
		count;

	//
	// Auto assign a helicopter for free flight
	//

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	ASSERT (get_game_type () == GAME_TYPE_FREE_FLIGHT);

	ASSERT (get_pilot_entity ());

	if (get_gunship_entity ())
	{
		return NULL;
	}

	force = get_local_entity_parent (get_pilot_entity (), LIST_TYPE_PILOT);

	ASSERT (force);

	//
	// Count up candidates
	//

	count = 0;

	en = get_local_entity_first_child (force, LIST_TYPE_AIR_REGISTRY);

	while (en)
	{
		if (get_local_entity_int_value (en, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE)
		{
			member = get_local_entity_first_child (en, LIST_TYPE_MEMBER);

			while (member)
			{
				sub_type = get_local_entity_int_value (member, INT_TYPE_ENTITY_SUB_TYPE);

				if ((sub_type == ENTITY_SUB_TYPE_AIRCRAFT_RAH66_COMANCHE) || (sub_type == ENTITY_SUB_TYPE_AIRCRAFT_KA52_HOKUM_B))
				{
					if (get_local_entity_suitable_for_player (member, get_pilot_entity ()))
					{
						count ++;
					}
				}

				member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER);
			}
		}

		en = get_local_entity_child_succ (en, LIST_TYPE_AIR_REGISTRY);
	}

	if (count == 0)
	{
		return NULL;
	}

	//
	// Create list of candidates
	//

	gunship_list = safe_malloc (sizeof (entity *) * count);

	count = 0;

	en = get_local_entity_first_child (force, LIST_TYPE_AIR_REGISTRY);

	while (en)
	{
		if (get_local_entity_int_value (en, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE)
		{
			member = get_local_entity_first_child (en, LIST_TYPE_MEMBER);

			while (member)
			{
				sub_type = get_local_entity_int_value (member, INT_TYPE_ENTITY_SUB_TYPE);

				if ((sub_type == ENTITY_SUB_TYPE_AIRCRAFT_RAH66_COMANCHE) || (sub_type == ENTITY_SUB_TYPE_AIRCRAFT_KA52_HOKUM_B))
				{
					if (get_local_entity_suitable_for_player (member, get_pilot_entity ()))
					{
						gunship_list [count] = member;

						count ++;
					}
				}

				member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER);
			}
		}

		en = get_local_entity_child_succ (en, LIST_TYPE_AIR_REGISTRY);
	}

	//
	// Pick one...
	//

	ASSERT (count > 0);

	index = rand16 () % count;

	for (c = 0; c < count; c ++)
	{
		en = gunship_list [index];

		group = get_local_entity_parent (en, LIST_TYPE_MEMBER);

		pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

		new_task = create_user_task (en, ENTITY_SUB_TYPE_TASK_FREE_FLIGHT, pos, NULL, NULL);

		set_assign_create_waypoint_route (FALSE);

		if (assign_primary_task_to_group (group, new_task))
		{
			set_gunship_entity (en);

			set_view_mode (VIEW_MODE_COCKPIT_PANEL_LEVEL_AHEAD);

			safe_free (gunship_list);

			initialise_free_flight_screen_map_page_objects ();

			return en;
		}
		else
		{
			debug_log ("FLIGHT: can't assign user to Created task");

			destroy_client_server_entity (new_task);
		}

		set_assign_create_waypoint_route (TRUE);

		index ++;

		if (index == count)
		{
			index = 0;
		}
	}

	safe_free (gunship_list);

	return NULL;
}
Example #24
0
void update_aircraft_decoy_release (entity *en)
{
	aircraft
		*raw;

	int
		chaff_available,
		flare_available,
		chaff_released,
		flare_released;

	float
		range,
		velocity,
		time_to_impact;

	entity_sub_types
		weapon_sub_type;

	entity
		*persuer;

	vec3d
		*target_position,
		*weapon_position;

	ASSERT (en);

	#ifdef DEBUG

	if (get_comms_model () == COMMS_MODEL_CLIENT)
	{
		ASSERT (en == get_gunship_entity ());
	}

	#endif

	raw = get_local_entity_data (en);

	////////////////////////////////////////
	//
	// update timer
	//
	////////////////////////////////////////

	raw->decoy_release_timer -= get_delta_time ();

	if (raw->decoy_release_timer >= 0.0)
	{
		return;
	}

	raw->decoy_release_timer = 2.0 + frand1 ();

	////////////////////////////////////////
	//
	// validate
	//
	////////////////////////////////////////

	if (en == get_gunship_entity ())
	{
		if (!get_global_auto_counter_measures ())
		{
			return;
		}
	}
	else if (get_local_entity_int_value (en, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
	{
		return;
	}

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

	persuer = get_local_entity_first_child (en, LIST_TYPE_TARGET);

	if (!persuer)
	{
		return;
	}

	chaff_available = get_local_entity_weapon_available (en, ENTITY_SUB_TYPE_WEAPON_CHAFF);

	flare_available = get_local_entity_weapon_available (en, ENTITY_SUB_TYPE_WEAPON_FLARE);

	if (!(chaff_available || flare_available))
	{
		return;
	}

	////////////////////////////////////////
	//
	// check all persuers
	//
	////////////////////////////////////////

	target_position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

	chaff_released = FALSE;
	flare_released = FALSE;

	while (persuer)
	{
		if (get_local_entity_type (persuer) == ENTITY_TYPE_WEAPON)
		{
			if (get_local_entity_int_value (persuer, INT_TYPE_WEAPON_GUIDANCE_TYPE) != WEAPON_GUIDANCE_TYPE_NONE)
			{
				weapon_sub_type = get_decoy_type_for_weapon (persuer);

				if (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_CHAFF)
				{
					if (chaff_available)
					{
						if (!chaff_released)
						{
							weapon_position = get_local_entity_vec3d_ptr (persuer, VEC3D_TYPE_POSITION);

							range = get_approx_3d_range (weapon_position, target_position);

							velocity = get_local_entity_float_value (persuer, FLOAT_TYPE_VELOCITY);

							time_to_impact = range / max (velocity, 1.0);

							if (time_to_impact < 10.0)
							{
								launch_client_server_weapon (en, ENTITY_SUB_TYPE_WEAPON_CHAFF);

								chaff_released = TRUE;

								if (flare_released)
								{
									break;
								}
							}
						}
					}
				}
				else if (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_FLARE)
				{
					if (flare_available)
					{
						if (!flare_released)
						{
							weapon_position = get_local_entity_vec3d_ptr (persuer, VEC3D_TYPE_POSITION);

							range = get_approx_3d_range (weapon_position, target_position);

							velocity = get_local_entity_float_value (persuer, FLOAT_TYPE_VELOCITY);

							time_to_impact = range / max (velocity, 1.0);

							if (time_to_impact < 10.0)
							{
								launch_client_server_weapon (en, ENTITY_SUB_TYPE_WEAPON_FLARE);

								flare_released = TRUE;

								if (chaff_released)
								{
									break;
								}
							}
						}
					}
				}
			}
		}

		persuer = get_local_entity_child_succ (persuer, LIST_TYPE_TARGET);
	}
}
Example #25
0
static void draw_local_3d_object (entity *en, float range)
{
	fixed_wing
		*raw;

	day_segment_types
		day_segment_type;

	raw = (fixed_wing *) get_local_entity_data (en);

	//
	// update viewpoint
	//

	raw->ac.inst3d->vp.position = raw->ac.mob.position;

	memcpy (&raw->ac.inst3d->vp.attitude, &raw->ac.mob.attitude, sizeof (matrix3x3));

	//
	// animate
	//

	animate_fixed_wing_afterburners (en);

	animate_fixed_wing_airbrakes (en);
	
	animate_fixed_wing_flaps (en);

	animate_fixed_wing_propellors (en);
	
	animate_aircraft_loading_doors (en);

	animate_aircraft_cargo_doors (en);

	animate_aircraft_undercarriage (en);

	animate_aircraft_weapon_system_ready (en);

	animate_aircraft_shadow (en);

	animate_aircraft_rudder (en);

	//
	// draw
	//

	day_segment_type = (day_segment_types) get_local_entity_int_value (get_session_entity (), INT_TYPE_DAY_SEGMENT_TYPE);

	raw->ac.inst3d->object_internal_lighting = ((day_segment_type == DAY_SEGMENT_TYPE_NIGHT) || (day_segment_type == DAY_SEGMENT_TYPE_DUSK));

	raw->ac.inst3d->object_sprite_lights = (raw->ac.inst3d->object_internal_lighting && sprite_light_valid (en));

	animate_and_draw_entity_muzzle_flash_effect (en);

	insert_object_into_3d_scene (OBJECT_3D_DRAW_TYPE_OBJECT, raw->ac.inst3d);

	#if DEBUG_MODULE

	if (en == get_external_view_entity ())
	{
		vec3d
			*pos,
			wp_pos;

		draw_mobile_entity_debug_info (en);

		if (get_local_entity_primary_task (en))
		{
			fixed_wing_movement_get_waypoint_position (en, &wp_pos);
	
			pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);
	
			create_debug_3d_line (pos, &wp_pos, sys_col_dark_green, 0.0);
		}
	}
	
	#endif
}
Example #26
0
void kill_routed_vehicles_on_segment (entity *en)
{
	float
		range,
		damage_radius;

	int
		sx,
		sz;

	vec3d
		*segment_position,
		*object_position;

	entity
		*sect,
		*object;

	bridge_segment_types
		bridge_segment_type;

	//
	// get damage radius ( plus a little overlap )
	//

	bridge_segment_type = (bridge_segment_types) get_local_entity_int_value (en, INT_TYPE_BRIDGE_SEGMENT_TYPE);

	damage_radius = bridge_segment_length (bridge_segment_type);

	if (damage_radius == 0.0)
	{
		return;
	}

	damage_radius *= ROOT2;

	//
	// get sector which the segment is in ( don't bother with adjacent sectors for now )
	//

	segment_position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

	get_x_sector (sx, segment_position->x);
	get_z_sector (sz, segment_position->z);

	sect = get_local_raw_sector_entity (sx, sz);

	//
	// search for routed vehicles
	//

	object = get_local_entity_first_child (sect, LIST_TYPE_SECTOR);

	while (object)
	{
		if (object->type == ENTITY_TYPE_ROUTED_VEHICLE)
		{
			if (get_local_entity_int_value (object, INT_TYPE_ALIVE))
			{
				object_position = get_local_entity_vec3d_ptr (object, VEC3D_TYPE_POSITION);

				if (object_position)
				{
					range = get_approx_3d_range (segment_position, object_position);

					if (range < damage_radius)
					{
						kill_client_server_entity (object);
					}
				}
			}
		}

		object = get_local_entity_child_succ (object, LIST_TYPE_SECTOR);
	}
}
Example #27
0
void show_base_page (entity *base, int force_update)
{
    entity
    *previous;

    vec3d
    *pos;

    int
    x, z;

    char
    s [128];

    ASSERT (base);

    ASSERT (get_local_entity_type (base) == ENTITY_TYPE_KEYSITE);

    if (force_update)
    {
        previous = NULL;
    }
    else
    {
        previous = get_local_entity_safe_ptr (get_ui_object_item_number (campaign_page [CAMPAIGN_PAGE_BASE]));
    }

    pos = get_local_entity_vec3d_ptr (base, VEC3D_TYPE_POSITION);

    ASSERT (pos);

    //
    // NAME
    //

    set_ui_object_text (base_page_title, get_local_entity_string (base, STRING_TYPE_KEYSITE_NAME));

    //
    // TYPE
    //

    set_ui_object_text (base_page_type_box, get_trans (get_local_entity_string (base, STRING_TYPE_FULL_NAME)));

    //
    // LOCATION
    //

    get_x_sector (x, pos->x);
    get_z_sector (z, pos->z);

    sprintf (s, "[%03d, %03d]", x, z);

    set_ui_object_text (base_page_sector_box, s);

    //
    // 3D WINDOW
    //

    set_ui_object_item_number (page_3d_area, get_local_entity_index (base));

    if (base != previous)
    {
        page_3d_heading = 0.0;
        page_3d_pitch = (PI * 0.25);
        page_3d_distance = max (50.0, get_local_entity_float_value (base, FLOAT_TYPE_RECON_DISTANCE));
    }

    //
    // 2D MAP
    //

    set_ui_object_item_number (page_map_area, get_local_entity_index (base));

    if (base != previous)
    {
        page_map_dimensions.x = pos->x;
        page_map_dimensions.z = pos->z;

        page_map_dimensions.subject_entity = base;
    }

    //

    display_campaign_page (CAMPAIGN_PAGE_BASE, get_local_entity_index (base), TRUE);
}
Example #28
0
int resume_local_entity_sound_type (entity *en, entity_sub_types type)
{
	entity
		*spec;

	sound_effect
		*raw;

	int
		count;

	count = 0;

	spec = get_local_entity_first_child (en, LIST_TYPE_SPECIAL_EFFECT);
	
	while (spec)
	{
		if (get_local_entity_type (spec) == ENTITY_TYPE_SOUND_EFFECT)
		{
			raw = get_local_entity_data (spec);

			if (raw->eff.sub_type == type)
			{
				//
				// "unpause" sound
				//

				if (!raw->valid_sound_effect)
				{
					//
					// set flag and start playing
					//

					raw->valid_sound_effect = TRUE;
	
					if (en == get_session_entity ())
					{
						play_local_entity_sound (en, &main_vp, 0);
					}
					else
					{
						vec3d
							*position;
	
						viewpoint
							*vp;
	
						float
							range;
	
						vp = &main_vp;
	
						position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);
	
						range = get_approx_3d_range (&vp->position, position);
	
						play_local_entity_sound (en, vp, range);
					}

					if (!get_local_entity_parent (spec, LIST_TYPE_UPDATE))
					{
						insert_local_entity_into_parents_child_list (spec, LIST_TYPE_UPDATE, get_update_entity (), NULL);
					}

					count ++;
				}
			}
		}

		spec = get_local_entity_child_succ (spec, LIST_TYPE_SPECIAL_EFFECT);
	}

	return count;
}
Example #29
0
unsigned int assign_engage_tasks_to_group (entity *group, unsigned int valid_members)
{
	entity
		*task,
		*guide,
		*target,
		*member,
		*single_member,
		*persuer,
		**guide_list;

	unsigned int
		member_number;

	int
		best_count,
		best_guide,
		loop,
		criteria,
		task_count,
		*assigned_count;

	float
		range,
		*priority;

	vec3d
		*member_pos,
		*target_pos;

	ASSERT (group);

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	if (!valid_members)
	{
		return valid_members;
	}	

	//
	// count up engage tasks
	//

	task_count = 0;

	guide = get_local_entity_first_child (group, LIST_TYPE_GUIDE_STACK);

	while (guide)
	{
		if (get_local_entity_int_value (guide, INT_TYPE_VALID_GUIDE_MEMBERS) == TASK_ASSIGN_NO_MEMBERS)
		{
			task = get_local_entity_parent (guide, LIST_TYPE_GUIDE);

			ASSERT (task);

			ASSERT (get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE) == ENTITY_SUB_TYPE_TASK_ENGAGE);

			if (get_local_entity_int_value (task, INT_TYPE_TASK_TERMINATED) == TASK_TERMINATED_IN_PROGRESS)
			{
				task_count ++;
			}
		}

		guide = get_local_entity_child_succ (guide, LIST_TYPE_GUIDE_STACK);
	}

	#if DEBUG_MODULE

	debug_log ("ENGAGE: ==========================");
	
	debug_log ("ENGAGE: %d suitable tasks", task_count);

	#endif

	if (task_count == 0)
	{
		return valid_members;
	}

	//////////////////////////////////////////////////////////////////
	//
	// prioritize engage tasks
	//
	//////////////////////////////////////////////////////////////////

	//
	// get target priority
	//

	guide_list = (entity * *) malloc_fast_mem (sizeof (entity *) * task_count);
	priority = (float *) malloc_fast_mem (sizeof (float) * task_count);
	assigned_count = (int *) malloc_fast_mem (sizeof (int) * task_count);

	#if DEBUG_MODULE

	debug_log ("ENGAGE: ======RAW LIST======");

	#endif

	single_member = NULL;
	// check if we have a single member, if so assign that member to single_member
	for (member = get_local_entity_first_child (group, LIST_TYPE_MEMBER);
		 member;
		 member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER))
	{
		member_number = (1 << get_local_entity_int_value (member, INT_TYPE_GROUP_MEMBER_NUMBER));

		if (member_number & valid_members)
		{
			if (single_member)  // we already have a valid member, so there is more than one
			{
				single_member = NULL;
				break;
			}
			else
				single_member = member;
		}
	}

	loop = 0;
	guide = get_local_entity_first_child (group, LIST_TYPE_GUIDE_STACK);

	while (guide)
	{
		if (get_local_entity_int_value (guide, INT_TYPE_VALID_GUIDE_MEMBERS) == TASK_ASSIGN_NO_MEMBERS)
		{
			task = get_local_entity_parent (guide, LIST_TYPE_GUIDE);

			ASSERT (task);

			ASSERT (get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE) == ENTITY_SUB_TYPE_TASK_ENGAGE);

			if (get_local_entity_int_value (task, INT_TYPE_TASK_TERMINATED) == TASK_TERMINATED_IN_PROGRESS)
			{
				target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT);

				ASSERT (target);

				if (!target)
				{
					notify_local_entity (ENTITY_MESSAGE_TASK_TERMINATED, task, group, TASK_TERMINATED_ABORTED);

					free_mem (guide_list);
				
					free_mem (priority);
				
					free_mem (assigned_count);
				
					return valid_members;
				}
				
				guide_list [loop] = guide;

				if (get_local_entity_int_value (group, INT_TYPE_AIRCRAFT_GROUP))
				{
					priority [loop] = get_local_entity_float_value (target, FLOAT_TYPE_TARGET_PRIORITY_AIR_ATTACK);
				}
				else
				{
					priority [loop] = get_local_entity_float_value (target, FLOAT_TYPE_TARGET_PRIORITY_GROUND_ATTACK);
				}

				#if DEBUG_MODULE

				debug_log ("ENGAGE: (%d) Target : %s, Priority %f", loop, get_local_entity_string (target, STRING_TYPE_FULL_NAME), priority [loop]);

				#endif

				loop ++;
			}
		}

		guide = get_local_entity_child_succ (guide, LIST_TYPE_GUIDE_STACK);
	}

	ASSERT (loop == task_count);

	//
	// sort the tasks according to their priority
	//

	quicksort_entity_list (guide_list, task_count, priority);

	#if DEBUG_MODULE

	debug_log ("ENGAGE: ======SORTED======");

	for (loop = 0; loop < task_count; loop ++)
	{
		task = get_local_entity_parent (guide_list [loop], LIST_TYPE_GUIDE);

		target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT);

		debug_log ("ENGAGE: (%d) Target : %s (%d), Priority %f", loop, get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target), priority [loop]);
	}

	#endif

	//
	// consider other entities attacking the same targets
	//

	memset (assigned_count, 0, sizeof (int) * task_count);

	for (loop = 0; loop < task_count; loop ++)
	{
		task = get_local_entity_parent (guide_list [loop], LIST_TYPE_GUIDE);

		target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT);

		persuer = get_local_entity_first_child (target, LIST_TYPE_TARGET);

		while (persuer)
		{
			assigned_count [loop] ++;

			persuer = get_local_entity_child_succ (persuer, LIST_TYPE_TARGET);
		}
	}

	//////////////////////////////////////////////////////////////////
	//
	// assign new engage tasks
	//
	// for each member, run through the task list (most important first)
	// try to assign one member per task, but as tasks run out group members can "team-up"
	//
	//////////////////////////////////////////////////////////////////

	member = get_local_entity_first_child (group, LIST_TYPE_MEMBER);

	while ((member) && (valid_members))
	{
		//
		// Only assign AI entities to ENGAGE tasks
		//
		
		if (get_local_entity_int_value (member, INT_TYPE_PLAYER) == ENTITY_PLAYER_AI)
		{
			if (get_local_entity_int_value (member, INT_TYPE_ENGAGE_ENEMY))
			{
				member_number = (1 << get_local_entity_int_value (member, INT_TYPE_GROUP_MEMBER_NUMBER));

				if (member_number & valid_members)
				{
					member_pos = get_local_entity_vec3d_ptr (member, VEC3D_TYPE_POSITION);

					if (get_local_entity_int_value (member, INT_TYPE_IDENTIFY_AIRCRAFT))
					{
						criteria = BEST_WEAPON_CRITERIA_MINIMAL;
					}
					else
					{
						criteria = BEST_WEAPON_RANGE_CHECK | BEST_WEAPON_LOS_CHECK;
					}
		
					best_guide = -1;
			
					best_count = INT_MAX;
			
					for (loop = 0; loop < task_count; loop ++)
					{
						if (assigned_count [loop] < best_count)
						{
							guide = guide_list [loop];					
			
							task = get_local_entity_parent (guide, LIST_TYPE_GUIDE);
			
							target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT);

							if (target == member)
							{
								//
								// Don't try to attack yourself !
								//
								
								continue;
							}

							//
							// Range Check
							//

							if (criteria & BEST_WEAPON_RANGE_CHECK)
							{
								// range handled by weapon selection
								range = 0.0;
							}
							else
							{
								target_pos = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION);

								range = get_sqr_2d_range (target_pos, member_pos);
							}
							
							if (range < MAX_ENGAGE_RANGE)
							{
								//
								// Weapon Check
								//
				
								if (get_best_weapon_for_target (member, target, criteria) != ENTITY_SUB_TYPE_WEAPON_NO_WEAPON)
								{
									best_count = assigned_count [loop];
				
									best_guide = loop;
								}
							}
						}
					}
			
					if (best_guide != -1)
					{
						guide = guide_list [best_guide];
						
						task = get_local_entity_parent (guide, LIST_TYPE_GUIDE);
			
						if (assign_new_task_to_group_member (group, member, task, NULL))
						{
							valid_members &= (~member_number);
				
							assigned_count [best_guide] ++;
			
							#if DEBUG_MODULE
						
							debug_log ("ENGAGE: Assigning %s (%d) to target %s (%d)",
											get_local_entity_string (member, STRING_TYPE_FULL_NAME), get_local_entity_index (member),
											get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target));
		
							#endif
						}
					}
					else
					{
						#if DEBUG_MODULE
						
						debug_log ("ENGAGE: Couldn't assign %s (%d) to engage task",
										get_local_entity_string (member, STRING_TYPE_FULL_NAME), get_local_entity_index (member));
		
						#endif
					}
				}
			}
		}
		
		member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER);
	}

	free_mem (guide_list);

	free_mem (priority);

	free_mem (assigned_count);

	return valid_members;
}
Example #30
0
void interpolate_entity_position (entity *en)
{

	vec3d
		new_position,
		*motion_vector,
		*position;

	connection_list_type
		*connection;

	float
		delta_time;

	if ((!command_line_comms_interpolate_gunships) || (get_local_entity_int_value (en, INT_TYPE_LANDED)))
	{

		return;
	}

	position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

	motion_vector = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_MOTION_VECTOR);

	if (get_comms_model () == COMMS_MODEL_CLIENT)
	{

		connection = get_connection_list_item (get_server_id ());
	}
	else
	{

		connection = get_gunships_connection_list_item (en);
	}

	if (connection)
	{
	
		delta_time = (float) (get_system_time () - connection->interpolation_time) / TIME_1_SECOND;
	
		new_position.x = position->x + motion_vector->x * delta_time;
		new_position.y = position->y + motion_vector->y * delta_time;
		new_position.z = position->z + motion_vector->z * delta_time;
	
		set_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &new_position);
						
		if (get_comms_model () == COMMS_MODEL_SERVER)
		{

			connection->interpolation_time = get_system_time ();
		}

		#if DEBUG_MODULE
	
		debug_log ("SERVER: interpolating entity %s (%d) old [%f, %f, %f], new [%f, %f, %f], motion_vector [%f, %f, %f], deltatime %f",
						get_local_entity_string (en, STRING_TYPE_FULL_NAME),
						get_local_entity_index (en),
						position->x, position->y, position->z,
						new_position.x, new_position.y, new_position.z,
						motion_vector->x, motion_vector->y, motion_vector->z,
						delta_time);

		#endif
	}
}