@@ -1692,7 +1692,6 @@ void AHuman::OnNewMovePath()
1692
1692
void AHuman::UpdateWalkAngle (AHuman::Layer whichLayer) {
1693
1693
if (m_Controller.IsState (BODY_JUMP)) {
1694
1694
m_WalkAngle[whichLayer] = Matrix (c_QuarterPI * GetFlipFactor ());
1695
- m_WalkPathOffset.Reset ();
1696
1695
} else {
1697
1696
float rayLength = 15 .0F ;
1698
1697
Vector hipPos = m_Pos;
@@ -1718,37 +1717,46 @@ void AHuman::UpdateWalkAngle(AHuman::Layer whichLayer) {
1718
1717
Matrix walkAngle;
1719
1718
walkAngle.SetDegAngle (terrainRotationDegs);
1720
1719
m_WalkAngle[whichLayer] = walkAngle;
1720
+ }
1721
+ }
1721
1722
1722
- if (m_pHead) {
1723
- // Cast a ray above our head to either side to determine whether we need to crouch
1724
- float desiredCrouchHeadRoom = std::floor (m_pHead->GetRadius () + 2 .0f );
1725
- float toPredicted = std::floor (m_Vel.m_X * m_pHead->GetRadius ()); // Check where we'll be a second from now
1726
- Vector hitPosStart = (m_pHead->GetPos () + Vector (0 .0F , m_SpriteRadius * 0 .5F )).Floor ();
1727
- Vector hitPosPredictedStart = (m_pHead->GetPos () + Vector (toPredicted, m_SpriteRadius * 0 .5F )).Floor ();
1728
- Vector hitPos, hitPosPredicted;
1729
- g_SceneMan.CastStrengthRay (hitPosStart, Vector (0 .0F , -desiredCrouchHeadRoom + m_SpriteRadius * -0 .5F ), 10 .0F , hitPos, 0 , g_MaterialGrass);
1730
- g_SceneMan.CastStrengthRay (hitPosPredictedStart, Vector (0 .0F , -desiredCrouchHeadRoom + m_SpriteRadius * -0 .5F ), 10 .0F , hitPosPredicted, 0 , g_MaterialGrass);
1731
-
1732
- // Don't do it if we're already hitting, we're probably in a weird spot
1733
- if (hitPosStart == hitPos) {
1734
- hitPos.m_X = 0 .0F ;
1735
- }
1723
+ // ////////////////////////////////////////////////////////////////////////////////////////
1736
1724
1737
- if (hitPosPredictedStart == hitPosPredicted) {
1738
- hitPosPredicted.m_X = 0 .0F ;
1739
- }
1725
+ void AHuman::UpdateCrouching () {
1726
+ if (!m_Controller.IsState (BODY_JUMP) && m_pHead) {
1727
+ // Cast a ray above our head to either side to determine whether we need to crouch
1728
+ float desiredCrouchHeadRoom = std::floor (m_pHead->GetRadius () + 2 .0f );
1729
+ float toPredicted = std::floor (m_Vel.m_X * m_pHead->GetRadius ()); // Check where we'll be a second from now
1730
+ Vector hitPosStart = (m_pHead->GetPos () + Vector (0 .0F , m_SpriteRadius * 0 .5F )).Floor ();
1731
+ Vector hitPosPredictedStart = (m_pHead->GetPos () + Vector (toPredicted, m_SpriteRadius * 0 .5F )).Floor ();
1732
+ Vector hitPos, hitPosPredicted;
1733
+ g_SceneMan.CastStrengthRay (hitPosStart, Vector (0 .0F , -desiredCrouchHeadRoom + m_SpriteRadius * -0 .5F ), 10 .0F , hitPos, 0 , g_MaterialGrass);
1734
+ g_SceneMan.CastStrengthRay (hitPosPredictedStart, Vector (0 .0F , -desiredCrouchHeadRoom + m_SpriteRadius * -0 .5F ), 10 .0F , hitPosPredicted, 0 , g_MaterialGrass);
1740
1735
1741
- float headroom = m_pHead-> GetPos (). m_Y - std::max (hitPos. m_Y , hitPosPredicted. m_Y );
1742
- float adjust = desiredCrouchHeadRoom - headroom;
1743
- float walkPathYOffset = std::clamp ( LERP ( 0 .0F , 1 . 0F , -m_WalkPathOffset. m_Y , adjust, 0 . 3F ), 0 . 0F , m_MaxWalkPathCrouchShift) ;
1744
- m_WalkPathOffset. m_Y = -walkPathYOffset;
1736
+ // Don't do it if we're already hitting, we're probably in a weird spot
1737
+ if (hitPosStart == hitPos) {
1738
+ hitPos. m_X = 0 .0F ;
1739
+ }
1745
1740
1746
- // Adjust our X offset to try to keep our legs under our centre-of-mass
1747
- float predictedPosition = ((m_pHead->GetPos ().m_X - m_Pos.m_X ) * 0 .15F ) + m_Vel.m_X ;
1748
- m_WalkPathOffset.m_X = predictedPosition;
1749
- } else {
1750
- m_WalkPathOffset.Reset ();
1741
+ if (hitPosPredictedStart == hitPosPredicted) {
1742
+ hitPosPredicted.m_X = 0 .0F ;
1751
1743
}
1744
+
1745
+ float headroom = m_pHead->GetPos ().m_Y - std::max (hitPos.m_Y , hitPosPredicted.m_Y );
1746
+ float adjust = desiredCrouchHeadRoom - headroom;
1747
+ float walkPathYOffset = std::clamp (LERP (0 .0F , 1 .0F , -m_WalkPathOffset.m_Y , adjust, 0 .3F ), 0 .0F , m_MaxWalkPathCrouchShift);
1748
+ m_WalkPathOffset.m_Y = -walkPathYOffset;
1749
+
1750
+ // If crouching, move at third speed
1751
+ float travelSpeedMultiplier = LERP (0 .0F , m_MaxWalkPathCrouchShift, 1 .0F , 0 .5F , -m_WalkPathOffset.m_Y );
1752
+ m_Paths[FGROUND][WALK].SetTravelSpeedMultiplier (travelSpeedMultiplier);
1753
+ m_Paths[BGROUND][WALK].SetTravelSpeedMultiplier (travelSpeedMultiplier);
1754
+
1755
+ // Adjust our X offset to try to keep our legs under our centre-of-mass
1756
+ float predictedPosition = ((m_pHead->GetPos ().m_X - m_Pos.m_X ) * 0 .15F ) + m_Vel.m_X ;
1757
+ m_WalkPathOffset.m_X = predictedPosition;
1758
+ } else {
1759
+ m_WalkPathOffset.Reset ();
1752
1760
}
1753
1761
}
1754
1762
@@ -2226,6 +2234,8 @@ void AHuman::PreControllerUpdate()
2226
2234
2227
2235
m_StrideFrame = false ;
2228
2236
2237
+ UpdateCrouching ();
2238
+
2229
2239
if (m_Status == STABLE && !m_LimbPushForcesAndCollisionsDisabled && m_MoveState != NOMOVE)
2230
2240
{
2231
2241
// This exists to support disabling foot collisions if the limbpath has that flag set.
0 commit comments