示例#1
0
// 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;
	}
}
示例#2
0
// 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;
	}
}