/*
* CSB Deathrun Manager
* Copyright (C) 2026 counter-strike-boost.com
*
* A deathrun game-mode core. Each round one player is picked, by a fair
* least-recently-used queue, to be the trap-controlling Terrorist; everyone
* else is a Counter-Terrorist with a knife. The Terrorist gets a configurable
* weapon to punish campers, buying is blocked and the round is won the normal
* way (kill the Terrorist, or the Terrorist wipes the runners).
*
* Inspired by Deathrun Manager by NiHiLaNTh. Independent GPL re-implementation.
*
* 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. Distributed WITHOUT ANY WARRANTY. See the GNU General
* Public License for more details: .
*/
#include
#include
#include
#include
new const PLUGIN[] = "CSB Deathrun Manager"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
new g_pEnabled, g_pTerHealth, g_pTerWeapon
new g_iPickCount[33] // times each slot has been the trap Terrorist this map
new g_iActivator // current trap Terrorist, 0 if none
new g_iMaxPlayers
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
g_pEnabled = register_cvar("csb_dr_enabled", "1")
g_pTerHealth = register_cvar("csb_dr_ter_health", "150")
g_pTerWeapon = register_cvar("csb_dr_ter_weapon", "weapon_deagle")
RegisterHam(Ham_Spawn, "player", "fwPlayerSpawnPost", 1)
// HLTV new-round event: fires once, right when the round actually starts.
register_event("HLTV", "evNewRound", "a", "1=0", "2=0")
// Kill the buy menu so the mode stays pure.
register_clcmd("buy", "blockCmd")
register_clcmd("buyammo", "blockCmd")
register_clcmd("buyequip", "blockCmd")
register_clcmd("say /dr", "cmdInfo")
g_iMaxPlayers = get_maxplayers()
set_task(1.0, "taskHud", _, _, _, "b")
}
public client_putinserver(id)
{
g_iPickCount[id] = 0
}
public client_disconnected(id)
{
if (g_iActivator == id)
g_iActivator = 0
}
public blockCmd(id)
{
return PLUGIN_HANDLED
}
public evNewRound()
{
if (!get_pcvar_num(g_pEnabled))
return
assignRoles()
}
assignRoles()
{
new players[32], num
get_players(players, num, "ch") // connected, on a team
if (num < 2)
{
g_iActivator = 0
return
}
// Fair pick: the connected player who has been Terrorist the fewest times.
new best = -1, bestCount = 999999
for (new i = 0; i < num; i++)
{
new id = players[i]
if (g_iPickCount[id] < bestCount)
{
bestCount = g_iPickCount[id]
best = id
}
}
g_iActivator = best
if (best != -1)
g_iPickCount[best]++
for (new i = 0; i < num; i++)
{
new id = players[i]
if (id == g_iActivator)
{
if (cs_get_user_team(id) != CS_TEAM_T)
cs_set_user_team(id, CS_TEAM_T)
}
else
{
if (cs_get_user_team(id) != CS_TEAM_CT)
cs_set_user_team(id, CS_TEAM_CT)
}
}
}
public fwPlayerSpawnPost(id)
{
if (!get_pcvar_num(g_pEnabled) || !is_user_alive(id))
return
new CsTeams:team = cs_get_user_team(id)
if (team == CS_TEAM_T && id == g_iActivator)
{
set_user_health(id, get_pcvar_num(g_pTerHealth))
new weapon[32]
get_pcvar_string(g_pTerWeapon, weapon, charsmax(weapon))
give_item(id, weapon)
refillWeapon(id, weapon)
}
else if (team == CS_TEAM_CT)
{
// Runners: knife only.
strip_user_weapons(id)
give_item(id, "weapon_knife")
}
cs_set_user_money(id, 0, 1)
}
refillWeapon(id, const weapon[])
{
// map the given entity name to a sensible backpack ammo amount
new csw = weaponToCsw(weapon)
if (csw > 0)
cs_set_user_bpammo(id, csw, 200)
}
weaponToCsw(const weapon[])
{
if (equal(weapon, "weapon_deagle")) return CSW_DEAGLE
if (equal(weapon, "weapon_ak47")) return CSW_AK47
if (equal(weapon, "weapon_m4a1")) return CSW_M4A1
if (equal(weapon, "weapon_awp")) return CSW_AWP
if (equal(weapon, "weapon_m249")) return CSW_M249
if (equal(weapon, "weapon_usp")) return CSW_USP
if (equal(weapon, "weapon_hegrenade")) return CSW_HEGRENADE
return 0
}
public cmdInfo(id)
{
client_print(id, print_chat, "[Deathrun] One trap-master Terrorist per round, picked by a fair queue. Runners get a knife. Buying is disabled.")
return PLUGIN_HANDLED
}
public taskHud()
{
if (!get_pcvar_num(g_pEnabled))
return
new name[32]
if (g_iActivator && is_user_connected(g_iActivator))
get_user_name(g_iActivator, name, charsmax(name))
else
copy(name, charsmax(name), "waiting...")
new players[32], num
get_players(players, num, "c")
for (new i = 0; i < num; i++)
{
set_hudmessage(255, 80, 80, 0.02, 0.15, 0, 0.0, 1.1, 0.0, 0.0, -1)
show_hudmessage(players[i], "Deathrun Trap master: %s", name)
}
}