Exemplo n.º 1
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);
}
Exemplo n.º 2
0
void kill_routed_vehicles_on_segment (entity *en)
{
	float
		range,
		damage_radius;

	int
		sx,
		sz;

	vec3d
		*segment_position,
		*object_position;

	entity
		*sect,
		*object;

	bridge_segment_types
		bridge_segment_type;

	//
	// get damage radius ( plus a little overlap )
	//

	bridge_segment_type = (bridge_segment_types) get_local_entity_int_value (en, INT_TYPE_BRIDGE_SEGMENT_TYPE);

	damage_radius = bridge_segment_length (bridge_segment_type);

	if (damage_radius == 0.0)
	{
		return;
	}

	damage_radius *= ROOT2;

	//
	// get sector which the segment is in ( don't bother with adjacent sectors for now )
	//

	segment_position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

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

	sect = get_local_raw_sector_entity (sx, sz);

	//
	// search for routed vehicles
	//

	object = get_local_entity_first_child (sect, LIST_TYPE_SECTOR);

	while (object)
	{
		if (object->type == ENTITY_TYPE_ROUTED_VEHICLE)
		{
			if (get_local_entity_int_value (object, INT_TYPE_ALIVE))
			{
				object_position = get_local_entity_vec3d_ptr (object, VEC3D_TYPE_POSITION);

				if (object_position)
				{
					range = get_approx_3d_range (segment_position, object_position);

					if (range < damage_radius)
					{
						kill_client_server_entity (object);
					}
				}
			}
		}

		object = get_local_entity_child_succ (object, LIST_TYPE_SECTOR);
	}
}
Exemplo n.º 3
0
void show_base_page (entity *base, int force_update)
{
    entity
    *previous;

    vec3d
    *pos;

    int
    x, z;

    char
    s [128];

    ASSERT (base);

    ASSERT (get_local_entity_type (base) == ENTITY_TYPE_KEYSITE);

    if (force_update)
    {
        previous = NULL;
    }
    else
    {
        previous = get_local_entity_safe_ptr (get_ui_object_item_number (campaign_page [CAMPAIGN_PAGE_BASE]));
    }

    pos = get_local_entity_vec3d_ptr (base, VEC3D_TYPE_POSITION);

    ASSERT (pos);

    //
    // NAME
    //

    set_ui_object_text (base_page_title, get_local_entity_string (base, STRING_TYPE_KEYSITE_NAME));

    //
    // TYPE
    //

    set_ui_object_text (base_page_type_box, get_trans (get_local_entity_string (base, STRING_TYPE_FULL_NAME)));

    //
    // LOCATION
    //

    get_x_sector (x, pos->x);
    get_z_sector (z, pos->z);

    sprintf (s, "[%03d, %03d]", x, z);

    set_ui_object_text (base_page_sector_box, s);

    //
    // 3D WINDOW
    //

    set_ui_object_item_number (page_3d_area, get_local_entity_index (base));

    if (base != previous)
    {
        page_3d_heading = 0.0;
        page_3d_pitch = (PI * 0.25);
        page_3d_distance = max (50.0, get_local_entity_float_value (base, FLOAT_TYPE_RECON_DISTANCE));
    }

    //
    // 2D MAP
    //

    set_ui_object_item_number (page_map_area, get_local_entity_index (base));

    if (base != previous)
    {
        page_map_dimensions.x = pos->x;
        page_map_dimensions.z = pos->z;

        page_map_dimensions.subject_entity = base;
    }

    //

    display_campaign_page (CAMPAIGN_PAGE_BASE, get_local_entity_index (base), TRUE);
}
Exemplo n.º 4
0
int debug_engage_targets_in_area (entity *group, vec3d *target_point, float radius, unsigned int target_type)
{
	//
	// Engages all targets in area, regardless of side 
	//

	int
		sx,
		sz,
		min_sector_x,
		max_sector_x,
		min_sector_z,
		max_sector_z;

	entity
		*new_task,
		*objective,
		*target_sector;

	entity_sides
		side;

	sector
		*raw;

	float
		range,
		temp_x,
		temp_z;

	vec3d
		*pos;

	new_task = NULL;

	temp_x = target_point->x - radius;
	temp_z = target_point->z - radius;

	get_x_sector (min_sector_x, temp_x);
	get_z_sector (min_sector_z, temp_z);

	temp_x = target_point->x + radius;
	temp_z = target_point->z + radius;

	get_x_sector (max_sector_x, temp_x);
	get_z_sector (max_sector_z, temp_z);

	min_sector_x = bound (min_sector_x, MIN_MAP_X_SECTOR, MAX_MAP_X_SECTOR);
	max_sector_x = bound (max_sector_x, MIN_MAP_X_SECTOR, MAX_MAP_X_SECTOR);

	min_sector_z = bound (min_sector_z, MIN_MAP_Z_SECTOR, MAX_MAP_Z_SECTOR);
	max_sector_z = bound (max_sector_z, MIN_MAP_Z_SECTOR, MAX_MAP_Z_SECTOR);

	side = (entity_sides) get_local_entity_int_value (group, INT_TYPE_SIDE);

	for (sz = min_sector_z; sz <= max_sector_z; sz ++)
	{
		for (sx = min_sector_x; sx <= max_sector_x; sx ++)
		{
			target_sector = get_local_raw_sector_entity (sx, sz);

			raw = (sector *) get_local_entity_data (target_sector);

			//
			// search for viable targets
			//

			objective = raw->sector_root.first_child;

			while (objective)
			{
				//
				// criteria for target is that it is a valid target, and not in your group
				//

				if (get_local_entity_int_value (objective, INT_TYPE_TARGET_TYPE) == target_type)
				{
					if (get_local_entity_int_value (objective, INT_TYPE_ALIVE))
					{
						if ((!get_local_entity_int_value (objective, INT_TYPE_IDENTIFY_MOBILE)) || (get_local_entity_parent (objective, LIST_TYPE_MEMBER) != group))
						{
							pos = get_local_entity_vec3d_ptr (objective, VEC3D_TYPE_POSITION);
	
							range = get_approx_2d_range (target_point, pos);
	
							if (range <= radius)
							{
	
								new_task = create_engage_task (group, objective, group, FALSE);
	
								if (new_task)
								{
									assign_task_to_group (group, new_task, TASK_ASSIGN_NO_MEMBERS);
								}
							}
						}
					}
				}

				objective = get_local_entity_child_succ (objective, LIST_TYPE_SECTOR);
			}
		}
	}

	if (assign_engage_tasks_to_group (group, TASK_ASSIGN_ALL_MEMBERS) != TASK_ASSIGN_ALL_MEMBERS)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
Exemplo n.º 5
0
static void set_local_vec3d (entity *en, vec3d_types type, vec3d *v)
{
	keysite
		*raw;

	ASSERT (v);

	#if DEBUG_MODULE

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

	#endif

	raw = (keysite *) get_local_entity_data (en);

	switch (type)
	{
		////////////////////////////////////////
		case VEC3D_TYPE_POSITION:
		////////////////////////////////////////
		{
			int
				old_x_sec,
				old_z_sec,
				new_x_sec,
				new_z_sec;

			entity
				*parent;

			get_x_sector (old_x_sec, raw->position.x);
			get_z_sector (old_z_sec, raw->position.z);

			get_x_sector (new_x_sec, v->x);
			get_z_sector (new_z_sec, v->z);

			if ((old_x_sec != new_x_sec) || (old_z_sec != new_z_sec))
			{
				delete_local_entity_from_parents_child_list (en, LIST_TYPE_SECTOR);

				raw->position = *v;

				parent = get_local_raw_sector_entity (new_x_sec, new_z_sec);

				insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, parent, NULL);
			}
			else
			{
				raw->position = *v;
			}

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

			break;
		}
	}
}
Exemplo n.º 6
0
void save_screen_image_and_viewpoint_data (void)
{
	char
		filename[100],
		large_image_filename[100],
		small_image_filename[100],
		viewpoint_data_filename[100];

	FILE
		*fp;

	int
		x_sec,
		z_sec;

	//
	// find first screen shot index
	//

	if (!found_first_screen_shot_index)
	{
		while (TRUE)
		{
			sprintf (large_image_filename, "%sIMAGE%03d.TGA", LARGE_IMAGE_PATH, screen_shot_index);

			if (file_exist (large_image_filename))
			{
				screen_shot_index++;

				if (screen_shot_index == 1000)
				{
					break;
				}
			}
			else
			{
				found_first_screen_shot_index = TRUE;

				break;
			}
		}
	}

	//
	// write screen files and viewpoint data file
	//

	if (screen_shot_index <= MAX_SCREEN_SHOT_INDEX)
	{
		sprintf (filename, "IMAGE%03d", screen_shot_index);

		debug_log ("Saving screen image (%s)", filename);

		sprintf (large_image_filename, "%s%s.TGA", LARGE_IMAGE_PATH, filename);

		sprintf (small_image_filename, "%s%s.TGA", SMALL_IMAGE_PATH, filename);

		sprintf (viewpoint_data_filename, "%s%s.TXT", VIEWPOINT_DATA_PATH, filename);

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

		if (lock_screen (video_screen))
		{

			save_tga_screen_with_thumbnail (large_image_filename, small_image_filename);

			unlock_screen (video_screen);
		}

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

		fp = safe_fopen (viewpoint_data_filename, "w");

		fprintf (fp, "Image viewpoint data:\n\n");

		fprintf (fp, "Map           : unknown\n");

		fprintf (fp, "X             : %.2f\n", main_vp.x);
		fprintf (fp, "Y             : %.2f\n", main_vp.y);
		fprintf (fp, "Z             : %.2f\n", main_vp.z);

		get_terrain_3d_sector (main_vp.x, main_vp.z, &x_sec, &z_sec);

		fprintf (fp, "X sector (3D) : %d\n", x_sec);
		fprintf (fp, "Z sector (3D) : %d\n", z_sec);

		get_x_sector (x_sec, main_vp.x);
		get_z_sector (z_sec, main_vp.z);

		fprintf (fp, "X sector (AI) : %d\n", x_sec);
		fprintf (fp, "Z sector (AI) : %d\n", z_sec);

		fprintf (fp, "Heading (degs): %.2f\n", deg (get_heading_from_attitude_matrix (main_vp.attitude)));
		fprintf (fp, "Pitch (degs)  : %.2f\n", deg (get_pitch_from_attitude_matrix (main_vp.attitude)));
		fprintf (fp, "Roll (degs)   : %.2f\n", deg (get_roll_from_attitude_matrix (main_vp.attitude)));

		safe_fclose (fp);

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

		screen_shot_index++;
	}
	else
	{
		debug_colour_log (DEBUG_COLOUR_RED, "Exceeded screen image limit");
	}
}
Exemplo n.º 7
0
int group_task_specific_retaliation_checks (entity *group, entity *aggressor, int assisted)
{
	entity
		*task,
		*objective;

	task_roe_types
		roe;

	entity_sides
		side;

	vec3d
		*group_pos,
		*objective_pos,
		*aggressor_pos;

	int
		sx,
		sz;

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	ASSERT (group);

	ASSERT (aggressor);

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

		if (!task)
		{
			return FALSE;
		}

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

		roe = get_local_entity_int_value (task, INT_TYPE_RULES_OF_ENGAGEMENT);

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

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

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

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

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

						return TRUE;
					}

					side = get_local_entity_int_value (group, INT_TYPE_SIDE);

					group_pos = get_local_entity_vec3d_ptr (group, VEC3D_TYPE_POSITION);

					ASSERT (group_pos);

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

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

						return TRUE;
					}
				}

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

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

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

					return TRUE;
				}

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

					return TRUE;
				}

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

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

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

				return TRUE;
			}
		}

		return FALSE;
	}
	else
	{
		return TRUE;
	}
}
Exemplo n.º 8
0
void debug_log_entity_args (entity_debug_modes mode, entity_debug_args arg, entity *en, ...)
{
	va_list
		pargs;

	////////////////////////////////////////
	//
	// trap remote args in single player game
	//
	////////////////////////////////////////

	if (!debug_log_entity_args_enabled)
	{
		return;
	}

	if (mode == ENTITY_DEBUG_REMOTE)
	{
		if (direct_play_get_comms_mode () == DIRECT_PLAY_COMMS_MODE_NONE)
		{
			return;
		}
	}

	////////////////////////////////////////
	//
	// sort debug log text
	//
	////////////////////////////////////////

	va_start (pargs, en);

	switch (arg)
	{
		////////////////////////////////////////
		case ENTITY_DEBUG_ATTITUDE_ANGLES:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, float heading, float pitch, float roll)
			//

			float
				heading,
				pitch,
				roll;

			heading = va_arg (pargs, double);

			pitch = va_arg (pargs, double);

			roll = va_arg (pargs, double);

			debug_log_text (mode, en, "attitude angles (h = %.3f, p = %.3f, r = %.3f)", deg (heading), deg (pitch), deg (roll));

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_ATTITUDE_MATRIX:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, matrix3x3 attitude)
			//

			matrix3x3
				*attitude;

			float
				heading,
				pitch,
				roll;

			attitude = va_arg (pargs, matrix3x3 *);

			ASSERT (attitude);

			heading = get_heading_from_attitude_matrix (*attitude);

			pitch = get_pitch_from_attitude_matrix (*attitude);

			roll = get_roll_from_attitude_matrix (*attitude);

			debug_log_text (mode, en, "attitude matrix (h = %.3f, p = %.3f, r = %.3f)", deg (heading), deg (pitch), deg (roll));

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_CHAR_TYPE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, char_types type)
			//

			char_types
				type;

			type = va_arg (pargs, char_types);

			debug_log_text (mode, NULL, "char type = %s", get_char_type_name (type));

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_CHAR_VALUE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, char_types type, char value)
			//

			char_types
				type;

			char
				value;

			type = va_arg (pargs, char_types);

			value = va_arg (pargs, int);

			debug_log_text (mode, en, "%s = %c", get_char_type_name (type), value);

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_CREATE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, entity_types type, int index)
			//

			entity_types
				type;

			int
				index;

			type = va_arg (pargs, entity_types);

			index = va_arg (pargs, int);

			debug_log_text (mode, NULL, "create %s (index = %d): ", get_entity_type_name (type), index);

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_DESTROY:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en)
			//

			debug_log_text (mode, en, "destroy");

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_DESTROY_FAMILY:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en)
			//

			debug_log_text (mode, en, "destroy family");

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_ENTITY_ATTRIBUTE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, entity_attributes attr)
			//

			entity_attributes
				attr;

			attr = va_arg (pargs, entity_attributes);

			debug_log_text (mode, NULL, "entity attribute = %s", get_entity_attribute_name (attr));

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_ENTITY_COMMS_MESSAGE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, entity_comms_messages message)
			//

			entity_comms_messages
				message;

			message = va_arg (pargs, entity_comms_messages);

			debug_log_text (mode, NULL, "entity comms message = %s", get_entity_comms_message_name (message));

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_ENTITY_INDEX:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, int index)
			//

			int
				index;

			index = va_arg (pargs, int);

			debug_log_text (mode, en, "entity index = %d", index);

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_ENTITY_TYPE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, entity_types type)
			//

			entity_types
				type;

			type = va_arg (pargs, entity_types);

			debug_log_text (mode, en, "entity type = %s", get_entity_type_name (type));

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_FLOAT_TYPE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, float_types type)
			//

			float_types
				type;

			type = va_arg (pargs, float_types);

			debug_log_text (mode, NULL, "float type = %s", get_float_type_name (type));

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_FLOAT_VALUE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, float_types type, float value)
			//

			float_types
				type;

			float
				value;

			type = va_arg (pargs, float_types);

			value = va_arg (pargs, double);

			debug_log_text (mode, en, "%s = %.3f", get_float_type_name (type), value);

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_INT_TYPE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, int_types type)
			//

			int_types
				type;

			type = va_arg (pargs, int_types);

			debug_log_text (mode, NULL, "int type = %s", get_int_type_name (type));

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_INT_VALUE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, int_types type, int value)
			//

			int_types
				type;

			int
				value;

			type = va_arg (pargs, int_types);

			value = va_arg (pargs, int);

			debug_log_text (mode, en, "%s = %d", get_int_type_name (type), value);

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_KILL:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en)
			//

			debug_log_text (mode, en, "kill");

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_LIST_TYPE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, list_types type)
			//

			list_types
				type;

			type = va_arg (pargs, list_types);

			debug_log_text (mode, NULL, "list type = %s", get_list_type_name (type));

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_LIST_TYPE_CHILD_PRED:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, list_types type, entity *child_pred)
			//

			list_types
				type;

			entity
				*child_pred;

			int
				index;

			type = va_arg (pargs, list_types);

			child_pred = va_arg (pargs, entity *);

			index = get_local_entity_safe_index (child_pred);

			debug_log_text (mode, en, "%s child pred index = %d", get_list_type_name (type), index);

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_LIST_TYPE_CHILD_SUCC:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, list_types type, entity *child_succ)
			//

			list_types
				type;

			entity
				*child_succ;

			int
				index;

			type = va_arg (pargs, list_types);

			child_succ = va_arg (pargs, entity *);

			index = get_local_entity_safe_index (child_succ);

			debug_log_text (mode, en, "%s child succ index = %d", get_list_type_name (type), index);

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_LIST_TYPE_FIRST_CHILD:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, list_types type, entity *first_child)
			//

			list_types
				type;

			entity
				*first_child;

			int
				index;

			type = va_arg (pargs, list_types);

			first_child = va_arg (pargs, entity *);

			index = get_local_entity_safe_index (first_child);

			debug_log_text (mode, en, "%s first child index = %d", get_list_type_name (type), index);

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_LIST_TYPE_PARENT:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, list_types type, entity *parent)
			//

			list_types
				type;

			entity
				*parent;

			int
				index;

			type = va_arg (pargs, list_types);

			parent = va_arg (pargs, entity *);

			index = get_local_entity_safe_index (parent);

			debug_log_text (mode, en, "%s parent index = %d", get_list_type_name (type), index);

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_PTR_TYPE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, ptr_types type)
			//

			ptr_types
				type;

			type = va_arg (pargs, ptr_types);

			debug_log_text (mode, NULL, "ptr type = %s", get_ptr_type_name (type));

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_PTR_VALUE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, ptr_types type, void *ptr)
			//

			ptr_types
				type;

			void
				*ptr;

			type = va_arg (pargs, ptr_types);

			ptr = va_arg (pargs, void *);

			debug_log_text (mode, en, "%s = 0x%x", get_ptr_type_name (type), ptr);

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_STRING_TYPE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, string_types type)
			//

			string_types
				type;

			type = va_arg (pargs, string_types);

			debug_log_text (mode, NULL, "string type = %s", get_string_type_name (type));

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_STRING:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, string_types type, char *s)
			//

			string_types
				type;

			char
				*s;

			type = va_arg (pargs, string_types);

			s = va_arg (pargs, char *);

			ASSERT (s);

			debug_log_text (mode, en, "%s = %s", get_string_type_name (type), s);

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_VEC3D_TYPE:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, vec3d_types type)
			//

			vec3d_types
				type;

			type = va_arg (pargs, vec3d_types);

			debug_log_text (mode, NULL, "vec3d type = %s", get_vec3d_type_name (type));

			break;
		}
		////////////////////////////////////////
		case ENTITY_DEBUG_VEC3D:
		////////////////////////////////////////
		{
			//
			// (entity_debug_modes mode, entity_debug_args arg, entity *en, vec3d_types type, vec3d *v)
			//

			vec3d_types
				type;

			vec3d
				*v;

			type = va_arg (pargs, vec3d_types);

			v = va_arg (pargs, vec3d *);

			ASSERT (v);

			if (type == VEC3D_TYPE_POSITION)
			{
				int
					x_sec,
					z_sec;

				get_x_sector (x_sec, v->x);
				get_z_sector (z_sec, v->z);

				debug_log_text (mode, en, "%s = (x = %.3f, y = %.3f, z = %.3f, x sec = %d, z sec = %d)", get_vec3d_type_name (type), v->x, v->y, v->z, x_sec, z_sec);
			}
			else
			{
				debug_log_text (mode, en, "%s = (x = %.3f, y = %.3f, z = %.3f)", get_vec3d_type_name (type), v->x, v->y, v->z);
			}

			break;
		}
		////////////////////////////////////////
		default:
		////////////////////////////////////////
		{
			debug_fatal ("Invalid entity debug arg = %d", arg);

			break;
		}
	}

	va_end (pargs);
}