Example #1
0
int group_task_specific_retaliation_checks (entity *group, entity *aggressor, int assisted)
{
	entity
		*task,
		*objective;

	task_roe_types
		roe;

	entity_sides
		side;

	vec3d
		*group_pos,
		*objective_pos,
		*aggressor_pos;

	int
		sx,
		sz;

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	ASSERT (group);

	ASSERT (aggressor);

	if (get_local_entity_int_value (group, INT_TYPE_AIRCRAFT_GROUP))
	{
		task = get_local_group_primary_task (group);

		if (!task)
		{
			return FALSE;
		}

		if (get_local_entity_int_value (aggressor, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
		{
			return TRUE;
		}

		roe = get_local_entity_int_value (task, INT_TYPE_RULES_OF_ENGAGEMENT);

		switch (roe)
		{
			case TASK_ROE_NONE:
			{
				//
				// FALSE if aggressor is within target area (stop RECON missions from destroying objectives)
				//

				if (get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE) == ENTITY_SUB_TYPE_TASK_RECON)
				{
					objective = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT);

					if (objective)
					{
						objective_pos = get_local_entity_vec3d_ptr (objective, VEC3D_TYPE_POSITION);
	
						ASSERT (objective_pos);
	
						aggressor_pos = get_local_entity_vec3d_ptr (aggressor, VEC3D_TYPE_POSITION);
	
						ASSERT (aggressor_pos);
	
						if (get_sqr_2d_range (aggressor_pos, objective_pos) < ((2.0 * KILOMETRE) * (2.0 * KILOMETRE)))
						{
							ai_log ("(RETALIATE CHECK) ROE NONE - Failed (Aggressor at target area)");
	
							return FALSE;
						}
					}
				}

				//
				// Retaliate if no-one else coming to assist, AND (mission complete OR aggressor in friendly territory)
				//

				if (!assisted)
				{
					if (get_local_entity_int_value (task, INT_TYPE_TASK_COMPLETED) != TASK_INCOMPLETE)
					{
						ai_log ("(RETALIATE CHECK) ROE NONE - Task Complete");

						return TRUE;
					}

					side = get_local_entity_int_value (group, INT_TYPE_SIDE);

					group_pos = get_local_entity_vec3d_ptr (group, VEC3D_TYPE_POSITION);

					ASSERT (group_pos);

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

					if (get_local_sector_side_ratio (sx, sz, side) > 0.5)
					{
						ai_log ("(RETALIATE CHECK) ROE NONE - Friendly Territory");

						return TRUE;
					}
				}

				ai_log ("(RETALIATE CHECK) ROE NONE - Failed Checks");

				break;
			}
			case TASK_ROE_OBJECTIVE:
			{
				//
				// Retaliate if no-one else coming to assist, OR primary task completed
				//

				if (!assisted)
				{
					ai_log ("(RETALIATE CHECK) ROE OBJECTIVE - No Assistance");

					return TRUE;
				}

				if (get_local_entity_int_value (task, INT_TYPE_TASK_COMPLETED) != TASK_INCOMPLETE)
				{
					ai_log ("(RETALIATE CHECK) ROE OBJECTIVE - Task Complete");

					return TRUE;
				}

				ai_log ("(RETALIATE CHECK) ROE OBJECTIVE - Failed Checks");

				break;
			}
			case TASK_ROE_ALL:
			{
				//
				// Always retaliate
				//

				ai_log ("(RETALIATE CHECK) ROE ALL");

				return TRUE;
			}
		}

		return FALSE;
	}
	else
	{
		return TRUE;
	}
}
Example #2
0
void assign_keysite_tasks (entity *keysite, task_category_types category)
{
	entity
		*task,
		*group,
		*force,
		**task_list;

	float
		*sort_order;

	int
		loop,
		task_type,
		task_count,
		assign_count,
		group_type,
		keysite_type,
		non_critical_task_count;

	static int
		idle_group_count [NUM_ENTITY_SUB_TYPE_GROUPS];

	ASSERT (keysite);

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	task = get_local_entity_first_child (keysite, LIST_TYPE_UNASSIGNED_TASK);

	if (!task)
	{
		return;
	}

	keysite_type = get_local_entity_int_value (keysite, INT_TYPE_ENTITY_SUB_TYPE);

	force = get_local_entity_parent (keysite, LIST_TYPE_KEYSITE_FORCE);

	ASSERT (force);

	//
	// Count tasks at keysite
	//

	task_count = 0;
	
	task = get_local_entity_first_child (keysite, LIST_TYPE_UNASSIGNED_TASK);

	while (task)
	{
		if (get_local_entity_int_value (task, INT_TYPE_TASK_CATEGORY) == category)
		{
			task_count ++;
		}

		task = get_local_entity_child_succ (task, LIST_TYPE_UNASSIGNED_TASK);
	}

	if (task_count == 0)
	{
		return;
	}

	//
	// Count up number of idle groups across the map (air registry only)
	//

	memset (idle_group_count, 0, sizeof (int) * NUM_ENTITY_SUB_TYPE_GROUPS);

	group = get_local_entity_first_child (force, LIST_TYPE_AIR_REGISTRY);

	while (group)
	{
		if (get_local_entity_int_value (group, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE)
		{
			group_type = get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE);

			idle_group_count [group_type] ++;
		}

		group = get_local_entity_child_succ (group, LIST_TYPE_AIR_REGISTRY);
	}

	//
	// Sort tasks
	//

	ASSERT (task_count > 0);
	
	task_list = ( entity * * ) malloc_fast_mem (sizeof (entity *) * task_count);

	sort_order = ( float * ) malloc_fast_mem (sizeof (float) * task_count);

	task_count = 0;

	task = get_local_entity_first_child (keysite, LIST_TYPE_UNASSIGNED_TASK);

	while (task)
	{
		if (get_local_entity_int_value (task, INT_TYPE_TASK_CATEGORY) == category)
		{
			task_list [task_count] = task;
	
			sort_order [task_count] = get_local_entity_float_value (task, FLOAT_TYPE_TASK_PRIORITY);
	
			if (get_local_entity_int_value (task, INT_TYPE_CRITICAL_TASK))
			{
				sort_order [task_count] *= 2.0;
			}
	
			task_count ++;
		}
			
		task = get_local_entity_child_succ (task, LIST_TYPE_UNASSIGNED_TASK);
	}

	quicksort_entity_list (task_list, task_count, sort_order);

	//
	// Assign tasks
	//

	assign_count = max (keysite_database [keysite_type].assign_task_count, 1u);

	non_critical_task_count = keysite_database [keysite_type].reserve_task_count;

	for (loop = 0; loop < task_count; loop ++)
	{
		if (assign_count == 0)
		{				
			break;
		}

		task = task_list [loop]; 

		//
		// Check for player lock
		//

		if (get_local_entity_parent (task, LIST_TYPE_PILOT_LOCK))
		{
			continue;
		}

		//
		// Reserve non-critical tasks for player
		//

		if (!get_local_entity_int_value (task, INT_TYPE_CRITICAL_TASK))
		{
			if (get_local_entity_float_value (task, FLOAT_TYPE_EXPIRE_TIMER) > KEYSITE_TASK_ASSIGN_TIMER)
			{
				if (non_critical_task_count > 0)
				{
					non_critical_task_count --;
	
					continue;
				}
			}
		}

		task_type = get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE);

		group = get_suitable_registered_group (task, idle_group_count);
	
		if (group)
		{
			if (assign_primary_task_to_group (group, task))
			{
	
				ai_log ("ASSIGN: (%d/%d) Assigned group %s (%d) to task %s (%d) from keysite %s (%s)",
								assign_count, keysite_database [keysite_type].assign_task_count,
								entity_sub_type_group_names [get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)],
								get_local_entity_index (group),
								entity_sub_type_task_names [task_type],
								get_local_entity_index (task),
								get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME),
								entity_side_short_names [get_local_entity_int_value (keysite, INT_TYPE_SIDE)]);
	
				//
				// Only Assign n tasks per keysite
				//

				assign_count --;
			}
			else
			{
				#if DEBUG_MODULE
	
				debug_log ("ASSIGN: not assigning group %s (%d) to task %s (%d) from keysite %s",
								entity_sub_type_group_names [get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)],
								get_local_entity_index (group),
								entity_sub_type_task_names [task_type],
								get_local_entity_index (task),
								get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME));
	
				#endif
			}
		}
	}

	free_mem (task_list);

	free_mem (sort_order);
}
Example #3
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;
	}
}
Example #4
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;
}