//////////////////////////////////////////////////////// // TEST: testSendTSOInteractionWithInvalidParameter() // //////////////////////////////////////////////////////// void SendInteractionTest::testSendTSOInteractionWithInvalidParameter() { RTI::ParameterHandleValuePairSet *params = defaultFederate->createPHVPS( 2 ); params->add( xaHandle, "xa", 3 ); params->add( 10000000, "no", 3 ); try { RTIfedTime theTime = 10.0; defaultFederate->rtiamb->sendInteraction( yHandle, *params, theTime, "NA" ); delete params; failTestMissingException( "InteractionParameterNotDefined", "sending interaction with invalid param handle" ); } catch( RTI::InteractionParameterNotDefined &ipnd ) { // success! delete params; } catch( RTI::Exception &e ) { delete params; failTestWrongException( "InteractionParameterNotDefined", e, "sending interaction with invalid param handle" ); } }
/* * This method will send out an interaction of the type InteractionRoot.X. Any * federates which are subscribed to it will receive a notification the next time * they tick(). Here we are passing only two of the three parameters we could be * passing, but we don't actually have to pass any at all! */ void ExampleCPPFederate::sendInteraction() { /////////////////////////////////////////////// // create the necessary container and values // /////////////////////////////////////////////// // create the collection to store the values in RTI::ParameterHandleValuePairSet *parameters = RTI::ParameterSetFactory::create( 2 ); // generate the new values char xaValue[16], xbValue[16]; sprintf( xaValue, "xa:%f", getLbts() ); sprintf( xbValue, "xb:%f", getLbts() ); parameters->add( xaHandle, xaValue, (RTI::ULong)strlen(xaValue)+1 ); parameters->add( xbHandle, xbValue, (RTI::ULong)strlen(xbValue)+1 ); ////////////////////////// // send the interaction // ////////////////////////// rtiamb->sendInteraction( xHandle, *parameters, "hi!" ); // if you want to associate a particular timestamp with the // interaction, you will have to supply it to the RTI. Here // we send another interaction, this time with a timestamp: RTIfedTime time = fedamb->federateTime + fedamb->federateLookahead; rtiamb->sendInteraction( xHandle, *parameters, time, "hi!" ); // clean up delete parameters; }
void Master_FA::receiveInteraction ( RTI::InteractionClassHandle theInteraction, const RTI::ParameterHandleValuePairSet & theParameters, const RTI::FedTime & theTime, const char * theTag, RTI::EventRetractionHandle theHandle) throw ( RTI::InteractionClassNotKnown, RTI::InteractionParameterNotKnown, RTI::InvalidFederationTime, RTI::FederateInternalError) { RTIfedTime fed_time(theTime); cout << "Incoming interaction at time " << fed_time.getTime() << endl; if (theInteraction != reply_handle) { cerr << "Received unknown interaction " << theInteraction << endl; return; } if (theParameters.size() != 3) { cerr << "Unexpected number of parameters " << theParameters.size() << endl; return; } // extract values RTI::ULong id; RTI::Double change_lat; RTI::Double change_long; unsigned long length; RTI::ParameterHandle handle; char buffer [20]; for (unsigned long i = 0; i < 3; i++) { handle = theParameters.getHandle (i); if (handle == reply_parameters [Id]) { theParameters.getValue (i, buffer, length); Sim_Hla_Istream is (buffer, length); is >> id; } else if (handle == reply_parameters [ChangeLat])
//----------------------------------------------------------------- // // METHOD: // void Country::Update( RTI::InteractionClassHandle theInteraction, // const RTI::ParameterHandleValuePairSet& theParameters ) // // PURPOSE: // Process an interaction. // // RETURN VALUES: // None. // // HISTORY: // 1) Created 11/6/96 // 2) Updated to RTI 1.3 3/26/98 // //----------------------------------------------------------------- void Country::Update( RTI::InteractionClassHandle theInteraction, const RTI::ParameterHandleValuePairSet& theParameters ) { if ( theInteraction == Country::GetCommRtiId() ) { RTI::ParameterHandle paramHandle; RTI::ULong valueLength; // We need to iterate through the AttributeHandleValuePairSet // to extract each AttributeHandleValuePair. Based on the type // specified ( the value returned by getHandle() ) we need to // extract the data frlom the buffer that is returned by // getValue(). for ( unsigned int i = 0; i < theParameters.size(); i++ ) { paramHandle = theParameters.getHandle( i ); if ( paramHandle == Country::GetMessageRtiId() ) { // When we run this over multiple platforms we will have // a problem with different endian-ness of platforms. Either // we need to encode the data using something like XDR or // provide another mechanism. char msg[ 1024 ]; theParameters.getValue( i, (char*)msg, valueLength ); cout << "FED_HW: Interaction Received: " << msg << endl; } else { // There must be an error since there should only be // one parameter to Communication. cerr << "FED_HW: Error: I seem to have received a parameter for " << "interaction class Communication that I don't " << "know about." << endl; } } } else { cerr << "FED_HW: Recieved an interaction class I don't know about." << endl; } }
//------------------------------------------------------------------------------ // munitionDetonationMsgFactory() -- (Output) Munition detonation message factory //------------------------------------------------------------------------------ bool Nib::munitionDetonationMsgFactory(const double) { std::cout << "rprfom::Nib::sendMunitionDetonation() HERE!!" << std::endl; // Early out -- we must be registered if (!isRegistered()) return false; NetIO* netIO = static_cast<NetIO*>(getNetIO()); // Create the parameter/value set RTI::ParameterHandleValuePairSet* pParams = RTI::ParameterSetFactory::create( NetIO::NUM_INTERACTION_PARAMETER ); // Set our mode so that we don't do this again. setMode(simulation::Player::DETONATED); // If our player just detonated, then it must be a weapon! simulation::Weapon* mPlayer = dynamic_cast<simulation::Weapon*>(getPlayer()); if (mPlayer == nullptr) return false; // Early out -- it wasn't a weapon // --- // Event ID // --- unsigned short fireEvent = getWeaponFireEvent(); EventIdentifierStruct eventIdentifier; base::NetHandler::toNetOrder(&eventIdentifier.eventCount, fireEvent); base::utStrncpy( reinterpret_cast<char*>(&eventIdentifier.issuingObjectIdentifier.id[0]), sizeof(eventIdentifier.issuingObjectIdentifier.id), getObjectName(), RTIObjectIdStruct::ID_SIZE ); pParams->add( netIO->getInteractionParameterHandle(NetIO::EVENT_IDENTIFIER_MD_PI), reinterpret_cast<char*>(&eventIdentifier), sizeof(EventIdentifierStruct) ); // --- // Location & Velocity // --- { osg::Vec3d geocPos = getDrPosition(); osg::Vec3d geocVel = getDrVelocity(); osg::Vec3d geocAcc = getDrAcceleration(); // World Coordinates WorldLocationStruct detonationLocation; base::NetHandler::toNetOrder(&detonationLocation.x, geocPos[base::Nav::IX]); base::NetHandler::toNetOrder(&detonationLocation.y, geocPos[base::Nav::IY]); base::NetHandler::toNetOrder(&detonationLocation.z, geocPos[base::Nav::IZ]); pParams->add( netIO->getInteractionParameterHandle(NetIO::DETONATION_LOCATION_MD_PI), reinterpret_cast<char*>(&detonationLocation), sizeof(WorldLocationStruct) ); // Velocity VelocityVectorStruct finalVelocityVector; base::NetHandler::toNetOrder(&finalVelocityVector.xVelocity, static_cast<float>(geocVel[base::Nav::IX])); base::NetHandler::toNetOrder(&finalVelocityVector.yVelocity, static_cast<float>(geocVel[base::Nav::IY])); base::NetHandler::toNetOrder(&finalVelocityVector.zVelocity, static_cast<float>(geocVel[base::Nav::IZ])); pParams->add( netIO->getInteractionParameterHandle(NetIO::FINAL_VELOCITY_VECTOR_MD_PI), reinterpret_cast<char*>(&finalVelocityVector), sizeof(VelocityVectorStruct) ); } // --- // Munition Object identifiers: // --- { RTIObjectIdStruct munitionObjectIdentifier; base::utStrncpy( reinterpret_cast<char*>(&munitionObjectIdentifier.id[0]), sizeof(munitionObjectIdentifier.id), getObjectName(), RTIObjectIdStruct::ID_SIZE ); pParams->add( netIO->getInteractionParameterHandle(NetIO::MUNITION_OBJECT_IDENTIFIER_MD_PI), reinterpret_cast<char*>(&munitionObjectIdentifier), sizeof(RTIObjectIdStruct) ); } // --- // Firing Object identifier: // // Get the firing player and its NIB. // First check to see if it's an IPlayer from an HLA network. // If it's not, then check our output list. // --- { Nib* fNib = nullptr; simulation::Player* fPlayer = mPlayer->getLaunchVehicle(); if (fPlayer != nullptr) { if (fPlayer->isNetworkedPlayer()) { fNib = dynamic_cast<Nib*>( fPlayer->getNib() ); } else { fNib = dynamic_cast<Nib*>( netIO->findNib(fPlayer, simulation::NetIO::OUTPUT_NIB) ); } } if (fNib != nullptr) { RTIObjectIdStruct firingObjectIdentifier; base::utStrncpy( reinterpret_cast<char*>(&firingObjectIdentifier.id[0]), sizeof(firingObjectIdentifier.id), fNib->getObjectName(), RTIObjectIdStruct::ID_SIZE ); pParams->add( netIO->getInteractionParameterHandle(NetIO::FIRING_OBJECT_IDENTIFIER_MD_PI), reinterpret_cast<char*>(&firingObjectIdentifier), sizeof(RTIObjectIdStruct) ); } } // --- // Target Object identifier: // // Get the target player and its NIB. // First check to see if it's an IPlayer from an HLA network. // If it's not, then check our output list. // --- { Nib* tNib = nullptr; simulation::Player* tPlayer = mPlayer->getTargetPlayer(); if (tPlayer != nullptr) { tNib = dynamic_cast<Nib*>( tPlayer->getNib() ); if (tNib == nullptr) tNib = dynamic_cast<Nib*>( netIO->findNib(tPlayer, simulation::NetIO::OUTPUT_NIB) ); } if (tNib != nullptr) { RTIObjectIdStruct targetObjectIdentifier; base::utStrncpy( reinterpret_cast<char*>(&targetObjectIdentifier.id[0]), sizeof(targetObjectIdentifier.id), tNib->getObjectName(), RTIObjectIdStruct::ID_SIZE ); pParams->add( netIO->getInteractionParameterHandle(NetIO::TARGET_OBJECT_IDENTIFIER_MD_PI), reinterpret_cast<char*>(&targetObjectIdentifier), sizeof(RTIObjectIdStruct) ); } } // --- // Munition Type // --- { EntityTypeStruct munitionType; munitionType.entityKind = getEntityKind(); munitionType.domain = getEntityDomain(); base::NetHandler::toNetOrder(&munitionType.countryCode, getEntityCountry() ); munitionType.category = getEntityCategory(); munitionType.subcategory = getEntitySubcategory(); munitionType.specific = getEntitySpecific(); munitionType.extra = getEntityExtra(); pParams->add( netIO->getInteractionParameterHandle(NetIO::MUNITION_TYPE_MD_PI), reinterpret_cast<char*>(&munitionType), sizeof(EntityTypeStruct) ); } // --- // Fuse Type (16 bit enum) // --- { FuseTypeEnum16 fuseType = FuseTypeOther; unsigned short netBuffer; base::NetHandler::toNetOrder(&netBuffer, static_cast<unsigned short>(fuseType) ); pParams->add( netIO->getInteractionParameterHandle(NetIO::FUSE_TYPE_MD_PI), reinterpret_cast<char*>(&netBuffer), sizeof(unsigned short) ); } // --- // Quantity fired // --- { unsigned short quantityFired = 1; unsigned short netBuffer; base::NetHandler::toNetOrder(&netBuffer, quantityFired ); pParams->add( netIO->getInteractionParameterHandle(NetIO::QUANTITY_FIRED_MD_PI), reinterpret_cast<char*>(&netBuffer), sizeof(unsigned short) ); } // --- // Rate Of Fire // --- { unsigned short rateOfFire = 0; unsigned short netBuffer; base::NetHandler::toNetOrder(&netBuffer, rateOfFire ); pParams->add( netIO->getInteractionParameterHandle(NetIO::RATE_OF_FIRE_MD_PI), reinterpret_cast<char*>(&netBuffer), sizeof(unsigned short) ); } // --- // Warhead type // --- { WarheadTypeEnum16 warheadType = WarheadTypeOther; unsigned short netBuffer; base::NetHandler::toNetOrder(&netBuffer, static_cast<unsigned short>(warheadType) ); pParams->add( netIO->getInteractionParameterHandle(NetIO::WARHEAD_TYPE_MD_PI), reinterpret_cast<char*>(&netBuffer), sizeof(unsigned short) ); } // --- // Relative detonation location // --- { RelativePositionStruct relativeDetonationLocation; relativeDetonationLocation.bodyXDistance = 0; relativeDetonationLocation.bodyYDistance = 0; relativeDetonationLocation.bodyZDistance = 0; RelativePositionStruct netBuffer; base::NetHandler::toNetOrder(&netBuffer.bodyXDistance, relativeDetonationLocation.bodyXDistance ); base::NetHandler::toNetOrder(&netBuffer.bodyYDistance, relativeDetonationLocation.bodyYDistance ); base::NetHandler::toNetOrder(&netBuffer.bodyZDistance, relativeDetonationLocation.bodyZDistance ); pParams->add( netIO->getInteractionParameterHandle(NetIO::RELATIVE_DETONATION_LOCATION_MD_PI), reinterpret_cast<char*>(&netBuffer), sizeof(RelativePositionStruct) ); } // --- // Detonation result code // --- { DetonationResultCodeEnum8 detonationResultCode; switch ( mPlayer->getDetonationResults() ) { case simulation::Weapon::DETONATE_OTHER : detonationResultCode = DetonationResultCodeOther; break; case simulation::Weapon::DETONATE_ENTITY_IMPACT : detonationResultCode = EntityImpact; break; case simulation::Weapon::DETONATE_ENTITY_PROXIMATE_DETONATION : detonationResultCode = EntityProximateDetonation; break; case simulation::Weapon::DETONATE_GROUND_IMPACT : detonationResultCode = GroundImpact; break; case simulation::Weapon::DETONATE_GROUND_PROXIMATE_DETONATION : detonationResultCode = GroundProximateDetonation; break; case simulation::Weapon::DETONATE_DETONATION : detonationResultCode = Detonation; break; case simulation::Weapon::DETONATE_NONE : detonationResultCode = None; break; default : detonationResultCode = DetonationResultCodeOther; break; }; unsigned char netBuffer = static_cast<unsigned char>(detonationResultCode); pParams->add( netIO->getInteractionParameterHandle(NetIO::DETONATION_RESULT_CODE_MD_PI), reinterpret_cast<char*>(&netBuffer), sizeof(unsigned char) ); } // --- // Send the interaction // --- bool ok = netIO->sendInteraction( netIO->getInteractionClassHandle(NetIO::MUNITION_DETONATION_INTERACTION), pParams ); // don't need this anymore delete pParams; return ok; }
//----------------------------------------------------------------- // // METHOD: // void Country::Update( RTIfedTime& newTime ) // // PURPOSE: // Update the state of the Country's population based on // the new time value. The deltaTime is calculated based // on the last time the Country object was updated and // the newTime passed in. The deltaTime is multiplied by // the growth rate and current population to determine the // number of births in the deltaTime. The population is // increased by the number of births. // // RETURN VALUES: // None. // // HISTORY: // 1) Created 11/6/96 // 2) Updated to RTI 1.3 3/26/98 // //----------------------------------------------------------------- void Country::Update( RTI::FedTime& newTime ) { //------------------------------------------------------ // we have advanced in time so calculate my next state. //------------------------------------------------------ RTI::FedTime *pTime = RTI::FedTimeFactory::makeZero(); (*pTime) = newTime; (*pTime) -= this->GetLastTime(); // Set last time to new time this->SetLastTime( newTime ); if ( !(pTime->isZero())) { SetPopulation( GetPopulation() + (GetPopulation()*ms_growthRate) ); } if ( ms_rtiAmb ) { //------------------------------------------------------ // Update state of country //------------------------------------------------------ try { //------------------------------------------------------ // In order to send the values of our attributes, we must // construct an AttributeHandleValuePairSet (AHVPS) which // is a set comprised of attribute handles, values, and // the size of the values. CreateNVPSet() is a method // defined on the Country class - it is not part of the RTI. // Look inside the method to see how to construct an AHVPS //------------------------------------------------------ RTI::AttributeHandleValuePairSet* pNvpSet = this->CreateNVPSet(); //------------------------------------------------------ // Send the AHVPS to the federation. // // this call returns an event retraction handle but we // don't support event retraction so no need to store it. //------------------------------------------------------ (void) ms_rtiAmb->updateAttributeValues( this->GetInstanceId(), *pNvpSet, this->GetLastTimePlusLookahead(), NULL ); // Must free the memory pNvpSet->empty(); delete pNvpSet; } catch ( RTI::Exception& e ) { cerr << "FED_HW: Error:" << e << endl; } // Periodically send an interaction to tell everyone Hello static int periodicMessage = 0; if ( (periodicMessage++%100) == 0 ) { RTI::ParameterHandleValuePairSet* pParams = NULL; //------------------------------------------------------ // Periodically stimulate an update of the "Name" // attribute for the benefit of late-arriving federates. // It would be more correct to use // "requestClassAttributeValueUpdate" and // "provideAttributeValueUpdate", but let's keep things // simple. //------------------------------------------------------ hasNameChanged = RTI::RTI_TRUE; //------------------------------------------------------ // Set up the data structure required to push this // objects's state to the RTI. The // ParameterHandleValuePairSet is similar to the AHVPS // except it contains ParameterHandles instead of // AttributeHandles. //------------------------------------------------------ pParams = RTI::ParameterSetFactory::create( 1 ); char *pMessage = "Hello World!"; pParams->add( this->GetMessageRtiId(), (char*) pMessage, ((strlen(pMessage)+1)*sizeof(char)) ); try { //------------------------------------------------------ // this call returns an event retraction handle but we // don't support event retraction so no need to store it. //------------------------------------------------------ (void) ms_rtiAmb->sendInteraction( GetCommRtiId(), *pParams, this->GetLastTimePlusLookahead(), NULL ); } catch ( RTI::Exception& e ) { cerr << "FED_HW: Error:" << e << endl; } //------------------------------------------------------ // Must free the memory: // ParameterSetFactory::create() allocates memory on // the heap. //------------------------------------------------------ delete pParams; } } delete pTime; }
bool HlaFedAmb::ReadDataIxnParameters( const RTI::ParameterHandleValuePairSet& theParameters, HlaDataIxnInfo& dataIxnInfo) { HlaVariableDatumSetInfo& vdsInfo = dataIxnInfo.variableDatumSetInfo; unsigned i; for (i = 0; i < theParameters.size(); i++) { RTI::ParameterHandle ph = theParameters.getHandle(i); RTI::ULong size = theParameters.getValueLength(i); if (ph == m_dataOriginatingEntityHandle) { // Not used. } else if (ph == m_dataReceivingEntityHandle) { // Not used. } else if (ph == m_dataRequestIdentifierHandle) { // Not used. } else if (ph == m_dataFixedDatumsHandle) { // Not used. } else if (ph == m_dataVariableDatumSetHandle) { if (size > g_hlaVariableDatumSetBufSize) { if (m_debug) { cout << "FED: Ignoring Data interaction containing" " large VariableDatumSet parameter" << endl; } return false; } char variableDatumSet[g_hlaVariableDatumSetBufSize]; theParameters.getValue(i, variableDatumSet, size); // NumberOfVariableDatums, DatumID, DatumLength. // Converted to host-byte-order. unsigned vdsOffset = 0; HlaCopyFromOffsetAndNtoh( &vdsInfo.numberOfVariableDatums, variableDatumSet, vdsOffset, sizeof(vdsInfo.numberOfVariableDatums)); if (vdsInfo.numberOfVariableDatums != 1) { if (m_debug) { cout << "FED: Ignoring Data interaction where" " NumberOfVariableDatums != 1" << endl; } return false; } HlaVariableDatumInfo& vdInfo = vdsInfo.variableDatumsInfo[0]; HlaCopyFromOffsetAndNtoh( &vdInfo.datumId, variableDatumSet, vdsOffset, sizeof(vdInfo.datumId)); HlaCopyFromOffsetAndNtoh( &vdInfo.datumLength, variableDatumSet, vdsOffset, sizeof(vdInfo.datumLength)); if (vdInfo.datumLength % 8 != 0) { if (m_debug) { cout << "FED: Ignoring Data interaction where" " DatumLength is not a multiple of 8" << endl; } return false; } unsigned datumLengthInBytes = vdInfo.datumLength / 8; if (datumLengthInBytes > g_hlaDatumValueBufSize) { if (m_debug) { cout << "FED: Ignoring Data interaction containing" " large DatumValue field" << endl; } return false; } // DatumValue. // Left in network-byte-order. HlaCopyFromOffset( vdInfo.datumValue, variableDatumSet, vdsOffset, datumLengthInBytes); } else { HlaReportError("Unknown parameter handle", __FILE__, __LINE__); } }//for// return true; }
//------------------------------------------------------------------------------ // receiveMunitionDetonation() -- (Input) handles the Munition Detonation interaction //------------------------------------------------------------------------------ bool NetIO::receiveMunitionDetonation(const RTI::ParameterHandleValuePairSet& theParameters) { // Things we need RTIObjectIdStruct firingObjectIdentifier; RTIObjectIdStruct munitionObjectIdentifier; RTIObjectIdStruct targetObjectIdentifier; simulation::Weapon::Detonation detonationResult = simulation::Weapon::DETONATE_NONE; // --- // Extract the required data from the interaction's parameters // --- RTI::ULong length; char netBuffer[1000]; for (RTI::ULong i = 0 ; i < theParameters.size(); i++ ) { // get the parameter's handed and data (network byte order) RTI::ParameterHandle theHandle = theParameters.getHandle(i); theParameters.getValue(i, netBuffer, length); // Process the parameter switch ( findParameterIndex(theHandle) ) { case DETONATION_RESULT_CODE_MD_PI : { switch ( DetonationResultCodeEnum8( netBuffer[0] ) ) { case DetonationResultCodeOther : detonationResult = simulation::Weapon::DETONATE_OTHER; break; case EntityImpact : detonationResult = simulation::Weapon::DETONATE_ENTITY_IMPACT; break; case EntityProximateDetonation : detonationResult = simulation::Weapon::DETONATE_ENTITY_PROXIMATE_DETONATION; break; case GroundImpact : detonationResult = simulation::Weapon::DETONATE_GROUND_IMPACT; break; case GroundProximateDetonation : detonationResult = simulation::Weapon::DETONATE_GROUND_PROXIMATE_DETONATION; break; case Detonation : detonationResult = simulation::Weapon::DETONATE_DETONATION; break; case None : detonationResult = simulation::Weapon::DETONATE_NONE; break; default : detonationResult = simulation::Weapon::DETONATE_OTHER; break; }; } break; case FIRING_OBJECT_IDENTIFIER_MD_PI : { // Get the object's name RTI::ULong n = RTIObjectIdStruct::ID_SIZE; if (n > length) n = length; base::utStrncpy(reinterpret_cast<char*>(&firingObjectIdentifier.id[0]), sizeof(firingObjectIdentifier.id), netBuffer, n); firingObjectIdentifier.id[n-1] = '\0'; } break; case MUNITION_OBJECT_IDENTIFIER_MD_PI : { // Get the object's name RTI::ULong n = RTIObjectIdStruct::ID_SIZE; if (n > length) n = length; base::utStrncpy(reinterpret_cast<char*>(&munitionObjectIdentifier.id[0]), sizeof(munitionObjectIdentifier.id), netBuffer, n); munitionObjectIdentifier.id[n-1] = '\0'; } break; case TARGET_OBJECT_IDENTIFIER_MD_PI : { // Get the object's name RTI::ULong n = RTIObjectIdStruct::ID_SIZE; if (n > length) n = length; base::utStrncpy(reinterpret_cast<char*>(&targetObjectIdentifier.id[0]), sizeof(targetObjectIdentifier.id), netBuffer, n); targetObjectIdentifier.id[n-1] = '\0'; } break; } } std::cout << "RprFom::Nib::receiveMunitionDetonation() fired(" << firingObjectIdentifier.id << ")" << std::endl; // --- // 1) Find the target (local) player // --- simulation::Player* tPlayer = nullptr; if ( std::strlen(reinterpret_cast<const char*>(targetObjectIdentifier.id)) > 0 ) { simulation::Nib* tNib = findNibByObjectName( reinterpret_cast<char*>(targetObjectIdentifier.id), OUTPUT_NIB); if (tNib != nullptr) tPlayer = tNib->getPlayer(); } // --- // Note: we're only interested (at this time) with our local players being hit // by other networked IPlayers. // --- if (tPlayer != nullptr) { // --- // 2) Find the firing player and munitions (networked) IPlayers // --- simulation::Nib* fNib = nullptr; simulation::Nib* mNib = nullptr; if ( std::strlen(reinterpret_cast<const char*>(firingObjectIdentifier.id)) > 0 ) { fNib = findNibByObjectName( reinterpret_cast<char*>(firingObjectIdentifier.id), INPUT_NIB); } if ( std::strlen(reinterpret_cast<const char*>(munitionObjectIdentifier.id)) > 0 ) { mNib = findNibByObjectName( reinterpret_cast<char*>(munitionObjectIdentifier.id), INPUT_NIB); } // --- // 3) Tell the target player that it was killed by the firing player // --- if (detonationResult == simulation::Weapon::DETONATE_ENTITY_IMPACT) { if (fNib != nullptr) { tPlayer->event(KILL_EVENT,fNib->getPlayer()); } else { tPlayer->event(KILL_EVENT,0); // killed by we don't know by whom } } // --- // 4) Update the mode of the munition IPlayer // --- if (mNib != nullptr) { simulation::Weapon* mPlayer = dynamic_cast<simulation::Weapon*>(mNib->getPlayer()); if (mPlayer != nullptr) { mPlayer->setMode(simulation::Player::DETONATED); mPlayer->setDetonationResults(detonationResult); } mNib->setMode(simulation::Player::DETONATED); } } return true; }