+// Hack - Generate AI traffic at an airport with no facilities file
+void FGAIMgr::GenerateSimpleAirportTraffic(string ident, double min_dist) {
+ // Ugly hack - don't let VFR Cessnas operate at a hardwired list of major airports
+ // This will go eventually once airport .xml files specify the traffic profile
+ if(ident == "KSFO" || ident == "KDFW" || ident == "EGLL" || ident == "KORD" || ident == "KJFK"
+ || ident == "KMSP" || ident == "KLAX" || ident == "KBOS" || ident == "KEDW"
+ || ident == "KSEA" || ident == "EHAM") {
+ return;
+ }
+
+ /*
+ // TODO - check for military airports - this should be in the current data.
+ // UGGH - there's no point at the moment - everything is labelled civil in basic.dat!
+ FGAirport a;
+ if(dclFindAirportID(ident, &a)) {
+ cout << "CODE IS " << a.code << '\n';
+ } else {
+ // UG - can't find the airport!
+ return;
+ }
+ */
+
+ Point3D aptpos = dclGetAirportPos(ident); // TODO - check for elev of -9999
+ //cout << "ident = " << ident << ", elev = " << aptpos.elev() << '\n';
+
+ // Operate from airports at 3000ft and below only to avoid the default cloud layers and since we don't degrade AI performance with altitude.
+ if(aptpos.elev() > 3000) {
+ //cout << "High alt airports not yet supported - returning\n";
+ return;
+ }
+
+ // Rough hack for plane type - make 70% of the planes cessnas, the rest pipers.
+ bool cessna = true;
+
+ // Get the time and only operate VFR in the (approximate) daytime.
+ struct tm *t = globals->get_time_params()->getGmt();
+ int loc_time = t->tm_hour + int(aptpos.lon() / (360.0 / 24.0));
+ while (loc_time < 0)
+ loc_time += 24;
+ while (loc_time >= 24)
+ loc_time -= 24;
+
+ //cout << "loc_time = " << loc_time << '\n';
+ if(loc_time < 7 || loc_time > 19) return;
+
+ // Check that the visibility is OK for IFR operation.
+ double visibility;
+ FGEnvironment stationweather =
+ ((FGEnvironmentMgr *)globals->get_subsystem("environment"))
+ ->getEnvironment(aptpos.lat(), aptpos.lon(), aptpos.elev()); // TODO - check whether this should take ft or m for elev.
+ visibility = stationweather.get_visibility_m();
+ // Technically we can do VFR down to 1 mile (1600m) but that's pretty murky!
+ //cout << "vis = " << visibility << '\n';
+ if(visibility < 3000) return;
+
+ ATC->AIRegisterAirport(ident);
+
+ // Next - get the distance from user to the airport.
+ Point3D userpos = Point3D(lon_node->getDoubleValue(), lat_node->getDoubleValue(), elev_node->getDoubleValue());
+ double d = dclGetHorizontalSeparation(userpos, aptpos); // in meters
+
+ int lev = fgGetInt("/sim/ai-traffic/level");
+ if(lev < 1 || lev > 3) lev = 2;
+ if(visibility < 6000) lev = 1;
+ //cout << "level = " << lev << '\n';
+
+ // Next - generate any local / circuit traffic
+
+ /*
+ // --------------------------- THIS BLOCK IS JUST FOR TESTING - COMMENT OUT BEFORE RELEASE ---------------
+ // Finally - generate VFR approaching traffic
+ //if(d > 2000) {
+ if(ident == "KPOC") {
+ double ad = 2000.0;
+ double avd = 3000.0; // average spacing of arriving traffic in meters - relate to airport business and AI density setting one day!
+ //while(ad < (d < 10000 ? 12000 : d + 2000)) {
+ for(int i=0; i<8; ++i) {
+ double dd = sg_random() * avd;
+ // put a minimum spacing in for now since I don't think tower will cope otherwise!
+ if(dd < 1500) dd = 1500;
+ //ad += dd;
+ ad += dd;
+ double dir = int(sg_random() * 36);
+ if(dir == 36) dir--;
+ dir *= 10;
+ //dir = 180;
+ if(sg_random() < 0.3) cessna = false;
+ else cessna = true;
+ string s = GenerateShortForm(GenerateUniqueCallsign(), (cessna ? "Cessna-" : "Piper-"));
+ FGAIGAVFRTraffic* t = new FGAIGAVFRTraffic();
+ t->SetModel(cessna ? _defaultModel : _piperModel);
+ //cout << "Generating VFR traffic " << s << " inbound to " << ident << " " << ad << " meters out from " << dir << " degrees\n";
+ Point3D tpos = dclUpdatePosition(aptpos, dir, 6.0, ad);
+ if(tpos.elev() > (aptpos.elev() + 3000.0)) tpos.setelev(aptpos.elev() + 3000.0);
+ t->Init(tpos, ident, s);
+ ai_list.push_back(t);
+ }
+ }
+ activated[ident] = 1;
+ return;
+ //---------------------------------------------------------------------------------------------------
+ */
+
+ double ad; // Minimum distance out of first arriving plane in meters.
+ double mind; // Minimum spacing of traffic in meters
+ double avd; // average spacing of arriving traffic in meters - relate to airport business and AI density setting one day!
+ // Finally - generate VFR approaching traffic
+ //if(d > 2000) {
+ if(1) {
+ if(lev == 3) {
+ ad = 5000.0;
+ mind = 2000.0;
+ avd = 6000.0;
+ } else if(lev == 2) {
+ ad = 8000.0;
+ mind = 4000.0;
+ avd = 10000.0;
+ } else {
+ ad = 9000.0; // Start the first aircraft at least 9K out for now.
+ mind = 6000.0;
+ avd = 15000.0;
+ }
+ /*
+ // Check if there is already arriving traffic at this airport
+ cout << "BING A " << ident << '\n';
+ if(traffic.find(ident) != traffic.end()) {
+ cout << "BING B " << ident << '\n';
+ ai_list_type lst = traffic[ident];
+ cout << "BING C " << ident << '\n';
+ if(lst.size()) {
+ cout << "BING D " << ident << '\n';
+ double cd = dclGetHorizontalSeparation(aptpos, (*lst.rbegin())->GetPos());
+ cout << "ident = " << ident << ", cd = " << cd << '\n';
+ if(cd > ad) ad = cd;
+ }
+ }
+ */
+ if(min_dist != 0) ad = min_dist;
+ //cout << "ident = " << ident << ", ad = " << ad << '\n';
+ while(ad < (d < 5000 ? 15000 : d + 10000)) {
+ double dd = mind + (sg_random() * (avd - mind));
+ ad += dd;
+ double dir = int(sg_random() * 36);
+ if(dir == 36) dir--;
+ dir *= 10;
+
+ if(sg_random() < 0.3) cessna = false;
+ else cessna = true;
+ string s = GenerateShortForm(GenerateUniqueCallsign(), (cessna ? "Cessna-" : "Piper-"));
+ FGAIGAVFRTraffic* t = new FGAIGAVFRTraffic();
+ t->SetModel(cessna ? _defaultModel : (_havePiperModel ? _piperModel : _defaultModel));
+ //cout << "Generating VFR traffic " << s << " inbound to " << ident << " " << ad << " meters out from " << dir << " degrees\n";
+ Point3D tpos = dclUpdatePosition(aptpos, dir, 6.0, ad);
+ if(tpos.elev() > (aptpos.elev() + 3000.0)) tpos.setelev(aptpos.elev() + 3000.0); // FEET yuk :-(
+ t->Init(tpos, ident, s);
+ ai_list.push_back(t);
+ traffic[ident].push_back(t);
+ }
+ }
+}
+
+/*
+// Generate a VFR arrival at airport apt, at least distance d (meters) out.
+void FGAIMgr::GenerateVFRArrival(string apt, double d) {
+}
+*/