Steer StarshipAI::SeekTarget() { if (navpt) { SimRegion* self_rgn = ship->GetRegion(); SimRegion* nav_rgn = navpt->Region(); QuantumDrive* qdrive = ship->GetQuantumDrive(); if (self_rgn && !nav_rgn) { nav_rgn = self_rgn; navpt->SetRegion(nav_rgn); } bool use_farcaster = self_rgn != nav_rgn && (navpt->Farcast() || !qdrive || !qdrive->IsPowerOn() || qdrive->Status() < System::DEGRADED ); if (use_farcaster) { if (!farcaster) { ListIter<Ship> s = self_rgn->Ships(); while (++s && !farcaster) { if (s->GetFarcaster()) { const Ship* dest = s->GetFarcaster()->GetDest(); if (dest && dest->GetRegion() == nav_rgn) { farcaster = s->GetFarcaster(); } } } } if (farcaster) { if (farcaster->GetShip()->GetRegion() != self_rgn) farcaster = farcaster->GetDest()->GetFarcaster(); obj_w = farcaster->EndPoint(); distance = Point(obj_w - ship->Location()).length(); if (distance < 1000) farcaster = 0; } } else if (self_rgn != nav_rgn) { QuantumDrive* q = ship->GetQuantumDrive(); if (q) { if (q->ActiveState() == QuantumDrive::ACTIVE_READY) { q->SetDestination(navpt->Region(), navpt->Location()); q->Engage(); } } } } return ShipAI::SeekTarget(); }
void NavAI::FindObjective() { navpt = 0; distance = 0; // runway takeoff: if (takeoff) { obj_w = ship->Location() + ship->Heading() * 10e3; obj_w.y = ship->Location().y + 2e3; // transform into camera coords: objective = Transform(obj_w); ship->SetDirectorInfo(Game::GetText("ai.takeoff")); return; } // PART I: Find next NavPoint: if (ship->GetNavSystem()) navpt = ship->GetNextNavPoint(); complete = !navpt; if (complete) return; // PART II: Compute Objective from NavPoint: Point npt = navpt->Location(); Sim* sim = Sim::GetSim(); SimRegion* self_rgn = ship->GetRegion(); SimRegion* nav_rgn = navpt->Region(); if (self_rgn && !nav_rgn) { nav_rgn = self_rgn; navpt->SetRegion(nav_rgn); } if (self_rgn == nav_rgn) { if (farcaster) { if (farcaster->GetShip()->GetRegion() != self_rgn) farcaster = farcaster->GetDest()->GetFarcaster(); obj_w = farcaster->EndPoint(); } else { obj_w = npt.OtherHand(); } // distance from self to navpt: distance = Point(obj_w - self->Location()).length(); // transform into camera coords: objective = Transform(obj_w); if (!ship->IsStarship()) objective.Normalize(); if (farcaster && distance < 1000) farcaster = 0; } // PART III: Deal with orbital transitions: else if (ship->IsDropship()) { if (nav_rgn->GetOrbitalRegion()->Primary() == self_rgn->GetOrbitalRegion()->Primary()) { Point npt = nav_rgn->Location() - self_rgn->Location(); obj_w = npt.OtherHand(); // distance from self to navpt: distance = Point(obj_w - ship->Location()).length(); // transform into camera coords: objective = Transform(obj_w); if (nav_rgn->IsAirSpace()) { drop_state = -1; } else if (nav_rgn->IsOrbital()) { drop_state = 1; } } // PART IIIa: Deal with farcaster jumps: else if (nav_rgn->IsOrbital() && self_rgn->IsOrbital()) { ListIter<Ship> s = self_rgn->Ships(); while (++s && !farcaster) { if (s->GetFarcaster()) { const Ship* dest = s->GetFarcaster()->GetDest(); if (dest && dest->GetRegion() == nav_rgn) { farcaster = s->GetFarcaster(); } } } if (farcaster) { Point apt = farcaster->ApproachPoint(0); Point npt = farcaster->StartPoint(); double r1 = (ship->Location() - npt).length(); if (r1 > 50e3) { obj_w = apt; distance = r1; objective = Transform(obj_w); } else { double r2 = (ship->Location() - apt).length(); double r3 = (npt - apt).length(); if (r1+r2 < 1.2*r3) { obj_w = npt; distance = r1; objective = Transform(obj_w); } else { obj_w = apt; distance = r2; objective = Transform(obj_w); } } } } } // PART IV: Deal with quantum jumps: else if (ship->IsStarship()) { quantum_state = 1; Point npt = nav_rgn->Location() + navpt->Location(); npt -= self_rgn->Location(); obj_w = npt.OtherHand(); // distance from self to navpt: distance = Point(obj_w - ship->Location()).length(); // transform into camera coords: objective = Transform(obj_w); } }