]> git.mxchange.org Git - flightgear.git/commitdiff
Vivian MEAZZA:
authormfranz <mfranz>
Thu, 18 May 2006 16:59:04 +0000 (16:59 +0000)
committermfranz <mfranz>
Thu, 18 May 2006 16:59:04 +0000 (16:59 +0000)
"Add Air to Air TACAN and User-User refuelling over the Multiplayer Network.
With this change, your TACAN instrument can be tuned to the channel of a
Multiplayer ac. It also activates fuel flow between User and User aircraft
when they are less than 50 ft apart. To participate in multiplayer as a
tanker, all you require to do is to use the callsign MOBIL* (where * is some
number) on the net. Only MOBIL1, MOBIL2 and MOBIL3 have been assigned TACAN
channels, but any MOBIL callsign will be able to give fuel."

src/AIModel/AIMultiplayer.cxx
src/AIModel/AIMultiplayer.hxx
src/Instrumentation/tacan.cxx
src/Instrumentation/tacan.hxx

index 4a38e29c54a16e6aff6f9ef7e172afa1155bf5d4..9502561bf46047c7e637f1f3a597bd3d16449bcd 100755 (executable)
@@ -44,12 +44,28 @@ FGAIMultiplayer::~FGAIMultiplayer() {
 }
 
 bool FGAIMultiplayer::init() {
+    refuel_node = fgGetNode("systems/refuel/contact", true);
+    isTanker = false; // do this until this property is
+                      // passed over the net
+
+    string str1 = mCallSign;
+    string str2 = "MOBIL";
+
+    unsigned int loc1= str1.find( str2, 0 );
+    if ( (loc1 != string::npos && str2 != "") /*|| mCallSign == "mpdummy" */) {
+        //        cout << " string found "     << str2 << " in " << str1 << endl;
+        isTanker = true;
+        //        cout << "isTanker " << isTanker << " " << mCallSign <<endl;
+    }
    return FGAIBase::init();
 }
 
 void FGAIMultiplayer::bind() {
     FGAIBase::bind();
 
+    props->tie("refuel/contact", SGRawValuePointer<bool>(&contact));
+    props->setBoolValue("tanker",isTanker);
+
 #define AIMPROProp(type, name) \
 SGRawValueMethods<FGAIMultiplayer, type>(*this, &FGAIMultiplayer::get##name)
 
@@ -64,6 +80,7 @@ SGRawValueMethods<FGAIMultiplayer, type>(*this, \
     props->tie("controls/lag-adjust-system-speed",
                AIMPRWProp(double, LagAdjustSystemSpeed));
 
+
 #undef AIMPROProp
 #undef AIMPRWProp
 }
@@ -74,6 +91,7 @@ void FGAIMultiplayer::unbind() {
     props->untie("callsign");
     props->untie("controls/allow-extrapolation");
     props->untie("controls/lag-adjust-system-speed");
+    props->untie("refuel/contact");
 }
 
 void FGAIMultiplayer::update(double dt)
@@ -296,7 +314,25 @@ void FGAIMultiplayer::update(double dt)
   //###########################//
   // do calculations for radar //
   //###########################//
-  UpdateRadar(manager);
+    double range_ft2 = UpdateRadar(manager);
+
+    //************************************//
+    // Tanker code                        //
+    //************************************//
+
+
+    if ( isTanker) {
+        if ( (range_ft2 < 250.0 * 250.0)
+                /*&& (y_shift > 0.0) && (elevation > 0.0)*/ ) {
+            refuel_node->setBoolValue(true);
+            contact = true;
+        } else {
+            refuel_node->setBoolValue(false);
+            contact = false;
+        }
+    } else {
+        contact = false;
+    }
 
   Transform();
 }
index 406b00c6ee2ced5c4d7fe0c30852d5f0a5fcfb42..3e10f87230a0d640fe1240019f2a80fe5c476e65 100755 (executable)
@@ -31,20 +31,20 @@ class FGAIMultiplayer : public FGAIBase {
 public:
   FGAIMultiplayer();
   virtual ~FGAIMultiplayer();
-  
+
   virtual bool init();
   virtual void bind();
   virtual void unbind();
   virtual void update(double dt);
-  
+
   void addMotionInfo(const FGExternalMotionData& motionInfo, long stamp);
   void setDoubleProperty(const std::string& prop, double val);
-  
+
   void setCallSign(const string& callSign)
   { mCallSign = callSign; }
   const char* getCallSign(void) const
   { return mCallSign.c_str(); }
-  
+
   long getLastTimestamp(void) const
   { return mLastTimestamp; }
 
@@ -71,22 +71,27 @@ private:
   // Automatic sorting of motion data according to its timestamp
   typedef std::map<double,FGExternalMotionData> MotionInfo;
   MotionInfo mMotionInfo;
-  
+
   // Map between the property id's from the multiplayers network packets
   // and the property nodes
   typedef std::map<unsigned, SGSharedPtr<SGPropertyNode> > PropertyMap;
   PropertyMap mPropertyMap;
 
   std::string mCallSign;
-  
+
   double mTimeOffset;
   bool mTimeOffsetSet;
-  
+
   /// Properties which are for now exposed for testing
   bool mAllowExtrapolation;
   double mLagAdjustSystemSpeed;
 
   long mLastTimestamp;
+
+  // Propertiies for tankers
+  SGPropertyNode* refuel_node;
+  bool isTanker;
+  bool contact;          // set if this tanker is within fuelling range
 };
 
 #endif  // _FG_AIMultiplayer_HXX
index 81627abff212693f157632ca9066b4af800ad64b..39097b6f0317dba83f1881d44eaeb92c40c83610 100755 (executable)
@@ -137,6 +137,10 @@ TACAN::init ()
     SGPropertyNode *tnode = fgGetNode("/ai/models/aircraft", num, false);
     if (tnode)
         _tanker_callsign_node = tnode->getChild("callsign", 0, false);
+
+    SGPropertyNode *mnode = fgGetNode("/ai/models/multiplayer", num, false);
+    if (mnode)
+        _mp_callsign_node = mnode->getChild("callsign", 0, false);
 }
 
 void
@@ -253,7 +257,7 @@ TACAN::update (double delta_time_sec)
                        &bearing, &az2, &distance);
 
     //select the nearest valid mobile transmitter
-    if ( _carrier_valid && _tanker_valid ){
+    if ( _carrier_valid && (_tanker_valid || _mp_tanker_valid ) ) {
         if( carrier_distance <= tanker_distance ){
             SG_LOG( SG_INSTR, SG_DEBUG, " select carrier (dist) " );
             mobile_bearing = carrier_bearing;
@@ -273,7 +277,7 @@ TACAN::update (double delta_time_sec)
         }
         mobile_valid = true;
     }
-    else if ( _carrier_valid && !_tanker_valid ){
+    else if ( _carrier_valid && (!_tanker_valid || _mp_tanker_valid) ) {
         SG_LOG( SG_INSTR, SG_DEBUG, " select carrier  " );
         mobile_bearing = carrier_bearing;
         mobile_distance = carrier_distance;
@@ -283,7 +287,7 @@ TACAN::update (double delta_time_sec)
         mobile_name = _carrier_name;
         mobile_valid = true;
     }
-    else if ( !_carrier_valid && _tanker_valid ){
+    else if ( !_carrier_valid && (_tanker_valid || _mp_tanker_valid ) ) {
         SG_LOG( SG_INSTR, SG_DEBUG, " select tanker  " );
         mobile_bearing = tanker_bearing;
         mobile_distance = tanker_distance;
@@ -504,6 +508,58 @@ TACAN::search (double frequency_mhz, double longitude_rad,
         SG_LOG( SG_INSTR, SG_DEBUG, " tanker transmitter invalid " << _tanker_valid  );
     }
 
+    //try any mp tankers third, if we haven't found the tanker in the ai aircraft
+    FGNavRecord *mp_tanker_tacan
+            = globals->get_carrierlist()->findStationByFreq( frequency_mhz );
+
+    _mp_tanker_valid = (mp_tanker_tacan != NULL);
+
+
+    if ( _mp_tanker_valid && ! _tanker_valid ) {
+        SG_LOG( SG_INSTR, SG_DEBUG, " mp tanker transmitter valid start " << _mp_tanker_valid  );
+
+        string str5( mp_tanker_tacan->get_name() );
+
+        SGPropertyNode * branch = fgGetNode("ai/models", true);
+        vector<SGPropertyNode_ptr> mp_tanker = branch->getChildren("multiplayer");
+
+        number = mp_tanker.size();
+
+        SG_LOG( SG_INSTR, SG_DEBUG, " mp tanker number " << number );
+
+        for ( i = 0; i < number; ++i ) {
+            string str6 ( mp_tanker[i]->getStringValue("callsign", ""));
+            SG_LOG( SG_INSTR, SG_DEBUG, "mp tanker callsign " << str6 );
+
+            SG_LOG( SG_INSTR, SG_DEBUG, "strings 5 " << str5 << " 5 " << str6 );
+            unsigned int loc1= str5.find( str6, 0 );
+            if ( loc1 != string::npos && str6 != "" ) {
+                SG_LOG( SG_INSTR, SG_DEBUG, " string found" );
+                _tanker_lat = mp_tanker[i]->getDoubleValue("position/latitude-deg");
+                _tanker_lon = mp_tanker[i]->getDoubleValue("position/longitude-deg");
+                _tanker_elevation_ft = mp_tanker[i]->getDoubleValue("position/altitude-ft");
+                _tanker_range_nm = mp_tanker_tacan->get_range();
+                _tanker_bias = mp_tanker_tacan->get_multiuse();
+                _tanker_name = mp_tanker_tacan->get_name();
+                _mp_tanker_valid = 1;
+
+                SG_LOG( SG_INSTR, SG_DEBUG, "  mp tanker transmitter valid " << _mp_tanker_valid );
+                SG_LOG( SG_INSTR, SG_DEBUG, "mp_tanker name " << _tanker_name);
+                SG_LOG( SG_INSTR, SG_DEBUG, "lat " << _tanker_lat << "lon " << _tanker_lon);
+                SG_LOG( SG_INSTR, SG_DEBUG, "elev " << _tanker_elevation_ft);
+                SG_LOG( SG_INSTR, SG_DEBUG, "range " << _tanker_range_nm);
+                break;
+            } else {
+                _mp_tanker_valid = 0;
+                SG_LOG( SG_INSTR, SG_DEBUG, " tanker transmitter invalid " << _mp_tanker_valid );
+            }
+        }
+
+
+
+    } else {
+        SG_LOG( SG_INSTR, SG_DEBUG, " tanker transmitter invalid " << _tanker_valid  );
+    }
     // try the TACAN/VORTAC list next
     FGNavRecord *tacan
         = globals->get_tacanlist()->findByFreq( frequency_mhz, longitude_rad,
index 8c119abb3d374e616bed25e1837beab88ad4adcb..7700376f41081c44799afdab5aff0295ad340bd9 100755 (executable)
@@ -81,6 +81,7 @@ private:
     SGPropertyNode_ptr _channel_node;
 
     SGPropertyNode_ptr _tanker_callsign_node;
+    SGPropertyNode_ptr _mp_callsign_node;
 
     double _last_distance_nm;
     double _last_frequency_mhz;
@@ -88,6 +89,7 @@ private:
 
     bool _carrier_valid;
     bool _tanker_valid;
+    bool _mp_tanker_valid;
     bool _transmitter_valid;
 
     Point3D _transmitter;