@@ -229,6 +229,15 @@ int AHuman::Create(const AHuman& reference) {
229
229
m_RotAngleTargets[i] = reference.m_RotAngleTargets [i];
230
230
}
231
231
232
+ // Default the run walkpath to be the same as the walk one, if it doesn't exist
233
+ if (m_Paths[FGROUND][RUN].GetSegCount () == 0 ) {
234
+ const LimbPath& walkLimbPath = reference.m_Paths [FGROUND][WALK];
235
+ float speedIncrease = walkLimbPath.GetSpeed (Speed::FAST) / walkLimbPath.GetSpeed (Speed::NORMAL);
236
+ m_Paths[FGROUND][RUN].Create (walkLimbPath);
237
+ m_Paths[FGROUND][RUN].SetBaseSpeedMultiplier (speedIncrease);
238
+ m_RotAngleTargets[RUN] = reference.m_RotAngleTargets [RUN];
239
+ }
240
+
232
241
m_DeviceState = reference.m_DeviceState ;
233
242
m_SweepState = reference.m_SweepState ;
234
243
m_DigState = reference.m_DigState ;
@@ -293,15 +302,18 @@ int AHuman::ReadProperty(const std::string_view& propName, Reader& reader) {
293
302
MatchProperty (" StandLimbPath" , { reader >> m_Paths[FGROUND][STAND]; });
294
303
MatchProperty (" StandLimbPathBG" , { reader >> m_Paths[BGROUND][STAND]; });
295
304
MatchProperty (" WalkLimbPath" , { reader >> m_Paths[FGROUND][WALK]; });
305
+ MatchProperty (" RunLimbPath" , { reader >> m_Paths[FGROUND][RUN]; });
296
306
MatchProperty (" CrouchLimbPath" , { reader >> m_Paths[FGROUND][CROUCH]; });
297
307
MatchProperty (" CrouchLimbPathBG" , { reader >> m_Paths[BGROUND][CROUCH]; });
298
308
MatchProperty (" CrawlLimbPath" , { reader >> m_Paths[FGROUND][CRAWL]; });
299
309
MatchProperty (" ArmCrawlLimbPath" , { reader >> m_Paths[FGROUND][ARMCRAWL]; });
300
310
MatchProperty (" ClimbLimbPath" , { reader >> m_Paths[FGROUND][CLIMB]; });
301
311
MatchProperty (" JumpLimbPath" , { reader >> m_Paths[FGROUND][JUMP]; });
302
312
MatchProperty (" DislodgeLimbPath" , { reader >> m_Paths[FGROUND][DISLODGE]; });
313
+
303
314
MatchProperty (" StandRotAngleTarget" , { reader >> m_RotAngleTargets[STAND]; });
304
315
MatchProperty (" WalkRotAngleTarget" , { reader >> m_RotAngleTargets[WALK]; });
316
+ MatchProperty (" RunRotAngleTarget" , { reader >> m_RotAngleTargets[RUN]; });
305
317
MatchProperty (" CrouchRotAngleTarget" , { reader >> m_RotAngleTargets[CROUCH]; });
306
318
MatchProperty (" JumpRotAngleTarget" , { reader >> m_RotAngleTargets[JUMP]; });
307
319
@@ -353,6 +365,8 @@ int AHuman::Save(Writer& writer) const {
353
365
writer << m_Paths[BGROUND][STAND];
354
366
writer.NewProperty (" WalkLimbPath" );
355
367
writer << m_Paths[FGROUND][WALK];
368
+ writer.NewProperty (" RunLimbPath" );
369
+ writer << m_Paths[FGROUND][RUN];
356
370
writer.NewProperty (" CrouchLimbPath" );
357
371
writer << m_Paths[FGROUND][CROUCH];
358
372
writer.NewProperty (" CrawlLimbPath" );
@@ -366,6 +380,12 @@ int AHuman::Save(Writer& writer) const {
366
380
writer.NewProperty (" DislodgeLimbPath" );
367
381
writer << m_Paths[FGROUND][DISLODGE];
368
382
383
+ writer.NewPropertyWithValue (" StandRotAngleTarget" , m_RotAngleTargets[STAND]);
384
+ writer.NewPropertyWithValue (" WalkRotAngleTarget" , m_RotAngleTargets[WALK]);
385
+ writer.NewPropertyWithValue (" RunRotAngleTarget" , m_RotAngleTargets[RUN]);
386
+ writer.NewPropertyWithValue (" CrouchRotAngleTarget" , m_RotAngleTargets[CROUCH]);
387
+ writer.NewPropertyWithValue (" JumpRotAngleTarget" , m_RotAngleTargets[JUMP]);
388
+
369
389
return 0 ;
370
390
}
371
391
@@ -1428,7 +1448,7 @@ void AHuman::UpdateLimbPathSpeed() {
1428
1448
m_Paths[FGROUND][m_MoveState].SetTravelSpeedMultiplier (1 .0F );
1429
1449
m_Paths[BGROUND][m_MoveState].SetTravelSpeedMultiplier (1 .0F );
1430
1450
1431
- if (m_MoveState == WALK || m_MoveState == CRAWL) {
1451
+ if (m_MoveState == WALK || m_MoveState == RUN || m_MoveState == CRAWL) {
1432
1452
// If crouching, move at reduced speed
1433
1453
const float crouchSpeedMultiplier = 0 .5F ;
1434
1454
float travelSpeedMultiplier = Lerp (0 .0F , m_MaxWalkPathCrouchShift, 1 .0F , crouchSpeedMultiplier, -m_WalkPathOffset.m_Y );
@@ -1496,22 +1516,26 @@ void AHuman::PreControllerUpdate() {
1496
1516
}
1497
1517
// Only if not jumping, OR if jumping, and apparently stuck on something - then help out with the limbs.
1498
1518
if (m_MoveState != JUMP || isStill) {
1519
+ MovementState oldMoveState = m_MoveState;
1520
+ if (crouching) {
1521
+ m_MoveState = CRAWL;
1522
+ } else if (m_Controller.IsState (MOVE_FAST)) {
1523
+ m_MoveState = RUN;
1524
+ } else {
1525
+ m_MoveState = WALK;
1526
+ }
1527
+
1499
1528
// Restart the stride if we're just starting to walk or crawl.
1500
- if (( m_MoveState != WALK && !crouching) || (m_MoveState != CRAWL && crouching) ) {
1529
+ if (m_MoveState != oldMoveState ) {
1501
1530
m_StrideStart = true ;
1502
1531
MoveOutOfTerrain (g_MaterialGrass);
1503
1532
}
1504
1533
1505
- m_MoveState = crouching ? CRAWL : WALK;
1506
-
1507
1534
// Engage prone state, this makes the body's rotational spring pull it horizontal instead of upright.
1508
1535
if (m_MoveState == CRAWL && m_ProneState == NOTPRONE) {
1509
1536
m_ProneState = GOPRONE;
1510
1537
m_ProneTimer.Reset ();
1511
1538
}
1512
-
1513
- m_Paths[FGROUND][m_MoveState].SetSpeed (m_Controller.IsState (MOVE_FAST) ? FAST : NORMAL);
1514
- m_Paths[BGROUND][m_MoveState].SetSpeed (m_Controller.IsState (MOVE_FAST) ? FAST : NORMAL);
1515
1539
}
1516
1540
1517
1541
// Walk backwards if the aiming is already focused in the opposite direction of travel.
@@ -1978,14 +2002,13 @@ void AHuman::PreControllerUpdate() {
1978
2002
UpdateLimbPathSpeed ();
1979
2003
1980
2004
// WALKING, OR WE ARE JETPACKING AND STUCK
1981
- if (m_MoveState == WALK || (m_MoveState == JUMP && isStill)) {
2005
+ if (m_MoveState == WALK || m_MoveState == RUN || (m_MoveState == JUMP && isStill)) {
1982
2006
m_Paths[FGROUND][STAND].Terminate ();
1983
2007
m_Paths[BGROUND][STAND].Terminate ();
1984
2008
1985
- // float FGLegProg = MAX(m_Paths[FGROUND][WALK].GetRegularProgress(), m_Paths[FGROUND][WALK].GetTotalTimeProgress());
1986
- // float BGLegProg = MAX(m_Paths[BGROUND][WALK].GetRegularProgress(), m_Paths[BGROUND][WALK].GetTotalTimeProgress());
1987
- float FGLegProg = m_Paths[FGROUND][WALK].GetRegularProgress ();
1988
- float BGLegProg = m_Paths[BGROUND][WALK].GetRegularProgress ();
2009
+ MovementState movementPath = m_MoveState == RUN ? RUN : WALK;
2010
+ float FGLegProg = m_Paths[FGROUND][movementPath].GetRegularProgress ();
2011
+ float BGLegProg = m_Paths[BGROUND][movementPath].GetRegularProgress ();
1989
2012
1990
2013
bool restarted = false ;
1991
2014
@@ -1994,24 +2017,24 @@ void AHuman::PreControllerUpdate() {
1994
2017
m_StrideStart = true ;
1995
2018
}
1996
2019
1997
- if (m_pFGLeg && (!m_pBGLeg || !(m_Paths[FGROUND][WALK ].PathEnded () && BGLegProg < 0 .5F ) || m_StrideStart)) {
2020
+ if (m_pFGLeg && (!m_pBGLeg || !(m_Paths[FGROUND][movementPath ].PathEnded () && BGLegProg < 0 .5F ) || m_StrideStart)) {
1998
2021
// Reset the stride timer if the path is about to restart.
1999
- if (m_Paths[FGROUND][WALK ].PathEnded () || m_Paths[FGROUND][WALK ].PathIsAtStart ()) {
2022
+ if (m_Paths[FGROUND][movementPath ].PathEnded () || m_Paths[FGROUND][movementPath ].PathIsAtStart ()) {
2000
2023
m_StrideTimer.Reset ();
2001
2024
}
2002
2025
Vector jointPos = m_Pos + RotateOffset (m_pFGLeg->GetParentOffset ());
2003
- m_ArmClimbing[BGROUND] = !m_pFGFootGroup->PushAsLimb (jointPos, m_Vel, m_WalkAngle[FGROUND], m_Paths[FGROUND][WALK ], deltaTime, &restarted, false , Vector (0 .0F , m_Paths[FGROUND][WALK ].GetLowestY ()), m_WalkPathOffset);
2026
+ m_ArmClimbing[BGROUND] = !m_pFGFootGroup->PushAsLimb (jointPos, m_Vel, m_WalkAngle[FGROUND], m_Paths[FGROUND][movementPath ], deltaTime, &restarted, false , Vector (0 .0F , m_Paths[FGROUND][movementPath ].GetLowestY ()), m_WalkPathOffset);
2004
2027
} else {
2005
2028
m_ArmClimbing[BGROUND] = false ;
2006
2029
}
2007
- if (m_pBGLeg && (!m_pFGLeg || !(m_Paths[BGROUND][WALK ].PathEnded () && FGLegProg < 0 .5F ))) {
2030
+ if (m_pBGLeg && (!m_pFGLeg || !(m_Paths[BGROUND][movementPath ].PathEnded () && FGLegProg < 0 .5F ))) {
2008
2031
m_StrideStart = false ;
2009
2032
// Reset the stride timer if the path is about to restart.
2010
- if (m_Paths[BGROUND][WALK ].PathEnded () || m_Paths[BGROUND][WALK ].PathIsAtStart ()) {
2033
+ if (m_Paths[BGROUND][movementPath ].PathEnded () || m_Paths[BGROUND][movementPath ].PathIsAtStart ()) {
2011
2034
m_StrideTimer.Reset ();
2012
2035
}
2013
2036
Vector jointPos = m_Pos + RotateOffset (m_pBGLeg->GetParentOffset ());
2014
- m_ArmClimbing[FGROUND] = !m_pBGFootGroup->PushAsLimb (jointPos, m_Vel, m_WalkAngle[BGROUND], m_Paths[BGROUND][WALK ], deltaTime, &restarted, false , Vector (0 .0F , m_Paths[BGROUND][WALK ].GetLowestY ()), m_WalkPathOffset);
2037
+ m_ArmClimbing[FGROUND] = !m_pBGFootGroup->PushAsLimb (jointPos, m_Vel, m_WalkAngle[BGROUND], m_Paths[BGROUND][movementPath ], deltaTime, &restarted, false , Vector (0 .0F , m_Paths[BGROUND][movementPath ].GetLowestY ()), m_WalkPathOffset);
2015
2038
} else {
2016
2039
if (m_pBGLeg) {
2017
2040
m_pBGFootGroup->FlailAsLimb (m_Pos, RotateOffset (m_pBGLeg->GetParentOffset ()), m_pBGLeg->GetMaxLength (), m_PrevVel, m_AngularVel, m_pBGLeg->GetMass (), deltaTime);
@@ -2054,7 +2077,7 @@ void AHuman::PreControllerUpdate() {
2054
2077
if (climbing) {
2055
2078
if (m_pFGArm && !m_pFGArm->GetHeldDevice () && !(m_Paths[FGROUND][CLIMB].PathEnded () && BGArmProg > 0 .1F )) { // < 0.5F
2056
2079
m_ArmClimbing[FGROUND] = true ;
2057
- m_Paths[FGROUND][WALK ].Terminate ();
2080
+ m_Paths[FGROUND][movementPath ].Terminate ();
2058
2081
m_StrideStart = true ;
2059
2082
// Reset the stride timer if the path is about to restart.
2060
2083
if (m_Paths[FGROUND][CLIMB].PathEnded () || m_Paths[FGROUND][CLIMB].PathIsAtStart ()) {
@@ -2067,7 +2090,7 @@ void AHuman::PreControllerUpdate() {
2067
2090
}
2068
2091
if (m_pBGArm) {
2069
2092
m_ArmClimbing[BGROUND] = true ;
2070
- m_Paths[BGROUND][WALK ].Terminate ();
2093
+ m_Paths[BGROUND][movementPath ].Terminate ();
2071
2094
m_StrideStart = true ;
2072
2095
// Reset the stride timer if the path is about to restart.
2073
2096
if (m_Paths[BGROUND][CLIMB].PathEnded () || m_Paths[BGROUND][CLIMB].PathIsAtStart ()) {
@@ -2085,11 +2108,11 @@ void AHuman::PreControllerUpdate() {
2085
2108
m_StrideStart = true ;
2086
2109
m_Paths[FGROUND][CLIMB].Terminate ();
2087
2110
m_Paths[BGROUND][CLIMB].Terminate ();
2088
- } else if (m_StrideTimer.IsPastSimMS (static_cast <double >(m_Paths[FGROUND][WALK ].GetTotalPathTime () * 1 .1F ))) {
2111
+ } else if (m_StrideTimer.IsPastSimMS (static_cast <double >(m_Paths[FGROUND][movementPath ].GetTotalPathTime () * 1 .1F ))) {
2089
2112
// Reset the walking stride if it's taking longer than it should.
2090
2113
m_StrideStart = true ;
2091
- m_Paths[FGROUND][WALK ].Terminate ();
2092
- m_Paths[BGROUND][WALK ].Terminate ();
2114
+ m_Paths[FGROUND][movementPath ].Terminate ();
2115
+ m_Paths[BGROUND][movementPath ].Terminate ();
2093
2116
}
2094
2117
} else if (m_MoveState == CRAWL) {
2095
2118
// Start crawling only once we are fully prone.
@@ -2345,7 +2368,7 @@ void AHuman::Update() {
2345
2368
2346
2369
if (HeldDevice* heldDevice = GetEquippedItem ()) {
2347
2370
float maxLength = heldDevice->GetSharpLength ();
2348
- if (maxLength == 0 ) {
2371
+ if (maxLength == 0 . 0F || m_MoveState == RUN ) {
2349
2372
m_SharpAimProgress = 0 ;
2350
2373
m_SharpAimMaxedOut = true ;
2351
2374
} else if (m_MoveState == WALK) {
0 commit comments