/* * CSB Jump Stats * Copyright (C) 2026 counter-strike-boost.com * * Announces notable jumps. Every player is watched in PlayerPostThink: when they * leave the ground the takeoff origin is stored, the peak horizontal speed while * airborne is tracked, and on landing the horizontal distance covered is * measured. Jumps over a distance threshold are printed to chat, and the longest * jump on the current map is kept in an nVault, announced when it is beaten. * * 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. It is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See for details. */ #include #include #include new const PLUGIN[] = "CSB Jump Stats" new const VERSION[] = "1.0.0" new const AUTHOR[] = "counter-strike-boost.com" #if !defined FL_ONGROUND #define FL_ONGROUND (1<<9) #endif new g_pEnabled, g_pMinDist new bool:g_bInAir[33] new Float:g_fTakeoff[33][3] new Float:g_fMaxSpeed[33] new g_vault new g_szMap[32] new Float:g_fRecord new g_szRecordHolder[32] public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) g_pEnabled = register_cvar("csb_js_enabled", "1") g_pMinDist = register_cvar("csb_js_mindist", "200") register_forward(FM_PlayerPostThink, "fwPostThink") register_clcmd("say /jumprecord", "cmdRecord") register_clcmd("say_team /jumprecord", "cmdRecord") get_mapname(g_szMap, charsmax(g_szMap)) g_vault = nvault_open("csb_jumpstats") loadRecord() } public plugin_end() { nvault_close(g_vault) } loadRecord() { new key[48] formatex(key, charsmax(key), "rec_%s", g_szMap) new data[64] if (nvault_get(g_vault, key, data, charsmax(data))) { new distStr[16] strtok(data, distStr, charsmax(distStr), g_szRecordHolder, charsmax(g_szRecordHolder), '|') g_fRecord = str_to_float(distStr) } else { g_fRecord = 0.0 copy(g_szRecordHolder, charsmax(g_szRecordHolder), "nobody") } } saveRecord() { new key[48], data[64] formatex(key, charsmax(key), "rec_%s", g_szMap) formatex(data, charsmax(data), "%f|%s", g_fRecord, g_szRecordHolder) nvault_set(g_vault, key, data) } public client_putinserver(id) { g_bInAir[id] = false g_fMaxSpeed[id] = 0.0 } public fwPostThink(id) { if (!get_pcvar_num(g_pEnabled) || !is_user_alive(id)) return FMRES_IGNORED new flags = pev(id, pev_flags) new bool:onground = (flags & FL_ONGROUND) != 0 static Float:fVel[3] pev(id, pev_velocity, fVel) new Float:hspeed = floatsqroot(fVel[0] * fVel[0] + fVel[1] * fVel[1]) if (!onground) { if (!g_bInAir[id]) { g_bInAir[id] = true pev(id, pev_origin, g_fTakeoff[id]) g_fMaxSpeed[id] = hspeed } else if (hspeed > g_fMaxSpeed[id]) { g_fMaxSpeed[id] = hspeed } } else if (g_bInAir[id]) { g_bInAir[id] = false landed(id) } return FMRES_IGNORED } landed(id) { static Float:fNow[3] pev(id, pev_origin, fNow) new Float:dx = fNow[0] - g_fTakeoff[id][0] new Float:dy = fNow[1] - g_fTakeoff[id][1] new Float:dist = floatsqroot(dx * dx + dy * dy) if (dist < get_pcvar_float(g_pMinDist)) return new name[32] get_user_name(id, name, charsmax(name)) client_print(id, print_chat, "^x04[CSB]^x01 Jump: %.1f units at %.0f u/s.", dist, g_fMaxSpeed[id]) if (dist > g_fRecord) { g_fRecord = dist copy(g_szRecordHolder, charsmax(g_szRecordHolder), name) saveRecord() client_print(0, print_chat, "^x04[CSB]^x01 NEW MAP RECORD! %s jumped %.1f units!", name, dist) } } public cmdRecord(id) { client_print(id, print_chat, "^x04[CSB]^x01 Longest jump on %s: %.1f units by %s.", g_szMap, g_fRecord, g_szRecordHolder) return PLUGIN_HANDLED }