/*
* CSB Overtime Handler
* Copyright (C) 2026 counter-strike-boost.com
*
* Keeps its own copy of the round score (from the CT/T win audio events) and,
* when regulation ends on a tie, starts an overtime: it raises mp_maxrounds by
* an OT block, sets a fresh OT start money and restarts the round. Overtimes
* repeat until one side is ahead. The live score and the current OT number are
* shown in a HUD sync message.
*
* 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
new const PLUGIN[] = "CSB Overtime Handler"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
#define TEAM_T 0
#define TEAM_CT 1
new g_pEnabled, g_pOtRounds, g_pOtMoney
new g_iScore[2]
new g_iOT
new g_iSync
new bool:g_bOtActive
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
g_pEnabled = register_cvar("csb_ot_enabled", "1")
g_pOtRounds = register_cvar("csb_ot_rounds", "3")
g_pOtMoney = register_cvar("csb_ot_money", "10000")
/* who won the round, from the radio win audio */
register_event("SendAudio", "eventTerWin", "a", "2=%!MRAD_terwin")
register_event("SendAudio", "eventCtWin", "a", "2=%!MRAD_ctwin")
register_logevent("eventRestart", 2, "1=World triggered", "2=Restart_Round_(1_second)")
g_iSync = CreateHudSyncObj()
set_task(1.0, "taskHud", 0, _, _, "b")
}
public eventTerWin()
{
onWin(TEAM_T)
}
public eventCtWin()
{
onWin(TEAM_CT)
}
onWin(team)
{
if (!get_pcvar_num(g_pEnabled))
return
g_iScore[team]++
checkRegulationEnd()
}
checkRegulationEnd()
{
new maxr = get_cvar_num("mp_maxrounds")
if (maxr <= 0)
return
new played = g_iScore[TEAM_T] + g_iScore[TEAM_CT]
if (played < maxr)
return
/* regulation (or a previous OT) is over */
if (g_iScore[TEAM_T] == g_iScore[TEAM_CT])
startOvertime()
}
startOvertime()
{
g_iOT++
g_bOtActive = true
new otRounds = get_pcvar_num(g_pOtRounds)
if (otRounds < 1)
otRounds = 3
/* an OT block is played on both sides -> two half-blocks */
new newMax = get_cvar_num("mp_maxrounds") + otRounds * 2
set_cvar_num("mp_maxrounds", newMax)
new money = get_pcvar_num(g_pOtMoney)
set_cvar_num("mp_startmoney", money)
client_print(0, print_chat, "[CSB] Scores tied %d-%d. Starting OVERTIME #%d (MR%d, $%d start).",
g_iScore[TEAM_T], g_iScore[TEAM_CT], g_iOT, otRounds, money)
/* restart the round to apply money and freeze */
set_cvar_num("sv_restart", 1)
}
public eventRestart()
{
/* nothing to reset here; score is kept across restarts on purpose */
return
}
public taskHud()
{
if (!get_pcvar_num(g_pEnabled))
return
set_hudmessage(0, 200, 255, 0.02, 0.15, 0, 0.0, 1.2, 0.0, 0.0, -1)
if (g_bOtActive)
ShowSyncHudMsg(0, g_iSync, "OVERTIME #%d^nT %d - %d CT", g_iOT, g_iScore[TEAM_T], g_iScore[TEAM_CT])
else
ShowSyncHudMsg(0, g_iSync, "T %d - %d CT", g_iScore[TEAM_T], g_iScore[TEAM_CT])
}