예제 #1
0
int hud_abort_lock()
{
	int target_team;

	target_team = obj_team(&Objects[Player_ai->target_objnum]);

	if ( Player_ship->weapons.num_secondary_banks <= 0 ) {
		return 1;
	}

	if ( Player_ship->weapons.current_secondary_bank < 0 ) {
		return 1;
	}

	// check to see if there are any missile to fire.. we don't want to show the 
	// lock indicator if there are no missiles to fire.
	if ( !ship_secondary_bank_has_ammo(Player_obj->instance) ) {
		return 1;
	}

	if ( Player_ship->flags[Ship::Ship_Flags::No_secondary_lockon] ) {
		return 1;
	}

	// if we're on the same team and the team doesn't attack itself, then don't lock!
	if ((Player_ship->team == target_team) && (!iff_x_attacks_y(Player_ship->team, target_team)))
	{
		// if we're in multiplayer dogfight, ignore this
		if(!MULTI_DOGFIGHT) {
			return 1;
		}
	}

	return 0;
}
예제 #2
0
int hud_abort_lock()
{
	int target_team;

	target_team = obj_team(&Objects[Player_ai->target_objnum]);

	if (Player_ship->weapons.num_secondary_banks <= 0)
	{
		return 1;
	}

	if (Player_ship->weapons.current_secondary_bank < 0)
	{
		return 1;
	}

	// check to see if there are any missile to fire.. we don't want to show the 
	// lock indicator if there are no missiles to fire.
	if (!ship_secondary_bank_has_ammo(Player_obj->instance))
	{
		return 1;
	}

	// if we're on the same team and the team doesn't attack itself, then don't lock!
	if ((Player_ship->team == target_team) && (!iff_x_attacks_y(Player_ship->team, target_team)))
	{
		// if we're in multiplayer dogfight, ignore this
		if (!((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT)))
		{
			return 1;
		}
	}

	weapon_info* wip = &Weapon_info[Player_ship->weapons.secondary_bank_weapons[Player_ship->weapons.
		current_secondary_bank]];
	object* target_obj = &Objects[Player_ai->target_objnum];

	if (target_obj->type == OBJ_SHIP)
	{
		if (target_obj->instance >= 0 && Ships[target_obj->instance].ship_info_index >= 0)
		{
			ship_info* sip = &Ship_info[Ships[target_obj->instance].ship_info_index];

			bool is_weapon_huge_or_bomb = ((wip->wi_flags & (WIF_HUGE | WIF_BOMB)) != 0);
			bool is_target_small_ship = ((sip->flags & (SIF_SMALL_SHIP)) != 0);

			if (is_weapon_huge_or_bomb && is_target_small_ship)
			{
				return 1;
			}
		}
	}

	return 0;
}
예제 #3
0
/**
 * Rather slower, since it has to construct a mask
 *
 * @param attackee_team Team of attacker
 * @return Bitmask
 */
int iff_get_attacker_mask(int attackee_team)
{
	Assert(attackee_team >= 0 && attackee_team < Num_iffs);

	int i, attacker_bitmask = 0;
	for (i = 0; i < Num_iffs; i++)
	{
		if (iff_x_attacks_y(i, attackee_team))
			attacker_bitmask |= iff_get_mask(i);
	}

	return attacker_bitmask;
}
// kill_id is the object signature of the guy who got the credit for the kill (may be -1, if no one got it)
// this is to ensure that you don't also get an assist if you get the kill.
void scoring_eval_assists(ship *sp,int killer_sig, bool is_enemy_player)
{
	int idx;
	player *plr;
	float scoring_scale_by_damage = 1;	// percentage to scale the score by if we score based on the amount of damage caused
	int assist_score; 
	int net_player_num;
	float scoring_scale_factor;


	// multiplayer clients bail here
	if(MULTIPLAYER_CLIENT){
		return;
	}
		
	// evaluate each damage slot to see if it did enough to give the assis
	for(idx=0;idx<MAX_DAMAGE_SLOTS;idx++){
		// if this slot did enough damage to get an assist
		if(((sp->damage_ship[idx]/sp->total_damage_received) >= Assist_percentage) || (The_mission.ai_profile->flags & AIPF_ASSIST_SCORING_SCALES_WITH_DAMAGE)){
			// get the player which did this damage (if any)
			plr = NULL;
			
			// multiplayer
			if(Game_mode & GM_MULTIPLAYER){
				net_player_num = multi_find_player_by_signature(sp->damage_ship_id[idx]);
				if(net_player_num != -1){
					plr = Net_players[net_player_num].m_player;
				}
			}
			// single player
			else {
				if(Objects[Player->objnum].signature == sp->damage_ship_id[idx]){
					plr = Player;
				}
			}

			// if we found a player, give him the assist if he attacks it
			if ((plr != NULL) && (iff_x_attacks_y(Ships[Objects[plr->objnum].instance].team, sp->team)) && (killer_sig != Objects[plr->objnum].signature))
			{
				// player has to equal the threshold to get an assist
				if ((sp->damage_ship[idx]/sp->total_damage_received) >= Assist_percentage) {
					plr->stats.m_assists++;	
					nprintf(("Network","-==============GAVE PLAYER %s AN ASSIST=====================-\n",plr->callsign));
				}
				
				// Don't scale in TvT and dogfight
				if (is_enemy_player) {
					Assert(Game_mode & GM_MULTIPLAYER); 
					scoring_scale_factor = 1.0f;
				}
				else {
					scoring_scale_factor = scoring_get_scale_factor();
				}


				// maybe award assist points based on damage
				if (The_mission.ai_profile->flags & AIPF_ASSIST_SCORING_SCALES_WITH_DAMAGE) {
					scoring_scale_by_damage = (sp->damage_ship[idx]/sp->total_damage_received);
					assist_score = (int)(sp->score * scoring_scale_factor * scoring_scale_by_damage);
					plr->stats.m_score += assist_score;
				}
				// otherwise give the points based on the percentage in the mission file
				else {
					assist_score = (int)(sp->score * sp->assist_score_pct * scoring_scale_factor );
					plr->stats.m_score += assist_score;
				}

#ifdef SCORING_DEBUG

				// DEBUG CODE TO TEST NEW SCORING
				char score_text[1024] = "";
				sprintf(score_text, "SCORING : %s gets %d pts for getting an assist\n", plr->callsign, assist_score);							
				if (MULTIPLAYER_MASTER) {		
					send_game_chat_packet(Net_player, score_text, MULTI_MSG_ALL);								
				} 
				HUD_printf(score_text);
				mprintf ((score_text));
#endif
			}
		}
	}
}
예제 #5
0
/**
 * @brief Return if the specified object is visible on the radar
 *
 * @param objp The object which should be checked
 * @return A RadarVisibility enum specifying the visibility of the specified object
 */
RadarVisibility radar_is_visible( object *objp )
{
	Assert( objp != NULL );

	if (objp->flags & OF_SHOULD_BE_DEAD)
	{
		return NOT_VISIBLE;
	}

	vec3d pos, tempv;
	float awacs_level, dist, max_radar_dist;
	vec3d world_pos = objp->pos;
	SCP_list<CJumpNode>::iterator jnp;

	// get team-wide awacs level for the object if not ship
	int ship_is_visible = 0;
	if (objp->type == OBJ_SHIP) {
		if (Player_ship != NULL) {
			if (ship_is_visible_by_team(objp, Player_ship)) {
				ship_is_visible = 1;
			}
		}
	}

	// only check awacs level if ship is not visible by team
	awacs_level = 1.5f;
	if (Player_ship != NULL && !ship_is_visible) {
		awacs_level = awacs_get_level(objp, Player_ship);
	}

	// if the awacs level is unviewable - bail
	if(awacs_level < 0.0f && !See_all){
		return NOT_VISIBLE;
	}

	// Apply object type filters	
	switch (objp->type)
	{
		case OBJ_SHIP:
			if (Ships[objp->instance].flags & SIF_STEALTH)
				return NOT_VISIBLE;

			// Ships that are warp in in are not visible on the radar
			if (Ships[objp->instance].flags & SF_ARRIVING_STAGE_1)
				return NOT_VISIBLE;

			break;
		
		case OBJ_JUMP_NODE:
		{
			for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
				if(jnp->GetSCPObject() == objp)
					break;
			}
			
			// don't plot hidden jump nodes
			if ( jnp->IsHidden() )
				return NOT_VISIBLE;

			// filter jump nodes here if required
			break;
		}

		case OBJ_WEAPON:
		{
			// if not a bomb, return
			if ( !(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags2 & WIF2_SHOWN_ON_RADAR) )
				if ( !(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags & WIF_BOMB) )
					return NOT_VISIBLE;

			// if explicitly hidden, return
			if (Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags2 & WIF2_DONT_SHOW_ON_RADAR)
				return NOT_VISIBLE;

			// if we don't attack the bomb, return
			if ( (!(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags2 & WIF2_SHOW_FRIENDLY)) && (!iff_x_attacks_y(Player_ship->team, obj_team(objp))))
				return NOT_VISIBLE;

			// if a local ssm is in subspace, return
			if (Weapons[objp->instance].lssm_stage == 3)
				return NOT_VISIBLE;

			break;
		}

		// if any other kind of object, don't show it on radar
		default:
			return NOT_VISIBLE;
	}
	
	vm_vec_sub(&tempv, &world_pos, &Player_obj->pos);
	vm_vec_rotate(&pos, &tempv, &Player_obj->orient);

	// Apply range filter
	dist = vm_vec_dist(&world_pos, &Player_obj->pos);
	max_radar_dist = Radar_ranges[HUD_config.rp_dist];
	if (dist > max_radar_dist) {
		return NOT_VISIBLE;
	}
	
	if (objp->type == OBJ_SHIP)
	{
		// ships specifically hidden from sensors
		if (Ships[objp->instance].flags & SF_HIDDEN_FROM_SENSORS)
			return DISTORTED;

		// determine if its AWACS distorted
		if (awacs_level < 1.0f)
			return DISTORTED;
	}
	
	return VISIBLE;
}
예제 #6
0
void radar_plot_object( object *objp )
{
	vec3d pos, tempv;
	float awacs_level, dist, max_radar_dist;
	vec3d world_pos = objp->pos;
	SCP_list<CJumpNode>::iterator jnp;

	// don't process anything here.  Somehow, a jumpnode object caused this function
	// to get entered on server side.
	if( Game_mode & GM_STANDALONE_SERVER ){
		return;
	}

	// multiplayer clients ingame joining should skip this function
	if ( MULTIPLAYER_CLIENT && (Net_player->flags & NETINFO_FLAG_INGAME_JOIN) ){
		return;
	}

	// get team-wide awacs level for the object if not ship
	int ship_is_visible = 0;
	if (objp->type == OBJ_SHIP) {
		if (Player_ship != NULL) {
			if (ship_is_visible_by_team(objp, Player_ship)) {
				ship_is_visible = 1;
			}
		}
	}

	// only check awacs level if ship is not visible by team
	awacs_level = 1.5f;
	if (Player_ship != NULL && !ship_is_visible) {
		awacs_level = awacs_get_level(objp, Player_ship);
	}

	// if the awacs level is unviewable - bail
	if(awacs_level < 0.0f && !See_all){
		return;
	}

	// Apply object type filters	
	switch (objp->type)
	{
		case OBJ_SHIP:
			// Place to cull ships, such as NavBuoys		
			break;
		
		case OBJ_JUMP_NODE:
		{
			for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
				if(jnp->GetSCPObject() == objp)
					break;
			}
			
			// don't plot hidden jump nodes
			if ( jnp->IsHidden() )
				return;

			// filter jump nodes here if required
			break;
		}

		case OBJ_WEAPON:
		{
			// if not a bomb, return
			if ( !(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags2 & WIF2_SHOWN_ON_RADAR) )
				if ( !(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags & WIF_BOMB) )
					return;

			// if explicitly hidden, return
			if (Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags2 & WIF2_DONT_SHOW_ON_RADAR)
				return;

			// if we don't attack the bomb, return
			if ( (!(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags2 & WIF2_SHOW_FRIENDLY)) && (!iff_x_attacks_y(Player_ship->team, obj_team(objp))))
				return;

			// if a local ssm is in subspace, return
			if (Weapons[objp->instance].lssm_stage == 3)
				return;

			// if corkscrew missile use last frame pos for pos
			if ( (Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags & WIF_CORKSCREW) )
				world_pos = objp->last_pos;

			break;
		}

		// if any other kind of object, don't show it on radar
		default:
			return;
	}

	// Retrieve the eye orientation so we can position the blips relative to it
	matrix eye_orient;

	if (Player_obj->type == OBJ_SHIP) 
		ship_get_eye(&tempv, &eye_orient, Player_obj, false , false);
	else
		eye_orient = Player_obj->orient;

	// JAS -- new way of getting the rotated point that doesn't require this to be
	// in a g3_start_frame/end_frame block.
	vm_vec_sub(&tempv, &world_pos, &Player_obj->pos);
	vm_vec_rotate(&pos, &tempv, &eye_orient);

	// Apply range filter
	dist = vm_vec_dist(&world_pos, &Player_obj->pos);
	max_radar_dist = Radar_ranges[HUD_config.rp_dist];
	if (dist > max_radar_dist) {
		return;
	}

	// determine the range within which the radar blip is bright
	if (timestamp_elapsed(Radar_calc_bright_dist_timer))
	{
		Radar_calc_bright_dist_timer = timestamp(1000);
		Radar_bright_range = player_farthest_weapon_range();
		if (Radar_bright_range <= 0)
			Radar_bright_range = 1500.0f;
	}

	blip *b;
	int blip_bright = 0;
	int blip_type = 0;

	if (N_blips >= MAX_BLIPS)
	{
		return;
	}

	b = &Blips[N_blips];
	b->flags = 0;

	// bright if within range
	blip_bright = (dist <= Radar_bright_range);

	// flag the blip as a current target if it is
	if (OBJ_INDEX(objp) == Player_ai->target_objnum)
	{
		b->flags |= BLIP_CURRENT_TARGET;
		blip_bright = 1;
	}

	radar_stuff_blip_info(objp, blip_bright, &b->blip_color, &blip_type);

	if (blip_bright)
		list_append(&Blip_bright_list[blip_type], b);
	else
		list_append(&Blip_dim_list[blip_type], b);

	b->position = pos;
	b->dist = dist;
	b->objp = objp;
	b->radar_image_2d = -1;
	b->radar_color_image_2d = -1;
	b->radar_image_size = -1;
	b->radar_projection_size = 1.0f;

	// see if blip should be drawn distorted
	// also determine if alternate image was defined for this ship
	if (objp->type == OBJ_SHIP)
	{
		// ships specifically hidden from sensors
		if (Ships[objp->instance].flags & SF_HIDDEN_FROM_SENSORS)
			b->flags |= BLIP_DRAW_DISTORTED;

		// determine if its AWACS distorted
		if (awacs_level < 1.0f)
			b->flags |= BLIP_DRAW_DISTORTED;

		ship_info *Iff_ship_info = &Ship_info[Ships[objp->instance].ship_info_index];

		if (Iff_ship_info->radar_image_2d_idx >= 0 || Iff_ship_info->radar_color_image_2d_idx >= 0)
		{
			b->radar_image_2d = Iff_ship_info->radar_image_2d_idx;
			b->radar_color_image_2d = Iff_ship_info->radar_color_image_2d_idx;
			b->radar_image_size = Iff_ship_info->radar_image_size;
			b->radar_projection_size = Iff_ship_info->radar_projection_size_mult;
		}
	}

	// don't distort the sensor blips if the player has primitive sensors and the nebula effect
	// is not active
	if (Player_ship->flags2 & SF2_PRIMITIVE_SENSORS)
	{
		if (!(The_mission.flags & MISSION_FLAG_FULLNEB))
			b->flags &= ~BLIP_DRAW_DISTORTED;
	}

	N_blips++;
}
예제 #7
0
/**
 * Parse the table
 */
void iff_init()
{
	char traitor_name[NAME_LENGTH];
	char attack_names[MAX_IFFS][MAX_IFFS][NAME_LENGTH];
	struct {
		char iff_name[NAME_LENGTH];
		int color_index;
	} observed_color_table[MAX_IFFS][MAX_IFFS];

	int num_attack_names[MAX_IFFS];
	int num_observed_colors[MAX_IFFS];
	int i, j, k;
	int string_idx;

	try
	{
		// Goober5000 - if table doesn't exist, use the default table
		if (cf_exists_full("iff_defs.tbl", CF_TYPE_TABLES))
			read_file_text("iff_defs.tbl", CF_TYPE_TABLES);
		else
			read_file_text_from_array(defaults_get_file("iff_defs.tbl"));

		reset_parse();

		// parse the table --------------------------------------------------------

		required_string("#IFFs");

		// get the traitor
		required_string("$Traitor IFF:");
		stuff_string(traitor_name, F_NAME, NAME_LENGTH);

		int rgb[3];

		// check if alternate colours are wanted to be used for these
		// Marks various stuff... like asteroids
		if ((optional_string("$Selection Color:")) || (optional_string("$Selection Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			iff_init_color(rgb[0], rgb[1], rgb[2]);
		}
		else
			iff_init_color(0xff, 0xff, 0xff);

		// Marks the ship currently saying something
		if ((optional_string("$Message Color:")) || (optional_string("$Message Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			iff_init_color(rgb[0], rgb[1], rgb[2]);
		}
		else
			iff_init_color(0x7f, 0x7f, 0x7f);

		// Marks the tagged ships
		if ((optional_string("$Tagged Color:")) || (optional_string("$Tagged Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			iff_init_color(rgb[0], rgb[1], rgb[2]);
		}
		else
			iff_init_color(0xff, 0xff, 0x00);

		// init radar blips colour table
		int a_bright, a_dim;
		bool alternate_blip_color = false;
		for (i = 0; i < 5; i++)
		{
			for (j = 0; j < 2; j++)
			{
				for (k = 0; k < 3; k++)
				{
					radar_iff_color[i][j][k] = -1;
				}
			}
		}

		// if the bright/dim scaling is wanted to be changed
		if (optional_string("$Dimmed IFF brightness:"))
		{
			int dim_iff_brightness;
			stuff_int(&dim_iff_brightness);
			Assert(dim_iff_brightness >= 0 && dim_iff_brightness <= HUD_COLOR_ALPHA_MAX);
			*iff_color_brightness = dim_iff_brightness;
		}
		else
			*iff_color_brightness = 4;

		// alternate = use same method as with ship blips
		// retail = use 1/2 intensities
		if (optional_string("$Use Alternate Blip Coloring:") || optional_string("$Use Alternate Blip Colouring:"))
		{
			stuff_boolean(&alternate_blip_color);
		}

		// Parse blip colours, their order is hardcoded.
		if ((optional_string("$Missile Blip Color:")) || (optional_string("$Missile Blip Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			for (i = 0; i < 3; i++)
			{
				Assert(rgb[i] >= 0 && rgb[i] <= 255);
				radar_iff_color[0][1][i] = rgb[i];
				radar_iff_color[0][0][i] = rgb[i] / 2;
			}
		}

		if ((optional_string("$Navbuoy Blip Color:")) || (optional_string("$Navbuoy Blip Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			for (i = 0; i < 3; i++)
			{
				Assert(rgb[i] >= 0 && rgb[i] <= 255);
				radar_iff_color[1][1][i] = rgb[i];
				radar_iff_color[1][0][i] = rgb[i] / 2;
			}
		}

		if ((optional_string("$Warping Blip Color:")) || (optional_string("$Warping Blip Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			for (i = 0; i < 3; i++)
			{
				Assert(rgb[i] >= 0 && rgb[i] <= 255);
				radar_iff_color[2][1][i] = rgb[i];
				radar_iff_color[2][0][i] = rgb[i] / 2;
			}
		}

		if ((optional_string("$Node Blip Color:")) || (optional_string("$Node Blip Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			for (i = 0; i < 3; i++)
			{
				Assert(rgb[i] >= 0 && rgb[i] <= 255);
				radar_iff_color[3][1][i] = rgb[i];
				radar_iff_color[3][0][i] = rgb[i] / 2;
			}
		}

		if ((optional_string("$Tagged Blip Color:")) || (optional_string("$Tagged Blip Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			for (i = 0; i < 3; i++)
			{
				Assert(rgb[i] >= 0 && rgb[i] <= 255);
				radar_iff_color[4][1][i] = rgb[i];
				radar_iff_color[4][0][i] = rgb[i] / 2;
			}
		}

		if (alternate_blip_color == true)
		{
			a_bright = iff_get_alpha_value(true);
			a_dim = iff_get_alpha_value(false);
			for (i = 0; i < 5; i++)
			{
				if (radar_iff_color[i][0][0] >= 0)
				{
					for (j = 0; j < 3; j++)
					{
						radar_iff_color[i][0][j] = radar_iff_color[i][1][j];
					}

					radar_iff_color[i][1][3] = a_bright;
					radar_iff_color[i][0][3] = a_dim;
				}
			}
		}
		else
		{
			for (i = 0; i < 5; i++)
			{
				if (radar_iff_color[i][0][0] >= 0)
				{
					radar_iff_color[i][0][3] = 255;
					radar_iff_color[i][1][3] = 255;
				}
			}
		}

		if (optional_string("$Radar Target ID Flags:")) {
			parse_string_flag_list((int*)&radar_target_id_flags, rti_flags, Num_rti_flags);
			if (optional_string("+reset"))
				radar_target_id_flags = 0;
		}

		// begin reading data
		Num_iffs = 0;
		while (required_string_either("#End", "$IFF Name:"))
		{
			iff_info *iff;
			int cur_iff;

			// make sure we're under the limit
			if (Num_iffs >= MAX_IFFS)
			{
				Warning(LOCATION, "Too many iffs in iffs_defs.tbl!  Max is %d.\n", MAX_IFFS);
				skip_to_start_of_string("#End", NULL);
				break;
			}

			// add new IFF
			iff = &Iff_info[Num_iffs];
			cur_iff = Num_iffs;
			Num_iffs++;


			// get required IFF info ----------------------------------------------

			// get the iff name
			required_string("$IFF Name:");
			stuff_string(iff->iff_name, F_NAME, NAME_LENGTH);

			// get the iff color
			if (check_for_string("$Colour:"))
				required_string("$Colour:");
			else
				required_string("$Color:");
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			iff->color_index = iff_init_color(rgb[0], rgb[1], rgb[2]);


			// get relationships between IFFs -------------------------------------

			// get the list of iffs attacked
			if (optional_string("$Attacks:"))
				num_attack_names[cur_iff] = stuff_string_list(attack_names[cur_iff], MAX_IFFS);
			else
				num_attack_names[cur_iff] = 0;

			// get the list of observed colors
			num_observed_colors[cur_iff] = 0;
			while (optional_string("+Sees"))
			{
				// get iff observed
				stuff_string_until(observed_color_table[cur_iff][num_observed_colors[cur_iff]].iff_name, "As:", NAME_LENGTH);
				required_string("As:");

				// get color observed
				stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
				observed_color_table[cur_iff][num_observed_colors[cur_iff]].color_index = iff_init_color(rgb[0], rgb[1], rgb[2]);

				// increment
				num_observed_colors[cur_iff]++;
			}


			// get flags ----------------------------------------------------------

			// get iff flags
			iff->flags = 0;
			if (optional_string("$Flags:"))
			{
				char flag_strings[MAX_IFF_FLAGS][NAME_LENGTH];

				int num_strings = stuff_string_list(flag_strings, MAX_IFF_FLAGS);
				for (string_idx = 0; string_idx < num_strings; string_idx++)
				{
					if (!stricmp(NOX("support allowed"), flag_strings[string_idx]))
						iff->flags |= IFFF_SUPPORT_ALLOWED;
					else if (!stricmp(NOX("exempt from all teams at war"), flag_strings[string_idx]))
						iff->flags |= IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR;
					else if (!stricmp(NOX("orders hidden"), flag_strings[string_idx]))
						iff->flags |= IFFF_ORDERS_HIDDEN;
					else if (!stricmp(NOX("orders shown"), flag_strings[string_idx]))
						iff->flags |= IFFF_ORDERS_SHOWN;
					else if (!stricmp(NOX("wing name hidden"), flag_strings[string_idx]))
						iff->flags |= IFFF_WING_NAME_HIDDEN;
					else
						Warning(LOCATION, "Bogus string in iff flags: %s\n", flag_strings[string_idx]);
				}
			}

			// get default ship flags
			iff->default_parse_flags = 0;
			if (optional_string("$Default Ship Flags:"))
			{
				i = 0;
				j = 0;
				char flag_strings[MAX_PARSE_OBJECT_FLAGS][NAME_LENGTH];
				int num_strings = stuff_string_list(flag_strings, MAX_PARSE_OBJECT_FLAGS);
				for (i = 0; i < num_strings; i++)
				{
					for (j = 0; j < MAX_PARSE_OBJECT_FLAGS; j++)
					{
						if (!stricmp(flag_strings[i], Parse_object_flags[j]))
						{
							iff->default_parse_flags |= (1 << j);
							break;
						}
					}
				}

				if (j == MAX_PARSE_OBJECT_FLAGS)
					Warning(LOCATION, "Bogus string in iff default ship flags: %s\n", flag_strings[i]);
			}

			// again
			iff->default_parse_flags2 = 0;
			if (optional_string("$Default Ship Flags2:"))
			{
				i = 0;
				j = 0;
				char flag_strings[MAX_PARSE_OBJECT_FLAGS_2][NAME_LENGTH];
				int num_strings = stuff_string_list(flag_strings, MAX_PARSE_OBJECT_FLAGS_2);
				for (i = 0; i < num_strings; i++)
				{
					for (j = 0; j < MAX_PARSE_OBJECT_FLAGS_2; j++)
					{
						if (!stricmp(flag_strings[i], Parse_object_flags_2[j]))
						{
							iff->default_parse_flags2 |= (1 << j);
							break;
						}
					}
				}

				if (j == MAX_PARSE_OBJECT_FLAGS_2)
					Warning(LOCATION, "Bogus string in iff default ship flags2: %s\n", flag_strings[i]);
			}

			// this is cleared between each level but let's just set it here for thoroughness
			iff->ai_rearm_timestamp = timestamp(-1);
		}

		required_string("#End");


		// now resolve the relationships ------------------------------------------

		// first get the traitor
		Iff_traitor = iff_lookup(traitor_name);
		if (Iff_traitor < 0)
		{
			Iff_traitor = 0;
			Warning(LOCATION, "Traitor IFF %s not found in iff_defs.tbl!  Defaulting to %s.\n", traitor_name, Iff_info[Iff_traitor].iff_name);
		}

		// next get the attackees and colors
		for (int cur_iff = 0; cur_iff < Num_iffs; cur_iff++)
		{
			iff_info *iff = &Iff_info[cur_iff];

			// clear the iffs to be attacked
			iff->attackee_bitmask = 0;
			iff->attackee_bitmask_all_teams_at_war = 0;

			// clear the observed colors
			for (j = 0; j < MAX_IFFS; j++)
				iff->observed_color_index[j] = -1;

			// resolve the list names
			for (int list_index = 0; list_index < MAX_IFFS; list_index++)
			{
				// are we within the number of attackees listed?
				if (list_index < num_attack_names[cur_iff])
				{
					// find out who
					int target_iff = iff_lookup(attack_names[cur_iff][list_index]);

					// valid?
					if (target_iff >= 0)
						iff->attackee_bitmask |= iff_get_mask(target_iff);
					else
						Warning(LOCATION, "Attack target IFF %s not found for IFF %s in iff_defs.tbl!\n", attack_names[cur_iff][list_index], iff->iff_name);
				}

				// are we within the number of colors listed?
				if (list_index < num_observed_colors[cur_iff])
				{
					// find out who
					int target_iff = iff_lookup(observed_color_table[cur_iff][list_index].iff_name);

					// valid?
					if (target_iff >= 0)
						iff->observed_color_index[target_iff] = observed_color_table[cur_iff][list_index].color_index;
					else
						Warning(LOCATION, "Observed color IFF %s not found for IFF %s in iff_defs.tbl!\n", observed_color_table[cur_iff][list_index].iff_name, iff->iff_name);
				}
			}

			// resolve the all teams at war relationships
			if (iff->flags & IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR)
			{
				// exempt, so use standard attacks
				iff->attackee_bitmask_all_teams_at_war = iff->attackee_bitmask;
			}
			else
			{
				// nonexempt, so build bitmask of all other nonexempt teams
				for (int other_iff = 0; other_iff < Num_iffs; other_iff++)
				{
					// skip myself (unless I attack myself normally)
					if ((other_iff == cur_iff) && !iff_x_attacks_y(cur_iff, cur_iff))
						continue;

					// skip anyone exempt
					if (Iff_info[other_iff].flags & IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR)
						continue;

					// add everyone else
					iff->attackee_bitmask_all_teams_at_war |= iff_get_mask(other_iff);
				}
			}
		}

		// add tbl/tbm to multiplayer validation list
		extern void fs2netd_add_table_validation(const char *tblname);
		fs2netd_add_table_validation("iff_defs.tbl");
	}
	catch (const parse::ParseException& e)
	{
		mprintf(("TABLES: Unable to parse '%s'!  Error message = %s.\n", "iff_defs.tbl", e.what()));
		return;
	}
}
예제 #8
0
void radar_plot_object_std( object *objp )	
{
	vec3d	pos, tempv;
	float		dist, rscale, zdist, max_radar_dist;
	int		xpos, ypos;
	vec3d	*world_pos = &objp->pos;	
	float		awacs_level;

	// don't process anything here.  Somehow, a jumpnode object caused this function
	// to get entered on server side.
	if( Game_mode & GM_STANDALONE_SERVER ){
		return;
	}

	// multiplayer clients ingame joining should skip this function
	if ( MULTIPLAYER_CLIENT && (Net_player->flags & NETINFO_FLAG_INGAME_JOIN) ){
		return;
	}

	// get team-wide awacs level for the object if not ship
	int ship_is_visible = 0;
	if (objp->type == OBJ_SHIP) {
		if (Player_ship != NULL) {
			if (ship_is_visible_by_team(objp, Player_ship)) {
				ship_is_visible = 1;
			}
		}
	}

	// only check awacs level if ship is not visible by team
	awacs_level = 1.5f;
	if (Player_ship != NULL && !ship_is_visible) {
		awacs_level = awacs_get_level(objp, Player_ship);
	}

	// if the awacs level is unviewable - bail
	if(awacs_level < 0.0f && !See_all){
		return;
	}

	// Apply object type filters	
	switch (objp->type)
	{
		case OBJ_SHIP:
			// Place to cull ships, such as NavBuoys		
			break;
		
		case OBJ_JUMP_NODE:
		{
			// don't plot hidden jump nodes
			if ( objp->jnp->is_hidden() )
				return;

			// filter jump nodes here if required
			break;
		}

		case OBJ_WEAPON:
		{
			// if not a bomb, return
			if ( !(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags & WIF_BOMB) )
				return;

			// if we don't attack the bomb, return
			if ( !iff_x_attacks_y(Player_ship->team, obj_team(objp)) )
				return;

			// if a local ssm is in subspace, return
			if (Weapons[objp->instance].lssm_stage == 3)
				return;

			break;
		}

		// if any other kind of object, don't show it on radar
		default:
			return;
	}

	
	// JAS -- new way of getting the rotated point that doesn't require this to be
	// in a g3_start_frame/end_frame block.
	vm_vec_sub(&tempv, world_pos, &Player_obj->pos);
	vm_vec_rotate(&pos, &tempv, &Player_obj->orient);

	// Apply range filter
	dist = vm_vec_dist(world_pos, &Player_obj->pos);
	max_radar_dist = Radar_ranges[HUD_config.rp_dist];
	if (dist > max_radar_dist) {
		return;
	}

	if (dist < pos.xyz.z) {
		rscale = 0.0f;
	} else {
		rscale = (float) acos(pos.xyz.z / dist) / 3.14159f;		//2.0f;	 
	}

	zdist = fl_sqrt((pos.xyz.x * pos.xyz.x) + (pos.xyz.y * pos.xyz.y));

	float new_x_dist, clipped_x_dist;
	float new_y_dist, clipped_y_dist;

	if (zdist < 0.01f)
	{
		new_x_dist = 0.0f;
		new_y_dist = 0.0f;
	}
	else
	{
		new_x_dist = (pos.xyz.x / zdist) * rscale * radx;
		new_y_dist = (pos.xyz.y / zdist) * rscale * rady;

		// force new_x_dist and new_y_dist to be inside the radar

		float hypotenuse;
		float max_radius;

		hypotenuse = (float) _hypot(new_x_dist, new_y_dist);
		max_radius = i2fl(Current_radar_global->Radar_radius[gr_screen.res][0] - 5);

		if (hypotenuse >= max_radius)
		{
			clipped_x_dist = max_radius * (new_x_dist / hypotenuse);
			clipped_y_dist = max_radius * (new_y_dist / hypotenuse);
			new_x_dist = clipped_x_dist;
			new_y_dist = clipped_y_dist;
		}
	}

	xpos = fl2i(Current_radar_global->Radar_center[gr_screen.res][0] + new_x_dist);
	ypos = fl2i(Current_radar_global->Radar_center[gr_screen.res][1] - new_y_dist);


	// determine the range within which the radar blip is bright
	if (timestamp_elapsed(Radar_calc_bright_dist_timer))
	{
		Radar_calc_bright_dist_timer = timestamp(1000);
		Radar_bright_range = player_farthest_weapon_range();
		if (Radar_bright_range <= 0)
			Radar_bright_range = 1500.0f;
	}

	blip *b;
	int blip_bright = 0;
	int blip_type = 0;

	if (N_blips >= MAX_BLIPS)
	{
		// out of blips, don't plot
		//Gahhh, this is bloody annoying -WMC
		//Int3();
		return;
	}

	b = &Blips[N_blips];
	b->flags = 0;

	// bright if within range
	blip_bright = (dist <= Radar_bright_range);

	// flag the blip as a current target if it is
	if (OBJ_INDEX(objp) == Player_ai->target_objnum)
	{
		b->flags |= BLIP_CURRENT_TARGET;
		blip_bright = 1;
	}

	radar_stuff_blip_info_std(objp, blip_bright, &b->blip_color, &blip_type);

	if (blip_bright)
		list_append(&Blip_bright_list[blip_type], b);
	else
		list_append(&Blip_dim_list[blip_type], b);

	b->x = xpos;
	b->y = ypos;

	// see if blip should be drawn distorted
	if (objp->type == OBJ_SHIP)
	{
		// ships specifically hidden from sensors
		if (Ships[objp->instance].flags & SF_HIDDEN_FROM_SENSORS)
			b->flags |= BLIP_DRAW_DISTORTED;

		// determine if its AWACS distorted
		if (awacs_level < 1.0f)
			b->flags |= BLIP_DRAW_DISTORTED;
	}				

	// don't distort the sensor blips if the player has primitive sensors and the nebula effect
	// is not active
	if (Player_ship->flags2 & SF2_PRIMITIVE_SENSORS)
	{
		if (!(The_mission.flags & MISSION_FLAG_FULLNEB))
			b->flags &= ~BLIP_DRAW_DISTORTED;
	}

	N_blips++;
}
예제 #9
0
// ********************************************************************************************
bool CanAutopilot(vec3d targetPos, bool send_msg)
{
	if (CurrentNav == -1)
	{
		if (send_msg)
					send_autopilot_msgID(NP_MSG_FAIL_NOSEL);
		return false;
	}

	if (object_get_gliding(Player_obj))
	{
		if (send_msg)
					send_autopilot_msgID(NP_MSG_FAIL_GLIDING);
		return false;
	}

	// You cannot autopilot if you're within 1000 meters of your destination nav point
	if (vm_vec_dist_quick(&targetPos, Navs[CurrentNav].GetPosition()) < 1000) {
		if (send_msg)
					send_autopilot_msgID(NP_MSG_FAIL_TOCLOSE);
		return false;
	}

	if ( AutopilotMinEnemyDistance > 0 ) {
		// see if any hostiles are nearby
		for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
		{
			object *other_objp = &Objects[so->objnum];
			// attacks player?
			if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj)) 
				&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO)) // ignore cargo
			{
				// Cannot autopilot if enemy within AutopilotMinEnemyDistance meters
				if (vm_vec_dist_quick(&targetPos, &other_objp->pos) < AutopilotMinEnemyDistance) {
					if (send_msg)
						send_autopilot_msgID(NP_MSG_FAIL_HOSTILES);
					return false;
				}
			}
		}
	}
	
	if ( AutopilotMinAsteroidDistance > 0 ) {
		//check for asteroids	
		for (int n=0; n<MAX_ASTEROIDS; n++) 
		{
			// asteroid
			if (Asteroids[n].flags & AF_USED)
			{
				// Cannot autopilot if asteroid within AutopilotMinAsteroidDistance meters
				if (vm_vec_dist_quick(&targetPos, &Objects[Asteroids[n].objnum].pos) < AutopilotMinAsteroidDistance) {
					if (send_msg)
						send_autopilot_msgID(NP_MSG_FAIL_HAZARD);
					return false;
				}
			}
		}
	}

	// check for support ships
	// cannot autopilot if support ship present
	if ( ship_find_repair_ship(Player_obj) != 0 ) {
		if (send_msg)
			send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_PRESENT);
		return false;
	}

	return true;
}