// Determine if point to lock on is in range int hud_lock_target_in_range() { vector target_world_pos, vec_to_target; object *targetp; if ( !hud_lock_has_homing_point() ) { return 0; } targetp = &Objects[Player_ai->target_objnum]; if ( Player_ai->targeted_subsys != NULL ) { vm_vec_unrotate(&target_world_pos, &Player_ai->targeted_subsys->system_info->pnt, &targetp->orient); vm_vec_add2(&target_world_pos, &targetp->pos); } else { if ( Player->locking_subsys ) { vm_vec_unrotate(&target_world_pos, &Player->locking_subsys->system_info->pnt, &targetp->orient); vm_vec_add2(&target_world_pos, &targetp->pos); } else { Assert(Player->locking_on_center); target_world_pos = targetp->pos; } } return hud_lock_world_pos_in_range(&target_world_pos, &vec_to_target); }
// Decide which point lock should be homing on void hud_lock_determine_lock_point(vector *lock_world_pos_out) { vector lock_world_pos; vertex lock_point; object *target_objp; Assert(Player_ai->target_objnum >= 0); target_objp = &Objects[Player_ai->target_objnum]; Player->current_target_sx = -1; Player->current_target_sx = -1; // If subsystem is targeted, we must try to lock on that if ( Player_ai->targeted_subsys ) { hud_lock_update_lock_pos(target_objp, &lock_world_pos); Player->locking_on_center=0; Player->locking_subsys=NULL; Player->locking_subsys_parent=-1; } 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; g3_rotate_vertex(&lock_point,&lock_world_pos); g3_project_vertex(&lock_point); if (!(lock_point.flags & PF_OVERFLOW)) { // make sure point projected Player->current_target_sx = (int)lock_point.sx; Player->current_target_sy = (int)lock_point.sy; } }
// 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; } }
// 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; } }