/* * CSB Semiclip * Copyright (C) 2026 counter-strike-boost.com * * Lets teammates pass through each other instead of blocking. During each * player's physics window (between his PreThink and PostThink) every close * teammate is temporarily made non-solid, so movement never collides with a * friend; the solidity is restored immediately after. AddToFullPack mirrors * the non-solid state into that client's own prediction so there is no * client-side jitter. Shooting is unaffected because the change only lasts for * the owner's own physics step. Essential on Deathrun, KZ, HNS and Jailbreak. * * Inspired by the classic "Semiclip" 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. 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 new const PLUGIN[] = "CSB Semiclip" new const VERSION[] = "1.0.0" new const AUTHOR[] = "counter-strike-boost.com" #define SOLID_NOT 0 #define SOLID_SLIDEBOX 3 new g_pEnabled, g_pTeamOnly, g_pRange new g_iMaxPlayers new g_iSaved[33] /* saved pev_solid while non-solid, -1 = untouched */ public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) g_pEnabled = register_cvar("csb_semiclip", "1") g_pTeamOnly = register_cvar("csb_semiclip_teamonly", "1") g_pRange = register_cvar("csb_semiclip_range", "160") register_forward(FM_PlayerPreThink, "fw_PreThink") register_forward(FM_PlayerPostThink, "fw_PostThink") register_forward(FM_AddToFullPack, "fw_AddToFullPack", 1) g_iMaxPlayers = get_maxplayers() for (new i = 1; i <= 32; i++) g_iSaved[i] = -1 } /* Make close teammates non-solid for the duration of id's physics step. */ public fw_PreThink(id) { if (!get_pcvar_num(g_pEnabled) || !is_user_alive(id)) return FMRES_IGNORED new Float:range = get_pcvar_float(g_pRange) new bool:teamOnly = get_pcvar_num(g_pTeamOnly) != 0 new team = get_user_team(id) new Float:oPos[3], Float:tPos[3] pev(id, pev_origin, oPos) for (new i = 1; i <= g_iMaxPlayers; i++) { if (i == id || !is_user_alive(i)) continue if (teamOnly && get_user_team(i) != team) continue pev(i, pev_origin, tPos) if (range > 0.0 && get_distance_f(oPos, tPos) > range) continue if (g_iSaved[i] != -1) /* already made non-solid this step */ continue g_iSaved[i] = pev(i, pev_solid) set_pev(i, pev_solid, SOLID_NOT) } return FMRES_IGNORED } /* Restore everything we touched once id's movement has been resolved. */ public fw_PostThink(id) { for (new i = 1; i <= g_iMaxPlayers; i++) { if (g_iSaved[i] == -1) continue if (pev_valid(i)) set_pev(i, pev_solid, g_iSaved[i]) g_iSaved[i] = -1 } return FMRES_IGNORED } /* Kill client-side collision prediction between teammates. */ public fw_AddToFullPack(es, e, ent, host, hostflags, player, pSet) { if (!get_pcvar_num(g_pEnabled)) return FMRES_IGNORED if (ent < 1 || ent > g_iMaxPlayers || host < 1 || host > g_iMaxPlayers || ent == host) return FMRES_IGNORED if (!is_user_alive(ent) || !is_user_alive(host)) return FMRES_IGNORED if (get_pcvar_num(g_pTeamOnly) && get_user_team(ent) != get_user_team(host)) return FMRES_IGNORED set_es(es, ES_Solid, SOLID_NOT) return FMRES_HANDLED } public client_disconnected(id) { g_iSaved[id] = -1 }