Esempio n. 1
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;
}
Esempio n. 2
0
void create_force_campaign_objectives (entity *force)
{
	entity
		*keysite,
		*target_force,
		**list;

	int
		loop,
		count,
		side,
		target_side;

	float
		highest,
		*rating;

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	ASSERT (get_session_entity ());

	ASSERT (force);

	side = get_local_entity_int_value (force, INT_TYPE_SIDE);

	//
	// count up potential objective keysites
	//

	count = 0;

	target_force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE);

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

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

				keysite = get_local_entity_child_succ (keysite, LIST_TYPE_KEYSITE_FORCE);
			}
		}

		target_force = get_local_entity_child_succ (target_force, LIST_TYPE_FORCE);
	}

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

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

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

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

	highest = 0.0;

	count = 0;

	target_force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE);

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

			keysite = get_local_entity_first_child (target_force, LIST_TYPE_KEYSITE_FORCE);

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

				keysite = get_local_entity_child_succ (keysite, LIST_TYPE_KEYSITE_FORCE);
			}
		}

		target_force = get_local_entity_child_succ (target_force, LIST_TYPE_FORCE);
	}

	//
	// Normalise ratings
	//

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

	//
	// obligatory random factor
	//

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

	//
	// sort the list
	//

	quicksort_entity_list (list, count, rating);

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

	count = min (count, NUMBER_OF_CAMPAIGN_OBJECTIVES_PER_SIDE);

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

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

	free_mem (list);

	free_mem (rating);
}
Esempio n. 3
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
			}
		}
	}
}