Beispiel #1
0
int create_downwash_effect(downwash_types type, vec3d *position, float main_rotor_radius, float main_rotor_rpm, float min_altitude)
{
	int	
		loop,
		count,
		num_components,
		comp,
		index_counter,
		*entity_index_list;

	downwash_component
		*this_downwash_component;

	ASSERT (type >= 0);

	ASSERT (type < NUM_DOWNWASH_TYPES);

	ASSERT (type != DOWNWASH_TYPE_NONE);

	//
	// create an array of entity index numbers and fill them all with ENTITY_INDEX_DONT_CARE
	//

	count = count_entities_in_downwash (type);

	ASSERT (count);

	entity_index_list = (int *) malloc_fast_mem (sizeof (int) * count);

	//Xhit replaced ENTITY_INDEX_DONT_CARE with ENTITY_INDEX_CREATE_LOCAL (030428)
	//This and the changes made to the entity heap and some smoke functions
	//clears the MP-bug caused by that local entities were not allowed to be created on a client
	for ( loop = 0 ; loop < count ; loop ++ )
	{
		entity_index_list [loop] = ENTITY_INDEX_CREATE_LOCAL;
	}

	index_counter = 0;

	num_components = downwash_database[ type ].number_of_components;

	for ( comp = 0 ; comp < num_components ; comp ++ )
	{

		this_downwash_component = &(downwash_database[ type ].component[ comp ]);
		index_counter += create_downwash_effect_component( this_downwash_component, type, position, &entity_index_list[ index_counter ], main_rotor_radius, main_rotor_rpm, min_altitude);	

	}
	
	free_mem (entity_index_list);

	return 0;
}
Beispiel #2
0
void parse_filename (char *text, int max_length)
{
	char
		*kb,
		*pm,
		*parsed_text;

	int
		length;

	ASSERT (text);

	ASSERT (max_length > 0);

	parsed_text = malloc_fast_mem (strlen (text) + 1);

	pm = parsed_text;

	kb = text;

	length = 0;

	while ((*kb) && (length < max_length))
	{
		if (valid_filename_symbol (*kb))
		{
			*pm = *kb;

			pm ++;

			length ++;
		}

		kb ++;
	}

	//
	// terminate new string
	//

	*pm = '\0';

	//
	// copy text back to original location
	//

	strcpy (text, parsed_text);
}
Beispiel #3
0
int add_message_to_campaign_log (int index)
{
	int
		hours,
		minutes,
		seconds;

	char
		*s;

	message_log_type
		*message;

	rgb_colour
		*col = NULL;

	message = get_message_log (index);

	ASSERT (message);

	if (message->type == MESSAGE_TEXT_PILOT_STRING)
	{
		get_digital_clock_int_values (message->time_of_day, &hours, &minutes, &seconds);
	
		s = (char *) malloc_fast_mem (strlen (message->string) + 20);
	
		sprintf (s, "[%02d:%02d] %s", hours, minutes, message->string);
	
		col = &(message->colour);
	
		ASSERT (col);
	
		add_to_pop_up_list (s, chat_message_list, NULL, index, -1, *col);
	
		free_mem (s);
	
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
Beispiel #4
0
static entity *create_local (entity_types type, int index, char *pargs)
{
	entity
		*en;

	sound_effect
		*raw;

	////////////////////////////////////////
  	//
  	// 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 = (sound_effect *) malloc_fast_mem (sizeof (sound_effect));

		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 (sound_effect));

		raw->effect_index = (sound_sample_indices*) SOUND_SAMPLE_INDEX_NONE;

		raw->amplification = 1.0;

		raw->pitch = 1.0; //Werewolf sound pitch mod

		raw->sound_channel = SOUND_CHANNEL_SOUND_EFFECT;

		//
		// effect
		//

		raw->eff.position.x = MID_MAP_X;
		raw->eff.position.y = MID_MAP_Y;
		raw->eff.position.z = MID_MAP_Z;

		////////////////////////////////////////
		//
		// OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES
		//
		////////////////////////////////////////

		set_local_entity_attributes (en, pargs);

		////////////////////////////////////////
		//
		// CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN
		//
		////////////////////////////////////////

		ASSERT (entity_sub_type_effect_valid (raw->eff.sub_type));

		ASSERT (raw->effect_index == (sound_sample_indices*) SOUND_SAMPLE_INDEX_NONE);			// samples haven't been specified at this point

		ASSERT (raw->eff.special_effect_link.parent);

		////////////////////////////////////////
		//
		// RESOLVE DEFAULT VALUES
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// BUILD COMPONENTS
		//
		////////////////////////////////////////
/*
		if (!raw->looping)
		{
			float
				rate,
				size;
				
			rate = (float)(application_sound_effects [raw->effect_index].rate);
			size = (float)(application_sound_effects [raw->effect_index].size);

			if (rate <= 0.0)
			{
				debug_log ("SE_CREAT : Sound effect rate invalid ( index = %s, rate = %d )", application_sound_effects [raw->effect_index].name, rate);
			}

			raw->effect_lifetime = size / rate;
		}
*/
		#if DEBUG_MODULE

		debug_log ("SE_CREAT : Created Sound effect %d (parent (%d), lifetime = %f (%d))",
							get_local_entity_safe_index (en),
							get_local_entity_safe_index (raw->eff.special_effect_link.parent),
							raw->effect_lifetime, raw->valid_sound_effect);

		#endif
	
		////////////////////////////////////////
		//
		// LINK INTO SYSTEM
		//
		////////////////////////////////////////

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_SPECIAL_EFFECT, raw->eff.special_effect_link.parent, NULL);

		if (raw->valid_sound_effect)
		{
			insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity(), raw->eff.update_link.child_pred);
		}
	}

	return (en);
}
Beispiel #5
0
static entity *create_local (entity_types type, int index, char *pargs)
{

	entity
		*en;

	guide
		*raw;

	////////////////////////////////////////
  	//
  	// 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 = (guide *) malloc_fast_mem (sizeof (guide));

		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 (guide));

		raw->sub_type = ENTITY_SUB_TYPE_GUIDE_NAVIGATION_DIRECT;

		////////////////////////////////////////
		//
		// OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES
		//
		////////////////////////////////////////

		set_local_entity_attributes (en, pargs);

		////////////////////////////////////////
		//
		// CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN
		//
		////////////////////////////////////////

		ASSERT (raw->guide_link.parent);

		ASSERT (raw->current_waypoint_link.parent);

		////////////////////////////////////////
		//
		// RESOLVE DEFAULT VALUES
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// LINK INTO SYSTEM
		//
		////////////////////////////////////////

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_GUIDE, raw->guide_link.parent, NULL);

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_CURRENT_WAYPOINT, raw->current_waypoint_link.parent, NULL);

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL);
	}

	return (en);
}
Beispiel #6
0
static entity *create_local (entity_types type, int index, char *pargs)
{
	entity
		*en;

	cargo
		*raw;

	////////////////////////////////////////
  	//
  	// 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 = (cargo *) malloc_fast_mem (sizeof (cargo));

		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 (cargo));

		//
		// mobile
		//

		raw->mob.sub_type = ENTITY_SUB_TYPE_UNINITIALISED;

		raw->mob.position.x = MID_MAP_X;
		raw->mob.position.y = MID_MAP_Y;
		raw->mob.position.z = MID_MAP_Z;

		get_identity_matrix3x3 (raw->mob.attitude);

		raw->mob.alive = TRUE;

		raw->mob.side = ENTITY_SIDE_UNINITIALISED;

		//
		// cargo
		//

		////////////////////////////////////////
		//
		// OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES
		//
		////////////////////////////////////////

		set_local_entity_attributes (en, pargs);

		////////////////////////////////////////
		//
		// CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// RESOLVE DEFAULT VALUES
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// BUILD COMPONENTS
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// LINK INTO SYSTEM
		//
		////////////////////////////////////////

		if (raw->cargo_link.parent)
		{

			insert_local_entity_into_parents_child_list (en, LIST_TYPE_CARGO, raw->cargo_link.parent, NULL);
		}

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->mob.position), NULL);

		//insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL);
	}

	return (en);
}
Beispiel #7
0
static entity *create_local (entity_types type, int index, char *pargs)
{

	entity
		*en;

	waypoint
		*raw;

	vec3d
		v;

	////////////////////////////////////////
  	//
  	// 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 (waypoint));

		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 (waypoint));

		raw->position.x = MID_MAP_X;
		raw->position.z = MID_MAP_Z;
		raw->position.y = MID_MAP_Y;

		raw->sub_type = ENTITY_SUB_TYPE_WAYPOINT_NAVIGATION;

		raw->waypoint_formation = FORMATION_ROW_LEFT;

		raw->position_type = POSITION_TYPE_ABSOLUTE;

		raw->heading = 0.0;

		////////////////////////////////////////
		//
		// OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES
		//
		////////////////////////////////////////

		set_local_entity_attributes (en, pargs);

		////////////////////////////////////////
		//
		// CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN
		//
		////////////////////////////////////////

		ASSERT (raw->waypoint_link.parent);

		get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &v);

		ASSERT (point_inside_map_volume (&v));

		////////////////////////////////////////
		//
		// RESOLVE DEFAULT VALUES
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// LINK INTO SYSTEM
		//
		////////////////////////////////////////

		if (raw->task_dependent_link.parent)
		{

			insert_local_entity_into_parents_child_list (en, LIST_TYPE_TASK_DEPENDENT, raw->task_dependent_link.parent, NULL);
		}

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_WAYPOINT, raw->waypoint_link.parent, raw->waypoint_link.child_pred);

		#if DEBUG_MODULE

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->position), NULL);

		#endif
	}

	return (en);
}
Beispiel #8
0
void set_local_sound_effect_sample_indices (entity *en, int count, sound_sample_indices *indices)
{
	sound_effect
		*raw;

	int
		loop;

	ASSERT (en);

	ASSERT (count > 0);

	ASSERT (indices);

	raw = get_local_entity_data (en);

	ASSERT (!raw->effect_index);

	//
	// copy sample indices
	//

	raw->sound_effect_sequence_count = count;

	raw->effect_index = malloc_fast_mem (sizeof (sound_sample_indices) * count);	
	
	memcpy (raw->effect_index, indices, sizeof (sound_sample_indices) * count);

	//
	// determine playing time
	//

	raw->effect_lifetime = 0;

	if (!raw->looping)
	{
		float
			rate,
			size;

		for (loop = 0; loop < count; loop ++)
		{
			ASSERT (indices [loop] != SOUND_SAMPLE_INDEX_NONE);

			rate = (float)(application_sound_effects [indices [loop]].rate);
			size = (float)(application_sound_effects [indices [loop]].size);

			if (rate <= 0.0)
			{
				debug_log ("SOUNDEFF : Sound effect rate invalid ( index = %s, rate = %d )", application_sound_effects [indices [loop]].name, rate);
			}
			else
			{
				raw->effect_lifetime += (size / rate);
			}
		}

		ASSERT (raw->effect_lifetime < 40.0);

		raw->effect_lifetime = min (raw->effect_lifetime, 40.0);
	}
}
Beispiel #9
0
static entity *create_local (entity_types type, int index, char *pargs)
{
	entity
		*en;

	scenic
		*raw;

	////////////////////////////////////////
  	//
  	// 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 (scenic));

		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 (scenic));

		//
		// fixed
		//

		raw->fix.position.x = MID_MAP_X;
		raw->fix.position.y = MID_MAP_Y;
		raw->fix.position.z = MID_MAP_Z;

		raw->fix.sub_type = ENTITY_SUB_TYPE_FIXED_UNKNOWN;

		raw->fix.object_3d_shape = OBJECT_3D_INVALID_OBJECT_INDEX;

		raw->fix.alive = TRUE;

		raw->fix.side = ENTITY_SIDE_NEUTRAL;

		//
		// scenic
		//

		if (fixed_3d_object_database[raw->fix.object_3d_shape].valid_entry)
		{
			raw->damage_level = fixed_3d_object_database[raw->fix.object_3d_shape].initial_damage;
		}
		else
		{
			raw->damage_level = 500;
		}

		////////////////////////////////////////
		//
		// OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES
		//
		////////////////////////////////////////

		set_local_entity_attributes (en, pargs);

		////////////////////////////////////////
		//
		// CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// RESOLVE DEFAULT VALUES
		//
		////////////////////////////////////////

		if (raw->fix.object_3d_shape == OBJECT_3D_INVALID_OBJECT_INDEX)
		{
			raw->fix.object_3d_shape = fixed_database[raw->fix.sub_type].default_3d_shape;
		}

		////////////////////////////////////////
		//
		// BUILD COMPONENTS
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// LINK INTO SYSTEM
		//
		////////////////////////////////////////

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->fix.position), NULL);
	}

	return (en);
}
Beispiel #10
0
static entity *create_local (entity_types type, int index, char *pargs)
{
	entity
		*en;

	camera
		*raw;

	////////////////////////////////////////
  	//
  	// 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);

	ASSERT (!get_camera_entity ());

	if (en)
	{
		////////////////////////////////////////
   	//
   	// MALLOC ENTITY DATA
   	//
		////////////////////////////////////////

		set_local_entity_type (en, type);

		raw = (camera *) malloc_fast_mem (sizeof (camera));

		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 (camera));

		raw->position.x = MID_MAP_X;
		raw->position.y = MID_MAP_Y;
		raw->position.z = MID_MAP_Z;

		raw->offset.x = 0;
		raw->offset.y = 0;
		raw->offset.z = 0;

		raw->offset_movement.x = 0;
		raw->offset_movement.y = 0;
		raw->offset_movement.z = 0;

	
		raw->turbulence_offset.x = 0.0;
		raw->turbulence_offset.y = 0.0;
		raw->turbulence_offset.z = 0.0;
	
		raw->turbulence_movement.x = 0.0;
		raw->turbulence_movement.y = 0.0;
		raw->turbulence_movement.z = 0.0;
	
		get_identity_matrix3x3 (raw->attitude);

		raw->camera_mode = CAMERA_MODE_CHASE;

		raw->chase_camera_lock_rotate = TRUE;

		reset_chase_camera_position (raw);

		reset_cinematic_camera_for_new_view_entity (raw);

		////////////////////////////////////////
		//
		// OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES
		//
		////////////////////////////////////////

		set_local_entity_attributes (en, pargs);

		////////////////////////////////////////
		//
		// CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// RESOLVE DEFAULT VALUES
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// LINK INTO SYSTEM
		//
		////////////////////////////////////////

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL);

		set_camera_entity (en);
	}

	return (en);
}
Beispiel #11
0
void unpack_vehicle_data (entity *en, vehicle *raw, pack_modes mode)
{
	int
		package;

	ASSERT ((mode >= 0) && (mode < NUM_PACK_MODES));

	switch (mode)
	{
		////////////////////////////////////////
		case PACK_MODE_SERVER_SESSION:
		case PACK_MODE_CLIENT_SESSION:
		////////////////////////////////////////
		{
			//
			// unpack mobile data
			//

			unpack_mobile_data (en, &raw->mob, mode);

			//
			// unpack vehicle data
			//

			raw->object_3d_shape = unpack_int_value (en, INT_TYPE_OBJECT_3D_SHAPE);

			raw->inst3d = construct_3d_object (raw->object_3d_shape);

			if (mode == PACK_MODE_SERVER_SESSION)
			{

				/////////////////////////////////////////////////////////////////
				if (unpack_int_value (en, INT_TYPE_VALID))
				{

					unpack_list_root (en, LIST_TYPE_TASK_DEPENDENT, &raw->task_dependent_root);
				}
				/////////////////////////////////////////////////////////////////
			}

			/////////////////////////////////////////////////////////////////
			if (unpack_int_value (en, INT_TYPE_VALID))
			{

				unpack_list_root (en, LIST_TYPE_LAUNCHED_WEAPON, &raw->launched_weapon_root);
			}
			/////////////////////////////////////////////////////////////////

			/////////////////////////////////////////////////////////////////
			if (unpack_int_value (en, INT_TYPE_VALID))
			{

				unpack_list_root (en, LIST_TYPE_MOVEMENT_DEPENDENT, &raw->movement_dependent_root);
			}
			/////////////////////////////////////////////////////////////////

			unpack_list_link (en, LIST_TYPE_FOLLOWER, &raw->follower_link);

			// gunship_target_link

			unpack_list_link (en, LIST_TYPE_MEMBER, &raw->member_link);

			/////////////////////////////////////////////////////////////////
			if (unpack_int_value (en, INT_TYPE_VALID))
			{

				unpack_list_link (en, LIST_TYPE_MOVEMENT_DEPENDENT, &raw->movement_dependent_link);
			}
			/////////////////////////////////////////////////////////////////

			// view_link

			if (mode == PACK_MODE_SERVER_SESSION)
			{
				unpack_list_link (en, LIST_TYPE_TAKEOFF_QUEUE, &raw->takeoff_queue_link);
			}

			raw->operational_state = unpack_int_value (en, INT_TYPE_OPERATIONAL_STATE);

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

			if (mode == PACK_MODE_SERVER_SESSION)
			{
				raw->distance = unpack_float_value (en, FLOAT_TYPE_DISTANCE);	// only needed by server?
			}

			/////////////////////////////////////////////////////////////////
			if (raw->operational_state == OPERATIONAL_STATE_LANDED)
			{

				raw->loading_door_state = unpack_float_value (en, FLOAT_TYPE_LOADING_DOOR_STATE);
			}
			/////////////////////////////////////////////////////////////////

			// radar_rotation_state

			if (mode == PACK_MODE_SERVER_SESSION)
			{
				raw->death_timer = unpack_float_value (en, FLOAT_TYPE_DEATH_TIMER);

				raw->target_fire_timer = unpack_float_value (en, FLOAT_TYPE_TARGET_FIRE_TIMER);

				raw->target_scan_timer = unpack_float_value (en, FLOAT_TYPE_TARGET_SCAN_TIMER);
			}

			// view_interest_level

			// weapon_burst_timer

			raw->weapon_system_ready_state = unpack_float_value (en, FLOAT_TYPE_WEAPON_SYSTEM_READY_STATE);

			if (mode == PACK_MODE_SERVER_SESSION)
			{
				raw->decoy_release_timer = unpack_float_value (en, FLOAT_TYPE_DECOY_RELEASE_TIMER);
			}

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

			raw->weapon_config_type = (weapon_config_types) unpack_int_value (en, INT_TYPE_WEAPON_CONFIG_TYPE);

			raw->weapon_package_status_array = (weapon_package_status *) malloc_fast_mem (SIZE_WEAPON_PACKAGE_STATUS_ARRAY);

			memset (raw->weapon_package_status_array, 0, SIZE_WEAPON_PACKAGE_STATUS_ARRAY);

			for (package = 0; package < NUM_WEAPON_PACKAGES; package++)
			{
				if (weapon_config_database[raw->weapon_config_type][package].sub_type == ENTITY_SUB_TYPE_WEAPON_NO_WEAPON)
				{
					break;
				}

				raw->weapon_package_status_array[package].number = unpack_int_value (en, INT_TYPE_WEAPON_PACKAGE_NUMBER);

				raw->weapon_package_status_array[package].damaged = unpack_int_value (en, INT_TYPE_WEAPON_PACKAGE_DAMAGED);

				if (weapon_config_database[raw->weapon_config_type][package].rotate)
				{
					raw->weapon_package_status_array[package].weapon_system_heading = unpack_float_value (en, FLOAT_TYPE_WEAPON_SYSTEM_HEADING);

					raw->weapon_package_status_array[package].weapon_system_pitch = unpack_float_value (en, FLOAT_TYPE_WEAPON_SYSTEM_PITCH);
				}

				// muzzle_flash_timer
			}

			reset_entity_weapon_config_animation (en);

			raw->selected_weapon = unpack_int_value (en, INT_TYPE_SELECTED_WEAPON);

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

			// sound_effect_data

			raw->formation_position = unpack_int_value (en, INT_TYPE_FORMATION_POSITION);

			// selected_weapon_system_ready

			// weapon_and_target_vectors_valid

			// gunship_radar_los_clear

			// los_to_target

			raw->lights_on = unpack_int_value (en, INT_TYPE_LIGHTS_ON);

			// cpg_identified

			raw->group_member_number = unpack_int_value (en, INT_TYPE_GROUP_MEMBER_NUMBER);

			// id_number_significant_digits

			raw->damage_level = unpack_int_value (en, INT_TYPE_DAMAGE_LEVEL);

			// id_number

			raw->weapon_vector.x = 0.0;
			raw->weapon_vector.y = 0.0;
			raw->weapon_vector.z = 1.0;

			raw->weapon_to_target_vector.x = 0.0;
			raw->weapon_to_target_vector.y = 0.0;
			raw->weapon_to_target_vector.z = -1.0;

			// terrain_info

			break;
		}
		////////////////////////////////////////
		case PACK_MODE_BROWSE_SESSION:
		////////////////////////////////////////
		{
			break;
		}
		////////////////////////////////////////
		case PACK_MODE_UPDATE_ENTITY:
		////////////////////////////////////////
		{
			//
			// cannot update entity at this level as the update may not apply to all entity types below
			//

			break;
		}
	}
}
Beispiel #12
0
void unpack_local_session_data (pack_modes mode)
{
	session
		*raw;

	entity
		*en;

	int
		index;

   ASSERT ((mode >= 0) && (mode < NUM_PACK_MODES));

   switch (mode)
   {
      ////////////////////////////////////////
      case PACK_MODE_SERVER_SESSION:
      ////////////////////////////////////////
		{
			en = get_session_entity ();

			ASSERT (en);
			
			raw = (session *) get_local_entity_data (en);

			raw->version_number = unpack_int_value (en, INT_TYPE_VERSION_NUMBER);
		
			unpack_list_root (en, LIST_TYPE_FORCE, &raw->force_root);
		
			// special_effect_root
		
			// update_link
		
			raw->elapsed_time = unpack_float_value (en, FLOAT_TYPE_ELAPSED_TIME);
		
			raw->lightning_timer = unpack_float_value (en, FLOAT_TYPE_LIGHTNING_TIMER);
		
			raw->start_time = unpack_float_value (en, FLOAT_TYPE_START_TIME);
		
			// time_of_day_resync
		
			raw->time_of_day_acceleration = unpack_float_value (en, FLOAT_TYPE_TIME_OF_DAY_ACCELERATION);
		
			raw->fog_of_war_maximum_value = unpack_float_value (en, FLOAT_TYPE_FOG_OF_WAR_MAXIMUM_VALUE);
		
			//
			// rain effect
			//
		
			raw->weather_radius = unpack_float_value (en, FLOAT_TYPE_WEATHER_RADIUS);
			raw->weather_mode_transitional_period = unpack_float_value (en, FLOAT_TYPE_WEATHER_MODE_TRANSITIONAL_PERIOD);
			raw->weather_mode_transitional_status = unpack_float_value (en, FLOAT_TYPE_WEATHER_MODE_TRANSITIONAL_STATUS);
		
			raw->weather_mode = (weathermodes) unpack_int_value (en, INT_TYPE_WEATHER_MODE);
			raw->target_weather_mode = (weathermodes) unpack_int_value (en, INT_TYPE_TARGET_WEATHER_MODE);
		
			unpack_vec3d (en, VEC3D_TYPE_WEATHER_POSITION, &raw->weather_position);
			unpack_vec3d (en, VEC3D_TYPE_WEATHER_VELOCITY, &raw->weather_velocity);
		
			//
			// wind effect
			//
		
			raw->wind_effect_radius = unpack_float_value (en, FLOAT_TYPE_WIND_EFFECT_RADIUS);
			raw->wind_gusting_value = unpack_float_value (en, FLOAT_TYPE_WIND_GUSTING_VALUE);
			raw->wind_minimum_speed = unpack_float_value (en, FLOAT_TYPE_WIND_MINIMUM_SPEED);
			raw->wind_maximum_speed = unpack_float_value (en, FLOAT_TYPE_WIND_MAXIMUM_SPEED);
		
			unpack_vec3d (en, VEC3D_TYPE_WIND_DIRECTION_VECTOR, &raw->wind_direction_vector);
			unpack_vec3d (en, VEC3D_TYPE_WIND_EFFECT_POSITION, &raw->wind_effect_position);
			unpack_vec3d (en, VEC3D_TYPE_WIND_EFFECT_VELOCITY, &raw->wind_effect_velocity);
		
			//
		
			raw->day_segment_type = (day_segment_types) unpack_int_value (en, INT_TYPE_DAY_SEGMENT_TYPE);

			raw->population_x_min = unpack_float_value (en, FLOAT_TYPE_POPULATION_X_MIN);
			raw->population_x_max = unpack_float_value (en, FLOAT_TYPE_POPULATION_X_MAX);
			raw->population_z_min = unpack_float_value (en, FLOAT_TYPE_POPULATION_Z_MIN);
			raw->population_z_max = unpack_float_value (en, FLOAT_TYPE_POPULATION_Z_MAX);
		
			raw->campaign_medal = unpack_int_value (en, INT_TYPE_CAMPAIGN_MEDAL);
		
			raw->campaign_requires_apache_havoc = unpack_int_value (en, INT_TYPE_CAMPAIGN_REQUIRES_APACHE_HAVOC);
		
			raw->auto_assign_gunship = unpack_int_value (en, INT_TYPE_AUTO_ASSIGN_GUNSHIP);
		
			raw->infinite_fuel = unpack_int_value (en, INT_TYPE_INFINITE_FUEL);
		
			raw->infinite_weapons = unpack_int_value (en, INT_TYPE_INFINITE_WEAPONS);
		
			raw->suppress_ai_fire = unpack_int_value (en, INT_TYPE_SUPPRESS_AI_FIRE);
		
			raw->invulnerable_from_collisions = unpack_int_value (en, INT_TYPE_INVULNERABLE_FROM_COLLISIONS);

			raw->invulnerable_from_weapons = unpack_int_value (en, INT_TYPE_INVULNERABLE_FROM_WEAPONS);
		
			raw->cheats_enabled = unpack_int_value (en, INT_TYPE_CHEATS_ENABLED);
		
			raw->skip_night_time = unpack_int_value (en, INT_TYPE_SKIP_NIGHT_TIME);
		
			raw->weather_increasing = unpack_int_value (en, INT_TYPE_WEATHER_INCREASING);
		
			raw->wind_increasing = unpack_int_value (en, INT_TYPE_WIND_INCREASING);
		
			raw->local_weather_model = unpack_int_value (en, INT_TYPE_LOCAL_WEATHER_MODEL);

			break;
		}
      ////////////////////////////////////////
      case PACK_MODE_CLIENT_SESSION:
      ////////////////////////////////////////
      {
         //
         // create entity
         //

			ASSERT (!get_session_entity ());

			index = unpack_entity_safe_index ();

			en = get_free_entity (index);

			set_local_entity_type (en, ENTITY_TYPE_SESSION);

			raw = (session *) malloc_fast_mem (sizeof (session));

			set_local_entity_data (en, raw);

			memset (raw, 0, sizeof (session));

			//
			// unpack data (in exactly the same order as the data was packed)
			//

			raw->version_number = unpack_int_value (en, INT_TYPE_VERSION_NUMBER);

			raw->session_complete = unpack_int_value (en, INT_TYPE_SESSION_COMPLETE);
		
			unpack_list_root (en, LIST_TYPE_FORCE, &raw->force_root);

			unpack_list_root (en, LIST_TYPE_SPECIAL_EFFECT, &raw->special_effect_root);

			// update_link

			raw->elapsed_time = unpack_float_value (en, FLOAT_TYPE_ELAPSED_TIME);

         raw->lightning_timer = unpack_float_value (en, FLOAT_TYPE_LIGHTNING_TIMER);

			raw->start_time = unpack_float_value (en, FLOAT_TYPE_START_TIME);

			// time_of_day_resync

			raw->time_of_day_acceleration = unpack_float_value (en, FLOAT_TYPE_TIME_OF_DAY_ACCELERATION);

			raw->fog_of_war_maximum_value = unpack_float_value (en, FLOAT_TYPE_FOG_OF_WAR_MAXIMUM_VALUE);
		
			//
			// rain effect
			//

         raw->weather_radius = unpack_float_value (en, FLOAT_TYPE_WEATHER_RADIUS);
         raw->weather_mode_transitional_period = unpack_float_value (en, FLOAT_TYPE_WEATHER_MODE_TRANSITIONAL_PERIOD);
         raw->weather_mode_transitional_status = unpack_float_value (en, FLOAT_TYPE_WEATHER_MODE_TRANSITIONAL_STATUS);

         raw->weather_mode = (weathermodes) unpack_int_value (en, INT_TYPE_WEATHER_MODE);
         raw->target_weather_mode = (weathermodes) unpack_int_value (en, INT_TYPE_TARGET_WEATHER_MODE);

			unpack_vec3d (en, VEC3D_TYPE_WEATHER_POSITION, &raw->weather_position);
			unpack_vec3d (en, VEC3D_TYPE_WEATHER_VELOCITY, &raw->weather_velocity);

			//
			// wind effect
			//

			raw->wind_effect_radius = unpack_float_value (en, FLOAT_TYPE_WIND_EFFECT_RADIUS);
         raw->wind_gusting_value = unpack_float_value (en, FLOAT_TYPE_WIND_GUSTING_VALUE);
			raw->wind_minimum_speed = unpack_float_value (en, FLOAT_TYPE_WIND_MINIMUM_SPEED);
			raw->wind_maximum_speed = unpack_float_value (en, FLOAT_TYPE_WIND_MAXIMUM_SPEED);

			unpack_vec3d (en, VEC3D_TYPE_WIND_DIRECTION_VECTOR, &raw->wind_direction_vector);
			unpack_vec3d (en, VEC3D_TYPE_WIND_EFFECT_POSITION, &raw->wind_effect_position);
			unpack_vec3d (en, VEC3D_TYPE_WIND_EFFECT_VELOCITY, &raw->wind_effect_velocity);

			//

			raw->day_segment_type = (day_segment_types) unpack_int_value (en, INT_TYPE_DAY_SEGMENT_TYPE);

			raw->population_x_min = unpack_float_value (en, FLOAT_TYPE_POPULATION_X_MIN);
			raw->population_x_max = unpack_float_value (en, FLOAT_TYPE_POPULATION_X_MAX);
			raw->population_z_min = unpack_float_value (en, FLOAT_TYPE_POPULATION_Z_MIN);
			raw->population_z_max = unpack_float_value (en, FLOAT_TYPE_POPULATION_Z_MAX);
		
			raw->campaign_medal = unpack_int_value (en, INT_TYPE_CAMPAIGN_MEDAL);
		
			raw->campaign_requires_apache_havoc = unpack_int_value (en, INT_TYPE_CAMPAIGN_REQUIRES_APACHE_HAVOC);

			raw->auto_assign_gunship = unpack_int_value (en, INT_TYPE_AUTO_ASSIGN_GUNSHIP);

         raw->infinite_fuel = unpack_int_value (en, INT_TYPE_INFINITE_FUEL);

         raw->infinite_weapons = unpack_int_value (en, INT_TYPE_INFINITE_WEAPONS);

         raw->suppress_ai_fire = unpack_int_value (en, INT_TYPE_SUPPRESS_AI_FIRE);
		
			raw->invulnerable_from_collisions = unpack_int_value (en, INT_TYPE_INVULNERABLE_FROM_COLLISIONS);

			raw->invulnerable_from_weapons = unpack_int_value (en, INT_TYPE_INVULNERABLE_FROM_WEAPONS);

			raw->cheats_enabled = unpack_int_value (en, INT_TYPE_CHEATS_ENABLED);
		
         raw->skip_night_time = unpack_int_value (en, INT_TYPE_SKIP_NIGHT_TIME);

         raw->weather_increasing = unpack_int_value (en, INT_TYPE_WEATHER_INCREASING);

         raw->wind_increasing = unpack_int_value (en, INT_TYPE_WIND_INCREASING);

         raw->local_weather_model = unpack_int_value (en, INT_TYPE_LOCAL_WEATHER_MODEL);

			//
			// link into system
			//

			//
			// need to insert session into update list after camera entity
			//

			ASSERT (get_camera_entity ());

         insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), get_camera_entity ());

			set_session_entity (en);

			set_display_campaign_timer_valid (FALSE);

			break;
		}

		////////////////////////////////////////
		case PACK_MODE_BROWSE_SESSION:
		////////////////////////////////////////
		{
			//
			// create entity
			//

			ASSERT (!get_session_entity ());

			index = unpack_entity_safe_index ();

			en = get_free_entity (index);

			set_local_entity_type (en, ENTITY_TYPE_SESSION);

			raw = (session *) malloc_fast_mem (sizeof (session));

			set_local_entity_data (en, raw);

			memset (raw, 0, sizeof (session));

			//
			// unpack data (in exactly the same order as the data was packed)
			//

         raw->version_number = unpack_int_value (en, INT_TYPE_VERSION_NUMBER);

			unpack_list_root (en, LIST_TYPE_FORCE, &raw->force_root);

			// update_link

			// tour of duty time

			raw->elapsed_time = unpack_float_value (en, FLOAT_TYPE_ELAPSED_TIME);

			raw->start_time = unpack_float_value (en, FLOAT_TYPE_START_TIME);

			// time_of_day_resync

			// time_of_day_acceleration

			// weather radius

			// weather_mode_transitional_period

			// weather_mode_transitional_status

			raw->weather_mode = (weathermodes) unpack_int_value (en, INT_TYPE_WEATHER_MODE);

			// target_weather_mode

			// weather position

			// weather velocity

			raw->day_segment_type = (day_segment_types) unpack_int_value (en, INT_TYPE_DAY_SEGMENT_TYPE);

			raw->population_x_min = unpack_float_value (en, FLOAT_TYPE_POPULATION_X_MIN);
			raw->population_x_max = unpack_float_value (en, FLOAT_TYPE_POPULATION_X_MAX);
			raw->population_z_min = unpack_float_value (en, FLOAT_TYPE_POPULATION_Z_MIN);
			raw->population_z_max = unpack_float_value (en, FLOAT_TYPE_POPULATION_Z_MAX);
		
			raw->campaign_requires_apache_havoc = unpack_int_value (en, INT_TYPE_CAMPAIGN_REQUIRES_APACHE_HAVOC);

			// infinite_weapons

			// skip_night_time

			// weather increasing

			set_session_entity (en);

			break;
		}
	}
}
Beispiel #13
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);
}
Beispiel #14
0
static entity *create_local (entity_types type, int index, char *pargs)
{
	entity
		*en;

	weapon
		*raw;

	int
		seed;

	viewpoint
		vp;

	////////////////////////////////////////
  	//
  	// 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)
	{
		float dispersion;

		////////////////////////////////////////
   	//
   	// MALLOC ENTITY DATA
   	//
		////////////////////////////////////////

		set_local_entity_type (en, type);

		raw = (weapon *) malloc_fast_mem (sizeof (weapon));

		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 (weapon));

		//
		// mobile
		//

		raw->mob.sub_type = ENTITY_SUB_TYPE_UNINITIALISED;

		raw->mob.position.x = MID_MAP_X;
		raw->mob.position.y = MID_MAP_Y;
		raw->mob.position.z = MID_MAP_Z;

		get_identity_matrix3x3 (raw->mob.attitude);

		raw->mob.alive = TRUE;

		//
		// weapon
		//

		raw->kill_code = WEAPON_KILL_CODE_OK;

		////////////////////////////////////////
		//
		// OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES
		//
		////////////////////////////////////////

		set_local_entity_attributes (en, pargs);

		////////////////////////////////////////
		//
		// CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN
		//
		////////////////////////////////////////

		ASSERT (entity_sub_type_weapon_valid (raw->mob.sub_type));

		ASSERT (raw->launched_weapon_link.parent);

		ASSERT (raw->burst_size > 0);

		////////////////////////////////////////
		//
		// RESOLVE DEFAULT VALUES
		//
		////////////////////////////////////////

		if (weapon_database[raw->mob.sub_type].acquire_parent_forward_velocity)
		{
			raw->mob.velocity = get_local_entity_float_value (raw->launched_weapon_link.parent, FLOAT_TYPE_VELOCITY);
		}
		else
		{
			//
			// overwrite attribute
			//

			raw->mob.velocity = 0.0;
		}

		raw->mob.velocity += weapon_database[raw->mob.sub_type].muzzle_velocity;

		seed = get_client_server_entity_random_number_seed (en);

		raw->mob.velocity += weapon_database[raw->mob.sub_type].muzzle_velocity_max_error * frand1x (&seed);

		raw->weapon_lifetime = weapon_database[raw->mob.sub_type].burn_time;

		raw->decoy_timer = get_decoy_timer_start_value (weapon_database[raw->mob.sub_type].decoy_type);

		//
		// detach weapon from launcher (get position and attitude)
		//

		detach_local_entity_weapon (raw->launched_weapon_link.parent, raw->mob.sub_type, raw->burst_size, &vp);

		raw->mob.position = vp.position;

		// arneh - add dispersion as random rotation in heading and pitch up to max error angle
		dispersion = weapon_database[raw->mob.sub_type].max_range_error_ratio;
		if (dispersion > 0.0)
		{
			matrix3x3
				m;

			float
				heading = dispersion * sfrand1norm(),
				pitch = dispersion * sfrand1norm();

			get_3d_transformation_matrix(m, heading, pitch, 0.0);
			multiply_matrix3x3_matrix3x3(raw->mob.attitude, vp.attitude, m);
		}
		else
			memcpy (raw->mob.attitude, vp.attitude, sizeof (matrix3x3));

		//
		// interest level
		//

		set_local_entity_float_value (raw->launched_weapon_link.parent, FLOAT_TYPE_VIEW_INTEREST_LEVEL, DEFAULT_VIEW_INTEREST_LEVEL);

		////////////////////////////////////////
		//
		// LINK INTO SYSTEM
		//
		////////////////////////////////////////

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_LAUNCHED_WEAPON, raw->launched_weapon_link.parent, NULL);

		if (raw->mob.target_link.parent)
		{
			insert_local_entity_into_parents_child_list (en, LIST_TYPE_TARGET, raw->mob.target_link.parent, NULL);
		}

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->mob.position), NULL);

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL);

		if (tacview_is_logging())
			write_tacview_new_unit(en);

		//
		// check if the weapon camera is primed and this weapon has been launched by the external view entity
		//

		if (get_camera_entity ())
		{
			if (get_local_entity_int_value (get_camera_entity (), INT_TYPE_WEAPON_CAMERA_PRIMED))
			{
				if (raw->launched_weapon_link.parent == get_external_view_entity ())
				{
					if (get_local_entity_int_value (en, INT_TYPE_VIEWABLE_WEAPON))
					{
						notify_local_entity (ENTITY_MESSAGE_SET_CAMERA_ACTION, get_camera_entity (), NULL, CAMERA_ACTION_WEAPON);

						set_local_entity_int_value (get_camera_entity (), INT_TYPE_WEAPON_CAMERA_PRIMED, FALSE);
					}
				}
			}
		}
	}

	return (en);
}
Beispiel #15
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 #16
0
void unpack_routed_vehicle_meta_smoke_lists (entity *en, pack_modes mode)
{
	object_3d_instance
		*inst3d;

	int
		item,
		loop,
		count,
		point,
		*entity_index_list;

	meta_smoke_list_types
		type;

	object_3d_sub_object_index_numbers
		attachment_point;

	if (get_local_entity_int_value (en, INT_TYPE_ALIVE))
	{
		inst3d = (object_3d_instance *) get_local_entity_ptr_value (en, PTR_TYPE_INSTANCE_3D_OBJECT);

		if (inst3d)
		{
			#if DEBUG_MODULE

			debug_log ("ROUTED : Unpacking smoke for %s ( %d )", vehicle_database [get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE)].full_name, en);

			#endif

			item = 0;

			while (TRUE)
			{
				type = attached_meta_smoke_list_table [item].type;

				if (type == -1)
				{
					break;
				}
				else
				{				
					for (point = 0; point < MAX_META_SMOKE_LIST_ATTACHMENT_POINTS; point ++)
					{
						attachment_point = attached_meta_smoke_list_table [item].attachment_point [point];

						if (attachment_point == -1)
						{
							break;
						}
						else
						{				
							count = count_sub_object_type_depth (inst3d, attachment_point);

							if (count >0)
							{
								count *= count_entities_in_meta_smoke_list (type);						

								entity_index_list = (int *) malloc_fast_mem (sizeof (int) * count);

								for (loop = 0; loop < count; loop ++)
								{
									if (mode == PACK_MODE_SERVER_SESSION)
									{
										entity_index_list [loop] = ENTITY_INDEX_DONT_CARE;
									}
									else
									{
										entity_index_list [loop] = unpack_entity_safe_index ();
									}

									#if DEBUG_MODULE

									debug_log ("ROUTED : Index %d = %d", loop, entity_index_list [loop]);

									#endif
								}

								register_attach_meta_smoke_list_to_object (en, type, attachment_point, entity_index_list, count);

								free_mem (entity_index_list);
							}
						}
					}
				}

				item ++;
			}
		}
	}
}
Beispiel #17
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 #18
0
static entity *create_local (entity_types type, int index, char *pargs)
{
	entity
		*en;

	sprite
		*raw;

	#if DEBUG_MODULE

	debug_log ("SPRITE: create");

	#endif

	////////////////////////////////////////
  	//
  	// 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 (sprite));

		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 (sprite));

		//
		// effect
		//

		raw->eff.position.x = MID_MAP_X;
		raw->eff.position.y = MID_MAP_Y;
		raw->eff.position.z = MID_MAP_Z;

		//
		// sprite
		//

		raw->effect_lifetime = 0.0;

		raw->start_scale = 1.0;
		raw->end_scale = 1.0;

		////////////////////////////////////////
		//
		// OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES
		//
		////////////////////////////////////////

		set_local_entity_attributes (en, pargs);

		////////////////////////////////////////
		//
		// CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN
		//
		////////////////////////////////////////

		ASSERT (raw->animation_frequency >= 0.0);

		ASSERT (raw->sprite_lifetime > 0.0);

		////////////////////////////////////////
		//
		// RESOLVE DEFAULT VALUES
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// BUILD COMPONENTS
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// LINK INTO SYSTEM
		//
		////////////////////////////////////////

		if (raw->eff.special_effect_link.parent)
		{
			insert_local_entity_into_parents_child_list (en, LIST_TYPE_SPECIAL_EFFECT, raw->eff.special_effect_link.parent, NULL);
		}

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL);

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->eff.position), NULL);
	}

	return (en);
}
Beispiel #19
0
void unpack_local_force_data (entity *en, pack_modes mode)
{

	int
		count,
		loop;

	force
		*raw;

	campaign_criteria_type
		*last_campaign_criteria,
		*campaign_criteria;

	ASSERT ((mode >= 0) && (mode < NUM_PACK_MODES));

	ASSERT (en);

	raw = (force *) get_local_entity_data (en);
		
	switch (mode)
	{
		////////////////////////////////////////
		case PACK_MODE_SERVER_SESSION:
		////////////////////////////////////////
		{
         unpack_string (en, STRING_TYPE_FORCE_NAME, raw->force_name);

			// keysite_force
		
			// pilot root
		
			unpack_list_root (en, LIST_TYPE_DIVISION, &raw->division_root);
	
			unpack_list_root (en, LIST_TYPE_CAMPAIGN_OBJECTIVE, &raw->campaign_objective_root);
	
			// air_registry_root
			// ground_registry_root
			// sea_registry_root
	
//			unpack_list_root (en, LIST_TYPE_INDEPENDENT_GROUP, &raw->independent_group_root);
	
			// force_link
		
			// update link
		
			// task generation //////////////////////////////////////////////
		
			for (loop = 0; loop < NUM_ENTITY_SUB_TYPE_TASKS; loop ++)
			{
				raw->task_generation [loop].valid = unpack_int_value (en, INT_TYPE_VALID);

				raw->task_generation [loop].created = unpack_int_value (en, INT_TYPE_TASK_GENERATION);
			}
			/////////////////////////////////////////////////////////////////
		
			// campaign criteria ////////////////////////////////////////////
		
			count = unpack_int_value (en, INT_TYPE_CAMPAIGN_CRITERIA_COUNT);
	
			last_campaign_criteria = NULL;
	
			while (count)
			{
	
				campaign_criteria = (campaign_criteria_type *) malloc_heap_mem (sizeof (campaign_criteria_type));
	
				memset (campaign_criteria, 0, sizeof (campaign_criteria_type));
		
				campaign_criteria->criteria_type = unpack_int_value (en, INT_TYPE_CAMPAIGN_CRITERIA_TYPE);
		
				campaign_criteria->valid = unpack_int_value (en, INT_TYPE_VALID);
		
				campaign_criteria->result = unpack_int_value (en, INT_TYPE_CAMPAIGN_CRITERIA_RESULT);
		
				campaign_criteria->value1 = unpack_int_value (en, INT_TYPE_CAMPAIGN_CRITERIA_VALUE);
		
				campaign_criteria->value2 = unpack_int_value (en, INT_TYPE_CAMPAIGN_CRITERIA_VALUE);
		
				campaign_criteria->value3 = unpack_int_value (en, INT_TYPE_CAMPAIGN_CRITERIA_VALUE);
		
				campaign_criteria->value4 = unpack_int_value (en, INT_TYPE_CAMPAIGN_CRITERIA_VALUE);
		
				campaign_criteria->next = last_campaign_criteria;
	
				raw->campaign_criteria = campaign_criteria;
	
				last_campaign_criteria = campaign_criteria;
	
				count --;
			}
			/////////////////////////////////////////////////////////////////
		
			// force_info_criteria
		
			for (loop = 0; loop < NUM_FORCE_INFO_CATAGORIES; loop ++)
			{
				raw->force_info_current_hardware [loop] = unpack_int_value (en, INT_TYPE_VALUE);
		
				raw->force_info_reserve_hardware [loop] = unpack_int_value (en, INT_TYPE_VALUE);
			}
			/////////////////////////////////////////////////////////////////
	
			for (loop = 0; loop < NUM_ENTITY_SUB_TYPE_GROUPS; loop ++)
			{
				raw->kills [loop] = unpack_int_value (en, INT_TYPE_VALUE);
				raw->losses [loop] = unpack_int_value (en, INT_TYPE_VALUE);
//				raw->group_count [loop] = unpack_int_value (en, INT_TYPE_VALUE);
			}

			raw->sleep = unpack_float_value (en, FLOAT_TYPE_SLEEP);
		
			raw->force_attitude = unpack_int_value (en, INT_TYPE_FORCE_ATTITUDE);
		
			// sector_count
		
			raw->colour = unpack_int_value (en, INT_TYPE_COLOUR);
		
			raw->side = unpack_int_value (en, INT_TYPE_SIDE);
	
			break;
		}
		////////////////////////////////////////
		case PACK_MODE_CLIENT_SESSION:
		////////////////////////////////////////
		{
			//
			// create entity
			//

			debug_assert (get_free_entity (get_local_entity_safe_index (en)));

			set_local_entity_type (en, ENTITY_TYPE_FORCE);

			raw = (force *) malloc_fast_mem (sizeof (force));

			set_local_entity_data (en, raw);

			memset (raw, 0, sizeof (force));

			//
			// unpack data (in exactly the same order as the data was packed)
			//

         unpack_string (en, STRING_TYPE_FORCE_NAME, raw->force_name);

			// keysite_force
	
			unpack_list_root (en, LIST_TYPE_PILOT, &raw->pilot_root);

			unpack_list_root (en, LIST_TYPE_DIVISION, &raw->division_root);

			unpack_list_root (en, LIST_TYPE_CAMPAIGN_OBJECTIVE, &raw->campaign_objective_root);

			//	air_registry_root
			//	ground_registry_root
			//	sea_registry_root

//			unpack_list_root (en, LIST_TYPE_INDEPENDENT_GROUP, &raw->independent_group_root);
	
			unpack_list_link (en, LIST_TYPE_FORCE, &raw->force_link);

			// update_link

			////////////////////////////////////////////
			// task_generation
			for (loop = 0; loop < NUM_ENTITY_SUB_TYPE_TASKS; loop ++)
			{
				raw->task_generation [loop].valid = unpack_int_value (en, INT_TYPE_VALID);

				raw->task_generation [loop].created = unpack_int_value (en, INT_TYPE_TASK_GENERATION);
			}
			////////////////////////////////////////////

			////////////////////////////////////////////
			// campaign criteria 
			raw->campaign_criteria = NULL;

			count = unpack_int_value (en, INT_TYPE_CAMPAIGN_CRITERIA_COUNT);

			while (count)
			{

				count --;

				campaign_criteria = (campaign_criteria_type *) malloc_heap_mem (sizeof (campaign_criteria_type));

				memset (campaign_criteria, 0, sizeof (campaign_criteria_type));

				campaign_criteria->next = raw->campaign_criteria;

				raw->campaign_criteria = campaign_criteria;

				campaign_criteria->criteria_type = unpack_int_value (en, INT_TYPE_CAMPAIGN_CRITERIA_TYPE);

				campaign_criteria->valid = unpack_int_value (en, INT_TYPE_VALID);

				campaign_criteria->result = unpack_int_value (en, INT_TYPE_CAMPAIGN_CRITERIA_RESULT);

				campaign_criteria->value1 = unpack_int_value (en, INT_TYPE_CAMPAIGN_CRITERIA_VALUE);

				campaign_criteria->value2 = unpack_int_value (en, INT_TYPE_CAMPAIGN_CRITERIA_VALUE);

				campaign_criteria->value3 = unpack_int_value (en, INT_TYPE_CAMPAIGN_CRITERIA_VALUE);

				campaign_criteria->value4 = unpack_int_value (en, INT_TYPE_CAMPAIGN_CRITERIA_VALUE);
			}
			/////////////////////////////////////////////////////////////////

			////////////////////////////////////////////
			// force_info_criteria
			for (loop = 0; loop < NUM_FORCE_INFO_CATAGORIES; loop ++)
			{
				raw->force_info_current_hardware [loop] = unpack_int_value (en, INT_TYPE_VALUE);

				raw->force_info_reserve_hardware [loop] = unpack_int_value (en, INT_TYPE_VALUE);
			}
			// force_info_criteria

			for (loop = 0; loop < NUM_ENTITY_SUB_TYPE_GROUPS; loop ++)
			{
				raw->kills [loop] = unpack_int_value (en, INT_TYPE_VALUE);
				raw->losses [loop] = unpack_int_value (en, INT_TYPE_VALUE);
//				raw->group_count [loop] = unpack_int_value (en, INT_TYPE_VALUE);
			}

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

			raw->force_attitude = unpack_int_value (en, INT_TYPE_FORCE_ATTITUDE);

			raw->sector_count = unpack_int_value (en, INT_TYPE_FORCE_SECTOR_COUNT);

			raw->colour = unpack_int_value (en, INT_TYPE_COLOUR);

			raw->side = unpack_int_value (en, INT_TYPE_SIDE);

			insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL);

			break;
		}
		////////////////////////////////////////
		case PACK_MODE_BROWSE_SESSION:
		////////////////////////////////////////
		{
			//
			// create entity
			//

			debug_assert (get_free_entity (get_local_entity_safe_index (en)));

			set_local_entity_type (en, ENTITY_TYPE_FORCE);

			raw = (force *) malloc_fast_mem (sizeof (force));

			set_local_entity_data (en, raw);

			memset (raw, 0, sizeof (force));

			//
			// unpack data (in exactly the same order as the data was packed)
			//

         unpack_string (en, STRING_TYPE_FORCE_NAME, raw->force_name);

			// keysite_force_root

			unpack_list_root (en, LIST_TYPE_PILOT, &raw->pilot_root);

			unpack_list_link (en, LIST_TYPE_FORCE, &raw->force_link);

			// update_link

			// task_generation

			// campaign_criteria

			// force_info_catagories

			// sleep

			raw->force_attitude = unpack_int_value (en, INT_TYPE_FORCE_ATTITUDE);

			raw->colour = unpack_int_value (en, INT_TYPE_COLOUR);

			raw->side = unpack_int_value (en, INT_TYPE_SIDE);

			break;
		}
	}
}
Beispiel #20
0
unsigned int assign_engage_tasks_to_group (entity *group, unsigned int valid_members)
{
	entity
		*task,
		*guide,
		*target,
		*member,
		*single_member,
		*persuer,
		**guide_list;

	unsigned int
		member_number;

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

	float
		range,
		*priority;

	vec3d
		*member_pos,
		*target_pos;

	ASSERT (group);

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	if (!valid_members)
	{
		return valid_members;
	}	

	//
	// count up engage tasks
	//

	task_count = 0;

	guide = get_local_entity_first_child (group, LIST_TYPE_GUIDE_STACK);

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

			ASSERT (task);

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

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

		guide = get_local_entity_child_succ (guide, LIST_TYPE_GUIDE_STACK);
	}

	#if DEBUG_MODULE

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

	#endif

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

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

	//
	// get target priority
	//

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

	#if DEBUG_MODULE

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

	#endif

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

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

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

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

			ASSERT (task);

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

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

				ASSERT (target);

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

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

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

				#if DEBUG_MODULE

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

				#endif

				loop ++;
			}
		}

		guide = get_local_entity_child_succ (guide, LIST_TYPE_GUIDE_STACK);
	}

	ASSERT (loop == task_count);

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

	quicksort_entity_list (guide_list, task_count, priority);

	#if DEBUG_MODULE

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

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

		target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT);

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

	#endif

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

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

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

		target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT);

		persuer = get_local_entity_first_child (target, LIST_TYPE_TARGET);

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

			persuer = get_local_entity_child_succ (persuer, LIST_TYPE_TARGET);
		}
	}

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

	member = get_local_entity_first_child (group, LIST_TYPE_MEMBER);

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

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

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

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

							//
							// Range Check
							//

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

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

	free_mem (guide_list);

	free_mem (priority);

	free_mem (assigned_count);

	return valid_members;
}
Beispiel #21
0
int update_pilot_high_score_table (void)
{
	int
		count,
		num_pilots;

	entity
		*force_en,
		*pilot_en;

	pilot_score_type
		*full_table;

	//
	// clear table
	//

	debug_log ("PILOT: Updating High Score Table");

	initialise_pilot_high_score_table ();

	num_pilots = 0;

	//
	// count up player pilots
	//

	ASSERT (get_session_entity ());

	force_en = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE);

	while (force_en)
	{
		pilot_en = get_local_entity_first_child (force_en, LIST_TYPE_PILOT);

		while (pilot_en)
		{
			num_pilots ++;

			pilot_en = get_local_entity_child_succ (pilot_en, LIST_TYPE_PILOT);
		}

		force_en = get_local_entity_child_succ (force_en, LIST_TYPE_FORCE);
	}

	if (num_pilots == 0)
	{
		return 0;
	}

	//
	// create arrays of player pilots and their scores
	//

	full_table = (pilot_score_type *) malloc_fast_mem (sizeof (pilot_score_type) * num_pilots);

	count = 0;

	force_en = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE);

	while (force_en)
	{
		pilot_en = get_local_entity_first_child (force_en, LIST_TYPE_PILOT);

		while (pilot_en)
		{
			full_table [count].kills = get_local_entity_int_value (pilot_en, INT_TYPE_KILLS);

			full_table [count].side = (entity_sides) get_local_entity_int_value (pilot_en, INT_TYPE_SIDE);

			full_table [count].valid = TRUE;

			strcpy (full_table [count].name, get_local_entity_string (pilot_en, STRING_TYPE_PILOTS_NAME));

			debug_log ("PILOT: Adding %s (kills %d) to High Score Table", full_table [count].name, full_table [count].kills);

			count ++;

			pilot_en = get_local_entity_child_succ (pilot_en, LIST_TYPE_PILOT);
		}

		force_en = get_local_entity_child_succ (force_en, LIST_TYPE_FORCE);
	}

	ASSERT (count == num_pilots);

	//
	// quicksort the list
	//

   qs_table (full_table, 0, num_pilots - 1);

	//
	// add first n items to the high score table
	//

	count = min (num_pilots, NUM_TABLE_ENTRIES);

	memcpy (pilot_high_score_table, full_table, sizeof (pilot_score_type) * count);

	free_mem (full_table);

	return count;
}
Beispiel #22
0
static entity *create_local (entity_types type, int index, char *pargs)
{

	char
		 name [STRING_TYPE_KEYSITE_NAME_MAX_LENGTH];

	entity
		*group,
		*force,
		*sector,
		*en;

	keysite
		*raw;

	////////////////////////////////////////
  	//
  	// 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 (keysite));

		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 (keysite));

		sprintf (name, "KEYSITE %d", (int) en % 100);

		strncpy (raw->keysite_name, name, STRING_TYPE_KEYSITE_NAME_MAX_LENGTH);

		//
		// fixed
		//

		raw->position.x = MID_MAP_X;
		raw->position.y = MID_MAP_Y;
		raw->position.z = MID_MAP_Z;

		raw->alive = TRUE;

		raw->keysite_usable_state = KEYSITE_STATE_USABLE;

		raw->in_use = FALSE;
		raw->object_index = OBJECT_3D_INVALID_OBJECT_INDEX;

		raw->side = ENTITY_SIDE_NEUTRAL;

		raw->supplies.ammo_supply_level = 0.0;

		raw->supplies.fuel_supply_level = 0.0;

		raw->assign_timer = frand1 () * KEYSITE_TASK_ASSIGN_TIMER;		// SERVER ONLY - OK TO USE RANDOM

		raw->sleep = frand1 () * KEYSITE_UPDATE_SLEEP_TIMER;				// SERVER ONLY - OK TO USE RANDOM

		////////////////////////////////////////
		//
		// OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES
		//
		////////////////////////////////////////

		set_local_entity_attributes (en, pargs);

		////////////////////////////////////////
		//
		// CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN
		//
		////////////////////////////////////////

		ASSERT (raw->side != ENTITY_SIDE_NEUTRAL);

		ASSERT (entity_sub_type_keysite_valid (raw->sub_type));

		ASSERT (keysite_database [raw->sub_type].minimum_efficiency < 1.0);

		// the following is currently required for the campaign to progress properly...
		ASSERT (keysite_database [raw->sub_type].repairable == keysite_database [raw->sub_type].troop_insertion_target);

		////////////////////////////////////////
		//
		// RESOLVE DEFAULT VALUES
		//
		////////////////////////////////////////

		update_keysite_cargo (en, raw->supplies.ammo_supply_level, ENTITY_SUB_TYPE_CARGO_AMMO, CARGO_AMMO_SIZE);

		update_keysite_cargo (en, raw->supplies.fuel_supply_level, ENTITY_SUB_TYPE_CARGO_FUEL, CARGO_FUEL_SIZE);

		////////////////////////////////////////
		//
		// BUILD COMPONENTS
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// LINK INTO SYSTEM
		//
		////////////////////////////////////////

		force = get_local_entity_parent (en, LIST_TYPE_KEYSITE_FORCE);

		debug_assert (get_local_entity_type (force) == ENTITY_TYPE_FORCE);

		ASSERT (force);

		sector = get_local_sector_entity (&raw->position);

		ASSERT (sector);

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_KEYSITE_FORCE, force, NULL);

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, sector, NULL);

		insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL);

		set_local_entity_int_value (sector, INT_TYPE_KEYSITE_COUNT, get_local_entity_int_value (sector, INT_TYPE_KEYSITE_COUNT) + 1);

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

			update_imap_importance_level (en, TRUE);

			update_keysite_distance_to_friendly_base (en, raw->side);
		}

		////////////////////////////////////////
		//
		//	CREATE SUB ENTITIES
		//
		////////////////////////////////////////

		// for site buildings

		group = create_local_entity
		(
			ENTITY_TYPE_GROUP,
			ENTITY_INDEX_DONT_CARE,
			ENTITY_ATTR_PARENT (LIST_TYPE_BUILDING_GROUP, en),
			ENTITY_ATTR_VEC3D (VEC3D_TYPE_POSITION, raw->position.x, raw->position.y, raw->position.z),
			ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, ENTITY_SUB_TYPE_GROUP_BUILDINGS),
			ENTITY_ATTR_END
		);

		#if DEBUG_MODULE
		{
			int
				sx,
				sz;

			get_x_sector (sx, raw->position.x);
			get_z_sector (sz, raw->position.z);
			
			debug_log ("KS_CREAT: Side %s creating keysite %s (type %d) index %d at %f, %f (%d, %d)", entity_side_short_names [raw->side], raw->keysite_name, raw->sub_type, get_local_entity_index (en), raw->position.x, raw->position.z, sx, sz);
		}
		#endif
	}

	return (en);
}
Beispiel #23
0
static entity *create_local (entity_types type, int index, char *pargs)
{
	entity
		*en;

	bridge
		*raw;

	#if DEBUG_MODULE

	debug_log ("BRIDGE: create %d", index);

	#endif

	////////////////////////////////////////
  	//
  	// 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 (bridge));

		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 (bridge));

		raw->alive = TRUE;

		////////////////////////////////////////
		//
		// OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES
		//
		////////////////////////////////////////

		set_local_entity_attributes (en, pargs);

		////////////////////////////////////////
		//
		// CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN
		//
		////////////////////////////////////////

		ASSERT (entity_sub_type_bridge_valid (raw->sub_type));

		////////////////////////////////////////
		//
		// RESOLVE DEFAULT VALUES
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// BUILD COMPONENTS
		//
		////////////////////////////////////////

		////////////////////////////////////////
		//
		// LINK INTO SYSTEM
		//
		////////////////////////////////////////

	}

	return (en);
}
Beispiel #24
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
				loop,
				index;

			sound_effect
				*raw;

			//
			// create entity
			//

			index = unpack_entity_safe_index ();

			en = get_free_entity (index);

			set_local_entity_type (en, type);

			raw = malloc_heap_mem (sizeof (sound_effect));

			set_local_entity_data (en, raw);

			memset (raw, 0, sizeof (sound_effect));

			//
			// unpack effect data (in exactly the same order as the data was packed)
			//

			unpack_effect_data( en, &raw->eff, mode );

			//
			// unpack sound data
			//

			raw->sound_effect_sequence_count = unpack_int_value (en, INT_TYPE_SOUND_EFFECT_SEQUENCE_COUNT);

			ASSERT (raw->sound_effect_sequence_count > 0);

			raw->effect_index = malloc_fast_mem (sizeof (sound_sample_indices) * raw->sound_effect_sequence_count);

			for (loop = 0; loop < raw->sound_effect_sequence_count; loop ++)
			{
				raw->effect_index [loop] = unpack_int_value (en, INT_TYPE_SOUND_EFFECT_INDEX);
			}

			raw->amplification = unpack_float_value (en, FLOAT_TYPE_AMPLIFICATION);

			raw->effect_lifetime = unpack_float_value (en, FLOAT_TYPE_EFFECT_LIFETIME);

			raw->valid_effect_lifetime = unpack_float_value (en, FLOAT_TYPE_VALID_EFFECT_LIFETIME);

			//sound_effect_data 

			raw->sound_channel = unpack_int_value (en, INT_TYPE_SOUND_CHANNEL);

			raw->sound_locality = unpack_int_value (en, INT_TYPE_SOUND_LOCALITY);

			raw->valid_sound_effect = unpack_int_value (en, INT_TYPE_VALID_SOUND_EFFECT);

			raw->looping = unpack_int_value (en, INT_TYPE_SOUND_EFFECT_LOOPING);

			raw->panning = unpack_int_value (en, INT_TYPE_SOUND_EFFECT_PANNING);

			//
			// link into system
			//

			// sound effect needs a parent
			//ASSERT (raw->eff.special_effect_link.parent);

			if (unpack_int_value (en, INT_TYPE_VALID))
			{
				insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL);
			}

			#if DEBUG_MODULE

			debug_log ("SE_PACK: Unpacked %d - Sub-type %d", get_local_entity_safe_index (en), raw->eff.sub_type);

			#endif

			break;
		}
		////////////////////////////////////////
		case PACK_MODE_BROWSE_SESSION:
		////////////////////////////////////////
		{
			break;
		}
		////////////////////////////////////////
		case PACK_MODE_UPDATE_ENTITY:
		////////////////////////////////////////
		{
			//
			// always use access functions to set the data
			//

			break;
		}
	}
}
Beispiel #25
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:
      ////////////////////////////////////////
		{
			break;
		}
      ////////////////////////////////////////
      case PACK_MODE_CLIENT_SESSION:
      ////////////////////////////////////////
      {
         int
            index;

         pilot
            *raw;

         //
         // create entity
         //

         index = unpack_entity_safe_index ();

         en = get_free_entity (index);

         set_local_entity_type (en, type);

         raw = malloc_fast_mem (sizeof (pilot));

         set_local_entity_data (en, raw);

         memset (raw, 0, sizeof (pilot));

         //
         // unpack data (in exactly the same order as the data was packed)
         //

         raw->sub_type = unpack_int_value (en, INT_TYPE_ENTITY_SUB_TYPE);

         unpack_string (en, STRING_TYPE_PILOTS_NAME, raw->pilots_name);

         raw->rank = unpack_int_value (en, INT_TYPE_PILOT_RANK);

         raw->kills = unpack_int_value (en, INT_TYPE_KILLS);

         raw->unique_id = unpack_int_value (en, INT_TYPE_UNIQUE_ID);

			raw->crew_role = CREW_ROLE_PILOT;

         unpack_list_root (en, LIST_TYPE_PILOT_LOCK, &raw->pilot_lock_root);

         unpack_list_link (en, LIST_TYPE_AIRCREW, &raw->aircrew_link);

         unpack_list_link (en, LIST_TYPE_PILOT, &raw->pilot_link);

         unpack_list_link (en, LIST_TYPE_PLAYER_TASK, &raw->player_task_link);

         raw->side = unpack_int_value (en, INT_TYPE_SIDE);

			raw->difficulty_level = unpack_int_value (en, INT_TYPE_DIFFICULTY_LEVEL);

         break;
      }
      ////////////////////////////////////////
      case PACK_MODE_BROWSE_SESSION:
      ////////////////////////////////////////
      {
         int
            index;

         pilot
            *raw;

         //
         // create entity
         //

         index = unpack_entity_safe_index ();

         en = get_free_entity (index);

         set_local_entity_type (en, type);

         raw = malloc_fast_mem (sizeof (pilot));

         set_local_entity_data (en, raw);

         memset (raw, 0, sizeof (pilot));

         //
         // unpack data (in exactly the same order as the data was packed)
         //

         raw->sub_type = unpack_int_value (en, INT_TYPE_ENTITY_SUB_TYPE);

         unpack_string (en, STRING_TYPE_PILOTS_NAME, raw->pilots_name);

         raw->rank = unpack_int_value (en, INT_TYPE_PILOT_RANK);

         raw->kills = unpack_int_value (en, INT_TYPE_KILLS);

         raw->unique_id = unpack_int_value (en, INT_TYPE_UNIQUE_ID);

			raw->crew_role = CREW_ROLE_PILOT;

			// aircrew_link

         unpack_list_link (en, LIST_TYPE_PILOT, &raw->pilot_link);

         raw->side = unpack_int_value (en, INT_TYPE_SIDE);

         break;
      }
      ////////////////////////////////////////
      case PACK_MODE_UPDATE_ENTITY:
      ////////////////////////////////////////
      {
         //
         // always use access functions to set the data
         //

         break;
      }
   }
}
Beispiel #26
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 #27
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);
}