/*
* CSB Multi Jump
* Copyright (C) 2026 counter-strike-boost.com
*
* Gives players N extra jumps in mid-air. In a PlayerPreThink hook the plugin
* watches for a fresh +jump press while the player is off the ground and, if
* jumps remain, launches them upward again. The number of extra jumps is
* configurable and can be gated to a team or an admin flag. The counter resets
* the moment the player touches the ground.
*
* Inspired by the well-known "Multi Jump" plugin by VEN. 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 Multi Jump"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
new g_pEnabled, g_pMax, g_pImpulse, g_pFlag, g_pTeam
new g_iJumpsDone[33]
new bool:g_bOnGround[33]
new g_iAllowFlags
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
g_pEnabled = register_cvar("csb_mj_enabled", "1")
g_pMax = register_cvar("csb_mj_max", "1") /* extra jumps after the first */
g_pImpulse = register_cvar("csb_mj_impulse", "265.0")
g_pFlag = register_cvar("csb_mj_flag", "") /* empty = everyone */
g_pTeam = register_cvar("csb_mj_team", "0") /* 0 = any, 1 = T, 2 = CT */
register_forward(FM_PlayerPreThink, "fwPreThink")
}
public plugin_cfg()
{
new flagStr[8]
get_pcvar_string(g_pFlag, flagStr, charsmax(flagStr))
g_iAllowFlags = read_flags(flagStr)
}
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 fwPreThink(id)
{
if (!get_pcvar_num(g_pEnabled) || !is_user_alive(id))
return FMRES_IGNORED
new flags = pev(id, pev_flags)
if (flags & FL_ONGROUND)
{
/* just landed: refill the jump budget */
g_iJumpsDone[id] = 0
g_bOnGround[id] = true
return FMRES_IGNORED
}
/* airborne from here on */
new button = pev(id, pev_button)
new oldButton = pev(id, pev_oldbuttons)
/* first frame after leaving the ground counts as the normal jump */
if (g_bOnGround[id])
{
g_bOnGround[id] = false
return FMRES_IGNORED
}
/* only a fresh press, not a held key */
if (!(button & IN_JUMP) || (oldButton & IN_JUMP))
return FMRES_IGNORED
if (!isAllowed(id))
return FMRES_IGNORED
if (g_iJumpsDone[id] >= get_pcvar_num(g_pMax))
return FMRES_IGNORED
g_iJumpsDone[id]++
new Float:velocity[3]
pev(id, pev_velocity, velocity)
velocity[2] = get_pcvar_float(g_pImpulse)
set_pev(id, pev_velocity, velocity)
return FMRES_IGNORED
}