//------------------------------------------------------------------------
void CVehicleMovementHelicopter::Update(const float deltaTime)
{
  FUNCTION_PROFILER( GetISystem(), PROFILE_GAME );

	CVehicleMovementBase::Update(deltaTime);

	UpdateDamages(deltaTime);
	UpdateEngine(deltaTime);

	{
		CryAutoCriticalSection lk(m_lock);
		m_netActionSync.Read(this);
		if (gEnv->bServer)
		{
			m_sendTimer -= deltaTime;
			if (m_sendTimer<=0.f)
			{
				m_netActionSync.Write(this);
				CHANGED_NETWORK_STATE(m_pVehicle, m_updateAspects);
				m_sendTimer = m_sendTime;
			}
		}
	}
			
	SetSoundParam(eSID_Run, "rpm_scale", m_rpmScale);

	// update animation
	if(m_isEngineGoingOff)
	{
		if(m_enginePower > 0.0f)
		{
			UpdateEngine(deltaTime);
		}
		else
		{
			m_enginePower = 0.0f;
		}
	}

	SetAnimationSpeed(eVMA_Engine, (m_enginePower / m_enginePowerMax));
}
//////////////////////////////////////////////////////////////////////////
// NOTE: This function must be thread-safe. Before adding stuff contact MarcoC.
void CVehicleMovementHelicopter::ProcessMovement(const float deltaTime)
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

	IPhysicalEntity *pPhysics = GetPhysics();
	assert(pPhysics);

	m_netActionSync.UpdateObject(this);

	CryAutoCriticalSection lk(m_lock);

	Vec3 &impulse = m_control.impulse;
	Vec3 &angImpulse = m_control.angImpulse;

	impulse.zero();
	angImpulse.zero();

	m_actionPitch = m_actionRoll = m_actionYaw = m_hoveringPower = 0.0f;

	if(!m_isEnginePowered)
		return;

	// This results in either ProcessActions or ProcessAI getting called
	CVehicleMovementBase::ProcessMovement(deltaTime);

	const Matrix33 tm(m_PhysPos.q);
	Ang3 angles = Ang3::GetAnglesXYZ(tm);

	m_currentFwdDir		= tm * Vec3(0.0f, 1.0f , 0.0f);
	m_currentLeftDir	= tm * Vec3(-1.0f, 0.0f, 0.0f);
	m_currentUpDir		= tm * Vec3(0.0f, 0.0f , 1.0f);

	m_mass				= m_PhysDyn.mass;
	Vec3 &velocity		= m_PhysDyn.v;
	Vec3 &angVelocity	= m_PhysDyn.w;

	/*	float gravity;

	pe_simulation_params paramsSim;
	if (pPhysics->GetParams(&paramsSim))
	gravity = abs(paramsSim.gravity.z);
	else
	gravity = 9.8f;
	*/
	UpdateDamages(deltaTime);
	UpdateEngine(deltaTime);
	PreProcessMovement(deltaTime);

	m_control.iSource = 3;
	m_control.iApplyTime = 0;

	if(!m_controlDamages.impulse.IsZero() || !m_controlDamages.angImpulse.IsZero())
	{
		m_controlDamages.iSource = 3;
		m_controlDamages.iApplyTime = 0;

		pPhysics->Action(&m_controlDamages,1);
	}

	if(abs(angles.x) < 0.01f)
		angles.x = 0.0f;

	if(abs(angles.y) < 0.01f)
		angles.y = 0.0f;

	float turbulenceMult = 1.0f - min(m_turbulenceMultMax, m_turbulence);

	Vec3 engineImpulse;
	engineImpulse  = m_workingUpDir * m_engineForce * m_hoveringPower;

	impulse += (engineImpulse - (velocity * m_velDamp * turbulenceMult));
	impulse *= deltaTime * m_mass;

	angImpulse += -m_currentLeftDir * m_actionPitch * m_pitchResponsiveness;
	angImpulse += m_currentFwdDir * m_actionRoll * m_rollResponsiveness;
	angImpulse += m_currentUpDir * m_actionYaw * m_yawResponsiveness;
	angImpulse += m_currentUpDir * m_steeringDamage * m_yawResponsiveness * 0.5f;
	angImpulse *= m_mass * deltaTime;

	angImpulse -= (angVelocity - m_controlDamages.angImpulse) * m_mass * m_rotationDamping * deltaTime;

	float powerScale = GetEnginePower();
	impulse *= powerScale;
	angImpulse *= powerScale;

	// apply the action
	pPhysics->Action(&m_control, 1);

	m_turbulence -= m_turbulence * deltaTime;

	if(m_turbulence < 0.01)
		m_turbulence = 0.0f;
}
//------------------------------------------------------------------------
void CVehicleMovementHelicopter::Update(const float deltaTime)
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

	CVehicleMovementBase::Update(deltaTime);

	CryAutoCriticalSection lk(m_lock);

	if(m_isTouchingGround)
	{
		m_timeOnTheGround += deltaTime;
		m_isTouchingGround = false;
	}
	else
	{
		m_timeOnTheGround = 0.0f;
	}

	// ai specific sound matter

	if(m_soundMasterVolume != m_vehicleVolume)
	{
		float vol = m_soundMasterVolume;

		if(m_vehicleVolume == 0)
			CVehicleMovementBase::SetSoundMasterVolume(m_vehicleVolume);
		else if(vol < m_vehicleVolume)
		{
			vol +=deltaTime;

			if(vol > m_vehicleVolume)
				vol = m_vehicleVolume;

			CVehicleMovementBase::SetSoundMasterVolume(vol);
		}
		else if(vol > m_vehicleVolume)
		{
			vol -=deltaTime;

			if(vol < m_vehicleVolume)
				vol = m_vehicleVolume;

			CVehicleMovementBase::SetSoundMasterVolume(vol);
		}
	}

	// update animation

	if(m_isEngineGoingOff)
	{
		if(m_enginePower > 0.0f)
		{
			UpdateEngine(deltaTime);
		}
		else
		{
			m_enginePower = 0.0f;
		}
	}

	SetAnimationSpeed(eVMA_Engine, (m_enginePower / m_enginePowerMax));

#if ENABLE_VEHICLE_DEBUG
	IActor *pActor = m_pActorSystem->GetActor(m_actorId);

	int profile = g_pGameCVars->v_profileMovement;

	if((profile == 1 && pActor && pActor->IsClient()) || profile == 2)
	{
		IRenderer *pRenderer = gEnv->pRenderer;
		float color[4] = {1,1,1,1};

		Ang3 localAngles = m_pEntity->GetWorldAngles();

		m_mass = m_statusDyn.mass;
		Vec3 &velocity = m_statusDyn.v;
		Vec3 &angVelocity = m_statusDyn.w;

		pRenderer->Draw2dLabel(5.0f,   0.0f, 2.0f, color, false, "Helicopter movement");
		Vec3 i;
		i = m_control.impulse.GetNormalizedSafe();
		pRenderer->Draw2dLabel(5.0f,  85.0f, 1.5f, color, false, "impulse: %f, %f, %f (%f, %f, %f)", m_control.impulse.x, m_control.impulse.y, m_control.impulse.z, i.x, i.y, i.z);
		pRenderer->Draw2dLabel(5.0f, 100.0f, 1.5f, color, false, "angImpulse: %f, %f, %f", m_control.angImpulse.x, m_control.angImpulse.y, m_control.angImpulse.z);
		i = velocity.GetNormalizedSafe();
		pRenderer->Draw2dLabel(5.0f, 115.0f, 1.5f, color, false, "velocity: %f, %f, %f (%f) (%f, %f, %f)", velocity.x, velocity.y, velocity.z, velocity.GetLength(), i.x, i.y, i.z);
		pRenderer->Draw2dLabel(5.0f, 130.0f, 1.5f, color, false, "angular velocity: %f, %f, %f", RAD2DEG(angVelocity.x), RAD2DEG(angVelocity.y), RAD2DEG(angVelocity.z));
		pRenderer->Draw2dLabel(5.0f, 160.0f, 1.5f, color, false, "angles: %f, %f, %f (%f, %f, %f)", RAD2DEG(localAngles.x), localAngles.y, localAngles.z, RAD2DEG(localAngles.x), RAD2DEG(localAngles.y), RAD2DEG(localAngles.z));
		pRenderer->Draw2dLabel(5.0f, 175.0f, 1.5f, color, false, "m_rpmScale: %f, damage: %f, damageActual: %f, turbulence: %f", m_rpmScale, m_damage, m_damageActual, m_turbulence);
		pRenderer->Draw2dLabel(5.0f, 190.0f, 1.5f, color, false, "m_turnAction: %f, actionYaw: %f, targetRotation: %f, %f, %f", m_turnAction, m_actionYaw, RAD2DEG(m_rotateTarget.x), RAD2DEG(m_rotateTarget.y), RAD2DEG(m_rotateTarget.z));
		pRenderer->Draw2dLabel(5.0f, 220.0f, 1.5f, color, false, "lift: %f, engineForce: %f, hoveringPower: %f, desiredHeight: %f, boost: %d, fwdAction: %f", m_liftAction, m_engineForce, m_hoveringPower, m_desiredHeight, Boosting(), m_forwardAction);
		pRenderer->Draw2dLabel(5.0f, 235.0f, 1.5f, color, false, "pitchAction:  %f, rollAction:  %f", m_actionPitch, m_actionRoll);
		pRenderer->Draw2dLabel(5.0f, 250.0f, 1.5f, color, false, "desiredPitch: %f, desiredRoll: %f", m_desiredPitch, m_desiredRoll);

		Vec3 direction = m_pEntity->GetWorldTM().GetColumn(1);
		pRenderer->Draw2dLabel(5.0f, 270.0f, 1.5f, color, false, "fwd direction: %.2f, %.2f, %.2f", direction.x, direction.y, direction.z);
		pRenderer->Draw2dLabel(5.0f, 285.0f, 1.5f, color, false, "workingUpDir:  %.2f, %.2f, %.2f", m_workingUpDir.x, m_workingUpDir.y, m_workingUpDir.z);
		pRenderer->Draw2dLabel(5.0f, 300.0f, 1.5f, color, false, "accel:  %f", m_playerAcceleration);
	}

#endif
}
//------------------------------------------------------------------------
void CVehicleMovementHelicopter::ProcessActions(const float deltaTime)
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

	UpdateDamages(deltaTime);
	UpdateEngine(deltaTime);

	m_velDamp = 0.0f;

	m_playerControls.ProcessActions(deltaTime);

	Limit(m_forwardAction, -1.0f, 1.0f);
	Limit(m_strafeAction, -1.0f, 1.0f);

	m_actionYaw = 0.0f;

	Matrix33 tm(m_PhysPos.q);
	Ang3 angles = Ang3::GetAnglesXYZ(tm);
	Vec3 worldPos =  m_PhysPos.pos;

	// +ve pitch means nose up
	const float &currentPitch = angles.x;
	// +ve roll means to the left
	const float &currentRoll = angles.y;
	// +ve direction mean rotation anti-clockwise about the z axis - 0 means along y
	float currentDir = angles.z;

	float pitchDeg = RAD2DEG(currentPitch);

	if(m_maxPitchAngleMov != 0.0f && pitchDeg >= (m_maxPitchAngleMov * 0.5f))
	{
		float mult = pitchDeg / (m_maxPitchAngleMov);

		if(mult > 1.0f && m_desiredPitch < 0.0f)
		{
			m_desiredPitch *= 0.0f;
			m_actionPitch *= 0.0f;
			m_desiredPitch += 0.5f * mult;
		}
		else if(m_desiredPitch < 0.0f)
		{
			m_desiredPitch *= (1.0f - mult);
			m_desiredPitch += 0.05f;
		}
	}
	else if(m_maxPitchAngleMov != 0.0f && pitchDeg <= (-m_maxPitchAngleMov * 0.5f))
	{
		float mult = abs(pitchDeg) / (m_maxPitchAngleMov);

		if(mult > 1.0f && m_desiredPitch > 0.0f)
		{
			m_desiredPitch *= 0.0f;
			m_actionPitch *= 0.0f;
			m_desiredPitch += 0.5f * mult;
		}
		else if(m_desiredPitch > 0.0f)
		{
			m_desiredPitch *= (1.0f - mult);
			m_desiredPitch -= 0.05f;
		}
	}

	if(m_pInvertPitchVar->GetIVal() == 0)
		m_desiredPitch *= -1.0f;

	Vec3 currentVel = m_PhysDyn.v;
	Vec3 currentVel2D = currentVel;
	currentVel2D.z = 0.0f;

	if(currentRoll >= DEG2RAD(m_maxRollAngle * 0.5f) && m_desiredRoll > 0.001f)
	{
		float r = currentRoll / DEG2RAD(m_maxRollAngle);
		r = min(1.0f, r * 1.0f);
		r = 1.0f - r;
		m_desiredRoll *= r;
		m_desiredRoll = min(1.0f, m_desiredRoll);
	}
	else if(currentRoll <= DEG2RAD(-m_maxRollAngle * 0.5f) && m_desiredRoll < 0.001f)
	{
		float r = abs(currentRoll) / DEG2RAD(m_maxRollAngle);
		r = min(1.0f, r * 1.0f);
		r = 1.0f - r;
		m_desiredRoll *= r;
		m_desiredRoll = max(-1.0f, m_desiredRoll);
	}

	Vec3 currentFwdDir2D = m_currentFwdDir;
	currentFwdDir2D.z = 0.0f;
	currentFwdDir2D.NormalizeSafe();

	Vec3 currentLeftDir2D(-currentFwdDir2D.y, currentFwdDir2D.x, 0.0f);

	currentVel2D.z = 0.0f;

	float currentHeight = worldPos.z;
	float currentFwdSpeed = currentVel.Dot(currentFwdDir2D);

	ProcessActions_AdjustActions(deltaTime);

	float inputMult = m_basicSpeedFraction;

	// desired things
	float turnDecreaseScale = m_yawDecreaseWithSpeed / (m_yawDecreaseWithSpeed + fabs(currentFwdSpeed));

	Vec3 desired_vel2D =
		currentFwdDir2D * m_forwardAction * m_maxFwdSpeed * inputMult +
		currentLeftDir2D * m_strafeAction * m_maxLeftSpeed * inputMult;

	// calculate the angle changes

	Vec3 desiredVelChange2D = desired_vel2D - currentVel2D;

	float desiredTiltAngle = m_tiltPerVelDifference * desiredVelChange2D.GetLength();
	Limit(desiredTiltAngle, -m_maxTiltAngle, m_maxTiltAngle);

	float goal = abs(m_desiredPitch) + abs(m_desiredRoll);
	goal *= 1.5f;
	Interpolate(m_playerAcceleration, goal, 0.25f, deltaTime);
	Limit(m_playerAcceleration, 0.0f, 5.0f);

	if(!iszero(m_desiredPitch))
	{
		m_actionPitch -= m_desiredPitch * m_pitchInputConst;
		Limit(m_actionPitch, -m_maxYawRate, m_maxYawRate);
	}

	m_actionRoll += m_pitchActionPerTilt * m_desiredRoll * (m_playerAcceleration + 1.0f);
	Limit(m_actionRoll, -10.0f, 10.0f);
	Limit(m_actionPitch, -10.0f, 10.0f);

	float relaxRollTolerance = 0.0f;

	if(!iszero(m_turnAction) || abs(m_PhysDyn.w.z) > DEG2RAD(10.0f))
	{
		m_actionYaw += -m_turnAction * m_yawInputConst * GetDamageMult();

		float side = 0.0f;

		if(abs(m_turnAction) > 0.01f)
			side = min(1.0f, max(-1.0f, m_turnAction));

		float roll = DEG2RAD(m_extraRollForTurn * side) - (currentRoll);
		m_actionRoll += max(0.0f, abs(roll)) * side * m_rollForTurnForce;

		float pitchComp = abs(currentPitch) / DEG2RAD(2.50f);

		if(pitchComp > 1.0f)
			roll *= pitchComp;

		roll *= max(1.0f, abs(m_PhysDyn.w.z));

		m_actionRoll += roll;

		Limit(m_actionYaw, -m_maxYawRate, m_maxYawRate);
	}

	m_desiredDir = currentDir;
	m_lastDir = currentDir;

	float boost = Boosting() ? m_boostMult : 1.0f;

	if(m_pAltitudeLimitVar)
	{
		float altitudeLimit = m_pAltitudeLimitVar->GetFVal();

		if(!iszero(altitudeLimit))
		{
			float altitudeLowerOffset;

			if(m_pAltitudeLimitLowerOffsetVar)
			{
				float r = 1.0f - min(1.0f, max(0.0f, m_pAltitudeLimitLowerOffsetVar->GetFVal()));
				altitudeLowerOffset = r * altitudeLimit;
			}
			else
				altitudeLowerOffset = altitudeLimit;

			float mult = 1.0f;

			if(currentHeight >= altitudeLimit)
			{
				if(m_liftAction > 0.f)
				{
					mult = 0.0f;
				}
			}
			else if(currentHeight >= altitudeLowerOffset)
			{
				float zone = altitudeLimit - altitudeLowerOffset;
				mult = (altitudeLimit - currentHeight) / (zone);
			}

			m_liftAction *= mult;

			if(currentPitch > DEG2RAD(0.0f))
			{
				if(m_forwardAction > 0.0f)
					m_forwardAction *= mult;

				if(m_actionPitch > 0.0f)
				{
					m_actionPitch *= mult;
					m_actionPitch += -currentPitch;
				}
			}

			m_desiredHeight = min(altitudeLowerOffset, currentHeight);
		}
	}
	else
	{
		m_desiredHeight = currentHeight;
	}

	ProcessActionsLift(deltaTime);

	if(m_pStabilizeVTOL)
	{
		float stabilizeTime = m_pStabilizeVTOL->GetFVal();

		if(stabilizeTime > 0.0f)
		{
			if(m_relaxTimer < 6.0f)
				m_relaxTimer += deltaTime;
			else
			{
				float r = currentRoll - relaxRollTolerance;
				r = min(1.0f, max(-1.0f, r));

				m_actionRoll += -r * m_relaxForce * (m_relaxTimer / 6.0f);
			}
		}
	}

	if(m_netActionSync.PublishActions(CNetworkMovementHelicopter(this)))
		CHANGED_NETWORK_STATE(m_pVehicle, eEA_GameClientDynamic);
}
Пример #5
0
void CPatchPageDlg::OnChangedDurationCombo(UINT nID, NMHDR* pNMHDR, LRESULT* pResult)
{
	UpdateEngine(nID);
	*pResult = 0;
}
//------------------------------------------------------------------------
void CVehicleMovementVTOL::ProcessActions(const float deltaTime)
{
	FUNCTION_PROFILER( GetISystem(), PROFILE_GAME );

	UpdateDamages(deltaTime);
	UpdateEngine(deltaTime);

	m_velDamp = 0.25f;

	m_playerControls.ProcessActions(deltaTime);

	Limit(m_forwardAction, -1.0f, 1.0f);
	Limit(m_strafeAction, -1.0f, 1.0f);

	m_actionYaw = 0.0f;

	Vec3 worldPos = m_pEntity->GetWorldPos();

	IPhysicalEntity* pPhysics = GetPhysics();

	// get the current state

	// roll pitch + yaw

	Matrix34 worldTM = m_pRotorPart ? m_pRotorPart->GetWorldTM() : m_pEntity->GetWorldTM();
//	if (m_pRotorPart)
//		worldTM = m_pRotorPart->GetWorldTM();
//	else
//		worldTM = m_pEntity->GetWorldTM();

	Vec3 specialPos = worldTM.GetTranslation();
	Ang3 angles = Ang3::GetAnglesXYZ(Matrix33(worldTM));

	Matrix33 tm;
	tm.SetRotationXYZ((angles));

	// +ve pitch means nose up
	const float& currentPitch = angles.x;
	// +ve roll means to the left
	const float& currentRoll = angles.y;
	// +ve direction mean rotation anti-clockwise about the z axis - 0 means along y
	float currentDir = angles.z;

	const float maxPitchAngle = 60.0f;
	
	float pitchDeg = RAD2DEG(currentPitch);
	if (pitchDeg >= (maxPitchAngle * 0.75f))
	{
		float mult = pitchDeg / (maxPitchAngle);
		
		if (mult > 1.0f && m_desiredPitch < 0.0f)
		{
			m_desiredPitch *= 0.0f;
			m_actionPitch *= 0.0f;
			m_desiredPitch += 0.2f * mult;
		}
		else if (m_desiredPitch < 0.0f)
		{
			m_desiredPitch *= (1.0f - mult);
			m_desiredPitch += 0.05f;
		}
	}
	else if (pitchDeg <= (-maxPitchAngle * 0.75f))
	{
		float mult = abs(pitchDeg) / (maxPitchAngle);

		if (mult > 1.0f && m_desiredPitch > 0.0f)
		{
			m_desiredPitch *= 0.0f;
			m_actionPitch *= 0.0f;
			m_desiredPitch += 0.2f * mult;
		}
		else if (m_desiredPitch > 0.0f)
		{
			m_desiredPitch *= (1.0f - mult);
			m_desiredPitch -= 0.05f;
		}
	}

	if (currentRoll >= DEG2RAD(m_maxRollAngle * 0.7f) && m_desiredRoll > 0.001f)
	{
		float r = currentRoll / DEG2RAD(m_maxRollAngle);
		r = min(1.0f, r * 1.0f);
		r = 1.0f - r;
		m_desiredRoll *= r;
		m_desiredRoll = min(1.0f, m_desiredRoll);
	}
	else if (currentRoll <= DEG2RAD(-m_maxRollAngle * 0.7f) && m_desiredRoll < 0.001f)
	{
		float r = abs(currentRoll) / DEG2RAD(m_maxRollAngle);
		r = min(1.0f, r * 1.0f);
		r = 1.0f - r;
		m_desiredRoll *= r;
		m_desiredRoll = max(-1.0f, m_desiredRoll);
	}

	Vec3 currentFwdDir2D = m_currentFwdDir;
	currentFwdDir2D.z = 0.0f;
	currentFwdDir2D.NormalizeSafe();

	Vec3 currentLeftDir2D(-currentFwdDir2D.y, currentFwdDir2D.x, 0.0f);

	Vec3 currentVel = m_PhysDyn.v;
	Vec3 currentVel2D = currentVel;
	currentVel2D.z = 0.0f;

	float currentHeight = worldPos.z;
	float currentFwdSpeed = currentVel.Dot(currentFwdDir2D);

	ProcessActions_AdjustActions(deltaTime);

	float inputMult = m_basicSpeedFraction;

	// desired things
	float turnDecreaseScale = m_yawDecreaseWithSpeed / (m_yawDecreaseWithSpeed + fabs(currentFwdSpeed));

	Vec3 desired_vel2D = 
		currentFwdDir2D * m_forwardAction * m_maxFwdSpeed * inputMult + 
		currentLeftDir2D * m_strafeAction * m_maxLeftSpeed * inputMult;

	// calculate the angle changes

	Vec3 desiredVelChange2D = desired_vel2D - currentVel2D;

	float desiredTiltAngle = m_tiltPerVelDifference * desiredVelChange2D.GetLength();
	Limit(desiredTiltAngle, -m_maxTiltAngle, m_maxTiltAngle);

	float goal = abs(m_desiredPitch) + abs(m_desiredRoll);
	goal *= 1.5f;
	Interpolate(m_playerAcceleration, goal, 0.25f, deltaTime);
	Limit(m_playerAcceleration, 0.0f, 5.0f);

	//static float g_angleLift = 4.0f;

	if (abs(m_liftAction) > 0.001f && abs(m_forwardAction) < 0.001)
	{
//		float pitch = RAD2DEG(currentPitch);

		if (m_liftPitchAngle < 0.0f && m_liftAction > 0.0f)
			m_liftPitchAngle = 0.0f;
		else if (m_liftPitchAngle > 0.0f && m_liftAction < 0.0f)
			m_liftPitchAngle = 0.0f;

		Interpolate(m_liftPitchAngle, 1.25f * m_liftAction, 0.75f, deltaTime);

		if (m_liftPitchAngle < 1.0f && m_liftPitchAngle > -1.0f)
			m_desiredPitch += 0.05f * m_liftAction;
	}
	else if (m_liftAction < 0.001f && abs(m_liftPitchAngle) > 0.001)
	{
		Interpolate(m_liftPitchAngle, 0.0f, 1.0f, deltaTime);
		m_desiredPitch += 0.05f * -m_liftPitchAngle;
	}

	/* todo
	else if (m_liftAction < -0.001f)
	{
		m_desiredPitch += min(0.0f, (DEG2RAD(-5.0f) - currentPitch)) * 0.5f * m_liftAction;
	}*/

	if (!iszero(m_desiredPitch))
	{
		m_actionPitch -= m_desiredPitch * m_pitchInputConst;
		Limit(m_actionPitch, -m_maxYawRate, m_maxYawRate);
	}

	float rollAccel = 1.0f;
	if (abs(currentRoll + m_desiredRoll) < abs(currentRoll))
		rollAccel *= 1.25f;

	m_actionRoll += m_pitchActionPerTilt * m_desiredRoll * rollAccel * (m_playerAcceleration + 1.0f);
	Limit(m_actionRoll, -10.0f, 10.0f);
	Limit(m_actionPitch, -10.0f, 10.0f);

	// roll as we turn
	if (!m_strafeAction)
	{
		m_actionYaw += m_yawPerRoll * currentRoll;
	}

	if (abs(m_strafeAction) > 0.001f)
	{
		float side = 0.0f;
		side = min(1.0f, max(-1.0f, m_strafeAction));

		float roll = DEG2RAD(m_extraRollForTurn * 0.25f * side) - (currentRoll);
		m_actionRoll += max(0.0f, abs(roll)) * side * 1.0f;
	}

	float relaxRollTolerance = 0.0f;

	if (abs(m_turnAction) > 0.01f || abs(m_PhysDyn.w.z) > DEG2RAD(3.0f))
	{
		m_actionYaw += -m_turnAction * m_yawInputConst * GetDamageMult();

		float side = 0.0f;
		if (abs(m_turnAction) > 0.01f)
			side = min(1.0f, max(-1.0f, m_turnAction));

		float roll = DEG2RAD(m_extraRollForTurn * side) - (currentRoll);
		m_actionRoll += max(0.0f, abs(roll)) * side * m_rollForTurnForce;

		roll *= max(1.0f, abs(m_PhysDyn.w.z));

		m_actionRoll += roll;

		Limit(m_actionYaw, -m_maxYawRate, m_maxYawRate);
	}

	m_desiredDir = currentDir;
	m_lastDir = currentDir;

	float boost = Boosting() ? m_boostMult : 1.0f;
	float liftActionMax = 1.0f;

	if (m_pAltitudeLimitVar)
	{
		float altitudeLimit = m_pAltitudeLimitVar->GetFVal();

		if (!iszero(altitudeLimit))
		{
			float altitudeLowerOffset;

			if (m_pAltitudeLimitLowerOffsetVar)
			{
				float r = 1.0f - min(1.0f, max(0.0f, m_pAltitudeLimitLowerOffsetVar->GetFVal()));
				altitudeLowerOffset = r * altitudeLimit;
			}
			else
				altitudeLowerOffset = altitudeLimit;

			float mult = 1.0f;

			if (currentHeight >= altitudeLimit)
			{
				if (m_liftAction > 0.f)
				{
					mult = 0.0f;
				}
			}
			else if (currentHeight >= altitudeLowerOffset)
			{
				float zone = altitudeLimit - altitudeLowerOffset;
				mult = (altitudeLimit - currentHeight) / (zone);
			}

			m_liftAction *= mult;

			if (currentPitch > DEG2RAD(0.0f))
			{
				if (m_forwardAction > 0.0f)
					m_forwardAction *= mult;

				if (m_actionPitch > 0.0f)
				{
					m_actionPitch *= mult;
					m_actionPitch += -currentPitch;
				}
			}

			m_desiredHeight = min(altitudeLowerOffset, currentHeight);
		}
	}
	else
	{
		m_desiredHeight = currentHeight;
	}

	if (abs(m_liftAction) > 0.001f)
	{
		m_liftAction = min(liftActionMax, max(-0.2f, m_liftAction));

		m_hoveringPower = (m_powerInputConst * m_liftAction) * boost;
		m_noHoveringTimer = 0.0f;
	}
	else if (!m_isTouchingGround)
	{
		if (m_noHoveringTimer <= 0.0f)
		{
			float gravity;

			pe_simulation_params paramsSim;
			if (pPhysics->GetParams(&paramsSim))
				gravity = abs(paramsSim.gravity.z);
			else
				gravity = 9.2f;

			float upDirZ = m_workingUpDir.z;

			if (abs(m_forwardAction) > 0.01 && upDirZ > 0.0f)
				upDirZ = 1.0f;
			else if (upDirZ > 0.8f)
				upDirZ = 1.0f;

			float upPower = upDirZ;
			upPower -= min(1.0f, abs(m_forwardAction) * abs(angles.x));

			float turbulenceMult = 1.0f - min(m_turbulenceMultMax, m_turbulence);
			Vec3& impulse = m_control.impulse;
			impulse += Vec3(0.0f, 0.0f, upPower) * gravity * turbulenceMult * GetDamageMult();
			impulse.z -= m_PhysDyn.v.z * turbulenceMult;
		}
		else
		{
			m_noHoveringTimer -= deltaTime;
		}
	}

	if (m_pStabilizeVTOL)
	{
		float stabilizeTime = m_pStabilizeVTOL->GetFVal();

		if (stabilizeTime > 0.0f)
		{
			if (m_relaxTimer < 6.0f)
				m_relaxTimer += deltaTime;
			else
			{
				float r = currentRoll - relaxRollTolerance;
				r = min(1.0f, max(-1.0f, r));

				m_actionRoll += -r * m_relaxForce * (m_relaxTimer / 6.0f);
			}

		}
	}

	if (m_netActionSync.PublishActions( CNetworkMovementHelicopter(this) ))
		m_pVehicle->GetGameObject()->ChangedNetworkState(eEA_GameClientDynamic);
}
Пример #7
0
void CPatchPageDlg::OnSelChangeCombo(UINT nID)
{
	UpdateEngine(nID);
}
Пример #8
0
void CPatchPageDlg::OnClickedBtn(UINT nID)
{
	UpdateEngine(nID);
}
Пример #9
0
void CPatchPageDlg::OnChangedNumEdit(UINT nID, NMHDR* pNMHDR, LRESULT* pResult)
{
	UpdateEngine(nID);
	*pResult = 0;
}
Пример #10
0
static bool LoadMind(const TCHAR* filename, int &line)
{
	TCHAR* fullname = GetFullName(filename);
	HCURSOR newCur = LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT));
	HCURSOR oldCur = SetCursor(newCur);
	#ifdef DEBUG_LOAD_TIME
	unsigned __int64 t = __rdtsc();
	#endif
	Mind* mind = new Mind();
	line = -1;
	try {
		mind->Load(fullname);
	}
	catch (Mind::CorruptedMind c) {
		line = c.line;
		delete mind;
		if (fullname != filename)
			delete[] fullname;
		SetCursor(oldCur);
		return false;
	}
	catch (...) {
		delete mind;
		if (fullname != filename)
			delete[] fullname;
		SetCursor(oldCur);
		return false;
	}
	if (fullname != filename)
		delete[] fullname;

	#ifdef DEBUG_LOAD_TIME
	t = __rdtsc() - t;
	char dest[101];
	mir_snprintf(dest, "%I64d ticks\n", t / 3200000);
	MessageBoxA(NULL, dest, NULL, 0);
	//exit(0);
	#endif
	SetCursor(oldCur);
	HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(IDR_SMILES), _T("SMILES"));
	if (!hRes) {
		delete mind;
		return false;
	}
	DWORD size = SizeofResource(hInst, hRes);
	if (!size) {
		delete mind;
		return false;
	}
	HGLOBAL hGlob = LoadResource(hInst, hRes);
	if (!hGlob) {
		delete mind;
		return false;
	}
	void *data = LockResource(hGlob);
	if (!data) {
		FreeResource(hGlob);
		delete mind;
		return false;
	}
	bool res = true;
	try {
		mind->LoadSmiles(data, size);
	}
	catch (...) {
		res = false;
	}
	UnlockResource(data);
	FreeResource(hGlob);
	if (!res) {
		delete mind;
		return false;
	}
	delete bot;
	bot = new TalkBot(*mind);
	delete mind;
	UpdateEngine();
	return true;
}
Пример #11
0
static INT_PTR CALLBACK EngineDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	WORD param;
	BOOL bTranslated = FALSE;
	static bool loading = true;
	static int changeCount = 0;
	switch (uMsg) {
	case WM_INITDIALOG:
		loading = true;
		TranslateDialogDefault(hwndDlg);
		CheckDlgButton(hwndDlg, IDC_ENGINE_SILENT, Config.EngineStaySilent ? BST_CHECKED : BST_UNCHECKED);
		CheckDlgButton(hwndDlg, IDC_ENGINE_LOWERCASE, Config.EngineMakeLowerCase ? BST_CHECKED : BST_UNCHECKED);
		CheckDlgButton(hwndDlg, IDC_ENGINE_UNDERSTAND_ALWAYS, Config.EngineUnderstandAlways ? BST_CHECKED : BST_UNCHECKED);
		SetDlgItemText(hwndDlg, IDC_MINDFILE, Config.MindFileName);
		EnableWindow(GetDlgItem(hwndDlg, IDC_BTNSAVE), blInit);
		UpdateUnderstandAlwaysCheckbox(hwndDlg);
		loading = false;
		return TRUE;
	
	case WM_COMMAND:
		param = LOWORD(wParam);
		if (param == IDC_ENGINE_SILENT && HIWORD(wParam) == BN_CLICKED)
			UpdateUnderstandAlwaysCheckbox(hwndDlg);

		switch (param) {
		case IDC_BTNPATH:
			{
				const size_t fileNameSize = 5000;
				TCHAR *filename = new TCHAR[fileNameSize];
				TCHAR *fullname = GetFullName(Config.MindFileName);
				mir_tstrcpy(filename, fullname);
				if (fullname != Config.MindFileName)
					delete[] fullname;

				OPENFILENAME ofn = { 0 };
				ofn.lStructSize = sizeof(OPENFILENAME);
				ofn.hwndOwner = GetParent(hwndDlg);

				TCHAR *mind = TranslateTS(MIND_FILE_DESC);
				TCHAR *anyfile = TranslateTS(ALL_FILES_DESC);
				CMString filt(FORMAT, MIND_DIALOG_FILTER, mind, anyfile);
				filt.Replace('\1', '\0');

				ofn.lpstrFilter = filt;
				ofn.lpstrFile = filename;
				ofn.nMaxFile = fileNameSize;
				ofn.Flags = OFN_FILEMUSTEXIST;
				ofn.lpstrInitialDir = tszPath;
				if (!GetOpenFileName(&ofn)) {
					delete[] filename;
					break;
				}

				TCHAR *origf = filename;
				TCHAR *f = filename;
				TCHAR *p = tszPath;
				while (*p && *f) {
					TCHAR p1 = (TCHAR)CharLower((TCHAR*)(long)*p++);
					TCHAR f1 = (TCHAR)CharLower((TCHAR*)(long)*f++);
					if (p1 != f1)
						break;
				}
				if (!*p)
					filename = f;
				Config.MindFileName = filename;
				SetDlgItemText(hwndDlg, IDC_MINDFILE, filename);
				delete[] origf;
			}

		case IDC_BTNRELOAD:
			{
				const TCHAR *c = Config.MindFileName;
				int line;
				bTranslated = blInit = LoadMind(c, line);
				if (!bTranslated) {
					TCHAR message[5000];
					mir_sntprintf(message, TranslateTS(FAILED_TO_LOAD_BASE), line, c);
					MessageBox(NULL, message, TranslateTS(BOLTUN_ERROR), MB_ICONERROR | MB_TASKMODAL | MB_OK);
				}
			}
			break;

		default:
			if (!loading) {
				if (param == IDC_MINDFILE/* && HIWORD(wParam) != EN_CHANGE*/)
					break;
				SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
			}
		}
		break;

	case WM_NOTIFY:
		NMHDR *nmhdr = (NMHDR*)lParam;
		switch (nmhdr->code) {
		case PSN_APPLY:
		case PSN_KILLACTIVE:
			Config.EngineStaySilent = IsDlgButtonChecked(hwndDlg, IDC_ENGINE_SILENT) == BST_CHECKED ? TRUE : FALSE;
			Config.EngineMakeLowerCase = IsDlgButtonChecked(hwndDlg, IDC_ENGINE_LOWERCASE) == BST_CHECKED ? TRUE : FALSE;
			Config.EngineUnderstandAlways = IsDlgButtonChecked(hwndDlg, IDC_ENGINE_UNDERSTAND_ALWAYS) == BST_CHECKED ? TRUE : FALSE;
			UpdateEngine();
			TCHAR c[MAX_MIND_FILE];
			bTranslated = GetDlgItemText(hwndDlg, IDC_MINDFILE, c, _countof(c));
			if (bTranslated)
				Config.MindFileName = c;
			else
				Config.MindFileName = DEFAULT_MIND_FILE;
			return TRUE;
		}
		break;
	}
	return 0;
}