Server bewerben
csb-map-stats / addons / amxmodx / scripting / csb_map_stats.sma
172 lines 4.1 KiB Pawn Raw Permalink History
/*
 * CSB Map Stats
 * Copyright (C) 2026 counter-strike-boost.com
 *
 * Records per-map aggregates into nVault keyed by map name: rounds played,
 * terrorist/counter-terrorist round wins, bombs planted, bombs defused and
 * total round time. /mapstats prints the numbers for the current map, and at
 * every round end a short chat line notes which side is dominating the map.
 *
 * 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 <https://www.gnu.org/licenses/> for details.
 */

#include <amxmodx>
#include <nvault>

new const PLUGIN[] = "CSB Map Stats"
new const VERSION[] = "1.0.0"
new const AUTHOR[]  = "counter-strike-boost.com"

new g_iRounds
new g_iTWins
new g_iCTWins
new g_iPlants
new g_iDefuses
new g_iTotalSecs

new Float:g_fRoundStart
new bool:g_bRoundLive

new g_iVault
new g_szMap[32]

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR)

    register_cvar("csb_mapstats_enabled", "1")

    get_mapname(g_szMap, charsmax(g_szMap))

    register_logevent("onRoundStart", 2, "1=Round_Start")
    register_logevent("onRoundEnd",   2, "1=Round_End")
    register_event("SendAudio", "onTWin",  "a", "2&%!MRAD_terwin")
    register_event("SendAudio", "onCTWin", "a", "2&%!MRAD_ctwin")
    register_logevent("onPlant",  3, "2=Planted_The_Bomb")
    register_logevent("onDefuse", 3, "2=Defused_The_Bomb")

    register_clcmd("say /mapstats", "cmdStats")
    register_clcmd("say_team /mapstats", "cmdStats")

    g_iVault = nvault_open("csb_mapstats")

    loadMap()
}

public plugin_end()
{
    saveMap()

    if (g_iVault != -1)
        nvault_close(g_iVault)
}

public onRoundStart()
{
    g_fRoundStart = get_gametime()
    g_bRoundLive  = true
}

public onRoundEnd()
{
    if (g_bRoundLive)
    {
        g_iRounds++
        g_iTotalSecs += floatround(get_gametime() - g_fRoundStart)
        g_bRoundLive = false

        printDominance()
    }
}

public onTWin()
{
    g_iTWins++
}

public onCTWin()
{
    g_iCTWins++
}

public onPlant()
{
    g_iPlants++
}

public onDefuse()
{
    g_iDefuses++
}

printDominance()
{
    new total = g_iTWins + g_iCTWins

    if (total < 5)
        return

    if (g_iTWins > g_iCTWins * 3 / 2)
    {
        client_print(0, print_chat,
            "[CSB] %s is T-sided so far: T %d - %d CT.", g_szMap, g_iTWins, g_iCTWins)
    }
    else if (g_iCTWins > g_iTWins * 3 / 2)
    {
        client_print(0, print_chat,
            "[CSB] %s is CT-sided so far: CT %d - %d T.", g_szMap, g_iCTWins, g_iTWins)
    }
}

public cmdStats(id)
{
    new Float:avg = g_iRounds > 0 ? float(g_iTotalSecs) / float(g_iRounds) : 0.0

    client_print(id, print_console, "----- CSB Map Stats: %s -----", g_szMap)
    client_print(id, print_console, "rounds played: %d (average %.0f s)", g_iRounds, avg)
    client_print(id, print_console, "T wins: %d   CT wins: %d", g_iTWins, g_iCTWins)
    client_print(id, print_console, "bombs planted: %d   defused: %d", g_iPlants, g_iDefuses)
    client_print(id, print_chat, "[CSB] Map stats printed to your console.")

    return PLUGIN_HANDLED
}

loadMap()
{
    if (g_iVault == -1)
        return

    new data[96]

    if (nvault_get(g_iVault, g_szMap, data, charsmax(data)) < 1)
        return

    new a[12], b[12], c[12], d[12], e[12], f[12]
    parse(data,
        a, charsmax(a), b, charsmax(b), c, charsmax(c),
        d, charsmax(d), e, charsmax(e), f, charsmax(f))

    g_iRounds    = str_to_num(a)
    g_iTWins     = str_to_num(b)
    g_iCTWins    = str_to_num(c)
    g_iPlants    = str_to_num(d)
    g_iDefuses   = str_to_num(e)
    g_iTotalSecs = str_to_num(f)
}

saveMap()
{
    if (g_iVault == -1)
        return

    new data[96]
    formatex(data, charsmax(data), "%d %d %d %d %d %d",
        g_iRounds, g_iTWins, g_iCTWins, g_iPlants, g_iDefuses, g_iTotalSecs)

    nvault_set(g_iVault, g_szMap, data)
}