public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
//Client Cvars
for ( new i = 0; i < sizeof( szPauseCmds ); i++ )
register_clcmd( szPauseCmds[ i ], "PauseCmd" )
for ( new i = 0; i < sizeof( szUnpauseCmds ); i++ )
register_clcmd( szUnpauseCmds[ i ], "Resume_Function")
//Server cvars
/*
amx_pause_resume ->>
!!! No value, just removes all current pauses and resumes gameplay.
*/
register_concmd( "amx_pause_resume", "Pause_ResumeCmd", ADMIN_RCON, "Removes the pause and resumes the game.") // fuck the naming is always the hardest
/*
amx_pause_set ->>
!!! 0 = CT, 1 = TT, 2 = ALL(CT+TT)
!!! integer | amount of pauses to set.
!!! example: amx_pause_set 0 0 will reset the CT Team pause counter, so if you have amx_pause_amount 1 then the CT's can call a pause again.
*/
register_concmd( "amx_pause_set", "CmdPauseSet", ADMIN_RCON, "Resets the pause amount for teams, 0 = CT, 1 = TT, 2 = ALL(CT+TT)" )
//MAXPLAYERS
g_iMaxPlayers = get_member_game( m_nMaxPlayers )
//POINTERS
g_BuyTimePCvar = get_cvar_pointer( "mp_buytime" )
/*
amx_pause_enabled ->>
!!! 0 | disable pause
!!! 1 | enable pause
*/
cvar_PauseFeat = register_cvar( "amx_pause_enabled", "1", FCVAR_PROTECTED )
/*
amx_pause_duration ->>
!!! integer | amount of freezetime to be set!
*/
cvar_PauseDuration = register_cvar( "amx_pause_duration", "60", FCVAR_PROTECTED )
/*
amx_pause_amount ->>
!!! integer | the amount of times each team can call a pause for the match!
*/
cvar_PauseAmount = register_cvar( "amx_pause_amount", "2", FCVAR_PROTECTED )
/*
amx_pause_buytime ->>
!!! 0 | buytime not altered, not recommended!
!!! 1 | buytime altered to allow people to buy during the pause.
*/
cvar_PauseBuyTime = register_cvar( "amx_pause_buytime", "1", FCVAR_PROTECTED )
/*
amx_pause_set_notify ->>
!!! 0 | do not notify players when you modify their pause amounts
!!! 1 | recommended, notify players of the amount of pauses they can use
*/
cvar_NotifyPauseSet = register_cvar( "amx_pause_set_notify", "1", FCVAR_PROTECTED )
/*
amx_pause_allow_resume ->>
!!! 0 | do not allow players to start a vote for resuming the game (removing the "artificial pause")
!!! 1 | allow players to start a vote
*/
cvar_UnpauseFeat = register_cvar( "amx_pause_allow_resume", "1", FCVAR_PROTECTED )
/*
amx_pause_resume_votes ->>
!!! integer | the amount of people that need to vote "yes" to remove the current pause.
*/
cvar_UnpauseVoteAmount = register_cvar( "amx_pause_resume_votes", "4", FCVAR_PROTECTED )
//MultiLang
register_dictionary( "pause.txt" )
//Message
iMsgRoundTime = get_user_msgid( "RoundTime" )
//Event
register_event( "HLTV", "event_new_round", "a", "1=0", "2=0" )
}
public event_new_round( )
{
/
Getting the latest mp_buytime cvar on event new round, since a lot of CW/PUG/MIX plugins modify it pre and post warmup, so getting it once in plugin_init() would make no sense.
Alternatively this can be achieved with hook_cvar_change but I'm too stupid to understand how to use it in my use case.
Cannot use pcvar_float for the sole reason that I need to store this as the original value before changing it
/
if ( get_pcvar_num( cvar_PauseBuyTime ) )
g_BuyTimeOriginalPCvar = get_cvar_float( "mp_buytime" )
/
Fixes some edge cases of a round ending before the pause ends!
Will remove the display progress function task and re-initialize the counter.
/
if ( task_exists( TASK_SHOWPROGRESS ) || task_exists( TASK_RESUME_VOTEMENU ) )
CleanReinitialize( )
if ( team == 2 )
{
NotifyFunc( "CT", print_team_blue, amount )
NotifyFunc( "TERRORIST", print_team_red, amount )
}
return PLUGIN_HANDLED
}
public CmdPauseSet( )
{
/*
You can call this cvar from your own plugins by using server_cmd, example
args[0] = team
!! 0 = CT
!! 1 = TT
!! 2 = ALL(CT+TT)
args[1] = amount to set
!! integer = TEAM'S PAUSES, 0 = reset.
** server_cmd( "amx_pause_set ^"2"^ ^"0^" ") ->> this will reset both teams available pauses by setting
stock DisplayPauseProgress( )
{
for ( new player = 0; player < g_iMaxPlayers; player++ ) {
if ( is_user_connected( player ) && is_user_alive( player ) )
rg_send_bartime( player, FREEZE_TIME, true )
}
set_task( HOLD_INTERVAL, "ShowPauseText", TASK_SHOWPROGRESS, _, _, "a", get_pcvar_num( cvar_PauseDuration ) - 1 ) // - 1 = https://github.com/s1lentq/ReGameDLL_CS/blob/dd243eaa0b5befb96bab8f113f43bc79e9bba098/regamedll/dlls/multiplay_gamerules.cpp#L456 is the reason for the - 1
return HC_CONTINUE
include
include
define AUTHOR "Esc"
define VERSION "1.0"
define PLUGIN "TACTICAL PAUSE"
define FREEZE_TIME get_member_game( m_iRoundTimeSecs ) // Actual round time
define mp_freezetime get_member_game( m_iIntroRoundTime ) // mp_freezetime
define IS_FREEZE_TIME get_member_game( m_bFreezePeriod ) // Check if game is in freezetime state
define HOLD_INTERVAL 1.0 // set_task delay
define PAUSE_BUYTIME 60.0 // mp_buytime while in pause
define UNPAUSE_MENU_RESULT 10.0 // stop the vote for unpausing (in seconds)
define TASK_SHOWPROGRESS 9486 // task id for showing the progress
define TASK_RESUME_VOTEMENU 9487 // task id for unpause votemenu
//RoundTimer Message static iMsgRoundTime //BuyTime cvars. new g_BuyTimePCvar static Float:g_BuyTimeOriginalPCvar //Boolean checks new bool:g_iPaused, g_iPauseQueued //Cvars new cvar_PauseDuration, cvar_PauseAmount, cvar_PauseBuyTime, cvar_NotifyPauseSet, cvar_UnpauseFeat, cvar_UnpauseVoteAmount, cvar_PauseFeat //Misc new g_iMaxPlayers, g_TeamPauses[ 3 ], g_WhoPaused
//VoteMenu new g_UnpauseVoteMenu, g_Votes[3], g_CurrentlyVoting
enum _:Teams { TERRORIST_TEAM, CT_TEAM } //Cmds new szPauseCmds[ ][ ] = { "say /pause", "say !pause", "say .pause", "say /p", "say !p", "say .p" }; new szUnpauseCmds[ ][ ] = { "say /unpause", "say !unpause", "say .unpause", "say /up", "say .up", "say !up" }
public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR)
}
public event_new_round( ) {
/ Getting the latest mp_buytime cvar on event new round, since a lot of CW/PUG/MIX plugins modify it pre and post warmup, so getting it once in plugin_init() would make no sense. Alternatively this can be achieved with hook_cvar_change but I'm too stupid to understand how to use it in my use case. Cannot use pcvar_float for the sole reason that I need to store this as the original value before changing it / if ( get_pcvar_num( cvar_PauseBuyTime ) ) g_BuyTimeOriginalPCvar = get_cvar_float( "mp_buytime" ) / Fixes some edge cases of a round ending before the pause ends! Will remove the display progress function task and re-initialize the counter. / if ( task_exists( TASK_SHOWPROGRESS ) || task_exists( TASK_RESUME_VOTEMENU ) ) CleanReinitialize( )
}
public CleanReinitialize( ) { remove_task( TASK_SHOWPROGRESS ) remove_task( TASK_RESUME_VOTEMENU )
}
public NotifyFunc( const szTeam[32], const print_team, const amount ) { new iPlayers[ 32 ], iNum, Player get_players( iPlayers, iNum, "ec", szTeam ) for ( new i = 0; i < iNum; i++ ) { Player = iPlayers[ i ] client_print_color( Player, print_team, "%L", Player, "PAUSE_NEW_AMOUNT", amount ) }
}
public NotifyCall( const team, const amount ) { !( team ) ? NotifyFunc( "CT", print_team_blue, amount ) : NotifyFunc( "TERRORIST", print_team_red, amount )
}
public CmdPauseSet( ) { /*
You can call this cvar from your own plugins by using server_cmd, example args[0] = team !! 0 = CT !! 1 = TT !! 2 = ALL(CT+TT)
args[1] = amount to set !! integer = TEAM'S PAUSES, 0 = reset. ** server_cmd( "amx_pause_set ^"2"^ ^"0^" ") ->> this will reset both teams available pauses by setting
*/ new args[ 2 ][ 32 ] read_argv( 1, args[ 0 ], sizeof( args ) ) // read argument number 1 (team) trim( args[ 0 ] ) // remove unexpected whitespaces read_argv( 2, args[ 1 ], sizeof( args ) ) // read argument number 2 (amount of pauses to set) trim( args[ 1 ] ) // remove unexpected whitespaces
}
public PauseRequest( id, const g_PauseTeam, const print_team, const player_team ) { if ( g_TeamPauses[ g_PauseTeam ] == get_pcvar_num( cvar_PauseAmount ) ) return client_print_color( id, print_team, "%L", id, "PAUSE_NOMORE" )
}
public PauseCmd( id ) { if ( !get_pcvar_num( cvar_PauseFeat ) ) return client_print_color( id, print_team_grey, "%L", id, "PAUSE_DISABLED" ) if ( g_iPaused ) return client_print_color( id, print_team_grey, "%L", id, "PAUSE_ALREADY" ) if ( g_iPauseQueued ) return client_print_color( id, print_team_grey, "%L", id, "PAUSE_ALREADY_QUEUED" )
}
public Resume_Function( id ) { if ( !get_pcvar_num( cvar_UnpauseFeat ) ) return client_print_color( id, print_team_grey, "%L", id, "UNPAUSE_FEATURE_NOT_ENABLED" ) if ( !g_iPaused ) return client_print_color( id, print_team_grey, "%L", id, "UNPAUSE_UNAVAILABLE" ) if ( g_WhoPaused != get_member( id, m_iTeam ) ) return client_print_color( id, print_team_grey, "%L", id, "UNPAUSE_WRONG_TEAM" ) if ( g_CurrentlyVoting ) return client_print_color( id, print_team_grey, "%L", id, "UNPAUSE_ONGOING" )
}
public Resume_Votemenu_Handler( id, g_UnpauseVoteMenu, item ) { if ( item == MENU_EXIT || !g_CurrentlyVoting ) return PLUGIN_HANDLED
}
public Resume_Votemenu_Result( ) { new iPlayers[ 32 ], iPNum, Player get_players( iPlayers, iPNum, "e", ( g_WhoPaused == 2 ) ? "CT" : "TERRORIST")
}
public Pause_ResumeCmd( ) { CleanReinitialize( ) Pause( mp_freezetime ) }
public ShowPauseText( ) { set_dhudmessage( 255, 255, 255, -1.0, 0.60, .holdtime = HOLD_INTERVAL - 0.1, .fadeintime = 0.1, .fadeouttime = 0.2 ) show_dhudmessage( 0, "%L", LANG_PLAYER, "PAUSE_TEXT", RemainingTime() )
}
@PauseFunc( ){ g_iPaused = true
}
public Pause( const iSecAmount ) { new Float:lGameTime = get_gametime( ) //Sets the gametime. set_member_game( m_fRoundStartTime, lGameTime ) set_member_game( m_fRoundStartTimeReal, lGameTime ) set_member_game( m_iRoundTimeSecs, iSecAmount ) //Checks for BuyTime cvar. if ( get_pcvar_num( cvar_PauseBuyTime ) ) (IS_FREEZE_TIME && g_iPaused) ? set_pcvar_float(g_BuyTimePCvar, PAUSE_BUYTIME) : set_pcvar_float(g_BuyTimePCvar, g_BuyTimeOriginalPCvar)
}
stock DisplayPauseProgress( ) { for ( new player = 0; player < g_iMaxPlayers; player++ ) { if ( is_user_connected( player ) && is_user_alive( player ) ) rg_send_bartime( player, FREEZE_TIME, true ) }
}
stock Float:RemainingTime( ) { return ( float ( get_member_game ( m_iRoundTimeSecs ) ) - get_gametime( ) + Float:get_member_game ( m_fRoundStartTimeReal ) ); }