/*
* CSB Timeleft HUD
* Copyright (C) 2026 counter-strike-boost.com
*
* Shows the remaining map time as a permanent HUD element, refreshed every
* second from get_timeleft(). The colour turns to amber and then red as time
* runs out, and the server announces "10 / 5 / 1 minute(s) left" in coloured
* chat. Players can check the time themselves with say /timeleft.
*
* This is an independent GPL implementation; it is not based on any other
* plugin's source.
*
* 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
new const PLUGIN[] = "CSB Timeleft HUD"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
new g_pEnabled, g_pX, g_pY, g_pAnnounce
new g_iSync
new g_iLastAnnounce = -1
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
g_pEnabled = register_cvar("csb_timeleft_enabled", "1")
g_pX = register_cvar("csb_timeleft_x", "0.02")
g_pY = register_cvar("csb_timeleft_y", "0.90")
g_pAnnounce = register_cvar("csb_timeleft_announce", "1")
g_iSync = CreateHudSyncObj()
register_clcmd("say /timeleft", "cmdTimeleft")
register_clcmd("say_team /timeleft", "cmdTimeleft")
set_task(1.0, "taskShow", 0, _, _, "b")
}
public taskShow()
{
if (!get_pcvar_num(g_pEnabled))
return
new seconds = get_timeleft()
if (seconds <= 0)
{
/* no mp_timelimit set - nothing to count down */
set_hudmessage(120, 200, 120, get_pcvar_float(g_pX), get_pcvar_float(g_pY), 0, 0.0, 1.1, 0.0, 0.0, -1)
ShowSyncHudMsg(0, g_iSync, "Time left: no limit")
return
}
new r, g, b
hudColor(seconds, r, g, b)
new text[48]
formatTime(seconds, text, charsmax(text))
set_hudmessage(r, g, b, get_pcvar_float(g_pX), get_pcvar_float(g_pY), 0, 0.0, 1.1, 0.0, 0.0, -1)
ShowSyncHudMsg(0, g_iSync, "Time left: %s", text)
announce(seconds)
}
hudColor(seconds, &r, &g, &b)
{
if (seconds <= 60) { r = 255; g = 40; b = 40; } /* last minute - red */
else if (seconds <= 300){ r = 255; g = 170; b = 40; } /* last 5 min - amber */
else { r = 120; g = 200; b = 255; } /* normal - light blue */
}
formatTime(seconds, out[], len)
{
new mins = seconds / 60
new secs = seconds % 60
if (mins >= 60)
{
new hours = mins / 60
mins %= 60
formatex(out, len, "%d:%02d:%02d", hours, mins, secs)
}
else
{
formatex(out, len, "%d:%02d", mins, secs)
}
}
announce(seconds)
{
if (!get_pcvar_num(g_pAnnounce))
return
new mark = 0
if (seconds <= 63 && seconds >= 57)
mark = 1
else if (seconds <= 303 && seconds >= 297)
mark = 5
else if (seconds <= 603 && seconds >= 597)
mark = 10
if (mark == 0 || mark == g_iLastAnnounce)
return
g_iLastAnnounce = mark
client_print_color(0, print_team_default, "^x04[CSB]^x01 %d^x03 minute%s^x01 left on this map.", mark, mark == 1 ? "" : "s")
}
public cmdTimeleft(id)
{
new seconds = get_timeleft()
if (seconds <= 0)
{
client_print_color(id, print_team_default, "^x04[CSB]^x01 This map has no time limit.")
return PLUGIN_HANDLED
}
new text[48]
formatTime(seconds, text, charsmax(text))
client_print_color(id, print_team_default, "^x04[CSB]^x01 Time left on this map:^x04 %s", text)
return PLUGIN_HANDLED
}