Skip to content

Commit 6fe7421

Browse files
committed
Update crouching in our own function, and reduce speed when crouching
1 parent cbb2726 commit 6fe7421

File tree

5 files changed

+72
-33
lines changed

5 files changed

+72
-33
lines changed

Entities/AHuman.cpp

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,7 +1692,6 @@ void AHuman::OnNewMovePath()
16921692
void AHuman::UpdateWalkAngle(AHuman::Layer whichLayer) {
16931693
if (m_Controller.IsState(BODY_JUMP)) {
16941694
m_WalkAngle[whichLayer] = Matrix(c_QuarterPI * GetFlipFactor());
1695-
m_WalkPathOffset.Reset();
16961695
} else {
16971696
float rayLength = 15.0F;
16981697
Vector hipPos = m_Pos;
@@ -1718,37 +1717,46 @@ void AHuman::UpdateWalkAngle(AHuman::Layer whichLayer) {
17181717
Matrix walkAngle;
17191718
walkAngle.SetDegAngle(terrainRotationDegs);
17201719
m_WalkAngle[whichLayer] = walkAngle;
1720+
}
1721+
}
17211722

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+
//////////////////////////////////////////////////////////////////////////////////////////
17361724

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);
17401735

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+
}
17451740

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;
17511743
}
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();
17521760
}
17531761
}
17541762

@@ -2226,6 +2234,8 @@ void AHuman::PreControllerUpdate()
22262234

22272235
m_StrideFrame = false;
22282236

2237+
UpdateCrouching();
2238+
22292239
if (m_Status == STABLE && !m_LimbPushForcesAndCollisionsDisabled && m_MoveState != NOMOVE)
22302240
{
22312241
// This exists to support disabling foot collisions if the limbpath has that flag set.

Entities/AHuman.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,11 @@ DefaultPieMenuNameGetter("Default Human Pie Menu");
688688
/// <param name="whichLayer">The Layer in question.</param>
689689
void UpdateWalkAngle(AHuman::Layer whichLayer);
690690

691+
/// <summary>
692+
/// Detects overhead ceilings and crouches for them.
693+
/// </summary>
694+
void UpdateCrouching();
695+
691696
/// <summary>
692697
/// Gets the walk path rotation for the specified Layer.
693698
/// </summary>

Entities/LimbPath.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ void LimbPath::Clear()
3737
// m_CurrentSegment = 0;
3838
m_FootCollisionsDisabledSegment = -1;
3939
m_SegProgress = 0.0;
40-
for (int i = 0; i < SPEEDCOUNT; ++i)
40+
for (int i = 0; i < SPEEDCOUNT; ++i) {
4141
m_TravelSpeed[i] = 0.0;
42+
}
43+
m_TravelSpeedMultiplier = 1.0F;
4244
m_WhichSpeed = NORMAL;
4345
m_PushForce = 0.0;
4446
m_JointPos.Reset();
@@ -129,8 +131,10 @@ int LimbPath::Create(const LimbPath &reference)
129131
m_FootCollisionsDisabledSegment = reference.m_FootCollisionsDisabledSegment;
130132

131133
m_SegProgress = reference.m_SegProgress;
132-
for (int i = 0; i < SPEEDCOUNT; ++i)
134+
for (int i = 0; i < SPEEDCOUNT; ++i) {
133135
m_TravelSpeed[i] = reference.m_TravelSpeed[i];
136+
}
137+
m_TravelSpeedMultiplier = reference.m_TravelSpeedMultiplier;
134138
m_PushForce = reference.m_PushForce;
135139
m_TimeLeft = reference.m_TimeLeft;
136140
m_TotalLength = reference.m_TotalLength;
@@ -182,6 +186,7 @@ int LimbPath::ReadProperty(const std::string_view &propName, Reader &reader)
182186
reader >> m_TravelSpeed[FAST];
183187
//m_TravelSpeed[FAST] = m_TravelSpeed[FAST] * 2;
184188
});
189+
MatchProperty("TravelSpeedMultiplier", { reader >> m_TravelSpeedMultiplier; });
185190
MatchProperty("PushForce", {
186191
reader >> m_PushForce;
187192
//m_PushForce = m_PushForce / 1.5;
@@ -221,6 +226,8 @@ int LimbPath::Save(Writer &writer) const
221226
writer << m_TravelSpeed[NORMAL];
222227
writer.NewProperty("FastTravelSpeed");
223228
writer << m_TravelSpeed[FAST];
229+
writer.NewProperty("TravelSpeedMultiplier");
230+
writer << m_TravelSpeedMultiplier;
224231
writer.NewProperty("PushForce");
225232
writer << m_PushForce;
226233

@@ -309,7 +316,7 @@ Vector LimbPath::GetCurrentVel(const Vector &limbPos)
309316
{
310317
Vector returnVel;
311318
Vector distVect = g_SceneMan.ShortestDistance(limbPos, GetCurrentSegTarget());
312-
float adjustedTravelSpeed = m_TravelSpeed[m_WhichSpeed] / (1.0F + std::abs(m_JointVel.GetY()) * 0.1F);
319+
float adjustedTravelSpeed = (m_TravelSpeed[m_WhichSpeed] / (1.0F + std::abs(m_JointVel.GetY()) * 0.1F)) * m_TravelSpeedMultiplier;
313320

314321
if (IsStaticPoint())
315322
{

Entities/LimbPath.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ ClassInfoGetters;
228228
// Arguments: None.
229229
// Return value: A float describing the speed in m/s.
230230

231-
float GetSpeed() const { return m_TravelSpeed[m_WhichSpeed]; }
231+
float GetSpeed() const { return m_TravelSpeed[m_WhichSpeed] * m_TravelSpeedMultiplier; }
232232

233233

234234
//////////////////////////////////////////////////////////////////////////////////////////
@@ -240,6 +240,18 @@ ClassInfoGetters;
240240

241241
float GetSpeed(int speedPreset) const { if (speedPreset == SLOW || speedPreset == NORMAL || speedPreset == FAST) return m_TravelSpeed[speedPreset]; else return 0; }
242242

243+
/// <summary>
244+
/// Sets the current travel speed multiplier.
245+
/// </summary>
246+
/// <param="newValue">The new travel speed multiplier.</returns>
247+
void SetTravelSpeedMultiplier(float newValue) { m_TravelSpeedMultiplier = newValue; }
248+
249+
/// <summary>
250+
/// Gets the current travel speed multiplier.
251+
/// </summary>
252+
/// <returns>The current travel speed multiplier.</returns>
253+
float GetTravelSpeedMultiplier() const { return m_TravelSpeedMultiplier; }
254+
243255

244256
//////////////////////////////////////////////////////////////////////////////////////////
245257
// Method: GetPushForce
@@ -286,7 +298,7 @@ ClassInfoGetters;
286298
// Arguments: None.
287299
// Return value: The total time (ms) this should take to travel along, if unobstructed.
288300

289-
float GetTotalPathTime() const { return ((m_TotalLength * c_MPP) / m_TravelSpeed[m_WhichSpeed]) * 1000; }
301+
float GetTotalPathTime() const { return ((m_TotalLength * c_MPP) / (m_TravelSpeed[m_WhichSpeed] * m_TravelSpeedMultiplier)) * 1000; }
290302

291303

292304
//////////////////////////////////////////////////////////////////////////////////////////
@@ -297,7 +309,7 @@ ClassInfoGetters;
297309
// Arguments: None.
298310
// Return value: The total time (ms) this should take to travel along, if unobstructed.
299311

300-
float GetRegularPathTime() const { return ((m_RegularLength * c_MPP) / m_TravelSpeed[m_WhichSpeed]) * 1000; }
312+
float GetRegularPathTime() const { return ((m_RegularLength * c_MPP) / (m_TravelSpeed[m_WhichSpeed] * m_TravelSpeedMultiplier)) * 1000; }
301313

302314

303315
//////////////////////////////////////////////////////////////////////////////////////////
@@ -657,6 +669,10 @@ ClassInfoGetters;
657669

658670
// The constant speed that the limb traveling this path has in m/s.
659671
float m_TravelSpeed[SPEEDCOUNT];
672+
673+
// The current travel speed multiplier
674+
float m_TravelSpeedMultiplier;
675+
660676
// The current speed setting.
661677
int m_WhichSpeed;
662678

Lua/LuaBindingsEntities.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,7 @@ namespace RTE {
803803

804804
.property("StartOffset", &LimbPath::GetStartOffset, &LimbPath::SetStartOffset)
805805
.property("SegmentCount", &LimbPath::GetSegCount)
806+
.property("TravelSpeedMultiplier", &LimbPath::GetTravelSpeedMultiplier, &LimbPath::SetTravelSpeedMultiplier)
806807

807808
.def("GetSegment", &LimbPath::GetSegment);
808809
}

0 commit comments

Comments
 (0)