Dein Server hier Biete in der Wochenauktion Server bewerben
csb-pause-unpause / addons / amxmodx / scripting / csb_pause.sma
208 lines 5.4 KiB Pawn Raw Permalink History
/*
 * CSB Pause
 * Copyright (C) 2026 counter-strike-boost.com
 *
 * Match pause tool. /pause freezes the game at the end of the current round:
 * players are clamped to maxspeed 1, firing is blocked with a Ham
 * Weapon_PrimaryAttack supercede, and a "MATCH PAUSED" HUD is shown. /unpause
 * runs a short countdown and resumes. Pauses are limited per team.
 *
 * 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 <hamsandwich>
#include <fun>

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

#define TASK_FREEZE  5300
#define TASK_RESUME  5400

new bool:g_bPaused
new bool:g_bPendingPause
new bool:g_bResuming
new g_iPauseUsed[3]        /* index by team: 1 = T, 2 = CT */
new g_iResumeLeft

new g_pEnabled, g_pMaxPerTeam

new const g_szWeapons[][] =
{
    "weapon_p228", "weapon_scout", "weapon_hegrenade", "weapon_xm1014",
    "weapon_mac10", "weapon_aug", "weapon_smokegrenade", "weapon_elite",
    "weapon_fiveseven", "weapon_ump45", "weapon_sg550", "weapon_galil",
    "weapon_famas", "weapon_usp", "weapon_glock18", "weapon_awp",
    "weapon_mp5navy", "weapon_m249", "weapon_m3", "weapon_m4a1",
    "weapon_tmp", "weapon_g3sg1", "weapon_deagle", "weapon_sg552",
    "weapon_ak47", "weapon_knife", "weapon_p90", "weapon_flashbang"
}

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

    g_pEnabled    = register_cvar("csb_pause_enabled", "1")
    g_pMaxPerTeam = register_cvar("csb_pause_maxperteam", "2")

    register_clcmd("say /pause",       "cmdPause")
    register_clcmd("say_team /pause",  "cmdPause")
    register_clcmd("say /unpause",     "cmdUnpause")
    register_clcmd("say_team /unpause", "cmdUnpause")

    for (new i = 0; i < sizeof(g_szWeapons); i++)
        RegisterHam(Ham_Weapon_PrimaryAttack, g_szWeapons[i], "fwPrimaryAttack")

    register_event("HLTV", "eNewRound", "a", "1=0", "2=0")
    set_task(0.5, "taskFreeze", TASK_FREEZE, _, _, "b")
}

public cmdPause(id)
{
    if (!get_pcvar_num(g_pEnabled))
        return PLUGIN_HANDLED

    new team = get_user_team(id)

    if (team != 1 && team != 2)
    {
        client_print(id, print_chat, "[CSB] Only players in a team can pause.")
        return PLUGIN_HANDLED
    }

    if (g_bPaused || g_bPendingPause)
    {
        client_print(id, print_chat, "[CSB] A pause is already active or pending.")
        return PLUGIN_HANDLED
    }

    new maxPer = get_pcvar_num(g_pMaxPerTeam)

    if (maxPer > 0 && g_iPauseUsed[team] >= maxPer)
    {
        client_print(id, print_chat, "[CSB] Your team has used all %d pause(s).", maxPer)
        return PLUGIN_HANDLED
    }

    g_iPauseUsed[team]++
    g_bPendingPause = true

    new name[32]
    get_user_name(id, name, charsmax(name))
    chatAll("^x04[CSB]^x03 %s^x01 requested a pause - it will start at the end of this round.", name)

    return PLUGIN_HANDLED
}

public cmdUnpause(id)
{
    if (!g_bPaused || g_bResuming)
        return PLUGIN_HANDLED

    new team = get_user_team(id)

    if (team != 1 && team != 2)
        return PLUGIN_HANDLED

    g_bResuming = true
    g_iResumeLeft = 3

    new name[32]
    get_user_name(id, name, charsmax(name))
    chatAll("^x04[CSB]^x03 %s^x01 un-paused - resuming in 3...", name)

    set_task(1.0, "taskResume", TASK_RESUME, _, _, "a", 3)
    return PLUGIN_HANDLED
}

public taskResume()
{
    g_iResumeLeft--

    if (g_iResumeLeft > 0)
    {
        client_print(0, print_center, "Resuming in %d...", g_iResumeLeft)
        return
    }

    g_bPaused = false
    g_bResuming = false
    unfreezeAll()
    chatAll("^x04[CSB]^x01 *** MATCH RESUMED *** GO!")
    server_cmd("sv_restartround 1")
}

public eNewRound()
{
    if (g_bPendingPause && !g_bPaused)
    {
        g_bPendingPause = false
        g_bPaused = true
        set_cvar_num("mp_freezetime", 9999)
        chatAll("^x04[CSB]^x01 *** MATCH PAUSED *** type /unpause when both teams are ready.")
    }
}

public taskFreeze()
{
    if (!g_bPaused)
        return

    set_hudmessage(255, 40, 40, -1.0, 0.30, 0, 0.0, 0.6, 0.0, 0.0, -1)
    show_hudmessage(0, "MATCH PAUSED^ntype /unpause to resume")

    new players[32], num, pid
    get_players(players, num, "ae")

    for (new i = 0; i < num; i++)
    {
        pid = players[i]
        set_user_maxspeed(pid, 1.0)
    }
}

unfreezeAll()
{
    set_cvar_num("mp_freezetime", 0)

    new players[32], num, pid
    get_players(players, num, "ae")

    for (new i = 0; i < num; i++)
    {
        pid = players[i]
        set_user_maxspeed(pid, -1.0)   /* -1 restores the default weapon speed */
    }
}

public fwPrimaryAttack(weapon)
{
    if (g_bPaused)
        return HAM_SUPERCEDE

    return HAM_IGNORED
}

chatAll(const fmt[], any:...)
{
    new msg[192]
    vformat(msg, charsmax(msg), fmt, 2)

    new players[32], num, msgid = get_user_msgid("SayText")
    get_players(players, num, "ch")

    for (new i = 0; i < num; i++)
    {
        message_begin(MSG_ONE, msgid, _, players[i])
        write_byte(players[i])
        write_string(msg)
        message_end()
    }
}