Exemple #1
0
void terminate_all_engage_tasks (entity *group)
{
	entity
		*guide,
		*task;

	ASSERT (group);

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	do
	{
		guide = get_local_entity_first_child (group, LIST_TYPE_GUIDE_STACK);

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

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

				if (get_local_entity_int_value (task, INT_TYPE_TASK_TERMINATED) == TASK_TERMINATED_IN_PROGRESS)
				{
					notify_local_entity (ENTITY_MESSAGE_TASK_TERMINATED, task, group, TASK_TERMINATED_ABORTED);

					break;
				}
			}

			guide = get_local_entity_child_succ (guide, LIST_TYPE_GUIDE_STACK);
		}
	}
	while (guide);
}
Exemple #2
0
int assign_task_to_group_members (entity *group, entity *guide, unsigned int valid_members)
{
	entity
		*task,
		*member;

	ASSERT (group);

	ASSERT (guide);

	task = get_local_entity_parent (guide, LIST_TYPE_GUIDE);

	ASSERT (task);

	member = get_local_entity_first_child (group, LIST_TYPE_MEMBER);

	while (member)
	{
		if (valid_members & (1 << get_local_entity_int_value (member, INT_TYPE_GROUP_MEMBER_NUMBER)))
		{
			attach_group_member_to_guide_entity (member, guide);

			notify_local_entity (ENTITY_MESSAGE_TASK_ASSIGNED, member, task);
		}
		
		member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER);
	}

	return TRUE;
}
Exemple #3
0
void kill_client_server_group_entity (entity *en)
{
	entity
		*guide,
		*task,
		*next;

	ASSERT (en);

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	//
	// abort tasks (NOTE: Notifying each guide could indirectly destroy other guides on the stack)
	//

	do
	{
		guide = get_local_entity_first_child (en, LIST_TYPE_GUIDE_STACK);

		if (guide)
		{
			notify_local_entity (ENTITY_MESSAGE_GROUP_KILLED, guide, en);
		}
	}
	while (guide);

	//
	// notify task dependents
	//

	task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT);

	while (task)
	{
		next = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT);

		if (task->type == ENTITY_TYPE_TASK)
		{
			notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE);
		}

		task = next;
	}

	kill_client_server_entity (en);
}
Exemple #4
0
static int response_to_unlink_child (entity_messages message, entity *receiver, entity *sender, va_list pargs)
{
	camera
		*raw;

	list_types
		list_type;

	#if DEBUG_MODULE

	debug_log_entity_message (message, receiver, sender, pargs);

	#endif

	raw = get_local_entity_data (receiver);

	list_type = va_arg (pargs, list_types);

	switch (list_type)
	{
		////////////////////////////////////////
		case LIST_TYPE_VIEW:
		////////////////////////////////////////
		{
			if (raw->external_view_entity == sender)
			{
				raw->external_view_entity = NULL;
			}

			notify_view_menu_of_view_list_change (sender);

			break;
		}
		////////////////////////////////////////
		case LIST_TYPE_VIEW_WEAPON:
		////////////////////////////////////////
		{
			ASSERT (sender);

			if (get_view_mode () == VIEW_MODE_EXTERNAL)
			{
				if (get_local_entity_int_value (get_camera_entity (), INT_TYPE_CAMERA_MODE) == CAMERA_MODE_WEAPON)
				{
					notify_local_entity (ENTITY_MESSAGE_SET_CAMERA_ACTION, get_camera_entity (), NULL, CAMERA_ACTION_WEAPON_EXPLOSION);

					reset_weapon_explosion_camera_position (get_local_entity_vec3d_ptr (sender, VEC3D_TYPE_POSITION));
				}
			}

			break;
		}
	}

	return (TRUE);
}
Exemple #5
0
void navigation_guide_waypoint_reached (entity *en)
{
	entity
		*current_wp;

	//
	// set next waypoint (actual set function is called from within wp_msgs)
	//

	current_wp = get_local_entity_parent (en, LIST_TYPE_CURRENT_WAYPOINT);

	ASSERT (current_wp);

	// WARNING : must be done last because it can destroy the current guide entity
	notify_local_entity (ENTITY_MESSAGE_WAYPOINT_REACHED, current_wp, en);
}
Exemple #6
0
void group_terminate_all_tasks (entity *en)
{
	entity
		*task,
		*guide;

	int
		task_type;

	ASSERT (en);

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	terminate_all_engage_tasks (en);

	do
	{
		guide = get_local_entity_first_child (en, LIST_TYPE_GUIDE_STACK);

		if (guide)
		{
			task = get_local_entity_parent (guide, LIST_TYPE_GUIDE);

			ASSERT (task);

			task_type = get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE);

			if (task_database [task_type].persistent_task)
			{
				destroy_client_server_entity (guide);
			}
			else
			{
				notify_local_entity (ENTITY_MESSAGE_TASK_TERMINATED, task, NULL, TASK_TERMINATED_ABORTED);
			}
		}
	}
	while (guide);
}
Exemple #7
0
static void set_local_vec3d (entity *en, vec3d_types type, vec3d *v)
{
	weapon
		*raw;

	ASSERT (v);

	#if DEBUG_MODULE

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

	#endif

	raw = get_local_entity_data (en);

	switch (type)
	{
		////////////////////////////////////////
		case VEC3D_TYPE_POSITION:
		////////////////////////////////////////
		{
			entity
				*special_effect,
				*old_sector,
				*new_sector;

			raw->mob.position = *v;

			old_sector = get_local_entity_parent (en, LIST_TYPE_SECTOR);

			new_sector = get_local_sector_entity (v);

			if (old_sector != new_sector)
			{
				delete_local_entity_from_parents_child_list (en, LIST_TYPE_SECTOR);

				insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, new_sector, NULL);
			}

			//
			// notify special effects of move
			//

			special_effect = get_local_entity_first_child (en, LIST_TYPE_SPECIAL_EFFECT);

			while (special_effect)
			{
				#if DEBUG_MODULE

				debug_log ("WEAPON VEC3D: sending set entity position %f, %f, %f", raw->mob.position.x, raw->mob.position.y, raw->mob.position.z);

				#endif

				notify_local_entity (ENTITY_MESSAGE_SET_ENTITY_POSITION, special_effect, en, &raw->mob.position, 0.0, 0.0);

				special_effect = get_local_entity_child_succ (special_effect, LIST_TYPE_SPECIAL_EFFECT);
			}

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

			break;
		}
	}
}
Exemple #8
0
static void set_local_vec3d (entity *en, vec3d_types type, vec3d *v)
{
   aircraft
      *raw;

   ASSERT (v);

   #if DEBUG_MODULE

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

   #endif

   raw = (aircraft *) get_local_entity_data (en);

   switch (type)
   {
      ////////////////////////////////////////
      case VEC3D_TYPE_MOTION_VECTOR:
      ////////////////////////////////////////
      {
         raw->mob.motion_vector = *v;

         break;
      }
      ////////////////////////////////////////
      case VEC3D_TYPE_POSITION:
      ////////////////////////////////////////
      {

         float
            heading;

         entity
				*dependent,
				*special_effect,
				*old_sector,
				*new_sector;

			//
			// notify dependents of move, must be done before set_vec3d so children can work out delta positions
			//

         heading = 0.0;

			//if (get_local_entity_type (en) == ENTITY_TYPE_HELICOPTER)
			{

				heading = get_heading_from_attitude_matrix (raw->mob.attitude);
	
				dependent = get_local_entity_first_child (en, LIST_TYPE_MOVEMENT_DEPENDENT);
	
				while (dependent)
				{
					#if DEBUG_MODULE_AIRCRAFT_POSITION_MESSAGE
	
					debug_log ("AIRCRAFT VEC3D: sending set entity position %f, %f, %f", raw->mob.position.x, raw->mob.position.y, raw->mob.position.z);
	
					#endif
	
					notify_local_entity (ENTITY_MESSAGE_SET_ENTITY_POSITION, dependent, en, v, (double) heading, (double) raw->mob.velocity);
	
					dependent = get_local_entity_child_succ (dependent, LIST_TYPE_MOVEMENT_DEPENDENT);
				}
			}

			//
			// Actual set_vec3d
			//

         raw->mob.position = *v;

			//
			// check if entered new sector
			//

			old_sector = get_local_entity_parent (en, LIST_TYPE_SECTOR);

			new_sector = get_local_sector_entity (v);

         if (old_sector != new_sector)
         {
            delete_local_entity_from_parents_child_list (en, LIST_TYPE_SECTOR);

            insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, new_sector, NULL);

				//
				// play speech for flown across "front-line"
				//

				if (get_comms_model () == COMMS_MODEL_SERVER)
				{
					if (get_local_entity_int_value (new_sector, INT_TYPE_SIDE) != get_local_entity_int_value (old_sector, INT_TYPE_SIDE))
					{
						play_aircraft_flown_into_new_sector_speech (en, old_sector, new_sector);
					}
				}
         }

			//
			// notify special effects of move
			//

			special_effect = get_local_entity_first_child (en, LIST_TYPE_SPECIAL_EFFECT);

			while (special_effect)
			{
				#if DEBUG_MODULE_AIRCRAFT_POSITION_MESSAGE

				debug_log ("AIRCRAFT VEC3D: sending set entity position %f, %f, %f", raw->mob.position.x, raw->mob.position.y, raw->mob.position.z);

				#endif

				notify_local_entity (ENTITY_MESSAGE_SET_ENTITY_POSITION, special_effect, en, &raw->mob.position, (double) heading, (double) raw->mob.velocity);

				special_effect = get_local_entity_child_succ (special_effect, LIST_TYPE_SPECIAL_EFFECT);
			}

         break;
      }
      ////////////////////////////////////////
      case VEC3D_TYPE_WEAPON_TO_TARGET_VECTOR:
      ////////////////////////////////////////
      {
         raw->weapon_to_target_vector = *v;

         break;
      }
      ////////////////////////////////////////
      case VEC3D_TYPE_WEAPON_VECTOR:
      ////////////////////////////////////////
      {
         raw->weapon_vector = *v;

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

         break;
      }
   }
}
Exemple #9
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 #10
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 #11
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
	//
	/////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////
	//
	//
	/////////////////////////////////////////////////////////////////
}
Exemple #12
0
void assess_group_supplies (entity *en)
{

	entity
		*keysite,
		*force;

	group
		*raw;

	float
		required,
		level;

	raw = get_local_entity_data (en);

	if (get_local_entity_int_value (en, INT_TYPE_RESUPPLY_SOURCE) == RESUPPLY_SOURCE_GROUP)
	{

		//
		// Check if Group needs to request Supplies via Mission...
		//

		if (raw->supplies.ammo_supply_level < 100.0)
		{

			force = get_local_force_entity (get_local_entity_int_value (en, INT_TYPE_SIDE));

			#if DEBUG_MODULE || DEBUG_SUPPLY

			debug_log ("GROUP: SUPPLY_INFO: ground group %s low on ammo, requesting Supply mission", get_local_entity_string (en, STRING_TYPE_FULL_NAME));

			#endif

			notify_local_entity (ENTITY_MESSAGE_FORCE_LOW_ON_SUPPLIES, force, en, ENTITY_SUB_TYPE_CARGO_AMMO);
		}
		else if (raw->supplies.fuel_supply_level < 100.0)
		{

			force = get_local_force_entity (get_local_entity_int_value (en, INT_TYPE_SIDE));

			#if DEBUG_MODULE || DEBUG_SUPPLY

			debug_log ("GROUP: SUPPLY_INFO: ground group %s low on fuel, requesting Supply mission", get_local_entity_string (en, STRING_TYPE_FULL_NAME));

			#endif

			notify_local_entity (ENTITY_MESSAGE_FORCE_LOW_ON_SUPPLIES, force, en, ENTITY_SUB_TYPE_CARGO_FUEL);
		}
	}
	else if (get_local_entity_int_value (en, INT_TYPE_RESUPPLY_SOURCE) == RESUPPLY_SOURCE_KEYSITE)
	{
		//
		// check all group is landed. If so refuel/rearm group via keysite supplies
		//

		if (get_local_entity_int_value (en, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE)
		{

			if (raw->supplies.ammo_supply_level < 100.0)
			{

				//
				// re-arm
				//

				keysite = get_local_entity_parent (en, LIST_TYPE_KEYSITE_GROUP);

				if ((!keysite) || (get_local_entity_type (keysite) != ENTITY_TYPE_KEYSITE))
				{
					keysite = get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, raw->side, get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION), 1.0 * KILOMETRE, NULL, NULL);
				}

				ASSERT (keysite);

				level = get_local_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL);

				required = 100.0 - (raw->supplies.ammo_supply_level * AMMO_USAGE_ACCELERATOR);

				required = bound (required, 0.0, level);

				level -= required;

				set_client_server_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL, level);

				set_client_server_entity_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL, raw->supplies.ammo_supply_level + required);

				#if DEBUG_MODULE || DEBUG_SUPPLY

				debug_log ("GROUP: SUPPLY_INFO: Air group %s members landed, rearming group (now ammo = %f, fuel = %f) from keysite %s (%d) (now ammo = %f, fuel = %f)",
							get_local_entity_string (en, STRING_TYPE_FULL_NAME),
							get_local_entity_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL),
							get_local_entity_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL),
							get_local_entity_string (keysite, STRING_TYPE_FULL_NAME),
							get_local_entity_index (keysite),
							get_local_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL),
							get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL));

				#endif
			}

			if (raw->supplies.fuel_supply_level < 100.0)
			{

				//
				// re-fuel
				//

				keysite = get_local_entity_parent (en, LIST_TYPE_KEYSITE_GROUP);

				if ((!keysite) || (get_local_entity_type (keysite) != ENTITY_TYPE_KEYSITE))
				{
					keysite = get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, raw->side, get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION), 1.0 * KILOMETRE, NULL, NULL);
				}

				ASSERT (keysite);

				level = get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL);

				required = 100.0 - (raw->supplies.fuel_supply_level * FUEL_USAGE_ACCELERATOR);

				required = bound (required, 0.0, level);

				level -= required;

				set_client_server_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL, level);

				set_client_server_entity_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL, raw->supplies.fuel_supply_level + required);

				#if DEBUG_MODULE || DEBUG_SUPPLY

				debug_log ("GROUP: SUPPLY_INFO: Air group %s members landed, refuelling group (now ammo = %f, fuel = %f) from keysite %s (%d) (now ammo = %f, fuel = %f)",
							get_local_entity_string (en, STRING_TYPE_FULL_NAME),
							get_local_entity_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL),
							get_local_entity_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL),
							get_local_entity_string (keysite, STRING_TYPE_FULL_NAME),
							get_local_entity_index (keysite),
							get_local_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL),
							get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL));

				#endif
			}
		}
	}
}
Exemple #13
0
static void update_server (entity *en)
{
	entity
		*parent,
		*next_segment,
		*prev_segment;

	entity_sub_types
		sub_type;

	vec3d
		*pos;

	float
		terrain_height;

	terrain_3d_point_data
		terrain_info;

	//
	// notify the segments neighbours as applicable
	//

	parent = get_local_entity_parent (en, LIST_TYPE_SEGMENT);

	ASSERT (parent);

	next_segment = get_local_entity_child_succ (en, LIST_TYPE_SEGMENT);

	if (next_segment)
	{
		notify_local_entity (ENTITY_MESSAGE_COLLISION, parent, next_segment);
	}

	prev_segment = get_local_entity_child_pred (en, LIST_TYPE_SEGMENT);

	if (prev_segment)
	{
		notify_local_entity (ENTITY_MESSAGE_COLLISION, parent, prev_segment);
	}

	sub_type = get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE);

	if (sub_type == ENTITY_SUB_TYPE_FIXED_BRIDGE_UNSUPPORTED_MID_SECTION)
	{
		//
		// make the segment drop to the floor ( removing it from the update list when it hits )
		//
	
		pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);
	
		pos->y -= ( 10.0 * get_delta_time() );
	
		memset (&terrain_info, 0, sizeof (terrain_3d_point_data));
	
		terrain_height = get_3d_terrain_point_data (pos->x, pos->z, &terrain_info);

		if (get_terrain_type_class (terrain_info.terrain_type) == TERRAIN_CLASS_WATER)
		{
			terrain_height -= 1.0;
		}
	
		if ( pos->y <= terrain_height )
		{
			pos->y = terrain_height;
	
			delete_local_entity_from_parents_child_list (en, LIST_TYPE_UPDATE);
	
			if (get_comms_model () == COMMS_MODEL_SERVER)
			{
				create_client_server_object_hit_ground_explosion_effect (en, terrain_info.terrain_type);
			}
		}
	}
	else
	{
		//
		// segment is supported, and so should be instantly removed from the update list
		// ( only put there in the first place so that neighbours would be notified )
		//

		delete_local_entity_from_parents_child_list (en, LIST_TYPE_UPDATE);
	}
}
Exemple #14
0
void stop_vehicles_on_route (int start_node, int end_node)
{
	entity
		*task,
		*force,
		*group,
		*member;

	int
		index1,
		index2;

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE);

	while (force)
	{
		group = get_local_entity_first_child (force, LIST_TYPE_GROUND_REGISTRY);

		while (group)
		{
			task = get_local_group_primary_task (group);

			if (task)
			{
				member = (entity *) get_local_entity_ptr_value (group, PTR_TYPE_GROUP_LEADER);
	
				ASSERT (member);
			
				index1 = get_local_entity_int_value (member, INT_TYPE_WAYPOINT_THIS_INDEX);
	
				index2 = get_local_entity_int_value (member, INT_TYPE_WAYPOINT_NEXT_INDEX);
	
				if (((index1 == start_node) && (index2 == end_node)) || ((index2 == start_node) && (index1 == end_node)))
				{
					//
					// destroy task
					//
	
					notify_local_entity (ENTITY_MESSAGE_TASK_TERMINATED, task, group, TASK_TERMINATED_GROUP_DESTROYED);

					//
					// set group to busy, and operational state to stopped
					//
	
					set_client_server_entity_int_value (group, INT_TYPE_GROUP_MODE, GROUP_MODE_BUSY);

					{
						entity
							*mb;

						mb = get_local_entity_first_child (group, LIST_TYPE_MEMBER);

						while (mb)
						{
							set_client_server_entity_int_value (mb, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_STOPPED);

							mb = get_local_entity_child_succ (mb, LIST_TYPE_MEMBER);
						}
					}

					/////////////////////////////////////////////////////////////////
					//
					// SPECIAL_EFFECT_HOOK FOR BRIDGE OUT
					//
					/////////////////////////////////////////////////////////////////
	
					/////////////////////////////////////////////////////////////////
					//
					//
					/////////////////////////////////////////////////////////////////
				}
			}
	
			group = get_local_entity_child_succ (group, LIST_TYPE_GROUND_REGISTRY);
		}

		force = get_local_entity_child_succ (force, LIST_TYPE_FORCE);
	}
}
Exemple #15
0
void create_client_server_entity_weapon (entity *launcher, entity_sub_types weapon_sub_type, int weapon_index, int burst_size, int *smoke_trail_indices)
{
	entity
		*force,
		*target,
		*weapon;

	meta_smoke_list_types
		smoke_trail_type;

	int
		i,
		num_smoke_trail_entities,
		valid_sound_effect,
		current_weapon_count,
		new_weapon_count;

	ASSERT (launcher);

	ASSERT (entity_sub_type_weapon_valid (weapon_sub_type));

	//
	// get target
	//

	if (!(weapon_database[weapon_sub_type].weapon_class & (WEAPON_CLASS_DECOY | WEAPON_CLASS_CARGO | WEAPON_CLASS_DEBRIS)))
	{
		target = get_local_entity_parent (launcher, LIST_TYPE_TARGET);

/*		if (weapon_database[weapon_sub_type].hellfire_flight_profile)
		{
			if (get_local_entity_int_value (launcher, INT_TYPE_LOCK_ON_AFTER_LAUNCH))
			{
				target = NULL;
			}
		} */
	}
	else
	{
		target = NULL;
	}

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		////////////////////////////////////////
		//
		// SERVER/TX and SERVER/RX
		//
		////////////////////////////////////////

		ASSERT (weapon_index == ENTITY_INDEX_DONT_CARE);

		ASSERT (burst_size == BURST_SIZE_DONT_CARE);

		ASSERT (!smoke_trail_indices);

		// NOTE: The clients' weapon counters lag the servers' so it is possible that the
		//       client may unknowingly attempt to create more weapons than are available.
		//       This is prone to happen during rapid firing.

		current_weapon_count = get_local_entity_weapon_count (launcher, weapon_sub_type);

		if (current_weapon_count > 0)
		{
			int loal_mode = weapon_database[weapon_sub_type].hellfire_flight_profile && get_local_entity_int_value (launcher, INT_TYPE_LOCK_ON_AFTER_LAUNCH);

			if (get_comms_data_flow () == COMMS_DATA_FLOW_RX)
			{
				set_force_local_entity_create_stack_attributes (TRUE);
			}

			//
			// get burst size wrt rate of fire
			//

			if (weapon_database[weapon_sub_type].rate_of_fire != FIRE_SINGLE_WEAPON)
			{
				float time_per_shot = weapon_database[weapon_sub_type].inverse_rate_of_fire * ONE_MINUTE;
				unsigned int* last_shot = NULL;

				switch (launcher->type)
				{
				case ENTITY_TYPE_HELICOPTER:
					last_shot = &((helicopter*)get_local_entity_data(launcher))->ac.weapon_salvo_timer;
					break;

				case ENTITY_TYPE_FIXED_WING:
					last_shot = &((fixed_wing*)get_local_entity_data(launcher))->ac.weapon_salvo_timer;
					break;

				case ENTITY_TYPE_ANTI_AIRCRAFT:
					last_shot = &((anti_aircraft*)get_local_entity_data(launcher))->vh.weapon_salvo_timer;
					break;

				case ENTITY_TYPE_PERSON:
					last_shot = &((person*)get_local_entity_data(launcher))->vh.weapon_salvo_timer;
					break;

				case ENTITY_TYPE_ROUTED_VEHICLE:
					last_shot = &((routed_vehicle*)get_local_entity_data(launcher))->vh.weapon_salvo_timer;
					break;

				case ENTITY_TYPE_SHIP_VEHICLE:
					last_shot = &((ship_vehicle*)get_local_entity_data(launcher))->vh.weapon_salvo_timer;
					break;
				}

				if (last_shot)
				{
					unsigned int current_time = get_system_time();
					float elapsed_time = 1;

					if (*last_shot > 0)
					{
						if (current_time < *last_shot)
							return;
						elapsed_time = (current_time - *last_shot) * 0.001;
					}
					else
						elapsed_time = get_delta_time();

					burst_size = (int)(weapon_database[weapon_sub_type].rate_of_fire * ONE_OVER_ONE_MINUTE * elapsed_time);
					if (burst_size < 1)
					{
						if (*last_shot == 0)  // first shot in salvo always get fired
							burst_size = 1;
						else
							return;
					}

					if (*last_shot)
						*last_shot += (int)(burst_size * time_per_shot * 1000.0);
					else
						*last_shot = current_time;
				}
				else
				{
					ASSERT(FALSE);
					burst_size = 1;
				}
			}
			else
			{
				burst_size = 1;
			}

			//
			// set burst timer
			//

			valid_sound_effect = FALSE;

			if (get_local_entity_float_value (launcher, FLOAT_TYPE_WEAPON_BURST_TIMER) == 0.0)
			{
				set_local_entity_float_value (launcher, FLOAT_TYPE_WEAPON_BURST_TIMER, weapon_database[weapon_sub_type].burst_duration);

				valid_sound_effect = TRUE;
			}

			//
			// create weapon
			//

			weapon = create_local_entity
			(
				ENTITY_TYPE_WEAPON,
				ENTITY_INDEX_DONT_CARE,
				ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, weapon_sub_type),
				ENTITY_ATTR_INT_VALUE (INT_TYPE_WEAPON_BURST_SIZE, burst_size),
				ENTITY_ATTR_INT_VALUE (INT_TYPE_WEAPON_MISSILE_PHASE, MISSILE_PHASE1),
				ENTITY_ATTR_INT_VALUE (INT_TYPE_LOCK_ON_AFTER_LAUNCH, loal_mode),
				ENTITY_ATTR_PARENT (LIST_TYPE_LAUNCHED_WEAPON, launcher),
				ENTITY_ATTR_PARENT (LIST_TYPE_TARGET, target),
				ENTITY_ATTR_END
			);

			if (weapon)
			{
				//
				// send FIRE message to force (unless it's a decoy/cargo/debris being launched)
				//

				if ((target) && (!(weapon_database[weapon_sub_type].weapon_class & (WEAPON_CLASS_DECOY | WEAPON_CLASS_CARGO | WEAPON_CLASS_DEBRIS))))
				{
					force = get_local_force_entity ((entity_sides) get_local_entity_int_value (target, INT_TYPE_SIDE));

					if (force)
					{
						notify_local_entity (ENTITY_MESSAGE_ENTITY_FIRED_AT, force, launcher, target);
					}
				}

				//
				// create sound effect(s)
				//

				if (valid_sound_effect)
				{
					create_weapon_launched_sound_effects (launcher, weapon_sub_type);
				}

				//
				// create smoke trail
				//

				smoke_trail_type = (meta_smoke_list_types) get_local_entity_int_value (weapon, INT_TYPE_WEAPON_SMOKE_TRAIL_TYPE);

				if (smoke_trail_type != META_SMOKE_LIST_TYPE_NONE)
				{
					struct OBJECT_3D_BOUNDS
						*bounding_box;

					vec3d
						exhaust_offset;

					num_smoke_trail_entities = count_entities_in_meta_smoke_list (smoke_trail_type);

					ASSERT (num_smoke_trail_entities > 0);

					smoke_trail_indices = (int *) malloc_fast_mem (sizeof (int) * num_smoke_trail_entities);

					for (i = 0; i < num_smoke_trail_entities; i++)
					{
						smoke_trail_indices[i] = ENTITY_INDEX_DONT_CARE;
					}

					bounding_box = get_object_3d_bounding_box (get_local_entity_int_value (weapon, INT_TYPE_DEFAULT_3D_SHAPE));

					if ((weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_HOKUM_PILOT) ||(weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_HOKUM_CO_PILOT))
					{
						exhaust_offset.x = 0.0;
						exhaust_offset.y = 0.0;
						exhaust_offset.z = 0.0;
					}
					else
					{
						exhaust_offset.x = 0.0;
						exhaust_offset.y = 0.0;
						exhaust_offset.z = bounding_box->zmin;
					}

					create_meta_smoke_list_specified_offset (smoke_trail_type, weapon, &exhaust_offset, smoke_trail_indices);
				}

				transmit_entity_comms_message
				(
					ENTITY_COMMS_CREATE_WEAPON,
					NULL,
					launcher,
					weapon_sub_type,
					get_local_entity_safe_index (weapon),
					burst_size,
					smoke_trail_indices
				);

				if (smoke_trail_indices)
				{
					free_mem (smoke_trail_indices);
				}

				//
				// out of weapons (if infinite weapons then reload else select next weapon)
				//

				new_weapon_count = get_local_entity_weapon_count (launcher, weapon_sub_type);

				if (new_weapon_count <= 0)
				{
					#if !DEMO_VERSION
					if (get_local_entity_int_value (get_session_entity (), INT_TYPE_INFINITE_WEAPONS))
					{
						weapon_config_types
							config_type;

						config_type = (weapon_config_types) get_local_entity_int_value (launcher, INT_TYPE_WEAPON_CONFIG_TYPE);

						set_client_server_entity_int_value (launcher, INT_TYPE_WEAPON_CONFIG_TYPE, config_type);
					}
					else
					#endif
					{
						//
						// play weapon out of ammo speech
						//

						play_entity_weapon_out_speech (launcher, weapon_sub_type);

						//
						// select next weapon
						//
/*
						if (!(weapon_database[weapon_sub_type].weapon_class & (WEAPON_CLASS_DECOY | WEAPON_CLASS_CARGO | WEAPON_CLASS_DEBRIS)))
						{
							entity_sub_types
								next_weapon_sub_type;

							if (get_local_entity_int_value (launcher, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
							{
								next_weapon_sub_type = get_next_available_weapon_sub_type (launcher);
							}
							else
							{
								next_weapon_sub_type = ENTITY_SUB_TYPE_WEAPON_NO_WEAPON;
							}

							set_client_server_entity_int_value (launcher, INT_TYPE_SELECTED_WEAPON, next_weapon_sub_type);
						}
*/
					}
				}
				else
				{
					int
						report_ammo_low_count;

					report_ammo_low_count = weapon_database[weapon_sub_type].report_ammo_low_count;

					if ((current_weapon_count > report_ammo_low_count) && (new_weapon_count <= report_ammo_low_count))
					{
						//
						// play weapon low speech
						//

						play_entity_weapon_low_speech (launcher, weapon_sub_type);
					}
					else
					{
						//
						// weapon launch speech
						//

						play_entity_weapon_launched_speech (launcher, weapon_sub_type);
					}
				}
			}

			set_force_local_entity_create_stack_attributes (FALSE);
		}
		else
		{
			pause_client_server_continuous_weapon_sound_effect (launcher, weapon_sub_type);
		}
	}
	else
	{
		if (get_comms_data_flow () == COMMS_DATA_FLOW_TX)
		{
			////////////////////////////////////////
			//
			// CLIENT/TX
			//
			////////////////////////////////////////

			ASSERT (weapon_index == ENTITY_INDEX_DONT_CARE);

			ASSERT (burst_size == BURST_SIZE_DONT_CARE);

			ASSERT (!smoke_trail_indices);

			// NOTE: The clients' weapon counters lag the servers' so it is possible that the
			//       client may unknowingly attempt to create more weapons than are available.
			//       This is prone to happen during rapid firing.

			if (get_local_entity_weapon_available (launcher, weapon_sub_type))
			{
				transmit_entity_comms_message
				(
					ENTITY_COMMS_CREATE_WEAPON,
					NULL,
					launcher,
					weapon_sub_type,
					ENTITY_INDEX_DONT_CARE,
					burst_size,
					NULL
				);
			}
		}
		else
		{
			////////////////////////////////////////
			//
			// CLIENT/RX
			//
			////////////////////////////////////////

			ASSERT (weapon_index != ENTITY_INDEX_DONT_CARE);

			ASSERT (burst_size > 0);

			set_force_local_entity_create_stack_attributes (TRUE);

			weapon = create_local_entity
			(
				ENTITY_TYPE_WEAPON,
				weapon_index,
				ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, weapon_sub_type),
				ENTITY_ATTR_INT_VALUE (INT_TYPE_WEAPON_BURST_SIZE, burst_size),
				ENTITY_ATTR_PARENT (LIST_TYPE_LAUNCHED_WEAPON, launcher),
				ENTITY_ATTR_PARENT (LIST_TYPE_TARGET, target),
				ENTITY_ATTR_END
			);

			ASSERT (weapon);

			//
			// create smoke trail
			//

			smoke_trail_type = (meta_smoke_list_types) get_local_entity_int_value (weapon, INT_TYPE_WEAPON_SMOKE_TRAIL_TYPE);

			if (smoke_trail_type != META_SMOKE_LIST_TYPE_NONE)
			{
				struct OBJECT_3D_BOUNDS
					*bounding_box;

				vec3d
					exhaust_offset;

				ASSERT (smoke_trail_indices);

				bounding_box = get_object_3d_bounding_box (get_local_entity_int_value (weapon, INT_TYPE_DEFAULT_3D_SHAPE));

				if ((weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_HOKUM_PILOT) ||(weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_HOKUM_CO_PILOT))
				{
					exhaust_offset.x = 0.0;
					exhaust_offset.y = 0.0;
					exhaust_offset.z = 0.0;
				}
				else
				{
					exhaust_offset.x = 0.0;
					exhaust_offset.y = 0.0;
					exhaust_offset.z = bounding_box->zmin;
				}

				create_meta_smoke_list_specified_offset (smoke_trail_type, weapon, &exhaust_offset, smoke_trail_indices);
			}
			else
			{
				ASSERT (!smoke_trail_indices);
			}

			set_force_local_entity_create_stack_attributes (FALSE);
		}
	}
}
Exemple #16
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 #17
0
static int response_to_task_terminated (entity_messages message, entity *receiver, entity *sender, va_list pargs)
{

	entity
		*guide,
		*landing_en,
		*task;

	aircraft
		*raw;

	raw = (aircraft *) get_local_entity_data (receiver);

	#if DEBUG_MODULE_MESSAGE_TEXT

	debug_log ("AIRCRAFT MSGS: received task terminated, ac %s made safe", entity_sub_type_aircraft_names [raw->mob.sub_type]);

	#endif

	debug_assert (raw->member_link.parent);

	//
	// Check if aircraft was on a landing/takeoff/holding route
	//

	guide = get_local_entity_parent (receiver, LIST_TYPE_FOLLOWER);

	ASSERT (guide);

	task = get_local_entity_parent (guide, LIST_TYPE_GUIDE);

	ASSERT (task);

	landing_en = get_local_entity_parent (task, LIST_TYPE_ASSIGNED_TASK);

	switch (get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE))
	{

		case ENTITY_SUB_TYPE_TASK_LANDING:
		{
			ASSERT (landing_en);

			#if DEBUG_MODULE_MESSAGE_TEXT

			debug_log ("AC_MSGS: mobile was on a %s route, unlocking route and landing site", entity_sub_type_task_names [get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE)]);

			#endif

			if (get_local_entity_int_value (receiver, INT_TYPE_PLAYER) == ENTITY_PLAYER_AI)
			{

				notify_local_entity (ENTITY_MESSAGE_UNLOCK_LANDING_ROUTE, landing_en, receiver);
			}

			notify_local_entity (ENTITY_MESSAGE_UNLOCK_LANDING_SITE, landing_en, receiver);

			break;
		}

		case ENTITY_SUB_TYPE_TASK_TAKEOFF:
		{
			ASSERT (landing_en);

			#if DEBUG_MODULE_MESSAGE_TEXT

			debug_log ("AC_MSGS: mobile was on a %s route, unlocking route", entity_sub_type_task_names [get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE)]);

			#endif

			notify_local_entity (ENTITY_MESSAGE_UNLOCK_TAKEOFF_ROUTE, landing_en, receiver);

			break;
		}

		case ENTITY_SUB_TYPE_TASK_LANDING_HOLDING:
		{
			ASSERT (landing_en);

			#if DEBUG_MODULE_MESSAGE_TEXT

			debug_log ("AC_MSGS: mobile was on a %s route, locking route and landing site", entity_sub_type_task_names [get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE)]);

			#endif

			notify_local_entity (ENTITY_MESSAGE_UNLOCK_LANDING_SITE, landing_en, receiver);

			break;
		}

		case ENTITY_SUB_TYPE_TASK_TAKEOFF_HOLDING:
		{
			ASSERT (landing_en);

			#if DEBUG_MODULE_MESSAGE_TEXT

			debug_log ("AC_MSGS: mobile was on a %s route, no route to unlock", entity_sub_type_task_names [get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE)]);

			#endif

			break;
		}
	}

	return (TRUE);
}
Exemple #18
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 #19
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 #20
0
int assign_primary_task_to_group (entity *group_en, entity *task_en)
{
	entity_sub_types
		task_type,
		group_type;

	entity
		*force,
		*keysite;

	int
		side,
		formation,
		air_threat,
		enemy_sectors;

	unsigned int
		threat;

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);
		
	task_type = get_local_entity_int_value (task_en, INT_TYPE_ENTITY_SUB_TYPE);

	ASSERT (task_database [task_type].primary_task);

	group_type = get_local_entity_int_value (group_en, INT_TYPE_ENTITY_SUB_TYPE);

	ASSERT (!get_local_group_primary_task (group_en));

	if (assign_task_to_group (group_en, task_en, TASK_ASSIGN_ALL_MEMBERS))
	{
		//
		// set default group formation
		//

		formation = get_local_entity_int_value (group_en, INT_TYPE_GROUP_DEFAULT_FORMATION);

		if (formation != get_local_entity_int_value (group_en, INT_TYPE_GROUP_FORMATION))
		{
			set_client_server_entity_int_value (group_en, INT_TYPE_GROUP_FORMATION, formation);
		}

		//
		// Link to new keysite
		// 

		if (get_local_entity_int_value (group_en, INT_TYPE_GROUP_LIST_TYPE) == LIST_TYPE_KEYSITE_GROUP)
		{
			keysite = ( entity * ) get_local_entity_ptr_value (task_en, PTR_TYPE_RETURN_KEYSITE);

			if (keysite)
			{
				set_client_server_entity_parent (group_en, LIST_TYPE_KEYSITE_GROUP, keysite);
			}	
		}

		//
		// Notify Force
		//

		side = get_local_entity_int_value (group_en, INT_TYPE_SIDE);

		force = get_local_force_entity ( ( entity_sides ) side );

		ASSERT (force);

		notify_local_entity (ENTITY_MESSAGE_TASK_ASSIGNED, force, task_en);

		//
		// Assess for Escort task
		//

		if (task_database [task_type].escort_required_threshold != ESCORT_NEVER)
		{
			threat = assess_task_difficulty (task_en, &air_threat, &enemy_sectors);

			#if DEBUG_ESCORT_TASK_CREATION

			debug_filtered_log ("(ASSIGN) Side %s: Assigned %s to %s, objective %s",
											entity_side_short_names [side],
											get_local_entity_string (group_en, STRING_TYPE_FULL_NAME),
											get_local_entity_string (task_en, STRING_TYPE_FULL_NAME),
											get_task_objective_string (task_en)
									);

			debug_filtered_log ("Threat: %d (air_threat: %d, enemy_sectors: %d) - Threshold %d",
											threat, air_threat, enemy_sectors,
											task_database [task_type].escort_required_threshold);

			#endif

			if (threat >= task_database [task_type].escort_required_threshold)
			{
				create_escort_task (group_en, (threat >= ESCORT_CRITICAL), task_database [ENTITY_SUB_TYPE_TASK_ESCORT].task_priority, NULL, NULL);

				ai_log ("(ASSIGN) Created Escort Task for %s :- Threat %d / Threshold %d",
											get_local_entity_string (task_en, STRING_TYPE_FULL_NAME),
											threat,
											task_database [task_type].escort_required_threshold
											);
			}
		}

		//
		// Store Start Time
		//

		set_client_server_entity_float_value (task_en, FLOAT_TYPE_START_TIME, get_local_entity_float_value (get_session_entity (), FLOAT_TYPE_ELAPSED_TIME));

		//
		// Clear Expire Timer (now also used for destroying completed tasks)
		//

		set_local_entity_float_value (task_en, FLOAT_TYPE_EXPIRE_TIMER, 0.0);

		ai_log ("(ASSIGN) Side %s: Assigned %s (%d) to %s (%d) - Priority %f",
					entity_side_short_names [side],
					get_local_entity_string (group_en, STRING_TYPE_FULL_NAME),
					get_local_entity_safe_index (group_en),
					get_local_entity_string (task_en, STRING_TYPE_FULL_NAME),
					get_local_entity_safe_index (task_en),
					get_local_entity_float_value (task_en, FLOAT_TYPE_TASK_PRIORITY));

		return TRUE;
	}

	return FALSE;
}
Exemple #21
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 #22
0
unsigned int assign_engage_tasks_to_group (entity *group, unsigned int valid_members)
{
	entity
		*task,
		*guide,
		*target,
		*member,
		*single_member,
		*persuer,
		**guide_list;

	unsigned int
		member_number;

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

	float
		range,
		*priority;

	vec3d
		*member_pos,
		*target_pos;

	ASSERT (group);

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	if (!valid_members)
	{
		return valid_members;
	}	

	//
	// count up engage tasks
	//

	task_count = 0;

	guide = get_local_entity_first_child (group, LIST_TYPE_GUIDE_STACK);

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

			ASSERT (task);

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

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

		guide = get_local_entity_child_succ (guide, LIST_TYPE_GUIDE_STACK);
	}

	#if DEBUG_MODULE

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

	#endif

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

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

	//
	// get target priority
	//

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

	#if DEBUG_MODULE

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

	#endif

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

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

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

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

			ASSERT (task);

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

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

				ASSERT (target);

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

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

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

				#if DEBUG_MODULE

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

				#endif

				loop ++;
			}
		}

		guide = get_local_entity_child_succ (guide, LIST_TYPE_GUIDE_STACK);
	}

	ASSERT (loop == task_count);

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

	quicksort_entity_list (guide_list, task_count, priority);

	#if DEBUG_MODULE

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

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

		target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT);

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

	#endif

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

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

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

		target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT);

		persuer = get_local_entity_first_child (target, LIST_TYPE_TARGET);

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

			persuer = get_local_entity_child_succ (persuer, LIST_TYPE_TARGET);
		}
	}

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

	member = get_local_entity_first_child (group, LIST_TYPE_MEMBER);

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

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

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

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

							//
							// Range Check
							//

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

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

	free_mem (guide_list);

	free_mem (priority);

	free_mem (assigned_count);

	return valid_members;
}
Exemple #23
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 #24
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 #25
0
void repair_landing_entity_locks (pack_modes mode)
{

	entity
		*en,
		*guide,
		*group,
		*keysite,
		*landing,
		*task;

	int
		landing_flag;

	if (mode != PACK_MODE_SERVER_SESSION)
	{
		return;
	}

	en = get_local_entity_list ();

	while (en)
	{

		landing_flag = FALSE;

		// debug
		if (get_local_entity_type (en) != ENTITY_TYPE_GROUP)
		// debug
		{
	
			if ((get_local_entity_int_value (en, INT_TYPE_IDENTIFY_AIRCRAFT)) || (get_local_entity_int_value (en, INT_TYPE_IDENTIFY_VEHICLE)))
			{
	
				guide = get_local_entity_parent (en, LIST_TYPE_FOLLOWER);
	
				if (guide)
				{
	
					task = get_local_entity_parent (guide, LIST_TYPE_GUIDE);
	
					if (task)
					{
	
						switch (get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE))
						{
	
							case ENTITY_SUB_TYPE_TASK_LANDING:
							{
	
								//
								// LANDING
								//
						
								landing = get_local_entity_parent (task, LIST_TYPE_ASSIGNED_TASK);
		
								ASSERT (landing);
		
								#if DEBUG_MODULE
		
								debug_log ("EN_SESSN: LOCK_REPAIRING: %s landing lock for %s (%d) locks (total %d, free %d, landing %d, landed %d takeoff %d)", get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), get_local_entity_type_name (en), get_local_entity_index (en),
								get_local_entity_int_value (landing, INT_TYPE_TOTAL_LANDING_SITES),
								get_local_entity_int_value (landing, INT_TYPE_FREE_LANDING_SITES),
								get_local_entity_int_value (landing, INT_TYPE_LANDING_LOCK),
								get_local_entity_int_value (landing, INT_TYPE_LANDED_LOCK),
								get_local_entity_int_value (landing, INT_TYPE_TAKEOFF_LOCK));
		
								#endif
		
								notify_local_entity (ENTITY_MESSAGE_LOCK_LANDING_ROUTE, landing, en);
		
								landing_flag = TRUE;
	
								break;
							}
	
							case ENTITY_SUB_TYPE_TASK_LANDING_HOLDING:
							{
	
								//
								// LANDING HOLDING
								//
						
								landing_flag = TRUE;
	
								break;
							}
	
							case ENTITY_SUB_TYPE_TASK_TAKEOFF:
							{
			
								landing = get_local_entity_parent (task, LIST_TYPE_ASSIGNED_TASK);
		
								keysite = get_local_entity_parent (landing, LIST_TYPE_LANDING_SITE);
	
								#if DEBUG_MODULE
		
								debug_log ("EN_SESSN: LOCK_REPAIRING: %s takeoff lock for %s (%d) total %d, free %d, locks (landing %d, landed %d takeoff %d)", get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), get_local_entity_type_name (en), get_local_entity_index (en),
									get_local_entity_int_value (landing, INT_TYPE_TOTAL_LANDING_SITES),
									get_local_entity_int_value (landing, INT_TYPE_FREE_LANDING_SITES),
									get_local_entity_int_value (landing, INT_TYPE_LANDING_LOCK),
									get_local_entity_int_value (landing, INT_TYPE_LANDED_LOCK),
									get_local_entity_int_value (landing, INT_TYPE_TAKEOFF_LOCK));
		
								#endif
			
								notify_local_entity (ENTITY_MESSAGE_LOCK_TAKEOFF_ROUTE, landing, en);
	
								break;
							}
						}
					}
				}
	
				//
				// LANDED
				//
	
				if ((get_local_entity_int_value (en, INT_TYPE_LANDED)) || (landing_flag))
				{
	
					group = get_local_entity_parent (en, LIST_TYPE_MEMBER);
	
					keysite = get_local_entity_parent (group, LIST_TYPE_KEYSITE_GROUP);

					if (get_local_entity_type (keysite) != ENTITY_TYPE_KEYSITE)
					{
			
						ASSERT (get_local_entity_type (en) == ENTITY_TYPE_SHIP_VEHICLE);
			
						ASSERT (get_local_entity_type (keysite) == ENTITY_TYPE_FORCE);
			
						#if DEBUG_MODULE
			
						debug_log ("LANDING: %s. Not repairing locks", get_local_entity_string (en, STRING_TYPE_FULL_NAME));
			
						#endif

					}
					else
					{
		
						landing = get_local_entity_landing_entity (keysite, group_database [get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)].default_landing_type);
		
						#if DEBUG_MODULE
		
						debug_log ("EN_SESSN: LOCK_REPAIRING: %s landed site lock for %s (%d) total %d, free %d, locks (landing %d, landed %d takeoff %d)", get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), get_local_entity_type_name (en), get_local_entity_index (en),
							get_local_entity_int_value (landing, INT_TYPE_TOTAL_LANDING_SITES),
							get_local_entity_int_value (landing, INT_TYPE_FREE_LANDING_SITES),
							get_local_entity_int_value (landing, INT_TYPE_LANDING_LOCK),
							get_local_entity_int_value (landing, INT_TYPE_LANDED_LOCK),
							get_local_entity_int_value (landing, INT_TYPE_TAKEOFF_LOCK));
		
						#endif
			
						notify_local_entity (ENTITY_MESSAGE_LOCK_LANDING_SITE, landing, en);
					}
				}
			}
		}

		en = get_local_entity_succ (en);
	}
}
Exemple #26
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 #27
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);
		}
	}
}