]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/fg_init.cxx
Automatic tower positioning
[flightgear.git] / src / Main / fg_init.cxx
index e9592c14e68467f425e015de9322048005a06bad..50329b39f48506467809f5d548a0face5ee1e64e 100644 (file)
 
 #include <AIModel/AIManager.hxx>
 
-#if ENABLE_ATCDCL
-#   include <ATCDCL/ATCmgr.hxx>
-#   include "ATCDCL/commlist.hxx"
-#else
-#   include "ATC/atis.hxx"
-#   include "ATC/atcutils.hxx"
-#endif
+#include <ATCDCL/ATCmgr.hxx>
+#include <ATCDCL/commlist.hxx>
+#include <ATC/atis_mgr.hxx>
 
 #include <Autopilot/route_mgr.hxx>
 #include <Autopilot/autopilotgroup.hxx>
@@ -589,7 +585,7 @@ public:
   
   bool loadAircraft()
   {
-    std::string aircraft = fgGetString( "/sim/aircraft", "");    
+    std::string aircraft = fgGetString( "/sim/aircraft", "");
     if (aircraft.empty()) {
       SG_LOG(SG_GENERAL, SG_ALERT, "no aircraft specified");
       return false;
@@ -601,6 +597,9 @@ public:
       SGPropertyNode *n = _cache->getNode("fg-root", true);
       n->setStringValue(globals->get_fg_root().c_str());
       n->setAttribute(SGPropertyNode::USERARCHIVE, true);
+      n = _cache->getNode("fg-aircraft", true);
+      n->setStringValue(getAircraftPaths().c_str());
+      n->setAttribute(SGPropertyNode::USERARCHIVE, true);
       _cache->removeChildren("aircraft");
   
       fgFindAircraft(this, &FindAndCacheAircraft::checkAircraft);
@@ -629,11 +628,29 @@ public:
   }
   
 private:
+  SGPath getAircraftPaths() {
+    string_list pathList = globals->get_aircraft_paths();
+    SGPath aircraftPaths;
+    string_list::const_iterator it = pathList.begin();
+    if (it != pathList.end()) {
+        aircraftPaths.set(*it);
+        it++;
+    }
+    for (; it != pathList.end(); ++it) {
+        aircraftPaths.add(*it);
+    }
+    return aircraftPaths;
+  }
+  
   bool checkCache()
   {
     if (globals->get_fg_root() != _cache->getStringValue("fg-root", "")) {
       return false; // cache mismatch
     }
+
+    if (getAircraftPaths().str() != _cache->getStringValue("fg-aircraft", "")) {
+      return false; // cache mismatch
+    }
     
     vector<SGPropertyNode_ptr> cache = _cache->getChildren("aircraft");
     for (unsigned int i = 0; i < cache.size(); i++) {
@@ -776,14 +793,44 @@ static bool fgSetTowerPosFromAirportID( const string& id) {
 
 struct FGTowerLocationListener : SGPropertyChangeListener {
     void valueChanged(SGPropertyNode* node) {
-        const string id(node->getStringValue());
+        string id(node->getStringValue());
+        if (fgGetBool("/sim/tower/auto-position",true))
+        {
+            // enforce using closest airport when auto-positioning is enabled 
+            const char* closest_airport = fgGetString("/sim/airport/closest-airport-id", "");
+            if (closest_airport && (id != closest_airport))
+            {
+                id = closest_airport;
+                node->setStringValue(id);
+            }
+        }
         fgSetTowerPosFromAirportID(id);
     }
 };
 
+struct FGClosestTowerLocationListener : SGPropertyChangeListener
+{
+    void valueChanged(SGPropertyNode* )
+    {
+        // closest airport has changed
+        if (fgGetBool("/sim/tower/auto-position",true))
+        {
+            // update tower position
+            const char* id = fgGetString("/sim/airport/closest-airport-id", "");
+            if (id && *id!=0)
+                fgSetString("/sim/tower/airport-id", id);
+        }
+    }
+};
+
 void fgInitTowerLocationListener() {
     fgGetNode("/sim/tower/airport-id",  true)
         ->addChangeListener( new FGTowerLocationListener(), true );
+    FGClosestTowerLocationListener* ntcl = new FGClosestTowerLocationListener();
+    fgGetNode("/sim/airport/closest-airport-id", true)
+        ->addChangeListener(ntcl , true );
+    fgGetNode("/sim/tower/auto-position", true)
+           ->addChangeListener(ntcl, true );
 }
 
 static void fgApplyStartOffset(const SGGeod& aStartPos, double aHeading, double aTargetHeading = HUGE_VAL)
@@ -1146,6 +1193,7 @@ bool fgInitPosition() {
         // An airport + parking position is requested
         if ( fgSetPosFromAirportIDandParkpos( apt, parkpos ) ) {
             // set tower position
+            fgSetString("/sim/airport/closest-airport-id",  apt.c_str());
             fgSetString("/sim/tower/airport-id",  apt.c_str());
             set_pos = true;
         }
@@ -1156,7 +1204,8 @@ bool fgInitPosition() {
         if ( fgSetPosFromAirportIDandRwy( apt, rwy_no, rwy_req ) ) {
             // set tower position (a little off the heading for single
             // runway airports)
-           fgSetString("/sim/tower/airport-id",  apt.c_str());
+            fgSetString("/sim/airport/closest-airport-id",  apt.c_str());
+            fgSetString("/sim/tower/airport-id",  apt.c_str());
             set_pos = true;
         }
     }
@@ -1166,7 +1215,8 @@ bool fgInitPosition() {
         if ( fgSetPosFromAirportIDandHdg( apt, hdg ) ) {
             // set tower position (a little off the heading for single
             // runway airports)
-           fgSetString("/sim/tower/airport-id",  apt.c_str());
+            fgSetString("/sim/airport/closest-airport-id",  apt.c_str());
+            fgSetString("/sim/tower/airport-id",  apt.c_str());
             set_pos = true;
         }
     }
@@ -1366,19 +1416,17 @@ bool fgInitSubsystems() {
 
 
     ////////////////////////////////////////////////////////////////////
-    // Initialise the ATC Manager 
+    // Initialise the ATC Manager
     ////////////////////////////////////////////////////////////////////
 
-#if ENABLE_ATCDCL
     SG_LOG(SG_GENERAL, SG_INFO, "  ATC Manager");
     globals->set_ATC_mgr(new FGATCMgr);
     globals->get_ATC_mgr()->init(); 
-#else
+
     ////////////////////////////////////////////////////////////////////
     // Initialise the ATIS Manager
     ////////////////////////////////////////////////////////////////////
     globals->add_subsystem("atis", new FGAtisManager, SGSubsystemMgr::POST_FDM);
-#endif
 
 
     ////////////////////////////////////////////////////////////////////
@@ -1502,7 +1550,7 @@ bool fgInitSubsystems() {
     return true;
 }
 
-
+// Reset: this is what the 'reset' command (and hence, GUI) is attached to
 void fgReInitSubsystems()
 {
     static const SGPropertyNode *master_freeze
@@ -1538,12 +1586,17 @@ void fgReInitSubsystems()
     // Initialize the FDM
     globals->get_subsystem("flight")->reinit();
 
+    // reset replay buffers
+    globals->get_subsystem("replay")->reinit();
+    
     // reload offsets from config defaults
     globals->get_viewmgr()->reinit();
 
     globals->get_subsystem("time")->reinit();
-    globals->get_subsystem("tile-manager")->reinit();
-    
+
+    // need to bind FDMshell again, since we manually unbound it above...
+    globals->get_subsystem("flight")->bind();
+
 // setup state to end re-init
     fgSetBool("/sim/signals/reinit", false);
     if ( !freeze ) {
@@ -1553,13 +1606,6 @@ void fgReInitSubsystems()
 }
 
 
-void doSimulatorReset(void)  // from gui_local.cxx -- TODO merge with fgReInitSubsystems()
-{
-    
-
-    fgReInitSubsystems();
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // helper object to implement the --show-aircraft command.
 // resides here so we can share the fgFindAircraftInDir template above,