void LifeForm::fire() { Basic::Number* hdgObj = new Basic::Number(getHeadingR()); Basic::Number* pitchObj = new Basic::Number(lookAngle * Basic::Angle::D2RCC); StoresMgr* mgr = getStoresManagement(); if (mgr != nullptr) { if (getSimulation() != nullptr) { if (weaponSel == LF_MISSILE) { mgr->setGunSelected(false); Missile* missile = mgr->getNextMissile(); if (missile != nullptr) { missile->setSlotInitPitch(pitchObj); missile->setSlotInitHeading(hdgObj); missile->reset(); Missile* msl = mgr->releaseOneMissile(); if (msl != nullptr) { if (tgtAquired && tgtPlayer != nullptr) msl->setTargetPlayer(tgtPlayer, true); } } } else if (weaponSel == LF_GUN) { mgr->setGunSelected(true); Gun* myGun = mgr->getGun(); if (myGun != nullptr) { myGun->setGunArmed(true); Basic::Number* num = new Basic::Number(lookAngle * Basic::Angle::D2RCC); myGun->setSlotPitch(num); num->unref(); myGun->fireControl(true); } } } } hdgObj->unref(); pitchObj->unref(); }
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); } } } }
//------------------------------------------------------------------------------ // weaponDynamics -- default missile dynamics; using Robot Aircraft (RAC) dynamics //------------------------------------------------------------------------------ void Missile::weaponDynamics(const LCreal dt) { static const LCreal g = ETHG; // Acceleration of Gravity // --- // Max turning G (Missiles: Use Gmax) // --- LCreal gmax = maxG; // --- // Computer max turn rate, max/min pitch rates // --- // Turn rate base on vp and g,s LCreal ra_max = gmax * g / getTotalVelocity(); // Set max (pull up) pitch rate same as turn rate LCreal qa_max = ra_max; // Set min (push down) pitch rate LCreal qa_min = -qa_max; // --- // Get old angular values // --- const osg::Vec3 oldRates = getAngularVelocities(); //LCreal pa1 = oldRates[IROLL]; LCreal qa1 = oldRates[IPITCH]; LCreal ra1 = oldRates[IYAW]; // --- // Find pitch rate and update pitch // --- LCreal qa = lcAepcRad(cmdPitch - (LCreal) getPitchR()); if(qa > qa_max) qa = qa_max; if(qa < qa_min) qa = qa_min; // Using Pitch rate, integrate pitch LCreal newTheta = (LCreal) (getPitch() + (qa + qa1) * dt / 2.0); // Find turn rate LCreal ra = lcAepcRad(cmdHeading - (LCreal) getHeadingR()); if(ra > ra_max) ra = ra_max; if(ra < -ra_max) ra = -ra_max; // Use turn rate integrate heading LCreal newPsi = (LCreal) (getHeading() + (ra + ra1) * dt / 2.0); if(newPsi > 2.0f*PI) newPsi -= (LCreal)(2.0*PI); if(newPsi < 0.0f) newPsi += (LCreal)(2.0*PI); // Roll angle proportional to max turn rate - filtered LCreal pa = 0.0; LCreal newPhi = (LCreal) ( 0.98 * getRollR() + 0.02 * ((ra / ra_max) * (Basic::Angle::D2RCC * 60.0)) ); // Sent angular values setEulerAngles(newPhi, newTheta, newPsi); setAngularVelocities(pa, qa, ra); // Find Acceleration LCreal vpdot = (cmdVelocity - getTotalVelocity()); if(vpdot > maxAccel) vpdot = maxAccel; if(vpdot < -maxAccel) vpdot = -maxAccel; // Set acceleration vector osg::Vec3 aa(vpdot, 0.0, 0.0); osg::Vec3 ae = aa * getRotMat(); setAcceleration(ae); // Comute new velocity LCreal newVP = getTotalVelocity() + vpdot * dt; // Set acceleration vector osg::Vec3 ve0 = getVelocity(); osg::Vec3 va(newVP, 0.0, 0.0); osg::Vec3 ve1 = va * getRotMat(); setVelocity(ve1); setVelocityBody(newVP, 0.0, 0.0); }