Esempio n. 1
0
static void destroy_remote (entity *en)
{
	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_DESTROY, en);

	#endif

	transmit_entity_comms_message (ENTITY_COMMS_DESTROY, en);
}
Esempio n. 2
0
static void set_remote_float_value (entity *en, float_types type, float value)
{
	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_FLOAT_VALUE, en, type, value);

	#endif

	transmit_entity_comms_message (ENTITY_COMMS_FLOAT_VALUE, en, type, value);
}
Esempio n. 3
0
static void destroy_client_family (entity *en)
{
	#if DEBUG_MODULE >= 2

	debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_DESTROY_FAMILY, en);

	#endif

	transmit_entity_comms_message (ENTITY_COMMS_DESTROY_FAMILY, en);
}
Esempio n. 4
0
static void kill_remote (entity *en)
{
	#if DEBUG_MODULE >= 2

	debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_kill, en);

	#endif

	transmit_entity_comms_message (ENTITY_COMMS_KILL, en);
}
Esempio n. 5
0
static void destroy_local (entity *en)
{
	regen
		*raw;

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

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_DESTROY, en);

	#endif

	raw = (regen *) get_local_entity_data (en);

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

	ASSERT (!raw->member_root.first_child);

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

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

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_CURRENT_WAYPOINT);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_REGEN);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_UPDATE);

	////////////////////////////////////////
	//
	// FREE ENTITY DATA
	//
	////////////////////////////////////////

	free_mem (raw);

	set_free_entity (en);
}
Esempio n. 6
0
static void set_remote_string (entity *en, string_types type, const char *s)
{
	ASSERT (s);

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_STRING, en, type, s);

	#endif

	transmit_entity_comms_message (ENTITY_COMMS_STRING, en, type, s);
}
Esempio n. 7
0
static void destroy_local (entity *en)
{
	division
		*raw;

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

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_DESTROY, en);

	#endif

	raw = (division *) get_local_entity_data (en);

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

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

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

	unlink_local_entity_children (en, LIST_TYPE_DIVISION);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_DIVISION);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_DIVISION_HEADQUARTERS);

	////////////////////////////////////////
	//
	// FREE ENTITY DATA
	//
	////////////////////////////////////////

	free_mem (raw);

	set_free_entity (en);
}
Esempio n. 8
0
static void destroy_local (entity *en)
{
	sprite
		*raw;

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

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_DESTROY, en);

	#endif

	raw = (sprite *) get_local_entity_data (en);

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

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

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

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_SECTOR);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_UPDATE);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_SPECIAL_EFFECT);

	////////////////////////////////////////
	//
	// FREE ENTITY DATA
	//
	////////////////////////////////////////

	free_mem (raw);

	set_free_entity (en);
}
Esempio n. 9
0
static void destroy_local (entity *en)
{
	bridge
		*raw;

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

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_DESTROY, en);

	debug_log ("BR_DSTRY: destroying bridge %d", get_local_entity_index (en));

	#endif

	raw = get_local_entity_data (en);

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

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

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

	

	destroy_local_entity_children (en, LIST_TYPE_SEGMENT);

	////////////////////////////////////////
	//
	// FREE ENTITY DATA
	//
	////////////////////////////////////////

	free_mem (raw);

	set_free_entity (en);
}
Esempio n. 10
0
void pack_entity_safe_index (int index)
{
	ASSERT ((index == ENTITY_INDEX_DONT_CARE) || ((index >= 0) && (index < number_of_entities)));

	#if (DEBUG_MODULE_PACK_ALL)

	debug_log_entity_args (ENTITY_DEBUG_PACK, ENTITY_DEBUG_ENTITY_INDEX, NULL, index);

	#endif

	pack_signed_data (index, NUM_ENTITY_INDEX_PACK_BITS);
}
Esempio n. 11
0
static void set_remote_vec3d (entity *en, vec3d_types type, vec3d *v)
{
	ASSERT (v);

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_VEC3D, en, type, v);

	#endif

	transmit_entity_comms_message (ENTITY_COMMS_VEC3D, en, type, v);
}
Esempio n. 12
0
static void set_local_raw_int_value (entity *en, int_types type, int value)
{
	vehicle
		*raw;

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_INT_VALUE, en, type, value);

	#endif

	raw = (vehicle *) get_local_entity_data (en);

	switch (type)
	{
		////////////////////////////////////////
		case INT_TYPE_OPERATIONAL_STATE:
		////////////////////////////////////////
		{

			raw->operational_state = value;

			break;
		}
		////////////////////////////////////////
		case INT_TYPE_SELECTED_WEAPON:
		////////////////////////////////////////
		{
			raw->selected_weapon = value;

			break;
		}
		////////////////////////////////////////
		case INT_TYPE_WEAPON_CONFIG_TYPE:
		////////////////////////////////////////
		{
			raw->weapon_config_type = (weapon_config_types) value;

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

			break;
		}
	}
}
Esempio n. 13
0
static entity *create_remote (entity_types type, int index, char *pargs)
{
	validate_remote_create_entity_index (index);

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_REMOTE, ENTITY_DEBUG_CREATE, NULL, type, index);

	#endif

	transmit_entity_comms_message (ENTITY_COMMS_CREATE, NULL, type, index, pargs);

	return (NULL);
}
Esempio n. 14
0
static void set_local_float_value (entity *en, float_types type, float value)
{
	site_updatable
		*raw;

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_FLOAT_VALUE, en, type, value);

	#endif

	raw = get_local_entity_data (en);

	switch (type)
	{
		////////////////////////////////////////
		case FLOAT_TYPE_LOADING_DOOR_STATE:
		////////////////////////////////////////
		{
			raw->loading_door_state = value;

			break;
		}
		////////////////////////////////////////
		case FLOAT_TYPE_RADAR_ROTATION_STATE:
		////////////////////////////////////////
		{
			raw->radar_rotation_state = value;

			break;
		}
		////////////////////////////////////////
		case FLOAT_TYPE_LOADING_DOOR_TIMER:
		////////////////////////////////////////
		{
			raw->loading_door_timer = value;

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

			break;
		}
	}
}
Esempio n. 15
0
void pack_entity_type (entity_types type)
{
	ASSERT ((type >= 0) && (type < NUM_ENTITY_TYPES));

	#if (DEBUG_MODULE_PACK_ONE || DEBUG_MODULE_PACK_ALL)

	if (entity_type_database[type].debug_pack)
	{
		debug_log_entity_args (ENTITY_DEBUG_PACK, ENTITY_DEBUG_ENTITY_TYPE, NULL, type);
	}

	#endif

	pack_unsigned_data (type, NUM_ENTITY_TYPE_PACK_BITS);
}
Esempio n. 16
0
static void set_local_attitude_angles (entity *en, float heading, float pitch, float roll)
{
	camera
		*raw;

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_ATTITUDE_ANGLES, en, heading, pitch, roll);

	#endif

	raw = get_local_entity_data (en);

	get_3d_transformation_matrix (raw->attitude, heading, pitch, roll);
}
Esempio n. 17
0
static void set_local_ptr_value (entity *en, ptr_types type, void *ptr)
{
	group
		*raw;

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_PTR_VALUE, en, type, ptr);

	#endif

	raw = (group *) get_local_entity_data (en);

	switch (type)
	{
		////////////////////////////////////////
		case PTR_TYPE_GROUP_LEADER:
		////////////////////////////////////////
		{
			entity
				*member;
				
			//
			// make an entity group leader by removing it from the member list, and inserting it at the front
			//

			member = (entity *) ptr;

			ASSERT (member);

			ASSERT (get_local_entity_parent (member, LIST_TYPE_MEMBER) == en);
	
			delete_local_entity_from_parents_child_list (member, LIST_TYPE_MEMBER);

			insert_local_entity_into_parents_child_list (member, LIST_TYPE_MEMBER, en, NULL);

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

			break;
		}
	}
}
Esempio n. 18
0
static void set_local_attitude_matrix (entity *en, matrix3x3 attitude)
{
	camera
		*raw;

	ASSERT (attitude);

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_ATTITUDE_MATRIX, en, attitude);

	#endif

	raw = get_local_entity_data (en);

	memcpy (raw->attitude, attitude, sizeof (matrix3x3));
}
Esempio n. 19
0
static void set_local_vec3d (entity *en, vec3d_types type, vec3d *v)
{
	guide
		*raw;

	ASSERT (v);

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_VEC3D, en, type, v);

	#endif

	raw = get_local_entity_data (en);

	switch (type)
	{
		////////////////////////////////////////
		case VEC3D_TYPE_POSITION:
		////////////////////////////////////////
		{
			raw->position = *v;

			break;
		}
		////////////////////////////////////////
		case VEC3D_TYPE_RELATIVE_POSITION:
		////////////////////////////////////////
		{
			raw->position = *v;			// No - this isn't a cut'n'paste error !!

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

			break;
		}
	}
}
Esempio n. 20
0
int unpack_entity_safe_index (void)
{
	int
		index;

	index = unpack_signed_data (NUM_ENTITY_INDEX_PACK_BITS);

	ASSERT ((index == ENTITY_INDEX_DONT_CARE) || ((index >= 0) && (index < number_of_entities)));

	#if (DEBUG_MODULE_PACK_ALL)

	debug_log_entity_args (ENTITY_DEBUG_UNPACK, ENTITY_DEBUG_ENTITY_INDEX, NULL, index);

	#endif

	//debug_log ("EN_HEAP: index %d", index);

	return (index);
}
Esempio n. 21
0
string_types unpack_string_type (void)
{
	string_types
		type;

	type = (string_types) unpack_unsigned_data (NUM_STRING_TYPE_PACK_BITS);

	ASSERT ((type >= 0) && (type < NUM_STRING_TYPES));

	#if (DEBUG_MODULE_PACK_ONE || DEBUG_MODULE_PACK_ALL)

	if (string_type_database[type].debug_pack)
	{
		debug_log_entity_args (ENTITY_DEBUG_UNPACK, ENTITY_DEBUG_STRING_TYPE, NULL, type);
	}

	#endif

	return (type);
}
Esempio n. 22
0
static void set_local_float_value (entity *en, float_types type, float value)
{
	bridge
		*raw;

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_FLOAT_VALUE, en, type, value);

	#endif

	raw = (bridge *) get_local_entity_data (en);

	switch (type)
	{
		////////////////////////////////////////
		case FLOAT_TYPE_PITCH:
		////////////////////////////////////////
		{
			raw->pitch = value;

			break;
		}
		////////////////////////////////////////
		case FLOAT_TYPE_SCALE:
		////////////////////////////////////////
		{
			raw->scale = value;

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

			break;
		}
	}
}
Esempio n. 23
0
static void set_local_int_value (entity *en, int_types type, int value)
{
	particle
		*raw;

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_INT_VALUE, en, type, value);

	#endif

	raw = get_local_entity_data (en);

	switch (type)
	{
		////////////////////////////////////////
		case INT_TYPE_OBJECT_3D_SHAPE:
		////////////////////////////////////////
		{
			raw->object_3d_shape = value;

			break;
		}
		////////////////////////////////////////
		case INT_TYPE_PARTICLE_COUNT:
		////////////////////////////////////////
		{
			raw->particle_count = value;

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

			break;
		}
	}
}
Esempio n. 24
0
static void set_local_int_value (entity *en, int_types type, int value)
{
	weapon
		*raw;

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_INT_VALUE, en, type, value);

	#endif

	raw = get_local_entity_data (en);

	switch (type)
	{
		////////////////////////////////////////
		case INT_TYPE_WEAPON_BURST_SIZE:
		////////////////////////////////////////
		{
			raw->burst_size = value;

			break;
		}
		////////////////////////////////////////
		case INT_TYPE_WEAPON_KILL_CODE:
		////////////////////////////////////////
		{
			raw->kill_code = value;

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

			break;
		}
	}
}
Esempio n. 25
0
static void set_local_int_value (entity *en, int_types type, int value)
{
	smoke_list
		*raw;

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_INT_VALUE, en, type, value);

	#endif

	raw = get_local_entity_data (en);

	switch (type)
	{
		////////////////////////////////////////
		case INT_TYPE_INFINITE_GENERATOR:
		////////////////////////////////////////
		{
			raw->infinite_generator = value;

			break;
		}
		////////////////////////////////////////
		case INT_TYPE_SMOKE_TYPE:
		////////////////////////////////////////
		{
			raw->smoke_type = value;

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

			break;
		}
	}
}
Esempio n. 26
0
static void set_local_ptr_value (entity *en, ptr_types type, void *ptr)
{
	waypoint
		*raw;

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_PTR_VALUE, en, type, ptr);

	#endif

	raw = get_local_entity_data (en);

	switch (type)
	{
		////////////////////////////////////////
		case PTR_TYPE_POSITION_ENTITY:
		////////////////////////////////////////
		{
			if (ptr)
			{
				debug_fatal ("WP_PTR: REMOVE");
			}
			raw->position_entity = ptr;

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

			break;
		}
	}
}
Esempio n. 27
0
static void set_local_raw_vec3d (entity *en, vec3d_types type, vec3d *v)
{
	task
		*raw;

	ASSERT (v);

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_VEC3D, en, type, v);

	#endif

	raw = get_local_entity_data (en);

	switch (type)
	{
		////////////////////////////////////////
		case VEC3D_TYPE_POSITION:
		////////////////////////////////////////
		{

			raw->position = *v;

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

			break;
		}
	}
}
Esempio n. 28
0
static void set_local_vec3d (entity *en, vec3d_types type, vec3d *v)
{
	object
		*raw;

	ASSERT (v);

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_VEC3D, en, type, v);

	#endif

	raw = (object *) get_local_entity_data (en);

	switch (type)
	{
		////////////////////////////////////////
		case VEC3D_TYPE_OBJECT_SCALING:
		////////////////////////////////////////
		{

			raw->object_scaling = *v;

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

			break;
		}
	}
}
Esempio n. 29
0
void pack_string (entity *en, string_types type, const char *s)
{
	ASSERT ((type >= 0) && (type < NUM_STRING_TYPES));

	ASSERT (s);

	#if (DEBUG_MODULE_PACK_ONE || DEBUG_MODULE_PACK_ALL)

	if (string_type_database[type].debug_pack)
	{
		debug_log_entity_args (ENTITY_DEBUG_PACK, ENTITY_DEBUG_STRING, en, type, s);
	}

	#endif

	ASSERT (strlen (s) <= (unsigned)get_string_type_max_length (type));

	while (*s)
	{
		pack_unsigned_data ((unsigned char)*s++, 8);//DEBUG//
	}

	pack_unsigned_data (0, 8);//DEBUG//
}
Esempio n. 30
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);
}