void LEMEventTimer::Render(SURFHANDLE surf, SURFHANDLE digits) { // Don't do this if not powered. if (!IsPowered()) return; // // Digits are 16x19. // int Curdigit, Curdigit2; // Minute display on two digit Curdigit = minutes / 10; Curdigit2 = minutes / 100; oapiBlt(surf, digits, 0, 0, 19 * (Curdigit-(Curdigit2*10)), 0, 19,21); Curdigit = minutes; Curdigit2 = minutes / 10; oapiBlt(surf, digits, 20, 0, 19 * (Curdigit-(Curdigit2*10)), 0, 19,21); //oapiBlt(surf, digits, 37,0, 192,0,4,19); // second display on two digit Curdigit = seconds / 10; Curdigit2 = seconds / 100; oapiBlt(surf, digits, 43, 0, 19 * (Curdigit-(Curdigit2*10)), 0, 19,21); Curdigit = seconds; Curdigit2 = seconds/10; oapiBlt(surf, digits, 62, 0, 19 * (Curdigit-(Curdigit2*10)), 0, 19,21); }
void DSKY::RenderData(SURFHANDLE surf, SURFHANDLE digits, SURFHANDLE disp, int xOffset, int yOffset) { if (!IsPowered()) return; oapiBlt(surf, disp, 66 + xOffset, 3 + yOffset, 35, 0, 35, 10, SURF_PREDEF_CK); oapiBlt(surf, disp, 66 + xOffset, 38 + yOffset, 35, 10, 35, 10, SURF_PREDEF_CK); oapiBlt(surf, disp, 6 + xOffset, 38 + yOffset, 35, 20, 35, 10, SURF_PREDEF_CK); oapiBlt(surf, disp, 8 + xOffset, 73 + yOffset, 0, 32, 89, 4, SURF_PREDEF_CK); oapiBlt(surf, disp, 8 + xOffset, 107 + yOffset, 0, 32, 89, 4, SURF_PREDEF_CK); oapiBlt(surf, disp, 8 + xOffset, 141 + yOffset, 0, 32, 89, 4, SURF_PREDEF_CK); if (CompActy) { // // Do stuff to update Comp Acty light. // oapiBlt(surf, disp, 6 + xOffset, 4 + yOffset, 0, 0, 35, 31, SURF_PREDEF_CK); } RenderTwoDigitDisplay(surf, digits, 67 + xOffset, 16 + yOffset, Prog, false); RenderTwoDigitDisplay(surf, digits, 8 + xOffset, 51 + yOffset, Verb, VerbFlashing); RenderTwoDigitDisplay(surf, digits, 67 + xOffset, 51 + yOffset, Noun, NounFlashing); // // Register contents. // RenderSixDigitDisplay(surf, digits, 3 + xOffset, 83 + yOffset, R1); RenderSixDigitDisplay(surf, digits, 3 + xOffset, 117 + yOffset, R2); RenderSixDigitDisplay(surf, digits, 3 + xOffset, 151 + yOffset, R3); }
void DSKY::RenderLights(SURFHANDLE surf, SURFHANDLE lights, int xOffset, int yOffset, bool hasAltVel) { if (!IsPowered()) return; // // Check the lights. // DSKYLightBlt(surf, lights, 0, 0, UplinkLit(), xOffset, yOffset); DSKYLightBlt(surf, lights, 0, 25, NoAttLit(), xOffset, yOffset); DSKYLightBlt(surf, lights, 0, 49, StbyLit(), xOffset, yOffset); DSKYLightBlt(surf, lights, 0, 73, KbRelLit() && FlashOn, xOffset, yOffset); DSKYLightBlt(surf, lights, 0, 97, OprErrLit() && FlashOn, xOffset, yOffset); DSKYLightBlt(surf, lights, 52, 0, TempLit(), xOffset, yOffset); DSKYLightBlt(surf, lights, 52, 25, GimbalLockLit(), xOffset, yOffset); DSKYLightBlt(surf, lights, 52, 49, ProgLit(), xOffset, yOffset); DSKYLightBlt(surf, lights, 52, 73, RestartLit(), xOffset, yOffset); DSKYLightBlt(surf, lights, 52, 97, TrackerLit(), xOffset, yOffset); if (hasAltVel) { DSKYLightBlt(surf, lights, 52, 121, AltLit(), xOffset, yOffset); DSKYLightBlt(surf, lights, 52, 144, VelLit(), xOffset, yOffset); } }
//----------------------------------------------------------------------------- // Purpose: Can we get into the vehicle? //----------------------------------------------------------------------------- bool CObjectBaseMannedGun::CanGetInVehicle( CBaseTFPlayer *pPlayer ) { if ( !IsPowered() ) { ClientPrint( pPlayer, HUD_PRINTCENTER, "No power source for the manned gun!" ); return false; } return true; }
//----------------------------------------------------------------------------- // Purpose: Can we get into the vehicle? //----------------------------------------------------------------------------- bool CBaseTFVehicle::CanGetInVehicle( CBaseTFPlayer *pPlayer ) { if ( !IsPowered() ) return false; if ( !InSameTeam( pPlayer ) ) return false; // Player/Class-specific query. return pPlayer->CanGetInVehicle(); }
void DSKY::SystemTimestep(double simdt) { if (!IsPowered()){ return; } // // The DSKY power consumption is a little bit hard to figure out. According // to the Systems Handbook the complete interior lightning draws about 30W, so // we assume one DSKY draws 10W max, for now. We DO NOT rely on the render code to // track the number of lights that are lit, because during pause the still called render // code causes wrong power loads // // // Check the lights. // LightsLit = 0; if (UplinkLit()) LightsLit++; if (NoAttLit()) LightsLit++; if (StbyLit()) LightsLit++; if (KbRelLit() && FlashOn) LightsLit++; if (OprErrLit() && FlashOn) LightsLit++; if (TempLit()) LightsLit++; if (GimbalLockLit()) LightsLit++; if (ProgLit()) LightsLit++; if (RestartLit()) LightsLit++; if (TrackerLit()) LightsLit++; // // Check the segments // SegmentsLit = 6; if (CompActy) SegmentsLit += 4; SegmentsLit += TwoDigitDisplaySegmentsLit(Prog, false); SegmentsLit += TwoDigitDisplaySegmentsLit(Verb, VerbFlashing); SegmentsLit += TwoDigitDisplaySegmentsLit(Noun, NounFlashing); SegmentsLit += SixDigitDisplaySegmentsLit(R1); SegmentsLit += SixDigitDisplaySegmentsLit(R2); SegmentsLit += SixDigitDisplaySegmentsLit(R3); // 10 lights with together max. 6W, 184 segments with together max. 4W DrawPower((LightsLit * 0.6) + (SegmentsLit * 0.022)); //sprintf(oapiDebugString(), "DSKY %f", (LightsLit * 0.6) + (SegmentsLit * 0.022)); }
void CObjectBuffStation::UpdatePlayerAttachment( CBaseTFPlayer *pPlayer ) { // Valid player? if ( !pPlayer ) return; // Attach/Detach (toggle). if ( IsPlayerAttached( pPlayer ) ) DetachPlayer( pPlayer ); else { // Check for power, do not attach to unpowered generator. if ( !IsPowered() ) ClientPrint( pPlayer, HUD_PRINTCENTER, "No power source for the Buff Station!" ); else AttachPlayer( pPlayer ); } }
bool AudacityRover::GyroscopeSenseHAT::NextValue(OpenALRF::Sensor3DData & AValue) { if (IsPowered()) { SenseHAT::d3 sensedata = HAT->get_gyro(); if (sensedata.valid) { AValue.Timestamp = OpenALRF::GetCurrentTimestamp(); AValue.Data1 = sensedata.x; AValue.Data2 = sensedata.y; AValue.Data3 = sensedata.z; LatestSensorData = AValue; return true; } } return false; }
void MissionTimer::UpdateSeconds(int n) { if (!IsPowered()) return; if (CountUp == TIMER_COUNT_UP) { seconds += n; } else if (CountUp == TIMER_COUNT_DOWN) { seconds -= n; } while (seconds > 59) { seconds -= 60; } while (seconds < 0) { seconds += 60; } }
void MissionTimer::UpdateHours(int n) { if (!IsPowered()) return; if (CountUp == TIMER_COUNT_UP) { hours += n; } else if (CountUp == TIMER_COUNT_DOWN) { hours -= n; } while (hours > 999) { hours -= 1000; } while (hours < 0) { hours += 1000; } }
void MissionTimer::UpdateMinutes(int n) { if (!IsPowered()) return; if (CountUp == TIMER_COUNT_UP) { minutes += n; } else if (CountUp == TIMER_COUNT_DOWN) { minutes -= n; } while (minutes > 59) { minutes -= 60; } while (minutes < 0) { minutes += 60; } }
void MissionTimer::Render(SURFHANDLE surf, SURFHANDLE digits, bool csm) { if (!IsPowered()) return; int Curdigit, Curdigit2; // Hour display on three digit Curdigit = hours / 100; Curdigit2 = hours / 1000; oapiBlt(surf, digits, 0,0, 19*(Curdigit-(Curdigit2*10)),0,19,21); Curdigit = hours / 10; Curdigit2 = hours / 100; oapiBlt(surf, digits, 0+20,0, 19*(Curdigit-(Curdigit2*10)),0,19,21); Curdigit = hours; Curdigit2 = hours / 10; oapiBlt(surf, digits,0+39,0, 19*(Curdigit-(Curdigit2*10)),0,19,21); // Minute display on two digit Curdigit = minutes / 10; Curdigit2 = minutes / 100; oapiBlt(surf, digits,0+62,0, 19*(Curdigit-(Curdigit2*10)),0,19,21); Curdigit = minutes; Curdigit2 = minutes / 10; oapiBlt(surf, digits,0+81,0, 19*(Curdigit-(Curdigit2*10)),0,19,21); // second display on two digit Curdigit = seconds / 10; Curdigit2 = seconds / 100; oapiBlt(surf, digits,0+104,0, 19*(Curdigit-(Curdigit2*10)),0,19,21); Curdigit = seconds; Curdigit2 = seconds/10; oapiBlt(surf, digits,0+123,0, 19*(Curdigit-(Curdigit2*10)),0,19,21); }
void MissionTimer::Timestep(double simt, double deltat) { if (!IsPowered()) return; if (Running && Enabled && (CountUp != TIMER_COUNT_NONE)) { double t = GetTime(); if (CountUp) { t += deltat; } else { t -= deltat; } if (t < 0.0) t = 0.0; SetTime(t); } }
void LVIMU::Timestep(double simt) { double deltaTime, pulses; if (!Operate) { if (IsPowered()) TurnOn(); else return; } else if (!IsPowered()) { TurnOff(); return; } // // If we get here, we're powered up. // if (!TurnedOn) { return; } // fill OrbiterData VESSELSTATUS vs; OurVessel->GetStatus(vs); Orbiter.Attitude.X = vs.arot.x; Orbiter.Attitude.Y = vs.arot.y; Orbiter.Attitude.Z = vs.arot.z; // Vessel to Orbiter global transformation MATRIX3 tinv = getRotationMatrixZ(-vs.arot.z); tinv = mul(getRotationMatrixY(-vs.arot.y), tinv); tinv = mul(getRotationMatrixX(-vs.arot.x), tinv); if (!Initialized) { SetOrbiterAttitudeReference(); // Get current weight vector in vessel coordinates VECTOR3 w; OurVessel->GetWeightVector(w); // Transform to Orbiter global and calculate weight acceleration w = mul(tinv, w) / OurVessel->GetMass(); LastWeightAcceleration = w; OurVessel->GetGlobalVel(LastGlobalVel); LastTime = simt; Initialized = true; } else { deltaTime = (simt - LastTime); // Calculate accelerations VECTOR3 w, vel; OurVessel->GetWeightVector(w); // Transform to Orbiter global and calculate accelerations w = mul(tinv, w) / OurVessel->GetMass(); OurVessel->GetGlobalVel(vel); VECTOR3 dvel = (vel - LastGlobalVel) / deltaTime; // Measurements with the 2006-P1 version showed that the average of the weight // vector of this and the last step match the force vector while in free fall // The force vector matches the global velocity change of the last timestep exactly, // but isn't used because GetForceVector isn't working while docked VECTOR3 dw1 = w - dvel; VECTOR3 dw2 = LastWeightAcceleration - dvel; VECTOR3 accel = -(dw1 + dw2) / 2.0; LastWeightAcceleration = w; LastGlobalVel = vel; // orbiter earth rotation // imuState->Orbiter.Y = imuState->Orbiter.Y + (deltaTime * TwoPI / 86164.09); // sprintf(oapiDebugString(), "accel x %.10f y %.10f z %.10f DT %f", accel.x, accel.y, accel.z, deltaTime); // Process channel bits if (ZeroIMUCDUFlag) { ZeroIMUCDUs(); } else if (CoarseAlignEnableFlag) { SetOrbiterAttitudeReference(); } else if (Caged) { SetOrbiterAttitudeReference(); } else { // Gimbals MATRIX3 t = Orbiter.AttitudeReference; t = mul(getRotationMatrixX(Orbiter.Attitude.X), t); t = mul(getRotationMatrixY(Orbiter.Attitude.Y), t); t = mul(getRotationMatrixZ(Orbiter.Attitude.Z), t); t = mul(getOrbiterLocalToNavigationBaseTransformation(), t); // calculate the new gimbal angles VECTOR3 newAngles = getRotationAnglesXZY(t); // drive gimbals to new angles // CAUTION: gimbal angles are left-handed DriveGimbalX(-newAngles.x - Gimbal.X); DriveGimbalY(-newAngles.y - Gimbal.Y); DriveGimbalZ(-newAngles.z - Gimbal.Z); // PIPAs accel = tmul(Orbiter.AttitudeReference, accel); // sprintf(oapiDebugString(), "accel x %.10f y %.10f z %.10f DT %f", accel.x, accel.y, accel.z, deltaTime); // pulse PIPAs //pulses = RemainingPIPA.X + (accel.x * deltaTime / 0.0585); //PulsePIPA(LVRegPIPAX, (int) pulses); //RemainingPIPA.X = pulses - (int) pulses; //pulses = RemainingPIPA.Y + (accel.y * deltaTime / 0.0585); //PulsePIPA(LVRegPIPAY, (int) pulses); //RemainingPIPA.Y = pulses - (int) pulses; //pulses = RemainingPIPA.Z + (accel.z * deltaTime / 0.0585); //PulsePIPA(LVRegPIPAZ, (int) pulses); //RemainingPIPA.Z = pulses - (int) pulses; pulses = (accel.x * deltaTime); PulsePIPA(LVRegPIPAX, pulses); pulses = (accel.y * deltaTime); PulsePIPA(LVRegPIPAY, pulses); pulses = (accel.z * deltaTime); PulsePIPA(LVRegPIPAZ, pulses); } LastTime = simt; } }
//------------------------------------------------------------------------ void CVehicleMovementWarrior::Update(const float deltaTime) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); if(!IsCollapsing()) CVehicleMovementHovercraft::Update(deltaTime); else CVehicleMovementBase::Update(deltaTime); if(IsCollapsing()) { m_collapseTimer += deltaTime; // check platform Vec3 platformPos; if(m_pPlatformPos) platformPos = m_pPlatformPos->GetWorldSpaceTranslation(); else platformPos.zero(); float dist = platformPos.z - gEnv->p3DEngine->GetTerrainElevation(platformPos.x, platformPos.y); if(dist < 1.f) { m_platformDown = true; } // center turret RotatePart(m_pTurret, DEG2RAD(0.f), AXIS_Z, DEG2RAD(2.5f), deltaTime); // take down wing and cannon RotatePart(m_pWing, DEG2RAD(-12.5f), AXIS_X, DEG2RAD(3.f), deltaTime); RotatePart(m_pCannon, DEG2RAD(-20.f), AXIS_X, DEG2RAD(2.5f), deltaTime); if(!m_platformDown) { // handle legs to bring down platform TThrusters::iterator iter; for(iter=m_vecThrusters.begin(); iter!=m_vecThrusters.end(); ++iter) { SThruster *pThruster = *iter; if(pThruster->heightAdaption <= 0.f) { pThruster->hoverHeight = max(0.1f, pThruster->hoverHeight - 0.6f*deltaTime); continue; } else { //if (!pThruster->groundContact) //pThruster->hoverHeight = max(0.1f, pThruster->hoverHeight - 0.2f*deltaTime); } /* // special legs control float collapseSpeed = DEG2RAD(5.f); float maxDistMovable = 1.f/0.8f; float dist = (isneg(pThruster->prevDist)) ? 0.f : pThruster->hoverHeight - pThruster->prevDist; if (isneg(dist)) { collapseSpeed *= max(0.f, 1.f + maxDistMovable*dist); } if (collapseSpeed > 0.f) { float angle = RotatePart(pThruster->pParentPart, DEG2RAD(m_collapsedLegAngle), collapseSpeed, deltaTime); RotatePart(pThruster->pPart, DEG2RAD(m_collapsedFeetAngle), collapseSpeed, deltaTime); } */ } } else { if(!m_collapsed) { Collapsed(true); } } } if(IsPowered() && !IsCollapsed()) { // "normal" legs control here bool bStartComplete = (m_startComplete > 1.5f); float adaptionSpeed = IsCollapsing() ? 0.8f : 1.5f; int t = 0; for(TThrusters::iterator iter=m_vecThrusters.begin(); iter!=m_vecThrusters.end(); ++iter) { SThruster *pThruster = *iter; ++t; if(pThruster->heightAdaption > 0.f && bStartComplete && pThruster->pPart && pThruster->pParentPart) { const char *footName = pThruster->pPart->GetName(); EWarriorMovement mode = eWM_Hovering; float correction = 0.f, maxCorrection = 0.f; // adjust legs float error = 0.f; if(!pThruster->hit) error = pThruster->hoverHeight; // when not hit, correct downwards else if(pThruster->prevDist > 0.f) error = pThruster->prevDist - pThruster->hoverHeight; if(mode != eWM_None && abs(error) > 0.05f) { float speed = max(0.1f, min(1.f, abs(error))) * adaptionSpeed; correction = -sgn(error) * min(speed*deltaTime, abs(error)); // correct up to error // don't correct more than heightAdaption allows maxCorrection = abs((pThruster->heightInitial + sgn(correction)*pThruster->heightAdaption) - pThruster->pos.z); float minCorrection = (pThruster->groundContact) ? 0.f : -maxCorrection; correction = CLAMP(correction, minCorrection, maxCorrection); if(abs(correction) > 0.0001f) { // positive correction for leg, negative for foot Matrix34 legLocal = pThruster->pParentPart->GetLocalBaseTM(); Matrix34 footLocal = pThruster->pPart->GetLocalBaseTM(); float radius = footLocal.GetTranslation().len(); float deltaAngle = correction / radius; // this assumes correction on circle (accurate enough for large radius) Matrix34 legTM = Matrix33(legLocal) * Matrix33::CreateRotationX(deltaAngle); Matrix34 footTM = Matrix33(footLocal) * Matrix33::CreateRotationX(-deltaAngle); legTM.SetTranslation(legLocal.GetTranslation()); footTM.SetTranslation(footLocal.GetTranslation()); pThruster->pParentPart->SetLocalBaseTM(legTM); pThruster->pPart->SetLocalBaseTM(footTM); } } if(IsProfilingMovement()) { static ICVar *pDebugLeg = gEnv->pConsole->GetCVar("warrior_debug_leg"); if(pDebugLeg && pDebugLeg->GetIVal() == t) { //CryLog("hoverErr %.2f, levelErr %.2f, neutralErr %.2f -> %s corr %.3f (max %.2f)", hoverError, levelError, neutralError, sMode, correction, maxCorrection); } } } } } // regain control if(m_collapseTimer > m_recoverTime) { Collapsed(false); } for(TThrusters::iterator it=m_vecThrusters.begin(); it!=m_vecThrusters.end(); ++it) { (*it)->groundContact = false; } }
void DockingProbe::TimeStep(double simt, double simdt) { if (!FirstTimeStepDone) { DoFirstTimeStep(); FirstTimeStepDone = true; return; } if (UndockNextTimestep) { UpdatePort(Dockparam[1] * 0.5, simdt); OurVessel->Undock(ourPort); UndockNextTimestep = false; } if (ExtendingRetracting > 0) { if (Status >= DOCKINGPROBE_STATUS_EXTENDED) { Status = DOCKINGPROBE_STATUS_EXTENDED; ExtendingRetracting = 0; Dockproc = DOCKINGPROBE_PROC_UNDOCKED; OurVessel->Undocking(ourPort); OurVessel->SetDockingProbeMesh(); } else { Status += 0.33 * simdt; } } else if (ExtendingRetracting < 0) { if (Status <= DOCKINGPROBE_STATUS_RETRACTED) { Status = DOCKINGPROBE_STATUS_RETRACTED; ExtendingRetracting = 0; OurVessel->HaveHardDocked(ourPort); OurVessel->SetDockingProbeMesh(); } else { Status -= 0.33 * simdt; } } if (Dockproc == DOCKINGPROBE_PROC_SOFTDOCKED) { UpdatePort(Dockparam[1] * 0.5, simdt); Dockproc = DOCKINGPROBE_PROC_HARDDOCKED; } else if (Dockproc == DOCKINGPROBE_PROC_HARDDOCKED) { if (Status > DOCKINGPROBE_STATUS_RETRACTED) { UpdatePort(Dockparam[1] * 0.5 * Status / 0.9, simdt); } else { UpdatePort(_V(0,0,0), simdt); Dockproc = DOCKINGPROBE_PROC_UNDOCKED; } } // sprintf(oapiDebugString(), "Docked %d Status %.3f Dockproc %d ExtendingRetracting %d", (Docked ? 1 : 0), Status, Dockproc, ExtendingRetracting); // Switching logic if (OurVessel->DockingProbeExtdRelSwitch.IsUp() && IsPowered()) { Extend(); } else if (OurVessel->DockingProbeExtdRelSwitch.IsDown()) { if ((!OurVessel->DockingProbeRetractPrimSwitch.IsCenter() && OurVessel->DockProbeMnACircuitBraker.IsPowered() && OurVessel->PyroBusA.Voltage() > SP_MIN_DCVOLTAGE) || (!OurVessel->DockingProbeRetractSecSwitch.IsCenter() && OurVessel->DockProbeMnBCircuitBraker.IsPowered() && OurVessel->PyroBusB.Voltage() > SP_MIN_DCVOLTAGE)) { int ActiveCharges = 0; if (OurVessel->DockingProbeRetractPrimSwitch.IsUp()) ActiveCharges = ActiveCharges | DOCKINGPROBE_CHARGE_PRIM1; if (OurVessel->DockingProbeRetractPrimSwitch.IsDown()) ActiveCharges = ActiveCharges | DOCKINGPROBE_CHARGE_PRIM2; if (OurVessel->DockingProbeRetractSecSwitch.IsUp()) ActiveCharges = ActiveCharges | DOCKINGPROBE_CHARGE_SEC1; if (OurVessel->DockingProbeRetractSecSwitch.IsDown()) ActiveCharges = ActiveCharges | DOCKINGPROBE_CHARGE_SEC2; if ((ActiveCharges & RetractChargesUsed)!= ActiveCharges) Retract(); RetractChargesUsed = RetractChargesUsed | ActiveCharges; // sprintf(oapiDebugString(), "Charge Used: P1%d P2%d S1%d S2%d", RetractChargesUsed & DOCKINGPROBE_CHARGE_PRIM1 , RetractChargesUsed & DOCKINGPROBE_CHARGE_PRIM2 , RetractChargesUsed & DOCKINGPROBE_CHARGE_SEC1 , RetractChargesUsed & DOCKINGPROBE_CHARGE_SEC2); } } /// /// Begin Advanced Docking Code /// if (DockingMethod > ADVANCED){ // Code that follows is largely lifted from Atlantis... // Goal is to handle close proximity docking between a probe and drogue VECTOR3 gdrgPos, gdrgDir, gprbPos, gprbDir, gvslPos, rvel, pos, dir, rot; OurVessel->Local2Global (Dockparam[0],gprbPos); //converts probe location to global OurVessel->GlobalRot (Dockparam[1],gprbDir); //rotates probe direction to global // Search the complete vessel list for a grappling candidate. // Not very scalable ... for (DWORD i = 0; i < oapiGetVesselCount(); i++) { OBJHANDLE hV = oapiGetVesselByIndex (i); if (hV == OurVessel->GetHandle()) continue; // we don't want to grapple ourselves ... oapiGetGlobalPos (hV, &gvslPos); if (dist (gvslPos, gprbPos) < oapiGetSize (hV)) { // in range VESSEL *v = oapiGetVesselInterface (hV); DWORD nAttach = v->AttachmentCount (true); for (DWORD j = 0; j < nAttach; j++) { // now scan all attachment points of the candidate ATTACHMENTHANDLE hAtt = v->GetAttachmentHandle (true, j); const char *id = v->GetAttachmentId (hAtt); if (strncmp (id, "PADROGUE", 8)) continue; // attachment point not compatible v->GetAttachmentParams (hAtt, pos, dir, rot); v->Local2Global (pos, gdrgPos); // converts found drogue position to global v->GlobalRot (dir, gdrgDir); // rotates found drogue direction to global if (dist (gdrgPos, gprbPos) < COLLISION_DETECT_RANGE && DockingMethod == ADVANCEDPHYSICS) { // found one less than a meter away! // Detect if collision has happend, if so, t will return intersection point along the probe line X(t) = gprbPos + t * gprbDir double t = CollisionDetection(gprbPos, gprbDir, gdrgPos, gdrgDir); // Calculate time of penetration according to current velocity OurVessel->GetRelativeVel(hV, rvel); // Determine resultant force //APPLY rforce to DockingProbe Vessel, and APPLY -rforce to Drogue Vessel return; } if (dist(gdrgPos, gprbPos) < CAPTURE_DETECT_RANGE && DockingMethod > ADVANCED) { // If we're within capture range, set docking port to attachment so docking can take place // Originally, I would have used the Attachment features to soft dock and move the LM during retract // but Artlav's docking method does this better and uses the docking port itself. // Attachment is being used as a placeholder for the docking port and to identify its orientation. OurVessel->GetAttachmentParams(hattPROBE, pos, dir, rot); DOCKHANDLE dock = OurVessel->GetDockHandle(ourPort); OurVessel->SetDockParams(dock, pos, dir, rot); } }//for nAttach }//if inRange }//for nVessel } }
bool IsPassive() const { return IsPowered() || speed < fixed(4); }