void BunnyHop(CUserCmd* pCmd, CBaseUserCmdPB* pBaseCmd)
{
if (!func->movement.bBhop || !pCmd || !g_interfaces || !g_interfaces->m_entity_system)
return;
constexpr std::uint64_t kJumpMask = IN_JUMP;
const std::uint64_t cmdButtons = pCmd->nButtons.nValue;
const std::uint64_t baseButtons = (pBaseCmd && pBaseCmd->pInButtonState) ? pBaseCmd->pInButtonState->nValue : 0ULL;
if (((cmdButtons | baseButtons) & kJumpMask) == 0ULL)
return;
c_cs_player_pawn* pLocalPawn = g_interfaces->m_entity_system->get_local_pawn();
if (!pLocalPawn || !pLocalPawn->IsAlive())
return;
const int moveType = pLocalPawn->m_move_type();
if (moveType == MOVETYPE_NOCLIP || moveType == MOVETYPE_LADDER)
return;
const std::uint32_t flags = pLocalPawn->GetFlags();
if ((flags & FL_ONGROUND) != 0U)
return;
pCmd->nButtons.nValue &= ~kJumpMask;
pCmd->nButtons.nValueChanged &= ~kJumpMask;
pCmd->nButtons.nValueScroll &= ~kJumpMask;
if (pBaseCmd && pBaseCmd->pInButtonState)
{
pBaseCmd->pInButtonState->nValue &= ~kJumpMask;
pBaseCmd->pInButtonState->nValueChanged &= ~kJumpMask;
pBaseCmd->pInButtonState->nValueScroll &= ~kJumpMask;
pBaseCmd->pInButtonState->SetBits(
BUTTON_STATE_PB_BITS_BUTTONSTATE1 |
BUTTON_STATE_PB_BITS_BUTTONSTATE2 |
BUTTON_STATE_PB_BITS_BUTTONSTATE3
);
}
if (pBaseCmd && pBaseCmd->subtickMovesField.pRep)
{
for (int i = 0; i < pBaseCmd->subtickMovesField.nCurrentSize; ++i)
{
CSubtickMoveStep* step = pBaseCmd->subtickMovesField.pRep->tElements[i];
if (!step || (step->nButton & kJumpMask) == 0ULL)
continue;
step->nButton &= ~kJumpMask;
step->bPressed = false;
step->SetBits(MOVESTEP_BITS_BUTTON | MOVESTEP_BITS_PRESSED);
}
}
if (pBaseCmd)
pBaseCmd->SetBits(BASE_BITS_BUTTONPB);
}