+
+ if ((*ai_list_itr)->getDie()) {
+ tmgr->release((*ai_list_itr)->getID());
+ --mNumAiModels;
+ --(mNumAiTypeModels[(*ai_list_itr)->getType()]);
+ FGAIBase *base = (*ai_list_itr).get();
+ SGPropertyNode *props = base->_getProps();
+
+ props->setBoolValue("valid", false);
+ base->unbind();
+
+ // for backward compatibility reset properties, so that aircraft,
+ // which don't know the <valid> property, keep working
+ // TODO: remove after a while
+ props->setIntValue("id", -1);
+ props->setBoolValue("radar/in-range", false);
+ props->setIntValue("refuel/tanker", false);
+
+ ai_list_itr = ai_list.erase(ai_list_itr);
+ } else {
+ fetchUserState();
+ if ((*ai_list_itr)->isa(FGAIBase::otThermal)) {
+ FGAIBase *base = (*ai_list_itr).get();
+ processThermal((FGAIThermal*)base);
+ } else {
+ (*ai_list_itr)->update(_dt);
+ }
+ ++ai_list_itr;
+ }
+ }
+
+ wind_from_down_node->setDoubleValue( strength ); // for thermals
+}
+
+void
+FGAIManager::attach(FGAIBase *model)
+{
+ //unsigned idx = mNumAiTypeModels[model->getType()];
+ const char* typeString = model->getTypeString();
+ SGPropertyNode* root = globals->get_props()->getNode("ai/models", true);
+ SGPropertyNode* p;
+ int i;
+
+ // find free index in the property tree, if we have
+ // more than 10000 mp-aircrafts in the property tree we should optimize the mp-server
+ for (i = 0; i < 10000; i++) {
+ p = root->getNode(typeString, i, false);
+
+ if (!p || !p->getBoolValue("valid", false))
+ break;
+
+ if (p->getIntValue("id",-1)==model->getID()) {
+ p->setStringValue("callsign","***invalid node***"); //debug only, should never set!
+ }
+ }
+
+ p = root->getNode(typeString, i, true);
+ model->setManager(this, p);
+ ai_list.push_back(model);
+ ++mNumAiModels;
+ ++(mNumAiTypeModels[model->getType()]);
+ model->init(model->getType()==FGAIBase::otAircraft
+ || model->getType()==FGAIBase::otMultiplayer
+ || model->getType()==FGAIBase::otStatic);
+ model->bind();
+ p->setBoolValue("valid", true);
+}
+
+void
+FGAIManager::destroyObject( int ID ) {
+ ai_list_iterator ai_list_itr = ai_list.begin();
+
+ while(ai_list_itr != ai_list.end()) {
+
+ if ((*ai_list_itr)->getID() == ID) {
+ --mNumAiModels;
+ --(mNumAiTypeModels[(*ai_list_itr)->getType()]);
+ (*ai_list_itr)->unbind();
+ ai_list_itr = ai_list.erase(ai_list_itr);
+ } else
+ ++ai_list_itr;
+ }
+
+}
+
+int
+FGAIManager::getNumAiObjects(void) const
+{
+ return mNumAiModels;
+}
+
+void
+FGAIManager::fetchUserState( void ) {
+ user_latitude = user_latitude_node->getDoubleValue();
+ user_longitude = user_longitude_node->getDoubleValue();
+ user_altitude = user_altitude_node->getDoubleValue();
+ user_heading = user_heading_node->getDoubleValue();
+ user_pitch = user_pitch_node->getDoubleValue();
+ user_yaw = user_yaw_node->getDoubleValue();
+ user_speed = user_speed_node->getDoubleValue() * 0.592484;
+ user_roll = user_roll_node->getDoubleValue();
+ wind_from_east = wind_from_east_node->getDoubleValue();
+ wind_from_north = wind_from_north_node->getDoubleValue();
+}
+
+// only keep the results from the nearest thermal
+void
+FGAIManager::processThermal( FGAIThermal* thermal ) {
+ thermal->update(_dt);
+
+ if ( thermal->_getRange() < range_nearest ) {
+ range_nearest = thermal->_getRange();
+ strength = thermal->getStrength();