// start the emp effect for MYSELF (intensity == arbitrary intensity variable, time == time the effect will last) // NOTE : time should be in seconds void emp_start_local(float intensity, float time) { int idx; float start_intensity; // determine pre-existing EMP intensity (if any) start_intensity = Emp_intensity < 0.0f ? 0.0f : Emp_intensity; // cap all values (make sure that we un-normalize start_intensity) if(intensity + (start_intensity * EMP_INTENSITY_MAX) >= EMP_INTENSITY_MAX){ intensity = EMP_INTENSITY_MAX - 1.0f; } else { intensity += (start_intensity * EMP_INTENSITY_MAX); } if(time >= EMP_TIME_MAX){ time = EMP_TIME_MAX - 0.1f; } // setup all vars Emp_intensity = intensity / EMP_INTENSITY_MAX; // lose my current target if any if(Player_ai != NULL){ Player_ai->target_objnum = -1; } // lose any lock we have or are getting hud_lock_reset(); // reset HUD gauge text wackiness stuff for(idx=0; idx<NUM_TEXT_STAMPS; idx++){ memset(Emp_wacky_text[idx].str, 0, 256); Emp_wacky_text[idx].stamp = -1; } // start the emp icon flashing hud_start_text_flash(NOX("Emp"), 5000); // determine how much we have to decrement the effect per second Emp_decr = Emp_intensity / time; // play a flash game_flash( 1.0f, 1.0f, 0.5f ); }
// Try and find a new locking point void hud_lock_get_new_lock_pos(object* target_objp, vec3d* lock_world_pos) { ship* target_shipp = NULL; ship_weapon* swp = NULL; weapon_info* wip = NULL; if (target_objp->type == OBJ_SHIP) { target_shipp = &Ships[target_objp->instance]; } swp = &Player_ship->weapons; wip = &Weapon_info[swp->secondary_bank_weapons[swp->current_secondary_bank]]; // If Javelin HS, only target engines. if ((target_shipp) && wip->wi_flags & WIF_HOMING_JAVELIN) { Player->locking_subsys = ship_get_closest_subsys_in_sight(target_shipp, SUBSYSTEM_ENGINE, &Player_obj->pos); if (Player->locking_subsys != NULL) { get_subsystem_world_pos(target_objp, Player->locking_subsys, lock_world_pos); Player->locking_on_center = 0; Player->locking_subsys_parent = Player_ai->target_objnum; } else { hud_lock_reset(); return; } } else { // just go for the center *lock_world_pos = target_objp->pos; Player->locking_on_center = 1; Player->locking_subsys = NULL; Player->locking_subsys_parent = -1; } }
// hud_update_lock_indicator() will manage the non-rendering dependant part of // missle locking void hud_update_lock_indicator(float frametime) { ship_weapon *swp; weapon_info *wip; vector lock_world_pos; #ifndef NO_NETWORK // if i'm a multiplayer observer, bail here if((Game_mode & GM_MULTIPLAYER) && ((Net_player->flags & NETINFO_FLAG_OBSERVER) || (Player_obj->type == OBJ_OBSERVER)) ){ return; } #endif Assert(Player_ai->target_objnum != -1); // be sure to unset this flag, then possibly set later in this function so that // threat indicators work properly. Player_ai->ai_flags &= ~AIF_SEEK_LOCK; if ( hud_abort_lock() ) { hud_lock_reset(); return; } // if there is an EMP effect active, never update lock if(emp_active_local()){ hud_lock_reset(); return; } swp = &Player_ship->weapons; wip = &Weapon_info[swp->secondary_bank_weapons[swp->current_secondary_bank]]; Lock_start_dist = wip->min_lock_time * wip->lock_pixels_per_sec; // if secondary weapons change, reset the lock if ( hud_lock_secondary_weapon_changed(swp) ) { hud_lock_reset(); } Player_ai->last_secondary_index = swp->current_secondary_bank; if ( !(wip->wi_flags & WIF_HOMING_ASPECT) ) { hud_lock_reset(); return; } // Allow locking on ships and bombs (only targeted weapon allowed is a bomb, so don't bother checking flags) if ( (Objects[Player_ai->target_objnum].type != OBJ_SHIP) && (Objects[Player_ai->target_objnum].type != OBJ_WEAPON) ) { hud_lock_reset(); return; } hud_lock_determine_lock_point(&lock_world_pos); if ( !hud_lock_has_homing_point() ) { Player->target_in_lock_cone=0; } hud_lock_check_if_target_in_lock_cone(&lock_world_pos); // check if the target is within range of the current secondary weapon. If it is not, // a lock will not be detected if ( !hud_lock_target_in_range() ) { Player->target_in_lock_cone = 0; } // If locking on a subsystem, and not in sight... can't lock // Changed by MK on 4/3/98. It was confusing me that my hornets would not lock on my target. // It will now be confusing that they lock, but don't home on your subsystem, but I think that's preferable. // Often you really care about destroying the target, not just the subsystem. /*if ( Player_ai->targeted_subsys ) { if ( !hud_lock_on_subsys_ok() ) { Player->target_in_lock_cone=0; } }*/ if ( !Player->target_in_lock_cone ) { Player->locking_on_center=0; Player->locking_subsys_parent=-1; Player->locking_subsys=NULL; } hud_calculate_lock_position(frametime); if (!Players[Player_num].lock_indicator_visible) return; if (Player_ai->current_target_is_locked) { if ( Missile_track_loop > -1 ) { snd_chg_loop_status(Missile_track_loop, 0); Missile_track_loop = -1; Missile_lock_loop = snd_play(&Snds[SND_MISSILE_LOCK]); } } else { Player_ai->ai_flags |= AIF_SEEK_LOCK; // set this flag so multiplayer's properly track lock on other ships if ( Missile_lock_loop != -1 && snd_is_playing(Missile_lock_loop) ) { snd_stop(Missile_lock_loop); Missile_lock_loop = -1; } } }
// hud_do_lock_indicator() manages missle locking, both the non-rendering calculations and the 2D HUD rendering void hud_do_lock_indicator(float frametime) { ship_weapon *swp; weapon_info *wip; // if i'm a multiplayer observer, bail here if((Game_mode & GM_MULTIPLAYER) && ((Net_player->flags & NETINFO_FLAG_OBSERVER) || (Player_obj->type == OBJ_OBSERVER)) ){ return; } Assert(Player_ai->target_objnum >= 0); // be sure to unset this flag, then possibly set later in this function so that // threat indicators work properly. Player_ai->ai_flags.remove(AI::AI_Flags::Seek_lock); if ( hud_abort_lock() ) { hud_lock_reset(); return; } // if there is an EMP effect active, never update lock if(emp_active_local()){ hud_lock_reset(); return; } swp = &Player_ship->weapons; wip = &Weapon_info[swp->secondary_bank_weapons[swp->current_secondary_bank]]; Lock_start_dist = wip->min_lock_time * wip->lock_pixels_per_sec; // if secondary weapons change, reset the lock if ( hud_lock_secondary_weapon_changed(swp) ) { hud_lock_reset(); } Player_ai->last_secondary_index = swp->current_secondary_bank; object *tobjp = &Objects[Player_ai->target_objnum]; vec3d dir_to_target; vm_vec_normalized_dir(&dir_to_target, &tobjp->pos, &Player_obj->pos); if ( !(wip->is_locked_homing()) ) { hud_lock_reset(); return; } // Allow locking on ships and bombs (only targeted weapon allowed is a bomb, so don't bother checking flags) if ( (Objects[Player_ai->target_objnum].type != OBJ_SHIP) && (Objects[Player_ai->target_objnum].type != OBJ_WEAPON) ) { hud_lock_reset(); return; } // Javelins must lock on engines if locking on a ship and those must be in sight if (wip->wi_flags[Weapon::Info_Flags::Homing_javelin] && tobjp->type == OBJ_SHIP && Player->locking_subsys != NULL) { vec3d subobj_pos; vm_vec_unrotate(&subobj_pos, &Player->locking_subsys->system_info->pnt, &tobjp->orient); vm_vec_add2(&subobj_pos, &tobjp->pos); int target_subsys_in_sight = ship_subsystem_in_sight(tobjp, Player->locking_subsys, &Player_obj->pos, &subobj_pos); if (!target_subsys_in_sight || Player->locking_subsys->system_info->type != SUBSYSTEM_ENGINE) { Player->locking_subsys = ship_get_closest_subsys_in_sight(&Ships[tobjp->instance], SUBSYSTEM_ENGINE, &Player_obj->pos); } } if (wip->wi_flags[Weapon::Info_Flags::Homing_javelin] && tobjp->type == OBJ_SHIP && Player->locking_subsys == NULL) { Player->locking_subsys = ship_get_closest_subsys_in_sight(&Ships[tobjp->instance], SUBSYSTEM_ENGINE, &Player_obj->pos); if (Player->locking_subsys == NULL) { hud_lock_reset(); return; } } hud_lock_determine_lock_point(&lock_world_pos); if ( !hud_lock_has_homing_point() ) { Player->target_in_lock_cone=0; } hud_lock_check_if_target_in_lock_cone(); // check if the target is within range of the current secondary weapon. If it is not, // a lock will not be detected if ( !hud_lock_target_in_range() ) { Player->target_in_lock_cone = 0; } // If locking on a subsystem, and not in sight... can't lock // Changed by MK on 4/3/98. It was confusing me that my hornets would not lock on my target. // It will now be confusing that they lock, but don't home on your subsystem, but I think that's preferable. // Often you really care about destroying the target, not just the subsystem. /*if ( Player_ai->targeted_subsys ) { if ( !hud_lock_on_subsys_ok() ) { Player->target_in_lock_cone=0; } }*/ if ( !Player->target_in_lock_cone ) { Player->locking_on_center=0; Player->locking_subsys_parent=-1; Player->locking_subsys=NULL; } hud_calculate_lock_position(frametime); if (!Players[Player_num].lock_indicator_visible) return; if (Player_ai->current_target_is_locked) { if ( Missile_track_loop > -1 ) { snd_stop(Missile_track_loop); Missile_track_loop = -1; if (wip->hud_locked_snd >= 0) { Missile_lock_loop = snd_play(&Snds[wip->hud_locked_snd]); } else { Missile_lock_loop = snd_play(&Snds[ship_get_sound(Player_obj, SND_MISSILE_LOCK)]); } } } else { Player_ai->ai_flags.set(AI::AI_Flags::Seek_lock); // set this flag so multiplayer's properly track lock on other ships if ( Missile_lock_loop != -1 && snd_is_playing(Missile_lock_loop) ) { snd_stop(Missile_lock_loop); Missile_lock_loop = -1; } } }
// Decide which point lock should be homing on void hud_lock_determine_lock_point(vec3d *lock_world_pos_out) { object *target_objp; ship_weapon *swp; weapon_info *wip; vec3d vec_to_lock_pos; vec3d lock_local_pos; Assert(Player_ai->target_objnum >= 0); target_objp = &Objects[Player_ai->target_objnum]; Player->current_target_sx = -1; Player->current_target_sy = -1; swp = &Player_ship->weapons; wip = &Weapon_info[swp->secondary_bank_weapons[swp->current_secondary_bank]]; // If subsystem is targeted, we must try to lock on that if ( Player_ai->targeted_subsys && !(wip->wi_flags[Weapon::Info_Flags::Homing_javelin]) ) { hud_lock_update_lock_pos(target_objp); Player->locking_on_center=0; Player->locking_subsys=Player_ai->targeted_subsys; Player->locking_subsys_parent=Player_ai->target_objnum; } else if ( (wip->wi_flags[Weapon::Info_Flags::Homing_javelin]) && (target_objp->type == OBJ_SHIP)) { if (!Player->locking_subsys || Player->locking_subsys->system_info->type != SUBSYSTEM_ENGINE) { Player->locking_subsys = ship_get_closest_subsys_in_sight(&Ships[target_objp->instance], SUBSYSTEM_ENGINE, &Player_obj->pos); } if (Player->locking_subsys != NULL) { get_subsystem_world_pos(target_objp, Player->locking_subsys, &lock_world_pos); Player->locking_on_center=0; Player->locking_subsys_parent=Player_ai->target_objnum; } else { hud_lock_reset(); return; } } else { // See if we already have a successful locked point if ( hud_lock_has_homing_point() ) { hud_lock_update_lock_pos(target_objp); } else { hud_lock_get_new_lock_pos(target_objp); } } *lock_world_pos_out=lock_world_pos; vm_vec_sub(&vec_to_lock_pos,&lock_world_pos,&Player_obj->pos); vm_vec_rotate(&lock_local_pos,&vec_to_lock_pos,&Player_obj->orient); if ( lock_local_pos.xyz.z > 0.0f ) { // Get the location of our target in the "virtual frame" where the locking computation will be done float w = 1.0f / lock_local_pos.xyz.z; // Let's force our "virtual frame" to be 640x480. -MageKing17 float sx = gr_screen.clip_center_x + (lock_local_pos.xyz.x * VIRTUAL_FRAME_HALF_WIDTH * w); float sy = gr_screen.clip_center_y - (lock_local_pos.xyz.y * VIRTUAL_FRAME_HALF_HEIGHT * w); Player->current_target_sx = (int)sx; Player->current_target_sy = (int)sy; } }
// Try and find a new locking point void hud_lock_get_new_lock_pos(object *target_objp) { ship *target_shipp=NULL; int lock_in_range=0; float best_lock_dot=-1.0f, lock_dot=-1.0f; ship_subsys *ss; vec3d subsys_world_pos, vec_to_lock; ship_weapon *swp; weapon_info *wip; if ( target_objp->type == OBJ_SHIP ) { target_shipp = &Ships[target_objp->instance]; } swp = &Player_ship->weapons; wip = &Weapon_info[swp->secondary_bank_weapons[swp->current_secondary_bank]]; // if a large ship, lock to pos closest to center and within range if ( (target_shipp) && (Ship_info[target_shipp->ship_info_index].is_big_or_huge()) && !(wip->wi_flags[Weapon::Info_Flags::Homing_javelin]) ) { // check all the subsystems and the center of the ship // assume best lock pos is the center of the ship lock_world_pos = target_objp->pos; Player->locking_on_center=1; Player->locking_subsys=NULL; Player->locking_subsys_parent=-1; lock_in_range = hud_lock_world_pos_in_range(&lock_world_pos, &vec_to_lock); vm_vec_normalize(&vec_to_lock); if ( lock_in_range ) { best_lock_dot=vm_vec_dot(&Player_obj->orient.vec.fvec, &vec_to_lock); } // take center if reasonable dot if ( best_lock_dot > 0.95 ) { return; } // iterate through subsystems to see if we can get a better choice ss = GET_FIRST(&target_shipp->subsys_list); while ( ss != END_OF_LIST( &target_shipp->subsys_list ) ) { // get world pos of subsystem get_subsystem_world_pos(target_objp, ss, &subsys_world_pos); if ( hud_lock_world_pos_in_range(&subsys_world_pos, &vec_to_lock) ) { vm_vec_normalize(&vec_to_lock); lock_dot=vm_vec_dot(&Player_obj->orient.vec.fvec, &vec_to_lock); if ( lock_dot > best_lock_dot ) { best_lock_dot=lock_dot; Player->locking_on_center=0; Player->locking_subsys=ss; Player->locking_subsys_parent=Player_ai->target_objnum; lock_world_pos = subsys_world_pos; } } ss = GET_NEXT( ss ); } } else if ( (target_shipp) && (wip->wi_flags[Weapon::Info_Flags::Homing_javelin])) { Player->locking_subsys = ship_get_closest_subsys_in_sight(target_shipp, SUBSYSTEM_ENGINE, &Player_obj->pos); if (Player->locking_subsys != NULL) { get_subsystem_world_pos(target_objp, Player->locking_subsys, &lock_world_pos); Player->locking_on_center=0; Player->locking_subsys_parent=Player_ai->target_objnum; } else { hud_lock_reset(); return; } } else { // if small ship (or weapon), just go for the center lock_world_pos = target_objp->pos; Player->locking_on_center=1; Player->locking_subsys=NULL; Player->locking_subsys_parent=-1; } }
// Decide which point lock should be homing on void hud_lock_determine_lock_point(vec3d* lock_world_pos_out) { vec3d lock_world_pos; object* target_objp; ship_weapon* swp; weapon_info* wip; vec3d vec_to_lock_pos; vec3d lock_local_pos; Assert(Player_ai->target_objnum >= 0); target_objp = &Objects[Player_ai->target_objnum]; Player->current_target_sx = -1; Player->current_target_sx = -1; swp = &Player_ship->weapons; wip = &Weapon_info[swp->secondary_bank_weapons[swp->current_secondary_bank]]; // If subsystem is targeted, we must try to lock on that if (Player_ai->targeted_subsys && !(wip->wi_flags & WIF_HOMING_JAVELIN)) { hud_lock_update_lock_pos(target_objp, &lock_world_pos); Player->locking_on_center = 0; Player->locking_subsys = Player_ai->targeted_subsys; Player->locking_subsys_parent = Player_ai->target_objnum; } else if (wip->wi_flags & WIF_HOMING_JAVELIN && target_objp->type == OBJ_SHIP) { if (!Player->locking_subsys || Player->locking_subsys->system_info->type != SUBSYSTEM_ENGINE) { Player->locking_subsys = ship_get_closest_subsys_in_sight(&Ships[target_objp->instance], SUBSYSTEM_ENGINE, &Player_obj->pos); } if (Player->locking_subsys != NULL) { get_subsystem_world_pos(target_objp, Player->locking_subsys, &lock_world_pos); Player->locking_on_center = 0; Player->locking_subsys_parent = Player_ai->target_objnum; } else { hud_lock_reset(); return; } } else { // See if we already have a successful locked point if (hud_lock_has_homing_point()) { hud_lock_update_lock_pos(target_objp, &lock_world_pos); } else { hud_lock_get_new_lock_pos(target_objp, &lock_world_pos); } } *lock_world_pos_out = lock_world_pos; vm_vec_sub(&vec_to_lock_pos, &lock_world_pos, &Player_obj->pos); vm_vec_rotate(&lock_local_pos, &vec_to_lock_pos, &Player_obj->orient); if (lock_local_pos.xyz.z > 0.0f) { // Get the location of our target in the "virtual frame" where the locking computation will be done float w = 1.0f / lock_local_pos.xyz.z; float sx = ((gr_screen.clip_center_x * 2.0f) + (lock_local_pos.xyz.x * (gr_screen.clip_center_x * 2.0f) * w)) * 0.5f; float sy = ((gr_screen.clip_center_y * 2.0f) - (lock_local_pos.xyz.y * (gr_screen.clip_center_y * 2.0f) * w)) * 0.5f; Player->current_target_sx = (int)sx; Player->current_target_sy = (int)sy; } }