/*
* CSB Knife Round
* Copyright (C) 2026 counter-strike-boost.com
*
* Runs a knife-only round: weapons are stripped on spawn, money is zeroed and
* the buy commands are blocked. When a team wins the knife round, that team's
* captain gets a menu to keep sides or swap, and the choice is applied with
* cs_set_user_team followed by a game restart. Works standalone or as the
* side-pick step of a match system.
*
* Independent GPL implementation written for counter-strike-boost.com.
*
* 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 the GNU General
* Public License for more details: .
*/
#include
#include
#include
#include
#include
new const PLUGIN[] = "CSB Knife Round"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
new bool:g_bActive = false
new bool:g_bDecided = false
new const g_szBuyCmds[][] =
{
"buy", "buyammo", "buyequip", "autobuy", "rebuy", "nightvision"
}
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
RegisterHam(Ham_Spawn, "player", "fwSpawnPost", 1)
register_event("HLTV", "eNewRound", "a", "1=0", "2=0")
register_event("SendAudio", "eTerWin", "a", "2&%!MRAD_terwin")
register_event("SendAudio", "eCtWin", "a", "2&%!MRAD_ctwin")
register_clcmd("csb_kniferound", "cmdStart", ADMIN_LEVEL_A, "- start a knife round with a side-pick at the end")
register_clcmd("say /knife", "cmdStart", ADMIN_LEVEL_A)
register_clcmd("fullupdate", "blockBuy")
for (new i = 0; i < sizeof(g_szBuyCmds); i++)
register_clcmd(g_szBuyCmds[i], "blockBuy")
}
public cmdStart(id, level, cid)
{
if (!cmd_access(id, level, cid, 1))
return PLUGIN_HANDLED
g_bActive = true
g_bDecided = false
client_print(0, print_chat, "[CSB] Knife round! Winning team picks the sides.")
server_cmd("sv_restartround 1")
return PLUGIN_HANDLED
}
public eNewRound()
{
/* strip everyone again at the start of the knife round proper */
if (!g_bActive)
return
new players[32], num
get_players(players, num, "a")
for (new i = 0; i < num; i++)
stripToKnife(players[i])
}
public fwSpawnPost(id)
{
if (!g_bActive || !is_user_alive(id))
return
stripToKnife(id)
}
stripToKnife(id)
{
if (!is_user_alive(id))
return
strip_user_weapons(id)
give_item(id, "weapon_knife")
cs_set_user_money(id, 0, 1)
}
public blockBuy(id)
{
if (g_bActive)
{
client_print(id, print_center, "Knife round - buying is disabled")
return PLUGIN_HANDLED
}
return PLUGIN_CONTINUE
}
/* ---------- deciding sides ---------- */
public eTerWin()
{
onTeamWin(CS_TEAM_T)
}
public eCtWin()
{
onTeamWin(CS_TEAM_CT)
}
onTeamWin(CsTeams:team)
{
if (!g_bActive || g_bDecided)
return
g_bDecided = true
new captain = findCaptain(team)
if (!captain)
{
/* nobody left on the winning team to decide - just end the knife round */
endKnife()
client_print(0, print_chat, "[CSB] Knife round over - no captain found, sides kept.")
return
}
new tname[32]
get_user_name(captain, tname, charsmax(tname))
client_print(0, print_chat, "[CSB] %s (%s) is picking the sides...",
tname, (team == CS_TEAM_T) ? "T" : "CT")
showPickMenu(captain)
}
findCaptain(CsTeams:team)
{
new players[32], num
get_players(players, num, "c") // connected, skip HLTV
for (new i = 0; i < num; i++)
{
if (cs_get_user_team(players[i]) == team)
return players[i]
}
return 0
}
showPickMenu(id)
{
new menu = menu_create("\yKnife Round won!^n\wPick the sides", "handlerPick")
menu_additem(menu, "\wStay on the current sides", "1", 0)
menu_additem(menu, "\rSwap sides", "2", 0)
menu_setprop(menu, MPROP_EXIT, MEXIT_NEVER)
menu_display(id, menu, 0)
}
public handlerPick(id, menu, item)
{
if (item == MENU_EXIT)
{
menu_destroy(menu)
return PLUGIN_HANDLED
}
new info[4], name[32], access, callback
menu_item_getinfo(menu, item, access, info, charsmax(info), name, charsmax(name), callback)
menu_destroy(menu)
if (str_to_num(info) == 2)
{
swapAllSides()
client_print(0, print_chat, "[CSB] Sides swapped. Get ready!")
}
else
{
client_print(0, print_chat, "[CSB] Sides kept. Get ready!")
}
endKnife()
server_cmd("sv_restartround 3")
return PLUGIN_HANDLED
}
swapAllSides()
{
new players[32], num
get_players(players, num, "c")
for (new i = 0; i < num; i++)
{
new id = players[i]
new CsTeams:team = cs_get_user_team(id)
if (is_user_alive(id))
user_kill(id, 1)
if (team == CS_TEAM_T)
cs_set_user_team(id, CS_TEAM_CT)
else if (team == CS_TEAM_CT)
cs_set_user_team(id, CS_TEAM_T)
}
}
endKnife()
{
g_bActive = false
g_bDecided = false
}