Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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();
}
Esempio n. 6
0
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;
}
Esempio n. 9
0
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;
	}
}
Esempio n. 10
0
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;
	}
}
Esempio n. 11
0
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;
	}
}
Esempio n. 12
0
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);
}
Esempio n. 13
0
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);
	}
}
Esempio n. 14
0
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;
	}
}
Esempio n. 16
0
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
	}
}
Esempio n. 17
0
 bool IsPassive() const {
   return IsPowered() || speed < fixed(4);
 }