Exemplo n.º 1
0
int clear_ship_fires (entity *ship_en, entity_sub_types type)
{
	entity
		*en;

	vec3d
		*pos;

	en = get_local_entity_first_child (ship_en, LIST_TYPE_SPECIAL_EFFECT);

	while (en)
	{
		if (en->type == ENTITY_TYPE_SMOKE_LIST)
		{
			if (get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE) == type)
			{
				pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

				if (pos->y < 0.0)
				{
					set_local_entity_float_value (en, FLOAT_TYPE_GENERATOR_LIFETIME, 0.0);
				}
			}
      }

		en = get_local_entity_child_succ (en, LIST_TYPE_SPECIAL_EFFECT);
	}

	return TRUE;
}
Exemplo n.º 2
0
static int response_to_unlink_parent (entity_messages message, entity *receiver, entity *sender, va_list pargs)
{

	list_types
		list_type;

	#if DEBUG_MODULE

	debug_log_entity_message (message, receiver, sender, pargs);

	#endif

	list_type = va_arg (pargs, list_types);

	if (list_type == LIST_TYPE_SPECIAL_EFFECT)
	{
	
		//
		// set the effect_lifetime so that it will be destroyed next update
		//
	
		set_local_entity_float_value (receiver, FLOAT_TYPE_EFFECT_LIFETIME, get_local_entity_float_value (receiver, FLOAT_TYPE_SPRITE_LIFETIME));
	}

	return (TRUE);
}
Exemplo n.º 3
0
static int response_to_unlink_parent (entity_messages message, entity *receiver, entity *sender, va_list pargs)
{
	list_types
		list_type;

	#if DEBUG_MODULE

	debug_log_entity_message (message, receiver, sender, pargs);

	#endif

	list_type = va_arg (pargs, list_types);

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

			set_local_entity_float_value (receiver, FLOAT_TYPE_AIR_RADAR_CONTACT_TIMEOUT, AIR_RADAR_CONTACT_TIMEOUT_INVALID);

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

			break;
		}
	}

	return (TRUE);
}
Exemplo n.º 4
0
void update_local_entity_view_interest_level (entity *en)
{
    float
    level;

    ASSERT (en);

    level = get_local_entity_float_value (en, FLOAT_TYPE_VIEW_INTEREST_LEVEL);

    if (level > 0.0)
    {
        level -= get_delta_time ();

        if (level < 0.0)
        {
            level = 0.0;
        }

        set_local_entity_float_value (en, FLOAT_TYPE_VIEW_INTEREST_LEVEL, level);
    }
}
Exemplo n.º 5
0
void pause_local_continuous_weapon_sound_effect (entity *en, entity_sub_types weapon_sub_type)
{
	entity_sub_types
		effect_sub_type;

	ASSERT (en);

	//
	// reset burst timer so that it can fire next time round
	//
	
	if (get_comms_model () == COMMS_MODEL_SERVER)
	{
		set_local_entity_float_value (en, FLOAT_TYPE_WEAPON_BURST_TIMER, 0.0);
	}

	effect_sub_type = weapon_database [weapon_sub_type].launch_sound_effect_sub_type;

	if (effect_sub_type != ENTITY_SUB_TYPE_EFFECT_SOUND_MISC)
	{
		pause_local_entity_sound_type (en, effect_sub_type, 0.5);
	}
}
Exemplo n.º 6
0
void update_session_sound_effects (entity *en)
{
	session
		*raw;

	entity
		*spec;

	vec3d
		*camera_pos;

	weathermodes
		current_weather_mode,
		target_weather_mode;

	float
		alt,
		trans,
		value,
		light_wind_sound_level,
		heavy_wind_sound_level,
		rain_sound_levels [WEATHERMODE_LAST];

	ASSERT (en);

	raw = (session *) get_local_entity_data (en);

	if (in_cockpit)
	{
		camera_pos = get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION);

		alt = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_RADAR_ALTITUDE);
	}
	else
	{
		camera_pos = get_local_entity_vec3d_ptr (get_camera_entity (), VEC3D_TYPE_POSITION);

		alt = get_local_entity_float_value (get_camera_entity (), FLOAT_TYPE_RADAR_ALTITUDE);
	}

	//
	// rain
	//

	memset (rain_sound_levels, 0, sizeof (float) * WEATHERMODE_LAST);

	if (camera_pos->y < get_cloud_3d_base_height ())
	{
		if ((!in_cockpit) && (alt >= SESSION_RAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE))
		{
			//
			// rain should only make a sound when it hits either the cockpit, or the ground
			//
		}
		else
		{
			get_session_weather_at_point (camera_pos, &current_weather_mode, &target_weather_mode, &trans);

			if (target_weather_mode == current_weather_mode)
			{
				rain_sound_levels [target_weather_mode] = 1.0;
				rain_sound_levels [current_weather_mode] = 1.0;
			}
			else
			{
				rain_sound_levels [target_weather_mode] = trans;
				rain_sound_levels [current_weather_mode] = (1.0 - trans);
			}

			if (!in_cockpit)
			{
				rain_sound_levels [target_weather_mode] *= (1.0 - (alt / SESSION_RAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE));
				rain_sound_levels [current_weather_mode] *= (1.0 - (alt / SESSION_RAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE));
			}
		}
	}
	
	//
	// wind
	//
	{
		float
			r,
			wind_speed;
	
		wind_speed = get_session_wind_velocity_at_point (camera_pos, NULL);

		if (wind_speed <= raw->wind_minimum_speed)
		{
			r = 0.0;
		}
		else if (wind_speed >= raw->wind_maximum_speed)
		{
			r = 1.0;
		}
		else
		{
			r = (wind_speed - raw->wind_minimum_speed) / (raw->wind_maximum_speed - raw->wind_minimum_speed);
		}
		
		ASSERT ((r >= 0.0) && (r <= 1.0));

		if (r == 0.0)
		{
			light_wind_sound_level = 0.0;

			heavy_wind_sound_level = 0.0;
		}
		else if (r < 0.5)
		{
			light_wind_sound_level = r * 2.0;

			heavy_wind_sound_level = 0.0;
		}
		else
		{
			light_wind_sound_level = 1.0 - ((r - 0.5) * 2.0);

			heavy_wind_sound_level = (r - 0.5) * 2.0;
		}
	}

	//
	// terrain
	//
	{
		float
			xpos,
			zpos;

		xpos = bound (camera_pos->x, MIN_MAP_X, MAX_MAP_X);
		zpos = bound (camera_pos->z, MIN_MAP_Z, MAX_MAP_Z);
		
		get_terrain_3d_types_in_sector (xpos, zpos);
	}

	//
	// set new values
	//

	spec = get_local_entity_first_child (en, LIST_TYPE_SPECIAL_EFFECT);

	while (spec)
	{
		switch (get_local_entity_int_value (spec, INT_TYPE_ENTITY_SUB_TYPE))
		{
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_LIGHT_RAIN:
			{
				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, rain_sound_levels [WEATHERMODE_LIGHT_RAIN]);

				break;
			}
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_HEAVY_RAIN:
			{
				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, rain_sound_levels [WEATHERMODE_HEAVY_RAIN]);

				break;
			}
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_LIGHT_WIND:
			{
				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, light_wind_sound_level);

				break;
			}
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_HEAVY_WIND:
			{
				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, heavy_wind_sound_level);

				break;
			}
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_SEA:
			{
				if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)
				{
					value = 0.0;
				}
				else
				{
					value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION);
	

					if (terrain_types_in_sector [TERRAIN_TYPE_SEA])
					{
						value += (0.5 * get_delta_time ());
					}
					else
					{
						value -= (0.5 * get_delta_time ());
					}

					value = bound (value, 0.0, 0.3);

					value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0);

					if (in_cockpit)
					{
						value *= 0.75;
					}
				}

				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value);

				break;
			}
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_JUNGLE:
			{
				if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)
				{
					value = 0.0;
				}
				else
				{
					value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION);


					if (terrain_types_in_sector [TERRAIN_TYPE_FOREST_TOP])
					{
						value += (0.5 * get_delta_time ());
					}
					else
					{
						value -= (0.5 * get_delta_time ());
					}

					value = bound (value, 0.0, 0.3);
					value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0);

					if (in_cockpit)
					{
						value *= 0.75;
					}
				}

				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value);

				break;
	        }
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMB1:
			{
				if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)
				{
					value = 0.0;
				}
				else
				{
					value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION);
	
					if (terrain_types_in_sector [TERRAIN_TYPE_RIVER])
					{
						value += (0.5 * get_delta_time ());
					}
					else
					{
						value -= (0.5 * get_delta_time ());
					}
	
					value = bound (value, 0.0, 0.3);

					value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0);

					if (in_cockpit)
					{
						value *= 0.75;
					}
				}

				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value);

				break;
            }
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMB2:
			{
				if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)
				{
					value = 0.0;
				}
				else
				{
					value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION);
	
					if (terrain_types_in_sector [TERRAIN_TYPE_RESERVOIR])
					{
						value += (0.5 * get_delta_time ());
					}
					else
					{
						value -= (0.5 * get_delta_time ());
					}
	
					value = bound (value, 0.0, 0.3);

					value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0);

					if (in_cockpit)
					{
						value *= 0.75;
					}
				}

				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value);

				break;
            }
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMB3:
			{
				if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)
				{
					value = 0.0;
				}
				else
				{
					value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION);
	
					if (terrain_types_in_sector [TERRAIN_TYPE_ALTERED_LAND1])
					{
						value += (0.5 * get_delta_time ());
					}
					else
					{
						value -= (0.5 * get_delta_time ());
					}
	
					value = bound (value, 0.0, 0.3);

					value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0);

					if (in_cockpit)
					{
						value *= 0.75;
					}
				}

				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value);

				break;
            }
			case ENTITY_SUB_TYPE_EFFECT_SOUND_AMB4:
			{
				if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)
				{
					value = 0.0;
				}
				else
				{
					value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION);
	
					if (terrain_types_in_sector [TERRAIN_TYPE_ALTERED_LAND2])
					{
						value += (0.5 * get_delta_time ());
					}
					else
					{
						value -= (0.5 * get_delta_time ());
					}
	
					value = bound (value, 0.0, 0.3);

					value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0);

					if (in_cockpit)
					{
						value *= 0.75;
					}
				}

				set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value);

				break;
			}
		}

		spec = get_local_entity_child_succ (spec, LIST_TYPE_SPECIAL_EFFECT);
	}
}
Exemplo n.º 7
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
	//
	////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////
	//
	//
	/////////////////////////////////////////////////////////////////
}
Exemplo n.º 8
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);
}
Exemplo n.º 9
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
	//
	/////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////
	//
	//
	/////////////////////////////////////////////////////////////////
}
Exemplo n.º 10
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
	//
	/////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////
	//
	//
	/////////////////////////////////////////////////////////////////
}
Exemplo n.º 11
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);
}
Exemplo n.º 12
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);
		}
	}
}
Exemplo n.º 13
0
static void ship_movement_get_waypoint_position (entity *en, vec3d *wp_pos)
{
	entity
		*wp,
		*group,
		*guide;

	float
		distance;

	vec3d
		*pos;

	ASSERT (en);

	ASSERT (wp_pos);

	group = get_local_entity_parent (en, LIST_TYPE_MEMBER);

	ASSERT (group);

	guide = get_local_entity_parent (en, LIST_TYPE_FOLLOWER);

	ASSERT (guide);

	wp = get_local_entity_parent (guide, LIST_TYPE_CURRENT_WAYPOINT);

	ASSERT (wp);

	//
	// Should vehicle follow leader, or follow guide in set waypoint formation?
	//
	
	if (get_local_entity_int_value (wp, INT_TYPE_MOBILE_FOLLOW_WAYPOINT_OFFSET))
	{
		vec3d
			offset;

		get_local_entity_vec3d (guide, VEC3D_TYPE_GUIDE_POSITION, wp_pos);

		get_local_entity_formation_position_offset (en, wp, &offset);

		wp_pos->x += offset.x;
		wp_pos->y += offset.y;
		wp_pos->z += offset.z;
	}
	else
	{
		//
		// Task leader follows guide,.... other members follow task leader
		//
	
		if (get_local_entity_int_value (en, INT_TYPE_TASK_LEADER))
		{
			get_local_entity_vec3d (guide, VEC3D_TYPE_GUIDE_POSITION, wp_pos);
		}
		else
		{
			//
			// set wp pos to offset from task leader
			//
	
			entity
				*task_leader;
	
			vec3d
				*xv,
				*leader_pos;
	
			formation_type
				*formation;
	
			int
				type,
				formation_count,
				formation_index,
				leader_formation_index;
	
			//
			// find task leader
			//

			task_leader = get_local_entity_ptr_value (guide, PTR_TYPE_TASK_LEADER);

			ASSERT (task_leader);
	
			//
			// get formation
			//
	
			type = get_local_entity_int_value (group, INT_TYPE_GROUP_FORMATION);
	
			formation = get_formation (type);
	
			formation_count = formation->number_in_formation;
	
			formation_index = get_local_entity_int_value (en, INT_TYPE_GROUP_MEMBER_NUMBER);
	
			leader_formation_index = get_local_entity_int_value (task_leader, INT_TYPE_GROUP_MEMBER_NUMBER);
	
			ASSERT (formation_index < formation_count);
			ASSERT (leader_formation_index < formation_count);
	
			//
			// calculate position
			//
	
			leader_pos = get_local_entity_vec3d_ptr (task_leader, VEC3D_TYPE_POSITION);
	
			xv = get_local_entity_vec3d_ptr (task_leader, VEC3D_TYPE_XV);
	
			//
			// take leader position and SUBTRACT leaders formation position (coz leader is not necessarily formation pos 0)
			//
			
			wp_pos->x = leader_pos->x - ((xv->x * formation->sites [leader_formation_index].x) + (xv->z * formation->sites [leader_formation_index].z));
			wp_pos->y = 0;
			wp_pos->z = leader_pos->z - ((xv->z * formation->sites [leader_formation_index].x) + (xv->x * formation->sites [leader_formation_index].z));
	
			//
			// then ADD members formation position
			//
	
			wp_pos->x += ((xv->x * formation->sites [formation_index].x) + (xv->z * formation->sites [formation_index].z));
			wp_pos->z += ((xv->z * formation->sites [formation_index].x) + (xv->x * formation->sites [formation_index].z));
		}
	}

	//
	// calculate distance of entity to desired position
	//

	pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

	distance = get_2d_range (pos, wp_pos);

	#if DEBUG_WAYPOINT_VECTOR
	
	if (distance > 0.0)
	{
		create_debug_3d_line (pos, wp_pos, sys_col_black, 0.0);
	}

	#endif

	set_local_entity_float_value (en, FLOAT_TYPE_DISTANCE, distance);
}
Exemplo n.º 14
0
void ship_vehicle_death_movement (entity *en)
{

	ship_vehicle
		*raw;

	float
		speed,
		heading,
		pitch,
		roll;

	vec3d
		*pos,
		*velocity,
		new_pos;

	raw = get_local_entity_data (en);

	//
	// work out new position 
	//

	velocity = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_MOTION_VECTOR);

	pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

	new_pos.x = pos->x + (velocity->x * get_entity_movement_delta_time());
	new_pos.y = pos->y + (velocity->y * get_entity_movement_delta_time());
	new_pos.z = pos->z + (velocity->z * get_entity_movement_delta_time());
	
	//
	// update velocity
	//

	velocity->x -= (velocity->x * 0.2 * get_entity_movement_delta_time ());
	velocity->z -= (velocity->z * 0.2 * get_entity_movement_delta_time ());
	velocity->y -= (SHIP_SINK_RATE * get_entity_movement_delta_time ());

	speed = get_3d_vector_magnitude (velocity);

	set_local_entity_float_value (en, FLOAT_TYPE_VELOCITY, speed);

	//
	// update attitude
	//
		
	heading = get_heading_from_attitude_matrix (raw->vh.mob.attitude);

	pitch = get_pitch_from_attitude_matrix (raw->vh.mob.attitude);

	pitch += (SHIP_SINK_DELTA_PITCH_RATE * get_entity_movement_delta_time());

	roll = get_roll_from_attitude_matrix (raw->vh.mob.attitude);
	
	roll += (SHIP_SINK_DELTA_ROLL_RATE * get_entity_movement_delta_time());

	get_3d_transformation_matrix (raw->vh.mob.attitude, heading, pitch, roll);

	//
	// set new position
	//

	set_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &new_pos);

	clear_ship_fires (en, ENTITY_SUB_TYPE_EFFECT_SMOKE_LIST_FIRE);
	clear_ship_fires (en, ENTITY_SUB_TYPE_EFFECT_SMOKE_LIST_EXPLOSION_TRAIL);

	//
	// remove ship if totally obscured (i.e. sunk)
	//

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{

		struct OBJECT_3D_BOUNDS
			*bounding_box;

		vec3d
			d;

		float
			obscured_altitude;

		bounding_box = get_object_3d_bounding_box (get_local_entity_int_value (en, INT_TYPE_OBJECT_3D_SHAPE));

		d.x = bounding_box->xmax - bounding_box->xmin;
		d.y = bounding_box->ymax - bounding_box->ymin;
		d.z = bounding_box->zmax - bounding_box->zmin;

		obscured_altitude = -(0.5 * get_3d_vector_magnitude (&d));

		if (new_pos.y < obscured_altitude)
		{
			//
			// ship is no longer visible
			//

			destroy_client_server_entity_family (en);
		}
	}
}
Exemplo n.º 15
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);
    }
}
Exemplo n.º 16
0
static void unpack_local_data (entity *en, entity_types type, pack_modes mode)
{
	ASSERT ((mode >= 0) && (mode < NUM_PACK_MODES));

	switch (mode)
	{
		////////////////////////////////////////
		case PACK_MODE_SERVER_SESSION:
		case PACK_MODE_CLIENT_SESSION:
		////////////////////////////////////////
		{

			int
				index;

			routed_vehicle
				*raw;

			node_link_data
				*route_data;

			//
			// create entity
			//

			index = unpack_entity_safe_index ();

			en = get_free_entity (index);

			set_local_entity_type (en, type);

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

			set_local_entity_data (en, raw);

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

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

			unpack_vehicle_data (en, &raw->vh, mode);

			if (unpack_int_value (en, INT_TYPE_VALID))
			{

				raw->vh.mob.velocity = 0.0;

				raw->desired_velocity = 0.0;
			}
			else
			{

				raw->vh.mob.velocity = unpack_float_value (en, FLOAT_TYPE_LOW_VELOCITY);

				raw->desired_velocity = unpack_float_value (en, FLOAT_TYPE_DESIRED_VELOCITY);
			}

			//
			// unpack routed data
			//

			if (unpack_int_value (en, INT_TYPE_VALID))
			{
	
				raw->sub_waypoint_count = unpack_int_value (en, INT_TYPE_SUB_WAYPOINT_COUNT);
	
				raw->waypoint_next_index = unpack_int_value (en, INT_TYPE_WAYPOINT_NEXT_INDEX);
	
				raw->waypoint_this_index = unpack_int_value (en, INT_TYPE_WAYPOINT_THIS_INDEX);
			}

			//
			// turn lights on if necessary
			//

			set_vehicle_headlight_state (en, raw->vh.lights_on);

			//
			// setup waypoint route pointer
			//

			#if DEBUG_MODULE

			debug_log ("ROUTED ENTITY PACK: client setting up waypoint list pointer");

			#endif

			route_data = get_road_sub_route (raw->waypoint_this_index, raw->waypoint_next_index, &index, NULL);

			if ((route_data) && (route_data->link_positions))
			{

				raw->sub_route = route_data;
			}
			else
			{

				if ((raw->waypoint_this_index + raw->waypoint_next_index) != 0)
				{

					debug_log ("RV_PACK: WARNING NO SUB ROUTE FOUND BETWEEN %d AND %d", raw->waypoint_this_index, raw->waypoint_next_index);
				}
			}

			//
			// radar dish rotation (ok to use a random number as this is for visual effect only)
			//

			raw->vh.radar_rotation_state = frand1 ();

			set_routed_vehicle_id_number (en);

			set_initial_rotation_angle_of_routed_vehicle_wheels (raw->vh.inst3d);

			//
			// link into system
			//

			insert_local_entity_into_parents_child_list (en, LIST_TYPE_VIEW, get_camera_entity (), NULL);

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

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

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

			//
			// attached smoke lists must be unpacked after the entity is linked into the world
			//

			unpack_routed_vehicle_meta_smoke_lists (en, mode);
	
			unpack_mobile_local_sound_effects (en, mode);

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

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

			vec3d
				position;

			matrix3x3
				attitude;

			int
				sub_waypoint_count;

			//
			// unpack all data (even if the echoed data is to be ignored)
			//

			unpack_vec3d (en, VEC3D_TYPE_POSITION, &position);

			unpack_attitude_matrix (en, attitude);

			sub_waypoint_count = unpack_int_value (en, INT_TYPE_SUB_WAYPOINT_COUNT);

			set_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &position);

			set_local_entity_attitude_matrix (en, attitude);

			set_local_entity_int_value (en, INT_TYPE_SUB_WAYPOINT_COUNT, sub_waypoint_count);

			// Vehicle is moving so sleep must equal 0
			set_local_entity_float_value (en, FLOAT_TYPE_SLEEP, 0.0);

			break;
		}
	}
}
Exemplo n.º 17
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;
}
Exemplo n.º 18
0
static void unpack_local_data (entity *en, entity_types type, pack_modes mode)
{
   ASSERT ((mode >= 0) && (mode < NUM_PACK_MODES));

   switch (mode)
   {
      ////////////////////////////////////////
      case PACK_MODE_SERVER_SESSION:
      case PACK_MODE_CLIENT_SESSION:
		case PACK_MODE_BROWSE_SESSION:
      ////////////////////////////////////////
		{

			break;
		}

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

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

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

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

			//
			// rain effect
			//

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

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

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

			//
			// wind effect
			//

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

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

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

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

			//

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

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

			set_display_campaign_timer_valid (TRUE);

			break;
		}
	}
}
Exemplo n.º 19
0
entity *regen_update (entity *en)
{

	regen_management_element
		*m1;

	entity_sub_types
		member_type,
		group_type;

	entity
		*wp,
		*task,
		*group,
		*member,
		*building,
		*force_en,
		*landing,
		*keysite;

	unsigned int
		member_number;

	int
		reserve_count;

	force
		*force_raw;

	regen
		*raw;

	regen_list_element
		*e1;

	raw = (regen *) get_local_entity_data (en);

	wp = get_local_entity_parent (en, LIST_TYPE_CURRENT_WAYPOINT);

	task = get_local_entity_parent (wp, LIST_TYPE_WAYPOINT);

	landing = get_local_entity_parent (task, LIST_TYPE_UNASSIGNED_TASK);
			
	keysite = get_local_entity_parent (landing, LIST_TYPE_LANDING_SITE);

	force_en = get_local_force_entity ((entity_sides) raw->side);

	force_raw = (force *) get_local_entity_data (force_en);

	group_type = NUM_ENTITY_SUB_TYPE_GROUPS;

	m1 = &regen_manager [raw->side][raw->sub_type];

	//
	// is there anything in the regen queues?
	//
	
	if (m1->count == 0)
	{
		return NULL;
	}

	//
	// Can regen operate
	//

	building = raw->member_root.first_child;

	if ((!get_local_entity_int_value (building, INT_TYPE_ALIVE)) || (get_local_entity_int_value (keysite, INT_TYPE_KEYSITE_USABLE_STATE) != KEYSITE_STATE_USABLE))
	{
		#if DEBUG_MODULE

		debug_log ("RG_UPDT: keysite %s too damaged to regen", get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME));

		#endif

		return NULL;
	}

	e1 = &regen_queue [raw->side][raw->sub_type][m1->front];

	ASSERT (e1->type != -1);
	ASSERT (e1->sub_type != -1);
	ASSERT (e1->group != -1);

	// is there a reserve of this type?
	if ((e1->type == ENTITY_TYPE_FIXED_WING) || (e1->type == ENTITY_TYPE_HELICOPTER))
	{
		reserve_count = force_raw->force_info_reserve_hardware[aircraft_database[e1->sub_type].force_info_catagory];
	}
	else
	{
		reserve_count = force_raw->force_info_reserve_hardware[vehicle_database[e1->sub_type].force_info_catagory];
	}

	if (reserve_count <= 0)
	{
		return NULL;
	}

	#if DEBUG_MODULE

	debug_log ("RG_UPDT: Trying to Regen %s Sub Type %d at %s - reserve count %d",
								get_entity_type_name (e1->type), e1->sub_type,
								get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), reserve_count);

	#endif

	//
	// Don't regen if PLAYER landed there
	//

	group = get_local_entity_first_child (keysite, LIST_TYPE_KEYSITE_GROUP);

	while (group)
	{
		member = get_local_entity_first_child (group, LIST_TYPE_MEMBER);

		while (member)
		{

			if (get_local_entity_int_value (member, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
			{

				if (get_local_entity_int_value (member, INT_TYPE_LANDED))
				{
					#if DEBUG_MODULE

					debug_log ("RG_UPDT: PLAYER landed at keysite %s, can't regen", get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME));

					#endif

					return NULL;
				}
			}

			member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER);
		}

		group = get_local_entity_child_succ (group, LIST_TYPE_KEYSITE_GROUP);
	}

	group_type = e1->group;
	
	member_type = e1->sub_type;

	////////////////////////////////////////////////////////////////////////////
	// Dont regen people or transport aircraft in apache havoc campaign as airport might not be correct (landing routes etc)
	////////////////////////////////////////////////////////////////////////////
	if (get_local_entity_int_value (get_session_entity (), INT_TYPE_CAMPAIGN_REQUIRES_APACHE_HAVOC))
	{

		switch (get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE))
		{

			case ENTITY_SUB_TYPE_REGEN_PEOPLE:
			{

				#if DEBUG_MODULE

				debug_log ("RG_UPDT: Stopping Regening People - wrong warzone");

				#endif

				return NULL;
			}

			case ENTITY_SUB_TYPE_REGEN_FIXED_WING:
			{

				if (group_database [group_type].default_landing_type == ENTITY_SUB_TYPE_LANDING_FIXED_WING_TRANSPORT)
				{

					#if DEBUG_MODULE

					debug_log ("RG_UPDT: Stopping Regening Transport aircraft - wrong warzone");

					#endif

					return NULL;
				}
			}
		}
	}
	////////////////////////////////////////////////////////////////////////////
	// Dont regen people or transport aircraft in apache havoc campaign as airport might not be correct (landing routes etc)
	////////////////////////////////////////////////////////////////////////////

	if (group_type != NUM_ENTITY_SUB_TYPE_GROUPS)
	{

		int
			route_node;

		entity
			*building,
			*member,
			*guide,
			*group = NULL;

		group = create_landing_faction_members (keysite, member_type, group_type, 1, wp, &raw->position);

		if (group)
		{

			//
			// Assign closest route_node (only needed for routed vehicles)
			//

			if (get_local_entity_int_value (group, INT_TYPE_FRONTLINE))
			{
	
				route_node = get_closest_side_road_node ((entity_sides) get_local_entity_int_value (group, INT_TYPE_SIDE), &raw->position, 5 * KILOMETRE);
	
				set_client_server_entity_int_value (group, INT_TYPE_ROUTE_NODE, route_node);
			}

			//
			//
			//
			
			member = get_local_entity_first_child (group, LIST_TYPE_MEMBER);

			//
			// close members doors
			//

			close_client_server_entity_cargo_doors (member);

			close_client_server_entity_loading_doors (member);

			//
			// open building doors
			//

			building = get_local_entity_first_child (en, LIST_TYPE_MEMBER);

			open_client_server_entity_loading_doors (building);

			set_local_entity_float_value (building, FLOAT_TYPE_LOADING_DOOR_TIMER, 30.0);

			//
			// create guide entity for task (TEST)
			//

			// Debug for Transport aircraft.
			// Locate nearest Transport landing wp and insert into it
			if (group_database [group_type].default_landing_type == ENTITY_SUB_TYPE_LANDING_FIXED_WING_TRANSPORT)
			{

				float
					range,
					best_range;

				entity
					*transport_wp,
					*transport_task,
					*transport_landing;

				best_range = 999999999.0;

				transport_landing = get_local_entity_landing_entity (keysite, ENTITY_SUB_TYPE_LANDING_FIXED_WING_TRANSPORT);

				if (transport_landing)
				{
	
					transport_task = get_local_landing_entity_task (transport_landing, ENTITY_SUB_TYPE_TASK_LANDING);

					ASSERT (transport_task);
	
					transport_wp = get_local_entity_first_child (transport_task, LIST_TYPE_WAYPOINT);

					ASSERT (transport_wp);
	
					while (transport_wp)
					{
	
						range = get_sqr_2d_range (get_local_entity_vec3d_ptr (transport_wp, VEC3D_TYPE_POSITION), get_local_entity_vec3d_ptr (building, VEC3D_TYPE_POSITION));
	
						if (range < best_range)
						{
	
							wp = transport_wp;
	
							task = transport_task;
	
							best_range = range;
						}
	
						transport_wp = get_local_entity_child_succ (transport_wp, LIST_TYPE_WAYPOINT);
					}
				}
			}
			// Debug for Transport aircraft.

			member_number = get_local_entity_int_value (member, INT_TYPE_GROUP_MEMBER_NUMBER);

			guide = create_client_server_guide_entity (task, wp, (1 << member_number));

			attach_group_to_guide_entity (group, guide);

			attach_group_member_to_guide_entity (member, guide);

			//#if DEBUG_MODULE
			{

				entity
					*keysite;

				keysite = get_local_entity_parent (landing, LIST_TYPE_LANDING_SITE);

				member = get_local_entity_first_child (group, LIST_TYPE_MEMBER);

				debug_log ("RG_UPDT: %s creating %s (%d) at keysite %s free landing sites %d, reserved %d, lock %d, available lock: %d",
						entity_side_names [get_local_entity_int_value (keysite, INT_TYPE_SIDE)],
						get_local_entity_type_name (member),
						get_local_entity_index (member),
						get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), 
						get_local_entity_int_value (landing, INT_TYPE_FREE_LANDING_SITES),
						get_local_entity_int_value (landing, INT_TYPE_RESERVED_LANDING_SITES),
						get_local_entity_int_value (landing, INT_TYPE_LANDING_LOCK),
						check_available_landing_route_lock (landing)
						);

				if ((e1->type == ENTITY_TYPE_FIXED_WING) || (e1->type == ENTITY_TYPE_HELICOPTER))
				{
					debug_log("%s reserves left: %d",
							force_info_catagory_names[aircraft_database[e1->sub_type].force_info_catagory],
							force_raw->force_info_reserve_hardware[aircraft_database[e1->sub_type].force_info_catagory]
							);
				}
				else
				{
					debug_log("%s reserves left: %d",
							force_info_catagory_names[vehicle_database[e1->sub_type].force_info_catagory],
							force_raw->force_info_reserve_hardware[vehicle_database[e1->sub_type].force_info_catagory]
							);
				}

			}
			//#endif

			#if DEBUG_MODULE
			switch (e1->type)
			{
				case ENTITY_TYPE_FIXED_WING:
				case ENTITY_TYPE_HELICOPTER:
				{
					ASSERT (regen_ac_debug[e1->sub_type] > 0);

					break;
				}
				
				case ENTITY_TYPE_ROUTED_VEHICLE:
				case ENTITY_TYPE_SHIP_VEHICLE:
				case ENTITY_TYPE_PERSON:
				{
					ASSERT (regen_vh_debug[e1->sub_type] > 0);

					break;
				}
				
				default:
				{
					debug_fatal ("RG_UPDT: Unknown entity type for debug");
				}
				
			}
			#endif

			// update markers
			regen_queue_use ((entity_sides) raw->side, (raw->sub_type));

			return member;
		}
	}
	else
	{
		#if DEBUG_MODULE >= 2

		debug_log ("RG_UPDT: not creating anything at keysite %s free landing sites %d, reserved %d, lock %d",
						get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), 
						get_local_entity_int_value (landing, INT_TYPE_FREE_LANDING_SITES),
						get_local_entity_int_value (landing, INT_TYPE_RESERVED_LANDING_SITES),
						check_available_landing_route_lock (landing));

		#endif
	}

	return NULL;
}