void PlaneState::updateState(const Basic::Component* const actor)
{
   const Simulation::AirVehicle* airVehicle = dynamic_cast<const Simulation::AirVehicle*>(actor);
   setAlive(false);
   if (airVehicle != nullptr && airVehicle->isActive()) {
      setAltitude(airVehicle->getAltitude());
      setAlive(airVehicle->getMode() == Simulation::Player::ACTIVE);
      setHeading(airVehicle->getHeading());
      setPitch(airVehicle->getPitch());
      setRoll(airVehicle->getRoll());
      osg::Vec3d angularVels = airVehicle->getAngularVelocities();
      setRollRate(angularVels.x());
      setPitchRate(angularVels.y());
      setYawRate(angularVels.z());
      setTracking(false);
      setTargetTrack(MAX_TRACKS);  // 0 is a valid target track, use MAX_TRACKS to
                                   // signal "no tgt track"
      setSpeed(airVehicle->getCalibratedAirspeed());
      setNumEngines(airVehicle->getNumberOfEngines());
      setIncomingMissile(false);
      setMissileFired(false);

      // determine if we have a missile to fire
#if 1
      const Simulation::StoresMgr* stores = airVehicle->getStoresManagement();
      if (stores == nullptr || stores->getNextMissile() == nullptr) {
         // either we have no SMS, or we have no more missile
         setMissileFired(true);
      }
      else {
         // we have an sms, and we have a missile available
         // loop through player list and attempt to find out if one of our missiles is active
         // if there is an active missile, then for the time being, we do not have a missile to fire
         const Simulation::Simulation* sim = airVehicle->getSimulation();
         const Basic::PairStream* players = sim->getPlayers();
         bool finished = false;
         for (const Basic::List::Item* item = players->getFirstItem(); item != nullptr && !finished; item = item->getNext()) {
            // Get the pointer to the target player
            const Basic::Pair* pair = static_cast<const Basic::Pair*>(item->getValue());
            const Simulation::Player* player = static_cast<const Simulation::Player*>(pair->object());
            if (player->isMajorType(Simulation::Player::WEAPON) && (player->isActive() || player->isMode(Simulation::Player::PRE_RELEASE)) && (player->getSide() == airVehicle->getSide())) {
               // our side has a weapon on-the-way/in-the-air;
               setMissileFired(true);
               finished=true;
            }
         }
      }
#else
      // this state class has no way to determine whether we've fired a missile other than checking to see if sms is out of missiles to fire.
      // which means, it will fire all its missiles at first target.
      const Simulation::StoresMgr* stores = airVehicle->getStoresManagement();
      if (stores != 0) {
         const Simulation::Missile* wpn = stores->getNextMissile();
         if (!wpn)
            setMissileFired(true);
      }
      else {
         // we have no SMS, we can't fire a missile;
         setMissileFired(true);
      }
#endif

      //const Basic::String* playerName = airVehicle->getName();
      // DH - DOES NOT COMPILE WITH CONST -- ????
      Simulation::AirVehicle* airVehicleX = const_cast<Simulation::AirVehicle*>(airVehicle);
      const Basic::Pair* sensorPair = airVehicleX->getSensorByType(typeid(Simulation::Radar));

      if (sensorPair != nullptr) {
         const Simulation::Radar* radar = static_cast<const Simulation::Radar*>(sensorPair->object());
         if (radar != nullptr) {
            const Simulation::TrackManager* trackManager = radar->getTrackManager();
            Basic::safe_ptr<Simulation::Track> trackList[50];
            unsigned int nTracks = trackManager->getTrackList(trackList, 50);

            for (int trackIndex = nTracks -1; trackIndex >= 0; trackIndex--) {
               setHeadingToTracked(trackIndex, trackList[trackIndex]->getRelAzimuth());
               setPitchToTracked(trackIndex, trackList[trackIndex]->getElevation());
               setDistanceToTracked(trackIndex, trackList[trackIndex]->getRange());

               // do we have a live "target track"? (shootlist is 1-based)
               if (getTargetTrack()==MAX_TRACKS && (trackList[trackIndex]->getShootListIndex() == 1) && trackList[trackIndex]->getTarget()->isActive()  ) {
                  setTargetTrack(trackIndex);
               }
               setTracking(true);
               setNumTracks(nTracks);

               // hack to implement "missile warning"
               if (isIncomingMissile() == false) {
                  // is this track a weapon, and if so, is it targeting me?
                  Simulation::Player* target = trackList[trackIndex]->getTarget();
                  Simulation::Weapon* weapon = dynamic_cast<Simulation::Weapon*> (target);
                  if (weapon!=nullptr && !weapon->isDead()) {
                     Simulation::Player* wpntgt = weapon->getTargetPlayer();
                     if (wpntgt == airVehicle) {
                        setIncomingMissile(true);
                     }
                  }
               }

            }
         }
      }

      const Simulation::OnboardComputer* oc = airVehicle->getOnboardComputer();
      if (oc != nullptr) {
         const Simulation::TrackManager* rtm = oc->getTrackManagerByType(typeid(Simulation::RwrTrkMgr));
         if(rtm !=nullptr) {
            Basic::safe_ptr<Simulation::Track> trackList[50];
            unsigned int nTracks = rtm->getTrackList(trackList, 50);
            int newTracks = 0;
            for (unsigned int trackIndex = 0; trackIndex < nTracks; trackIndex++) {
               Simulation::Player* target = trackList[trackIndex]->getTarget();
               bool alreadyTracked = false;
               for (unsigned int currTracks = 0; currTracks>getNumTracks(); currTracks++) {
                  // tracks are the same if the associated players are the same
                  if(trackList[currTracks]->getTarget()==target) {
                     alreadyTracked = true;
                     break;
                  }
               }

               if (!alreadyTracked && (getNumTracks() + newTracks) < MAX_TRACKS) {
                  int newTrackIndex = getNumTracks() + newTracks;
                  newTracks++;
                  setHeadingToTracked(newTrackIndex, trackList[trackIndex]->getRelAzimuth());
                  setPitchToTracked(newTrackIndex, trackList[trackIndex]->getElevation());
                  setDistanceToTracked(newTrackIndex, trackList[trackIndex]->getRange());
                  setTracking(true);

                  // update numTracks to new sum of radar + rwr tracks
                  setNumTracks(getNumTracks()+newTracks);
               }

               // do we have a live "target track"? (shootlist is 1-based)
               if (getTargetTrack()==MAX_TRACKS && (trackList[trackIndex]->getShootListIndex() == 1) && trackList[trackIndex]->getTarget()->isActive()  ) {
                  setTargetTrack(trackIndex);
               }

               // hack to implement "missile warning"
               if (isIncomingMissile() == false) {
                  // is this track a weapon, and if so, is it targeting me?
                  Simulation::Weapon* weapon = dynamic_cast<Simulation::Weapon*> (target);
                  if (weapon!=nullptr && !weapon->isDead()) {
                     Simulation::Player* wpntgt = weapon->getTargetPlayer();
                     if (wpntgt == airVehicle) {
                        setIncomingMissile(true);
                     }
                  }
               }

            }
         }
      }
   }
   BaseClass::updateState(actor);
}
Exemple #2
0
//------------------------------------------------------------------------------
// weaponFireMsgFactory() -- (Output support) Weapon fire message factory
//------------------------------------------------------------------------------
bool Nib::weaponFireMsgFactory(const LCreal)
{
    bool ok = true;
    //std::cout << "NetIO::weaponFireMsgFactory() HERE!!" << std::endl;

    // Get our NetIO
    NetIO* disIO = (NetIO*)(getNetIO());
    //Simulation* sim = disIO->getSimulation();

    // Set the NIB mode so that we don't do this again.
    setMode(Simulation::Player::ACTIVE);
    
    // Our NIB's player is a weapon that just became active
    Simulation::Weapon* mPlayer = (Simulation::Weapon*)(getPlayer());

    // Ok, we have the weapon, now get the firing and target players
    Simulation::Player* tPlayer = mPlayer->getTargetPlayer();
    Simulation::Player* fPlayer = mPlayer->getLaunchVehicle();
    if (fPlayer == 0) return false;

    // ---
    // PDU header 
    // ---
    FirePDU pdu;
    pdu.header.protocolVersion = disIO->getVersion();
    pdu.header.exerciseIdentifier = disIO->getExerciseID();
    pdu.header.PDUType = NetIO::PDU_FIRE;
    pdu.header.protocolFamily = NetIO::PDU_FAMILY_WARFARE;
    pdu.header.timeStamp = disIO->timeStamp();
    pdu.header.length = sizeof(FirePDU);
    
    // ---
    // Set the PDU data with the firing (launcher) player's id
    // ---
    pdu.firingEntityID.ID = fPlayer->getID();
    pdu.firingEntityID.simulationID.siteIdentification = disIO->getSiteID();
    pdu.firingEntityID.simulationID.applicationIdentification = disIO->getApplicationID();
    
    // ---
    // Set the PDU data with the munition's ID
    // ---
    pdu.munitionID.ID = mPlayer->getID();
    pdu.munitionID.simulationID.siteIdentification = disIO->getSiteID();
    pdu.munitionID.simulationID.applicationIdentification = disIO->getApplicationID();
    
    // ---
    // Set the PDU data with the target's ID
    // ---
    {
      bool tOk = false;
      if (tPlayer != 0) {
         pdu.targetEntityID.ID = tPlayer->getID();
         if (tPlayer->isLocalPlayer()) {
            // Local player, use our site/app/exerc IDs
            pdu.targetEntityID.simulationID.siteIdentification = disIO->getSiteID();
            pdu.targetEntityID.simulationID.applicationIdentification = disIO->getApplicationID();
            tOk = true;
         }
         else {
            const Nib* fNIB = dynamic_cast<const Nib*>( tPlayer->getNib() );
            if (fNIB != 0) {
               // Networked player, use it's NIB's IDs
               pdu.targetEntityID.simulationID.siteIdentification = fNIB->getSiteID();
               pdu.targetEntityID.simulationID.applicationIdentification = fNIB->getApplicationID();
               tOk = true;
            }
         }
      }
      if (!tOk) {
         // Networked player, use it's NIB's IDs
         pdu.targetEntityID.ID = 0;
         pdu.targetEntityID.simulationID.siteIdentification = 0;
         pdu.targetEntityID.simulationID.applicationIdentification = 0;
      }
    }
    
    // ---
    // Event ID
    // ---
    pdu.eventID.simulationID.siteIdentification = disIO->getSiteID();
    pdu.eventID.simulationID.applicationIdentification = disIO->getApplicationID();
    pdu.eventID.eventNumber = mPlayer->getReleaseEventID();

    // ---
    // Location & Velociy
    // ---

    // World Coordinates
    osg::Vec3d geocPos = mPlayer->getGeocPosition();
    pdu.location.X_coord = geocPos[Basic::Nav::IX];
    pdu.location.Y_coord = geocPos[Basic::Nav::IY];
    pdu.location.Z_coord = geocPos[Basic::Nav::IZ];

    // Velocity
    osg::Vec3d geocVel = mPlayer->getGeocVelocity();
    pdu.velocity.component[0] = (float)geocVel[Basic::Nav::IX];
    pdu.velocity.component[1] = (float)geocVel[Basic::Nav::IY];
    pdu.velocity.component[2] = (float)geocVel[Basic::Nav::IZ];

    // ---
    // Burst
    // ---
    pdu.burst.munision.kind         = getEntityKind();
    pdu.burst.munision.domain       = getEntityDomain();
    pdu.burst.munision.country      = getEntityCountry();
    pdu.burst.munision.category     = getEntityCategory();
    pdu.burst.munision.subcategory  = getEntitySubcategory();
    pdu.burst.munision.specific     = getEntitySpecific();
    pdu.burst.munision.extra        = getEntityExtra();
    pdu.burst.warhead = 0;
    pdu.burst.fuse = 0;;
    pdu.burst.quantity = 1;
    pdu.burst.rate = 0;

    // ---
    // Range and fire index
    // ---
    pdu.fireMissionIndex = 0;
    pdu.range = 0.0;

    //pdu.dumpData();
    //std::cout << "NetIO::weaponFireMsgFactory() fired:";
    //std::cout << "(" << pdu.firingEntityID.ID;
    //std::cout << "," << pdu.firingEntityID.simulationID.applicationIdentification ;
    //std::cout << "," << pdu.firingEntityID.simulationID.siteIdentification;
    //std::cout << ")   munision:";
    //std::cout << "(" << pdu.munitionID.ID;
    //std::cout << "," << pdu.munitionID.simulationID.applicationIdentification ;
    //std::cout << "," << pdu.munitionID.simulationID.siteIdentification;
    //std::cout << ")" << std::endl;

    if (Basic::NetHandler::isNotNetworkByteOrder()) pdu.swapBytes();
    ok = disIO->sendData((char*)&pdu,sizeof(pdu));

    return ok;
}    
//------------------------------------------------------------------------------
// munitionDetonationMsgFactory() -- (Output) Munition detonation message factory
//------------------------------------------------------------------------------
bool Nib::munitionDetonationMsgFactory(const LCreal)
{
   // Dummy weapon?
   const Simulation::Weapon* ww = dynamic_cast<const Simulation::Weapon*>( getPlayer() );
   if (ww != 0) {
      if (ww->isDummy()) return true;
   }

    bool ok = true;
    //std::cout << "NetIO::munitionDetonationMsgFactory() HERE!!" << std::endl;

    // Get our NetIO
    NetIO* disIO = (NetIO*)(getNetIO());

    // If our NIB's player just detonated, then it must be a weapon!
    Simulation::Weapon* mPlayer = dynamic_cast<Simulation::Weapon*>(getPlayer());
    if (mPlayer == 0) return false;

    // Ok, we have the weapon, now get the firing and target players
    Simulation::Player* tPlayer = mPlayer->getTargetPlayer();
    Simulation::Player* fPlayer = mPlayer->getLaunchVehicle();
    if (fPlayer == 0) return false;

    // ---
    // PDU header
    // ---
    DetonationPDU pdu;
    pdu.header.protocolVersion = disIO->getVersion();
    pdu.header.PDUType = NetIO::PDU_DETONATION;
    pdu.header.protocolFamily = NetIO::PDU_FAMILY_WARFARE;
    pdu.header.length = sizeof(DetonationPDU);
    pdu.header.exerciseIdentifier = disIO->getExerciseID();
    pdu.header.timeStamp = disIO->timeStamp();
    pdu.header.status = 0;
    pdu.header.padding = 0;

    // ---
    // Set the PDU data with the firing (launcher) player's id
    // ---
    pdu.firingEntityID.ID = fPlayer->getID();
    pdu.firingEntityID.simulationID.siteIdentification = getSiteID();
    pdu.firingEntityID.simulationID.applicationIdentification = getApplicationID();

    // ---
    // Set the PDU data with the munition's ID
    // ---
    pdu.munitionID.ID = mPlayer->getID();
    pdu.munitionID.simulationID.siteIdentification = getSiteID();
    pdu.munitionID.simulationID.applicationIdentification = getApplicationID();

    // ---
    // Set the PDU data with the target's ID
    // ---
    {
         bool tOk = false;
         if (tPlayer != 0) {
            pdu.targetEntityID.ID = tPlayer->getID();
            if (tPlayer->isLocalPlayer()) {
               // Local player, use our site/app/exerc IDs
               pdu.targetEntityID.simulationID.siteIdentification = getSiteID();
               pdu.targetEntityID.simulationID.applicationIdentification = getApplicationID();
               tOk = true;
            }
            else {
               // Networked player, use its NIB's IDs
               const Nib* fNIB = dynamic_cast<const Nib*>( tPlayer->getNib() );
               if (fNIB != 0) {
                  pdu.targetEntityID.simulationID.siteIdentification = fNIB->getSiteID();
                  pdu.targetEntityID.simulationID.applicationIdentification = fNIB->getApplicationID();
                  tOk = true;
               }
            }
         }
         if (!tOk) {
            pdu.targetEntityID.ID = 0;
            pdu.targetEntityID.simulationID.siteIdentification = 0;
            pdu.targetEntityID.simulationID.applicationIdentification = 0;
         }
    }

    // ---
    // Event ID
    // ---
    pdu.eventID.simulationID.siteIdentification = getSiteID();
    pdu.eventID.simulationID.applicationIdentification = getApplicationID();
    pdu.eventID.eventNumber = mPlayer->getReleaseEventID();

    // ---
    // Location & Velocity
    // ---

    // World Coordinates
    osg::Vec3d geocPos = mPlayer->getGeocPosition();
    pdu.location.X_coord = geocPos[Basic::Nav::IX];
    pdu.location.Y_coord = geocPos[Basic::Nav::IY];
    pdu.location.Z_coord = geocPos[Basic::Nav::IZ];

    // Velocity
    osg::Vec3d geocVel = mPlayer->getGeocVelocity();
    pdu.velocity.component[0] = (float)geocVel[Basic::Nav::IX];
    pdu.velocity.component[1] = (float)geocVel[Basic::Nav::IY];
    pdu.velocity.component[2] = (float)geocVel[Basic::Nav::IZ];

    // ---
    // Burst
    // ---
    pdu.burst.munition.kind         = getEntityKind();
    pdu.burst.munition.domain       = getEntityDomain();
    pdu.burst.munition.country      = getEntityCountry();
    pdu.burst.munition.category     = getEntityCategory();
    pdu.burst.munition.subcategory  = getEntitySubcategory();
    pdu.burst.munition.specific     = getEntitySpecific();
    pdu.burst.munition.extra        = getEntityExtra();
    pdu.burst.warhead = 0;
    pdu.burst.fuse = 0;;
    pdu.burst.quantity = 1;
    pdu.burst.rate = 0;

    // ---
    // Location
    // ---
    osg::Vec3 lpos = mPlayer->getDetonationLocation();
    pdu.locationInEntityCoordinates.component[0] = (float) lpos[0];
    pdu.locationInEntityCoordinates.component[1] = (float) lpos[1];
    pdu.locationInEntityCoordinates.component[2] = (float) lpos[2];

    // ---
    // Results
    // ---
    pdu.detonationResult = (unsigned char)( mPlayer->getDetonationResults() );
    pdu.numberOfArticulationParameters = 0;

    //std::cout << "NetIO::munitionDetonationMsgFactory() results: " << int(pdu.detonationResult) << std::endl;
    //pdu.dumpData();

    // ---
    // Send the PDU
    // ---
    if (Basic::NetHandler::isNotNetworkByteOrder()) pdu.swapBytes();
    ok = disIO->sendData((char*)&pdu,sizeof(pdu));

    // Set the detonation message sent flag so that we don't do this again.
    setDetonationMessageSent(true);

    return ok;
}