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; }
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; }
/** * 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 } } } }
/** * @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; }
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++; }
/** * 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; } }
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++; }
// ******************************************************************************************** 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; }