//------------------------------------------------------------------------------ // sendMessage() -- send the datalink message out to the world. //------------------------------------------------------------------------------ bool Datalink::sendMessage(Basic::Object* const msg) { bool sent = false; // If we can send to our local players directly (or via radio) if (sendLocal) { // --- // Have a comm radio -- then we'll just let our companion radio system handle this // --- if (radio != 0) { sent = radio->transmitDataMessage(msg); } // --- // No comm radio -- then we'll send this out to the other players ourself. // --- else if (getOwnship() != 0) { Simulation* sim = getSimulation(); if (sim != 0) { Basic::PairStream* players = sim->getPlayers(); if (players != 0) { Basic::List::Item* playerItem = players->getFirstItem(); while (playerItem != 0) { Basic::Pair* playerPair = static_cast<Basic::Pair*>(playerItem->getValue()); Player* player = static_cast<Player*>(playerPair->object()); if (player->isLocalPlayer()) { // Send to active, local players only (and not to ourself) if ((player->isActive() || player->isMode(Player::PRE_RELEASE)) && player != getOwnship() ) { player->event(DATALINK_MESSAGE, msg); } playerItem = playerItem->getNext(); } else { // Networked players are at the end of the list, // so we can stop now. playerItem = 0; } } players->unref(); players = 0; } } sent = true; } } // --- // and let any (optional) outgoing queue know about this. // --- if (queueForNetwork) { Player* ownship = getOwnship(); if (ownship != 0) { if (ownship->isLocalPlayer()) { queueOutgoingMessage(msg); } } } return sent; }
//------------------------------------------------------------------------------ // emitterBeamsManager() // -- (Output) Manages the emitter beam for this NIB(Player) //------------------------------------------------------------------------------ bool Nib::emitterBeamsManager(const LCreal curExecTime) { // --- // First, find all of our player's RfSensor systems and setup their handlers // --- if ( numEmissionSystems == 0 ) { // Check for the single-beam RADAR { // (DPG -- #### only a simple, single-beam Radar) const Basic::Pair * pair = getPlayer()->getSensorByType(typeid(Simulation::Radar)); if (pair != nullptr) { Simulation::RfSensor* rs = (Simulation::RfSensor*) pair->object(); // When we have a R/F sensor, create a handler for it EmissionPduHandler* handler = nullptr; // First, try to find an Emission PDU handler for this type system. // If we find one, then clone it for our use. NetIO* const disIO = static_cast<NetIO*>(getNetIO()); const EmissionPduHandler* tmp = disIO->findEmissionPduHandler(rs); if (tmp != nullptr) { handler = tmp->clone(); } // Handler wasn't found? Then just create a simple, default emission handler if (handler == nullptr) { handler = new EmissionPduHandler(); } handler->setSensor( rs ); handler->setEmitterIdNumber( numEmissionSystems + 1 ); emitterSysHandler[numEmissionSystems] = handler; numEmissionSystems++; } } // end radar check // Check for a Jammer { const Basic::Pair * pair = getPlayer()->getSensorByType(typeid(Simulation::Jammer)); if (pair != nullptr) { Simulation::RfSensor* js = (Simulation::RfSensor*) pair->object(); bool singleBeam = true; Basic::PairStream* subcomponents = js->getComponents(); if (subcomponents != nullptr) { // Check for multi-beam jammer (each beam is a subcomponent Jammer) Basic::List::Item* item = subcomponents->getFirstItem(); while (item != nullptr && numEmissionSystems < MAX_EM_SYSTEMS) { Basic::Pair* pair = static_cast<Basic::Pair*>( item->getValue() ); Simulation::Jammer* jam = dynamic_cast<Simulation::Jammer*>( pair->object() ); if (jam != nullptr) { singleBeam = false; // When we have a R/F sensor, create a handler for it EmissionPduHandler* handler = nullptr; // First, try to find an Emission PDU handler for this type system. // If we find one, then clone it for our use. NetIO* const disIO = static_cast<NetIO*>(getNetIO()); const EmissionPduHandler* tmp = disIO->findEmissionPduHandler(jam); if (tmp != nullptr) { handler = tmp->clone(); } // Handler wasn't found? Then just create a simple, default handler if (handler == nullptr) { handler = new EmissionPduHandler(); handler->setEmitterFunction(EmissionPduHandler::ESF_JAMMING); } handler->setSensor( jam ); handler->setEmitterIdNumber( numEmissionSystems + 1 ); emitterSysHandler[numEmissionSystems] = handler; numEmissionSystems++; } item = item->getNext(); } subcomponents->unref(); subcomponents = nullptr; } // Single beam jammer if (singleBeam && numEmissionSystems < MAX_EM_SYSTEMS) { // When we have a R/F sensor, create a handler for it EmissionPduHandler* handler = nullptr; // First, try to find an Emission PDU handler for this type system. // If we find one, then clone it for our use. NetIO* const disIO = static_cast<NetIO*>(getNetIO()); const EmissionPduHandler* tmp = disIO->findEmissionPduHandler(js); if (tmp != nullptr) { handler = tmp->clone(); } // Handler wasn't found? Then just create a simple, default jammer handler if (handler == nullptr) { handler = new EmissionPduHandler(); handler->setEmitterFunction(EmissionPduHandler::ESF_JAMMING); } handler->setSensor( js ); handler->setEmitterIdNumber( numEmissionSystems + 1 ); emitterSysHandler[numEmissionSystems] = handler; numEmissionSystems++; } } } // end jammer check } // end (numEmissionSystems == 0) // --- // Have the handlers check their electromagnetic emission systems // and generate the PDUs as needed. // --- for (emissionSystemsIndex = 0; emissionSystemsIndex < numEmissionSystems; emissionSystemsIndex++) { if (emitterSysHandler[emissionSystemsIndex] != nullptr) { emitterSysHandler[emissionSystemsIndex]->updateOutgoing(curExecTime, this); } } return true; }
//------------------------------------------------------------------------------ // checkForTargetHit() -- check to see if we hit anything //------------------------------------------------------------------------------ bool Bullet::checkForTargetHit() { Player* ownship = getLaunchVehicle(); Player* tgt = getTargetPlayer(); if (ownship != nullptr && tgt != nullptr) { osg::Vec3 osPos = tgt->getPosition(); // For all active bursts ... for (int i = 0; i < nbt; i++) { if (bursts[i].bStatus == Burst::ACTIVE) { // Check if we're within range of the target osg::Vec3 rPos = bursts[i].bPos - osPos; LCreal rng = rPos.length(); if (rng < 10.0) { // Yes -- it's a hit! bursts[i].bStatus = Burst::HIT; setHitPlayer(tgt); setLocationOfDetonation(); tgt->processDetonation(rng,this); } } } } // if we are just flying along, check our range to the nearest player and tell him we killed it else { //osg::Vec3 old = getEulerAngles(); osg::Vec3 myPos = getPosition(); osg::Vec3 tgtPos; osg::Vec3 vecPos; //LCreal az = 0; //LCreal el = 0; LCreal range = 0; //LCreal diffAz = 0; //LCreal diffEl = 0; LCreal maxRange = 1; // close range of detonation Simulation* sim = getSimulation(); if (sim != nullptr) { Basic::PairStream* players = sim->getPlayers(); if (players != nullptr) { Basic::List::Item* item = players->getFirstItem(); while (item != nullptr) { Basic::Pair* pair = static_cast<Basic::Pair*>(item->getValue()); if (pair != nullptr) { Player* player = dynamic_cast<Player*>(pair->object()); if (player != nullptr && player != ownship && player->isMajorType(LIFE_FORM) && !player->isDestroyed()) { // ok, calculate our position from this guy tgtPos = player->getPosition(); vecPos = tgtPos - myPos; //az = lcAtan2(vecPos.y(), vecPos.x()); range = (vecPos.x() * vecPos.x() + vecPos.y() * vecPos.y()); range = std::sqrt(range); if (range < maxRange) { // tell this target we hit it player->processDetonation(range, this); } } } item = item->getNext(); } players->unref(); players = nullptr; } } } return false; }
// Set the stores bool Stores::setSlotStores(const Basic::PairStream* const msg) { // --- // Quick out if the number of stations hasn't been set. // --- if (ns == 0 && msg != 0) { std::cerr << "Stores::setSlotStation() Number of stations is not set!" << std::endl; return false; } // --- // Clear the previous stores and assigned weapons // --- storesList = 0; for (unsigned int s = 1; s <= ns; s++) { assignWeaponToStation(s,0); assignExtStoreToStation(s,0); } numWpn = 0; numEs = 0; // --- // Quick out if 'msg' is zero // --- if (msg == 0) return true; bool ok = true; // --- // Create the new external stores list // // For all items in the 'msg' list ... // -- Make sure that it's a weapon or other type of external store, and // that it has a valid station number. // -- Clone the store and if it's a weapon then assign it to the station. // --- Basic::PairStream* newStores = new Basic::PairStream(); const Basic::List::Item* item = msg->getFirstItem(); while (item != 0) { const Basic::Pair* pair = static_cast<const Basic::Pair*>(item->getValue()); const Basic::Component* p = static_cast<const Basic::Component*>(pair->object()); if (p != 0) { // get the station number from the stores' slot name int stationNumber = 0; const Basic::Identifier* stationName = pair->slot(); if (stationName->isInteger()) { stationNumber = stationName->getInteger(); } if (stationNumber > 0 && stationNumber <= static_cast<int>(ns)) { // check the type of component bool isWpn = p->isClassType(typeid(Weapon)); bool isEE = p->isClassType(typeid(ExternalStore)); if ( isWpn || isEE ) { // Clone the weapon pair and set us as its container Basic::Pair* cpair = pair->clone(); Component* cp = static_cast<Component*>(cpair->object()); cp->container(this); if ( isWpn ) { // Weapon types ... // Assign the weapon to the station Weapon* cwpn = static_cast<Weapon*>( cpair->object() ); assignWeaponToStation(stationNumber, cwpn); } if ( isEE ) { // External stores types ... // Assign the external store to the station ExternalStore* cwpn = static_cast<ExternalStore*>( cpair->object() ); assignExtStoreToStation(stationNumber, cwpn); } if (cpair != 0) { // Add to the new stores list newStores->put(cpair); cpair->unref(); // the new list has it. } } else { std::cerr << "Stores::setSlotStores(): invalid external stores type; use Weapon or Stores classes" << std::endl; ok = false; } } else { std::cerr << "Stores::setSlotStores(): invalid station number from the store's slot name." << std::endl; ok = false; } } item = item->getNext(); } // Make the new stores list the active list if (ok && newStores->entries() > 0) { storesList = newStores; } else { for (unsigned int s = 1; s <= ns; s++) { assignWeaponToStation(s,0); } numWpn = 0; } newStores->unref(); return ok; }
void LifeForm::look(const LCreal up, const LCreal sdws) { if (getDamage() < 1) { if (lockMode != LOCKED) { lockMode = SEARCHING; // our up and sideways come in as -5 to 5, which is a rate to adjust heading const osg::Vec3 old = getEulerAngles(); LCreal hdg = old.z(); LCreal ptc = lookAngle; LCreal tempSdws = sdws; LCreal tempUp = up; if (lcAbs(tempSdws) < 0.00005) tempSdws = 0; if (lcAbs(tempUp) < 0.05) tempUp = 0; hdg += tempSdws; hdg = lcAepcRad(hdg); // we don't change our pitch when we look up and down, we only change our look angle, so we have to keep // that separate. WE do, however, change our heading based on where we are looking, so that is correct ptc += tempUp; if (ptc > 90) ptc = 90; else if (ptc < -90) ptc = -90; //std::cout << "HEADING = " << hdg << std::endl; setLookAngle(ptc); osg::Vec3 eul(0, 0, hdg); setEulerAngles(eul); // now based on this we need to know if we have a target in our crosshairs... tgtAquired = false; if (tgtPlayer != nullptr) tgtPlayer->unref(); tgtPlayer = nullptr; const osg::Vec3 myPos = getPosition(); osg::Vec3 tgtPos; osg::Vec3 vecPos; LCreal az = 0.0, el = 0.0, range = 0.0, diffAz = 0.0, diffEl = 0.0; const LCreal maxAz = (0.7f * static_cast<LCreal>(Basic::Angle::D2RCC)); const LCreal maxEl = (0.7f * static_cast<LCreal>(Basic::Angle::D2RCC)); //LCreal maxRange = 1500.0f; // long range right now const LCreal la = lookAngle * static_cast<LCreal>(Basic::Angle::D2RCC); Simulation* sim = getSimulation(); if (sim != nullptr) { Basic::PairStream* players = sim->getPlayers(); if (players != nullptr) { Basic::List::Item* item = players->getFirstItem(); while (item != nullptr && !tgtAquired) { Basic::Pair* pair = static_cast<Basic::Pair*>(item->getValue()); if (pair != nullptr) { Player* player = dynamic_cast<Player*>(pair->object()); if (player != nullptr && player != this && !player->isMajorType(WEAPON) && !player->isDestroyed()) { // ok, calculate our position from this guy tgtPos = player->getPosition(); vecPos = tgtPos - myPos; az = lcAtan2(vecPos.y(), vecPos.x()); range = (vecPos.x() * vecPos.x() + vecPos.y() * vecPos.y()); range = std::sqrt(range); // now get our elevation el = lcAtan2(-vecPos.z(), range); diffAz = lcAbs(lcAepcRad(az - static_cast<LCreal>(getHeadingR()))); diffEl = lcAbs(lcAepcRad(la - el)); if ((diffAz <= maxAz) && (diffEl <= maxEl)) { lockMode = TGT_IN_SIGHT; tgtAquired = true; if (tgtPlayer != player) { if (tgtPlayer != nullptr) tgtPlayer->unref(); tgtPlayer = player; tgtPlayer->ref(); } } } } item = item->getNext(); } players->unref(); players = nullptr; } } } // else we are locking on target, and need to follow our target player else { if (tgtPlayer == nullptr) lockMode = SEARCHING; else { const osg::Vec3 vecPos = tgtPlayer->getPosition() - getPosition(); const LCreal az = lcAtan2(vecPos.y(), vecPos.x()); LCreal range = (vecPos.x() * vecPos.x() + vecPos.y() * vecPos.y()); range = std::sqrt(range); // now get our elevation const LCreal el = lcAtan2(-vecPos.z(), range); // now force that on us setLookAngle(el * static_cast<LCreal>(Basic::Angle::R2DCC)); setEulerAngles(0, 0, az); } } } }
//------------------------------------------------------------------------------ // Set slot functions //------------------------------------------------------------------------------ bool StoresMgr::setSlotStores(const Basic::PairStream* const msg) { // First let our base class do everything that it needs to. BaseClass::setSlotStores(msg); // --- // Clear all previous stores and assigned weapons // --- weaponsList = 0; externalList = 0; fuelList = 0; gunPtr = 0; // --- // Use the stores list that the Stores class just processed. Basic::PairStream* stores = getStores(); if (stores != 0){ // Create the new weapons list that contains all weapons { Basic::PairStream* newWeapons = new Basic::PairStream(); searchAndAdd(stores, typeid(Weapon), newWeapons); if (newWeapons->entries() > 0) weaponsList = newWeapons; newWeapons->unref(); } // Create the new external stores list that contains all // non-weapon, external stores (e.g., fuel tanks, pods, guns) { Basic::PairStream* newExternal = new Basic::PairStream(); searchAndAdd(stores, typeid(ExternalStore), newExternal); if (newExternal->entries() > 0) externalList = newExternal; newExternal->unref(); } // Create the new fuel tank list that contains all fuel tanks { Basic::PairStream* newFuel = new Basic::PairStream(); searchAndAdd(stores, typeid(FuelTank), newFuel); if (newFuel->entries() > 0) fuelList = newFuel; newFuel->unref(); } // Find the primary gun; i.e., the first gun found on our stores Basic::List::Item* item = stores->getFirstItem(); while (item != 0 && gunPtr == 0) { Basic::Pair* pair = (Basic::Pair*)(item->getValue()); Gun* p = dynamic_cast<Gun*>( pair->object() ); if (p != 0) gunPtr = p; item = item->getNext(); } stores->unref(); stores = 0; } return true; }
//------------------------------------------------------------------------------ // updateTC() -- update time critical stuff here //------------------------------------------------------------------------------ void Station::updateTC(const LCreal dt) { // Update the Basic::Timers if (isUpdateTimersEnabled()) { Basic::Timer::updateTimers(dt); } // The I/O handers if (ioHandlers != 0) { Basic::List::Item* item = ioHandlers ->getFirstItem(); while (item != 0) { Basic::Pair* pair = (Basic::Pair*)(item->getValue()); Basic::IoHandler* p = (Basic::IoHandler*)( pair->object() ); p->tcFrame(dt); item = item->getNext(); } } // Process station inputs inputDevices(dt); // Update the simulation if (sim != 0) sim->tcFrame(dt); // Process station outputs outputDevices(dt); // Our major subsystems if (sim != 0 && otw != 0) { Basic::PairStream* playerList = sim->getPlayers(); Basic::List::Item* item = otw->getFirstItem(); while (item != 0) { Basic::Pair* pair = (Basic::Pair*)(item->getValue()); Otw* p = (Otw*)( pair->object() ); // Set ownship & player list p->setOwnship(ownship); p->setPlayerList(playerList); // TC frame p->tcFrame(dt); item = item->getNext(); } if (playerList != 0) playerList->unref(); } // Startup RESET timer -- // Sends an initial RESET pulse after timeout // (Some simulation may need this) if (startupResetTimer >= 0) { startupResetTimer -= dt; if (startupResetTimer < 0) { this->event(RESET_EVENT); } } // Update the base class data BaseClass::updateTC(dt); }
//------------------------------------------------------------------------------ // copyData() -- copy member data //------------------------------------------------------------------------------ void Station::copyData(const Station& org, const bool cc) { BaseClass::copyData(org); if (cc) initData(); // Terminate any old threads setTcThread(0); setNetThread(0); setBgThread(0); // Set the simulation exec if (org.sim != 0) { Simulation* copy = (Simulation*) org.sim->clone(); setSlotSimulation( copy ); copy->unref(); } else { setSlotSimulation(0); } // Copy the OTW handlers if (org.otw != 0) { Basic::PairStream* copy = (Basic::PairStream*) org.otw->clone(); setSlotOutTheWindow( copy ); copy->unref(); } else { setSlotOutTheWindow((Basic::PairStream*)0); } // Copy the networks if (org.networks != 0) { Basic::PairStream* copy = (Basic::PairStream*) org.networks->clone(); setSlotNetworks( copy ); copy->unref(); } else { setSlotNetworks((Basic::PairStream*)0); } // Copy the I/O handlers if (org.ioHandlers != 0) { Basic::PairStream* copy = (Basic::PairStream*) org.ioHandlers->clone(); setSlotIoHandler( copy ); copy->unref(); } else { setSlotIoHandler((Basic::PairStream*)0); } tcRate = org.tcRate; tcPri = org.tcPri; fastForwardRate = org.fastForwardRate; netRate = org.netRate; netPri = org.netPri; bgRate = org.bgRate; bgPri = org.bgPri; tmrUpdateEnbl = org.tmrUpdateEnbl; if (org.startupResetTimer0!= 0) { Basic::Time* copy = (Basic::Time*) org.startupResetTimer0->clone(); setSlotStartupResetTime( copy ); copy->unref(); } else { setSlotStartupResetTime(0); } startupResetTimer = org.startupResetTimer; // Unref our old stuff (if any) if (ownshipName != 0) { ownshipName->unref(); ownshipName = 0; } if (ownship != 0) { ownship->unref(); ownship = 0; } // Copy own ownship name if (org.ownshipName != 0) { ownshipName = dynamic_cast<Basic::String*> (org.ownshipName->clone() ); } // Attach our ownship setOwnshipByName( *ownshipName ); }
//----------------------------------------------------------------------------- // setSlotIoHandler() -- Sets a list of I/O handlers //----------------------------------------------------------------------------- bool Station::setSlotIoHandler(Basic::IoHandler* const p) { Basic::PairStream* list = new Basic::PairStream(); list->put( new Basic::Pair("1",p) ); return setSlotIoHandler(list); }