Exemple #1
0
void restore_local_fixed_entity (entity *en)
{
	int
		object_index;

	entity
		*keysite;

	ASSERT (en);

	//
	// Set alive flag
	//

	ASSERT (!get_local_entity_int_value (en, INT_TYPE_ALIVE));

	set_local_entity_int_value (en, INT_TYPE_ALIVE, TRUE);

	//
	// 3d shape
	//

	object_index = get_local_entity_int_value (en, INT_TYPE_OBJECT_3D_SHAPE);

	set_local_entity_int_value (en, INT_TYPE_OBJECT_3D_SHAPE, get_3d_object_restored_object_index (object_index));

	//
	// Restore damage level (MUST be done AFTER object 3d shape reset)
	//

	set_local_entity_int_value (en, INT_TYPE_DAMAGE_LEVEL, get_local_entity_int_value (en, INT_TYPE_INITIAL_DAMAGE_LEVEL));

	ASSERT (get_local_entity_int_value (en, INT_TYPE_DAMAGE_LEVEL) > 0);

	//
	// Keysite strength
	//

	keysite = get_fixed_structure_keysite_entity (en);

	ASSERT (keysite);
	
	restore_local_entity_importance_to_keysite (en, keysite);
}
Exemple #2
0
static int response_to_unlink_parent (entity_messages message, entity *receiver, entity *sender, va_list pargs)
{
	list_types
		list_type;

	#if DEBUG_MODULE

	debug_log_entity_message (message, receiver, sender, pargs);

	#endif

	list_type = va_arg (pargs, list_types);

	switch (list_type)
	{
		////////////////////////////////////////
		case LIST_TYPE_GUNSHIP_TARGET:
		////////////////////////////////////////
		{
			set_local_entity_int_value (receiver, INT_TYPE_GUNSHIP_RADAR_LOS_CLEAR, FALSE);

			set_local_entity_float_value (receiver, FLOAT_TYPE_AIR_RADAR_CONTACT_TIMEOUT, AIR_RADAR_CONTACT_TIMEOUT_INVALID);

			break;
		}
		////////////////////////////////////////
		case LIST_TYPE_UPDATE:
		////////////////////////////////////////
		{
			set_local_entity_float_value (receiver, FLOAT_TYPE_VIEW_INTEREST_LEVEL, 0.0);

			break;
		}
	}

	return (TRUE);
}
Exemple #3
0
int set_local_division_name (entity *en, char *s)
{
	int
		division_type,
		division_id;

	char
		extension [10],
		id_string [10];

	entity
		*group;

	ASSERT (en);

	ASSERT (s);

	if (get_local_entity_type (en) == ENTITY_TYPE_DIVISION)
	{
		division_id = get_local_entity_int_value (en, INT_TYPE_DIVISION_ID);
	}
	else
	{
		ASSERT (get_local_entity_type (en) == ENTITY_TYPE_GROUP);

		division_id = 1;

		group = en;

		while (get_local_entity_child_succ (group, LIST_TYPE_DIVISION))
		{
			division_id ++;

			group = get_local_entity_child_succ (group, LIST_TYPE_DIVISION);
		}

		if (!get_local_entity_int_value (en, INT_TYPE_AIRCRAFT_GROUP))
		{
			set_local_entity_int_value (en, INT_TYPE_GROUP_CALLSIGN, division_id);
		}
	}

	sprintf (id_string, "%d", division_id);

	//
	// Specify extension after number (bloody English language)
	//	

	get_number_extension (division_id, extension);

	strcat (id_string, extension);

	//
	// Store result
	//
	
	division_type = get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE);
	
	if (get_local_entity_type (en) == ENTITY_TYPE_DIVISION)
	{
		sprintf (s, division_database [division_type].full_name, id_string);
	}
	else
	{
		switch (group_database [division_type].platoon_id_type)
		{
			case PLATOON_ID_NONE:
			{
				sprintf (s, group_database [division_type].platoon_name);

				break;
			}
			case PLATOON_ID_NUMBER:
			{
				sprintf (s, group_database [division_type].platoon_name, id_string);

				break;
			}
			case PLATOON_ID_LETTER:
			{
				sprintf (s, group_database [division_type].platoon_name, ((division_id - 1) + 'A'));

				break;
			}
			case PLATOON_ID_CALLSIGN:
			{
				strcpy (s, get_local_entity_string (en, STRING_TYPE_GROUP_CALLSIGN));

				break;
			}
			case PLATOON_ID_KEYSITE:
			{
				entity
					*keysite,
					*division;

				if (get_local_entity_type (en) == ENTITY_TYPE_GROUP)
				{
					division = get_local_entity_parent (en, LIST_TYPE_DIVISION);
				}
				else
				{
					division = en;
				}

				keysite = get_local_entity_parent (division, LIST_TYPE_DIVISION_HEADQUARTERS);

				ASSERT (keysite);
				
				sprintf (s, group_database [division_type].platoon_name, get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME));

				break;
			}
			default:
			{
				debug_fatal ("Invalid Platoon Id Type %d", group_database [division_type].platoon_id_type);
			}
		}
	}

	return TRUE;
}
Exemple #4
0
static void kill_local (entity *en)
{

    person
    *raw;

    int
    losses;

    entity
    *task,
    *destroy_task,
    *group;

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

#if DEBUG_MODULE >= 2

    debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en);

#endif

    if (!get_local_entity_int_value (en, INT_TYPE_ALIVE))
    {
        return;
    }

    raw = get_local_entity_data (en);

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

    ////////////////////////////////////////
    //
    // KILL
    //
    ////////////////////////////////////////

    // must be done before alive flag set to FALSE
    remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en);

    set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

    // update person object
    damage_person_3d_object (en);

    group = get_local_entity_parent (en, LIST_TYPE_MEMBER);

    ASSERT (group);

    //
    // group losses
    //

    losses = get_local_entity_int_value (group, INT_TYPE_LOSSES);

    losses ++;

    set_local_entity_int_value (group, INT_TYPE_LOSSES, losses);

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

    if (get_comms_model () == COMMS_MODEL_SERVER)
    {
        ////////////////////////////////////////
        //
        // SEND NOTIFY MESSAGES
        //
        ////////////////////////////////////////

        //
        //
        //

        task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT);

        while (task)
        {

            destroy_task = task;

            task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT);

            if (get_local_entity_type (destroy_task) == ENTITY_TYPE_TASK)
            {

#if DEBUG_MODULE

                debug_log ("PS_DSTRY: killing person, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]);

#endif

                notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en);
            }
        }

        //
        // Release landing lock (if any)
        //

        //release_mobile_entity_landing_locks (en);
    }

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

    //
    // person
    //

    //
    // vehicle
    //

    unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

    unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON);

    delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER);

    delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER);

    // gunship_target_link

    // member_link

    // view_link

    delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE);

    //
    // mobile
    //

    //
    // kill weapon sound effects
    //

    kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN);

    //unlink_local_entity_children (en, LIST_TYPE_SPECIAL_EFFECT);

    unlink_local_entity_children (en, LIST_TYPE_TARGET);

    delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK);

    // sector_link

    delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET);

    set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DEAD);

    //
    // Notify Campaign Screen
    //

    notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group);

    //
    // Notify the GROUP that the mobile has been killed  (N.B. must be done AFTER mobile is unlinked from member list)
    //

    if (get_comms_model () == COMMS_MODEL_SERVER)
    {
        notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en);
    }

    ////////////////////////////////////////
    //
    // SPECIAL EFFECTS
    //
    ////////////////////////////////////////

    set_local_entity_float_value (en, FLOAT_TYPE_DEATH_TIMER, calculate_mobile_death_timer_value (en));

    if (get_comms_model () == COMMS_MODEL_SERVER)
    {
        create_client_server_object_killed_explosion_effect (en);
    }
}
Exemple #5
0
aircraft_fire_result aircraft_fire_weapon (entity *en, unsigned int check_flags)
{
	entity
		*target;

	aircraft
		*raw;

	vec3d
		*target_pos,
		en_pos;

	int loal_mode = FALSE;

	ASSERT (en);

	raw = (aircraft *) get_local_entity_data (en);

	//
	// Fire suppressed
	//

	if (check_flags & AIRCRAFT_FIRE_SUPPRESSED)
	{
		if (get_local_entity_int_value (get_session_entity (), INT_TYPE_SUPPRESS_AI_FIRE))
		{
			return AIRCRAFT_FIRE_SUPPRESSED;
		}
	}

	//
	// check weapon
	//

	if (check_flags & AIRCRAFT_FIRE_NO_WEAPON)
	{
		if (get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON) == ENTITY_SUB_TYPE_WEAPON_NO_WEAPON)
		{
			debug_log ("AC_WPN: Fire Weapon Error - NO WEAPON");

			return AIRCRAFT_FIRE_NO_WEAPON;
		}
	}

	//
	// weapon system_ready
	//

	if (check_flags & AIRCRAFT_FIRE_WEAPON_SYSTEM_NOT_READY)
	{
		if (!get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON_SYSTEM_READY))
		{
			debug_log ("AC_WPN: Fire Weapon Error - WEAPON SYSTEM NOT READY");

			return AIRCRAFT_FIRE_WEAPON_SYSTEM_NOT_READY;
		}
	}

//	debug_log("%s: %d", get_sub_type_name(en), get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON));

	//
	// find target
	//

	if (check_flags & AIRCRAFT_FIRE_NO_TARGET)
	{
		target = get_local_entity_parent (en, LIST_TYPE_TARGET);

		if (!target)
		{
			debug_log ("AC_WPN: Fire Weapon Error - NO TARGET");

			return AIRCRAFT_FIRE_NO_TARGET;
		}
	}

	//
	// line of sight checks
	//

	if (check_flags & AIRCRAFT_FIRE_NO_LOS)
	{
		int
			criteria;

		if (get_local_entity_int_value (target, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
		{
			criteria = MOBILE_LOS_CHECK_ALL;
		}
		else
		{
			criteria = MOBILE_LOS_CHECK_COURSE_TERRAIN;
		}

		get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &en_pos);

		target_pos = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION);

		en_pos.y -= (get_local_entity_float_value (en, FLOAT_TYPE_CENTRE_OF_GRAVITY_TO_GROUND_DISTANCE) + 2.0);

		if (!check_position_line_of_sight (en, target, &en_pos, target_pos, (mobile_los_check_criteria) criteria))
		{
			if (get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON) == ENTITY_SUB_TYPE_WEAPON_AGM114L_LONGBOW_HELLFIRE
				&& get_2d_range(&en_pos, target_pos) > weapon_database[ENTITY_SUB_TYPE_WEAPON_AGM114L_LONGBOW_HELLFIRE].min_range_loal)
			{
				debug_log("AC_WPN: Switching to LOAL mode to fire at target without LOS ((Aircraft %s (%d), Target %s (%d))",
									get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_index (en),
									get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target));

				loal_mode = TRUE;
			}
			else
			{
				debug_log ("AC_WPN: Fire Weapon Error - NO LOS (Aircraft %s (%d), Target %s (%d))",
									get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_index (en),
									get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target));

				return AIRCRAFT_FIRE_NO_LOS;
			}
		}
	}

	//
	// Play Speech
	//

	play_aircraft_weapon_launched_speech (en, raw->selected_weapon);

	//
	// Fire weapon
	//

	set_local_entity_int_value(en, INT_TYPE_LOCK_ON_AFTER_LAUNCH, loal_mode);

	launch_client_server_weapon (en, raw->selected_weapon);

	return AIRCRAFT_FIRE_OK;
}
Exemple #6
0
static void destroy_local (entity *en)
{

	helicopter
		*raw;

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

	#if DEBUG_MODULE >= 2

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_DESTROY, en);

	#endif

	raw = get_local_entity_data (en);

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

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

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

	destruct_3d_object (raw->ac.inst3d);

	free_mem (raw->ac.weapon_package_status_array);

	if (raw->ac.sound_effect_data)
	{

		destroy_system_sound_effect (raw->ac.sound_effect_data);
	}

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

	//
	// helicopter
	//

	unlink_local_entity_children (en, LIST_TYPE_GUNSHIP_TARGET);

	unlink_local_entity_children (en, LIST_TYPE_PADLOCK);

	//
	// aircraft
	//

	unlink_local_entity_children (en, LIST_TYPE_AIRCREW);

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_GUNSHIP_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MOVEMENT_DEPENDENT);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_VIEW);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE);

	//
	// mobile
	//

	unlink_local_entity_children (en, LIST_TYPE_SPECIAL_EFFECT);

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_SECTOR);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_UPDATE);

	//
	//
	//

	if (en == get_gunship_entity ())
	{
		set_raw_gunship_entity (NULL);
	}

	#if LANDING_ROUTE_CHECK

	destroy_debug_entity_landing_route_check (en);

	#endif

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

	free_mem (raw);

	set_free_entity (en);
}
Exemple #7
0
static void kill_local (entity *en)
{
	site
		*raw;

	vec3d
		pos;

	entity
		*task,
		*destroy_task;

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

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en);

	#endif

	raw = get_local_entity_data (en);

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

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT);

		while (task)
		{

			destroy_task = task;

			task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT);

			if (destroy_task->type == ENTITY_TYPE_TASK)
			{

				#if DEBUG_MODULE

				debug_log ("ST_DSTRY: killing site, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]);

				#endif

				notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE);
			}
		}
	}

	//
	// fixed
	//

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	// gunship_target_link

	// sector_link

	//
	// site
	//

	////////////////////////////////////////
	//
 	// KILL
	//
	////////////////////////////////////////

	// must be done BEFORE alive flag set
	subtract_local_entity_importance_from_keysite (en);

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

	////////////////////////////////////////
	//
	// SPECIAL EFFECTS
	//
	////////////////////////////////////////

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		create_client_server_object_killed_explosion_effect (en);

		get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &pos);

		pos.y = get_3d_terrain_elevation (pos.x, pos.z);

		create_client_server_crater (CRATER_TYPE_LARGE_EXPLOSION, &pos);
	}

	//
	// must be done AFTER object explosion
	//

	raw->fix.object_3d_shape = get_3d_object_destroyed_object_index (raw->fix.object_3d_shape);
}
Exemple #8
0
static void destroy_local (entity *en)
{

	ship_vehicle
		*raw;

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

	#if DEBUG_MODULE >= 2

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_DESTROY, en);

	#endif

	raw = (ship_vehicle *) get_local_entity_data (en);

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

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

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

	destruct_3d_object (raw->vh.inst3d);

	free_mem (raw->vh.weapon_package_status_array);

	if (raw->vh.sound_effect_data)
	{

		destroy_system_sound_effect (raw->vh.sound_effect_data);
	}

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

	//
	// ship_vehicle
	//

	//
	// vehicle
	//

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON);

	unlink_local_entity_children (en, LIST_TYPE_MOVEMENT_DEPENDENT);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MOVEMENT_DEPENDENT);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_DESIGNATED_TARGET); // Jabberwock 031107 Designated targets

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_GUNSHIP_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_VIEW);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE);

	//
	// mobile
	//

	unlink_local_entity_children (en, LIST_TYPE_SPECIAL_EFFECT);

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_SECTOR);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_UPDATE);

	#if LANDING_ROUTE_CHECK

	destroy_debug_entity_landing_route_check (en);

	#endif

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

	free_mem (raw);

	set_free_entity (en);
}
Exemple #9
0
static void kill_local (entity *en)
{
	entity
		*parent;

	entity
		*task,
		*destroy_task;

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

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en);

	#endif

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

	ASSERT (get_local_entity_int_value (en, INT_TYPE_ALIVE));

	parent = get_local_entity_parent (en, LIST_TYPE_SEGMENT);

	ASSERT (parent);

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

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT);

		while (task)
		{

			destroy_task = task;

			task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT);

			if (destroy_task->type == ENTITY_TYPE_TASK)
			{

				#if DEBUG_MODULE

				debug_log ("SG_DSTRY: killing segment, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]);

				#endif

				notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE);
			}
		}
	}

	//
	// fixed
	//

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	// gunship_target_link

	// sector_link

	//
	// segment
	//

	// segment_link

	// update_link

	////////////////////////////////////////
	//
	// KILL
	//
	////////////////////////////////////////

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

	////////////////////////////////////////
	//
	// SPECIAL EFFECTS
	//
	////////////////////////////////////////

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		create_client_server_object_killed_explosion_effect (en);

		//
		// kill any routed vehicles that are on the bridge at the time
		//

		kill_routed_vehicles_on_segment (en);
	}

	//
	// notify the parent's collision function ( primarily to change the objects shape ),
	// and the parents killed function ( to handle breaking of links, and setting off chain reactions etc. )
	//

	notify_local_entity (ENTITY_MESSAGE_COLLISION, parent, en);

	notify_local_entity (ENTITY_MESSAGE_CHILD_KILLED, parent, en);
}
Exemple #10
0
static void kill_local (entity *en)
{
	object
		*raw;

	vec3d
		pos;

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

	#if DEBUG_MODULE

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en);

	#endif

	raw = (object *) get_local_entity_data (en);

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

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

	//
	// fixed
	//

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	// gunship_target_link

	// sector_link

	//
	// object
	//

	////////////////////////////////////////
	//
	// SPECIAL EFFECTS
	//
	////////////////////////////////////////

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		create_client_server_object_killed_explosion_effect (en);

		get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &pos);

		pos.y = get_3d_terrain_elevation (pos.x, pos.z);

		create_client_server_crater (CRATER_TYPE_LARGE_EXPLOSION, &pos);
	}

	//
	// must be done AFTER object explosion
	//

	raw->fix.object_3d_shape = get_3d_object_destroyed_object_index (raw->fix.object_3d_shape);
}
Exemple #11
0
static int response_to_link_parent (entity_messages message, entity *receiver, entity *sender, va_list pargs)
{
	list_types
		list_type;

	#if DEBUG_MODULE

	debug_log_entity_message (message, receiver, sender, pargs);

	#endif

	list_type = va_arg (pargs, list_types);

	switch (list_type)
	{
		////////////////////////////////////////
		case LIST_TYPE_GUNSHIP_TARGET:
		////////////////////////////////////////
		{
			set_local_entity_int_value (receiver, INT_TYPE_GUNSHIP_RADAR_LOS_CLEAR, TRUE);

			set_local_entity_float_value (receiver, FLOAT_TYPE_AIR_RADAR_CONTACT_TIMEOUT, AIR_RADAR_CONTACT_TIMEOUT);

			// show icon on map if gunship scans it.
/*
			if (get_local_entity_int_value (receiver, INT_TYPE_SIDE) == get_global_gunship_side ())
			{

				set_planner_icon_update (receiver, FALSE);
			}
*/
			break;
		}
		////////////////////////////////////////
		case LIST_TYPE_TARGET:
		////////////////////////////////////////
		{
			entity
				*group;

			//
			// Notify the group that it has been targeted
			//
			
			if (get_comms_model () == COMMS_MODEL_SERVER)
			{
				if (get_local_entity_int_value (sender, INT_TYPE_IDENTIFY_MOBILE))
				{
					group = get_local_entity_parent (sender, LIST_TYPE_MEMBER);

					if (group)
					{
						notify_local_entity (ENTITY_MESSAGE_ENTITY_TARGETED, group, receiver, sender);
					}
				}
			}

			//
			// if targetting the player then insert into the gunship target list if not already there
			//

			if (sender == get_gunship_entity ())
			{
				if (!get_local_entity_parent (receiver, LIST_TYPE_GUNSHIP_TARGET))
				{
					if (get_local_entity_int_value (receiver, INT_TYPE_TARGET_TYPE) != TARGET_TYPE_INVALID)
					{
						if (get_local_entity_int_value (receiver, INT_TYPE_THREAT_TYPE) != THREAT_TYPE_INVALID)
						{
							insert_local_entity_into_parents_child_list (receiver, LIST_TYPE_GUNSHIP_TARGET, sender, NULL);
						}
					}
				}
			}

			break;
		}
	}

	return (TRUE);
}
Exemple #12
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:
		case PACK_MODE_BROWSE_SESSION:
      ////////////////////////////////////////
		{

			break;
		}

		////////////////////////////////////////
		case PACK_MODE_UPDATE_ENTITY:
		////////////////////////////////////////
		{
			vec3d
				v;

			//
			// always use access functions to set the data
			//

			set_local_entity_float_value (en, FLOAT_TYPE_ELAPSED_TIME, unpack_float_value (en, FLOAT_TYPE_ELAPSED_TIME));

         set_local_entity_float_value (en, FLOAT_TYPE_LIGHTNING_TIMER, unpack_float_value (en, FLOAT_TYPE_LIGHTNING_TIMER));

			//
			// rain effect
			//

         set_local_entity_float_value (en, FLOAT_TYPE_WEATHER_RADIUS, unpack_float_value (en, FLOAT_TYPE_WEATHER_RADIUS));

			unpack_vec3d (en, VEC3D_TYPE_WEATHER_POSITION, &v);
			set_local_entity_vec3d (en, VEC3D_TYPE_WEATHER_POSITION, &v);

			unpack_vec3d (en, VEC3D_TYPE_WEATHER_VELOCITY, &v);
			set_local_entity_vec3d (en, VEC3D_TYPE_WEATHER_VELOCITY, &v);

			//
			// wind effect
			//

			set_local_entity_float_value (en, FLOAT_TYPE_WIND_EFFECT_RADIUS, unpack_float_value (en, FLOAT_TYPE_WIND_EFFECT_RADIUS));
			set_local_entity_float_value (en, FLOAT_TYPE_WIND_GUSTING_VALUE, unpack_float_value (en, FLOAT_TYPE_WIND_GUSTING_VALUE));

			unpack_vec3d (en, VEC3D_TYPE_WIND_DIRECTION_VECTOR, &v);
			set_local_entity_vec3d (en, VEC3D_TYPE_WIND_DIRECTION_VECTOR, &v);

			unpack_vec3d (en, VEC3D_TYPE_WIND_EFFECT_POSITION, &v);
			set_local_entity_vec3d (en, VEC3D_TYPE_WIND_EFFECT_POSITION, &v);

			unpack_vec3d (en, VEC3D_TYPE_WIND_EFFECT_VELOCITY, &v);
			set_local_entity_vec3d (en, VEC3D_TYPE_WIND_EFFECT_VELOCITY, &v);

			//

         set_local_entity_int_value (en, INT_TYPE_WEATHER_INCREASING, unpack_int_value (en, INT_TYPE_WEATHER_INCREASING));

         set_local_entity_int_value (en, INT_TYPE_WIND_INCREASING, unpack_int_value (en, INT_TYPE_WIND_INCREASING));

			set_display_campaign_timer_valid (TRUE);

			break;
		}
	}
}
Exemple #13
0
static void kill_local (entity *en)
{

	int
		losses;

	entity
		*task,
		*group,
		*destroy_task;

	fixed_wing
		*raw;

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

	#if DEBUG_MODULE >= 2

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en);

	#endif

	if (!get_local_entity_int_value (en, INT_TYPE_ALIVE))
	{
		return;
	}

	raw = (fixed_wing *) get_local_entity_data (en);

	group = get_local_entity_parent (en, LIST_TYPE_MEMBER);

	ASSERT (group);

	//
	// update force info
	//

	remove_from_force_info (get_local_force_entity ((entity_sides) raw->ac.mob.side), en);

	if (tacview_is_logging())
		write_tacview_unit_event(en, TACVIEW_UNIT_DESTROYED, NULL);

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

	////////////////////////////////////////
	//
	// SEND NOTIFY MESSAGES
	//
	////////////////////////////////////////

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		// notify regen of kill

		add_entity_to_regen_queue
		(
			(entity_sides) get_local_entity_int_value(en, INT_TYPE_SIDE),
			get_local_entity_type(en),
			get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE),
			get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)
		);

		task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT);

		while (task)
		{

			destroy_task = task;

			task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT);

			if (destroy_task->type == ENTITY_TYPE_TASK)
			{

				#if DEBUG_MODULE

				debug_log ("FW_DSTRY: killing fixed wing, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]);

				#endif

				notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE);
			}
		}

		//
		// Release landing lock (if any)
		//

		release_mobile_entity_landing_locks (en);
	}

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

	//
	// fixed_wing
	//

	//
	// aircraft
	//

	// aircrew_root

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	// unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER);

	// gunship_target_link

	// member_link

	// view_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE);

	//
	// mobile
	//

	//
	// kill weapon sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN);

	//
	// kill engine sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING2);

	//
	// Kill speech
	//

	notify_speech_buffers_entity_killed (en);

	// special_effect root

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK);

	// sector_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET);

	// update_link

	set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DYING);

	//
	// death timer (set time after which entity is totally destroyed)
	//

	set_local_entity_float_value (en, FLOAT_TYPE_DEATH_TIMER, calculate_mobile_death_timer_value (en));

	////////////////////////////////////////
	//
	// KILL
	//
	////////////////////////////////////////

	damage_fixed_wing_3d_object (en);

	// must be done before alive flag set to FALSE
	remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en);

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

	//
	// group losses
	//

	losses = get_local_entity_int_value (group, INT_TYPE_LOSSES);

	losses ++;

	set_local_entity_int_value (group, INT_TYPE_LOSSES, losses);

	//
	// task losses
	//

	task = get_local_group_primary_task (group);

	if (task)
	{
		losses = get_local_entity_int_value (task, INT_TYPE_LOSSES);

		losses ++;

		set_local_entity_int_value (task, INT_TYPE_LOSSES, losses);
	}

	//
	// Notify Campaign Screen
	//

	notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group);

	//
	// Notify the GROUP that the mobile has been killed  (N.B. must be done AFTER mobile is unlinked from member list)
	//

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en);
	}

	////////////////////////////////////////
	//
	// SPECIAL EFFECTS
	//
	////////////////////////////////////////

	set_local_fixed_wing_afterburner_state (en, OFF);

	fixed_wing_impact_movement (en);

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		vec3d
			*position;

		sound_sample_indices
			sound_sample_index;

		create_client_server_object_killed_explosion_effect (en);

		position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

		sound_sample_index = SOUND_SAMPLE_INDEX_SHOT_DOWN_AIRCRAFT;

		create_client_server_sound_effect_entity
		(
			en,
			ENTITY_SIDE_NEUTRAL,
			ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1,
			SOUND_CHANNEL_SOUND_EFFECT,
			SOUND_LOCALITY_ALL,
			NULL,												// position
			1.0,												// amplification
			1.0,												// Werewolf pitch
			TRUE,												// valid sound effect
			TRUE,												// looping
			1,													// sample count
			&sound_sample_index							// sample index list
		);
	}

	#if LANDING_ROUTE_CHECK

	destroy_debug_entity_landing_route_check (en);

	#endif

	/////////////////////////////////////////////////////////////////
	//
	// SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED
	//
	/////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////
	//
	//
	/////////////////////////////////////////////////////////////////
}
Exemple #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);
}
Exemple #15
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;
		}
	}
}
Exemple #16
0
void update_vector_altitude_dynamics (void)
{

	static float
		last_ground_height = 0;

	matrix3x3
		attitude;

	float
		heading,
		pitch,
		roll,
		ground_height,
		centre_of_gravity_to_ground_distance;

	vec3d
		position,
		*face_normal;

	centre_of_gravity_to_ground_distance = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_CENTRE_OF_GRAVITY_TO_GROUND_DISTANCE);

	get_local_entity_attitude_matrix (get_gunship_entity (), attitude);

	ground_height = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_TERRAIN_ELEVATION);

	//
	// debug
	//

	if ((ground_height < -1000) || (ground_height > 32000))
	{

		debug_log ("!!!!!!!!!!!!!! GROUND HEIGHT %f", ground_height);

		ground_height = last_ground_height;
	}

	//
	// end
	//

	last_ground_height = ground_height;

	current_flight_dynamics->altitude.value = current_flight_dynamics->position.y;

	current_flight_dynamics->altitude.min = ground_height;

	switch (get_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE))
	{

		case OPERATIONAL_STATE_LANDED:
		{

			if (current_flight_dynamics->world_velocity_y.value > 0.0)
			{
		
				#if DEBUG_DYNAMICS
		
				debug_log ("VECTOR DYN: takeoff !");
		
				#endif
		
				set_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_NAVIGATING);
		
				delete_local_entity_from_parents_child_list (get_gunship_entity (), LIST_TYPE_CURRENT_WAYPOINT);
		
				transmit_entity_comms_message (ENTITY_COMMS_MOBILE_TAKEOFF, get_gunship_entity ());
			}
			else
			{

				entity
					*wp;

				vec3d
					wp_pos;

				wp = get_local_entity_parent (get_gunship_entity (), LIST_TYPE_CURRENT_WAYPOINT);

				if (wp)
				{

					get_local_waypoint_formation_position (get_local_entity_int_value (get_gunship_entity (), INT_TYPE_FORMATION_POSITION), wp, &wp_pos);

					ground_height = wp_pos.y;
				}
	
				current_flight_dynamics->world_velocity_y.value = max (current_flight_dynamics->world_velocity_y.value, 0.0);

				current_flight_dynamics->velocity_y.value = max (current_flight_dynamics->velocity_y.value, 0.0);
				
				memset (&current_flight_dynamics->world_motion_vector, 0, sizeof (vec3d));
			
				current_flight_dynamics->velocity_x.value = bound (current_flight_dynamics->velocity_x.value, knots_to_metres_per_second (-10), knots_to_metres_per_second (50));
				current_flight_dynamics->velocity_y.value = 0;
				current_flight_dynamics->velocity_z.value = bound (current_flight_dynamics->velocity_z.value, knots_to_metres_per_second (-10), knots_to_metres_per_second (50));
			
				current_flight_dynamics->position.y = ground_height + centre_of_gravity_to_ground_distance;
			
				current_flight_dynamics->altitude.value = ground_height + centre_of_gravity_to_ground_distance;
				
				heading = get_heading_from_attitude_matrix (attitude);
			
				//get_3d_terrain_face_normal (&n, current_flight_dynamics->position.x, current_flight_dynamics->position.z);
				face_normal = get_local_entity_ptr_value (get_gunship_entity (), PTR_TYPE_TERRAIN_FACE_NORMAL);
			
				get_3d_transformation_matrix_from_face_normal_and_heading (attitude, face_normal, heading);
				
				pitch = get_pitch_from_attitude_matrix (attitude);
			
				pitch += rad (aircraft_database [ENTITY_SUB_TYPE_AIRCRAFT_AH64D_APACHE_LONGBOW].fuselage_angle);
			
				roll = get_roll_from_attitude_matrix (attitude);
			
				get_3d_transformation_matrix (attitude, heading, pitch, roll);

				position.x = current_flight_dynamics->position.x;
				position.y = current_flight_dynamics->position.y;
				position.z = current_flight_dynamics->position.z;
			
				set_local_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &position);
			
				set_local_entity_attitude_matrix (get_gunship_entity (), attitude);
			}

			break;
		}

		default:
		{
	
			if (current_flight_dynamics->world_velocity_y.value < 0.0)
			{
	
				if (current_flight_dynamics->altitude.value < current_flight_dynamics->altitude.min + centre_of_gravity_to_ground_distance)
				{
			
					if (get_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE) != OPERATIONAL_STATE_LANDED)
					{
			
						//
						// need to find what wp the user is trying to land on ....
						//
			
						//entity
							//*wp;
				
						#if DEBUG_DYNAMICS
				
						debug_log ("VECTOR DYN: landed !");
				
						#endif
				
						set_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_LANDED);
			
						//transmit_entity_comms_message (ENTITY_COMMS_MOBILE_LAND, get_gunship_entity (), wp);
					}
				}
			}
		
			break;
		}
	}

	current_flight_dynamics->altitude.value = bound (
														current_flight_dynamics->altitude.value,
														current_flight_dynamics->altitude.min,
														current_flight_dynamics->altitude.max);
}
Exemple #17
0
static void kill_local (entity *en)
{

	int
		losses;

	routed_vehicle
		*raw;

	entity
		*task,
		*destroy_task,
		*group;

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

	#if DEBUG_MODULE >= 2

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en);

	#endif

	if (!get_local_entity_int_value (en, INT_TYPE_ALIVE))
	{
		return;
	}

	raw = get_local_entity_data (en);

	group = get_local_entity_parent (en, LIST_TYPE_MEMBER);

	ASSERT (group);

	//
	// update force info
	//

	remove_from_force_info (get_local_force_entity (raw->vh.mob.side), en);

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

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

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		////////////////////////////////////////
		//
		// SEND NOTIFY MESSAGES
		//
		////////////////////////////////////////

		// notify regen of kill

		add_entity_to_regen_queue
		(
			get_local_entity_int_value(en, INT_TYPE_SIDE),
			get_local_entity_type(en),
			get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE),
			get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)
		);

		//
		//
		//

		task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT);

		while (task)
		{

			destroy_task = task;

			task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT);

			if (get_local_entity_type (destroy_task) == ENTITY_TYPE_TASK)
			{

				#if DEBUG_MODULE

				debug_log ("RV_DSTRY: killing routed vehicle, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]);

				#endif

				notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE);
			}
		}

		//
		// Release landing lock (if any)
		//

		release_mobile_entity_landing_locks (en);
	}

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

	//
	// routed_vehicle
	//

	//
	// vehicle
	//

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	unlink_local_entity_children (en, LIST_TYPE_MOVEMENT_DEPENDENT);

	#if DEBUG_MODULE

	debug_log ("RV_DSTRY: removing member %d from group %d", get_local_entity_index (en), get_local_entity_index (raw->vh.member_link.parent));

	#endif

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MOVEMENT_DEPENDENT);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER);

	// gunship_target_link

	// member_link

	// view_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE);

	//
	// mobile
	//

	//
	// kill weapon sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN);

	//
	// kill engine sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING2);

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK);

	// sector_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET);

	// update_link

	set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DYING);

	////////////////////////////////////////
	//
	// KILL
	//
	////////////////////////////////////////

	// must be done before alive flag set to FALSE
	remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en);

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

	damage_routed_vehicle_3d_object (en);

	//
	// group losses
	//

	losses = get_local_entity_int_value (group, INT_TYPE_LOSSES);

	losses ++;

	set_local_entity_int_value (group, INT_TYPE_LOSSES, losses);

	//
	// task losses
	//

	task = get_local_group_primary_task (group);

	if (task)
	{
		losses = get_local_entity_int_value (task, INT_TYPE_LOSSES);

		losses ++;

		set_local_entity_int_value (task, INT_TYPE_LOSSES, losses);
	}

	//
	// Notify Campaign Screen
	//

	notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group);

	//
	// Notify the GROUP that the mobile has been killed  (N.B. must be done AFTER mobile is unlinked from member list)
	//

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en);
	}

	////////////////////////////////////////
	//
	// SPECIAL EFFECTS
	//
	////////////////////////////////////////

	set_local_entity_float_value (en, FLOAT_TYPE_DEATH_TIMER, calculate_mobile_death_timer_value (en));

	routed_vehicle_impact_movement (en);

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		create_client_server_object_killed_explosion_effect (en);
	}

	#if LANDING_ROUTE_CHECK

	destroy_debug_entity_landing_route_check (en);

	#endif

	/////////////////////////////////////////////////////////////////
	//
	// SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED
	//
	////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////
	//
	//
	/////////////////////////////////////////////////////////////////
}
Exemple #18
0
static void kill_local (entity *en)
{

	int
		losses;

	entity
		*task,
		*group,
		*keysite,
		*destroy_task;

	ship_vehicle
		*raw;

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

	#if DEBUG_MODULE >= 2

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en);

	#endif

	if (!get_local_entity_int_value (en, INT_TYPE_ALIVE))
	{
		return;
	}

	raw = (ship_vehicle *) get_local_entity_data (en);

	group = get_local_entity_parent (en, LIST_TYPE_MEMBER);

	ASSERT (group);

	keysite = NULL;

	if (tacview_is_logging())
		write_tacview_unit_event(en, TACVIEW_UNIT_DESTROYED, NULL);

	//
	// update force info
	//

	remove_from_force_info (get_local_force_entity ((entity_sides) raw->vh.mob.side), en);

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

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

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT);

		while (task)
		{
			destroy_task = task;

			task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT);

			if (destroy_task->type == ENTITY_TYPE_TASK)
			{
				#if DEBUG_MODULE

				debug_log ("SH_DSTRY: killing ship, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]);

				#endif

				notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE);
			}
		}

		//
		// Release landing lock (if any)
		//

		release_mobile_entity_landing_locks (en);

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

		//
		// Destroy keysite entity if ship is carrier
		//

		keysite = get_local_entity_first_child (en, LIST_TYPE_MOVEMENT_DEPENDENT);

		while (keysite)
		{
			if (get_local_entity_type (keysite) == ENTITY_TYPE_KEYSITE)
			{
				break;
			}

			keysite = get_local_entity_child_succ (keysite, LIST_TYPE_MOVEMENT_DEPENDENT);
		}
	}

	//
	// ship_vehicle
	//

	//
	// vehicle
	//

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	unlink_local_entity_children (en, LIST_TYPE_MOVEMENT_DEPENDENT);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MOVEMENT_DEPENDENT);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER);

	// gunship_target_link

	// member_link

	// view_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE);

	//
	// mobile
	//

	//
	// kill weapon sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN);

	//
	// kill engine sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING2);

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK);

	// sector_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET);

	// update_link

	set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_STOPPED);

	////////////////////////////////////////
	//
	// KILL
	//
	////////////////////////////////////////

	// must be done before alive flag set
	remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en);

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

	damage_ship_3d_object (en);

	//
	// group losses
	//

	losses = get_local_entity_int_value (group, INT_TYPE_LOSSES);

	losses ++;

	set_local_entity_int_value (group, INT_TYPE_LOSSES, losses);

	//
	// task losses
	//

	task = get_local_group_primary_task (group);

	if (task)
	{
		losses = get_local_entity_int_value (task, INT_TYPE_LOSSES);

		losses ++;

		set_local_entity_int_value (task, INT_TYPE_LOSSES, losses);
	}

	//
	// Notify Campaign Screen
	//

	notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group);

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		//
		// Notify the GROUP that the mobile has been killed  (N.B. must be done AFTER mobile is unlinked from member list)
		//

		notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en);

		//
		// Kill the keysite if ship is the carrier (N.B. must be done AFTER ships alive flag cleared)
		//

		if (keysite)
		{
			kill_client_server_entity (keysite);
		}
	}

	////////////////////////////////////////
	//
	// SPECIAL EFFECTS
	//
	////////////////////////////////////////

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		create_client_server_object_killed_explosion_effect (en);
	}

	#if LANDING_ROUTE_CHECK

	destroy_debug_entity_landing_route_check (en);

	#endif

	/////////////////////////////////////////////////////////////////
	//
	// SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED
	//
	/////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////
	//
	//
	/////////////////////////////////////////////////////////////////
}
Exemple #19
0
void kill_local_restored_anti_aircraft_entity (entity *en)
{

	anti_aircraft
		*raw;

	entity
		*group;

	raw = (anti_aircraft *) get_local_entity_data (en);

	// must be done before alive flag set to FALSE
	remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en);

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

	damage_anti_aircraft_3d_object (en);

	set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DEAD);

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

	group = get_local_entity_parent (en, LIST_TYPE_MEMBER);

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

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER);

	// gunship_target_link

	// member_link

	// view_link

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK);

	// sector_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_UPDATE);

	//
	// kill weapon sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN);

	//
	// Notify the GROUP that the mobile has been killed  (N.B. must be done AFTER mobile is unlinked from member list)
	//

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en);
	}
	else
	{
		//
		// Client - Kill local group if empty
		//

		if (get_local_entity_int_value (group, INT_TYPE_MEMBER_COUNT) == 0)
		{
			kill_local_entity (group);
		}
	}
}
Exemple #20
0
void update_client_server_entities (void)
{
	entity
		*en;

	float
		delta_time;

	int
		loop,
		iterations;

	ASSERT (get_update_entity ());

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

	iterations = 1;

	if (!locked_frame_rate)
	{
	
		delta_time = get_delta_time ();
	
		iterations = set_entity_update_frame_rate (command_line_entity_update_frame_rate);
	}

	for (loop = 0; loop < iterations; loop ++)
	{
	
		////////////////////////////////////////

		//
		// update_entities is coded around the entity system to avoid spinning through
		// the update list twice (which Vtune shows up as slow). MB_INT sets and gets
		// the values. You may only set the value to true. It is set to false by the
		// memset below.
		//

		memset (updated_entities, 0, MAX_NUM_ENTITIES / (sizeof (unsigned int) * 8));

		//
		// replaces....
		//
		/*
		en = get_local_entity_first_child (get_update_entity (), LIST_TYPE_UPDATE);
	
		while (en)
		{

			set_local_entity_int_value (en, INT_TYPE_UPDATED, FALSE);
	
			en = get_local_entity_child_succ (en, LIST_TYPE_UPDATE);
		}
		*/
		////////////////////////////////////////

		en = get_local_entity_first_child (get_update_entity (), LIST_TYPE_UPDATE);
	
		while (en)
		{
			set_update_succ (get_local_entity_child_succ (en, LIST_TYPE_UPDATE));
	
			update_client_server_entity (en);
	
			set_local_entity_int_value (en, INT_TYPE_UPDATED, TRUE);
	
			en = get_update_succ ();
		}
	
		set_update_succ (NULL);

		////////////////////////////////////////
	}

	if (!locked_frame_rate)
	{

		set_manual_delta_time (delta_time);
	}

	/////////////////////////////////////////////////
}
Exemple #21
0
static void kill_local (entity *en)
{

	entity
		*task,
		*destroy_task;

	cargo
		*raw;

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

	#if DEBUG_MODULE >= 2

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en);

	#endif

	raw = (cargo *) get_local_entity_data (en);

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

	////////////////////////////////////////
	//
	// KILL
	//
	////////////////////////////////////////

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

	////////////////////////////////////////
	//
	// SEND NOTIFY MESSAGES
	//
	////////////////////////////////////////

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{

		task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT);

		while (task)
		{

			destroy_task = task;

			task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT);

			if (destroy_task->type == ENTITY_TYPE_TASK)
			{

				#if DEBUG_MODULE

				debug_log ("FW_DSTRY: killing cargo, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]);

				#endif

				notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE);
			}
		}

		////////////////////////////////////////
		//
		// SEND NOTIFY MESSAGES
		//
		////////////////////////////////////////
	}

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

	//
	// cargo
	//

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_CARGO);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MOVEMENT_DEPENDENT);

	// view_link

	//
	// mobile
	//

	unlink_local_entity_children (en, LIST_TYPE_SPECIAL_EFFECT);

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK);

	// sector_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET);

	// update_link

	////////////////////////////////////////
	//
	// SPECIAL EFFECTS
	//
	////////////////////////////////////////
}
Exemple #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);
}
Exemple #23
0
static void kill_local (entity *en)
{

	int
		losses;

	helicopter
		*raw;

	entity
		*task,
		*group,
		*member,
		*destroy_task;

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

	#if DEBUG_MODULE >= 2

	debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en);

	#endif

	if (!get_local_entity_int_value (en, INT_TYPE_ALIVE))
	{
		return;
	}

	raw = get_local_entity_data (en);

	group = get_local_entity_parent (en, LIST_TYPE_MEMBER);

	ASSERT (group);

	//
	// update force info
	//

	remove_from_force_info (get_local_force_entity (raw->ac.mob.side), en);

	if (en == get_gunship_entity ())
	{
		//
		// Award Points for mission
		//

		task = get_local_entity_primary_task (en);

		if (task)
		{
			if (get_local_entity_int_value (task, INT_TYPE_TASK_STATE) == TASK_STATE_COMPLETED)
			{
				//
				// Only award points for COMPLETE missions (also means player can't rejoin that mission and get points again)
				//

				notify_gunship_entity_mission_terminated (en, task);
			}
		}
	}

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

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

	#if DEBUG_MODULE

	debug_log ("HC_DSTRY: killing helicopter %s", entity_sub_type_aircraft_names [raw->ac.mob.sub_type]);

	#endif

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		// notify regen of kill

		add_entity_to_regen_queue
		(
			get_local_entity_int_value(en, INT_TYPE_SIDE),
			get_local_entity_type(en),
			get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE),
			get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)
		);

		//
		// notify task dependents
		//

		task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT);

		while (task)
		{

			destroy_task = task;

			task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT);

			if (destroy_task->type == ENTITY_TYPE_TASK)
			{

				#if DEBUG_MODULE

				debug_log ("HC_DSTRY: killing helicopter, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]);

				#endif

				notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE);
			}
		}

		//
		// Release landing lock (if any)
		//

		release_mobile_entity_landing_locks (en);

		//
		// if group contains player, set all helicopters in group to "weapons free", and clear "hold position" flag
		//

		if (get_local_entity_int_value (en, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
		{
			member = get_local_entity_first_child (group, LIST_TYPE_MEMBER);

			while (member)
			{
				set_client_server_entity_int_value (member, INT_TYPE_WEAPONS_HOLD, FALSE);

				set_client_server_entity_int_value (member, INT_TYPE_POSITION_HOLD, FALSE);

				member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER);
			}
		}
	}

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

	//
	// helicopter
	//

	unlink_local_entity_children (en, LIST_TYPE_GUNSHIP_TARGET);

	unlink_local_entity_children (en, LIST_TYPE_PADLOCK);

	//
	// aircraft
	//

	// aircrew_root

	unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT);

	////////////////////////////////////////
	//
	// the eject sequence relies on launched weapons NOT being unlinked
	//

	// unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON);

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

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER);

	// gunship_target_link

	// member_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_MOVEMENT_DEPENDENT);

	// view_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE);

	//
	// mobile
	//

	//
	// kill weapon sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN);

	//
	// kill engine sound effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_LOOPING);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_WIND_UP);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_WIND_DOWN);

	//
	// kill radio / warning effects
	//

	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_INCOMING_MISSILE_WARNING);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_LOCK_ON_TONE);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_MCA);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_RADAR_LOCKED);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_RADAR_TRACKED);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CPG_MESSAGE);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_RADIO_MESSAGE);
	kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_WARNING_MESSAGE);

	notify_speech_buffers_entity_killed (en);

	unlink_local_entity_children (en, LIST_TYPE_TARGET);

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK);

	// sector_link

	delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET);

	// update_link

	//
	// death timer (set time after which entity is totally destroyed)
	//

	set_local_entity_float_value (en, FLOAT_TYPE_DEATH_TIMER, calculate_mobile_death_timer_value (en));

	////////////////////////////////////////
	//
	// KILL
	//
	////////////////////////////////////////

	damage_helicopter_3d_object (en);

	// must be done before alive flag set to FALSE
	remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en);

	set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE);

	//
	// group losses
	//

	losses = get_local_entity_int_value (group, INT_TYPE_LOSSES);

	losses ++;

	set_local_entity_int_value (group, INT_TYPE_LOSSES, losses);

	//
	// task losses
	//

	task = get_local_group_primary_task (group);

	if (task)
	{
		losses = get_local_entity_int_value (task, INT_TYPE_LOSSES);

		losses ++;

		set_local_entity_int_value (task, INT_TYPE_LOSSES, losses);
	}

	//
	// Notify Campaign Screen
	//

	notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group);

	//
	// Notify the GROUP that the mobile has been killed  (N.B. must be done AFTER mobile is unlinked from member list)
	//

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en);
	}

	//
	// Notify force to check campaign criteria
	//

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		entity
			*force;

		force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE);

		while (force)
		{
			notify_local_entity (ENTITY_MESSAGE_CHECK_CAMPAIGN_OBJECTIVES, force, en);

			force = get_local_entity_child_succ (force, LIST_TYPE_FORCE);
		}
	}

	////////////////////////////////////////
	//
	// SPECIAL EFFECTS
	//
	////////////////////////////////////////

	helicopter_impact_movement (en);

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		vec3d
			*position;

		sound_sample_indices
			sound_sample_index;

		set_client_server_entity_int_value (en, INT_TYPE_MAIN_ROTOR_DAMAGED, TRUE);

		set_client_server_entity_int_value (en, INT_TYPE_TAIL_ROTOR_DAMAGED, TRUE);

		create_client_server_object_killed_explosion_effect (en);

		position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

		sound_sample_index = SOUND_SAMPLE_INDEX_SHOT_DOWN_HELICOPTER;

		create_client_server_sound_effect_entity
		(
			en,
			ENTITY_SIDE_NEUTRAL,
			ENTITY_SUB_TYPE_EFFECT_SOUND_ROTOR_LOOPING,
			SOUND_CHANNEL_SOUND_EFFECT,
			SOUND_LOCALITY_ALL,
			NULL,												// position
			1.0,												// amplification
			TRUE,												// valid sound effect
			TRUE,												// looping
			1,													// sample count
			&sound_sample_index							// sample index list
		);
	}

	set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DYING);

	////////////////////////////////////////
	//
	// VIEWS
	//
	////////////////////////////////////////

	if ((en == get_gunship_entity ()) && (!get_local_entity_int_value (en, INT_TYPE_EJECTED)))
	{
		set_gunship_entity (NULL);
	}

	#if LANDING_ROUTE_CHECK

	destroy_debug_entity_landing_route_check (en);

	#endif

	/////////////////////////////////////////////////////////////////
	//
	// SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED
	//
	/////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////
	//
	//
	/////////////////////////////////////////////////////////////////
}