Example #1
0
// create objects for all known observers in the game at level start
// call this before entering a mission
// this implies for the local player in the case of a client or for _all_ players in the case of a server
void multi_obs_level_init()
{
	int idx;

	// unset the OBS_PLAYER flag here for all net players
	for (idx = 0; idx < MAX_PLAYERS; idx++)
	{
		Net_players[idx].flags &= ~(NETINFO_FLAG_OBS_PLAYER);
	}

	// if i'm a client and I'm an observer, create an object for myself
	if (!(Net_player->flags & NETINFO_FLAG_AM_MASTER) && (Net_player->flags & NETINFO_FLAG_OBSERVER))
	{
		// create my own observer object and setup other misc. data
		multi_obs_create_observer_client();
	}
		// otherwise create stuff for all (permanent) observers in the game
	else
	{
		for (idx = 0; idx < MAX_PLAYERS; idx++)
		{
			if (MULTI_CONNECTED(Net_players[idx]) && MULTI_OBSERVER(Net_players[idx]))
			{
				// make an observer object for the guy
				multi_obs_create_observer(&Net_players[idx]);
			}
		}
	}
}
Example #2
0
// notify of a player leaving
void multi_respawn_player_leave(net_player *pl)
{
	// bogus
	if(pl == NULL){
		return;
	}
	if( MULTI_OBSERVER((*pl)) ){
		return;
	}
	if((Net_player == NULL) || !(Net_player->flags & NETINFO_FLAG_AM_MASTER)){
		return;
	}
	if(pl->p_info.p_objp == NULL){
		return;
	}

	// dogfight mode
	if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT)){
		return;
	}	

	// if we need to respawn this ai ship, add him to a list of ships to get respawned
	p_object *pobjp = pl->p_info.p_objp;
	if ( (pobjp->flags & P_OF_PLAYER_START) && (pobjp->respawn_count < Netgame.respawn) ){
		int i;

		for (i = 0; i < MAX_AI_RESPAWNS; i++ ) {
			if ( Ai_respawns[i].pobjp == NULL ) {
				Ai_respawns[i].pobjp = pobjp;
				Ai_respawns[i].timestamp = timestamp(AI_RESPAWN_TIME);
				break;
			}
		}
	}
}
// called once per frame to update the reticle gauges.  Makes calls to
// ship_dumbfire_threat() and ship_lock_threat() and updates Threat_flags.
void hud_update_reticle( player *pp )
{
	int rval;
	ship *shipp;

	// multiplayer clients won't call this routine
	if ( MULTIPLAYER_CLIENT || MULTI_OBSERVER(Net_players[MY_NET_PLAYER_NUM]))
		return;

	shipp = &Ships[Objects[pp->objnum].instance];

	if ( ship_dumbfire_threat(shipp) ) {
		pp->threat_flags |= THREAT_DUMBFIRE;
		pp->update_dumbfire_time = timestamp(THREAT_UPDATE_DUMBFIRE_TIME);
	}

	if ( timestamp_elapsed(pp->update_dumbfire_time) ) {
		pp->update_dumbfire_time = timestamp(THREAT_UPDATE_DUMBFIRE_TIME);
		pp->threat_flags &= ~THREAT_DUMBFIRE;
	}

	if ( timestamp_elapsed(pp->update_lock_time) ) {
		pp->threat_flags &= ~(THREAT_LOCK | THREAT_ATTEMPT_LOCK);
		pp->update_lock_time = timestamp(THREAT_UPDATE_LOCK_TIME);
		rval = ship_lock_threat(shipp);
		if ( rval == 1 ) {
			pp->threat_flags |= THREAT_ATTEMPT_LOCK;
		} else if ( rval == 2 ) {
			pp->threat_flags |= THREAT_LOCK;
		}
	}

	if(Player->threat_flags & THREAT_LOCK ) {
		// a less hacked up version of the missile launch warning
		hud_start_text_flash(XSTR("Launch", 1507), THREAT_LOCK_FLASH, fl2i(THREAT_LOCK_FLASH/2.0f));
	}

	if ( Player->threat_flags & (THREAT_ATTEMPT_LOCK) ) {
		if ( timestamp_elapsed(Threat_lock_timer) ) {
			Threat_lock_timer = timestamp(THREAT_LOCK_FLASH);
			
			Threat_lock_frame++;
			if ( Threat_lock_frame > 2 ) {
				Threat_lock_frame = 1;
			}
			if ( (Threat_lock_frame == 2) && (Player->threat_flags & THREAT_ATTEMPT_LOCK ) ) {
				snd_play( &Snds[ship_get_sound(Player_obj, SND_THREAT_FLASH)]);
			}
		}
	} 
}
// call once per level just before entering the mission
void multi_df_level_pre_enter()
{			
	int idx;

	// if we're not in dogfight mode, do nothing
	if(!(Netgame.type_flags & NG_TYPE_DOGFIGHT)){
		return;
	}

	// go through all player ships and make them hostile
	for(idx=0; idx<MAX_PLAYERS; idx++){
		if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_OBSERVER(Net_players[idx]) && (Net_players[idx].m_player != NULL) && (Net_players[idx].m_player->objnum >= 0) && (Objects[Net_players[idx].m_player->objnum].type == OBJ_SHIP)){
			Ships[Objects[Net_players[idx].m_player->objnum].instance].team = Iff_traitor;
		}
	}

	// 
}
Example #5
0
// get the total AWACS level for target to viewer
// < 0.0f		: untargetable
// 0.0 - 1.0f	: marginally targetable
// >= 1.0f			: fully targetable as normal
float awacs_get_level(object *target, ship *viewer, int use_awacs)
{
	Assert(target);	// Goober5000
	Assert(viewer);	// Goober5000

	vec3d dist_vec, subsys_pos;
	float closest = 0.0f;
	float test;
	int closest_index = -1;
	int idx, stealth_ship = 0, check_huge_ship = 0, friendly_stealth_invisible = 0;
	ship *shipp = NULL;
	ship_info *sip = NULL;

	int viewer_has_primitive_sensors = (viewer->flags[Ship::Ship_Flags::Primitive_sensors]);

	// calc distance from viewer to target
	vm_vec_sub(&dist_vec, &target->pos, &Objects[viewer->objnum].pos);
	int distance = (int) vm_vec_mag_quick(&dist_vec);

// redone by Goober5000
#define ALWAYS_TARGETABLE		1.5f
#define MARGINALLY_TARGETABLE	0.5f
#define UNTARGETABLE			-1.0f
#define FULLY_TARGETABLE		(viewer_has_primitive_sensors ? ((distance < viewer->primitive_sensor_range) ? MARGINALLY_TARGETABLE : UNTARGETABLE) : ALWAYS_TARGETABLE)

	// if the viewer is me, and I'm a multiplayer observer, its always viewable
	if ((viewer == Player_ship) && (Game_mode & GM_MULTIPLAYER) && (Net_player != NULL) && MULTI_OBSERVER(Net_players[MY_NET_PLAYER_NUM]))
		return ALWAYS_TARGETABLE;

	// check the targeting threshold
	if ((Hud_max_targeting_range > 0) && (distance > Hud_max_targeting_range)) {
		return UNTARGETABLE;
	}

	if (target->type == OBJ_SHIP) {
		// if no valid target then bail as never viewable
		if (target->instance < 0)
			return UNTARGETABLE;

		// Goober5000
		shipp = &Ships[target->instance];
		sip = &Ship_info[shipp->ship_info_index];
		stealth_ship = (shipp->flags[Ship::Ship_Flags::Stealth]);
		friendly_stealth_invisible = (shipp->flags[Ship::Ship_Flags::Friendly_stealth_invis]);

		check_huge_ship = (sip->is_huge_ship());
	}
	
	int nebula_enabled = (The_mission.flags[Mission::Mission_Flags::Fullneb]);

	// ships on the same team are always viewable
	if ((target->type == OBJ_SHIP) && (shipp->team == viewer->team))
	{
		// not necessarily now! -- Goober5000
		if ( !(stealth_ship && friendly_stealth_invisible) )
			return FULLY_TARGETABLE;
	}

	// check for a tagged ship. TAG'd ships are _always_ visible
	if (target->type == OBJ_SHIP)
	{
		Assert( shipp != NULL );
		if (shipp->tag_left > 0.0f || shipp->level2_tag_left > 0.0f)
			return FULLY_TARGETABLE;
	}
	
	// only check for Awacs if stealth ship or Nebula mission
	// determine the closest awacs on our team
	if ((stealth_ship || nebula_enabled) && use_awacs)
	{
		for (idx=0; idx<Awacs_count; idx++)
		{
			// if not on the same team as the viewer
			if (Awacs[idx].team != viewer->team)
				continue;

			// if this awacs source has somehow become invalid
			if (Awacs[idx].objp->type != OBJ_SHIP)
				continue;

			// get the subsystem position
			if (!get_subsystem_pos(&subsys_pos, Awacs[idx].objp, Awacs[idx].subsys))
				continue;

			// determine if its the closest
			// special case for HUGE_SHIPS
			if (check_huge_ship)
			{
				// check if inside bbox expanded by awacs_radius
				if (check_world_pt_in_expanded_ship_bbox(&subsys_pos, target, Awacs[idx].subsys->awacs_radius))
				{
					closest_index = idx;
					break;
				}
			}
			// not a huge ship
			else
			{
				// get distance from Subsys to target
				vm_vec_sub(&dist_vec, &subsys_pos, &target->pos);
				test = vm_vec_mag_quick(&dist_vec);

				if (test > Awacs[idx].subsys->awacs_radius)
					continue;

				if ((closest_index == -1) || (test < closest))
				{
					closest = test;
					closest_index = idx;
					break;
				}
			}
		}
	}

	// if this is a stealth ship
	if (stealth_ship)
	{
		// if the ship is within range of an awacs
		if (closest_index >= 0)
		{
			// if the nebula effect is active, stealth ships are only partially targetable
			if (nebula_enabled)
				return MARGINALLY_TARGETABLE;

			// otherwise it's targetable
			return FULLY_TARGETABLE;
		} 
		// otherwise its completely hidden
		else
		{
			return UNTARGETABLE;
		}
	}
	// all other ships
	else
	{
		// if this is not a nebula mission, its always targetable
		if (!nebula_enabled)
			return FULLY_TARGETABLE;

		// if the ship is within range of an awacs, its fully targetable
		if (closest_index >= 0)
			return FULLY_TARGETABLE;


		// fully targetable at half the nebula value

		// modify distance by species
		float scan_nebula_range = Neb2_awacs * Species_info[Ship_info[viewer->ship_info_index].species].awacs_multiplier;

		// special case for huge ship - check inside expanded bounding boxes
		if (check_huge_ship)
		{
			if (check_world_pt_in_expanded_ship_bbox(&Objects[viewer->objnum].pos, target, scan_nebula_range))
			{
				if (check_world_pt_in_expanded_ship_bbox(&Objects[viewer->objnum].pos, target, 0.5f * scan_nebula_range))
					return FULLY_TARGETABLE;

				return MARGINALLY_TARGETABLE;
			}
		} 
		// otherwise check straight up nebula numbers
		else
		{
			vm_vec_sub(&dist_vec, &target->pos, &Objects[viewer->objnum].pos);
			test = vm_vec_mag_quick(&dist_vec);

			if (test < (0.5f * scan_nebula_range))
				return FULLY_TARGETABLE;
			else if (test < scan_nebula_range)
				return MARGINALLY_TARGETABLE;
		}

		// untargetable at longer range
		return UNTARGETABLE;	
	}		
}
// create complete priority sorted escort list for all active ships
// escorts - array of escort info
// num_escorts - number of escorts requests in field of active ships
//	  This will be culled to MAX_ESCORTS, selecting the top set from escorts
void hud_create_complete_escort_list(escort_info *escorts, int *num_escorts)
{
	ship_obj *so;
	object *objp;	

	// start with none on list
	*num_escorts = 0;

	int idx;

	// multiplayer dogfight
	if(MULTI_DOGFIGHT){
		for(idx=0; idx<MAX_PLAYERS; idx++){
			// break out of the loop when we have reached our max
			if ( *num_escorts == MAX_COMPLETE_ESCORT_LIST ) {
				mprintf(("exceeded max ships in big escort list\n"));
				break;
			}		

			// is this a valid player			
			if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_OBSERVER(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx])){
				// add the ship
				escorts[*num_escorts].objnum = -1;
				escorts[*num_escorts].obj_signature = -1;
				escorts[*num_escorts].priority = -1;
				escorts[*num_escorts].np_id = Net_players[idx].player_id;
				escorts[*num_escorts].escort_hit_timer = 0;
				escorts[*num_escorts].escort_hit_next_flash = 0;
				escorts[*num_escorts].escort_show_bright = false;
				(*num_escorts)++;
			}
		}
	}
	// all others 
	else {
		for ( so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so) ) {
			Assert( so->objnum >= 0 && so->objnum < MAX_OBJECTS);
			if((so->objnum < 0) || (so->objnum >= MAX_OBJECTS)){
				continue;
			}
			objp = &Objects[so->objnum];
			Assert( objp->type == OBJ_SHIP );
			if(objp->type != OBJ_SHIP){
				continue;
			}

			// break out of the loop when we have reached our max
			if ( *num_escorts == MAX_COMPLETE_ESCORT_LIST ) {
				mprintf(("exceeded max ships in big escort list\n"));
				break;
			}		
			
			// only process ships that might be on the list
			if ( !(Ships[objp->instance].flags[Ship::Ship_Flags::Escort]) ){
				continue;
			}

			// only process ships that can be seen by sensors
			if ( (Ships[objp->instance].flags[Ship::Ship_Flags::Hidden_from_sensors]) ){
				continue;
			}

			// don't process most stealth ships
			if ( (Ships[objp->instance].flags[Ship::Ship_Flags::Stealth]) )
			{
				if ( Ships[objp->instance].team == Player_ship->team )
				{
					// friendly stealths are only not seen when explicitly specified
					if ( Ships[objp->instance].flags[Ship::Ship_Flags::Friendly_stealth_invis] )
					{
						continue;
					}
				}
				// non-friendly stealths are never seen
				else
				{
					continue;
				}
			}

			// don't process objects that should be dead
			if ( objp->flags[Object::Object_Flags::Should_be_dead] ) {
				continue;
			}

			// add the ship
			escorts[*num_escorts].objnum = so->objnum;
			escorts[*num_escorts].obj_signature = objp->signature;
			escorts[*num_escorts].priority = Ships[objp->instance].escort_priority;
			escorts[*num_escorts].np_id = -1;
			escorts[*num_escorts].escort_hit_timer = 0;
			escorts[*num_escorts].escort_hit_next_flash = 0;
			escorts[*num_escorts].escort_show_bright = false;
			(*num_escorts)++;			
		}
	}
}
Example #7
0
// create complete priority sorted escort list for all active ships
// escorts - array of escort info
// num_escorts - number of escorts requests in field of active ships
//	  This will be culled to MAX_ESCORTS, selecting the top set from escorts
void hud_create_complete_escort_list(escort_info *escorts, int *num_escorts)
{
	ship_obj *so;
	object *objp;	

	// start with none on list
	*num_escorts = 0;

	int idx;

	// multiplayer dogfight
	if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT)){
		for(idx=0; idx<MAX_PLAYERS; idx++){
			// break out of the loop when we have reached our max
			if ( *num_escorts == MAX_COMPLETE_ESCORT_LIST ) {
				mprintf(("exceeded max ships in big escort list"));
				break;
			}		

			// is this a valid player			
			if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_OBSERVER(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx])){
				// add the ship
				escorts[*num_escorts].objnum = -1;
				escorts[*num_escorts].obj_signature = -1;
				escorts[*num_escorts].priority = -1;
				escorts[*num_escorts].np_id = Net_players[idx].player_id;
				(*num_escorts)++;
			}
		}
	}
	// all others 
	else {
		for ( so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so) ) {
			Assert( so->objnum >= 0 && so->objnum < MAX_OBJECTS);
			if((so->objnum < 0) || (so->objnum >= MAX_OBJECTS)){
				continue;
			}
			objp = &Objects[so->objnum];
			Assert( objp->type == OBJ_SHIP );
			if(objp->type != OBJ_SHIP){
				continue;
			}

			// break out of the loop when we have reached our max
			if ( *num_escorts == MAX_COMPLETE_ESCORT_LIST ) {
				mprintf(("exceeded max ships in big escort list"));
				break;
			}		
			
			// only process ships that might be on the list
			if ( !(Ships[objp->instance].flags & SF_ESCORT) ){
				continue;
			}

			// only process ships that can be seen by sensors
			if ( (Ships[objp->instance].flags & SF_HIDDEN_FROM_SENSORS) ){
				continue;
			}

			// don't process most stealth ships
			if ( (Ships[objp->instance].flags2 & SF2_STEALTH) )
			{
				if ( Ships[objp->instance].team == Player_ship->team )
				{
					// friendly stealths are only not seen when explicitly specified
					if ( Ships[objp->instance].flags2 & SF2_FRIENDLY_STEALTH_INVIS )
					{
						continue;
					}
				}
				// non-friendly stealths are never seen
				else
				{
					continue;
				}
			}

			// don't process ships that are dying, or objects that should be dead
			if ( (Ships[objp->instance].flags & (SF_DYING|SF_DEPARTING)) || (objp->flags & OF_SHOULD_BE_DEAD) ){
				continue;
			}

			// add the ship
			escorts[*num_escorts].objnum = so->objnum;
			escorts[*num_escorts].obj_signature = objp->signature;
			escorts[*num_escorts].priority = Ships[objp->instance].escort_priority;
			escorts[*num_escorts].np_id = -1;
			(*num_escorts)++;			
		}
	}
}