// 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) { 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 & WIF_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 & 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); } 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; } }