Add CS2-valid movement features (W release, instant strafe, snap tap, minijump, subtick-perfect crouch jump)
This commit is contained in:
@@ -537,6 +537,9 @@ auto CMisc::RunMovement( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
|
|||||||
|
|
||||||
const bool bOnGround = ( flFlags & FL_ONGROUND ) != 0;
|
const bool bOnGround = ( flFlags & FL_ONGROUND ) != 0;
|
||||||
|
|
||||||
|
if ( Settings::Misc::SnapTap )
|
||||||
|
RunSnapTap( pUserCmd );
|
||||||
|
|
||||||
if ( Settings::Misc::SubtickStrafe )
|
if ( Settings::Misc::SubtickStrafe )
|
||||||
RunSubtickStrafe( pInput , pUserCmd , pLocalPawn , bOnGround );
|
RunSubtickStrafe( pInput , pUserCmd , pLocalPawn , bOnGround );
|
||||||
else if ( Settings::Misc::NullStrafe )
|
else if ( Settings::Misc::NullStrafe )
|
||||||
@@ -565,12 +568,30 @@ auto CMisc::RunMovement( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool bJumpHeld = ( pUserCmd->button_states.buttonstate1 & IN_JUMP ) != 0;
|
||||||
|
const bool bJumpEdge = bJumpHeld && !m_bWasJumping;
|
||||||
|
|
||||||
if ( Settings::Misc::JumpCrouch )
|
if ( Settings::Misc::JumpCrouch )
|
||||||
{
|
{
|
||||||
if ( bOnGround && ( pUserCmd->button_states.buttonstate1 & IN_JUMP ) )
|
if ( bOnGround && bJumpHeld )
|
||||||
|
{
|
||||||
pUserCmd->button_states.buttonstate1 |= IN_DUCK;
|
pUserCmd->button_states.buttonstate1 |= IN_DUCK;
|
||||||
|
pUserCmd->cmd.mutable_base()->mutable_buttons_pb()->set_buttonstate1( pUserCmd->button_states.buttonstate1 );
|
||||||
|
|
||||||
|
GetCL_Bypass()->AddProcessSubTick( IN_DUCK , true , 0.0f );
|
||||||
|
GetCL_Bypass()->AddProcessSubTick( IN_JUMP , true , 0.0f );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( Settings::Misc::WRelease )
|
||||||
|
RunWRelease( pUserCmd , bOnGround );
|
||||||
|
|
||||||
|
if ( Settings::Misc::InstantStrafe )
|
||||||
|
RunInstantStrafe( pUserCmd , bOnGround , bJumpEdge );
|
||||||
|
|
||||||
|
if ( Settings::Misc::Minijump )
|
||||||
|
RunMinijump( pUserCmd , bOnGround , bJumpEdge );
|
||||||
|
|
||||||
if ( Settings::Misc::LongJump )
|
if ( Settings::Misc::LongJump )
|
||||||
{
|
{
|
||||||
if ( !bOnGround )
|
if ( !bOnGround )
|
||||||
@@ -636,6 +657,7 @@ auto CMisc::RunMovement( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void
|
|||||||
pUserCmd->button_states.buttonstate1 |= IN_SPEED;
|
pUserCmd->button_states.buttonstate1 |= IN_SPEED;
|
||||||
|
|
||||||
m_bWasOnGround = bOnGround;
|
m_bWasOnGround = bOnGround;
|
||||||
|
m_bWasJumping = ( pUserCmd->button_states.buttonstate1 & IN_JUMP ) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CMisc::RunAutoStrafe( CCSGOInput* pInput , CUserCmd* pUserCmd , C_CSPlayerPawn* pLocalPawn , bool bOnGround ) -> void
|
auto CMisc::RunAutoStrafe( CCSGOInput* pInput , CUserCmd* pUserCmd , C_CSPlayerPawn* pLocalPawn , bool bOnGround ) -> void
|
||||||
@@ -928,6 +950,117 @@ auto CMisc::RotateMoveToYaw( CBaseUserCmdPB* pBaseCmd , const float flTargetYaw
|
|||||||
pBaseCmd->set_leftmove( std::clamp( -flCorrectedSide , -1.f , 1.f ) );
|
pBaseCmd->set_leftmove( std::clamp( -flCorrectedSide , -1.f , 1.f ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto CMisc::RunSnapTap( CUserCmd* pUserCmd ) -> void
|
||||||
|
{
|
||||||
|
if ( !pUserCmd )
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto& uButtons = pUserCmd->button_states.buttonstate1;
|
||||||
|
|
||||||
|
const bool bLeft = ( uButtons & IN_MOVELEFT ) != 0;
|
||||||
|
const bool bRight = ( uButtons & IN_MOVERIGHT ) != 0;
|
||||||
|
const bool bForward = ( uButtons & IN_FORWARD ) != 0;
|
||||||
|
const bool bBack = ( uButtons & IN_BACK ) != 0;
|
||||||
|
|
||||||
|
// Newest key wins: pressing A while D is held releases D and vice versa.
|
||||||
|
if ( bLeft && m_bRightHeld && !m_bLeftHeld )
|
||||||
|
uButtons &= ~IN_MOVERIGHT;
|
||||||
|
|
||||||
|
if ( bRight && m_bLeftHeld && !m_bRightHeld )
|
||||||
|
uButtons &= ~IN_MOVELEFT;
|
||||||
|
|
||||||
|
if ( bForward && m_bBackHeld && !m_bForwardHeld )
|
||||||
|
uButtons &= ~IN_BACK;
|
||||||
|
|
||||||
|
if ( bBack && m_bForwardHeld && !m_bBackHeld )
|
||||||
|
uButtons &= ~IN_FORWARD;
|
||||||
|
|
||||||
|
pUserCmd->cmd.mutable_base()->mutable_buttons_pb()->set_buttonstate1( uButtons );
|
||||||
|
|
||||||
|
m_bLeftHeld = ( uButtons & IN_MOVELEFT ) != 0;
|
||||||
|
m_bRightHeld = ( uButtons & IN_MOVERIGHT ) != 0;
|
||||||
|
m_bForwardHeld = ( uButtons & IN_FORWARD ) != 0;
|
||||||
|
m_bBackHeld = ( uButtons & IN_BACK ) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto CMisc::RunWRelease( CUserCmd* pUserCmd , bool bOnGround ) -> void
|
||||||
|
{
|
||||||
|
if ( !pUserCmd )
|
||||||
|
return;
|
||||||
|
|
||||||
|
constexpr int k_ReleaseTicks = 2;
|
||||||
|
|
||||||
|
if ( bOnGround )
|
||||||
|
{
|
||||||
|
if ( pUserCmd->button_states.buttonstate1 & IN_JUMP )
|
||||||
|
m_iWReleaseTicks = k_ReleaseTicks;
|
||||||
|
else
|
||||||
|
m_iWReleaseTicks = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_iWReleaseTicks > 0 )
|
||||||
|
{
|
||||||
|
auto& uButtons = pUserCmd->button_states.buttonstate1;
|
||||||
|
|
||||||
|
uButtons &= ~IN_FORWARD;
|
||||||
|
|
||||||
|
pUserCmd->cmd.mutable_base()->set_forwardmove( 0.f );
|
||||||
|
pUserCmd->cmd.mutable_base()->mutable_buttons_pb()->set_buttonstate1( uButtons );
|
||||||
|
|
||||||
|
GetCL_Bypass()->AddProcessSubTick( IN_FORWARD , false , 0.01f , 0.f , 0.f );
|
||||||
|
|
||||||
|
--m_iWReleaseTicks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto CMisc::RunInstantStrafe( CUserCmd* pUserCmd , bool bOnGround , bool bJumpEdge ) -> void
|
||||||
|
{
|
||||||
|
if ( !pUserCmd )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( !bOnGround || !bJumpEdge )
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto uButtons = pUserCmd->button_states.buttonstate1;
|
||||||
|
|
||||||
|
if ( uButtons & IN_MOVELEFT )
|
||||||
|
GetCL_Bypass()->AddProcessSubTick( IN_MOVELEFT , true , 0.01f );
|
||||||
|
|
||||||
|
if ( uButtons & IN_MOVERIGHT )
|
||||||
|
GetCL_Bypass()->AddProcessSubTick( IN_MOVERIGHT , true , 0.01f );
|
||||||
|
|
||||||
|
if ( uButtons & IN_FORWARD )
|
||||||
|
GetCL_Bypass()->AddProcessSubTick( IN_FORWARD , true , 0.01f );
|
||||||
|
|
||||||
|
if ( uButtons & IN_BACK )
|
||||||
|
GetCL_Bypass()->AddProcessSubTick( IN_BACK , true , 0.01f );
|
||||||
|
}
|
||||||
|
|
||||||
|
auto CMisc::RunMinijump( CUserCmd* pUserCmd , bool bOnGround , bool bJumpEdge ) -> void
|
||||||
|
{
|
||||||
|
if ( !pUserCmd )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( bOnGround && bJumpEdge )
|
||||||
|
{
|
||||||
|
// Crouch-jump for a single tiny hop (minijump) instead of a full jump.
|
||||||
|
GetCL_Bypass()->AddProcessSubTick( IN_DUCK , true , 0.0f );
|
||||||
|
GetCL_Bypass()->AddProcessSubTick( IN_JUMP , true , 0.0f );
|
||||||
|
|
||||||
|
m_iMinijumpForceRelease = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_iMinijumpForceRelease > 0 )
|
||||||
|
{
|
||||||
|
if ( !bOnGround )
|
||||||
|
GetCL_Bypass()->SetDontJump( pUserCmd , true );
|
||||||
|
|
||||||
|
--m_iMinijumpForceRelease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto CMisc::RunEdgeBug( CCSGOInput* pInput , CUserCmd* pUserCmd , C_CSPlayerPawn* pLocalPawn , bool bOnGround ) -> void
|
auto CMisc::RunEdgeBug( CCSGOInput* pInput , CUserCmd* pUserCmd , C_CSPlayerPawn* pLocalPawn , bool bOnGround ) -> void
|
||||||
{
|
{
|
||||||
if ( bOnGround )
|
if ( bOnGround )
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ private:
|
|||||||
auto RunNullStrafe( CCSGOInput* pInput , CUserCmd* pUserCmd , C_CSPlayerPawn* pLocalPawn , bool bOnGround ) -> void;
|
auto RunNullStrafe( CCSGOInput* pInput , CUserCmd* pUserCmd , C_CSPlayerPawn* pLocalPawn , bool bOnGround ) -> void;
|
||||||
auto RunSubtickStrafe( CCSGOInput* pInput , CUserCmd* pUserCmd , C_CSPlayerPawn* pLocalPawn , bool bOnGround ) -> void;
|
auto RunSubtickStrafe( CCSGOInput* pInput , CUserCmd* pUserCmd , C_CSPlayerPawn* pLocalPawn , bool bOnGround ) -> void;
|
||||||
auto RunEdgeBug( CCSGOInput* pInput , CUserCmd* pUserCmd , C_CSPlayerPawn* pLocalPawn , bool bOnGround ) -> void;
|
auto RunEdgeBug( CCSGOInput* pInput , CUserCmd* pUserCmd , C_CSPlayerPawn* pLocalPawn , bool bOnGround ) -> void;
|
||||||
|
auto RunSnapTap( CUserCmd* pUserCmd ) -> void;
|
||||||
|
auto RunWRelease( CUserCmd* pUserCmd , bool bOnGround ) -> void;
|
||||||
|
auto RunInstantStrafe( CUserCmd* pUserCmd , bool bOnGround , bool bJumpEdge ) -> void;
|
||||||
|
auto RunMinijump( CUserCmd* pUserCmd , bool bOnGround , bool bJumpEdge ) -> void;
|
||||||
auto RotateMoveToYaw( CBaseUserCmdPB* pBaseCmd , const float flTargetYaw , const float flViewYaw ) -> void;
|
auto RotateMoveToYaw( CBaseUserCmdPB* pBaseCmd , const float flTargetYaw , const float flViewYaw ) -> void;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -64,6 +68,15 @@ private:
|
|||||||
bool m_bSideSwitch = false;
|
bool m_bSideSwitch = false;
|
||||||
float m_flLastForwardMove = 0.f;
|
float m_flLastForwardMove = 0.f;
|
||||||
float m_flLastLeftMove = 0.f;
|
float m_flLastLeftMove = 0.f;
|
||||||
|
|
||||||
|
bool m_bWasJumping = false;
|
||||||
|
int m_iWReleaseTicks = 0;
|
||||||
|
int m_iMinijumpForceRelease = 0;
|
||||||
|
|
||||||
|
bool m_bLeftHeld = false;
|
||||||
|
bool m_bRightHeld = false;
|
||||||
|
bool m_bForwardHeld = false;
|
||||||
|
bool m_bBackHeld = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto GetMisc() -> CMisc*;
|
auto GetMisc() -> CMisc*;
|
||||||
|
|||||||
@@ -336,10 +336,14 @@ auto CAndromedaMenu::RenderMiscPanel() -> void
|
|||||||
Checkbox( "Auto-Strafe" , Settings::Misc::AutoStrafe );
|
Checkbox( "Auto-Strafe" , Settings::Misc::AutoStrafe );
|
||||||
Checkbox( "Null-Strafe" , Settings::Misc::NullStrafe );
|
Checkbox( "Null-Strafe" , Settings::Misc::NullStrafe );
|
||||||
Checkbox( "SubTick-Strafe" , Settings::Misc::SubtickStrafe );
|
Checkbox( "SubTick-Strafe" , Settings::Misc::SubtickStrafe );
|
||||||
|
Checkbox( "W-Release" , Settings::Misc::WRelease );
|
||||||
|
Checkbox( "Instant Strafe" , Settings::Misc::InstantStrafe );
|
||||||
|
Checkbox( "Snap Tap" , Settings::Misc::SnapTap );
|
||||||
Checkbox( "JumpBug" , Settings::Misc::JumpBug );
|
Checkbox( "JumpBug" , Settings::Misc::JumpBug );
|
||||||
Checkbox( "EdgeBug" , Settings::Misc::EdgeBug );
|
Checkbox( "EdgeBug" , Settings::Misc::EdgeBug );
|
||||||
Checkbox( "EdgeJump" , Settings::Misc::EdgeJump );
|
Checkbox( "EdgeJump" , Settings::Misc::EdgeJump );
|
||||||
Checkbox( "JumpCrouch" , Settings::Misc::JumpCrouch );
|
Checkbox( "JumpCrouch" , Settings::Misc::JumpCrouch );
|
||||||
|
Checkbox( "Minijump" , Settings::Misc::Minijump );
|
||||||
Checkbox( "Fast-Stop" , Settings::Misc::FastStop );
|
Checkbox( "Fast-Stop" , Settings::Misc::FastStop );
|
||||||
Checkbox( "LongJump" , Settings::Misc::LongJump );
|
Checkbox( "LongJump" , Settings::Misc::LongJump );
|
||||||
Checkbox( "Pixel Surf" , Settings::Misc::PixelSurf );
|
Checkbox( "Pixel Surf" , Settings::Misc::PixelSurf );
|
||||||
|
|||||||
@@ -48,10 +48,14 @@ namespace Settings
|
|||||||
inline auto AutoStrafe = false;
|
inline auto AutoStrafe = false;
|
||||||
inline auto NullStrafe = false;
|
inline auto NullStrafe = false;
|
||||||
inline auto SubtickStrafe = false;
|
inline auto SubtickStrafe = false;
|
||||||
|
inline auto WRelease = false;
|
||||||
|
inline auto InstantStrafe = false;
|
||||||
|
inline auto SnapTap = false;
|
||||||
inline auto JumpBug = false;
|
inline auto JumpBug = false;
|
||||||
inline auto EdgeBug = false;
|
inline auto EdgeBug = false;
|
||||||
inline auto EdgeJump = false;
|
inline auto EdgeJump = false;
|
||||||
inline auto JumpCrouch = false;
|
inline auto JumpCrouch = false;
|
||||||
|
inline auto Minijump = false;
|
||||||
inline auto FastStop = false;
|
inline auto FastStop = false;
|
||||||
inline auto LongJump = false;
|
inline auto LongJump = false;
|
||||||
inline auto PixelSurf = false;
|
inline auto PixelSurf = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user