Further progress towards interactive ATC
This commit is contained in:
parent
6162d4462b
commit
430a44a803
5 changed files with 149 additions and 40 deletions
|
@ -19,6 +19,17 @@
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
/*==========================================================
|
||||||
|
|
||||||
|
TODO list.
|
||||||
|
|
||||||
|
Should get pattern direction from tower.
|
||||||
|
|
||||||
|
Need to continually monitor and adjust deviation from glideslope
|
||||||
|
during descent to avoid occasionally landing short or long.
|
||||||
|
|
||||||
|
============================================================*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -95,6 +95,7 @@ struct RunwayDetails {
|
||||||
double length; // In *METERS*
|
double length; // In *METERS*
|
||||||
double width; // ditto
|
double width; // ditto
|
||||||
string rwyID;
|
string rwyID;
|
||||||
|
int patternDirection; // -1 for left, 1 for right
|
||||||
};
|
};
|
||||||
|
|
||||||
ostream& operator << (ostream& os, atc_type atc);
|
ostream& operator << (ostream& os, atc_type atc);
|
||||||
|
|
|
@ -254,41 +254,33 @@ void FGATCDialog::add_entry(string station, string transmission, string menutext
|
||||||
a.menuentry = menutext;
|
a.menuentry = menutext;
|
||||||
a.callback_code = code;
|
a.callback_code = code;
|
||||||
|
|
||||||
//atcmentrylist_station[station.c_str()].push_back(a);
|
|
||||||
(available_dialog[type])[station.c_str()].push_back(a);
|
(available_dialog[type])[station.c_str()].push_back(a);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGATCDialog::remove_entry( const string &station, const string &trans, atc_type type ) {
|
void FGATCDialog::remove_entry( const string &station, const string &trans, atc_type type ) {
|
||||||
atcmentry_vec_type atcmlist = (available_dialog[type])[station];
|
atcmentry_vec_type* p = &((available_dialog[type])[station]);
|
||||||
atcmentry_vec_iterator current = atcmlist.begin();
|
atcmentry_vec_iterator current = p->begin();
|
||||||
atcmentry_vec_iterator last = atcmlist.end();
|
while(current != p->end()) {
|
||||||
|
if(current->transmission == trans) current = p->erase(current);
|
||||||
while(current != last) {
|
|
||||||
if(current->transmission == trans) current = atcmlist.erase(current);
|
|
||||||
else ++current;
|
else ++current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGATCDialog::remove_entry( const string &station, int code, atc_type type ) {
|
void FGATCDialog::remove_entry( const string &station, int code, atc_type type ) {
|
||||||
atcmentry_vec_type atcmlist = (available_dialog[type])[station];
|
atcmentry_vec_type* p = &((available_dialog[type])[station]);
|
||||||
atcmentry_vec_iterator current = atcmlist.begin();
|
atcmentry_vec_iterator current = p->begin();
|
||||||
atcmentry_vec_iterator last = atcmlist.end();
|
while(current != p->end()) {
|
||||||
|
if(current->callback_code == code) current = p->erase(current);
|
||||||
while(current != last) {
|
|
||||||
if(current->callback_code == code) current = atcmlist.erase(current);
|
|
||||||
else ++current;
|
else ++current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// query the database whether the transmission is already registered;
|
// query the database whether the transmission is already registered;
|
||||||
bool FGATCDialog::trans_reg( const string &station, const string &trans, atc_type type ) {
|
bool FGATCDialog::trans_reg( const string &station, const string &trans, atc_type type ) {
|
||||||
//atcmentry_list_type atcmlist = atcmentrylist_station[station];
|
atcmentry_vec_type* p = &((available_dialog[type])[station]);
|
||||||
atcmentry_vec_type atcmlist = (available_dialog[type])[station];
|
atcmentry_vec_iterator current = p->begin();
|
||||||
atcmentry_vec_iterator current = atcmlist.begin();
|
for ( ; current != p->end() ; ++current ) {
|
||||||
atcmentry_vec_iterator last = atcmlist.end();
|
|
||||||
|
|
||||||
for ( ; current != last ; ++current ) {
|
|
||||||
if ( current->transmission == trans ) return true;
|
if ( current->transmission == trans ) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -296,12 +288,9 @@ bool FGATCDialog::trans_reg( const string &station, const string &trans, atc_typ
|
||||||
|
|
||||||
// query the database whether the transmission is already registered;
|
// query the database whether the transmission is already registered;
|
||||||
bool FGATCDialog::trans_reg( const string &station, int code, atc_type type ) {
|
bool FGATCDialog::trans_reg( const string &station, int code, atc_type type ) {
|
||||||
//atcmentry_list_type atcmlist = atcmentrylist_station[station];
|
atcmentry_vec_type* p = &((available_dialog[type])[station]);
|
||||||
atcmentry_vec_type atcmlist = (available_dialog[type])[station];
|
atcmentry_vec_iterator current = p->begin();
|
||||||
atcmentry_vec_iterator current = atcmlist.begin();
|
for ( ; current != p->end() ; ++current ) {
|
||||||
atcmentry_vec_iterator last = atcmlist.end();
|
|
||||||
|
|
||||||
for ( ; current != last ; ++current ) {
|
|
||||||
if ( current->callback_code == code ) return true;
|
if ( current->callback_code == code ) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -366,7 +355,7 @@ void FGATCDialog::PopupDialog() {
|
||||||
}
|
}
|
||||||
optList[k] = NULL;
|
optList[k] = NULL;
|
||||||
atcDialogCommunicationOptions->newList(optList);
|
atcDialogCommunicationOptions->newList(optList);
|
||||||
atcDialogCommunicationOptions->setSize(w-100, h-100);
|
atcDialogCommunicationOptions->setSize(w-100, h-90);
|
||||||
atcDialogCommunicationOptions->reveal();
|
atcDialogCommunicationOptions->reveal();
|
||||||
atcDialogMessage -> setLabel( "ATC Menu" );
|
atcDialogMessage -> setLabel( "ATC Menu" );
|
||||||
atcDialogMessage -> setPosition(w / 2, h - 30);
|
atcDialogMessage -> setPosition(w / 2, h - 30);
|
||||||
|
|
|
@ -45,6 +45,8 @@ TowerPlaneRec::TowerPlaneRec() :
|
||||||
longFinalAcknowledged(false),
|
longFinalAcknowledged(false),
|
||||||
finalReported(false),
|
finalReported(false),
|
||||||
finalAcknowledged(false),
|
finalAcknowledged(false),
|
||||||
|
rwyVacatedReported(false),
|
||||||
|
rwyVacatedAcknowledged(false),
|
||||||
instructedToGoAround(false),
|
instructedToGoAround(false),
|
||||||
onRwy(false),
|
onRwy(false),
|
||||||
nextOnRwy(false),
|
nextOnRwy(false),
|
||||||
|
@ -68,6 +70,8 @@ TowerPlaneRec::TowerPlaneRec(PlaneRec p) :
|
||||||
longFinalAcknowledged(false),
|
longFinalAcknowledged(false),
|
||||||
finalReported(false),
|
finalReported(false),
|
||||||
finalAcknowledged(false),
|
finalAcknowledged(false),
|
||||||
|
rwyVacatedReported(false),
|
||||||
|
rwyVacatedAcknowledged(false),
|
||||||
instructedToGoAround(false),
|
instructedToGoAround(false),
|
||||||
onRwy(false),
|
onRwy(false),
|
||||||
nextOnRwy(false),
|
nextOnRwy(false),
|
||||||
|
@ -91,6 +95,8 @@ TowerPlaneRec::TowerPlaneRec(Point3D pt) :
|
||||||
longFinalAcknowledged(false),
|
longFinalAcknowledged(false),
|
||||||
finalReported(false),
|
finalReported(false),
|
||||||
finalAcknowledged(false),
|
finalAcknowledged(false),
|
||||||
|
rwyVacatedReported(false),
|
||||||
|
rwyVacatedAcknowledged(false),
|
||||||
instructedToGoAround(false),
|
instructedToGoAround(false),
|
||||||
onRwy(false),
|
onRwy(false),
|
||||||
nextOnRwy(false),
|
nextOnRwy(false),
|
||||||
|
@ -115,6 +121,8 @@ TowerPlaneRec::TowerPlaneRec(PlaneRec p, Point3D pt) :
|
||||||
longFinalAcknowledged(false),
|
longFinalAcknowledged(false),
|
||||||
finalReported(false),
|
finalReported(false),
|
||||||
finalAcknowledged(false),
|
finalAcknowledged(false),
|
||||||
|
rwyVacatedReported(false),
|
||||||
|
rwyVacatedAcknowledged(false),
|
||||||
instructedToGoAround(false),
|
instructedToGoAround(false),
|
||||||
onRwy(false),
|
onRwy(false),
|
||||||
nextOnRwy(false),
|
nextOnRwy(false),
|
||||||
|
@ -388,6 +396,13 @@ void FGTower::ReceiveUserCallback(int code) {
|
||||||
VFRArrivalContact("USER", FULL_STOP);
|
VFRArrivalContact("USER", FULL_STOP);
|
||||||
} else if(code == (int)USER_REQUEST_VFR_ARRIVAL_TOUCH_AND_GO) {
|
} else if(code == (int)USER_REQUEST_VFR_ARRIVAL_TOUCH_AND_GO) {
|
||||||
VFRArrivalContact("USER", TOUCH_AND_GO);
|
VFRArrivalContact("USER", TOUCH_AND_GO);
|
||||||
|
} else if(code == (int)USER_REPORT_DOWNWIND) {
|
||||||
|
ReportDownwind("USER");
|
||||||
|
} else if(code == (int)USER_REPORT_3_MILE_FINAL) {
|
||||||
|
// For now we'll just call report final instead of report long final to avoid having to alter the response code
|
||||||
|
ReportFinal("USER");
|
||||||
|
} else if(code == (int)USER_REPORT_RWY_VACATED) {
|
||||||
|
ReportRunwayVacated("USER");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,7 +416,23 @@ void FGTower::Respond() {
|
||||||
string trns = t->plane.callsign;
|
string trns = t->plane.callsign;
|
||||||
trns += " ";
|
trns += " ";
|
||||||
trns += name;
|
trns += name;
|
||||||
trns += " tower Report three mile straight in for runway ";
|
trns += " Tower";
|
||||||
|
// Should we clear staight in or for downwind entry?
|
||||||
|
// For now we'll clear straight in if greater than 1km from a line drawn through the threshold perpendicular to the rwy.
|
||||||
|
// Later on we might check the actual heading and direct some of those to enter on downwind or base.
|
||||||
|
Point3D op = ortho.ConvertToLocal(t->pos);
|
||||||
|
if(op.y() < -1000) {
|
||||||
|
trns += " Report three mile straight-in runway ";
|
||||||
|
current_atcdialog->add_entry(ident, "@AP Tower @CS @MI mile final Runway @RW", "Report Final", TOWER, (int)USER_REPORT_3_MILE_FINAL);
|
||||||
|
} else {
|
||||||
|
// For now we'll just request reporting downwind.
|
||||||
|
// TODO - In real life something like 'report 2 miles southwest right downwind rwy 19R' might be used
|
||||||
|
// but I'm not sure how to handle all permutations of which direction to tell to report from yet.
|
||||||
|
trns += " Report ";
|
||||||
|
trns += (rwy.patternDirection ? "right " : "left ");
|
||||||
|
trns += "downwind runway ";
|
||||||
|
current_atcdialog->add_entry(ident, "@AP Tower @CS Downwind @RW", "Report Downwind", TOWER, (int)USER_REPORT_DOWNWIND);
|
||||||
|
}
|
||||||
trns += ConvertRwyNumToSpokenString(activeRwy);
|
trns += ConvertRwyNumToSpokenString(activeRwy);
|
||||||
if(display) {
|
if(display) {
|
||||||
globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
|
globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
|
||||||
|
@ -415,16 +446,21 @@ void FGTower::Respond() {
|
||||||
for(tower_plane_rec_list_iterator twrItr = circuitList.begin(); twrItr != circuitList.end(); twrItr++) {
|
for(tower_plane_rec_list_iterator twrItr = circuitList.begin(); twrItr != circuitList.end(); twrItr++) {
|
||||||
if((*twrItr)->plane.callsign == responseID) break;
|
if((*twrItr)->plane.callsign == responseID) break;
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
string trns = "Number ";
|
string trns = t->plane.callsign;
|
||||||
|
trns += " Number ";
|
||||||
trns += ConvertNumToSpokenDigits(i);
|
trns += ConvertNumToSpokenDigits(i);
|
||||||
trns += " ";
|
trns += " ";
|
||||||
trns += t->plane.callsign;
|
if(i == 1) {
|
||||||
if(display) {
|
trns += "Cleared to land";
|
||||||
globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
|
t->clearedToLand = true;
|
||||||
}
|
}
|
||||||
if(t->isUser && t->opType == TTT_UNKNOWN) {
|
if(display) {
|
||||||
t->opType = CIRCUIT;
|
globals->get_ATC_display()->RegisterSingleMessage(trns);
|
||||||
|
}
|
||||||
|
if(t->isUser) {
|
||||||
|
if(t->opType == TTT_UNKNOWN) t->opType = CIRCUIT;
|
||||||
|
current_atcdialog->add_entry(ident, "@CS Clear of the runway", "Report runway vacated", TOWER, USER_REPORT_RWY_VACATED);
|
||||||
}
|
}
|
||||||
} else if(t->holdShortReported) {
|
} else if(t->holdShortReported) {
|
||||||
if(t->nextOnRwy) {
|
if(t->nextOnRwy) {
|
||||||
|
@ -469,6 +505,7 @@ void FGTower::Respond() {
|
||||||
}
|
}
|
||||||
// TODO - add winds
|
// TODO - add winds
|
||||||
t->clearedToLand = true;
|
t->clearedToLand = true;
|
||||||
|
if(t->isUser) current_atcdialog->add_entry(ident, "@CS Clear of the runway", "Report runway vacated", TOWER, USER_REPORT_RWY_VACATED);
|
||||||
} else if(t->eta < 20) {
|
} else if(t->eta < 20) {
|
||||||
// Do nothing - we'll be telling it to go around in less than 10 seconds if the
|
// Do nothing - we'll be telling it to go around in less than 10 seconds if the
|
||||||
// runway doesn't clear so no point in calling "continue approach".
|
// runway doesn't clear so no point in calling "continue approach".
|
||||||
|
@ -478,9 +515,27 @@ void FGTower::Respond() {
|
||||||
t->clearedToLand = false;
|
t->clearedToLand = false;
|
||||||
}
|
}
|
||||||
if(display && disp) {
|
if(display && disp) {
|
||||||
globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
|
globals->get_ATC_display()->RegisterSingleMessage(trns);
|
||||||
}
|
}
|
||||||
t->finalAcknowledged = true;
|
t->finalAcknowledged = true;
|
||||||
|
} else if(t->rwyVacatedReported && !(t->rwyVacatedAcknowledged)) {
|
||||||
|
string trns = t->plane.callsign;
|
||||||
|
if(separateGround) {
|
||||||
|
trns += " Contact ground on ";
|
||||||
|
double f = globals->get_ATC_mgr()->GetFrequency(ident, GROUND) / 100.0;
|
||||||
|
char buf[10];
|
||||||
|
sprintf(buf, "%.2f", f);
|
||||||
|
trns += buf;
|
||||||
|
trns += " Good Day";
|
||||||
|
} else {
|
||||||
|
// Cop-out!!
|
||||||
|
trns += " cleared for taxi to the GA parking";
|
||||||
|
}
|
||||||
|
if(display) {
|
||||||
|
globals->get_ATC_display()->RegisterSingleMessage(trns);
|
||||||
|
}
|
||||||
|
t->rwyVacatedAcknowledged = true;
|
||||||
|
// Maybe we should check that the plane really *has* vacated the runway!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
freqClear = true; // FIXME - set this to come true after enough time to render the message
|
freqClear = true; // FIXME - set this to come true after enough time to render the message
|
||||||
|
@ -978,6 +1033,14 @@ void FGTower::DoRwyDetails() {
|
||||||
ortho.Init(rwy.threshold_pos, rwy.hdg);
|
ortho.Init(rwy.threshold_pos, rwy.hdg);
|
||||||
rwy.end1ortho = ortho.ConvertToLocal(rwy.threshold_pos); // should come out as zero
|
rwy.end1ortho = ortho.ConvertToLocal(rwy.threshold_pos); // should come out as zero
|
||||||
rwy.end2ortho = ortho.ConvertToLocal(takeoff_end);
|
rwy.end2ortho = ortho.ConvertToLocal(takeoff_end);
|
||||||
|
|
||||||
|
// Set the pattern direction
|
||||||
|
// TODO - we'll check for a facilities file with this in eventually - for now assume left traffic except
|
||||||
|
// for certain circumstances (RH parallel rwy).
|
||||||
|
rwy.patternDirection = -1; // Left
|
||||||
|
if(rwy.rwyID.size() == 3) {
|
||||||
|
rwy.patternDirection = (rwy.rwyID.substr(2,1) == "R" ? 1 : -1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
SG_LOG(SG_ATC, SG_ALERT, "Help - can't get good runway in FGTower!!");
|
SG_LOG(SG_ATC, SG_ALERT, "Help - can't get good runway in FGTower!!");
|
||||||
activeRwy = "NN";
|
activeRwy = "NN";
|
||||||
|
@ -1429,14 +1492,14 @@ void FGTower::VFRArrivalContact(string ID, LandingType opt) {
|
||||||
if(ID == "USER" || ID == usercall) {
|
if(ID == "USER" || ID == usercall) {
|
||||||
t = FindPlane(usercall);
|
t = FindPlane(usercall);
|
||||||
if(!t) {
|
if(!t) {
|
||||||
cout << "NOT t\n";
|
//cout << "NOT t\n";
|
||||||
t = new TowerPlaneRec;
|
t = new TowerPlaneRec;
|
||||||
t->isUser = true;
|
t->isUser = true;
|
||||||
t->pos.setlon(user_lon_node->getDoubleValue());
|
t->pos.setlon(user_lon_node->getDoubleValue());
|
||||||
t->pos.setlat(user_lat_node->getDoubleValue());
|
t->pos.setlat(user_lat_node->getDoubleValue());
|
||||||
t->pos.setelev(user_elev_node->getDoubleValue());
|
t->pos.setelev(user_elev_node->getDoubleValue());
|
||||||
} else {
|
} else {
|
||||||
cout << "IS t\n";
|
//cout << "IS t\n";
|
||||||
// Oops - the plane is already registered with this tower - maybe we took off and flew a giant circuit without
|
// Oops - the plane is already registered with this tower - maybe we took off and flew a giant circuit without
|
||||||
// quite getting out of tower airspace - just ignore for now and treat as new arrival.
|
// quite getting out of tower airspace - just ignore for now and treat as new arrival.
|
||||||
// TODO - Maybe should remove from departure and circuit list if in there though!!
|
// TODO - Maybe should remove from departure and circuit list if in there though!!
|
||||||
|
@ -1463,6 +1526,10 @@ void FGTower::VFRArrivalContact(string ID, LandingType opt) {
|
||||||
|
|
||||||
appList.push_back(t); // Not necessarily permanent
|
appList.push_back(t); // Not necessarily permanent
|
||||||
AddToTrafficList(t);
|
AddToTrafficList(t);
|
||||||
|
|
||||||
|
current_atcdialog->remove_entry(ident, USER_REQUEST_VFR_ARRIVAL, TOWER);
|
||||||
|
current_atcdialog->remove_entry(ident, USER_REQUEST_VFR_ARRIVAL_FULL_STOP, TOWER);
|
||||||
|
current_atcdialog->remove_entry(ident, USER_REQUEST_VFR_ARRIVAL_TOUCH_AND_GO, TOWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGTower::RequestDepartureClearance(string ID) {
|
void FGTower::RequestDepartureClearance(string ID) {
|
||||||
|
@ -1470,6 +1537,10 @@ void FGTower::RequestDepartureClearance(string ID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGTower::ReportFinal(string ID) {
|
void FGTower::ReportFinal(string ID) {
|
||||||
|
if(ID == "USER") {
|
||||||
|
ID = fgGetString("/sim/user/callsign");
|
||||||
|
current_atcdialog->remove_entry(ident, USER_REPORT_3_MILE_FINAL, TOWER);
|
||||||
|
}
|
||||||
TowerPlaneRec* t = FindPlane(ID);
|
TowerPlaneRec* t = FindPlane(ID);
|
||||||
if(t) {
|
if(t) {
|
||||||
t->finalReported = true;
|
t->finalReported = true;
|
||||||
|
@ -1482,7 +1553,23 @@ void FGTower::ReportFinal(string ID) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//void FGTower::ReportLongFinal(string ID);
|
void FGTower::ReportLongFinal(string ID) {
|
||||||
|
if(ID == "USER") {
|
||||||
|
ID = fgGetString("/sim/user/callsign");
|
||||||
|
current_atcdialog->remove_entry(ident, USER_REPORT_3_MILE_FINAL, TOWER);
|
||||||
|
}
|
||||||
|
TowerPlaneRec* t = FindPlane(ID);
|
||||||
|
if(t) {
|
||||||
|
t->longFinalReported = true;
|
||||||
|
t->longFinalAcknowledged = false;
|
||||||
|
if(!(t->clearedToLand)) {
|
||||||
|
responseReqd = true;
|
||||||
|
} // possibly respond with wind even if already cleared to land?
|
||||||
|
} else {
|
||||||
|
SG_LOG(SG_ATC, SG_WARN, "WARNING: Unable to find plane " << ID << " in FGTower::ReportLongFinal(...)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//void FGTower::ReportOuterMarker(string ID);
|
//void FGTower::ReportOuterMarker(string ID);
|
||||||
//void FGTower::ReportMiddleMarker(string ID);
|
//void FGTower::ReportMiddleMarker(string ID);
|
||||||
//void FGTower::ReportInnerMarker(string ID);
|
//void FGTower::ReportInnerMarker(string ID);
|
||||||
|
@ -1490,6 +1577,17 @@ void FGTower::ReportFinal(string ID) {
|
||||||
|
|
||||||
void FGTower::ReportRunwayVacated(string ID) {
|
void FGTower::ReportRunwayVacated(string ID) {
|
||||||
//cout << "Report Runway Vacated Called...\n";
|
//cout << "Report Runway Vacated Called...\n";
|
||||||
|
if(ID == "USER") {
|
||||||
|
ID = fgGetString("/sim/user/callsign");
|
||||||
|
current_atcdialog->remove_entry(ident, USER_REPORT_RWY_VACATED, TOWER);
|
||||||
|
}
|
||||||
|
TowerPlaneRec* t = FindPlane(ID);
|
||||||
|
if(t) {
|
||||||
|
t->rwyVacatedReported = true;
|
||||||
|
responseReqd = true;
|
||||||
|
} else {
|
||||||
|
SG_LOG(SG_ATC, SG_WARN, "WARNING: Unable to find plane " << ID << " in FGTower::ReportRunwayVacated(...)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TowerPlaneRec* FGTower::FindPlane(string ID) {
|
TowerPlaneRec* FGTower::FindPlane(string ID) {
|
||||||
|
@ -1512,7 +1610,10 @@ TowerPlaneRec* FGTower::FindPlane(string ID) {
|
||||||
|
|
||||||
void FGTower::ReportDownwind(string ID) {
|
void FGTower::ReportDownwind(string ID) {
|
||||||
//cout << "ReportDownwind(...) called\n";
|
//cout << "ReportDownwind(...) called\n";
|
||||||
// Tell the plane reporting what number she is in the circuit
|
if(ID == "USER") {
|
||||||
|
ID = fgGetString("/sim/user/callsign");
|
||||||
|
current_atcdialog->remove_entry(ident, USER_REPORT_DOWNWIND, TOWER);
|
||||||
|
}
|
||||||
TowerPlaneRec* t = FindPlane(ID);
|
TowerPlaneRec* t = FindPlane(ID);
|
||||||
if(t) {
|
if(t) {
|
||||||
t->downwindReported = true;
|
t->downwindReported = true;
|
||||||
|
|
|
@ -57,7 +57,10 @@ enum tower_callback_type {
|
||||||
USER_REQUEST_VFR_DEPARTURE = 1,
|
USER_REQUEST_VFR_DEPARTURE = 1,
|
||||||
USER_REQUEST_VFR_ARRIVAL = 2,
|
USER_REQUEST_VFR_ARRIVAL = 2,
|
||||||
USER_REQUEST_VFR_ARRIVAL_FULL_STOP = 3,
|
USER_REQUEST_VFR_ARRIVAL_FULL_STOP = 3,
|
||||||
USER_REQUEST_VFR_ARRIVAL_TOUCH_AND_GO = 4
|
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.
|
// TODO - need some differentiation of IFR and VFR traffic in order to give the former priority.
|
||||||
|
@ -89,6 +92,8 @@ public:
|
||||||
bool longFinalAcknowledged;
|
bool longFinalAcknowledged;
|
||||||
bool finalReported;
|
bool finalReported;
|
||||||
bool finalAcknowledged;
|
bool finalAcknowledged;
|
||||||
|
bool rwyVacatedReported;
|
||||||
|
bool rwyVacatedAcknowledged;
|
||||||
bool instructedToGoAround; // set true if told by tower to go around
|
bool instructedToGoAround; // set true if told by tower to go around
|
||||||
bool onRwy; // is physically on the runway
|
bool onRwy; // is physically on the runway
|
||||||
bool nextOnRwy; // currently projected by tower to be the next on the runway
|
bool nextOnRwy; // currently projected by tower to be the next on the runway
|
||||||
|
@ -153,6 +158,8 @@ public:
|
||||||
// in the future and consider multi-runway use, airplane weight etc.
|
// in the future and consider multi-runway use, airplane weight etc.
|
||||||
inline string GetActiveRunway() { return activeRwy; }
|
inline string GetActiveRunway() { return activeRwy; }
|
||||||
inline RunwayDetails GetActiveRunwayDetails() { return rwy; }
|
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 SetDisplay() { display = true; }
|
||||||
inline void SetNoDisplay() { display = false; }
|
inline void SetNoDisplay() { display = false; }
|
||||||
|
|
Loading…
Add table
Reference in a new issue