/*
* CSB Bunny Hop
* Copyright (C) 2026 counter-strike-boost.com
*
* Server-side auto bunny hop. While +jump is held, the plugin re-applies the
* jump the instant the player lands: in a PlayerPreThink hook it detects the
* ON_GROUND frame, sets the upward jump velocity and clears the ground flag so
* the engine never adds the usual landing friction. Includes a horizontal speed
* cap, team/flag gating and a per-player /bhop toggle.
*
* Inspired by the well-known "Auto BunnyHop" plugin by ConnorMcLeod. This is an
* independent GPL re-implementation; no original code is reused.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version. See for details.
*/
#include
#include
new const PLUGIN[] = "CSB Bunny Hop"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
new g_pEnabled, g_pFlag, g_pTeam, g_pMaxSpeed, g_pAllowToggle
new bool:g_bWantsBhop[33] /* per-player /bhop preference, default on */
new g_iAllowFlags
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
g_pEnabled = register_cvar("csb_bhop_enabled", "1")
g_pFlag = register_cvar("csb_bhop_flag", "") /* empty = everyone */
g_pTeam = register_cvar("csb_bhop_team", "0") /* 0 = any, 1 = T, 2 = CT */
g_pMaxSpeed = register_cvar("csb_bhop_maxspeed", "0") /* 0 = uncapped */
g_pAllowToggle = register_cvar("csb_bhop_allow_toggle", "1")
register_clcmd("say /bhop", "cmdToggle")
register_clcmd("say_team /bhop", "cmdToggle")
register_forward(FM_PlayerPreThink, "fwPreThink")
}
public plugin_cfg()
{
new flagStr[8]
get_pcvar_string(g_pFlag, flagStr, charsmax(flagStr))
g_iAllowFlags = read_flags(flagStr)
}
public client_connect(id)
{
g_bWantsBhop[id] = true
}
bool:isAllowed(id)
{
if (g_iAllowFlags != 0 && !(get_user_flags(id) & g_iAllowFlags))
return false
new team = get_pcvar_num(g_pTeam)
if (team != 0 && get_user_team(id) != team)
return false
return true
}
public cmdToggle(id)
{
if (!get_pcvar_num(g_pAllowToggle))
{
client_print_color(id, print_team_default, "^x04[CSB]^x01 The bunny hop toggle is disabled on this server.")
return PLUGIN_HANDLED
}
g_bWantsBhop[id] = !g_bWantsBhop[id]
client_print_color(id, print_team_default, "^x04[CSB]^x01 Auto bunny hop is now^x04 %s^x01 for you.",
g_bWantsBhop[id] ? "ON" : "OFF")
return PLUGIN_HANDLED
}
public fwPreThink(id)
{
if (!get_pcvar_num(g_pEnabled) || !is_user_alive(id))
return FMRES_IGNORED
if (!g_bWantsBhop[id] || !isAllowed(id))
return FMRES_IGNORED
new button = pev(id, pev_button)
/* only bhop while the player is actively holding jump */
if (!(button & IN_JUMP))
return FMRES_IGNORED
new flags = pev(id, pev_flags)
if (!(flags & FL_ONGROUND))
return FMRES_IGNORED
/* the player is on the ground with jump held: bounce them again */
new Float:velocity[3]
pev(id, pev_velocity, velocity)
new maxSpeed = get_pcvar_num(g_pMaxSpeed)
if (maxSpeed > 0)
{
new Float:horiz = floatsqroot(velocity[0] * velocity[0] + velocity[1] * velocity[1])
if (horiz > float(maxSpeed) && horiz > 0.0)
{
new Float:scale = float(maxSpeed) / horiz
velocity[0] *= scale
velocity[1] *= scale
}
}
velocity[2] = 265.0
set_pev(id, pev_velocity, velocity)
set_pev(id, pev_flags, flags & ~FL_ONGROUND)
return FMRES_IGNORED
}