void
FlightPlanner::CreateGuardRoute(Element* guard, Element* ward)
{
	if (!guard || !ward)
		return;

	RLoc	rloc;
	Vec3           dummy(0,0,0);
	Point          loc   = ship->Location();
	double         head  = ship->CompassHeading();
	Instruction*   instr = 0;

if (ship->IsAirborne())
	loc += ship->Cam().vup() * 8e3;
	else
	loc += ship->Cam().vup() * 1e3;

	loc = loc.OtherHand();

	rloc.SetReferenceLoc(0);
	rloc.SetBaseLocation(loc);
	rloc.SetDistance(30e3);
	rloc.SetDistanceVar(0);
	rloc.SetAzimuth(head);
	rloc.SetAzimuthVar(0);

	instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::VECTOR);
	instr->SetSpeed(750);
	instr->GetRLoc() = rloc;

	guard->AddNavPoint(instr);

	if(ward) {
		rloc.SetReferenceLoc(0);
		rloc.SetBaseLocation(ward->GetShip(1)->Location());
		rloc.SetDistance(10e3);
		rloc.SetDistanceVar(5e3);
		rloc.SetAzimuth(0);
		rloc.SetAzimuthVar(90*DEGREES);

		instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::DEFEND);
		instr->SetSpeed(1000);
		instr->GetRLoc() = rloc;
		//instr->SetHoldTime(30 * 60); // 30 minutes or low fuel, whatever comes first.
		instr->SetTarget(ward->Name());

		guard->AddNavPoint(instr);
	}
}
void
FlightPlanner::CreateDeployPoint(Element* squad, Element* hold)
{
		if (!squad) return;
	Point		   loc = ship->Location();
	RLoc           rloc;
	Vec3           dummy(0,0,0);
	double         head  = ship->CompassHeading();
	Instruction*   instr = 0;
	loc += Point(0, 2e3, 0);

	if (ship->IsAirborne())
	loc += ship->Cam().vup() * 8e3;
	else
	loc += ship->Cam().vup() * 1e3;

	loc = loc.OtherHand();

	rloc.SetReferenceLoc(0);
	rloc.SetBaseLocation(loc);
	rloc.SetDistance(10e3);
	rloc.SetDistanceVar(0);
	rloc.SetAzimuth(head);
	rloc.SetAzimuthVar(0);

	instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::VECTOR);
	instr->SetSpeed(850);
	instr->GetRLoc() = rloc;

	squad->AddNavPoint(instr);

	rloc.SetReferenceLoc(0);
	rloc.SetBaseLocation(hold->GetShip(1)->Location());
	rloc.SetDistance(20e3);
	rloc.SetDistanceVar(5e3);
	rloc.SetAzimuth(0);
	rloc.SetAzimuthVar(90*DEGREES);

	instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::DEFEND);
	instr->SetSpeed(800);
	instr->GetRLoc() = rloc;
	instr->SetTarget(hold->Name());

	squad->AddNavPoint(instr);
}
void
FlightPlanner::CreatePatrolRoute(Element* elem, int index)
{
	RLoc           rloc;
	Vec3           dummy(0,0,0);
	Point          loc   = ship->Location();
	double         zone  = ship->CompassHeading();
	Instruction*   instr = 0;

	if (ship->IsAirborne())
	loc.y += 8e3;
	else
	loc.y += 1e3;

	loc = loc.OtherHand();

	if (index > 2)
	zone += 170*DEGREES;
	else if (index > 1)
	zone += -90*DEGREES;
	else if (index > 0)
	zone +=  90*DEGREES;

	rloc.SetReferenceLoc(0);
	rloc.SetBaseLocation(loc);
	rloc.SetDistance(30e3);
	rloc.SetDistanceVar(0);
	rloc.SetAzimuth(-10*DEGREES + zone);
	rloc.SetAzimuthVar(0);

	instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::VECTOR);
	instr->SetSpeed(750);
	instr->GetRLoc() = rloc;

	elem->AddNavPoint(instr);

	rloc.SetReferenceLoc(0);
	rloc.SetBaseLocation(loc);
	if (ship->IsAirborne())
	rloc.SetDistance(140e3);
	else
	rloc.SetDistance(220e3);
	rloc.SetDistanceVar(50e3);
	rloc.SetAzimuth(-20*DEGREES + zone);
	rloc.SetAzimuthVar(15*DEGREES);

	instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::PATROL);
	instr->SetSpeed(500);
	instr->GetRLoc() = rloc;

	elem->AddNavPoint(instr);

	rloc.SetReferenceLoc(&instr->GetRLoc());
	rloc.SetDistance(120e3);
	rloc.SetDistanceVar(30e3);
	rloc.SetAzimuth(60*DEGREES + zone);
	rloc.SetAzimuthVar(20*DEGREES);

	instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::PATROL);
	instr->SetSpeed(350);
	instr->GetRLoc() = rloc;

	elem->AddNavPoint(instr);

	rloc.SetReferenceLoc(&instr->GetRLoc());
	rloc.SetDistance(120e3);
	rloc.SetDistanceVar(30e3);
	rloc.SetAzimuth(120*DEGREES + zone);
	rloc.SetAzimuthVar(20*DEGREES);

	instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::PATROL);
	instr->SetSpeed(350);
	instr->GetRLoc() = rloc;

	elem->AddNavPoint(instr);

	rloc.SetReferenceLoc(0);
	rloc.SetBaseLocation(loc);
	rloc.SetDistance(40e3);
	rloc.SetDistanceVar(0);
	rloc.SetAzimuth(180*DEGREES + ship->CompassHeading());
	rloc.SetAzimuthVar(0*DEGREES);

	instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::RTB);
	instr->SetSpeed(500);
	instr->GetRLoc() = rloc;

	elem->AddNavPoint(instr);
}
void
FlightPlanner::CreateCircusRoute(Element* elem, Element* ward)       //********* New Sweep for bombers planning.
{
	if (!elem) return;

	RLoc           rloc;
	Vec3           dummy(0,0,0);
	Point          loc   = ship->Location();
	double         head  = ship->CompassHeading();
	Instruction*   instr = 0;

	if (ship->IsAirborne())
	loc += ship->Cam().vup() * 8e3;
	else
	loc += ship->Cam().vup() * 1e3;

	loc = loc.OtherHand();

	rloc.SetReferenceLoc(0);
	rloc.SetBaseLocation(loc);
	rloc.SetDistance(30e3);
	rloc.SetDistanceVar(0);
	rloc.SetAzimuth(head);
	rloc.SetAzimuthVar(0);

	instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::VECTOR);
	instr->SetSpeed(850);
	instr->GetRLoc() = rloc;

	elem->AddNavPoint(instr);

	if (ward) { 

		// follow ward's flight plan:
		if (ward->GetFlightPlan().size()) {
			ListIter<Instruction> iter = ward->GetFlightPlan();

			while (++iter) {
				Instruction* ward_instr = iter.value();

				if (ward_instr->Action() != Instruction::RTB) {
					rloc.SetReferenceLoc(&ward_instr->GetRLoc());
					rloc.SetDistance(20e3);
					rloc.SetDistanceVar(5e3);
					rloc.SetAzimuth(0);
					rloc.SetAzimuthVar(90*DEGREES);

					instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::SWEEP); 
					instr->SetSpeed(800);
					instr->GetRLoc() = rloc;

					elem->AddNavPoint(instr);
				}
			}
		}

		// if ward has no flight plan, just go to a point nearby:
		else {
			rloc.SetReferenceLoc(0);
			rloc.SetBaseLocation(ward->GetShip(1)->Location());
			rloc.SetDistance(25e3);
			rloc.SetDistanceVar(5e3);
			rloc.SetAzimuth(0);
			rloc.SetAzimuthVar(90*DEGREES);

			instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::SWEEP);
			instr->SetSpeed(500);
			instr->GetRLoc() = rloc;
			instr->SetTarget(ward->Name());
			instr->SetHoldTime(15 * 60); // fifteen minutes

			elem->AddNavPoint(instr);
		}
	}

	rloc.SetReferenceLoc(0);
	rloc.SetBaseLocation(loc);
	rloc.SetDistance(40e3);
	rloc.SetDistanceVar(0);
	rloc.SetAzimuth(180*DEGREES + ship->CompassHeading());
	rloc.SetAzimuthVar(0*DEGREES);

	instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::RTB);
	instr->SetSpeed(500);
	instr->GetRLoc() = rloc;

	elem->AddNavPoint(instr);
}
void
FlightPlanner::CreateStrikeRoute(Element* elem, Element* target)
{
	if (!elem) return;

	RLoc           rloc;
	Vec3           dummy(0,0,0);
	Point          loc      = ship->Location();
	double         head     = ship->CompassHeading() + 15*DEGREES;
	double         dist     = 30e3;
	Instruction*   instr    = 0;
	Ship*          tgt_ship = 0;

	if (ship->IsAirborne())
	loc += ship->Cam().vup() * 8e3;
	else
	loc += ship->Cam().vup() * 1e3;

	loc = loc.OtherHand();

	if (target)
	tgt_ship = target->GetShip(1);

	if (tgt_ship) {
		double range = Point(tgt_ship->Location() - ship->Location()).length();

		if (range < 100e3)
		dist = 20e3;
	}

	rloc.SetReferenceLoc(0);
	rloc.SetBaseLocation(loc);
	rloc.SetDistance(dist);
	rloc.SetDistanceVar(0);
	rloc.SetAzimuth(head);
	rloc.SetAzimuthVar(2*DEGREES);

	instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::VECTOR);
	instr->SetSpeed(750);
	instr->GetRLoc() = rloc;


	elem->AddNavPoint(instr);

	if (tgt_ship) {
		Ship*    tgt_ship = target->GetShip(1);
		Point    tgt      = tgt_ship->Location() + tgt_ship->Velocity() * 10;
		Point    mid      = ship->Location() + (tgt - ship->Location()) * 0.5;
		double   beam     = tgt_ship->CompassHeading() + 90*DEGREES;

		if (tgt_ship->IsAirborne())
		tgt += tgt_ship->Cam().vup() * 8e3;
		else
		tgt += tgt_ship->Cam().vup() * 1e3;

		tgt = tgt.OtherHand();
		mid = mid.OtherHand();

      //****** No direct attack run *******//
//		if (tgt_ship && tgt_ship->IsStarship()) {   
//			rloc.SetReferenceLoc(0);
//			rloc.SetBaseLocation(tgt);
//			rloc.SetDistance(60e3);
//			rloc.SetDistanceVar(5e3);
//			rloc.SetAzimuth(beam);
//			rloc.SetAzimuthVar(5*DEGREES);

//			instr = new(__FILE__,__LINE__) Instruction(tgt_ship->GetRegion(), dummy, Instruction::ASSAULT);
//			instr->SetSpeed(750);
//			instr->GetRLoc() = rloc;
//			instr->SetTarget(target->Name());
//			instr->SetFormation(Instruction::TRAIL);

//			elem->AddNavPoint(instr);
//		}

//		if (tgt_ship && tgt_ship->IsStatic()) {


		 if (tgt_ship && tgt_ship->IsDropship()) {
			rloc.SetReferenceLoc(0);
			rloc.SetBaseLocation(tgt);
			rloc.SetDistance(60e3);
			rloc.SetDistanceVar(5e3);
			rloc.SetAzimuth(tgt_ship->CompassHeading());
			rloc.SetAzimuthVar(20*DEGREES);
			rloc.SetElevation(1e3);
			rloc.SetElevationVar(5e3);

			instr = new(__FILE__,__LINE__) Instruction(tgt_ship->GetRegion(), dummy, Instruction::INTERCEPT);
			instr->SetSpeed(750);
			instr->GetRLoc() = rloc;
			instr->SetTarget(target->Name());

			elem->AddNavPoint(instr);
		}

		      //***** Always use mid point Nav before bombing run****//
		 else if (tgt_ship) {
			rloc.SetReferenceLoc(0);
			rloc.SetBaseLocation(mid);
			rloc.SetDistance(60e3);
			rloc.SetDistanceVar(5e3);
			rloc.SetAzimuth(beam);
			rloc.SetAzimuthVar(15*DEGREES);
			rloc.SetElevation(1e3);
			rloc.SetElevationVar(5e3);

			instr = new(__FILE__,__LINE__) Instruction(tgt_ship->GetRegion(), dummy, Instruction::VECTOR);
			instr->SetSpeed(750);
			instr->GetRLoc() = rloc;
			instr->SetFormation(Instruction::BOX);

			elem->AddNavPoint(instr);

			//Assault navpoint
			rloc.SetReferenceLoc(0);
			rloc.SetBaseLocation(tgt);
			rloc.SetDistance(40e3);
			rloc.SetDistanceVar(5e3);
			rloc.SetAzimuth(beam);
			rloc.SetAzimuthVar(5*DEGREES);
			rloc.SetElevation(1e3);
			rloc.SetElevationVar(25e3);

			int action = Instruction::ASSAULT;
			
			if (tgt_ship->IsGroundUnit())
			action = Instruction::STRIKE;

			instr = new(__FILE__,__LINE__) Instruction(tgt_ship->GetRegion(), dummy, action);
			instr->SetSpeed(750);
			instr->GetRLoc() = rloc;
			instr->SetTarget(target->Name());


			elem->AddNavPoint(instr);
		}

	}

	rloc.SetReferenceLoc(0);
	rloc.SetBaseLocation(loc);
	rloc.SetDistance(40e3);
	rloc.SetDistanceVar(0);
	rloc.SetAzimuth(180*DEGREES + ship->CompassHeading());
	rloc.SetAzimuthVar(0*DEGREES);

	instr = new(__FILE__,__LINE__) Instruction(ship->GetRegion(), dummy, Instruction::RTB);
	instr->SetSpeed(750);
	instr->GetRLoc() = rloc;

	elem->AddNavPoint(instr);
}
Пример #6
0
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);
	}
}