diff --git a/src/AIModel/AIBallistic.cxx b/src/AIModel/AIBallistic.cxx index 5e3b15509..68a388e75 100644 --- a/src/AIModel/AIBallistic.cxx +++ b/src/AIModel/AIBallistic.cxx @@ -61,6 +61,7 @@ FGAIBallistic::FGAIBallistic(object_type ot) : _slave_load_to_ac(false), _contents_lb(0), _report_collision(false), + _report_expiry(false), _report_impact(false), _external_force(false), _impact_report_node(fgGetNode("/ai/models/model-impact", true)), @@ -321,6 +322,7 @@ void FGAIBallistic::setMass(double m) { void FGAIBallistic::setWeight(double w) { _weight_lb = w; } + void FGAIBallistic::setRandom(bool r) { _random = r; } @@ -333,6 +335,11 @@ void FGAIBallistic::setCollision(bool c) { _report_collision = c; } +void FGAIBallistic::setExpiry(bool e) { + _report_expiry = e; +// cout << "_report_expiry " << _report_expiry << endl; +} + void FGAIBallistic::setExternalForce(bool f) { _external_force = f; } @@ -536,8 +543,14 @@ void FGAIBallistic::Run(double dt) { _life_timer += dt; // if life = -1 the object does not die - if (_life_timer > life && life != -1) - setDie(true); + if (_life_timer > life && life != -1){ + + if (_report_expiry && !_expiry_reported){ + handle_expiry(); + } else + setDie(true); + + } //set the contents in the appropriate tank or other property in the parent to zero setContents(0); @@ -809,6 +822,19 @@ void FGAIBallistic::handle_impact() { } } +void FGAIBallistic::handle_expiry() { + + report_impact(pos.getElevationM()); + _expiry_reported = true; + + SG_LOG(SG_GENERAL, SG_ALERT, "AIBallistic: expiry"); + //if (life == -1){ + // invisible = true; + //} else if (_subID == 0) // kill the AIObject if there is no subsubmodel + // setDie(true); + +} + void FGAIBallistic::handle_collision() { const FGAIBase *object = manager->calcCollision(pos.getElevationFt(), diff --git a/src/AIModel/AIBallistic.hxx b/src/AIModel/AIBallistic.hxx index 859bcd109..29b51fffd 100644 --- a/src/AIModel/AIBallistic.hxx +++ b/src/AIModel/AIBallistic.hxx @@ -70,6 +70,7 @@ public: void setRandom( bool r ); void setName(const string&); void setCollision(bool c); + void setExpiry(bool e); void setImpact(bool i); void setImpactReportNode(const string&); void setContentsNode(const string&); @@ -164,6 +165,7 @@ private: bool _report_collision; // if true a collision point with AI Objects is calculated bool _report_impact; // if true an impact point on the terrain is calculated bool _external_force; // if true then apply external force + bool _report_expiry; SGPropertyNode_ptr _impact_report_node; // report node for impact and collision SGPropertyNode_ptr _contents_node; // report node for impact and collision @@ -181,6 +183,7 @@ private: const SGMaterial* _material; void handle_collision(); + void handle_expiry(); void handle_impact(); void report_impact(double elevation, const FGAIBase *target = 0); void slaveToAC(double dt); diff --git a/src/AIModel/AIBase.cxx b/src/AIModel/AIBase.cxx index de107a682..f4d002563 100644 --- a/src/AIModel/AIBase.cxx +++ b/src/AIModel/AIBase.cxx @@ -579,6 +579,10 @@ bool FGAIBase::_getCollisionData() { return _collision_reported; } +bool FGAIBase::_getExpiryData() { + return _expiry_reported; +} + bool FGAIBase::_getImpactData() { return _impact_reported; } diff --git a/src/AIModel/AIBase.hxx b/src/AIModel/AIBase.hxx index ee6a70a34..e47f778d0 100644 --- a/src/AIModel/AIBase.hxx +++ b/src/AIModel/AIBase.hxx @@ -177,6 +177,7 @@ protected: bool _impact_reported; bool _collision_reported; + bool _expiry_reported; double _impact_lat; double _impact_lon; @@ -246,6 +247,7 @@ public: bool _getImpact(); bool _getImpactData(); bool _getCollisionData(); + bool _getExpiryData(); SGPropertyNode* _getProps() const; diff --git a/src/AIModel/submodel.cxx b/src/AIModel/submodel.cxx index 7b946f0b8..c810c5ccf 100644 --- a/src/AIModel/submodel.cxx +++ b/src/AIModel/submodel.cxx @@ -37,6 +37,7 @@ FGSubmodelMgr::FGSubmodelMgr() string contents_node; contrail_altitude = 30000; _count = 0; + _found_sub = true; } FGSubmodelMgr::~FGSubmodelMgr() @@ -82,7 +83,9 @@ void FGSubmodelMgr::init() void FGSubmodelMgr::postinit() { // postinit, so that the AI list is populated loadAI(); - loadSubmodels(); + + while (_found_sub) + loadSubmodels(); //TODO reload submodels if an MP ac joins } @@ -106,6 +109,7 @@ void FGSubmodelMgr::update(double dt) _impact = false; _hit = false; + _expiry = false; // check if the submodel hit an object or terrain sm_list = ai->get_ai_list(); @@ -115,13 +119,14 @@ void FGSubmodelMgr::update(double dt) for (; sm_list_itr != end; ++sm_list_itr) { _impact = (*sm_list_itr)->_getImpactData(); _hit = (*sm_list_itr)->_getCollisionData(); + _expiry = (*sm_list_itr)->_getExpiryData(); int parent_subID = (*sm_list_itr)->_getSubID(); //SG_LOG(SG_GENERAL, SG_DEBUG, "Submodel: Impact " << _impact << " hit! " // << _hit <<" parent_subID " << parent_subID); if ( parent_subID == 0) // this entry in the list has no associated submodel continue; // so we can continue - if (_impact || _hit) { + if (_impact || _hit || _expiry) { //SG_LOG(SG_GENERAL, SG_DEBUG, "Submodel: Impact " << _impact << " hit! " << _hit ); submodel_iterator = submodels.begin(); @@ -175,58 +180,19 @@ void FGSubmodelMgr::update(double dt) //cout << (*submodel_iterator)->name << "trigger node not found " << trigger << endl; } - if (trigger) { - int id = (*submodel_iterator)->id; - string name = (*submodel_iterator)->name; - // don't release submodels from AI Objects if they are - // too far away to be seen. id 0 is not an AI model, - // so we can skip the whole process - sm_list_iterator sm_list_itr = sm_list.begin(); - sm_list_iterator end = sm_list.end(); + if (trigger && (*submodel_iterator)->count != 0) { - while (sm_list_itr != end) { - in_range = true; + //int id = (*submodel_iterator)->id; + //string name = (*submodel_iterator)->name; + /*SG_LOG(SG_GENERAL, SG_DEBUG, + "Submodels end: " << (*submodel_iterator)->id + << " name " << (*submodel_iterator)->name + << " count " << (*submodel_iterator)->count + << " in range " << in_range);*/ - if (id == 0) { - //SG_LOG(SG_GENERAL, SG_DEBUG, - // "Submodels: continuing: " << id << " name " << name ); - ++sm_list_itr; - continue; - } - - int parent_id = (*submodel_iterator)->id; - - if (parent_id == id) { - double parent_lat = (*sm_list_itr)->_getLatitude(); - double parent_lon = (*sm_list_itr)->_getLongitude(); - string parent_name = (*sm_list_itr)->_getName(); - double own_lat = _user_lat_node->getDoubleValue(); - double own_lon = _user_lon_node->getDoubleValue(); - double range_nm = getRange(parent_lat, parent_lon, own_lat, own_lon); - //cout << "parent name " << parent_name << ", "<< parent_id << ", "<< parent_lat << ", " << parent_lon << endl; - //cout << "own name " << own_lat << ", " << own_lon << " range " << range_nm << endl; - - if (range_nm > 15) { - //SG_LOG(SG_GENERAL, SG_DEBUG, - // "Submodels: skipping release, out of range: " << id); - in_range = false; - } - } - - ++sm_list_itr; - } // end while - - /*SG_LOG(SG_GENERAL, SG_DEBUG, - "Submodels end: " << (*submodel_iterator)->id - << " name " << (*submodel_iterator)->name - << " count " << (*submodel_iterator)->count - << " in range " << in_range);*/ - - if ((*submodel_iterator)->count != 0 && in_range) - release(*submodel_iterator, dt); - - } else - (*submodel_iterator)->first_time = true; + release(*submodel_iterator, dt); + } else + (*submodel_iterator)->first_time = true; ++submodel_iterator; } // end while @@ -281,6 +247,7 @@ bool FGSubmodelMgr::release(submodel *sm, double dt) ballist->setNoRoll(sm->no_roll); ballist->setName(sm->name); ballist->setCollision(sm->collision); + ballist->setExpiry(sm->expiry); ballist->setImpact(sm->impact); ballist->setImpactReportNode(sm->impact_report); ballist->setFuseRange(sm->fuse_range); @@ -595,6 +562,7 @@ void FGSubmodelMgr::setData(int id, string& path, bool serviceable) sm->aero_stabilised = entry_node->getBoolValue("aero-stabilised", true); sm->no_roll = entry_node->getBoolValue("no-roll", false); sm->collision = entry_node->getBoolValue("collision", false); + sm->expiry = entry_node->getBoolValue("expiry", false); sm->impact = entry_node->getBoolValue("impact", false); sm->impact_report = entry_node->getStringValue("impact-reports"); sm->fuse_range = entry_node->getDoubleValue("fuse-range", 0.0); @@ -698,6 +666,7 @@ void FGSubmodelMgr::setSubData(int id, string& path, bool serviceable) sm->aero_stabilised = entry_node->getBoolValue("aero-stabilised", true); sm->no_roll = entry_node->getBoolValue("no-roll", false); sm->collision = entry_node->getBoolValue("collision", false); + sm->expiry = entry_node->getBoolValue("expiry", false); sm->impact = entry_node->getBoolValue("impact", false); sm->impact_report = entry_node->getStringValue("impact-reports"); sm->fuse_range = entry_node->getDoubleValue("fuse-range", 0.0); @@ -757,31 +726,38 @@ void FGSubmodelMgr::loadSubmodels() { SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: Loading sub submodels"); + _found_sub = false; + submodel_iterator = submodels.begin(); - while (submodel_iterator != submodels.end()) { - string submodel = (*submodel_iterator)->submodel; - if (!submodel.empty()) { - //int id = (*submodel_iterator)->id; - bool serviceable = true; - //SG_LOG(SG_GENERAL, SG_DEBUG, "found path sub sub " - // << submodel - // << " index " << index - // << "name " << (*submodel_iterator)->name); + while (submodel_iterator != submodels.end()) { + string submodel = (*submodel_iterator)->submodel; + if (!submodel.empty()) { + //int id = (*submodel_iterator)->id; + bool serviceable = true; + //SG_LOG(SG_GENERAL, SG_DEBUG, "found path sub sub " + // << submodel + // << " index " << index + // << "name " << (*submodel_iterator)->name); - (*submodel_iterator)->sub_id = index; - setSubData(index, submodel, serviceable); - } + if ((*submodel_iterator)->sub_id == 0){ + (*submodel_iterator)->sub_id = index; + _found_sub = true; + setSubData(index, submodel, serviceable); + } + } - ++submodel_iterator; - } + ++submodel_iterator; + } // end while subsubmodel_iterator = subsubmodels.begin(); while (subsubmodel_iterator != subsubmodels.end()) { submodels.push_back(*subsubmodel_iterator); ++subsubmodel_iterator; - } + } // end while + + subsubmodels.clear(); //submodel_iterator = submodels.begin(); diff --git a/src/AIModel/submodel.hxx b/src/AIModel/submodel.hxx index 9709bb375..bcf7363e8 100644 --- a/src/AIModel/submodel.hxx +++ b/src/AIModel/submodel.hxx @@ -63,6 +63,7 @@ public: bool no_roll; bool serviceable; bool collision; + bool expiry; bool impact; string impact_report; double fuse_range; @@ -148,6 +149,8 @@ private: bool _impact; bool _hit; + bool _expiry; + bool _found_sub; SGPropertyNode_ptr _serviceable_node; SGPropertyNode_ptr _user_lat_node;