ostream& operator << (ostream& os, tower_traffic_type ttt);
+enum tower_callback_type {
+ USER_REQUEST_VFR_DEPARTURE = 1,
+ USER_REQUEST_VFR_ARRIVAL = 2,
+ USER_REQUEST_VFR_ARRIVAL_FULL_STOP = 3,
+ USER_REQUEST_VFR_ARRIVAL_TOUCH_AND_GO = 4,
+ USER_REPORT_3_MILE_FINAL = 5,
+ USER_REPORT_DOWNWIND = 6,
+ USER_REPORT_RWY_VACATED = 7
+};
+
// TODO - need some differentiation of IFR and VFR traffic in order to give the former priority.
// Structure for holding details of a plane under tower control.
bool clearedToTakeOff;
// ought to add time cleared to depart so we can nag if necessary
bool holdShortReported;
+ bool downwindReported;
bool longFinalReported;
bool longFinalAcknowledged;
bool finalReported;
bool finalAcknowledged;
+ bool rwyVacatedReported;
+ bool rwyVacatedAcknowledged;
+ bool instructedToGoAround; // set true if told by tower to go around
bool onRwy; // is physically on the runway
bool nextOnRwy; // currently projected by tower to be the next on the runway
-
- double clearanceCounter; // Hack for communication timing - counter since clearance requested in seconds
+ bool vfrArrivalReported;
+ bool vfrArrivalAcknowledged;
+
// Type of operation the plane is doing
tower_traffic_type opType;
void Init();
void Update(double dt);
+
+ void ReceiveUserCallback(int code);
- void RequestLandingClearance(string ID);
+ // Contact tower for VFR approach
+ // eg "Cessna Charlie Foxtrot Golf Foxtrot Sierra eight miles South of the airport for full stop with Bravo"
+ // This function probably only called via user interaction - AI planes will have an overloaded function taking a planerec.
+ void VFRArrivalContact(string ID, LandingType opt = AIP_LT_UNKNOWN);
+
void RequestDepartureClearance(string ID);
void ReportFinal(string ID);
void ReportLongFinal(string ID);
// Contact tower when at a hold short for departure - for now we'll assume plane - maybe vehicles might want to cross runway eventually?
void ContactAtHoldShort(PlaneRec plane, FGAIPlane* requestee, tower_traffic_type operation);
+ // Register the presence of an AI plane at a point where contact would already have been made in real life
+ // CAUTION - currently it is assumed that this plane's callsign is unique - it is up to AIMgr to generate unique callsigns.
+ void RegisterAIPlane(PlaneRec plane, FGAIPlane* ai, tower_traffic_type op, PatternLeg lg = LEG_UNKNOWN);
+
// Public interface to the active runway - this will get more complex
// in the future and consider multi-runway use, airplane weight etc.
inline string GetActiveRunway() { return activeRwy; }
inline RunwayDetails GetActiveRunwayDetails() { return rwy; }
+ // Get the pattern direction of the active rwy.
+ inline int GetPatternDirection() { return rwy.patternDirection; }
inline void SetDisplay() { display = true; }
inline void SetNoDisplay() { display = false; }
bool GetCrosswindConstraint(double& cpos);
bool GetDownwindConstraint(double& dpos);
bool GetBaseConstraint(double& bpos);
+
+ string GenText(const string& m, int c);
private:
FGATCMgr* ATCmgr;
// This is purely for synactic convienience to avoid writing globals->get_ATC_mgr()-> all through the code!
+
+ // Respond to a transmission
+ void Respond();
+
+ void CheckHoldList(double dt);
+
+ void CheckCircuitList(double dt);
+
+ void CheckRunwayList(double dt);
+ void CheckApproachList(double dt);
+
+ // Currently this assumes we *are* next on the runway and doesn't check for planes about to land -
+ // this should be done prior to calling this function.
+ void ClearHoldingPlane(TowerPlaneRec* t);
+
+ // Find a pointer to plane of callsign ID within the internal data structures
+ TowerPlaneRec* FindPlane(string ID);
+
// Figure out if a given position lies on the active runway
// Might have to change when we consider more than one active rwy.
bool OnActiveRunway(Point3D pt);
// Add a tower plane rec with ETA to the traffic list in the correct position ETA-wise.
// Returns true if this could cause a threshold ETA conflict with other traffic, false otherwise.
bool AddToTrafficList(TowerPlaneRec* t, bool holding = false);
+
+ bool AddToCircuitList(TowerPlaneRec* t);
// Ground can be separate or handled by tower in real life.
// In the program we will always use a separate FGGround class, but we need to know
// Currently not sure whether the above should be always +ve or just take the natural orthopos sign (+ve for RH circuit, -ve for LH).
double base_leg_pos; // Actual offset distance from the threshold (-ve) that planes are turning to base leg.
+ double nominal_crosswind_leg_pos;
+ double nominal_downwind_leg_pos;
+ double nominal_base_leg_pos;
+
friend istream& operator>> ( istream&, FGTower& );
};