From 82bc35478b364c717262832c6b46f94f3a233847 Mon Sep 17 00:00:00 2001 From: PhlexPlexico Date: Tue, 5 Apr 2022 14:47:43 -0600 Subject: [PATCH 1/4] Include timeouts for tech pauses. Adjust unpausing based on commands? Compiles with no errors, time to test. Include max tech pauses. Include debug. Update pausing to set/get props to tell who is pausing. Keep track of who tech paused. Limit when tech pauses can be called while in tech pause. Disable counter if the team calling calls unpause. Remove pause/unpause util changes. Update some bad assumptions for pausing. Bad command syntax. Keep track of time so we don't spin off two timers for one pause. Feature should be complete. Minor testing still needs to be done. Include ready for unpause in tech pauses as we always want both teams to unpause. Missed call for increasing max pauses. Include edge case where users have tech pause limits but no timer. Remove call in unpause. Missed period. Remove unnecessary log message. Add 10 second expiration message. Add in check to make sure max pauses is above zero as well. Add in minute warning and then a 30 second warning. Per conversations with league organizers, tech pauses have been reworked. --- scripting/get5.sp | 12 ++++ scripting/get5/debug.sp | 3 + scripting/get5/matchconfig.sp | 3 + scripting/get5/pausing.sp | 103 ++++++++++++++++++++++++++++++++++ translations/get5.phrases.txt | 24 ++++++++ 5 files changed, 145 insertions(+) diff --git a/scripting/get5.sp b/scripting/get5.sp index 49eb84604..014ef4c45 100644 --- a/scripting/get5.sp +++ b/scripting/get5.sp @@ -50,6 +50,8 @@ /** ConVar handles **/ ConVar g_AllowTechPauseCvar; +ConVar g_MaxTechPauseTime; +ConVar g_MaxTechPauseCvar; ConVar g_AutoLoadConfigCvar; ConVar g_AutoReadyActivePlayers; ConVar g_BackupSystemEnabledCvar; @@ -166,6 +168,9 @@ bool g_TeamGivenStopCommand[MATCHTEAM_COUNT]; bool g_InExtendedPause; int g_TeamPauseTimeUsed[MATCHTEAM_COUNT]; int g_TeamPausesUsed[MATCHTEAM_COUNT]; +int g_TeamTechPausesUsed[MATCHTEAM_COUNT]; +int g_TechPausedTimeOverride[MATCHTEAM_COUNT]; +int g_TeamGivenTechPauseCommand[MATCHTEAM_COUNT]; int g_PauseTimeUsed = 0; int g_ReadyTimeWaitingUsed = 0; char g_DefaultTeamColors[][] = { @@ -262,6 +267,10 @@ public void OnPluginStart() { /** ConVars **/ g_AllowTechPauseCvar = CreateConVar("get5_allow_technical_pause", "1", "Whether or not technical pauses are allowed"); + g_MaxTechPauseTime = CreateConVar("get5_tech_pause_time", "0", + "Number of seconds before anyone can call unpause on a technical timeout, 0=unlimited"); + g_MaxTechPauseCvar = CreateConVar("get5_max_tech_pauses", "0", + "Number of technical pauses a team is allowed to have, 0=unlimited"); g_AutoLoadConfigCvar = CreateConVar("get5_autoload_config", "", "Name of a match config file to automatically load when the server loads"); @@ -653,6 +662,9 @@ public void OnMapStart() { g_TeamPauseTimeUsed[team] = 0; g_TeamPausesUsed[team] = 0; g_ReadyTimeWaitingUsed = 0; + g_TeamTechPausesUsed[team] = 0; + g_TechPausedTimeOverride[team] = 0; + g_TeamGivenTechPauseCommand[team] = false; } if (g_WaitingForRoundBackup) { diff --git a/scripting/get5/debug.sp b/scripting/get5/debug.sp index 25b1f37c3..466653bc7 100644 --- a/scripting/get5/debug.sp +++ b/scripting/get5/debug.sp @@ -133,7 +133,10 @@ static void AddGlobalStateInfo(File f) { f.WriteLine("g_TeamReadyOverride = %d", g_TeamReadyOverride[team]); f.WriteLine("g_TeamStartingSide = %d", g_TeamStartingSide[team]); f.WriteLine("g_TeamPauseTimeUsed = %d", g_TeamPauseTimeUsed[team]); + f.WriteLine("g_TechPausedTimeOverride = %d", g_TechPausedTimeOverride[team]); f.WriteLine("g_TeamPausesUsed = %d", g_TeamPausesUsed[team]); + f.WriteLine("g_TeamTechPausesUsed = %d", g_TeamTechPausesUsed[team]); + f.WriteLine("g_TeamGivenTechPauseCommand = %d", g_TeamGivenTechPauseCommand[team]); } } diff --git a/scripting/get5/matchconfig.sp b/scripting/get5/matchconfig.sp index c55fc6c6c..7cc618b16 100644 --- a/scripting/get5/matchconfig.sp +++ b/scripting/get5/matchconfig.sp @@ -24,6 +24,9 @@ stock bool LoadMatchConfig(const char[] config, bool restoreBackup = false) { g_TeamGivenStopCommand[team] = false; g_TeamPauseTimeUsed[team] = 0; g_TeamPausesUsed[team] = 0; + g_TeamTechPausesUsed[team] = 0; + g_TechPausedTimeOverride[team] = 0; + g_TeamGivenTechPauseCommand[team] = false; ClearArray(GetTeamAuths(team)); } diff --git a/scripting/get5/pausing.sp b/scripting/get5/pausing.sp index 4fc9e7b0f..6a603b380 100644 --- a/scripting/get5/pausing.sp +++ b/scripting/get5/pausing.sp @@ -23,6 +23,37 @@ public Action Command_TechPause(int client, int args) { } MatchTeam team = GetClientMatchTeam(client); + int maxTechPauses = g_MaxTechPauseCvar.IntValue; + + g_TeamReadyForUnpause[MatchTeam_Team1] = false; + g_TeamReadyForUnpause[MatchTeam_Team2] = false; + + // Only set these if we are a non-zero value. + if (maxTechPauses > 0 || g_MaxTechPauseTime.IntValue > 0) { + int timeLeft = g_MaxTechPauseTime.IntValue - g_TechPausedTimeOverride[team]; + // Don't allow more than one tech pause per time. + if (g_TeamGivenTechPauseCommand[MatchTeam_Team1] || g_TeamGivenTechPauseCommand[MatchTeam_Team2]) { + return Plugin_Handled; + } + if (maxTechPauses > 0 && g_TeamTechPausesUsed[team] >= maxTechPauses) { + Get5_MessageToAll("%t", "TechPauseNoTimeRemaining", g_FormattedTeamNames[team]); + return Plugin_Handled; + } else if (g_MaxTechPauseTime.IntValue > 0 && timeLeft <= 0) { + Get5_MessageToAll("%t", "TechPauseNoTimeRemaining", g_FormattedTeamNames[team]); + return Plugin_Handled; + } else { + g_TeamGivenTechPauseCommand[team] = true; + // Only create a new timer when the old one expires. + if (g_TechPausedTimeOverride[team] == 0) { + CreateTimer(1.0, Timer_TechPauseOverrideCheck, team, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); + } + // Once we run out of time, subtract a tech pause used and reset the timer. + g_TeamTechPausesUsed[team]++; + int pausesLeft = maxTechPauses - g_TeamTechPausesUsed[team]; + Get5_MessageToAll("%t", "TechPausePausesRemaining", g_FormattedTeamNames[team], pausesLeft); + } + } + Pause(); EventLogger_PauseCommand(team, PauseType_Tech); LogDebug("Calling Get5_OnMatchPaused(team=%d, pauseReason=%d)", team, PauseType_Tech); @@ -128,6 +159,47 @@ public Action Command_Pause(int client, int args) { return Plugin_Handled; } +public Action Timer_TechPauseOverrideCheck(Handle timer, int data) { + MatchTeam team = view_as(data); + if (!Pauseable()) { + g_TechPausedTimeOverride[team] = 0; + g_TeamGivenTechPauseCommand[team] = false; + return Plugin_Stop; + } + + // Unlimited Tech Pause so no one can unpause unless both teams agree. + if (g_MaxTechPauseTime.IntValue <= 0) { + g_TechPausedTimeOverride[team] = 0; + return Plugin_Stop; + } + + int timeLeft = g_MaxTechPauseTime.IntValue - g_TechPausedTimeOverride[team]; + + if (InFreezeTime() && g_TeamGivenTechPauseCommand[team] && g_InExtendedPause && !g_TeamReadyForUnpause[team]) { + LogDebug("Adding tech time used. Current time = %d", g_TechPausedTimeOverride[team]); + g_TechPausedTimeOverride[team]++; + + // Every 30 seconds output a message with the time remaining before unpause. + if (timeLeft != 0) { + if (timeLeft >= 60 && timeLeft % 60 == 0) { + timeLeft = timeLeft / 60; + Get5_MessageToAll("%t", "TechPauseTimeRemainingMinutes", timeLeft); + } else if (timeLeft <= 30 && (timeLeft % 30 == 0 || timeLeft == 10)) { + Get5_MessageToAll("%t", "TechPauseTimeRemaining", timeLeft); + } + } + + if (timeLeft <= 0) { + Get5_MessageToAll("%t", "TechPauseRunoutInfoMessage"); + return Plugin_Stop; + } + } + + // Someone can call pause during a round and will set this timer. + // Keep running timer until we are paused. + return Plugin_Continue; +} + public Action Timer_UnpauseEventCheck(Handle timer, int data) { if (!Pauseable()) { g_PauseTimeUsed = 0; @@ -225,6 +297,34 @@ public Action Command_Unpause(int client, int args) { MatchTeam team = GetClientMatchTeam(client); g_TeamReadyForUnpause[team] = true; + // Get which team is currently tech paused. + MatchTeam pausedTeam = MatchTeam_TeamNone; + if (g_TeamGivenTechPauseCommand[MatchTeam_Team1]) { + pausedTeam = MatchTeam_Team1; + } else if (g_TeamGivenTechPauseCommand[MatchTeam_Team2]) { + pausedTeam = MatchTeam_Team2; + } + + if (g_InExtendedPause && g_MaxTechPauseTime.IntValue > 0) { + if (g_TechPausedTimeOverride[pausedTeam] >= g_MaxTechPauseTime.IntValue) { + Unpause(); + EventLogger_UnpauseCommand(team); + LogDebug("Calling Get5_OnMatchUnpaused(team=%d)", team); + Call_StartForward(g_OnMatchUnpaused); + Call_PushCell(team); + Call_Finish(); + if (IsPlayer(client)) { + Get5_MessageToAll("%t", "MatchUnpauseInfoMessage", client); + } + if (pausedTeam != MatchTeam_TeamNone) { + g_TeamGivenTechPauseCommand[pausedTeam] = false; + g_TechPausedTimeOverride[pausedTeam] = 0; + } + g_InExtendedPause = false; + return Plugin_Handled; + } + } + if (g_TeamReadyForUnpause[MatchTeam_Team1] && g_TeamReadyForUnpause[MatchTeam_Team2]) { Unpause(); EventLogger_UnpauseCommand(team); @@ -232,6 +332,9 @@ public Action Command_Unpause(int client, int args) { Call_StartForward(g_OnMatchUnpaused); Call_PushCell(team); Call_Finish(); + if (pausedTeam != MatchTeam_TeamNone) { + g_TeamGivenTechPauseCommand[pausedTeam] = false; + } if (IsPlayer(client)) { Get5_MessageToAll("%t", "MatchUnpauseInfoMessage", client); } diff --git a/translations/get5.phrases.txt b/translations/get5.phrases.txt index 53c5121cf..73f2ea3c7 100644 --- a/translations/get5.phrases.txt +++ b/translations/get5.phrases.txt @@ -121,6 +121,30 @@ "#format" "{1:s}" "en" "{1} has run out of pause time, unpausing the match." } + "TechPauseRunoutInfoMessage" + { + "en" "Grace period has expired for the technical pause, anyone may unpause now." + } + "TechPauseTimeRemaining" + { + "#format" "{1:d}" + "en" "{1} seconds remaining of tech pause time before anyone can resume." + } + "TechPauseTimeRemainingMinutes" + { + "#format" "{1:d}" + "en" "{1} minutes remaining of tech pause time before anyone can resume." + } + "TechPauseNoTimeRemaining" + { + "#format" "{1:s}" + "en" "Sorry, team {1} has no more tech pause time. Please use tactical pauses." + } + "TechPausePausesRemaining" + { + "#format" "{1:s},{2:d}" + "en" "Team {1} has {2} technical pauses remaining." + } "MatchUnpauseInfoMessage" { "#format" "{1:N}" From cf8e3254299cb392f1b05872febf81718fd27c8c Mon Sep 17 00:00:00 2001 From: PhlexPlexico Date: Tue, 10 May 2022 11:58:08 -0600 Subject: [PATCH 2/4] Add brackets for grammatical purposes. --- translations/get5.phrases.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/get5.phrases.txt b/translations/get5.phrases.txt index 73f2ea3c7..1f05a904c 100644 --- a/translations/get5.phrases.txt +++ b/translations/get5.phrases.txt @@ -143,7 +143,7 @@ "TechPausePausesRemaining" { "#format" "{1:s},{2:d}" - "en" "Team {1} has {2} technical pauses remaining." + "en" "Team {1} has {2} technical pause(s) remaining." } "MatchUnpauseInfoMessage" { From 803466984db388c0b7b910a348a977c84e35a8d7 Mon Sep 17 00:00:00 2001 From: PhlexPlexico Date: Tue, 10 May 2022 12:05:10 -0600 Subject: [PATCH 3/4] Grammatical fix. --- translations/get5.phrases.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/get5.phrases.txt b/translations/get5.phrases.txt index 1f05a904c..eea16ce01 100644 --- a/translations/get5.phrases.txt +++ b/translations/get5.phrases.txt @@ -133,7 +133,7 @@ "TechPauseTimeRemainingMinutes" { "#format" "{1:d}" - "en" "{1} minutes remaining of tech pause time before anyone can resume." + "en" "{1} minute(s) remaining of tech pause time before anyone can resume." } "TechPauseNoTimeRemaining" { From 8a5703a1adc1dd0761d509614e9956e579b8df02 Mon Sep 17 00:00:00 2001 From: PhlexPlexico Date: Wed, 11 May 2022 13:12:06 -0600 Subject: [PATCH 4/4] Fix timeout message not showing on second tech pause. Fix dangling timers for when teams unpause before a timer finishes. --- scripting/get5/pausing.sp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripting/get5/pausing.sp b/scripting/get5/pausing.sp index 6a603b380..5efe51556 100644 --- a/scripting/get5/pausing.sp +++ b/scripting/get5/pausing.sp @@ -173,6 +173,12 @@ public Action Timer_TechPauseOverrideCheck(Handle timer, int data) { return Plugin_Stop; } + // This condition will only be hit when we resume from a pause. + if (!g_TeamGivenTechPauseCommand[team]) { + g_TechPausedTimeOverride[team] = 0; + return Plugin_Stop; + } + int timeLeft = g_MaxTechPauseTime.IntValue - g_TechPausedTimeOverride[team]; if (InFreezeTime() && g_TeamGivenTechPauseCommand[team] && g_InExtendedPause && !g_TeamReadyForUnpause[team]) { @@ -332,8 +338,10 @@ public Action Command_Unpause(int client, int args) { Call_StartForward(g_OnMatchUnpaused); Call_PushCell(team); Call_Finish(); + g_InExtendedPause = false; if (pausedTeam != MatchTeam_TeamNone) { g_TeamGivenTechPauseCommand[pausedTeam] = false; + g_TechPausedTimeOverride[pausedTeam] = 0; } if (IsPlayer(client)) { Get5_MessageToAll("%t", "MatchUnpauseInfoMessage", client);