Beispiel #1
0
entity *create_new_pilot_entity (const char *name, entity_sides side, int rank, entity_sub_types sub_type, int unique_id, int difficulty)
{
	entity
		*en,
		*force;

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);
	
	ASSERT (name);

	force = get_local_force_entity (side);

	ASSERT (force);

	en = create_client_server_entity
				(
					ENTITY_TYPE_PILOT,
					ENTITY_INDEX_DONT_CARE,
					ENTITY_ATTR_PARENT (LIST_TYPE_PILOT, force),
					ENTITY_ATTR_STRING (STRING_TYPE_PILOTS_NAME, name),
					ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, sub_type),
					ENTITY_ATTR_INT_VALUE (INT_TYPE_UNIQUE_ID, unique_id),
					ENTITY_ATTR_INT_VALUE (INT_TYPE_SIDE, side),
					ENTITY_ATTR_INT_VALUE (INT_TYPE_PILOT_RANK, rank),
					ENTITY_ATTR_INT_VALUE (INT_TYPE_DIFFICULTY_LEVEL, difficulty),
					ENTITY_ATTR_END
				);

	send_pilot_joined_message (en);

	return en;
}
Beispiel #2
0
void reinitialise_client_ai_system (void)
{

	comms_model_types
		temp_comms_model;

	comms_data_flow_types
		temp_comms_data_flow;

	temp_comms_model = get_comms_model ();

	temp_comms_data_flow = get_comms_data_flow ();

	//
	// set comms model and data flow to SERVER/TX
	//

	set_comms_model (COMMS_MODEL_SERVER);

	set_comms_data_flow (COMMS_DATA_FLOW_TX);

	if (population_placement_filename)
	{

		read_population_placement_file (population_placement_filename);
	}

	set_comms_model (temp_comms_model);

	set_comms_data_flow (temp_comms_data_flow);

	initialise_keysite_farp_enable (get_local_force_entity (ENTITY_SIDE_BLUE_FORCE));

	initialise_keysite_farp_enable (get_local_force_entity (ENTITY_SIDE_RED_FORCE));

	initialise_briefing_parser ();

	set_assign_create_waypoint_route (TRUE);
}
Beispiel #3
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;
		}
	}
}
Beispiel #4
0
entity *add_group_to_division (entity *group, entity *specified_division)
{
	entity_sides
		side;

	int
		count,
		max_count,
		group_type,
		keysite_type,
		division_type,
		main_division_type;

	entity
		*en,
		*force,
		*keysite,
		*division;

	vec3d
		*group_pos;
		
	ASSERT (group);

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	ASSERT (!get_local_entity_parent (group, LIST_TYPE_DIVISION));

	group_type = get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE);
	
	group_pos = get_local_entity_vec3d_ptr (group, VEC3D_TYPE_POSITION);
	
	if (specified_division)
	{
		division = specified_division;
	}
	else
	{
		side = (entity_sides) get_local_entity_int_value (group, INT_TYPE_SIDE);
	
		force = get_local_force_entity (side);
	
		ASSERT (force);
	
		division_type = group_database [group_type].default_group_division;
	
		ASSERT (entity_sub_type_division_valid (division_type));
	
		main_division_type = division_database [division_type].default_group_division;
	
		ASSERT (entity_sub_type_division_valid (main_division_type));
	
		//
		// Find the keysite the company should be attached to
		//

		keysite = NULL;
	
		if (get_local_entity_int_value (group, INT_TYPE_GROUP_LIST_TYPE) == LIST_TYPE_KEYSITE_GROUP)
		{
			keysite = get_local_entity_parent (group, LIST_TYPE_KEYSITE_GROUP);

			if (!keysite)
			{
				keysite = get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, side, group_pos, 1.0 * KILOMETRE, NULL, NULL);
			}
	
			ASSERT (keysite);
	
			keysite_type = get_local_entity_int_value (keysite, INT_TYPE_ENTITY_SUB_TYPE);
	
			if ((keysite_type == ENTITY_SUB_TYPE_KEYSITE_AIRBASE) || (keysite_type == ENTITY_SUB_TYPE_KEYSITE_ANCHORAGE))
			{
				//
				// Use keysite landed at
				//
			}
			else
			{
				//
				// Find nearest keysite (below)
				//

				keysite = NULL;
			}
		}
		else
		{
			if (group_database [group_type].movement_type == MOVEMENT_TYPE_SEA)
			{
				//
				// Find nearest carrier
				//
			
				keysite = get_closest_keysite (ENTITY_SUB_TYPE_KEYSITE_ANCHORAGE, side, group_pos, 0.0, NULL, NULL);
			}
		}

		if (!keysite)
		{
			//
			// Find nearest airbase
			//
			
			keysite = get_closest_keysite (ENTITY_SUB_TYPE_KEYSITE_AIRBASE, side, group_pos, 0.0, NULL, NULL);

			if (!keysite)
			{
				//
				// Find nearest military base
				//
				
				keysite = get_closest_keysite (ENTITY_SUB_TYPE_KEYSITE_MILITARY_BASE, side, group_pos, 0.0, NULL, NULL);

				if (!keysite)
				{
					//
					// Find nearest FARP  
					//
				
					keysite = get_closest_keysite (ENTITY_SUB_TYPE_KEYSITE_FARP, side, group_pos, 0.0, NULL, NULL);
				}
			}
		}
	
		ASSERT (keysite);
	
		//
		// Check all companies at this keysite to see if they have vacancies....
		//
	
		max_count = group_database [group_type].maximum_groups_per_division;
	
		division = get_local_entity_first_child (keysite, LIST_TYPE_DIVISION_HEADQUARTERS);
	
		while (division)
		{
			if (get_local_entity_int_value (division, INT_TYPE_ENTITY_SUB_TYPE) == division_type)
			{
				if (max_count == 0)
				{
					break;
				}
	
				count = 0;
	
				en = get_local_entity_first_child (division, LIST_TYPE_DIVISION);
	
				while (en)
				{
					ASSERT (get_local_entity_type (en) == ENTITY_TYPE_GROUP);
	
					count ++;
	
					en = get_local_entity_child_succ (en, LIST_TYPE_DIVISION);
				}
	
				if (count < max_count)
				{
					break;
				}
			}
	
			division = get_local_entity_child_succ (division, LIST_TYPE_DIVISION_HEADQUARTERS);
		}
	
		if (division)
		{
			//
			// found an existing division with space available
			//
		}
		else
		{
			//
			// create a new division
			//
	
			entity
				*main_division;
	
			max_count = division_database [division_type].maximum_groups_per_division;
	
			main_division = get_local_entity_first_child (force, LIST_TYPE_DIVISION);
	
			while (main_division)
			{
				if (get_local_entity_int_value (main_division, INT_TYPE_ENTITY_SUB_TYPE) == main_division_type)
				{
					//
					// check division for vacancies
					//
	
					if (max_count == 0)
					{
						break;
					}
	
					count = 0;
	
					en = get_local_entity_first_child (main_division, LIST_TYPE_DIVISION);
	
					while (en)
					{
						ASSERT (get_local_entity_type (en) == ENTITY_TYPE_DIVISION);
	
						if (get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE) == division_type)
						{
							count ++;
						}
						
						en = get_local_entity_child_succ (en, LIST_TYPE_DIVISION);
					}
	
					if (count < max_count)
					{
						break;
					}
				}
	
				main_division = get_local_entity_child_succ (main_division, LIST_TYPE_DIVISION);
			}
	
			if (main_division)
			{
				//
				// found an existing division with space available
				//
			}
			else
			{
				//
				// create a new division
				//
	
				main_division = create_new_division (main_division_type, side, force, NULL, FALSE);
			}
	
			ASSERT (main_division);
	
			division = create_new_division (division_type, side, main_division, keysite, FALSE);
		}
	}

	ASSERT (division);

	set_client_server_entity_parent (group, LIST_TYPE_DIVISION, division);

	return division;
}
Beispiel #5
0
void display_campaign_criteria_time_remaining (void)
{
#if 0
	entity
		*force_en;

	force
		*force_raw;

	//session
		//*session_raw;

	//campaign_criteria_type
		//*this_campaign_criteria;

	//float
		//elapsed_hours,
		//elapsed_minutes,
		//elapsed_seconds;

	//int
		//remaining_hours,
		//remaining_minutes,
		//remaining_seconds;

	//int
		//x, y;

	//char
		//s [20];

	//
	// display count down timer until campaign completiion (NOT "tour of duty" timer)
	//

	//
	// currently used only for special games, so I have tailored it to suit :-
	// only displays minutes and seconds,
	// doesn't display on the clients until after first time-of-day resync
	//

	if ((get_game_type () != GAME_TYPE_SPECIAL) && (get_game_type () != GAME_TYPE_MAGAZINE_DEMO))
	{

		return;
	}

	ASSERT (get_session_entity ());

	force_en = get_local_force_entity (get_global_gunship_side ());

	ASSERT (force_en);

	force_raw = (force *) get_local_entity_data (force_en);
/*
	this_campaign_criteria = force_raw->campaign_criteria;

	while (this_campaign_criteria)
	{
		if (this_campaign_criteria->criteria_type == CAMPAIGN_CRITERIA_TIME_DURATION)
		{
			break;
		}

		this_campaign_criteria = this_campaign_criteria->next;
	}

	if (this_campaign_criteria)
	{
		if (this_campaign_criteria->valid)
		{
			session_raw = (force *) get_local_entity_data (get_session_entity ());

			//
			// clients don't display until AFTER first resync (otherwise time will be wrong)
			//

			if (get_comms_model () == COMMS_MODEL_CLIENT)
			{
				if (!display_timer_valid)
				{
					return;
				}
			}

			//
			// get time remaining 
			//

			get_digital_clock_values (session_raw->elapsed_time_of_day, &elapsed_hours, &elapsed_minutes, &elapsed_seconds);

			remaining_seconds = (this_campaign_criteria->days - session_raw->elapsed_days) * ONE_DAY;

			remaining_seconds += (this_campaign_criteria->hours - elapsed_hours) * ONE_HOUR;

			remaining_seconds += (this_campaign_criteria->minutes - elapsed_minutes) * ONE_MINUTE;

			remaining_seconds += (this_campaign_criteria->seconds - elapsed_seconds) * ONE_SECOND;

			if ((remaining_seconds > 0.0) && (remaining_seconds < ONE_HOUR))
			{
				if (remaining_seconds < ONE_MINUTE)
				{
					if (remaining_seconds < 10.0)
					{
						//
						// flash if < 10 seconds
						//
					
						if (frac (session_raw->elapsed_time_of_day) < 0.5)
						{
							return;
						}
					}

					set_ui_font (UI_FONT_ADS_15_ORANGE);
				}
				else
				{
					set_ui_font (UI_FONT_ADS_15_WHITE);
				}

				get_digital_clock_int_values (remaining_seconds, &remaining_hours, &remaining_minutes, &remaining_seconds);

				if (lock_screen (active_screen))
				{
					set_full_screen_viewport ();

					sprintf (s, "T-%02d:%02d", remaining_minutes, remaining_seconds);

					// string WAS right-justified, but looked bad due to proportional fonts changing the width every second !
//					x = get_screen_width (active_screen) - ui_get_string_length (s);
					x = get_screen_width (active_screen) - 62;

					y = ui_get_font_height () + 2;

					ui_display_text (s, x, y);

					unlock_screen (active_screen);
				}
			}
		}
	}
	*/
#endif
}
Beispiel #6
0
void unpack_local_keysite_data (pack_modes mode)
{
   entity
      *en,
		*landing_en;

	landing
		*landing_raw;

   keysite
      *raw;

	int
		side,
		landing_lock,
		landed_lock,
		takeoff_lock,
		in_use,
		index;

   ASSERT (mode != PACK_MODE_UPDATE_ENTITY);

   if (mode == PACK_MODE_BROWSE_SESSION)
   {
      return;
   }

	en = get_local_entity_list ();

	while (en)
	{

		if (get_local_entity_type (en) == ENTITY_TYPE_KEYSITE)
		{

			//
			// unpack keysite
			//

			index = unpack_entity_safe_index ();

			raw = (keysite *) get_local_entity_data (en);

			raw->supplies.ammo_supply_level = unpack_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL);

			raw->supplies.fuel_supply_level = unpack_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL);

			raw->keysite_strength = unpack_float_value (en, FLOAT_TYPE_KEYSITE_STRENGTH);

			raw->keysite_maximum_strength = unpack_float_value (en, FLOAT_TYPE_KEYSITE_MAXIMUM_STRENGTH);

			raw->alive = unpack_int_value (en, INT_TYPE_ALIVE);

			side = unpack_int_value (en, INT_TYPE_SIDE);

			if (side != raw->side)
			{
				//
				// update I-Maps (remove old side)
				//

				if (raw->in_use)
				{
					update_imap_sector_side (en, FALSE);

					if (mode == PACK_MODE_SERVER_SESSION)
					{
						update_imap_importance_level (en, FALSE);
					}
				}

				//
				// change side of keysite buildings
				//

				change_local_keysite_building_sides (en, (entity_sides) side);

				//
				// place into other sides force
				//

				delete_local_entity_from_parents_child_list (en, LIST_TYPE_KEYSITE_FORCE);

				insert_local_entity_into_parents_child_list (en, LIST_TYPE_KEYSITE_FORCE, get_local_force_entity ((entity_sides) side), NULL);

				if (mode == PACK_MODE_SERVER_SESSION)
				{
					// Must be done after removed from force
					update_imap_distance_to_friendly_base ((entity_sides) raw->side);
				}

				//
				// switch sides
				//

				raw->side = side;

				//
				// update I-Maps (add new side)
				//

				if (raw->in_use)
				{
					update_imap_sector_side (en, TRUE);

					if (mode == PACK_MODE_SERVER_SESSION)
					{
						update_imap_importance_level (en, TRUE);

						update_keysite_distance_to_friendly_base (en, (entity_sides) side);
					}
				}
			}

			in_use = unpack_int_value (en, INT_TYPE_IN_USE);

			raw->keysite_id = unpack_int_value (en, INT_TYPE_KEYSITE_ID);

			raw->keysite_usable_state = unpack_int_value (en, INT_TYPE_KEYSITE_USABLE_STATE);

			if (raw->in_use != in_use)
			{
				//
				// Update I-Maps (in use flag changed)
				//

				raw->in_use = in_use;

				update_imap_sector_side (en, in_use);

				if (mode == PACK_MODE_SERVER_SESSION)
				{
					update_imap_importance_level (en, in_use);

					if (in_use)
					{
						update_keysite_distance_to_friendly_base (en, (entity_sides) side);
					}
					else
					{
						update_imap_distance_to_friendly_base ((entity_sides) side);
					}
				}
			}

			unpack_list_root (en, LIST_TYPE_UNASSIGNED_TASK, &raw->unassigned_task_root);
			unpack_list_root (en, LIST_TYPE_ASSIGNED_TASK, &raw->assigned_task_root);
			unpack_list_root (en, LIST_TYPE_COMPLETED_TASK, &raw->completed_task_root);

//			unpack_list_root (en, LIST_TYPE_KEYSITE_GROUP, &raw->keysite_group_root);

			unpack_list_root (en, LIST_TYPE_DIVISION_HEADQUARTERS, &raw->division_headquarters_root);

			if (unpack_int_value (en, INT_TYPE_VALID))
			{
				unpack_list_link (en, LIST_TYPE_CAMPAIGN_OBJECTIVE, &raw->campaign_objective_link);
			}

			#if DEBUG_MODULE

			debug_log ("KS_PACK: unpacking keysite %s", raw->keysite_name);

			#endif

			if (mode == PACK_MODE_SERVER_SESSION)
			{
				raw->repair_timer = unpack_float_value (en, FLOAT_TYPE_REPAIR_TIMER);

				raw->sleep = unpack_float_value (en, FLOAT_TYPE_SLEEP);

				raw->assist_timer = unpack_float_value (en, FLOAT_TYPE_ASSIST_TIMER);

				raw->assign_timer = unpack_float_value (en, FLOAT_TYPE_ASSIGN_TIMER);

				//
				// unpack landing data
				//

				landing_en = get_local_entity_first_child (en, LIST_TYPE_LANDING_SITE);
	
				while (landing_en)
				{
	
					landing_raw = (landing *) get_local_entity_data (landing_en);
	
					landing_raw->reserved_landing_sites = unpack_int_value (landing_en, INT_TYPE_RESERVED_LANDING_SITES);
	
					//landing_raw->free_landing_sites = unpack_int_value (en, INT_TYPE_FREE_LANDING_SITES);
					landing_raw->free_landing_sites = landing_raw->total_landing_sites;
	
					landing_lock = unpack_int_value (landing_en, INT_TYPE_LANDING_LOCK);
	
					landed_lock = unpack_int_value (landing_en, INT_TYPE_LANDED_LOCK);
	
					takeoff_lock = unpack_int_value (landing_en, INT_TYPE_TAKEOFF_LOCK);
	
					#if DEBUG_MODULE

					debug_log ("KS_PACK: %s (%d) unpacking %s landing entity, reserved %d, free %d, locks (saved :landing %d, landed %d, takeoff %d, calc landing %d, landed %d, takeoff %d)",
									raw->keysite_name,
									get_local_entity_index (en),
									entity_sub_type_landing_names [landing_raw->sub_type],
									landing_raw->reserved_landing_sites, landing_raw->free_landing_sites,
									landing_lock, landed_lock, takeoff_lock,
									landing_raw->landing_lock, landing_raw->landed_lock, landing_raw->takeoff_lock);

					if (landing_raw->landing_lock != landing_lock)
					{

						debug_log ("KS_PACK: %s %s landing entity needs landing_lock repairing", raw->keysite_name, entity_sub_type_landing_names [landing_raw->sub_type]);
					}
					if (landing_raw->landed_lock != landed_lock)
					{

						debug_log ("KS_PACK: %s %s landing entity needs landed_lock repairing", raw->keysite_name, entity_sub_type_landing_names [landing_raw->sub_type]);
					}
					if (landing_raw->takeoff_lock != takeoff_lock)
					{

						debug_log ("KS_PACK: %s %s landing entity needs takeoff_lock repairing", raw->keysite_name, entity_sub_type_landing_names [landing_raw->sub_type]);
					}

					#endif
	
					unpack_list_root (landing_en, LIST_TYPE_TAKEOFF_QUEUE, &landing_raw->takeoff_queue_root);

					landing_en = get_local_entity_child_succ (landing_en, LIST_TYPE_LANDING_SITE);
				}
			}
		}

		en = get_local_entity_succ (en);
	}
}
Beispiel #7
0
void assess_group_supplies (entity *en)
{

	entity
		*keysite,
		*force;

	group
		*raw;

	float
		required,
		level;

	raw = get_local_entity_data (en);

	if (get_local_entity_int_value (en, INT_TYPE_RESUPPLY_SOURCE) == RESUPPLY_SOURCE_GROUP)
	{

		//
		// Check if Group needs to request Supplies via Mission...
		//

		if (raw->supplies.ammo_supply_level < 100.0)
		{

			force = get_local_force_entity (get_local_entity_int_value (en, INT_TYPE_SIDE));

			#if DEBUG_MODULE || DEBUG_SUPPLY

			debug_log ("GROUP: SUPPLY_INFO: ground group %s low on ammo, requesting Supply mission", get_local_entity_string (en, STRING_TYPE_FULL_NAME));

			#endif

			notify_local_entity (ENTITY_MESSAGE_FORCE_LOW_ON_SUPPLIES, force, en, ENTITY_SUB_TYPE_CARGO_AMMO);
		}
		else if (raw->supplies.fuel_supply_level < 100.0)
		{

			force = get_local_force_entity (get_local_entity_int_value (en, INT_TYPE_SIDE));

			#if DEBUG_MODULE || DEBUG_SUPPLY

			debug_log ("GROUP: SUPPLY_INFO: ground group %s low on fuel, requesting Supply mission", get_local_entity_string (en, STRING_TYPE_FULL_NAME));

			#endif

			notify_local_entity (ENTITY_MESSAGE_FORCE_LOW_ON_SUPPLIES, force, en, ENTITY_SUB_TYPE_CARGO_FUEL);
		}
	}
	else if (get_local_entity_int_value (en, INT_TYPE_RESUPPLY_SOURCE) == RESUPPLY_SOURCE_KEYSITE)
	{
		//
		// check all group is landed. If so refuel/rearm group via keysite supplies
		//

		if (get_local_entity_int_value (en, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE)
		{

			if (raw->supplies.ammo_supply_level < 100.0)
			{

				//
				// re-arm
				//

				keysite = get_local_entity_parent (en, LIST_TYPE_KEYSITE_GROUP);

				if ((!keysite) || (get_local_entity_type (keysite) != ENTITY_TYPE_KEYSITE))
				{
					keysite = get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, raw->side, get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION), 1.0 * KILOMETRE, NULL, NULL);
				}

				ASSERT (keysite);

				level = get_local_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL);

				required = 100.0 - (raw->supplies.ammo_supply_level * AMMO_USAGE_ACCELERATOR);

				required = bound (required, 0.0, level);

				level -= required;

				set_client_server_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL, level);

				set_client_server_entity_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL, raw->supplies.ammo_supply_level + required);

				#if DEBUG_MODULE || DEBUG_SUPPLY

				debug_log ("GROUP: SUPPLY_INFO: Air group %s members landed, rearming group (now ammo = %f, fuel = %f) from keysite %s (%d) (now ammo = %f, fuel = %f)",
							get_local_entity_string (en, STRING_TYPE_FULL_NAME),
							get_local_entity_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL),
							get_local_entity_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL),
							get_local_entity_string (keysite, STRING_TYPE_FULL_NAME),
							get_local_entity_index (keysite),
							get_local_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL),
							get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL));

				#endif
			}

			if (raw->supplies.fuel_supply_level < 100.0)
			{

				//
				// re-fuel
				//

				keysite = get_local_entity_parent (en, LIST_TYPE_KEYSITE_GROUP);

				if ((!keysite) || (get_local_entity_type (keysite) != ENTITY_TYPE_KEYSITE))
				{
					keysite = get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, raw->side, get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION), 1.0 * KILOMETRE, NULL, NULL);
				}

				ASSERT (keysite);

				level = get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL);

				required = 100.0 - (raw->supplies.fuel_supply_level * FUEL_USAGE_ACCELERATOR);

				required = bound (required, 0.0, level);

				level -= required;

				set_client_server_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL, level);

				set_client_server_entity_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL, raw->supplies.fuel_supply_level + required);

				#if DEBUG_MODULE || DEBUG_SUPPLY

				debug_log ("GROUP: SUPPLY_INFO: Air group %s members landed, refuelling group (now ammo = %f, fuel = %f) from keysite %s (%d) (now ammo = %f, fuel = %f)",
							get_local_entity_string (en, STRING_TYPE_FULL_NAME),
							get_local_entity_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL),
							get_local_entity_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL),
							get_local_entity_string (keysite, STRING_TYPE_FULL_NAME),
							get_local_entity_index (keysite),
							get_local_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL),
							get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL));

				#endif
			}
		}
	}
}
Beispiel #8
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);
}
Beispiel #9
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);
}
Beispiel #10
0
static void kill_local (entity *en)
{

	int
		losses;

	routed_vehicle
		*raw;

	entity
		*task,
		*destroy_task,
		*group;

	////////////////////////////////////////
	//
	// PRE-AMBLE
	//
	////////////////////////////////////////

	#if DEBUG_MODULE >= 2

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en);

	#endif

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

	raw = get_local_entity_data (en);

	group = get_local_entity_parent (en, LIST_TYPE_MEMBER);

	ASSERT (group);

	//
	// update force info
	//

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

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

	////////////////////////////////////////
	//
	// DESTROY COMPONENTS
	//
	////////////////////////////////////////

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		////////////////////////////////////////
		//
		// SEND NOTIFY MESSAGES
		//
		////////////////////////////////////////

		// notify regen of kill

		add_entity_to_regen_queue
		(
			get_local_entity_int_value(en, INT_TYPE_SIDE),
			get_local_entity_type(en),
			get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE),
			get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)
		);

		//
		//
		//

		task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT);

		while (task)
		{

			destroy_task = task;

			task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT);

			if (get_local_entity_type (destroy_task) == ENTITY_TYPE_TASK)
			{

				#if DEBUG_MODULE

				debug_log ("RV_DSTRY: killing routed vehicle, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]);

				#endif

				notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE);
			}
		}

		//
		// Release landing lock (if any)
		//

		release_mobile_entity_landing_locks (en);
	}

	////////////////////////////////////////
	//
	// UNLINK FROM SYSTEM
	//
	////////////////////////////////////////

	//
	// routed_vehicle
	//

	//
	// vehicle
	//

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	unlink_local_entity_children (en, LIST_TYPE_MOVEMENT_DEPENDENT);

	#if DEBUG_MODULE

	debug_log ("RV_DSTRY: removing member %d from group %d", get_local_entity_index (en), get_local_entity_index (raw->vh.member_link.parent));

	#endif

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MOVEMENT_DEPENDENT);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER);

	// gunship_target_link

	// member_link

	// view_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE);

	//
	// mobile
	//

	//
	// kill weapon sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN);

	//
	// kill engine sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING2);

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK);

	// sector_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET);

	// update_link

	set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DYING);

	////////////////////////////////////////
	//
	// KILL
	//
	////////////////////////////////////////

	// must be done before alive flag set to FALSE
	remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en);

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

	damage_routed_vehicle_3d_object (en);

	//
	// group losses
	//

	losses = get_local_entity_int_value (group, INT_TYPE_LOSSES);

	losses ++;

	set_local_entity_int_value (group, INT_TYPE_LOSSES, losses);

	//
	// task losses
	//

	task = get_local_group_primary_task (group);

	if (task)
	{
		losses = get_local_entity_int_value (task, INT_TYPE_LOSSES);

		losses ++;

		set_local_entity_int_value (task, INT_TYPE_LOSSES, losses);
	}

	//
	// Notify Campaign Screen
	//

	notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group);

	//
	// Notify the GROUP that the mobile has been killed  (N.B. must be done AFTER mobile is unlinked from member list)
	//

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en);
	}

	////////////////////////////////////////
	//
	// SPECIAL EFFECTS
	//
	////////////////////////////////////////

	set_local_entity_float_value (en, FLOAT_TYPE_DEATH_TIMER, calculate_mobile_death_timer_value (en));

	routed_vehicle_impact_movement (en);

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		create_client_server_object_killed_explosion_effect (en);
	}

	#if LANDING_ROUTE_CHECK

	destroy_debug_entity_landing_route_check (en);

	#endif

	/////////////////////////////////////////////////////////////////
	//
	// SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED
	//
	////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////
	//
	//
	/////////////////////////////////////////////////////////////////
}
Beispiel #11
0
int assign_task_to_group (entity *group, entity *task_en, unsigned int valid_members)
{

	int
		sites_required;

	entity_sub_types
		sub_type,
		group_type;

	entity
		*force,
		*landing,
		*end_keysite,
		*start_keysite,
		*guide,
		*member;

	vec3d
		*pos;

	task
		*task_raw;

   debug_assert (get_comms_model () == COMMS_MODEL_SERVER);

	ASSERT (task_en);

	ASSERT (group);

	ASSERT (!(get_local_group_primary_task (group) && (get_local_entity_int_value (task_en, INT_TYPE_PRIMARY_TASK))));

	task_raw = ( task * ) get_local_entity_data (task_en);

	group_type = get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE);

	member = get_local_entity_first_child (group, LIST_TYPE_MEMBER);

	// don't if no members or if the group is a CARRIER
	if (!member)
	{
		return FALSE;
	}

	if (get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE) == ENTITY_SUB_TYPE_GROUP_ASSAULT_SHIP)
	{
		if (task_raw->sub_type != ENTITY_SUB_TYPE_TASK_ENGAGE)
		{
			return FALSE;
		}
	}

	//
	// check for invalid tasks
	//
	
	switch (task_raw->sub_type)
	{
		case ENTITY_SUB_TYPE_TASK_LANDING:
		case ENTITY_SUB_TYPE_TASK_LANDING_HOLDING:
		case ENTITY_SUB_TYPE_TASK_TAKEOFF:
		case ENTITY_SUB_TYPE_TASK_TAKEOFF_HOLDING:
		{
			#ifdef DEBUG

			debug_fatal ("ASSIGN: Invalid task type (%s) for assign_task_to_group", get_local_entity_string (task_en, STRING_TYPE_FULL_NAME));

			#endif

			return FALSE;
		}
	}

	//
	// Create route
	//

	if (get_local_entity_int_value (group, INT_TYPE_GROUP_LIST_TYPE) == LIST_TYPE_KEYSITE_GROUP)
	{
		start_keysite = get_local_entity_parent (group, LIST_TYPE_KEYSITE_GROUP);
	}
	else
	{
//		start_keysite = get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, task_raw->side, get_local_entity_vec3d_ptr (group, VEC3D_TYPE_POSITION), 1.0 * KILOMETRE, NULL);
		start_keysite = NULL;
	}

	pos = get_local_entity_vec3d_ptr (task_en, VEC3D_TYPE_STOP_POSITION);

	force = get_local_force_entity ( ( entity_sides ) get_local_entity_int_value (task_en, INT_TYPE_SIDE) );

	sub_type = group_database [group_type].default_landing_type;

	landing = NULL;

	end_keysite = NULL;

	if (get_local_entity_int_value (task_en, INT_TYPE_ASSESS_LANDING))
	{
		ASSERT (start_keysite);

		end_keysite = ( entity * ) get_local_entity_ptr_value (task_en, PTR_TYPE_RETURN_KEYSITE);

		if (end_keysite)
		{
			//
			// check end keysite has suitble free landing sites
			//

			if (start_keysite != end_keysite)
			{
				//
				// if end keysite == start keysite then keysite MUST have enough sites because the aircraft are already there
				//
				
				sites_required = get_local_group_member_count (group);
	
				if (get_keysite_landing_sites_available (end_keysite, sub_type) < sites_required)
				{
					//
					// END keysite was specified - but no free landing sites for this group
					//
					
					return FALSE;
				}
			}
		}
		else
		{
			//
			// No END keysite specified so return to start keysite
			//

			end_keysite = start_keysite;

			set_local_entity_ptr_value (task_en, PTR_TYPE_RETURN_KEYSITE, end_keysite);
		}

		ASSERT (end_keysite);

		landing = get_local_entity_landing_entity (end_keysite, group_database [get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)].default_landing_type);
	}

	if (create_generic_waypoint_route (group, task_en, end_keysite, NULL, NULL, NULL, 0))
	{
		#if DEBUG_MODULE

		debug_log ("ASSIGN: group %s (%d) assigned to task %s (%d)",
							get_local_entity_string (group, STRING_TYPE_FULL_NAME),
							get_local_entity_index (group),
							get_local_entity_string (task_en, STRING_TYPE_FULL_NAME),
							get_local_entity_index (task_en));

		#endif

		//
		// Assign task
		//

		guide = push_task_onto_group_task_stack (group, task_en, valid_members);

		assign_task_to_group_members (group, guide, valid_members);

		return TRUE;
	}

	return FALSE;
}
Beispiel #12
0
int assign_primary_task_to_group (entity *group_en, entity *task_en)
{
	entity_sub_types
		task_type,
		group_type;

	entity
		*force,
		*keysite;

	int
		side,
		formation,
		air_threat,
		enemy_sectors;

	unsigned int
		threat;

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);
		
	task_type = get_local_entity_int_value (task_en, INT_TYPE_ENTITY_SUB_TYPE);

	ASSERT (task_database [task_type].primary_task);

	group_type = get_local_entity_int_value (group_en, INT_TYPE_ENTITY_SUB_TYPE);

	ASSERT (!get_local_group_primary_task (group_en));

	if (assign_task_to_group (group_en, task_en, TASK_ASSIGN_ALL_MEMBERS))
	{
		//
		// set default group formation
		//

		formation = get_local_entity_int_value (group_en, INT_TYPE_GROUP_DEFAULT_FORMATION);

		if (formation != get_local_entity_int_value (group_en, INT_TYPE_GROUP_FORMATION))
		{
			set_client_server_entity_int_value (group_en, INT_TYPE_GROUP_FORMATION, formation);
		}

		//
		// Link to new keysite
		// 

		if (get_local_entity_int_value (group_en, INT_TYPE_GROUP_LIST_TYPE) == LIST_TYPE_KEYSITE_GROUP)
		{
			keysite = ( entity * ) get_local_entity_ptr_value (task_en, PTR_TYPE_RETURN_KEYSITE);

			if (keysite)
			{
				set_client_server_entity_parent (group_en, LIST_TYPE_KEYSITE_GROUP, keysite);
			}	
		}

		//
		// Notify Force
		//

		side = get_local_entity_int_value (group_en, INT_TYPE_SIDE);

		force = get_local_force_entity ( ( entity_sides ) side );

		ASSERT (force);

		notify_local_entity (ENTITY_MESSAGE_TASK_ASSIGNED, force, task_en);

		//
		// Assess for Escort task
		//

		if (task_database [task_type].escort_required_threshold != ESCORT_NEVER)
		{
			threat = assess_task_difficulty (task_en, &air_threat, &enemy_sectors);

			#if DEBUG_ESCORT_TASK_CREATION

			debug_filtered_log ("(ASSIGN) Side %s: Assigned %s to %s, objective %s",
											entity_side_short_names [side],
											get_local_entity_string (group_en, STRING_TYPE_FULL_NAME),
											get_local_entity_string (task_en, STRING_TYPE_FULL_NAME),
											get_task_objective_string (task_en)
									);

			debug_filtered_log ("Threat: %d (air_threat: %d, enemy_sectors: %d) - Threshold %d",
											threat, air_threat, enemy_sectors,
											task_database [task_type].escort_required_threshold);

			#endif

			if (threat >= task_database [task_type].escort_required_threshold)
			{
				create_escort_task (group_en, (threat >= ESCORT_CRITICAL), task_database [ENTITY_SUB_TYPE_TASK_ESCORT].task_priority, NULL, NULL);

				ai_log ("(ASSIGN) Created Escort Task for %s :- Threat %d / Threshold %d",
											get_local_entity_string (task_en, STRING_TYPE_FULL_NAME),
											threat,
											task_database [task_type].escort_required_threshold
											);
			}
		}

		//
		// Store Start Time
		//

		set_client_server_entity_float_value (task_en, FLOAT_TYPE_START_TIME, get_local_entity_float_value (get_session_entity (), FLOAT_TYPE_ELAPSED_TIME));

		//
		// Clear Expire Timer (now also used for destroying completed tasks)
		//

		set_local_entity_float_value (task_en, FLOAT_TYPE_EXPIRE_TIMER, 0.0);

		ai_log ("(ASSIGN) Side %s: Assigned %s (%d) to %s (%d) - Priority %f",
					entity_side_short_names [side],
					get_local_entity_string (group_en, STRING_TYPE_FULL_NAME),
					get_local_entity_safe_index (group_en),
					get_local_entity_string (task_en, STRING_TYPE_FULL_NAME),
					get_local_entity_safe_index (task_en),
					get_local_entity_float_value (task_en, FLOAT_TYPE_TASK_PRIORITY));

		return TRUE;
	}

	return FALSE;
}
Beispiel #13
0
static void kill_local (entity *en)
{

	int
		losses;

	entity
		*task,
		*group,
		*destroy_task;

	fixed_wing
		*raw;

	////////////////////////////////////////
	//
	// PRE-AMBLE
	//
	////////////////////////////////////////

	#if DEBUG_MODULE >= 2

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en);

	#endif

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

	raw = (fixed_wing *) get_local_entity_data (en);

	group = get_local_entity_parent (en, LIST_TYPE_MEMBER);

	ASSERT (group);

	//
	// update force info
	//

	remove_from_force_info (get_local_force_entity ((entity_sides) raw->ac.mob.side), en);

	if (tacview_is_logging())
		write_tacview_unit_event(en, TACVIEW_UNIT_DESTROYED, NULL);

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

	////////////////////////////////////////
	//
	// SEND NOTIFY MESSAGES
	//
	////////////////////////////////////////

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		// notify regen of kill

		add_entity_to_regen_queue
		(
			(entity_sides) get_local_entity_int_value(en, INT_TYPE_SIDE),
			get_local_entity_type(en),
			get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE),
			get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)
		);

		task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT);

		while (task)
		{

			destroy_task = task;

			task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT);

			if (destroy_task->type == ENTITY_TYPE_TASK)
			{

				#if DEBUG_MODULE

				debug_log ("FW_DSTRY: killing fixed wing, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]);

				#endif

				notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE);
			}
		}

		//
		// Release landing lock (if any)
		//

		release_mobile_entity_landing_locks (en);
	}

	////////////////////////////////////////
	//
	// UNLINK FROM SYSTEM
	//
	////////////////////////////////////////

	//
	// fixed_wing
	//

	//
	// aircraft
	//

	// aircrew_root

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	// unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER);

	// gunship_target_link

	// member_link

	// view_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE);

	//
	// mobile
	//

	//
	// kill weapon sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN);

	//
	// kill engine sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING2);

	//
	// Kill speech
	//

	notify_speech_buffers_entity_killed (en);

	// special_effect root

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK);

	// sector_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET);

	// update_link

	set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DYING);

	//
	// death timer (set time after which entity is totally destroyed)
	//

	set_local_entity_float_value (en, FLOAT_TYPE_DEATH_TIMER, calculate_mobile_death_timer_value (en));

	////////////////////////////////////////
	//
	// KILL
	//
	////////////////////////////////////////

	damage_fixed_wing_3d_object (en);

	// must be done before alive flag set to FALSE
	remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en);

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

	//
	// group losses
	//

	losses = get_local_entity_int_value (group, INT_TYPE_LOSSES);

	losses ++;

	set_local_entity_int_value (group, INT_TYPE_LOSSES, losses);

	//
	// task losses
	//

	task = get_local_group_primary_task (group);

	if (task)
	{
		losses = get_local_entity_int_value (task, INT_TYPE_LOSSES);

		losses ++;

		set_local_entity_int_value (task, INT_TYPE_LOSSES, losses);
	}

	//
	// Notify Campaign Screen
	//

	notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group);

	//
	// Notify the GROUP that the mobile has been killed  (N.B. must be done AFTER mobile is unlinked from member list)
	//

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en);
	}

	////////////////////////////////////////
	//
	// SPECIAL EFFECTS
	//
	////////////////////////////////////////

	set_local_fixed_wing_afterburner_state (en, OFF);

	fixed_wing_impact_movement (en);

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		vec3d
			*position;

		sound_sample_indices
			sound_sample_index;

		create_client_server_object_killed_explosion_effect (en);

		position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

		sound_sample_index = SOUND_SAMPLE_INDEX_SHOT_DOWN_AIRCRAFT;

		create_client_server_sound_effect_entity
		(
			en,
			ENTITY_SIDE_NEUTRAL,
			ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1,
			SOUND_CHANNEL_SOUND_EFFECT,
			SOUND_LOCALITY_ALL,
			NULL,												// position
			1.0,												// amplification
			1.0,												// Werewolf pitch
			TRUE,												// valid sound effect
			TRUE,												// looping
			1,													// sample count
			&sound_sample_index							// sample index list
		);
	}

	#if LANDING_ROUTE_CHECK

	destroy_debug_entity_landing_route_check (en);

	#endif

	/////////////////////////////////////////////////////////////////
	//
	// SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED
	//
	/////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////
	//
	//
	/////////////////////////////////////////////////////////////////
}
Beispiel #14
0
void create_client_server_entity_weapon (entity *launcher, entity_sub_types weapon_sub_type, int weapon_index, int burst_size, int *smoke_trail_indices)
{
	entity
		*force,
		*target,
		*weapon;

	meta_smoke_list_types
		smoke_trail_type;

	int
		i,
		num_smoke_trail_entities,
		valid_sound_effect,
		current_weapon_count,
		new_weapon_count;

	ASSERT (launcher);

	ASSERT (entity_sub_type_weapon_valid (weapon_sub_type));

	//
	// get target
	//

	if (!(weapon_database[weapon_sub_type].weapon_class & (WEAPON_CLASS_DECOY | WEAPON_CLASS_CARGO | WEAPON_CLASS_DEBRIS)))
	{
		target = get_local_entity_parent (launcher, LIST_TYPE_TARGET);

/*		if (weapon_database[weapon_sub_type].hellfire_flight_profile)
		{
			if (get_local_entity_int_value (launcher, INT_TYPE_LOCK_ON_AFTER_LAUNCH))
			{
				target = NULL;
			}
		} */
	}
	else
	{
		target = NULL;
	}

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		////////////////////////////////////////
		//
		// SERVER/TX and SERVER/RX
		//
		////////////////////////////////////////

		ASSERT (weapon_index == ENTITY_INDEX_DONT_CARE);

		ASSERT (burst_size == BURST_SIZE_DONT_CARE);

		ASSERT (!smoke_trail_indices);

		// NOTE: The clients' weapon counters lag the servers' so it is possible that the
		//       client may unknowingly attempt to create more weapons than are available.
		//       This is prone to happen during rapid firing.

		current_weapon_count = get_local_entity_weapon_count (launcher, weapon_sub_type);

		if (current_weapon_count > 0)
		{
			int loal_mode = weapon_database[weapon_sub_type].hellfire_flight_profile && get_local_entity_int_value (launcher, INT_TYPE_LOCK_ON_AFTER_LAUNCH);

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

			//
			// get burst size wrt rate of fire
			//

			if (weapon_database[weapon_sub_type].rate_of_fire != FIRE_SINGLE_WEAPON)
			{
				float time_per_shot = weapon_database[weapon_sub_type].inverse_rate_of_fire * ONE_MINUTE;
				unsigned int* last_shot = NULL;

				switch (launcher->type)
				{
				case ENTITY_TYPE_HELICOPTER:
					last_shot = &((helicopter*)get_local_entity_data(launcher))->ac.weapon_salvo_timer;
					break;

				case ENTITY_TYPE_FIXED_WING:
					last_shot = &((fixed_wing*)get_local_entity_data(launcher))->ac.weapon_salvo_timer;
					break;

				case ENTITY_TYPE_ANTI_AIRCRAFT:
					last_shot = &((anti_aircraft*)get_local_entity_data(launcher))->vh.weapon_salvo_timer;
					break;

				case ENTITY_TYPE_PERSON:
					last_shot = &((person*)get_local_entity_data(launcher))->vh.weapon_salvo_timer;
					break;

				case ENTITY_TYPE_ROUTED_VEHICLE:
					last_shot = &((routed_vehicle*)get_local_entity_data(launcher))->vh.weapon_salvo_timer;
					break;

				case ENTITY_TYPE_SHIP_VEHICLE:
					last_shot = &((ship_vehicle*)get_local_entity_data(launcher))->vh.weapon_salvo_timer;
					break;
				}

				if (last_shot)
				{
					unsigned int current_time = get_system_time();
					float elapsed_time = 1;

					if (*last_shot > 0)
					{
						if (current_time < *last_shot)
							return;
						elapsed_time = (current_time - *last_shot) * 0.001;
					}
					else
						elapsed_time = get_delta_time();

					burst_size = (int)(weapon_database[weapon_sub_type].rate_of_fire * ONE_OVER_ONE_MINUTE * elapsed_time);
					if (burst_size < 1)
					{
						if (*last_shot == 0)  // first shot in salvo always get fired
							burst_size = 1;
						else
							return;
					}

					if (*last_shot)
						*last_shot += (int)(burst_size * time_per_shot * 1000.0);
					else
						*last_shot = current_time;
				}
				else
				{
					ASSERT(FALSE);
					burst_size = 1;
				}
			}
			else
			{
				burst_size = 1;
			}

			//
			// set burst timer
			//

			valid_sound_effect = FALSE;

			if (get_local_entity_float_value (launcher, FLOAT_TYPE_WEAPON_BURST_TIMER) == 0.0)
			{
				set_local_entity_float_value (launcher, FLOAT_TYPE_WEAPON_BURST_TIMER, weapon_database[weapon_sub_type].burst_duration);

				valid_sound_effect = TRUE;
			}

			//
			// create weapon
			//

			weapon = create_local_entity
			(
				ENTITY_TYPE_WEAPON,
				ENTITY_INDEX_DONT_CARE,
				ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, weapon_sub_type),
				ENTITY_ATTR_INT_VALUE (INT_TYPE_WEAPON_BURST_SIZE, burst_size),
				ENTITY_ATTR_INT_VALUE (INT_TYPE_WEAPON_MISSILE_PHASE, MISSILE_PHASE1),
				ENTITY_ATTR_INT_VALUE (INT_TYPE_LOCK_ON_AFTER_LAUNCH, loal_mode),
				ENTITY_ATTR_PARENT (LIST_TYPE_LAUNCHED_WEAPON, launcher),
				ENTITY_ATTR_PARENT (LIST_TYPE_TARGET, target),
				ENTITY_ATTR_END
			);

			if (weapon)
			{
				//
				// send FIRE message to force (unless it's a decoy/cargo/debris being launched)
				//

				if ((target) && (!(weapon_database[weapon_sub_type].weapon_class & (WEAPON_CLASS_DECOY | WEAPON_CLASS_CARGO | WEAPON_CLASS_DEBRIS))))
				{
					force = get_local_force_entity ((entity_sides) get_local_entity_int_value (target, INT_TYPE_SIDE));

					if (force)
					{
						notify_local_entity (ENTITY_MESSAGE_ENTITY_FIRED_AT, force, launcher, target);
					}
				}

				//
				// create sound effect(s)
				//

				if (valid_sound_effect)
				{
					create_weapon_launched_sound_effects (launcher, weapon_sub_type);
				}

				//
				// create smoke trail
				//

				smoke_trail_type = (meta_smoke_list_types) get_local_entity_int_value (weapon, INT_TYPE_WEAPON_SMOKE_TRAIL_TYPE);

				if (smoke_trail_type != META_SMOKE_LIST_TYPE_NONE)
				{
					struct OBJECT_3D_BOUNDS
						*bounding_box;

					vec3d
						exhaust_offset;

					num_smoke_trail_entities = count_entities_in_meta_smoke_list (smoke_trail_type);

					ASSERT (num_smoke_trail_entities > 0);

					smoke_trail_indices = (int *) malloc_fast_mem (sizeof (int) * num_smoke_trail_entities);

					for (i = 0; i < num_smoke_trail_entities; i++)
					{
						smoke_trail_indices[i] = ENTITY_INDEX_DONT_CARE;
					}

					bounding_box = get_object_3d_bounding_box (get_local_entity_int_value (weapon, INT_TYPE_DEFAULT_3D_SHAPE));

					if ((weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_HOKUM_PILOT) ||(weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_HOKUM_CO_PILOT))
					{
						exhaust_offset.x = 0.0;
						exhaust_offset.y = 0.0;
						exhaust_offset.z = 0.0;
					}
					else
					{
						exhaust_offset.x = 0.0;
						exhaust_offset.y = 0.0;
						exhaust_offset.z = bounding_box->zmin;
					}

					create_meta_smoke_list_specified_offset (smoke_trail_type, weapon, &exhaust_offset, smoke_trail_indices);
				}

				transmit_entity_comms_message
				(
					ENTITY_COMMS_CREATE_WEAPON,
					NULL,
					launcher,
					weapon_sub_type,
					get_local_entity_safe_index (weapon),
					burst_size,
					smoke_trail_indices
				);

				if (smoke_trail_indices)
				{
					free_mem (smoke_trail_indices);
				}

				//
				// out of weapons (if infinite weapons then reload else select next weapon)
				//

				new_weapon_count = get_local_entity_weapon_count (launcher, weapon_sub_type);

				if (new_weapon_count <= 0)
				{
					#if !DEMO_VERSION
					if (get_local_entity_int_value (get_session_entity (), INT_TYPE_INFINITE_WEAPONS))
					{
						weapon_config_types
							config_type;

						config_type = (weapon_config_types) get_local_entity_int_value (launcher, INT_TYPE_WEAPON_CONFIG_TYPE);

						set_client_server_entity_int_value (launcher, INT_TYPE_WEAPON_CONFIG_TYPE, config_type);
					}
					else
					#endif
					{
						//
						// play weapon out of ammo speech
						//

						play_entity_weapon_out_speech (launcher, weapon_sub_type);

						//
						// select next weapon
						//
/*
						if (!(weapon_database[weapon_sub_type].weapon_class & (WEAPON_CLASS_DECOY | WEAPON_CLASS_CARGO | WEAPON_CLASS_DEBRIS)))
						{
							entity_sub_types
								next_weapon_sub_type;

							if (get_local_entity_int_value (launcher, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
							{
								next_weapon_sub_type = get_next_available_weapon_sub_type (launcher);
							}
							else
							{
								next_weapon_sub_type = ENTITY_SUB_TYPE_WEAPON_NO_WEAPON;
							}

							set_client_server_entity_int_value (launcher, INT_TYPE_SELECTED_WEAPON, next_weapon_sub_type);
						}
*/
					}
				}
				else
				{
					int
						report_ammo_low_count;

					report_ammo_low_count = weapon_database[weapon_sub_type].report_ammo_low_count;

					if ((current_weapon_count > report_ammo_low_count) && (new_weapon_count <= report_ammo_low_count))
					{
						//
						// play weapon low speech
						//

						play_entity_weapon_low_speech (launcher, weapon_sub_type);
					}
					else
					{
						//
						// weapon launch speech
						//

						play_entity_weapon_launched_speech (launcher, weapon_sub_type);
					}
				}
			}

			set_force_local_entity_create_stack_attributes (FALSE);
		}
		else
		{
			pause_client_server_continuous_weapon_sound_effect (launcher, weapon_sub_type);
		}
	}
	else
	{
		if (get_comms_data_flow () == COMMS_DATA_FLOW_TX)
		{
			////////////////////////////////////////
			//
			// CLIENT/TX
			//
			////////////////////////////////////////

			ASSERT (weapon_index == ENTITY_INDEX_DONT_CARE);

			ASSERT (burst_size == BURST_SIZE_DONT_CARE);

			ASSERT (!smoke_trail_indices);

			// NOTE: The clients' weapon counters lag the servers' so it is possible that the
			//       client may unknowingly attempt to create more weapons than are available.
			//       This is prone to happen during rapid firing.

			if (get_local_entity_weapon_available (launcher, weapon_sub_type))
			{
				transmit_entity_comms_message
				(
					ENTITY_COMMS_CREATE_WEAPON,
					NULL,
					launcher,
					weapon_sub_type,
					ENTITY_INDEX_DONT_CARE,
					burst_size,
					NULL
				);
			}
		}
		else
		{
			////////////////////////////////////////
			//
			// CLIENT/RX
			//
			////////////////////////////////////////

			ASSERT (weapon_index != ENTITY_INDEX_DONT_CARE);

			ASSERT (burst_size > 0);

			set_force_local_entity_create_stack_attributes (TRUE);

			weapon = create_local_entity
			(
				ENTITY_TYPE_WEAPON,
				weapon_index,
				ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, weapon_sub_type),
				ENTITY_ATTR_INT_VALUE (INT_TYPE_WEAPON_BURST_SIZE, burst_size),
				ENTITY_ATTR_PARENT (LIST_TYPE_LAUNCHED_WEAPON, launcher),
				ENTITY_ATTR_PARENT (LIST_TYPE_TARGET, target),
				ENTITY_ATTR_END
			);

			ASSERT (weapon);

			//
			// create smoke trail
			//

			smoke_trail_type = (meta_smoke_list_types) get_local_entity_int_value (weapon, INT_TYPE_WEAPON_SMOKE_TRAIL_TYPE);

			if (smoke_trail_type != META_SMOKE_LIST_TYPE_NONE)
			{
				struct OBJECT_3D_BOUNDS
					*bounding_box;

				vec3d
					exhaust_offset;

				ASSERT (smoke_trail_indices);

				bounding_box = get_object_3d_bounding_box (get_local_entity_int_value (weapon, INT_TYPE_DEFAULT_3D_SHAPE));

				if ((weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_HOKUM_PILOT) ||(weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_HOKUM_CO_PILOT))
				{
					exhaust_offset.x = 0.0;
					exhaust_offset.y = 0.0;
					exhaust_offset.z = 0.0;
				}
				else
				{
					exhaust_offset.x = 0.0;
					exhaust_offset.y = 0.0;
					exhaust_offset.z = bounding_box->zmin;
				}

				create_meta_smoke_list_specified_offset (smoke_trail_type, weapon, &exhaust_offset, smoke_trail_indices);
			}
			else
			{
				ASSERT (!smoke_trail_indices);
			}

			set_force_local_entity_create_stack_attributes (FALSE);
		}
	}
}
Beispiel #15
0
static void kill_local (entity *en)
{

	int
		losses;

	helicopter
		*raw;

	entity
		*task,
		*group,
		*member,
		*destroy_task;

	////////////////////////////////////////
	//
	// PRE-AMBLE
	//
	////////////////////////////////////////

	#if DEBUG_MODULE >= 2

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en);

	#endif

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

	raw = get_local_entity_data (en);

	group = get_local_entity_parent (en, LIST_TYPE_MEMBER);

	ASSERT (group);

	//
	// update force info
	//

	remove_from_force_info (get_local_force_entity (raw->ac.mob.side), en);

	if (en == get_gunship_entity ())
	{
		//
		// Award Points for mission
		//

		task = get_local_entity_primary_task (en);

		if (task)
		{
			if (get_local_entity_int_value (task, INT_TYPE_TASK_STATE) == TASK_STATE_COMPLETED)
			{
				//
				// Only award points for COMPLETE missions (also means player can't rejoin that mission and get points again)
				//

				notify_gunship_entity_mission_terminated (en, task);
			}
		}
	}

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

	////////////////////////////////////////
	//
	// DESTROY COMPONENTS
	//
	////////////////////////////////////////

	#if DEBUG_MODULE

	debug_log ("HC_DSTRY: killing helicopter %s", entity_sub_type_aircraft_names [raw->ac.mob.sub_type]);

	#endif

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		// notify regen of kill

		add_entity_to_regen_queue
		(
			get_local_entity_int_value(en, INT_TYPE_SIDE),
			get_local_entity_type(en),
			get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE),
			get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)
		);

		//
		// notify task dependents
		//

		task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT);

		while (task)
		{

			destroy_task = task;

			task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT);

			if (destroy_task->type == ENTITY_TYPE_TASK)
			{

				#if DEBUG_MODULE

				debug_log ("HC_DSTRY: killing helicopter, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]);

				#endif

				notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE);
			}
		}

		//
		// Release landing lock (if any)
		//

		release_mobile_entity_landing_locks (en);

		//
		// if group contains player, set all helicopters in group to "weapons free", and clear "hold position" flag
		//

		if (get_local_entity_int_value (en, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
		{
			member = get_local_entity_first_child (group, LIST_TYPE_MEMBER);

			while (member)
			{
				set_client_server_entity_int_value (member, INT_TYPE_WEAPONS_HOLD, FALSE);

				set_client_server_entity_int_value (member, INT_TYPE_POSITION_HOLD, FALSE);

				member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER);
			}
		}
	}

	////////////////////////////////////////
	//
	// UNLINK FROM SYSTEM
	//
	////////////////////////////////////////

	//
	// helicopter
	//

	unlink_local_entity_children (en, LIST_TYPE_GUNSHIP_TARGET);

	unlink_local_entity_children (en, LIST_TYPE_PADLOCK);

	//
	// aircraft
	//

	// aircrew_root

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	////////////////////////////////////////
	//
	// the eject sequence relies on launched weapons NOT being unlinked
	//

	// unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON);

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

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER);

	// gunship_target_link

	// member_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MOVEMENT_DEPENDENT);

	// view_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE);

	//
	// mobile
	//

	//
	// kill weapon sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN);

	//
	// kill engine sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_LOOPING);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_WIND_UP);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_WIND_DOWN);

	//
	// kill radio / warning effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_INCOMING_MISSILE_WARNING);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_LOCK_ON_TONE);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_MCA);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_RADAR_LOCKED);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_RADAR_TRACKED);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CPG_MESSAGE);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_RADIO_MESSAGE);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_WARNING_MESSAGE);

	notify_speech_buffers_entity_killed (en);

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK);

	// sector_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET);

	// update_link

	//
	// death timer (set time after which entity is totally destroyed)
	//

	set_local_entity_float_value (en, FLOAT_TYPE_DEATH_TIMER, calculate_mobile_death_timer_value (en));

	////////////////////////////////////////
	//
	// KILL
	//
	////////////////////////////////////////

	damage_helicopter_3d_object (en);

	// must be done before alive flag set to FALSE
	remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en);

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

	//
	// group losses
	//

	losses = get_local_entity_int_value (group, INT_TYPE_LOSSES);

	losses ++;

	set_local_entity_int_value (group, INT_TYPE_LOSSES, losses);

	//
	// task losses
	//

	task = get_local_group_primary_task (group);

	if (task)
	{
		losses = get_local_entity_int_value (task, INT_TYPE_LOSSES);

		losses ++;

		set_local_entity_int_value (task, INT_TYPE_LOSSES, losses);
	}

	//
	// Notify Campaign Screen
	//

	notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group);

	//
	// Notify the GROUP that the mobile has been killed  (N.B. must be done AFTER mobile is unlinked from member list)
	//

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en);
	}

	//
	// Notify force to check campaign criteria
	//

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		entity
			*force;

		force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE);

		while (force)
		{
			notify_local_entity (ENTITY_MESSAGE_CHECK_CAMPAIGN_OBJECTIVES, force, en);

			force = get_local_entity_child_succ (force, LIST_TYPE_FORCE);
		}
	}

	////////////////////////////////////////
	//
	// SPECIAL EFFECTS
	//
	////////////////////////////////////////

	helicopter_impact_movement (en);

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		vec3d
			*position;

		sound_sample_indices
			sound_sample_index;

		set_client_server_entity_int_value (en, INT_TYPE_MAIN_ROTOR_DAMAGED, TRUE);

		set_client_server_entity_int_value (en, INT_TYPE_TAIL_ROTOR_DAMAGED, TRUE);

		create_client_server_object_killed_explosion_effect (en);

		position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

		sound_sample_index = SOUND_SAMPLE_INDEX_SHOT_DOWN_HELICOPTER;

		create_client_server_sound_effect_entity
		(
			en,
			ENTITY_SIDE_NEUTRAL,
			ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_LOOPING,
			SOUND_CHANNEL_SOUND_EFFECT,
			SOUND_LOCALITY_ALL,
			NULL,												// position
			1.0,												// amplification
			TRUE,												// valid sound effect
			TRUE,												// looping
			1,													// sample count
			&sound_sample_index							// sample index list
		);
	}

	set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DYING);

	////////////////////////////////////////
	//
	// VIEWS
	//
	////////////////////////////////////////

	if ((en == get_gunship_entity ()) && (!get_local_entity_int_value (en, INT_TYPE_EJECTED)))
	{
		set_gunship_entity (NULL);
	}

	#if LANDING_ROUTE_CHECK

	destroy_debug_entity_landing_route_check (en);

	#endif

	/////////////////////////////////////////////////////////////////
	//
	// SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED
	//
	/////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////
	//
	//
	/////////////////////////////////////////////////////////////////
}
Beispiel #16
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;
}
Beispiel #17
0
static void kill_local (entity *en)
{

	int
		losses;

	entity
		*task,
		*group,
		*keysite,
		*destroy_task;

	ship_vehicle
		*raw;

	////////////////////////////////////////
	//
	// PRE-AMBLE
	//
	////////////////////////////////////////

	#if DEBUG_MODULE >= 2

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en);

	#endif

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

	raw = (ship_vehicle *) get_local_entity_data (en);

	group = get_local_entity_parent (en, LIST_TYPE_MEMBER);

	ASSERT (group);

	keysite = NULL;

	if (tacview_is_logging())
		write_tacview_unit_event(en, TACVIEW_UNIT_DESTROYED, NULL);

	//
	// update force info
	//

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

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

	////////////////////////////////////////
	//
	// DESTROY COMPONENTS
	//
	////////////////////////////////////////

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT);

		while (task)
		{
			destroy_task = task;

			task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT);

			if (destroy_task->type == ENTITY_TYPE_TASK)
			{
				#if DEBUG_MODULE

				debug_log ("SH_DSTRY: killing ship, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]);

				#endif

				notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE);
			}
		}

		//
		// Release landing lock (if any)
		//

		release_mobile_entity_landing_locks (en);

		////////////////////////////////////////
		//
		// UNLINK FROM SYSTEM
		//
		////////////////////////////////////////

		//
		// Destroy keysite entity if ship is carrier
		//

		keysite = get_local_entity_first_child (en, LIST_TYPE_MOVEMENT_DEPENDENT);

		while (keysite)
		{
			if (get_local_entity_type (keysite) == ENTITY_TYPE_KEYSITE)
			{
				break;
			}

			keysite = get_local_entity_child_succ (keysite, LIST_TYPE_MOVEMENT_DEPENDENT);
		}
	}

	//
	// ship_vehicle
	//

	//
	// vehicle
	//

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	unlink_local_entity_children (en, LIST_TYPE_MOVEMENT_DEPENDENT);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MOVEMENT_DEPENDENT);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER);

	// gunship_target_link

	// member_link

	// view_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE);

	//
	// mobile
	//

	//
	// kill weapon sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN);

	//
	// kill engine sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING2);

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK);

	// sector_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET);

	// update_link

	set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_STOPPED);

	////////////////////////////////////////
	//
	// KILL
	//
	////////////////////////////////////////

	// must be done before alive flag set
	remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en);

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

	damage_ship_3d_object (en);

	//
	// group losses
	//

	losses = get_local_entity_int_value (group, INT_TYPE_LOSSES);

	losses ++;

	set_local_entity_int_value (group, INT_TYPE_LOSSES, losses);

	//
	// task losses
	//

	task = get_local_group_primary_task (group);

	if (task)
	{
		losses = get_local_entity_int_value (task, INT_TYPE_LOSSES);

		losses ++;

		set_local_entity_int_value (task, INT_TYPE_LOSSES, losses);
	}

	//
	// Notify Campaign Screen
	//

	notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group);

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		//
		// Notify the GROUP that the mobile has been killed  (N.B. must be done AFTER mobile is unlinked from member list)
		//

		notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en);

		//
		// Kill the keysite if ship is the carrier (N.B. must be done AFTER ships alive flag cleared)
		//

		if (keysite)
		{
			kill_client_server_entity (keysite);
		}
	}

	////////////////////////////////////////
	//
	// SPECIAL EFFECTS
	//
	////////////////////////////////////////

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		create_client_server_object_killed_explosion_effect (en);
	}

	#if LANDING_ROUTE_CHECK

	destroy_debug_entity_landing_route_check (en);

	#endif

	/////////////////////////////////////////////////////////////////
	//
	// SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED
	//
	/////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////
	//
	//
	/////////////////////////////////////////////////////////////////
}
Beispiel #18
0
static void kill_local (entity *en)
{

	anti_aircraft
		*raw;

	int
		losses;

	entity
		*task,
		*destroy_task,
		*group;

	////////////////////////////////////////
	//
	// PRE-AMBLE
	//
	////////////////////////////////////////

	#if DEBUG_MODULE >= 2

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en);

	#endif

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

	raw = (anti_aircraft *) get_local_entity_data (en);

	group = get_local_entity_parent (en, LIST_TYPE_MEMBER);

	ASSERT (group);

	if (tacview_is_logging())
		write_tacview_unit_event(en, TACVIEW_UNIT_DESTROYED, NULL);

	//
	// update force info
	//

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

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

	////////////////////////////////////////
	//
	// DESTROY COMPONENTS
	//
	////////////////////////////////////////

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		////////////////////////////////////////
		//
		// SEND NOTIFY MESSAGES
		//
		////////////////////////////////////////

		//
		//
		//

		task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT);

		while (task)
		{

			destroy_task = task;

			task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT);

			if (get_local_entity_type (destroy_task) == ENTITY_TYPE_TASK)
			{

				#if DEBUG_MODULE

				debug_log ("AA_DSTRY: killing routed vehicle, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]);

				#endif

				notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE);
			}
		}

		//
		// Release landing lock (if any)
		//

		release_mobile_entity_landing_locks (en);
	}

	////////////////////////////////////////
	//
	// UNLINK FROM SYSTEM
	//
	////////////////////////////////////////

	//
	// anti_aircraft
	//

	//
	// vehicle
	//

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	// unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER);

	// gunship_target_link

	// member_link

	// view_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE);

	//
	// mobile
	//

	//
	// kill weapon sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN);

	//unlink_local_entity_children (en, LIST_TYPE_SPECIAL_EFFECT);

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK);

	// sector_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_UPDATE);

	set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DEAD);

	////////////////////////////////////////
	//
	// KILL
	//
	////////////////////////////////////////

	// must be done before alive flag set to FALSE
	remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en);

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

	damage_anti_aircraft_3d_object (en);

	//
	// group losses
	//

	losses = get_local_entity_int_value (group, INT_TYPE_LOSSES);

	losses ++;

	set_local_entity_int_value (group, INT_TYPE_LOSSES, losses);

	//
	// Notify Campaign Screen
	//

	notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group);

	//
	// Notify the GROUP that the mobile has been killed  (N.B. must be done AFTER mobile is unlinked from member list)
	//

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en);
	}

	////////////////////////////////////////
	//
	// SPECIAL EFFECTS
	//
	////////////////////////////////////////

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		create_client_server_object_killed_explosion_effect (en);
	}
}
Beispiel #19
0
int create_group_emergency_transfer_task (entity *en)
{
	entity
		*landing,
		*new_keysite,
		*new_task;

	int
		side,
		landing_type,
		sites_required;

	vec3d
		*pos;

	ASSERT (en);

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	side = get_local_entity_int_value (en, INT_TYPE_SIDE);

	pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

	group_terminate_all_tasks (en);

	sites_required = get_local_group_member_count (en);

	landing_type = group_database [get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE)].default_landing_type;

	landing = get_closest_free_landing_site (landing_type, get_local_force_entity (side), pos, 0.0, NULL, sites_required);

	if (landing)
	{
		//
		// Found new keysite
		//

		new_keysite = get_local_entity_parent (landing, LIST_TYPE_LANDING_SITE);

		if (landing_type == ENTITY_SUB_TYPE_LANDING_HELICOPTER)
		{
			new_task = create_transfer_task (side, ENTITY_SUB_TYPE_TASK_TRANSFER_HELICOPTER, 10.0, new_keysite, new_keysite);
		}
		else
		{
			new_task = create_transfer_task (side, ENTITY_SUB_TYPE_TASK_TRANSFER_FIXED_WING, 10.0, new_keysite, new_keysite);
		}

		ASSERT (new_task);

		if (!assign_primary_task_to_group (en, new_task))
		{
			//
			// Failed to assign transfer task
			//

			ai_log ("(TRANSFER) Failed to assign Emergency Transfer to %s", get_local_entity_string (en, STRING_TYPE_FULL_NAME));

			group_kill_all_members (en);

			return FALSE;
		}
		else
		{
			ai_log ("(TRANSFER) Successfully assigned Emergency Transfer to %s", get_local_entity_string (en, STRING_TYPE_FULL_NAME));

			return TRUE;
		}
	}
	else
	{
		//
		// Failed to find alternate keysite
		//

		ai_log ("(TRANSFER) Failed to find Emergency Transfer keysite for %s", get_local_entity_string (en, STRING_TYPE_FULL_NAME));

		group_kill_all_members (en);

		return FALSE;
	}
}
Beispiel #20
0
entity *regen_update (entity *en)
{

	regen_management_element
		*m1;

	entity_sub_types
		member_type,
		group_type;

	entity
		*wp,
		*task,
		*group,
		*member,
		*building,
		*force_en,
		*landing,
		*keysite;

	unsigned int
		member_number;

	int
		reserve_count;

	force
		*force_raw;

	regen
		*raw;

	regen_list_element
		*e1;

	raw = (regen *) get_local_entity_data (en);

	wp = get_local_entity_parent (en, LIST_TYPE_CURRENT_WAYPOINT);

	task = get_local_entity_parent (wp, LIST_TYPE_WAYPOINT);

	landing = get_local_entity_parent (task, LIST_TYPE_UNASSIGNED_TASK);
			
	keysite = get_local_entity_parent (landing, LIST_TYPE_LANDING_SITE);

	force_en = get_local_force_entity ((entity_sides) raw->side);

	force_raw = (force *) get_local_entity_data (force_en);

	group_type = NUM_ENTITY_SUB_TYPE_GROUPS;

	m1 = &regen_manager [raw->side][raw->sub_type];

	//
	// is there anything in the regen queues?
	//
	
	if (m1->count == 0)
	{
		return NULL;
	}

	//
	// Can regen operate
	//

	building = raw->member_root.first_child;

	if ((!get_local_entity_int_value (building, INT_TYPE_ALIVE)) || (get_local_entity_int_value (keysite, INT_TYPE_KEYSITE_USABLE_STATE) != KEYSITE_STATE_USABLE))
	{
		#if DEBUG_MODULE

		debug_log ("RG_UPDT: keysite %s too damaged to regen", get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME));

		#endif

		return NULL;
	}

	e1 = &regen_queue [raw->side][raw->sub_type][m1->front];

	ASSERT (e1->type != -1);
	ASSERT (e1->sub_type != -1);
	ASSERT (e1->group != -1);

	// is there a reserve of this type?
	if ((e1->type == ENTITY_TYPE_FIXED_WING) || (e1->type == ENTITY_TYPE_HELICOPTER))
	{
		reserve_count = force_raw->force_info_reserve_hardware[aircraft_database[e1->sub_type].force_info_catagory];
	}
	else
	{
		reserve_count = force_raw->force_info_reserve_hardware[vehicle_database[e1->sub_type].force_info_catagory];
	}

	if (reserve_count <= 0)
	{
		return NULL;
	}

	#if DEBUG_MODULE

	debug_log ("RG_UPDT: Trying to Regen %s Sub Type %d at %s - reserve count %d",
								get_entity_type_name (e1->type), e1->sub_type,
								get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), reserve_count);

	#endif

	//
	// Don't regen if PLAYER landed there
	//

	group = get_local_entity_first_child (keysite, LIST_TYPE_KEYSITE_GROUP);

	while (group)
	{
		member = get_local_entity_first_child (group, LIST_TYPE_MEMBER);

		while (member)
		{

			if (get_local_entity_int_value (member, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
			{

				if (get_local_entity_int_value (member, INT_TYPE_LANDED))
				{
					#if DEBUG_MODULE

					debug_log ("RG_UPDT: PLAYER landed at keysite %s, can't regen", get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME));

					#endif

					return NULL;
				}
			}

			member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER);
		}

		group = get_local_entity_child_succ (group, LIST_TYPE_KEYSITE_GROUP);
	}

	group_type = e1->group;
	
	member_type = e1->sub_type;

	////////////////////////////////////////////////////////////////////////////
	// Dont regen people or transport aircraft in apache havoc campaign as airport might not be correct (landing routes etc)
	////////////////////////////////////////////////////////////////////////////
	if (get_local_entity_int_value (get_session_entity (), INT_TYPE_CAMPAIGN_REQUIRES_APACHE_HAVOC))
	{

		switch (get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE))
		{

			case ENTITY_SUB_TYPE_REGEN_PEOPLE:
			{

				#if DEBUG_MODULE

				debug_log ("RG_UPDT: Stopping Regening People - wrong warzone");

				#endif

				return NULL;
			}

			case ENTITY_SUB_TYPE_REGEN_FIXED_WING:
			{

				if (group_database [group_type].default_landing_type == ENTITY_SUB_TYPE_LANDING_FIXED_WING_TRANSPORT)
				{

					#if DEBUG_MODULE

					debug_log ("RG_UPDT: Stopping Regening Transport aircraft - wrong warzone");

					#endif

					return NULL;
				}
			}
		}
	}
	////////////////////////////////////////////////////////////////////////////
	// Dont regen people or transport aircraft in apache havoc campaign as airport might not be correct (landing routes etc)
	////////////////////////////////////////////////////////////////////////////

	if (group_type != NUM_ENTITY_SUB_TYPE_GROUPS)
	{

		int
			route_node;

		entity
			*building,
			*member,
			*guide,
			*group = NULL;

		group = create_landing_faction_members (keysite, member_type, group_type, 1, wp, &raw->position);

		if (group)
		{

			//
			// Assign closest route_node (only needed for routed vehicles)
			//

			if (get_local_entity_int_value (group, INT_TYPE_FRONTLINE))
			{
	
				route_node = get_closest_side_road_node ((entity_sides) get_local_entity_int_value (group, INT_TYPE_SIDE), &raw->position, 5 * KILOMETRE);
	
				set_client_server_entity_int_value (group, INT_TYPE_ROUTE_NODE, route_node);
			}

			//
			//
			//
			
			member = get_local_entity_first_child (group, LIST_TYPE_MEMBER);

			//
			// close members doors
			//

			close_client_server_entity_cargo_doors (member);

			close_client_server_entity_loading_doors (member);

			//
			// open building doors
			//

			building = get_local_entity_first_child (en, LIST_TYPE_MEMBER);

			open_client_server_entity_loading_doors (building);

			set_local_entity_float_value (building, FLOAT_TYPE_LOADING_DOOR_TIMER, 30.0);

			//
			// create guide entity for task (TEST)
			//

			// Debug for Transport aircraft.
			// Locate nearest Transport landing wp and insert into it
			if (group_database [group_type].default_landing_type == ENTITY_SUB_TYPE_LANDING_FIXED_WING_TRANSPORT)
			{

				float
					range,
					best_range;

				entity
					*transport_wp,
					*transport_task,
					*transport_landing;

				best_range = 999999999.0;

				transport_landing = get_local_entity_landing_entity (keysite, ENTITY_SUB_TYPE_LANDING_FIXED_WING_TRANSPORT);

				if (transport_landing)
				{
	
					transport_task = get_local_landing_entity_task (transport_landing, ENTITY_SUB_TYPE_TASK_LANDING);

					ASSERT (transport_task);
	
					transport_wp = get_local_entity_first_child (transport_task, LIST_TYPE_WAYPOINT);

					ASSERT (transport_wp);
	
					while (transport_wp)
					{
	
						range = get_sqr_2d_range (get_local_entity_vec3d_ptr (transport_wp, VEC3D_TYPE_POSITION), get_local_entity_vec3d_ptr (building, VEC3D_TYPE_POSITION));
	
						if (range < best_range)
						{
	
							wp = transport_wp;
	
							task = transport_task;
	
							best_range = range;
						}
	
						transport_wp = get_local_entity_child_succ (transport_wp, LIST_TYPE_WAYPOINT);
					}
				}
			}
			// Debug for Transport aircraft.

			member_number = get_local_entity_int_value (member, INT_TYPE_GROUP_MEMBER_NUMBER);

			guide = create_client_server_guide_entity (task, wp, (1 << member_number));

			attach_group_to_guide_entity (group, guide);

			attach_group_member_to_guide_entity (member, guide);

			//#if DEBUG_MODULE
			{

				entity
					*keysite;

				keysite = get_local_entity_parent (landing, LIST_TYPE_LANDING_SITE);

				member = get_local_entity_first_child (group, LIST_TYPE_MEMBER);

				debug_log ("RG_UPDT: %s creating %s (%d) at keysite %s free landing sites %d, reserved %d, lock %d, available lock: %d",
						entity_side_names [get_local_entity_int_value (keysite, INT_TYPE_SIDE)],
						get_local_entity_type_name (member),
						get_local_entity_index (member),
						get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), 
						get_local_entity_int_value (landing, INT_TYPE_FREE_LANDING_SITES),
						get_local_entity_int_value (landing, INT_TYPE_RESERVED_LANDING_SITES),
						get_local_entity_int_value (landing, INT_TYPE_LANDING_LOCK),
						check_available_landing_route_lock (landing)
						);

				if ((e1->type == ENTITY_TYPE_FIXED_WING) || (e1->type == ENTITY_TYPE_HELICOPTER))
				{
					debug_log("%s reserves left: %d",
							force_info_catagory_names[aircraft_database[e1->sub_type].force_info_catagory],
							force_raw->force_info_reserve_hardware[aircraft_database[e1->sub_type].force_info_catagory]
							);
				}
				else
				{
					debug_log("%s reserves left: %d",
							force_info_catagory_names[vehicle_database[e1->sub_type].force_info_catagory],
							force_raw->force_info_reserve_hardware[vehicle_database[e1->sub_type].force_info_catagory]
							);
				}

			}
			//#endif

			#if DEBUG_MODULE
			switch (e1->type)
			{
				case ENTITY_TYPE_FIXED_WING:
				case ENTITY_TYPE_HELICOPTER:
				{
					ASSERT (regen_ac_debug[e1->sub_type] > 0);

					break;
				}
				
				case ENTITY_TYPE_ROUTED_VEHICLE:
				case ENTITY_TYPE_SHIP_VEHICLE:
				case ENTITY_TYPE_PERSON:
				{
					ASSERT (regen_vh_debug[e1->sub_type] > 0);

					break;
				}
				
				default:
				{
					debug_fatal ("RG_UPDT: Unknown entity type for debug");
				}
				
			}
			#endif

			// update markers
			regen_queue_use ((entity_sides) raw->side, (raw->sub_type));

			return member;
		}
	}
	else
	{
		#if DEBUG_MODULE >= 2

		debug_log ("RG_UPDT: not creating anything at keysite %s free landing sites %d, reserved %d, lock %d",
						get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), 
						get_local_entity_int_value (landing, INT_TYPE_FREE_LANDING_SITES),
						get_local_entity_int_value (landing, INT_TYPE_RESERVED_LANDING_SITES),
						check_available_landing_route_lock (landing));

		#endif
	}

	return NULL;
}