@@ -81,6 +81,7 @@ void AHuman::Clear()
81
81
m_FGArmFlailScalar = 0 .0F ;
82
82
m_BGArmFlailScalar = 0 .7F ;
83
83
m_EquipHUDTimer.Reset ();
84
+ m_WalkAngle.fill (Matrix ());
84
85
85
86
m_DeviceState = SCANNING;
86
87
m_SweepState = NOSWEEP;
@@ -1796,6 +1797,41 @@ bool AHuman::UpdateMovePath()
1796
1797
return true ;
1797
1798
}
1798
1799
1800
+ // ////////////////////////////////////////////////////////////////////////////////////////
1801
+
1802
+ void AHuman::UpdateWalkAngle (AHuman::Layer whichLayer) {
1803
+ if (m_Controller.IsState (BODY_JUMP)) {
1804
+ m_WalkAngle[whichLayer] = Matrix (c_QuarterPI * GetFlipFactor ());
1805
+ } else if (m_MaintainUpright) {
1806
+ // Cast rays to calculate the approximate shape of terrain.
1807
+ int rayCount = 4 ;
1808
+ float rayLength = 10 .0F ;
1809
+ Vector hipPos = m_Pos;
1810
+ if (whichLayer == AHuman::Layer::FGROUND && m_pFGLeg) {
1811
+ rayLength += m_pFGLeg->GetMaxLength ();
1812
+ hipPos += RotateOffset (m_pFGLeg->GetParentOffset ());
1813
+ } else if (m_pBGLeg) {
1814
+ rayLength += m_pBGLeg->GetMaxLength ();
1815
+ hipPos += RotateOffset (m_pBGLeg->GetParentOffset ());
1816
+ }
1817
+ float traceRotation = rayCount > 1 ? c_HalfPI / static_cast <float >(rayCount - 1 ) * GetFlipFactor () : 0 ;
1818
+ Vector hitPos;
1819
+ Vector terrainVector (0 , rayLength);
1820
+ Vector trace (0 , rayLength);
1821
+ for (int i = 0 ; i < rayCount; i++) {
1822
+ if (g_SceneMan.CastStrengthRay (hipPos, trace, 10 .0F , hitPos, 4 , g_MaterialGrass)) {
1823
+ terrainVector += trace - g_SceneMan.ShortestDistance (hipPos, hitPos, g_SceneMan.SceneWrapsX ());
1824
+ } else {
1825
+ // Reinforce focus on previously assumed terrain.
1826
+ terrainVector *= 1 .5F ;
1827
+ }
1828
+ trace.RadRotate (traceRotation);
1829
+ }
1830
+ m_WalkAngle[whichLayer] = Matrix ((terrainVector * GetFlipFactor ()).GetAbsRadAngle () + c_HalfPI * GetFlipFactor ());
1831
+ } else {
1832
+ m_WalkAngle[whichLayer] = m_Rotation;
1833
+ }
1834
+ }
1799
1835
1800
1836
// ////////////////////////////////////////////////////////////////////////////////////////
1801
1837
// Virtual method: UpdateAI
@@ -3565,51 +3601,39 @@ void AHuman::Update()
3565
3601
float FGLegProg = m_Paths[FGROUND][WALK].GetRegularProgress ();
3566
3602
float BGLegProg = m_Paths[BGROUND][WALK].GetRegularProgress ();
3567
3603
3568
- bool playStride = false ;
3604
+ bool restarted = false ;
3569
3605
3570
3606
// Make sure we are starting a stride if we're basically stopped.
3571
3607
if (isStill) { m_StrideStart = true ; }
3572
3608
3573
- if (m_pFGLeg && (!m_pBGLeg || (!(m_Paths[FGROUND][WALK].PathEnded () && BGLegProg < 0.5 ) || m_StrideStart)))
3574
- {
3575
- // m_StrideStart = false;
3576
- // Reset the stride timer if the path is about to restart
3577
- if (m_Paths[FGROUND][WALK].PathEnded () || m_Paths[FGROUND][WALK].PathIsAtStart ())
3578
- m_StrideTimer.Reset ();
3579
- m_ArmClimbing[BGROUND] = !m_pFGFootGroup->PushAsLimb (m_Pos +
3580
- m_pFGLeg->GetParentOffset ().GetXFlipped (m_HFlipped),
3581
- m_Vel,
3582
- Matrix (),
3583
- m_Paths[FGROUND][WALK],
3584
- deltaTime,
3585
- &playStride,
3586
- false );
3587
- }
3588
- else
3589
- m_ArmClimbing[BGROUND] = false ;
3590
-
3591
- if (m_pBGLeg && (!m_pFGLeg || !(m_Paths[BGROUND][WALK].PathEnded () && FGLegProg < 0.5 )))
3592
- {
3593
- m_StrideStart = false ;
3594
- // Reset the stride timer if the path is about to restart
3595
- if (m_Paths[BGROUND][WALK].PathEnded () || m_Paths[BGROUND][WALK].PathIsAtStart ())
3596
- m_StrideTimer.Reset ();
3597
- m_ArmClimbing[FGROUND] = !m_pBGFootGroup->PushAsLimb (m_Pos +
3598
- m_pBGLeg->GetParentOffset ().GetXFlipped (m_HFlipped),
3599
- m_Vel,
3600
- Matrix (),
3601
- m_Paths[BGROUND][WALK],
3602
- deltaTime,
3603
- &playStride,
3604
- false );
3605
- }
3606
- else
3607
- m_ArmClimbing[FGROUND] = false ;
3609
+ if (m_pFGLeg && (!m_pBGLeg || !(m_Paths[FGROUND][WALK].PathEnded () && BGLegProg < 0 .5F ) || m_StrideStart)) {
3610
+ // Reset the stride timer if the path is about to restart.
3611
+ if (m_Paths[FGROUND][WALK].PathEnded () || m_Paths[FGROUND][WALK].PathIsAtStart ()) { m_StrideTimer.Reset (); }
3612
+ m_ArmClimbing[BGROUND] = !(m_pFGFootGroup->PushAsLimb (m_Pos + RotateOffset (m_pFGLeg->GetParentOffset ()), m_Vel, m_WalkAngle[FGROUND], m_Paths[FGROUND][WALK], deltaTime, &restarted, false ));
3613
+ if (restarted) { UpdateWalkAngle (FGROUND); }
3614
+ } else {
3615
+ m_ArmClimbing[BGROUND] = false ;
3616
+ }
3617
+ if (m_pBGLeg && (!m_pFGLeg || !(m_Paths[BGROUND][WALK].PathEnded () && FGLegProg < 0 .5F ))) {
3618
+ m_StrideStart = false ;
3619
+ // Reset the stride timer if the path is about to restart.
3620
+ if (m_Paths[BGROUND][WALK].PathEnded () || m_Paths[BGROUND][WALK].PathIsAtStart ()) { m_StrideTimer.Reset (); }
3621
+ m_ArmClimbing[FGROUND] = !m_pBGFootGroup->PushAsLimb (m_Pos + RotateOffset (m_pBGLeg->GetParentOffset ()), m_Vel, m_WalkAngle[BGROUND], m_Paths[BGROUND][WALK], deltaTime, &restarted, false );
3622
+ if (restarted) { UpdateWalkAngle (BGROUND); }
3623
+ } else {
3624
+ if (m_pBGLeg) { m_pBGFootGroup->FlailAsLimb (m_Pos, RotateOffset (m_pBGLeg->GetParentOffset ()), m_pBGLeg->GetMaxLength (), m_PrevVel, m_AngularVel, m_pBGLeg->GetMass (), deltaTime); }
3625
+ m_ArmClimbing[FGROUND] = false ;
3626
+ }
3627
+ bool climbing = m_ArmClimbing[FGROUND] || m_ArmClimbing[BGROUND];
3608
3628
3609
- // Play the stride sound, if applicable
3610
- if (playStride && !m_ArmClimbing[FGROUND] && !m_ArmClimbing[BGROUND]) {
3611
- if (m_StrideSound) { m_StrideSound->Play (m_Pos); }
3612
- RunScriptedFunctionInAppropriateScripts (" OnStride" );
3629
+ if (restarted) {
3630
+ if (!climbing) {
3631
+ if (m_StrideSound) { m_StrideSound->Play (m_Pos); }
3632
+ RunScriptedFunctionInAppropriateScripts (" OnStride" );
3633
+ } else {
3634
+ m_WalkAngle[FGROUND] = Matrix ();
3635
+ m_WalkAngle[BGROUND] = Matrix ();
3636
+ }
3613
3637
}
3614
3638
3615
3639
// //////////////////////////////////////
@@ -3620,61 +3644,41 @@ void AHuman::Update()
3620
3644
float FGArmProg = m_Paths[FGROUND][CLIMB].GetRegularProgress ();
3621
3645
float BGArmProg = m_Paths[BGROUND][CLIMB].GetRegularProgress ();
3622
3646
3647
+ // TODO: Figure out what this comment means, and then rephrase it better!
3623
3648
// Slightly negative BGArmProg makes sense because any progress on the starting segments are reported as negative,
3624
3649
// and there's many starting segments on properly formed climbing paths
3625
- if (m_pFGArm && (m_ArmClimbing[FGROUND] || m_ArmClimbing[BGROUND]) && (!m_pBGArm || !m_pFGLeg || BGArmProg > 0.1 ))
3626
- {
3627
- m_ArmClimbing[FGROUND] = true ;
3628
- m_Paths[FGROUND][WALK].Terminate ();
3629
- // m_Paths[BGROUND][WALK].Terminate();
3630
- m_StrideStart = true ;
3631
- // Reset the stride timer if the path is about to restart
3632
- if (m_Paths[FGROUND][CLIMB].PathEnded () || m_Paths[FGROUND][CLIMB].PathIsAtStart ())
3633
- m_StrideTimer.Reset ();
3634
- m_pFGHandGroup->PushAsLimb (m_Pos +
3635
- m_pFGArm->GetParentOffset ().GetXFlipped (m_HFlipped),
3636
- m_Vel,
3637
- m_Rotation,
3638
- m_Paths[FGROUND][CLIMB],
3639
- deltaTime);
3640
- }
3641
- else
3642
- {
3643
- m_ArmClimbing[FGROUND] = false ;
3644
- m_Paths[FGROUND][CLIMB].Terminate ();
3645
- }
3646
-
3647
- if (m_pBGArm && (m_ArmClimbing[FGROUND] || m_ArmClimbing[BGROUND]))
3648
- {
3649
- m_ArmClimbing[BGROUND] = true ;
3650
- // m_Paths[FGROUND][WALK].Terminate();
3651
- m_Paths[BGROUND][WALK].Terminate ();
3652
- m_StrideStart = true ;
3653
- // Reset the stride timer if the path is about to restart
3654
- if (m_Paths[BGROUND][CLIMB].PathEnded () || m_Paths[BGROUND][CLIMB].PathIsAtStart ())
3655
- m_StrideTimer.Reset ();
3656
- m_pBGHandGroup->PushAsLimb (m_Pos +
3657
- m_pBGArm->GetParentOffset ().GetXFlipped (m_HFlipped),
3658
- m_Vel,
3659
- m_Rotation,
3660
- m_Paths[BGROUND][CLIMB],
3661
- deltaTime);
3662
- }
3663
- else
3664
- {
3665
- m_ArmClimbing[BGROUND] = false ;
3666
- m_Paths[BGROUND][CLIMB].Terminate ();
3667
- }
3650
+ if (climbing) {
3651
+ if (m_pFGArm && !(m_Paths[FGROUND][CLIMB].PathEnded () && BGArmProg > 0 .1F )) { // < 0.5F
3652
+ m_ArmClimbing[FGROUND] = true ;
3653
+ m_Paths[FGROUND][WALK].Terminate ();
3654
+ m_StrideStart = true ;
3655
+ // Reset the stride timer if the path is about to restart.
3656
+ if (m_Paths[FGROUND][CLIMB].PathEnded () || m_Paths[FGROUND][CLIMB].PathIsAtStart ()) { m_StrideTimer.Reset (); }
3657
+ m_pFGHandGroup->PushAsLimb (m_Pos + Vector (0 , m_pFGArm->GetParentOffset ().m_Y ).RadRotate (-rot), m_Vel, Matrix (), m_Paths[FGROUND][CLIMB], deltaTime, 0 , false );
3658
+ } else {
3659
+ m_ArmClimbing[FGROUND] = false ;
3660
+ m_Paths[FGROUND][CLIMB].Terminate ();
3661
+ }
3662
+ if (m_pBGArm) {
3663
+ m_ArmClimbing[BGROUND] = true ;
3664
+ m_Paths[BGROUND][WALK].Terminate ();
3665
+ m_StrideStart = true ;
3666
+ // Reset the stride timer if the path is about to restart.
3667
+ if (m_Paths[BGROUND][CLIMB].PathEnded () || m_Paths[BGROUND][CLIMB].PathIsAtStart ()) { m_StrideTimer.Reset (); }
3668
+ m_pBGHandGroup->PushAsLimb (m_Pos + Vector (0 , m_pBGArm->GetParentOffset ().m_Y ).RadRotate (-rot), m_Vel, Matrix (), m_Paths[BGROUND][CLIMB], deltaTime, 0 , false );
3669
+ } else {
3670
+ m_ArmClimbing[BGROUND] = false ;
3671
+ m_Paths[BGROUND][CLIMB].Terminate ();
3672
+ }
3673
+ }
3668
3674
3669
- // Restart the climbing stroke if the current one seems to be taking too long with no movement.
3670
- if ((m_ArmClimbing[FGROUND] || m_ArmClimbing[BGROUND]) && isStill && m_StrideTimer.IsPastSimMS (static_cast <double >(m_Paths[BGROUND][CLIMB].GetTotalPathTime () * 0 .5F ))) {
3675
+ // Restart the climbing stroke if the current one seems to be taking too long with no movement.
3676
+ if (climbing && isStill && m_StrideTimer.IsPastSimMS (static_cast <double >(m_Paths[BGROUND][CLIMB].GetTotalPathTime () * 0 .5F ))) {
3671
3677
m_StrideStart = true ;
3672
3678
m_Paths[FGROUND][CLIMB].Terminate ();
3673
3679
m_Paths[BGROUND][CLIMB].Terminate ();
3674
- }
3675
- // Reset the walking stride if it's taking too long
3676
- else if (m_StrideTimer.IsPastSimMS (m_Paths[FGROUND][WALK].GetTotalPathTime ()))
3677
- {
3680
+ } else if (m_StrideTimer.IsPastSimMS (static_cast <double >(m_Paths[FGROUND][WALK].GetTotalPathTime () * 1 .1F ))) {
3681
+ // Reset the walking stride if it's taking longer than it should.
3678
3682
m_StrideStart = true ;
3679
3683
m_Paths[FGROUND][WALK].Terminate ();
3680
3684
m_Paths[BGROUND][WALK].Terminate ();
@@ -3692,15 +3696,8 @@ void AHuman::Update()
3692
3696
{
3693
3697
// m_StrideStart = false;
3694
3698
// Reset the stride timer if the path is about to restart
3695
- if (m_Paths[FGROUND][CRAWL].PathEnded () || m_Paths[FGROUND][CRAWL].PathIsAtStart ())
3696
- m_StrideTimer.Reset ();
3697
- m_pFGFootGroup->PushAsLimb (m_Pos + RotateOffset (m_pFGLeg->GetParentOffset ()),
3698
- m_Vel,
3699
- m_Rotation,
3700
- m_Paths[FGROUND][CRAWL],
3701
- deltaTime,
3702
- 0 ,
3703
- true );
3699
+ if (m_Paths[FGROUND][CRAWL].PathEnded () || m_Paths[FGROUND][CRAWL].PathIsAtStart ()) { m_StrideTimer.Reset (); }
3700
+ m_pFGFootGroup->PushAsLimb (m_Pos + RotateOffset (m_pFGLeg->GetParentOffset ()), m_Vel, m_Rotation, m_Paths[FGROUND][CRAWL], deltaTime);
3704
3701
}
3705
3702
else
3706
3703
m_Paths[FGROUND][CRAWL].Terminate ();
@@ -3710,16 +3707,8 @@ void AHuman::Update()
3710
3707
{
3711
3708
m_StrideStart = false ;
3712
3709
// Reset the stride timer if the path is about to restart
3713
- if (m_Paths[BGROUND][CRAWL].PathEnded () || m_Paths[BGROUND][CRAWL].PathIsAtStart ())
3714
- m_StrideTimer.Reset ();
3715
- // If both legs can't find free resrtart, ti's time to use the arm!
3716
- m_pBGFootGroup->PushAsLimb (m_Pos + RotateOffset (m_pBGLeg->GetParentOffset ()),
3717
- m_Vel,
3718
- m_Rotation,
3719
- m_Paths[BGROUND][CRAWL],
3720
- deltaTime,
3721
- 0 ,
3722
- true );
3710
+ if (m_Paths[BGROUND][CRAWL].PathEnded () || m_Paths[BGROUND][CRAWL].PathIsAtStart ()) { m_StrideTimer.Reset (); }
3711
+ m_pBGFootGroup->PushAsLimb (m_Pos + RotateOffset (m_pBGLeg->GetParentOffset ()), m_Vel, m_Rotation, m_Paths[BGROUND][CRAWL], deltaTime);
3723
3712
}
3724
3713
else
3725
3714
m_Paths[BGROUND][CRAWL].Terminate ();
0 commit comments