/* * CSB Respawn On Join * Copyright (C) 2026 counter-strike-boost.com * * Players who join a team mid-round are respawned right away instead of waiting * for the next round. The respawn goes through Ham_CS_RoundRespawn, the player * gets a few seconds of spawn protection (godmode + a glow), and an end-of-round * guard stops it from spawning people into a round that is about to end. * * 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 #include new const PLUGIN[] = "CSB Respawn On Join" new const VERSION[] = "1.0.0" new const AUTHOR[] = "counter-strike-boost.com" new g_pEnabled, g_pDelay, g_pProtect, g_pEndGuard new Float:g_fRoundStart new bool:g_bRoundActive public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) g_pEnabled = register_cvar("csb_roj_enabled", "1") g_pDelay = register_cvar("csb_roj_delay", "2.0") g_pProtect = register_cvar("csb_roj_protect", "3.0") g_pEndGuard = register_cvar("csb_roj_endguard", "20") /* seconds before round end to stop respawning */ register_event("TeamInfo", "evTeamInfo", "a") register_logevent("evRoundStart", 2, "1=Round_Start") register_logevent("evRoundEnd", 2, "1=Round_End") RegisterHam(Ham_Spawn, "player", "fwSpawnPost", 1) } public evRoundStart() { g_fRoundStart = get_gametime() g_bRoundActive = true } public evRoundEnd() { g_bRoundActive = false } /* TeamInfo fires when a player is assigned a team. arg1 = index, arg2 = team. */ public evTeamInfo() { if (!get_pcvar_num(g_pEnabled)) return new id = read_data(1) if (id < 1 || id > get_maxplayers() || !is_user_connected(id)) return new team[8] read_data(2, team, charsmax(team)) /* only real playing teams */ if (!equal(team, "TERRORIST") && !equal(team, "CT")) return /* already alive? nothing to do */ if (is_user_alive(id)) return if (!g_bRoundActive) return if (isNearRoundEnd()) return new Float:delay = get_pcvar_float(g_pDelay) if (delay < 0.1) delay = 0.1 set_task(delay, "taskRespawn", id + 20000) } bool:isNearRoundEnd() { new guard = get_pcvar_num(g_pEndGuard) if (guard <= 0) return false new Float:roundTime = get_cvar_float("mp_roundtime") * 60.0 /* mp_roundtime is in minutes */ if (roundTime <= 0.0) return false new Float:elapsed = get_gametime() - g_fRoundStart return (elapsed > (roundTime - float(guard))) } public taskRespawn(param) { new id = param - 20000 if (!is_user_connected(id) || is_user_alive(id) || !g_bRoundActive) return new team = get_user_team(id) if (team != 1 && team != 2) return ExecuteHamB(Ham_CS_RoundRespawn, id) } /* Give spawn protection on every spawn (natural or our forced one). */ public fwSpawnPost(id) { if (!get_pcvar_num(g_pEnabled) || !is_user_alive(id)) return new Float:protect = get_pcvar_float(g_pProtect) if (protect <= 0.0) return set_user_godmode(id, 1) set_user_rendering(id, kRenderFxGlowShell, 0, 200, 255, kRenderNormal, 12) set_task(protect, "taskEndProtect", id + 20000) } public taskEndProtect(param) { new id = param - 20000 if (!is_user_connected(id)) return set_user_godmode(id, 0) if (is_user_alive(id)) set_user_rendering(id, kRenderFxNone, 0, 0, 0, kRenderNormal, 16) }