@@ -6,6 +6,9 @@ static DynamicDetour H_OnJump;
66static DynamicDetour H_OnAirAccelerate ;
77static DynamicDetour H_OnWalkMove ;
88static DynamicDetour H_OnCategorizePosition ;
9+ static DynamicDetour H_OnTryPlayerMove ;
10+ static Address moveHelperAddr ;
11+ static bool tryPlayerMoveThisTick ;
912
1013float gF_Origin [MAXPLAYERS + 1 ][3 ];
1114float gF_Velocity [MAXPLAYERS + 1 ][3 ];
@@ -31,6 +34,12 @@ float gF_PostAAVelocity[MAXPLAYERS + 1][3];
3134
3235bool gB_OldWalkMoved [MAXPLAYERS + 1 ];
3336
37+ int gI_CollisionCount [MAXPLAYERS + 1 ];
38+
39+ float gF_TraceStartOrigin [MAXPLAYERS + 1 ][MAX_BUMPS ][3 ];
40+ float gF_TraceEndOrigin [MAXPLAYERS + 1 ][MAX_BUMPS ][3 ];
41+ float gF_TraceNormal [MAXPLAYERS + 1 ][MAX_BUMPS ][3 ];
42+
3443void HookGameMovementFunctions ()
3544{
3645 HookGameMovementFunction (H_OnDuck , " CCSGameMovement::Duck" , DHooks_OnDuck_Pre , DHooks_OnDuck_Post );
@@ -41,6 +50,13 @@ void HookGameMovementFunctions()
4150 HookGameMovementFunction (H_OnJump , " CCSGameMovement::OnJump" , DHooks_OnJump_Pre , DHooks_OnJump_Post );
4251 HookGameMovementFunction (H_OnPlayerMove , " CCSGameMovement::PlayerMove" , DHooks_OnPlayerMove_Pre , DHooks_OnPlayerMove_Post );
4352 HookGameMovementFunction (H_OnCategorizePosition , " CGameMovement::CategorizePosition" , DHooks_OnCategorizePosition_Pre , DHooks_OnCategorizePosition_Post );
53+ HookGameMovementFunction (H_OnTryPlayerMove , " CGameMovement::TryPlayerMove" , DHooks_OnTryPlayerMove_Pre , DHooks_OnTryPlayerMove_Post );
54+
55+ moveHelperAddr = GameConfGetAddress (gH_GameData , " sm_pSingleton" );
56+ if (! moveHelperAddr )
57+ {
58+ SetFailState (" Failed to find IMoveHelper::sm_pSingleton." );
59+ }
4460}
4561
4662Action UpdateMoveData (Address pThis , int client , Function func )
@@ -429,7 +445,7 @@ public MRESReturn DHooks_OnPlayerMove_Post(Address pThis)
429445 return MRES_Ignored ;
430446 }
431447 Action result = UpdateMoveData (pThis , client , Call_OnPlayerMovePost );
432-
448+ tryPlayerMoveThisTick = false ;
433449 if (result != Plugin_Continue )
434450 {
435451 return MRES_Handled ;
@@ -513,8 +529,74 @@ public MRESReturn DHooks_OnCategorizePosition_Post(Address pThis)
513529 }
514530}
515531
532+ public MRESReturn DHooks_OnTryPlayerMove_Pre (Address pThis , DHookReturn hReturn , DHookParam hParams )
533+ {
534+ int client = GetClientFromGameMovementAddress (pThis );
535+ if (! IsPlayerAlive (client ) || IsFakeClient (client ))
536+ {
537+ return MRES_Ignored ;
538+ }
539+ Action result = UpdateMoveData (pThis , client , Call_OnTryPlayerMovePre );
540+
541+ for (int i = 0 ; i < MAX_BUMPS ; i ++ )
542+ {
543+ gF_TraceStartOrigin [client ][i ] = NULL_VECTOR ;
544+ gF_TraceEndOrigin [client ][i ] = NULL_VECTOR ;
545+ gF_TraceNormal [client ][i ] = NULL_VECTOR ;
546+ }
547+
548+ if (result != Plugin_Continue )
549+ {
550+ return MRES_Handled ;
551+ }
552+ else
553+ {
554+ return MRES_Ignored ;
555+ }
556+ }
557+
558+ public MRESReturn DHooks_OnTryPlayerMove_Post (Address pThis , DHookReturn hReturn , DHookParam hParams )
559+ {
560+ int client = GetClientFromGameMovementAddress (pThis );
561+ if (! IsPlayerAlive (client ) || IsFakeClient (client ))
562+ {
563+ return MRES_Ignored ;
564+ }
565+
566+ tryPlayerMoveThisTick = true ;
567+ gI_CollisionCount [client ] = LoadFromAddress (moveHelperAddr + view_as <Address >(8 ) + view_as <Address >(12 ), NumberType_Int32 );
568+
569+ Address m_TouchList_m_pElements = LoadFromAddress (moveHelperAddr + view_as <Address >(8 ) + view_as <Address >(16 ), NumberType_Int32 );
570+
571+ for (int i = 0 ; i < gI_CollisionCount [client ]; i ++ )
572+ {
573+ Trace trace = Trace (m_TouchList_m_pElements + view_as <Address >(i * 96 ) + view_as <Address >(12 ));
574+ trace .startpos .ToArray (gF_TraceStartOrigin [client ][i ]);
575+ trace .endpos .ToArray (gF_TraceEndOrigin [client ][i ]);
576+ trace .plane .normal .ToArray (gF_TraceNormal [client ][i ]);
577+ }
578+
579+ Action result = UpdateMoveData (pThis , client , Call_OnTryPlayerMovePost );
580+ if (result != Plugin_Continue )
581+ {
582+ return MRES_Handled ;
583+ }
584+ else
585+ {
586+ return MRES_Ignored ;
587+ }
588+ }
589+
516590static void NobugLandingOrigin (int client , float landingOrigin [3 ])
517591{
592+ // Jump is bugged, try to use the trace result of TryPlayerMove if possible.
593+ if (tryPlayerMoveThisTick && gI_CollisionCount [client ] > 0 )
594+ {
595+ landingOrigin = gF_TraceEndOrigin [client ][0 ];
596+ return ;
597+ }
598+ // Fallback when no collision happened during TryPlayerMove, or that function was not called.
599+
518600 // NOTE: Get ground position and distance to ground.
519601 float groundEndPoint [3 ];
520602 groundEndPoint = gF_Origin [client ];
0 commit comments