int GetNextTaxiPt (int ptindex)
{
	// FRB - CTD's here
	if ((ptindex < 0) || (ptindex >= NumPts))
		ptindex = 0;
	ptindex = GetNextPt(ptindex);
	while(ptindex && PtDataTable[ptindex].type != TaxiPt && PtDataTable[ptindex].type != CritTaxiPt){
		ptindex = GetNextPt(ptindex);
	}
	return ptindex;
}
int FalconATCMessage::Process(uchar autodisp)
{
	AircraftClass *aircraft = (AircraftClass*)vuDatabase->Find(dataBlock.from );
	ObjectiveClass *atc = (ObjectiveClass*)vuDatabase->Find(EntityId());
	runwayQueueStruct *info = NULL;
	FalconRadioChatterMessage *radioMessage = NULL;
	
	if (autodisp)
		return 0;

	float cosAngle=0.0F, dx=0.0F, dy=0.0F, finalHdg=0.0F;
	float finalX=0.0F, finalY=0.0F, baseX=0.0F, baseY=0.0F, x=0.0F ,y=0.0F,z=0.0F, dist=0.0F;
	int	taxiPoint=0, tod=0, time_in_minutes=0;
	int delay = 7 * CampaignSeconds;
	if (!PlayerOptions.PlayerRadioVoice)
	    delay = 500;

	if (aircraft && aircraft->IsAirplane())
	{      
		DigitalBrain *acBrain = aircraft->DBrain();
		ATCBrain*	atcBrain = NULL;

		if(atc)
		{
			atcBrain = atc->brain;
			dx = aircraft->XPos() - atc->XPos();
			dy = aircraft->YPos() - atc->YPos();
			dist = dx*dx + dy*dy;
		}

		switch (dataBlock.type)
		{
		case ContactApproach:
        case RequestClearance:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
			{
				if(aircraft->pctStrength < STRENGTH_PCT_FOR_EMERG_LDG)
					SendCallToATC(aircraft, EntityId(), rcLANDCLEAREMERGENCY, FalconLocalSession);
				else
					SendCallToATC(aircraft, EntityId(), rcLANDCLEARANCE, FalconLocalSession);
			}
			
			if(atcBrain && atc->IsLocal())
			{
				info = atcBrain->InList(aircraft->Id());
				if( info )
				{
					cosAngle = atcBrain->DetermineAngle(aircraft, acBrain->Runway(), lOnFinal);

					//if(info->status >= tReqTaxi)
					//if(info->status < tReqTaxi) // JB 010802 RTBing AI aircraft won't land. This compare was messed up.  Right? I hope so.
					if(info->status >= tReqTaxi) // JB It appears to work but this was called a bit much for my comfort level. We'll try another approach.
					{
						if(!aircraft->OnGround())
						{
							if(dist < (TOWER_RANGE + 100) * NM_TO_FT * NM_TO_FT)
							{
								if(!aircraft->IsPlayer() && aircraft->pctStrength < STRENGTH_PCT_FOR_EMERG_LDG)
									atcBrain->RequestEmerClearance(aircraft);
								else
									atcBrain->RequestClearance(aircraft);
							}
							else if(dist < APPROACH_RANGE * NM_TO_FT * NM_TO_FT && dist >= (TOWER_RANGE + 100) * NM_TO_FT * NM_TO_FT)
							{
								if(!aircraft->IsPlayer() && aircraft->GetCampaignObject()->GetComponentLead() == aircraft)
									HandleInboundFlight( atc, (Flight)aircraft->GetCampaignObject());
								else
									HandleInbound(atc, aircraft);			
							}
							else
							{
								//note this comm should be rcOUTSIDEAIRSPACE, but Joe misnamed it
								radioMessage = CreateCallFromATC(atc, aircraft, rcOUTSIDEAIRSPEED, FalconLocalGame);
								radioMessage->dataBlock.edata[4]	= (short)(rand()%2);
								radioMessage->dataBlock.time_to_play= delay;
								atcBrain->RemoveTraffic(aircraft->Id(), PtHeaderDataTable[info->rwindex].runwayNum);
							}
							info->lastContacted = SimLibElapsedTime;
						}
						break;
					}
					else if(info->rwindex)
					{
						switch(info->status)
						{
						case noATC:

						case lReqClearance:
						case lReqEmerClearance:

						case lIngressing:
						case lTakingPosition:
							ShiWarning("This should never happen!");
							radioMessage = CreateCallFromATC(atc, aircraft, rcCONTINUEINBOUND1, FalconLocalGame);
							//M.N. changed to 32767 -> flexibly use randomized value of max available eval indexes
							radioMessage->dataBlock.edata[4]	= 32767;
							radioMessage->dataBlock.edata[5]	= (short)atcBrain->GetRunwayName(atcBrain->GetOppositeRunway(info->rwindex));
							if(rand()%2)
								radioMessage->dataBlock.edata[6]	= 4;
							else
								radioMessage->dataBlock.edata[6]	= -1;
							break;

						case lAborted:
							atcBrain->FindAbortPt(aircraft, &x, &y, &z);
							radioMessage = CreateCallFromATC (atc, aircraft, rcATCGOAROUND, FalconLocalSession);
					
							atcBrain->CalculateStandRateTurnToPt(aircraft, x, y, &finalHdg);
							radioMessage->dataBlock.edata[3] = (short)FloatToInt32(finalHdg);
							//M.N. changed to 32767 -> flexibly use randomized value of max available eval indexes
							radioMessage->dataBlock.edata[4] = 32767;
							break;

						case lEmerHold:
						case lHolding:
							radioMessage = CreateCallFromATC (atc, aircraft, rcATCORBIT2, FalconLocalGame);
							radioMessage->dataBlock.edata[2] = -1; //altitude in thousands
							radioMessage->dataBlock.edata[3] = -1; //altitude in thousands
							break;

						case lFirstLeg:
						case lToBase:
						case lToFinal:
							radioMessage = CreateCallFromATC(atc, aircraft, rcATCLANDSEQUENCE, FalconLocalGame);
							radioMessage->dataBlock.edata[4] = (short)atcBrain->GetLandingNumber(info);
							//atcBrain->SendCmdMessage(aircraft, info);
							break;

						case lOnFinal:
						case lClearToLand:
							if(aircraft->DBrain()->IsSetATC(DigitalBrain::ClearToLand))
							{
								radioMessage = CreateCallFromATC (atc, aircraft, rcCLEAREDLAND, FalconLocalGame);
								radioMessage->dataBlock.edata[4] = (short)atcBrain->GetRunwayName(atcBrain->GetOppositeRunway(acBrain->Runway()));
							}
							else
							{
								radioMessage = CreateCallFromATC(atc, aircraft, rcATCLANDSEQUENCE, FalconLocalGame);
								radioMessage->dataBlock.edata[4] = (short)atcBrain->GetLandingNumber(info);
							}
							break;

						case lLanded:
							radioMessage = CreateCallFromATC (atc, aircraft, rcTAXICLEAR, FalconLocalGame);
							break;

						case lTaxiOff:
							//there isn't anything better to say, oh well :)
							radioMessage = CreateCallFromATC (atc, aircraft, rcTAXICLEAR, FalconLocalGame);
							break;

						case lEmergencyToBase:
						case lEmergencyToFinal:
						case lEmergencyOnFinal:
							atcBrain->RequestClearance(aircraft);
							return 1;
							break;

						case lCrashed:
							radioMessage = CreateCallFromATC (atc, aircraft, rcCLEAREDEMERGLAND, FalconLocalGame);
							radioMessage->dataBlock.edata[3] = -1;

							radioMessage->dataBlock.edata[4] = -1;
							//M.N. changed to 32767 -> flexibly use randomized value of max available eval indexes
							radioMessage->dataBlock.edata[5] = 32767;
							break;
						}
					}
					else
					{
						radioMessage = CreateCallFromATC(atc, aircraft, rcCONTINUEINBOUND2, FalconLocalGame);

						if(rand()%2)
						{
							radioMessage->dataBlock.edata[3]	= (short)(rand()%3);
						}
						else
						{
							time_in_minutes =  TheCampaign.GetMinutesSinceMidnight();
							if (time_in_minutes < 180)//3am
								tod = 1;
							else if(time_in_minutes < 720 )//noon
								tod = 0;
							else if(time_in_minutes < 1020 ) //5pm
								tod = 2;
							else
								tod = 1;

							radioMessage->dataBlock.edata[3]	= (short)(3 + tod + (rand()%3)*3);
						}

						if(rand()%2)
							radioMessage->dataBlock.edata[4]	= 4;
						else
							radioMessage->dataBlock.edata[4]	= -1;

						atcBrain->SendCmdMessage(aircraft, info);
					}
					if (radioMessage)
					{
						info->lastContacted = SimLibElapsedTime;
						if (PlayerOptions.PlayerRadioVoice)
						    radioMessage->dataBlock.time_to_play= 2 * CampaignSeconds;
						else 
						    radioMessage->dataBlock.time_to_play= delay;
						FalconSendMessage(radioMessage, TRUE);
					}
				}
				else
				{
					if(dist <= (TOWER_RANGE + 100) * NM_TO_FT * NM_TO_FT)
					{
						if(aircraft->GetCampaignObject()->GetComponentLead() == aircraft)
						{
							AircraftClass *element = NULL;
							Flight flight = (Flight)aircraft->GetCampaignObject();
							VuListIterator	flightIter(flight->GetComponents());

							element = (AircraftClass*) flightIter.GetFirst();
							while(element)
							{
								runwayQueueStruct *tempinfo = atcBrain->InList(element->Id());
								if(!tempinfo)
								{
									if( !element->IsPlayer() && element->pctStrength < STRENGTH_PCT_FOR_EMERG_LDG)
									{
										SendCallToATC(element, EntityId(), rcLANDCLEAREMERGENCY, FalconLocalGame);
										atcBrain->RequestEmerClearance(element);
									}
									else
										atcBrain->RequestClearance(element);
								}
								element = (AircraftClass*) flightIter.GetNext();
							}
						}
						else
						{
							if(!aircraft->IsPlayer() && aircraft->pctStrength < STRENGTH_PCT_FOR_EMERG_LDG)
							{
								SendCallToATC(aircraft, EntityId(), rcLANDCLEAREMERGENCY, FalconLocalGame);
								atcBrain->RequestEmerClearance(aircraft);
							}
							else
								atcBrain->RequestClearance(aircraft);
						}
					}
					else if(dist < APPROACH_RANGE * NM_TO_FT * NM_TO_FT && dist > (TOWER_RANGE + 100) * NM_TO_FT * NM_TO_FT)
					{
						if(aircraft->GetCampaignObject()->GetComponentLead() == aircraft)
							HandleInboundFlight( atc, (Flight)aircraft->GetCampaignObject());
						else
							HandleInbound(atc, aircraft);						
					}
					else
					{
						//note this comm should be rcOUTSIDEAIRSPACE, but Joe misnamed it
						radioMessage = CreateCallFromATC(atc, aircraft, rcOUTSIDEAIRSPEED, FalconLocalGame);
						radioMessage->dataBlock.edata[4]	= (short)(rand()%2);
						radioMessage->dataBlock.time_to_play= delay;
						FalconSendMessage(radioMessage, TRUE);
					}
				}
			}
			break;
			
        case RequestEmerClearance:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcLANDCLEAREMERGENCY, FalconLocalSession);
			if(atcBrain && atc->IsLocal())
				atcBrain->RequestEmerClearance(aircraft);			
			break;
		
        case RequestTakeoff:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcREADYFORDERARTURE, FalconLocalSession);
			if(atcBrain && atc->IsLocal())
				atcBrain->RequestTakeoff(aircraft);
			break;
			
        case RequestTaxi:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcREADYFORDERARTURE, FalconLocalSession);
			if(atcBrain && atc->IsLocal())
				atcBrain->RequestTaxi(aircraft);
			break;
// M.N. 2001-12-20
		case AbortApproach:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcABORTAPPROACH, FalconLocalSession);
				atcBrain->AbortApproach(aircraft);//Cobra
			if (atcBrain && atc->IsLocal())
				atcBrain->AbortApproach(aircraft);
			break;

// RAS - 22Jan04 - Set flag for traffic in sight call 
		case TrafficInSight:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcCOPY, FalconLocalSession);
			if (atcBrain && atc->IsLocal())
				atcBrain->trafficInSightFlag = TRUE;
			break;
// TJL 08/16/04 - Set flag for Hotpit Refueling //Cobra 10/31/04 TJL
 		case RequestHotpitRefuel:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
 				SendCallToATC(aircraft, EntityId(), rcCOPY, FalconLocalSession);
				aircraft->requestHotpitRefuel = TRUE; //Cobra 11/13/04 TJL will this make online work?
 			if (atcBrain && atc->IsLocal())
 				aircraft->requestHotpitRefuel = TRUE;
 			break;


		case UpdateStatus:
			if(atcBrain)
			{
				if(atc->IsLocal())
				{
					info = atcBrain->InList(aircraft->Id());
					if(info)
					{
						switch(dataBlock.status)
						{
						case noATC:
							if(info->rwindex)
								atcBrain->RemoveTraffic(aircraft->Id(), PtHeaderDataTable[info->rwindex].runwayNum);
							else
								atcBrain->RemoveInbound(info);
							break;
						case lReqClearance:
						case lReqEmerClearance:
						case tReqTaxi:
						case tReqTakeoff:
						case lIngressing:
						case lTakingPosition:
							break;
						case tFlyOut:
							info->lastContacted = SimLibElapsedTime;
							info->status = noATC;
							break;
						case lCrashed:
							info->lastContacted = SimLibElapsedTime;
							info->status = lCrashed;
							{
								atcBrain->RemoveFromAllOtherATCs(aircraft);
								int Runway = atcBrain->IsOverRunway(aircraft);
								if(GetQueue(Runway) != GetQueue(info->rwindex))
								{
									atcBrain->RemoveTraffic(aircraft->Id(), GetQueue(info->rwindex));
									atcBrain->AddTraffic(aircraft->Id(), lCrashed, Runway, SimLibElapsedTime);
								}
								atcBrain->FindNextEmergency(GetQueue(Runway));
								atcBrain->SetEmergency(GetQueue(Runway));
							}
							break;
						default:
							info->lastContacted = SimLibElapsedTime;
							info->status = (AtcStatusEnum)dataBlock.status;
							break;
						}
					}
					else
					{
						//he thinks we already know about him, orig owner of atc must have dropped
						//offline, so we need to put him into the appropriate list
						switch(dataBlock.status)
						{
							case lIngressing:
								break;
							case lTakingPosition:
							case lAborted:
							case lEmerHold:
							case lHolding:
							case lFirstLeg:
							case lToBase:
							case lToFinal:
							case lOnFinal:
							case lLanded:
							case lTaxiOff:
							case lEmergencyToBase:
							case lEmergencyToFinal:
							case lEmergencyOnFinal:
							case lClearToLand:
								atcBrain->RequestClearance(aircraft);			
								break;
							case lCrashed:
								{
									atcBrain->RemoveFromAllOtherATCs(aircraft);
									int Runway = atcBrain->IsOverRunway(aircraft);
									atcBrain->AddTraffic(aircraft->Id(), lCrashed, Runway, SimLibElapsedTime);
									atcBrain->FindNextEmergency(GetQueue(Runway));
									atcBrain->SetEmergency(GetQueue(Runway));
								}
								break;
							case tEmerStop:
							case tTaxi:
							case tHoldShort:
							case tPrepToTakeRunway:
							case tTakeRunway:
							case tTakeoff:
								atcBrain->RequestTaxi(aircraft);
								break;
							case tFlyOut:
								break;
							default:
								break;
						}
					}
				}

				//update track point, taxi point, timer, status, etc...
				switch(dataBlock.status)
				{
				case noATC:
					break;
				case lClearToLand:
					break;
				case lIngressing:
				case lTakingPosition:
					atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &x, &y);
					acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lTakingPosition));
					break;
				case lEmerHold:
				case lHolding:
					acBrain->SetTrackPoint(aircraft->XPos(), aircraft->YPos(), atcBrain->GetAltitude(aircraft, lHolding));
					break;

				case lFirstLeg:				
					if(acBrain->ATCStatus() != lFirstLeg && acBrain->ATCStatus() <= lOnFinal)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						cosAngle = atcBrain->DetermineAngle(aircraft, acBrain->Runway(), lFirstLeg);
						if(cosAngle < 0.0F)
						{
							atcBrain->FindBasePt(aircraft, acBrain->Runway(), finalX, finalY, &baseX, &baseY);
							atcBrain->FindFirstLegPt(aircraft, acBrain->Runway(), acBrain->RwTime(), baseX, baseY, TRUE, &x, &y);
						}
						else
						{
							atcBrain->FindFirstLegPt(aircraft, acBrain->Runway(), acBrain->RwTime(), finalX, finalY, FALSE, &x, &y);
						}

						acBrain->SetATCStatus(lFirstLeg);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lFirstLeg));
						acBrain->CalculateNextTurnDistance();
					}

					if( !aircraft->IsPlayer() )
					{
						atcBrain->MakeVectorCall(aircraft, FalconLocalSession);
					}
					break;

				case lToBase:
					if(acBrain->ATCStatus() != lToBase && acBrain->ATCStatus() <= lOnFinal)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						atcBrain->FindBasePt(aircraft, acBrain->Runway(), finalX, finalY, &baseX, &baseY);
						acBrain->SetATCStatus(lToBase);
						acBrain->SetTrackPoint(baseX, baseY, atcBrain->GetAltitude(aircraft, lToBase));
						acBrain->CalculateNextTurnDistance();
					}

					if( !aircraft->IsPlayer() )
					{
						atcBrain->MakeVectorCall(aircraft, FalconLocalSession);
					}
					break;

				case lToFinal:
					if(acBrain->ATCStatus() != lToFinal && acBrain->ATCStatus() <= lOnFinal)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						acBrain->SetATCStatus(lToFinal);
						acBrain->SetTrackPoint(finalX, finalY, atcBrain->GetAltitude(aircraft, lToFinal));
						acBrain->CalculateNextTurnDistance();
					}

					if( !aircraft->IsPlayer() )
					{
						atcBrain->MakeVectorCall(aircraft, FalconLocalSession);
					}
					break;

				case lOnFinal:
					TranslatePointData (atc, GetFirstPt(acBrain->Runway()), &x, &y);
					//if we sent the message we already know this				
					if(acBrain->ATCStatus() != lOnFinal && acBrain->ATCStatus() <= lOnFinal)
					{						
						acBrain->SetATCStatus(lOnFinal);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lOnFinal));
						acBrain->CalculateNextTurnDistance();
					}

					if( !aircraft->IsPlayer() )
					{
						radioMessage = CreateCallFromATC (atc, aircraft, rcTURNTOFINAL, FalconLocalSession);
#if 0
						//MI Turn final for AI fix
						if(atcBrain->CalculateStandRateTurnToPt(aircraft, x, y, &finalHdg) > 0)
							radioMessage->dataBlock.edata[2] = 1;
						else
							radioMessage->dataBlock.edata[2] = 0;
#else
						if(atcBrain->CalculateStandRateTurnToPt(aircraft, x, y, &finalHdg) > 0)
							radioMessage->dataBlock.edata[2] = 0;
						else
							radioMessage->dataBlock.edata[2] = 1;
#endif	
						finalHdg = PtHeaderDataTable[acBrain->Runway()].data + 180.0F;
						if(finalHdg > 360)
							finalHdg -= 360;

						radioMessage->dataBlock.edata[3] = (short)FloatToInt32(finalHdg);
						//M.N. changed to 32767 -> flexibly use randomized value of max available eval indexes
						radioMessage->dataBlock.edata[4] = 32767; //vector type
						FalconSendMessage(radioMessage, TRUE);
					}
					break;


				case lLanded:
					//if we sent the message we already know this	
					if(acBrain->ATCStatus() != lLanded)
					{
						acBrain->SetATCStatus(lLanded);
						taxiPoint = GetFirstPt(acBrain->Runway());
						TranslatePointData (atc,GetNextPt(taxiPoint) , &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lLanded));
					}
					break;

				case lTaxiOff:
					break;

				case lAborted:					
					if(acBrain->ATCStatus() != lAborted)
					{
						atcBrain->FindAbortPt(aircraft, &x, &y, &z);
						acBrain->SetATCStatus(lAborted);					
						acBrain->SetTrackPoint(x, y, z);
					}

					if(atc->IsLocal())
					{
						atcBrain->RemoveTraffic(aircraft->Id(), PtHeaderDataTable[acBrain->Runway()].runwayNum);
					}
					break;

				case lEmergencyToBase:
					if(acBrain->ATCStatus() != lEmergencyToBase)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						atcBrain->FindBasePt(aircraft, acBrain->Runway(), finalX, finalY, &baseX, &baseY);
						acBrain->SetATCStatus(lEmergencyToBase);
						acBrain->SetTrackPoint(baseX, baseY, atcBrain->GetAltitude(aircraft, lEmergencyToBase));
					}
					break;

				case lEmergencyToFinal:
					if(acBrain->ATCStatus() != lEmergencyToFinal)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						acBrain->SetATCStatus(lEmergencyToFinal);
						acBrain->SetTrackPoint(finalX, finalY, atcBrain->GetAltitude(aircraft, lEmergencyToFinal));
					}
					break;

				case lEmergencyOnFinal:
					if(acBrain->ATCStatus() != lEmergencyOnFinal)
					{
						TranslatePointData (atc, GetFirstPt(acBrain->Runway()), &x, &y);
						acBrain->SetATCStatus(lEmergencyOnFinal);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lEmergencyOnFinal));
					}
					break;

				case lCrashed:
					acBrain->SetATCStatus(lCrashed);
					break;

				case tEmerStop:
					acBrain->SetATCStatus(tEmerStop);
					break;

				case tTaxi:
					if(acBrain->ATCStatus() != tTaxi)
					{
						acBrain->SetATCStatus(tTaxi);
						TranslatePointData (atc,acBrain->GetTaxiPoint() , &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tTaxi));
					}
					break;

				case tHoldShort:
					acBrain->ClearATCFlag(DigitalBrain::PermitRunway);
					acBrain->ClearATCFlag(DigitalBrain::PermitTakeoff);

					if(acBrain->ATCStatus() != tHoldShort)
					{
						acBrain->SetATCStatus(tHoldShort);
						taxiPoint = GetFirstPt(acBrain->Runway());
						taxiPoint = GetNextPt(taxiPoint);
						TranslatePointData (atc,taxiPoint , &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tHoldShort));
					}
					break;

				case tPrepToTakeRunway:
					acBrain->SetATCFlag(DigitalBrain::PermitTakeRunway);
					if(acBrain->ATCStatus() != tTaxi)
					{
						acBrain->SetATCStatus(tTaxi);
						if(PtDataTable[acBrain->GetTaxiPoint()].type == TakeoffPt)
							atcBrain->FindTakeoffPt((Flight)aircraft->GetCampaignObject(), aircraft->vehicleInUnit, acBrain->Runway(), &x, &y);
						else
							TranslatePointData (atc,acBrain->GetTaxiPoint() , &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tTaxi));
					}
					break;

				case tTakeRunway:
					if(acBrain->ATCStatus() != tTakeRunway)
					{
						acBrain->SetATCFlag(DigitalBrain::PermitTakeRunway);
						acBrain->SetATCStatus(tTakeRunway);
						atcBrain->FindTakeoffPt((Flight)aircraft->GetCampaignObject(), aircraft->vehicleInUnit, acBrain->Runway(), &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tTakeRunway));
					}
					break;

				case tTakeoff:
					if(acBrain->ATCStatus() != tTakeoff)
					{
						acBrain->SetATCFlag(DigitalBrain::PermitRunway);
						acBrain->SetATCFlag(DigitalBrain::PermitTakeoff);
						acBrain->SetATCStatus(tTakeRunway);
						atcBrain->FindRunwayPt((Flight)aircraft->GetCampaignObject(), aircraft->vehicleInUnit, acBrain->Runway(), &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tTakeRunway));
					}
					break;

				case tTaxiBack:
					if(acBrain->ATCStatus() != tTaxiBack)
					{
						acBrain->SetATCStatus(tTaxiBack);
					}
					break;

				case tFlyOut:
					if(acBrain->ATCStatus() != tFlyOut)
					{
						acBrain->ResetATC();
					}
				default:
					break;
				}
			}
			break;
		}
	}
	return 1;
}
Beispiel #3
0
void CControl::TreeGrowing(TreeType::iterator n_Iterator,CTreeTracker& n_treetracker,int n_depth)
{
  //++++++++++++++++++++++++++++++++++++++
  // Iterator Function
  RotatedRect n_RectCenter=n_Iterator->mRect;
  int n_neighbour[5]={0,1,-1,2,-2};
  int n_neighbours=0;
  for(int i=0;i<n_depth;i++)
    cout<<"+";
  cout<<endl;
  for(int i=0;i<5;i++)
    {
      //get next points
      Point2f n_pt=GetNextPt(n_RectCenter.center,n_RectCenter.angle,nControlOptions.nSteps);
      //get the next angle
      float n_angle=n_RectCenter.angle+n_neighbour[i]*45;
      //get the next rotatedrect
      RotatedRect n_RectNeighbour;
      if(!GetRotatedRect(n_pt,n_angle,n_RectNeighbour))
	continue;
      //check if overlay in temp spatial index;
      if(n_treetracker.CheckOverLay(n_RectNeighbour))
	continue;
      //check if overlay in gloable spatial index;

      //get subsetimg;
      Mat n_img=GetSubsetImg(n_RectNeighbour);
      //get lines in all direction;
      nLineSegExtractor.SetParamters(n_img);
      vector<Point2f> n_linevct=nLineSegExtractor.GetLineSegments();
      //get lines in specific direction
      vector<Point2f> n_filterlinevct;
      FilterLineAngle(n_linevct,n_filterlinevct,0,nControlOptions.nAngleThhold);
      //get ransac lines;
      vector<Point3f> n_linecoef;
      nRansacExtractor.GetRansacLines(n_linecoef,n_filterlinevct,nControlOptions.nInterval,nControlOptions.nRansacThreshold,nControlOptions.nRansacMininlier);
      if(nIfDebug)
	{
	  //	  cout<<"angle: "<<n_angle<<' '<<"threshold: "<<nControlOptions.nAngleThhold<<endl;
	  //	  cout<<"get filter line: "<<n_filterlinevct.size()<<endl;
	  //	  cout<<"get ransac lines: "<<n_linecoef.size()<<endl;
	  //   Draw_debug;
	  // draw n_filterlinevct;
	  char* n_windowname1="2";
	  Draw_debug(n_img,n_filterlinevct,n_windowname1);
	  //draw all lines
	  char* n_windowname2="1";
	  Draw_debug(n_img,n_linevct,n_windowname2);
      	}	    
      //evaluate pass direction;
      CEvaluate n_evaluate;
      n_evaluate.SetLines(n_linecoef,n_filterlinevct);
      n_evaluate.GetNearestLines(5);
      float n_score=GetWeightedScore(n_evaluate.GetDensityVal(),n_evaluate.GetLengthVal(),n_RectNeighbour.size.width);

      //in the turning directions,we should add **  information
      float n_score2=0;
      if(i!=0)
	{
	  //get lines in vertical direction
	  vector<Point2f> n_filterlinevct2;
	  FilterLineAngle(n_linevct,n_filterlinevct2,90,nControlOptions.nAngleThhold);
	  //get ransac lines;
	  vector<Point3f> n_linecoef2;
	  nRansacExtractor.GetRansacLines(n_linecoef2,n_filterlinevct2,nControlOptions.nInterval,nControlOptions.nRansacThreshold,nControlOptions.nRansacMininlier);
	  if(nIfDebug)
	    {
	      //	      cout<<"get vertical filter line: "<<n_filterlinevct2.size()<<endl;
	      //	      cout<<"get vertical ransac lines: "<<n_linecoef2.size()<<endl;
	      //   Draw_debug;
	      // draw n_filterlinevct;
	      char* n_windowname1="vertical lines";
	      Draw_debug(n_img,n_filterlinevct2,n_windowname1);
	    }	    
	  //evaluate vertical situation;
	  CEvaluate n_evaluate2;
	  n_evaluate2.SetLines(n_linecoef2,n_filterlinevct2);
	  n_evaluate2.GetNearestLines(5);
	  n_score2=GetWeightedScore(n_evaluate2.GetDensityVal(),n_evaluate2.GetLengthVal(),n_RectNeighbour.size.height);
	  //draw vertical direction rectangles.
	  n_evaluate2.Draw_debug(n_img,"VerticalDirection");
	}
      
      if(nIfDebug)
	{
	  cout<<"score1:"<<n_score<<" score2:"<<n_score2<<endl;
	  //draw rotated rect on gloable img
	  char* n_windowname3="gloable";
	  Point2f n_vertices[4];
	  n_RectNeighbour.points(n_vertices);
	  Draw_debug(nImgRaw,n_vertices,n_windowname3);
	  //draw pass direction rectangles 
	  n_evaluate.Draw_debug(n_img,"PassDirection");
	  waitKey(0);
	}
      n_score-=n_score2;
      if(n_score>nControlOptions.mEvaluateThreshold)
	{
	  //do something;
	  //insert into tree;
	  StrctRoadNode n_node(n_RectNeighbour);
	  TreeType::iterator n_it2;
	  if(!n_treetracker.Insert(n_Iterator,n_node,n_it2))
	    continue;
	  //add into spatial tree
	  n_treetracker.AddSpatialIdx(n_RectNeighbour,1);
	  //grow tree using iterate;
	  n_neighbours++;
	  //draw all path rectangles in gloable img
	  if(nIfDebug)
	    {
	      Draw_debug(nImgRaw,n_treetracker.GetPathRect(n_it2),"gloable2");
	      waitKey(0);
	    }
	  //  n_evaluate.Draw_debug_gloable(nImgRaw,
	  //  Draw_debug(nImgRaw,
	  //reduce case;
	  TreeGrowing(n_it2,n_treetracker,n_depth+1);
	}	
      
    }
  //if no neighour exist,then add end point for traverse
  if(n_neighbours==0)
    n_treetracker.InsertEndNode(n_Iterator);
}
int TaskForceClass::GetDeaggregationPoint (int slot, CampEntity *installation)
{
    int			pt=0,type;
    static int	last_pt, index = 0;

    if (!*installation)
    {
        // We're looking for a new list, so clear statics
        last_pt = index = 0;

        // Check if we care about placement
        if (!Moving())
        {
            // Find the appropriate installation
            GridIndex	x,y;
            Objective	o;
            GetLocation(&x,&y);
            o = FindNearestObjective (x,y,NULL,0);
            *installation = o;

            // Find the appropriate list
            if (o)
            {
                ObjClassDataType	*oc = o->GetObjectiveClassData();
                index = oc->PtDataIndex;
                while (index)
                {
                    if (PtHeaderDataTable[index].type == DockListType)
                    {
                        // The first time we look, we just want to know if we have a list.
                        // Return now.
                        return index;
                    }
                    index = PtHeaderDataTable[index].nextHeader;
                }
#ifdef DEBUG
                FILE	*fp = fopen("PtDatErr.log","a");
                if (fp)
                {
                    char		name[80];
                    o->GetName(name,79,FALSE);
                    fprintf(fp, "Obj %s @ %d,%d: No header list of type %d.\n",name,x,y,DockListType);
                    fclose(fp);
                }
#endif
            }
        }
    }

    if (index)
    {
        // We have a list, and want to find the correct point
        UnitClassDataType		*uc = GetUnitClassData();
        VehicleClassDataType	*vc = GetVehicleClassData(uc->VehicleType[slot]);

        // Check which type of point we're looking for
        // TODO: Check ship type here...
        //		type = SmallDockPt;
        type = LargeDockPt;

        // Return the next point, if it's the base type
        // NOTE: Log error if we don't have enough points of this type
        if (last_pt)
        {
            last_pt = pt = GetNextPt(last_pt);
#ifdef DEBUG
            if (!pt || PtDataTable[pt].type != type)
            {
                FILE	*fp = fopen("PtDatErr.log","a");
                if (fp)
                {
                    char		name[80];
                    GridIndex	x,y;
                    (*installation)->GetName(name,79,FALSE);
                    (*installation)->GetLocation(&x,&y);
                    fprintf(fp, "HeaderList %d (Obj %s @ %d,%d): Insufficient points of type %d.\n",index,name,x,y,type);
                    fclose(fp);
                }
            }
#endif
            return pt;
        }

        // Find one of the appropriate type
        pt = GetFirstPt(index);
        while (pt)
        {
            if (PtDataTable[pt].type == type)
            {
                last_pt = pt;
                return pt;
            }
            pt = GetNextPt(pt);
        }
#ifdef DEBUG
        FILE	*fp = fopen("PtDatErr.log","a");
        if (fp)
        {
            char		name[80];
            GridIndex	x,y;
            (*installation)->GetName(name,79,FALSE);
            (*installation)->GetLocation(&x,&y);
            fprintf(fp, "HeaderList %d (Obj %s @ %d,%d): No points of type %d.\n",index,name,x,y,type);
            fclose(fp);
        }
#endif
    }
    return pt;
}