//------------------------------------------------------------------------ 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(¶msSim)) 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 ¤tPitch = angles.x; // +ve roll means to the left const float ¤tRoll = 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); }
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(¶msSim)) 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); }
void CPatchPageDlg::OnSelChangeCombo(UINT nID) { UpdateEngine(nID); }
void CPatchPageDlg::OnClickedBtn(UINT nID) { UpdateEngine(nID); }
void CPatchPageDlg::OnChangedNumEdit(UINT nID, NMHDR* pNMHDR, LRESULT* pResult) { UpdateEngine(nID); *pResult = 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; }
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; }