void Weapon::SelectTarget() { bool select_locked = false; SimObject* targ = 0; double dist = 1e9; double az = 0; double el = 0; if (ammo && enabled && (availability > crit_level)) { ZeroAim(); ListIter<Contact> contact = ship->ContactList(); // lock onto any threatening shots first (if we can): if (design->target_type & Ship::DRONE) { while (++contact) { Shot* c_shot = contact->GetShot(); if (c_shot && contact->Threat(ship)) { // distance from self to target: double distance = Point(c_shot->Location() - muzzle_pts[0]).length(); if (distance > design->min_range && distance < design->max_range && distance < dist) { // check aim basket: select_locked = CanLockPoint(c_shot->Location(), az, el); if (select_locked) { targ = c_shot; dist = distance; } } } } } // lock onto a threatening ship only if it is (much) closer: dist *= 0.2; contact.reset(); while (++contact) { Ship* c_ship = contact->GetShip(); if (!c_ship) continue; // can we lock onto this target? if ((c_ship->IsRogue() || c_ship->GetIFF() > 0 && c_ship->GetIFF() != ship->GetIFF()) && (c_ship->Class() & design->target_type) && c_ship->Weapons().size() > 0) { // distance from self to target: double distance = Point(c_ship->Location() - muzzle_pts[0]).length(); if (distance < design->max_range && distance < dist) { // check aim basket: select_locked = CanLockPoint(c_ship->Location(), az, el); if (select_locked) { targ = c_ship; dist = distance; } } } } } if (!ammo || !enabled) { SetTarget(0,0); locked = false; } else { SetTarget(targ, 0); } }