From 8a5580dce3c1ce571138301f46084ed02df3d85a Mon Sep 17 00:00:00 2001 From: Nicolai Cornelis Date: Fri, 22 Jul 2022 00:55:43 +0200 Subject: [PATCH] Clean up pause time counter logic: Remove g_PauseTimeUsed Only fire necessary timers Ensure fixed pause configuration takes precedence over combined max pause time Redirect sm_tech to admin pause if used in console Prevent direct calls to mp_pause_match and mp_unpause_match, force sm_pause/sm_unpause Remove g_TeamGivenTechPauseCommand array Add g_PausingTeam and g_PauseType to debug output Prevent multiple pauses from being triggered at the same time Prevent spectators and team none from ever calling pause or unpause Renamed g_MaxTechPauseTime to g_MaxTechPauseDurationCvar for consistency Renamed g_MaxPausesCvar to g_MaxTacticalPausesCvar for consistency Renamed g_TechPausedTimeOverride to g_TechnicalPauseTimeUsed, as that's what it is Renamed g_TeamPauseTimeUsed to g_TacticalPauseTimeUsed Renamed g_TechPauseTimeUsed to g_TechnicalPauseTimeUsed Renamed g_TeamPausesUsed to g_TacticalPausesUsed Renamed g_TeamTechPausesUsed to g_TechnicalPausesUsed Add print-to-all localized hints for all pauses, ditched the in-game pause state as it's buggy Add util function for converting seconds to minutes:seconds Ensure unpausing when loading a match Refactored translations and removed redundant chat-text Allow admin to pause even if pausing is disabled Add team name to max pause/pause time used. Add backup pause type hint Add stop command not enabled translation Don't allow stop command during admin pause Automatically unpause if max pauses get set to a lower value than already consumed while a pause is active Adjust danish translations Adjust game state pause permissions --- documentation/docs/event_schema.yml | 13 +- scripting/get5.sp | 65 ++-- scripting/get5/backups.sp | 4 +- scripting/get5/debug.sp | 13 +- scripting/get5/goinglive.sp | 10 +- scripting/get5/mapveto.sp | 8 +- scripting/get5/matchconfig.sp | 12 +- scripting/get5/pausing.sp | 544 ++++++++++++++++------------ scripting/get5/util.sp | 42 +-- scripting/include/get5.inc | 11 +- translations/chi/get5.phrases.txt | 26 +- translations/da/get5.phrases.txt | 92 +++-- translations/de/get5.phrases.txt | 16 +- translations/es/get5.phrases.txt | 26 +- translations/fr/get5.phrases.txt | 26 +- translations/get5.phrases.txt | 94 +++-- translations/pl/get5.phrases.txt | 22 +- translations/pt/get5.phrases.txt | 22 +- translations/ru/get5.phrases.txt | 16 +- 19 files changed, 533 insertions(+), 529 deletions(-) diff --git a/documentation/docs/event_schema.yml b/documentation/docs/event_schema.yml index b1c60e892..5d5e5cc4e 100644 --- a/documentation/docs/event_schema.yml +++ b/documentation/docs/event_schema.yml @@ -176,13 +176,11 @@ paths: schema: title: Get5MatchPausedEvent allOf: - - "$ref": "#/components/schemas/Get5MapTeamEvent" + - "$ref": "#/components/schemas/Get5MatchPauseEvent" properties: event: enum: - game_paused - pause_type: - $ref: "#/components/schemas/Get5PauseType" responses: { } "/Get5_OnMatchUnpaused": post: @@ -196,7 +194,7 @@ paths: schema: title: Get5MatchUnpausedEvent allOf: - - "$ref": "#/components/schemas/Get5MapTeamEvent" + - "$ref": "#/components/schemas/Get5MatchPauseEvent" properties: event: enum: @@ -969,6 +967,13 @@ components: - technical - admin - backup + Get5MatchPauseEvent: + allOf: + - "$ref": "#/components/schemas/Get5MapTeamEvent" + - type: object + properties: + pause_type: + $ref: "#/components/schemas/Get5PauseType" Get5Player: type: object properties: diff --git a/scripting/get5.sp b/scripting/get5.sp index 64915f098..2cc33ba06 100644 --- a/scripting/get5.sp +++ b/scripting/get5.sp @@ -51,8 +51,8 @@ /** ConVar handles **/ ConVar g_AllowTechPauseCvar; -ConVar g_MaxTechPauseTime; -ConVar g_MaxTechPauseCvar; +ConVar g_MaxTechPauseDurationCvar; +ConVar g_MaxTechPausesCvar; ConVar g_AutoLoadConfigCvar; ConVar g_AutoReadyActivePlayersCvar; ConVar g_BackupSystemEnabledCvar; @@ -70,7 +70,7 @@ ConVar g_KickClientsWithNoMatchCvar; ConVar g_LiveCfgCvar; ConVar g_LiveCountdownTimeCvar; ConVar g_MaxBackupAgeCvar; -ConVar g_MaxPausesCvar; +ConVar g_MaxTacticalPausesCvar; ConVar g_MaxPauseTimeCvar; ConVar g_MessagePrefixCvar; ConVar g_PauseOnVetoCvar; @@ -135,6 +135,17 @@ ArrayList g_CvarValues = null; bool g_InScrimMode = false; bool g_HasKnifeRoundStarted = false; +/** Pausing **/ +bool g_IsChangingPauseState = false; // Used to prevent mp_pause_match and mp_unpause_match from being called directly. +Get5Team g_PausingTeam = Get5Team_None; // The team that last called for a pause. +Get5PauseType g_PauseType = Get5PauseType_None; // The type of pause last initiated. +int g_LatestPauseDuration = 0; +bool g_TeamReadyForUnpause[MATCHTEAM_COUNT]; +bool g_TeamGivenStopCommand[MATCHTEAM_COUNT]; +int g_TacticalPauseTimeUsed[MATCHTEAM_COUNT]; +int g_TacticalPausesUsed[MATCHTEAM_COUNT]; +int g_TechnicalPausesUsed[MATCHTEAM_COUNT]; + /** Other state **/ Get5State g_GameState = Get5State_None; ArrayList g_MapsToPlay = null; @@ -182,15 +193,6 @@ bool g_TeamReadyOverride[MATCHTEAM_COUNT]; // Whether a team has been voluntari bool g_ClientReady[MAXPLAYERS + 1]; // Whether clients are marked ready. int g_TeamSide[MATCHTEAM_COUNT]; // Current CS_TEAM_* side for the team. int g_TeamStartingSide[MATCHTEAM_COUNT]; -bool g_TeamReadyForUnpause[MATCHTEAM_COUNT]; -bool g_TeamGivenStopCommand[MATCHTEAM_COUNT]; -Get5PauseType g_PauseType = Get5PauseType_None; -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[][] = { TEAM1_COLOR, @@ -312,10 +314,10 @@ public void OnPluginStart() { /** ConVars **/ g_AllowTechPauseCvar = CreateConVar("get5_allow_technical_pause", "1", "Whether or not technical pauses are allowed"); - g_MaxTechPauseTime = CreateConVar( + g_MaxTechPauseDurationCvar = CreateConVar( "get5_tech_pause_time", "0", "Number of seconds before anyone can call unpause on a technical timeout, 0=unlimited"); - g_MaxTechPauseCvar = + g_MaxTechPausesCvar = CreateConVar("get5_max_tech_pauses", "0", "Number of technical pauses a team is allowed to have, 0=unlimited"); g_AutoLoadConfigCvar = @@ -366,7 +368,7 @@ public void OnPluginStart() { g_MaxBackupAgeCvar = CreateConVar("get5_max_backup_age", "160000", "Number of seconds before a backup file is automatically deleted, 0 to disable"); - g_MaxPausesCvar = + g_MaxTacticalPausesCvar = CreateConVar("get5_max_pauses", "0", "Maximum number of pauses a team can use, 0=unlimited"); g_MaxPauseTimeCvar = CreateConVar("get5_max_pause_time", "300", @@ -524,6 +526,8 @@ public void OnPluginStart() { AddCommandListener(Command_Coach, "coach"); AddCommandListener(Command_JoinTeam, "jointeam"); AddCommandListener(Command_JoinGame, "joingame"); + AddCommandListener(Command_PauseOrUnpauseMatch, "mp_pause_match"); + AddCommandListener(Command_PauseOrUnpauseMatch, "mp_unpause_match"); /** Setup data structures **/ g_MapPoolList = new ArrayList(PLATFORM_MAX_PATH); @@ -773,12 +777,10 @@ public void OnMapStart() { LOOP_TEAMS(team) { g_TeamGivenStopCommand[team] = false; g_TeamReadyForUnpause[team] = false; - g_TeamPauseTimeUsed[team] = 0; - g_TeamPausesUsed[team] = 0; + g_TacticalPauseTimeUsed[team] = 0; + g_TacticalPausesUsed[team] = 0; g_ReadyTimeWaitingUsed = 0; - g_TeamTechPausesUsed[team] = 0; - g_TechPausedTimeOverride[team] = 0; - g_TeamGivenTechPauseCommand[team] = false; + g_TechnicalPausesUsed[team] = 0; } if (g_WaitingForRoundBackup) { @@ -1037,6 +1039,7 @@ public Action Command_DumpStats(int client, int args) { public Action Command_Stop(int client, int args) { if (!g_StopCommandEnabledCvar.BoolValue) { + Get5_MessageToAll("%t", "StopCommandNotEnabled"); return Plugin_Handled; } @@ -1047,6 +1050,12 @@ public Action Command_Stop(int client, int args) { // Let the server/rcon always force restore. if (client == 0) { RestoreLastRound(client); + return Plugin_Handled; + } + + if (g_PauseType == Get5PauseType_Admin) { + // Don't let teams restore backups while an admin has paused the game. + return Plugin_Handled; } Get5Team team = GetClientMatchTeam(client); @@ -1309,6 +1318,13 @@ public Action Event_RoundPreStart(Event event, const char[] name, bool dontBroad public Action Event_FreezeEnd(Event event, const char[] name, bool dontBroadcast) { LogDebug("Event_FreezeEnd"); + + // If someone changes the map while in a pause, we have to make sure we reset this state, as the UnpauseGame function + // will not be called to do it. FreezeTimeEnd is always called when the map initially loads. + g_LatestPauseDuration = 0; + g_PauseType = Get5PauseType_None; + g_PausingTeam = Get5Team_None; + // We always want this to be correct, regardless of game state. g_RoundStartedTime = GetEngineTime(); if (g_GameState == Get5State_Live) { @@ -1502,13 +1518,8 @@ public void SwapSides() { if (g_ResetPausesEachHalfCvar.BoolValue) { LOOP_TEAMS(team) { - g_TeamPauseTimeUsed[team] = 0; - g_TeamPausesUsed[team] = 0; - } - // Reset the built-in timeout counter of the game - if (g_MaxPausesCvar.IntValue > 0) { - GameRules_SetProp("m_nTerroristTimeOuts", g_MaxPausesCvar.IntValue); - GameRules_SetProp("m_nCTTimeOuts", g_MaxPausesCvar.IntValue); + g_TacticalPauseTimeUsed[team] = 0; + g_TacticalPausesUsed[team] = 0; } } } diff --git a/scripting/get5/backups.sp b/scripting/get5/backups.sp index 4f416b91a..18a703d80 100644 --- a/scripting/get5/backups.sp +++ b/scripting/get5/backups.sp @@ -355,7 +355,7 @@ public void RestoreGet5Backup() { EndWarmup(); EndWarmup(); ServerCommand("mp_restartgame 5"); - PauseGame(Get5Team_None, Get5PauseType_Backup, 1); + PauseGame(Get5Team_None, Get5PauseType_Backup); if (g_CoachingEnabledCvar.BoolValue) { CreateTimer(6.0, Timer_SwapCoaches); } @@ -377,7 +377,7 @@ public Action Timer_SwapCoaches(Handle timer) { } public Action Time_StartRestore(Handle timer) { - PauseGame(Get5Team_None, Get5PauseType_Backup, 1); + PauseGame(Get5Team_None, Get5PauseType_Backup); char tempValveBackup[PLATFORM_MAX_PATH]; GetTempFilePath(tempValveBackup, sizeof(tempValveBackup), TEMP_VALVE_BACKUP_PATTERN); diff --git a/scripting/get5/debug.sp b/scripting/get5/debug.sp index 187087ade..59dc1f1fb 100644 --- a/scripting/get5/debug.sp +++ b/scripting/get5/debug.sp @@ -117,6 +117,9 @@ static void AddGlobalStateInfo(File f) { f.WriteLine("g_SavedValveBackup = %d", g_SavedValveBackup); f.WriteLine("g_DoingBackupRestoreNow = %d", g_DoingBackupRestoreNow); f.WriteLine("g_ReadyTimeWaitingUsed = %d", g_ReadyTimeWaitingUsed); + f.WriteLine("g_PausingTeam = %d", g_PausingTeam); + f.WriteLine("g_PauseType = %d", g_PauseType); + f.WriteLine("g_LatestPauseDuration = %d", g_LatestPauseDuration); LOOP_TEAMS(team) { GetTeamString(team, buffer, sizeof(buffer)); @@ -134,11 +137,9 @@ static void AddGlobalStateInfo(File f) { f.WriteLine("g_TeamSeriesScores = %d", g_TeamSeriesScores[team]); 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]); + f.WriteLine("g_TacticalPauseTimeUsed = %d", g_TacticalPauseTimeUsed[team]); + f.WriteLine("g_TacticalPausesUsed = %d", g_TacticalPausesUsed[team]); + f.WriteLine("g_TechnicalPausesUsed = %d", g_TechnicalPausesUsed[team]); f.WriteLine("g_TeamGivenStopCommand = %d", g_TeamGivenStopCommand[team]); WriteArrayList(f, "g_TeamCoaches", g_TeamCoaches[team]); } @@ -153,8 +154,10 @@ static void AddInterestingCvars(File f) { WriteCvarString(f, "get5_fixed_pause_time"); WriteCvarString(f, "get5_kick_when_no_match_loaded"); WriteCvarString(f, "get5_live_cfg"); + WriteCvarString(f, "get5_tech_pause_time"); WriteCvarString(f, "get5_max_pause_time"); WriteCvarString(f, "get5_max_pauses"); + WriteCvarString(f, "get5_max_tech_pauses"); WriteCvarString(f, "get5_pause_on_veto"); WriteCvarString(f, "get5_pausing_enabled"); WriteCvarString(f, "get5_print_damage"); diff --git a/scripting/get5/goinglive.sp b/scripting/get5/goinglive.sp index bb2b0b014..e21565e6d 100644 --- a/scripting/get5/goinglive.sp +++ b/scripting/get5/goinglive.sp @@ -47,14 +47,6 @@ public Action MatchLive(Handle timer) { SetMatchTeamCvars(); ExecuteMatchConfigCvars(); - // If there is a set amount of timeouts available update the built-in convar and game rule - // properties to show the correct amount of timeouts remaining in gsi and in-game - if (g_MaxPausesCvar.IntValue > 0) { - ServerCommand("mp_team_timeout_max %d", g_MaxPausesCvar.IntValue); - GameRules_SetProp("m_nTerroristTimeOuts", g_MaxPausesCvar.IntValue); - GameRules_SetProp("m_nCTTimeOuts", g_MaxPausesCvar.IntValue); - } - // We force the match end-delay to extend for the duration of the GOTV broadcast here. g_PendingSideSwap = false; SetMatchRestartDelay(); @@ -76,4 +68,4 @@ public void SetMatchRestartDelay() { ConVar mp_match_restart_delay = FindConVar("mp_match_restart_delay"); int delay = GetTvDelay() + MATCH_END_DELAY_AFTER_TV + 5; SetConVarInt(mp_match_restart_delay, delay); -} \ No newline at end of file +} diff --git a/scripting/get5/mapveto.sp b/scripting/get5/mapveto.sp index b76ba84b6..d86800f69 100644 --- a/scripting/get5/mapveto.sp +++ b/scripting/get5/mapveto.sp @@ -15,11 +15,7 @@ public void CreateVeto() { g_VetoCaptains[Get5Team_2] = GetTeamCaptain(Get5Team_2); ResetReadyStatus(); if (g_PauseOnVetoCvar.BoolValue) { - if (g_PausingEnabledCvar.BoolValue) { - PauseGame(Get5Team_None, Get5PauseType_Admin, 1); - } else { - ServerCommand("mp_pause_match"); - } + PauseGame(Get5Team_None, Get5PauseType_Admin); } CreateTimer(1.0, Timer_VetoCountdown, _, TIMER_REPEAT); } @@ -50,7 +46,7 @@ public void VetoFinished() { Get5_MessageToAll("%t", "MapDecidedInfoMessage"); if (IsPaused()) { - ServerCommand("mp_unpause_match"); + UnpauseGame(Get5Team_None); } // Use total series score as starting point, to not print skipped maps diff --git a/scripting/get5/matchconfig.sp b/scripting/get5/matchconfig.sp index acfb910e1..eba7f2ced 100644 --- a/scripting/get5/matchconfig.sp +++ b/scripting/get5/matchconfig.sp @@ -27,12 +27,10 @@ stock bool LoadMatchConfig(const char[] config, bool restoreBackup = false) { // During restore we want to keep our // current pauses used. if (!restoreBackup) { - g_TeamPauseTimeUsed[team] = 0; - g_TeamPausesUsed[team] = 0; - g_TeamTechPausesUsed[team] = 0; + g_TacticalPauseTimeUsed[team] = 0; + g_TacticalPausesUsed[team] = 0; + g_TechnicalPausesUsed[team] = 0; } - g_TechPausedTimeOverride[team] = 0; - g_TeamGivenTechPauseCommand[team] = false; ClearArray(GetTeamCoaches(team)); ClearArray(GetTeamAuths(team)); } @@ -122,6 +120,10 @@ stock bool LoadMatchConfig(const char[] config, bool restoreBackup = false) { ExecuteMatchConfigCvars(); LoadPlayerNames(); EnsureIndefiniteWarmup(); + if (IsPaused()) { + LogDebug("Match was paused when loading match config. Unpausing."); + UnpauseGame(Get5Team_None); + } Stats_InitSeries(); diff --git a/scripting/get5/pausing.sp b/scripting/get5/pausing.sp index bc2302acb..88a17d029 100644 --- a/scripting/get5/pausing.sp +++ b/scripting/get5/pausing.sp @@ -1,8 +1,20 @@ -public bool Pauseable() { - return g_GameState >= Get5State_KnifeRound && g_PausingEnabledCvar.BoolValue; +public bool PauseableGameState() { + return (g_GameState == Get5State_KnifeRound || + g_GameState == Get5State_WaitingForKnifeRoundDecision || + g_GameState == Get5State_Live || + g_GameState == Get5State_GoingLive); } -public bool PauseGame(Get5Team team, Get5PauseType type, int pausesLeft) { +public void PauseGame(Get5Team team, Get5PauseType type) { + if (type == Get5PauseType_None) { + LogError("PauseGame() called with Get5PauseType_None. Please call UnpauseGame() instead."); + UnpauseGame(team); + return; + } + + g_TeamReadyForUnpause[Get5Team_1] = false; + g_TeamReadyForUnpause[Get5Team_2] = false; + Get5MatchPausedEvent event = new Get5MatchPausedEvent(g_MatchID, g_MapNumber, team, type); LogDebug("Calling Get5_OnMatchPaused()"); @@ -13,11 +25,24 @@ public bool PauseGame(Get5Team team, Get5PauseType type, int pausesLeft) { EventLogger_LogAndDeleteEvent(event); - return Pause(type, g_FixedPauseTimeCvar.IntValue, Get5TeamToCSTeam(team), pausesLeft); + // Only create a pause timer if a pause is not already ongoing. + if (g_PauseType == Get5PauseType_None) { + CreateTimer(1.0, Timer_PauseTimeCheck, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); + } + + g_PauseType = type; + g_PausingTeam = team; + g_IsChangingPauseState = true; + ServerCommand("mp_pause_match"); + CreateTimer(0.1, Timer_ResetPauseRestriction); } -public void UnpauseGame(Get5Team team) { - Get5MatchUnpausedEvent event = new Get5MatchUnpausedEvent(g_MatchID, g_MapNumber, team); +public Action Timer_ResetPauseRestriction(Handle timer, int data) { + g_IsChangingPauseState = false; +} + +stock void UnpauseGame(Get5Team team) { + Get5MatchUnpausedEvent event = new Get5MatchUnpausedEvent(g_MatchID, g_MapNumber, team, g_PauseType); LogDebug("Calling Get5_OnMatchUnpaused()"); @@ -27,330 +52,375 @@ public void UnpauseGame(Get5Team team) { EventLogger_LogAndDeleteEvent(event); - Unpause(); + g_PauseType = Get5PauseType_None; + g_PausingTeam = Get5Team_None; + g_LatestPauseDuration = 0; + g_IsChangingPauseState = true; + ServerCommand("mp_unpause_match"); + CreateTimer(0.1, Timer_ResetPauseRestriction); } -public Action Command_TechPause(int client, int args) { - if (!g_AllowTechPauseCvar.BoolValue || !Pauseable() || IsPaused()) { - return Plugin_Handled; +public Action Command_PauseOrUnpauseMatch(int client, const char[] command, int argc) { + if (g_GameState == Get5State_None || g_IsChangingPauseState) { + return Plugin_Continue; } + ReplyToCommand(client, "Get5 prevents calls to %s. Administrators should use sm_pause/sm_unpause.", command); + return Plugin_Stop; +} +public Action Command_TechPause(int client, int args) { if (client == 0) { - PauseGame(Get5Team_None, Get5PauseType_Admin, 1); - Get5_MessageToAll("%t", "AdminForceTechPauseInfoMessage"); + // Redirect admin use of sm_tech to regular pause. We only have one type of admin pause. + return Command_Pause(client, args); + } + + if (!PauseableGameState()) { return Plugin_Handled; } Get5Team team = GetClientMatchTeam(client); - int maxTechPauses = g_MaxTechPauseCvar.IntValue; - int maxTechPauseTime = g_MaxTechPauseTime.IntValue; + if (!IsPlayerTeam(team)) { + return Plugin_Handled; + } - g_TeamReadyForUnpause[Get5Team_1] = false; - g_TeamReadyForUnpause[Get5Team_2] = false; + if (!g_PausingEnabledCvar.BoolValue) { + Get5_MessageToAll("%t", "PausesNotEnabled"); + return Plugin_Handled; + } + + if (!g_AllowTechPauseCvar.BoolValue) { + Get5_MessageToAll("%t", "TechPausesNotEnabled"); + return Plugin_Handled; + } - // Only set these if we are a non-zero value. - if (maxTechPauses > 0 || maxTechPauseTime > 0) { - int timeLeft = maxTechPauseTime - g_TechPausedTimeOverride[team]; - // Don't allow more than one tech pause per time. - if (g_TeamGivenTechPauseCommand[Get5Team_1] || g_TeamGivenTechPauseCommand[Get5Team_2]) { + if (g_PauseType != Get5PauseType_None) { + g_TeamReadyForUnpause[team] = false; + LogDebug("Ignoring technical pause request as game is already paused; setting team to not ready to unpause."); + return Plugin_Handled; + } + + int maxTechPauses = g_MaxTechPausesCvar.IntValue; + int maxTechPauseDuration = g_MaxTechPauseDurationCvar.IntValue; + + // Max tech pause COUNT + if (maxTechPauses > 0) { + if (g_TechnicalPausesUsed[team] >= maxTechPauses) { + Get5_MessageToAll("%t", "TechPauseNoPausesRemaining", g_FormattedTeamNames[team]); return Plugin_Handled; } - if (maxTechPauses > 0 && g_TeamTechPausesUsed[team] >= maxTechPauses) { - Get5_MessageToAll("%t", "TechPauseNoTimeRemaining", g_FormattedTeamNames[team]); - return Plugin_Handled; - } else if (maxTechPauseTime > 0 && timeLeft <= 0) { + } + + // Max tech pause TIME + if (maxTechPauseDuration > 0) { + if (maxTechPauseDuration - g_LatestPauseDuration <= 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); } } - PauseGame(team, Get5PauseType_Tech, 1); - Get5_MessageToAll("%t", "MatchTechPausedByTeamMessage", client); + g_TechnicalPausesUsed[team]++; + PauseGame(team, Get5PauseType_Tech); + Get5_MessageToAll("%t", "MatchTechPausedByTeamMessage", client); + if (maxTechPauses > 0) { + Get5_MessageToAll("%t", "TechPausePausesRemaining", g_FormattedTeamNames[team], maxTechPauses - g_TechnicalPausesUsed[team]); + } return Plugin_Handled; } public Action Command_Pause(int client, int args) { - if (!Pauseable() || IsPaused()) { + if (client == 0) { + PauseGame(Get5Team_None, Get5PauseType_Admin); + Get5_MessageToAll("%t", "AdminForcePauseInfoMessage"); return Plugin_Handled; } - if (client == 0) { - PauseGame(Get5Team_None, Get5PauseType_Admin, 1); - Get5_MessageToAll("%t", "AdminForcePauseInfoMessage"); + if (!PauseableGameState()) { return Plugin_Handled; } Get5Team team = GetClientMatchTeam(client); - int maxPauses = g_MaxPausesCvar.IntValue; - char pausePeriodString[32]; - if (g_ResetPausesEachHalfCvar.BoolValue) { - Format(pausePeriodString, sizeof(pausePeriodString), " %t", "PausePeriodSuffix"); + if (!IsPlayerTeam(team)) { + return Plugin_Handled; } - if (maxPauses > 0 && g_TeamPausesUsed[team] >= maxPauses && IsPlayerTeam(team)) { - Get5_Message(client, "%t", "MaxPausesUsedInfoMessage", maxPauses, pausePeriodString); + if (!g_PausingEnabledCvar.BoolValue) { + Get5_MessageToAll("%t", "PausesNotEnabled"); return Plugin_Handled; } - int maxPauseTime = g_MaxPauseTimeCvar.IntValue; - if (maxPauseTime > 0 && g_TeamPauseTimeUsed[team] >= maxPauseTime && IsPlayerTeam(team)) { - Get5_Message(client, "%t", "MaxPausesTimeUsedInfoMessage", maxPauseTime, pausePeriodString); + if (g_PauseType != Get5PauseType_None) { + g_TeamReadyForUnpause[team] = false; + LogDebug("Ignoring tactical pause request as game is already paused; setting team to not ready to unpause."); return Plugin_Handled; } - g_TeamReadyForUnpause[Get5Team_1] = false; - g_TeamReadyForUnpause[Get5Team_2] = false; + int maxPauses = g_MaxTacticalPausesCvar.IntValue; - int pausesLeft = 1; - if (g_MaxPausesCvar.IntValue > 0 && IsPlayerTeam(team)) { - // Update the built-in convar to ensure correct max amount is displayed - ServerCommand("mp_team_timeout_max %d", g_MaxPausesCvar.IntValue); - pausesLeft = g_MaxPausesCvar.IntValue - g_TeamPausesUsed[team] - 1; + if (!g_FixedPauseTimeCvar.BoolValue) { + int maxPauseTime = g_MaxPauseTimeCvar.IntValue; + if (maxPauseTime > 0 && g_TacticalPauseTimeUsed[team] >= maxPauseTime) { + char maxPauseTimeFormatted[16]; + convertSecondsToMinutesAndSeconds(maxPauseTime, maxPauseTimeFormatted, sizeof(maxPauseTimeFormatted)); + Get5_Message(client, "%t", "MaxPausesTimeUsedInfoMessage", maxPauseTimeFormatted, g_FormattedTeamNames[team]); + return Plugin_Handled; + } } - // If the pause will need explicit resuming, we will create a timer to poll the pause status. - bool need_resume = PauseGame(team, Get5PauseType_Tactical, pausesLeft); + if (maxPauses > 0 && g_TacticalPausesUsed[team] >= maxPauses) { + Get5_Message(client, "%t", "MaxPausesUsedInfoMessage", maxPauses, g_FormattedTeamNames[team]); + return Plugin_Handled; + } + + g_TacticalPausesUsed[team]++; + PauseGame(team, Get5PauseType_Tactical); if (IsPlayer(client)) { Get5_MessageToAll("%t", "MatchPausedByTeamMessage", client); } - if (IsPlayerTeam(team)) { - if (need_resume) { - g_PauseTimeUsed = g_PauseTimeUsed + g_FixedPauseTimeCvar.IntValue - 1; - CreateTimer(1.0, Timer_PauseTimeCheck, team, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); - // This timer is used to only fire off the Unpause event. - CreateTimer(1.0, Timer_UnpauseEventCheck, team, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); - } - - g_TeamPausesUsed[team]++; - - pausePeriodString = ""; - if (g_ResetPausesEachHalfCvar.BoolValue) { - Format(pausePeriodString, sizeof(pausePeriodString), " %t", "PausePeriodSuffix"); - } - - if (g_MaxPausesCvar.IntValue > 0) { - if (pausesLeft == 1 && g_MaxPausesCvar.IntValue > 0) { - Get5_MessageToAll("%t", "OnePauseLeftInfoMessage", g_FormattedTeamNames[team], pausesLeft, - pausePeriodString); - } else if (g_MaxPausesCvar.IntValue > 0) { - Get5_MessageToAll("%t", "PausesLeftInfoMessage", g_FormattedTeamNames[team], pausesLeft, - pausePeriodString); - } + if (maxPauses > 0) { + int pausesLeft = maxPauses - g_TacticalPausesUsed[team]; + if (pausesLeft >= 0) { + Get5_MessageToAll("%t", "PausesLeftInfoMessage", g_FormattedTeamNames[team], pausesLeft); } } - return Plugin_Handled; } -public Action Timer_TechPauseOverrideCheck(Handle timer, int data) { - Get5Team team = view_as(data); - int maxTechPauseTime = g_MaxTechPauseTime.IntValue; - if (!Pauseable()) { - g_TechPausedTimeOverride[team] = 0; - g_TeamGivenTechPauseCommand[team] = false; - return Plugin_Stop; +public Action Command_Unpause(int client, int args) { + if (!IsPaused()) { + // Game is not paused; ignore command. + return Plugin_Handled; } - // Unlimited Tech Pause so no one can unpause unless both teams agree. - if (maxTechPauseTime <= 0) { - g_TechPausedTimeOverride[team] = 0; - return Plugin_Stop; + if (g_PauseType == Get5PauseType_Admin && client != 0) { + Get5_MessageToAll("%t", "UserCannotUnpauseAdmin"); + return Plugin_Handled; } - // This condition will only be hit when we resume from a pause. - if (!g_TeamGivenTechPauseCommand[team]) { - g_TechPausedTimeOverride[team] = 0; - return Plugin_Stop; + // Let console force unpause + if (client == 0) { + UnpauseGame(Get5Team_None); + Get5_MessageToAll("%t", "AdminForceUnPauseInfoMessage"); + return Plugin_Handled; + } + + Get5Team team = GetClientMatchTeam(client); + if (team == g_PausingTeam && !InFreezeTime()) { + Get5_MessageToAll("%t", "PausingTeamCannotUnpauseUntilFreezeTime"); + return Plugin_Handled; + } else if (!IsPlayerTeam(team)) { + return Plugin_Handled; } - int timeLeft = maxTechPauseTime - g_TechPausedTimeOverride[team]; - - // Only count down if we're still frozen, fit the right pause type - // and the team who paused has not given the go ahead. - if (InFreezeTime() && g_TeamGivenTechPauseCommand[team] && g_PauseType == Get5PauseType_Tech && - !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); + g_TeamReadyForUnpause[team] = true; + if (g_PauseType == Get5PauseType_Tech) { + int maxTechPauseDuration = g_MaxTechPauseDurationCvar.IntValue; + int maxTechPauses = g_MaxTechPausesCvar.IntValue; + int techPausesUsed = g_TechnicalPausesUsed[g_PausingTeam]; + + if ((maxTechPauseDuration > 0 && g_LatestPauseDuration >= maxTechPauseDuration) || + (maxTechPauses > 0 && techPausesUsed > maxTechPauses) + ) { + UnpauseGame(team); + if (IsPlayer(client)) { + Get5_MessageToAll("%t", "MatchUnpauseInfoMessage", client); } + return Plugin_Handled; } + } - if (timeLeft <= 0) { - Get5_MessageToAll("%t", "TechPauseRunoutInfoMessage"); - return Plugin_Stop; + if (g_TeamReadyForUnpause[Get5Team_1] && g_TeamReadyForUnpause[Get5Team_2]) { + UnpauseGame(team); + if (IsPlayer(client)) { + Get5_MessageToAll("%t", "MatchUnpauseInfoMessage", client); } + } else if (!g_TeamReadyForUnpause[Get5Team_2]) { + Get5_MessageToAll("%t", "WaitingForUnpauseInfoMessage", g_FormattedTeamNames[Get5Team_1], + g_FormattedTeamNames[Get5Team_2]); + } else if (!g_TeamReadyForUnpause[Get5Team_1]) { + Get5_MessageToAll("%t", "WaitingForUnpauseInfoMessage", g_FormattedTeamNames[Get5Team_2], + g_FormattedTeamNames[Get5Team_1]); } - // Someone can call pause during a round and will set this timer. - // Keep running timer until we are paused. - return Plugin_Continue; + return Plugin_Handled; } -public Action Timer_UnpauseEventCheck(Handle timer, int data) { - if (!Pauseable()) { - g_PauseTimeUsed = 0; +public Action Timer_PauseTimeCheck(Handle timer) { + if (g_PauseType == Get5PauseType_None || !IsPaused()) { + LogDebug("Stopping pause timer as game is not paused."); return Plugin_Stop; } - // Unlimited pause time. - if (g_MaxPauseTimeCvar.IntValue <= 0) { - // Reset state. - g_PauseTimeUsed = 0; - return Plugin_Stop; - } + // Shorter local variable because g_PausingTeam for the rest of the code was just too much. + Get5Team team = g_PausingTeam; if (!InFreezeTime()) { - // Someone can call pause during a round and will set this timer. - // Keep running timer until we are paused. + LogDebug("Ignoring pause counter as game is not yet frozen."); return Plugin_Continue; - } else { - if (g_PauseTimeUsed <= 0) { - Get5Team team = view_as(data); - UnpauseGame(team); - // Reset state - g_PauseTimeUsed = 0; - return Plugin_Stop; - } - g_PauseTimeUsed--; - LogDebug("Subtracting time used. Current time = %d", g_PauseTimeUsed); } - return Plugin_Continue; -} + // This is incremented no matter what and used both for fixed tactical pauses and tech pause time. + g_LatestPauseDuration++; + LogDebug("Incrementing pause duration. Now: %d", g_LatestPauseDuration); -public Action Timer_PauseTimeCheck(Handle timer, int data) { - if (!Pauseable() || !IsPaused() || g_FixedPauseTimeCvar.BoolValue) { - return Plugin_Stop; - } - int maxPauseTime = g_MaxPauseTimeCvar.IntValue; - // Unlimited pause time. - if (maxPauseTime <= 0) { - return Plugin_Stop; - } + char teamString[4]; + CSTeamString(Get5TeamToCSTeam(team), teamString, sizeof(teamString)); - char pausePeriodString[32]; - if (g_ResetPausesEachHalfCvar.BoolValue) { - Format(pausePeriodString, sizeof(pausePeriodString), " %t", "PausePeriodSuffix"); - } + if (g_PauseType == Get5PauseType_Tactical) { - Get5Team team = view_as(data); - int timeLeft = maxPauseTime - g_TeamPauseTimeUsed[team]; - // Only count against the team's pause time if we're actually in the freezetime - // pause and they haven't requested an unpause yet. - if (InFreezeTime() && !g_TeamReadyForUnpause[team]) { - g_TeamPauseTimeUsed[team]++; - - if (timeLeft == 10) { - Get5_MessageToAll("%t", "PauseTimeExpiration10SecInfoMessage", g_FormattedTeamNames[team]); - } else if (timeLeft % 30 == 0) { - Get5_MessageToAll("%t", "PauseTimeExpirationInfoMessage", g_FormattedTeamNames[team], - timeLeft, pausePeriodString); + int maxTacticalPauseTime = g_MaxPauseTimeCvar.IntValue; + int maxTacticalPauses = g_MaxTacticalPausesCvar.IntValue; + int tacticalPausesUsed = g_TacticalPausesUsed[team]; + + int fixedPauseTime = g_FixedPauseTimeCvar.IntValue; + if (fixedPauseTime > 0 && fixedPauseTime < 15) { + fixedPauseTime = 15; // Don't allow less than 15 second fixed pauses. } - } - if (timeLeft <= 0) { - Get5_MessageToAll("%t", "PauseRunoutInfoMessage", g_FormattedTeamNames[team]); - UnpauseGame(team); - return Plugin_Stop; - } - return Plugin_Continue; -} + // -1 assumes unlimited. + int timeLeft = -1; -public Action Command_Unpause(int client, int args) { - if (!IsPaused()) - return Plugin_Handled; + if (fixedPauseTime > 0) { + timeLeft = fixedPauseTime - g_LatestPauseDuration; + if (timeLeft <= 0) { + UnpauseGame(team); + return Plugin_Stop; + } + } else if (maxTacticalPauses > 0 && tacticalPausesUsed > maxTacticalPauses) { + // The game gets unpaused if the number of maximum pauses changes to below the number of used pauses while a + // pause is active. Kind of a weird edge-case, but it should be handled gracefully. + Get5_MessageToAll("%t", "MaxPausesUsedInfoMessage", maxTacticalPauses, g_FormattedTeamNames[g_PausingTeam]); + UnpauseGame(team); + return Plugin_Stop; + } else if (!g_TeamReadyForUnpause[team]) { + // If the team that called the pause has indicated they are ready, no more time should be subtracted from their + // maximum pause time, but the timer must keep running as they could go back to not-ready-for-unpause before the + // other team unpauses, in which case we would keep counting their seconds used. + g_TacticalPauseTimeUsed[team]++; + LogDebug("Adding tactical pause time used for Get5Team %d. Now: %d", team, g_TacticalPauseTimeUsed[team]); + if (maxTacticalPauseTime > 0) { + timeLeft = maxTacticalPauseTime - g_TacticalPauseTimeUsed[team]; + if (timeLeft <= 0) { + Get5_MessageToAll("%t", "PauseRunoutInfoMessage", g_FormattedTeamNames[team]); + UnpauseGame(team); + return Plugin_Stop; + } + } + } - if (g_PauseType == Get5PauseType_Admin && client != 0) { - Get5_MessageToAll("%t", "UserCannotUnpauseAdmin"); - return Plugin_Handled; - } + char timeLeftFormatted[16] = ""; + if (timeLeft >= 0) { + // Only format the string once; not inside the loop. + convertSecondsToMinutesAndSeconds(timeLeft, timeLeftFormatted, sizeof(timeLeftFormatted)); + } - // Let console force unpause - if (client == 0) { - // Remove any techpause conditions if an admin unpauses. - if (g_PauseType == Get5PauseType_Tech) { - LOOP_TEAMS(team) { - if (team != Get5Team_None) { - g_TeamGivenTechPauseCommand[team] = false; - g_TechPausedTimeOverride[team] = 0; + char pauseTimeMaxFormatted[16] = ""; + if (timeLeft >= 0) { + convertSecondsToMinutesAndSeconds(maxTacticalPauseTime, pauseTimeMaxFormatted, sizeof(pauseTimeMaxFormatted)); + } + + LOOP_CLIENTS(i) { + if (IsPlayer(i)) { + if (fixedPauseTime) { // If fixed pause; takes precedence over total time and reuses timeLeft for simplicity + if (maxTacticalPauses > 0) { + // Team A (CT) tactical pause (2/4): 0:45 + PrintHintText(i, "%s (%s) %t (%d/%d): %s", g_TeamNames[team], teamString, "TacticalPauseMidSentence", tacticalPausesUsed, maxTacticalPauses, timeLeftFormatted); + } else { + // Team A (CT) tactical pause: 0:45 + PrintHintText(i, "%s (%s) %t: %s", g_TeamNames[team], teamString, "TacticalPauseMidSentence", timeLeftFormatted); + } + } else if (timeLeft >= 0) { // If total time restriction + if (maxTacticalPauses > 0) { + // Team A (CT) tactical pause (2/4). + // Remaining pause time: 0:45 / 3:00 + PrintHintText(i, "%s (%s) %t (%d/%d).\n%t: %s / %s", g_TeamNames[team], teamString, "TacticalPauseMidSentence", tacticalPausesUsed, maxTacticalPauses, "PauseTimeRemainingPrefix", timeLeftFormatted, pauseTimeMaxFormatted); + } else { + // Team A (CT) tactical pause. + // Remaining pause time: 0:45 / 3:00 + PrintHintText(i, "%s (%s) %t.\n%t: %s / %s", g_TeamNames[team], teamString, "TacticalPauseMidSentence", "PauseTimeRemainingPrefix", timeLeftFormatted, pauseTimeMaxFormatted); + } + } else { // if no time restriction or awaiting unpause + if (maxTacticalPauses > 0) { + // Team A (CT) tactical pause (2/4). + // Awaiting unpause. + PrintHintText(i, "%s (%s) %t (%d/%d).\n%t.", g_TeamNames[team], teamString, "TacticalPauseMidSentence", tacticalPausesUsed, maxTacticalPauses, "AwaitingUnpause"); + } else { + // Team A (CT) tactical pause. + // Awaiting unpause. + PrintHintText(i, "%s (%s) %t.\n%t.", g_TeamNames[team], teamString, "TacticalPauseMidSentence", "AwaitingUnpause"); + } } } } - UnpauseGame(Get5Team_None); - Get5_MessageToAll("%t", "AdminForceUnPauseInfoMessage"); - return Plugin_Handled; - } - // Check to see if we have a timeout that is timed. Otherwise, we need to - // continue for unpausing. New pause type to avoid match restores failing. - if (g_FixedPauseTimeCvar.BoolValue && g_PauseType == Get5PauseType_Tactical) { - return Plugin_Handled; - } + } else if (g_PauseType == Get5PauseType_Tech) { - Get5Team team = GetClientMatchTeam(client); - g_TeamReadyForUnpause[team] = true; + int maxTechPauseDuration = g_MaxTechPauseDurationCvar.IntValue; + int maxTechPauses = g_MaxTechPausesCvar.IntValue; + int techPausesUsed = g_TechnicalPausesUsed[team]; - int maxTechPauseTime = g_MaxTechPauseTime.IntValue; + // -1 assumes unlimited. + int timeLeft = -1; - // Get which team is currently tech paused. - Get5Team pausedTeam = Get5Team_None; - if (g_TeamGivenTechPauseCommand[Get5Team_1]) { - pausedTeam = Get5Team_1; - } else if (g_TeamGivenTechPauseCommand[Get5Team_2]) { - pausedTeam = Get5Team_2; - } - - if (g_PauseType == Get5PauseType_Tech && maxTechPauseTime > 0) { - if (g_TechPausedTimeOverride[pausedTeam] >= maxTechPauseTime) { - UnpauseGame(team); - if (IsPlayer(client)) { - Get5_MessageToAll("%t", "MatchUnpauseInfoMessage", client); + // If tech pause max is reduced to below what is used, we don't want to print remaining time, as anyone can unpause. + // We achieve this by simply skipping the time calculation if max tech pauses have been exceeded. + if (!g_TeamReadyForUnpause[team] && (maxTechPauses == 0 || techPausesUsed <= maxTechPauses)) { + if (maxTechPauseDuration > 0) { + timeLeft = maxTechPauseDuration - g_LatestPauseDuration; + if (timeLeft == 0) { + // Only print to chat when hitting 0, but keep the timer going as tech pauses don't unpause on their own. + // The PrintHintText below will inform users that they can now unpause. + Get5_MessageToAll("%t", "TechPauseRunoutInfoMessage"); + } } - if (pausedTeam != Get5Team_None) { - g_TeamGivenTechPauseCommand[pausedTeam] = false; - g_TechPausedTimeOverride[pausedTeam] = 0; + } + + char timeLeftFormatted[16] = ""; + if (timeLeft >= 0) { + // Only format the string once; not inside the loop. + convertSecondsToMinutesAndSeconds(timeLeft, timeLeftFormatted, sizeof(timeLeftFormatted)); + } + + LOOP_CLIENTS(i) { + if (IsPlayer(i)) { + if (timeLeft >= 0) { + if (maxTechPauses > 0) { + // Team A (CT) technical pause (3/4): Time remaining before anyone can unpause: 1:30 + PrintHintText(i, "%s (%s) %t (%d/%d).\n%t: %s", g_TeamNames[team], teamString, "TechnicalPauseMidSentence", techPausesUsed, maxTechPauses, "TimeRemainingBeforeAnyoneCanUnpausePrefix", timeLeftFormatted); + } else { + // Team A (CT) technical pause. Time remaining before anyone can unpause: 1:30 + PrintHintText(i, "%s (%s) %t.\n%t: %s", g_TeamNames[team], teamString, "TechnicalPauseMidSentence", "TimeRemainingBeforeAnyoneCanUnpausePrefix", timeLeftFormatted); + } + } else { + if (maxTechPauses > 0) { + // Team A (CT) technical pause (3/4). Awaiting unpause. + PrintHintText(i, "%s (%s) %t (%d/%d).\n%t.", g_TeamNames[team], teamString, "TechnicalPauseMidSentence", techPausesUsed, maxTechPauses, "AwaitingUnpause"); + } else { + // Team A (CT) technical pause. Awaiting unpause. + PrintHintText(i, "%s (%s) %t.\n%t.", g_TeamNames[team], teamString, "TechnicalPauseMidSentence", "AwaitingUnpause"); + } + } } - return Plugin_Handled; } - } - if (g_TeamReadyForUnpause[Get5Team_1] && g_TeamReadyForUnpause[Get5Team_2]) { - UnpauseGame(team); - if (pausedTeam != Get5Team_None) { - g_TeamGivenTechPauseCommand[pausedTeam] = false; - g_TechPausedTimeOverride[pausedTeam] = 0; + } else if (g_PauseType == Get5PauseType_Admin) { + + LOOP_CLIENTS(i) { + if (IsPlayer(i)) { + PrintHintText(i, "%t", "PausedByAdministrator"); + } } - if (IsPlayer(client)) { - Get5_MessageToAll("%t", "MatchUnpauseInfoMessage", client); + + } else if (g_PauseType == Get5PauseType_Backup) { + + LOOP_CLIENTS(i) { + if (IsPlayer(i)) { + PrintHintText(i, "%t", "PausedForBackup"); + } } - } else if (g_TeamReadyForUnpause[Get5Team_1] && !g_TeamReadyForUnpause[Get5Team_2]) { - Get5_MessageToAll("%t", "WaitingForUnpauseInfoMessage", g_FormattedTeamNames[Get5Team_1], - g_FormattedTeamNames[Get5Team_2]); - } else if (!g_TeamReadyForUnpause[Get5Team_1] && g_TeamReadyForUnpause[Get5Team_2]) { - Get5_MessageToAll("%t", "WaitingForUnpauseInfoMessage", g_FormattedTeamNames[Get5Team_2], - g_FormattedTeamNames[Get5Team_1]); - } - return Plugin_Handled; + } + return Plugin_Continue; } diff --git a/scripting/get5/util.sp b/scripting/get5/util.sp index 4c7b90582..9ab377b33 100644 --- a/scripting/get5/util.sp +++ b/scripting/get5/util.sp @@ -293,38 +293,6 @@ stock bool IsPaused() { return GameRules_GetProp("m_bMatchWaitingForResume") != 0; } -// Pauses and returns if the match will automatically unpause after the duration ends. -stock bool Pause(Get5PauseType pauseType, int pauseTime, int csTeam, int pausesLeft) { - if (pauseType == Get5PauseType_None) { - LogMessage("Pause() called with Get5PauseType_None. Please call Unpause() instead."); - Unpause(); - return false; - } - - g_PauseType = pauseType; - ServerCommand("mp_pause_match"); - if (pauseType == Get5PauseType_Tech || pauseTime == 0 || csTeam == CS_TEAM_SPECTATOR || - csTeam == CS_TEAM_NONE) { - return false; - } else { - if (csTeam == CS_TEAM_T) { - GameRules_SetProp("m_bTerroristTimeOutActive", true); - GameRules_SetPropFloat("m_flTerroristTimeOutRemaining", float(pauseTime)); - GameRules_SetProp("m_nTerroristTimeOuts", pausesLeft); - } else if (csTeam == CS_TEAM_CT) { - GameRules_SetProp("m_bCTTimeOutActive", true); - GameRules_SetPropFloat("m_flCTTimeOutRemaining", float(pauseTime)); - GameRules_SetProp("m_nCTTimeOuts", pausesLeft); - } - return true; - } -} - -stock void Unpause() { - g_PauseType = Get5PauseType_None; - ServerCommand("mp_unpause_match"); -} - stock void RestartGame(int delay) { ServerCommand("mp_restartgame %d", delay); } @@ -849,3 +817,13 @@ stock Get5BombSite GetNearestBombsite(int client) { return (aDist < bDist) ? Get5BombSite_A : Get5BombSite_B; } + +stock void convertSecondsToMinutesAndSeconds(int timeAsSeconds, char[] buffer, const int bufferSize) { + int minutes = 0; + int seconds = timeAsSeconds; + if (timeAsSeconds >= 60) { + minutes = timeAsSeconds / 60; + seconds = timeAsSeconds % 60; + } + Format(buffer, bufferSize, seconds < 10 ? "%d:0%d" : "%d:%d", minutes, seconds); +} diff --git a/scripting/include/get5.inc b/scripting/include/get5.inc index e95b26982..12b71e357 100644 --- a/scripting/include/get5.inc +++ b/scripting/include/get5.inc @@ -904,8 +904,7 @@ methodmap Get5KnifeRoundWonEvent < Get5MapTeamEvent { } - -methodmap Get5MatchPausedEvent < Get5MapTeamEvent { +methodmap Get5MatchPauseEvent < Get5MapTeamEvent { property Get5PauseType PauseType { public get() { @@ -918,6 +917,9 @@ methodmap Get5MatchPausedEvent < Get5MapTeamEvent { ConvertGet5PauseTypeToStringInJson(this, "pause_type", type); } } +} + +methodmap Get5MatchPausedEvent < Get5MatchPauseEvent { public Get5MatchPausedEvent(const char[] matchId, const int mapNumber, const Get5Team team, const Get5PauseType pauseType) { Get5MatchPausedEvent self = view_as(new JSON_Object()); @@ -931,14 +933,15 @@ methodmap Get5MatchPausedEvent < Get5MapTeamEvent { } -methodmap Get5MatchUnpausedEvent < Get5MapTeamEvent { +methodmap Get5MatchUnpausedEvent < Get5MatchPauseEvent { - public Get5MatchUnpausedEvent(const char[] matchId, const int mapNumber, const Get5Team team) { + public Get5MatchUnpausedEvent(const char[] matchId, const int mapNumber, const Get5Team team, const Get5PauseType pauseType) { Get5MatchUnpausedEvent self = view_as(new JSON_Object()); self.SetEvent("game_unpaused"); self.SetMatchId(matchId); self.MapNumber = mapNumber; self.Team = team; + self.PauseType = pauseType; return self; } diff --git a/translations/chi/get5.phrases.txt b/translations/chi/get5.phrases.txt index fbbdbe623..98e1d73cf 100644 --- a/translations/chi/get5.phrases.txt +++ b/translations/chi/get5.phrases.txt @@ -64,17 +64,13 @@ { "chi" "{1}有10秒的时间来准备就绪,否则将被视为放弃比赛。" } - "PausePeriodSuffix" - { - "chi" "于这个半场" - } "MaxPausesUsedInfoMessage" { - "chi" "您的队伍已经使用了最大为{1}次的暂停次数{2}。" + "chi" "您的队伍已经使用了最大为{1}次的暂停次数。" } "MaxPausesTimeUsedInfoMessage" { - "chi" "您的队伍已经使用了最大为{1}秒的暂停时间{2}。" + "chi" "您的队伍已经使用了最大为{1}秒的暂停时间。" } "MatchPausedByTeamMessage" { @@ -84,18 +80,6 @@ { "chi" "{1}要求发起一个技术暂停。" } - "AdminForceTechPauseInfoMessage" - { - "chi" "一位管理员发起了技术暂停。" - } - "PauseTimeExpiration10SecInfoMessage" - { - "chi" "{1}的暂停时间即将耗尽,将在10秒后解除暂停。" - } - "PauseTimeExpirationInfoMessage" - { - "chi" "{1}剩余{2}秒的暂停时间{3}。" - } "PauseRunoutInfoMessage" { "chi" "{1}的暂停时间已经耗尽,已解除比赛的暂停。" @@ -110,11 +94,7 @@ } "PausesLeftInfoMessage" { - "chi" "{1}剩余{2}次pauses暂停次数{3}。" - } - "OnePauseLeftInfoMessage" - { - "chi" "{1}剩余{2}次pauses暂停次数{3}。" + "chi" "{1}剩余{2}次pauses暂停次数。" } "TeamFailToReadyMinPlayerCheck" { diff --git a/translations/da/get5.phrases.txt b/translations/da/get5.phrases.txt index 09f75497f..20012325b 100644 --- a/translations/da/get5.phrases.txt +++ b/translations/da/get5.phrases.txt @@ -72,45 +72,89 @@ { "da" "{1} har 10 sekunder til at gøre sig klar før de opgiver kampen." } - "PausePeriodSuffix" - { - "da" "til denne halvleg" - } "MaxPausesUsedInfoMessage" { - "da" "Dit hold har allerede brugt max {1} pauser{2}." + "da" "{2} har brugt alle deres taktiske pauser ({1})." } "MaxPausesTimeUsedInfoMessage" { - "da" "Dit hold har allerede brugt max {1} sekunder af pause tid{2}." + "da" "{2} har brugt al deres taktiske pausetid ({1})." } "MatchPausedByTeamMessage" { - "da" "{1} satte kampen på pause." + "da" "{1} har bedt om taktisk pause." } "MatchTechPausedByTeamMessage" { "da" "{1} har bedt om teknisk pause." } - "AdminForceTechPauseInfoMessage" + "TechPausesNotEnabled" + { + "da" "Tekniske pauser er ikke aktiveret." + } + "TechnicalPauseMidSentence" + { + "da" "teknisk pause" + } + "TacticalPauseMidSentence" + { + "da" "taktisk pause" + } + "TimeRemainingBeforeAnyoneCanUnpausePrefix" + { + "da" "Resterende tid, før alle kan unpause" + } + "PauseTimeRemainingPrefix" + { + "da" "Tilbageværende pausetid" + } + "AwaitingUnpause" + { + "da" "Afventer unpause" + } + "PausedByAdministrator" + { + "da" "En administrator har sat kampen på pause." + } + "PausedForBackup" + { + "da" "Kampen er blevet gendannet fra en backup. Begge hold skal unpause for at fortsætte." + } + "PauseNotAvailable" { - "da" "En admin har bedt om teknisk pause." + "da" "Der kan ikke anmodes om pause, før kampen er igang, og kun hvis pausesystemet er slået til." } - "PauseTimeExpiration10SecInfoMessage" + "UserCannotUnpauseAdmin" { - "da" "{1}s pause udløber om 10 sekunder." + "da" "Pauser startet af administratorer kan kun afbrydes af administratorer." } - "PauseTimeExpirationInfoMessage" + "PausingTeamCannotUnpauseUntilFreezeTime" { - "da" "{1} har {2} sekunder pausetid tilbage {3}." + "da" "Du kan ikke afbryde din pause, før den er startet. Pauseanmodninger kan ikke annulleres." } "PauseRunoutInfoMessage" { "da" "{1} er løbet tør for pausetid. Kampen fortsættes." } + "TechPauseRunoutInfoMessage" + { + "da" "Maksimal teknisk pauselængde er nået, og alle kan nu stoppe pausen." + } + "TechPauseNoTimeRemaining" + { + "da" "{1} har ikke mere teknisk pausetid. Brug taktisk pause i stedet." + } + "TechPauseNoPausesRemaining" + { + "da" "{1} har ikke flere tekniske pauser. Brug taktisk pause i stedet." + } + "TechPausePausesRemaining" + { + "da" "Tekniske pauser tilbage for {1}: {2}" + } "MatchUnpauseInfoMessage" { - "da" "{1:N} fortsatte kampen." + "da" "{1} fortsatte kampen." } "WaitingForUnpauseInfoMessage" { @@ -118,11 +162,7 @@ } "PausesLeftInfoMessage" { - "da" "{1} har {2} pauser tilbage{3}." - } - "OnePauseLeftInfoMessage" - { - "da" "{1} har {2} pause tilbage{3}." + "da" "Taktiske pauser tilbage for {1}: {2}" } "TeamFailToReadyMinPlayerCheck" { @@ -134,11 +174,11 @@ } "TeamReadyToRestoreBackupInfoMessage" { - "da" "{1} er klar til at genoprette match backup." + "da" "{1} er klar til at genoprette match fra backup." } "TeamReadyToKnifeInfoMessage" { - "da" "{1} er klar til at knife om sider." + "da" "{1} er klar til at knife om side." } "TeamReadyToBeginInfoMessage" { @@ -206,12 +246,16 @@ } "MatchFinishedInfoMessage" { - "da" "Kampen er afgjort." + "da" "Kampen er afsluttet" } "CurrentScoreInfoMessage" { "da" "{LIGHT_GREEN}{1} {GREEN}{2} {NORMAL}- {GREEN}{3} {LIGHT_GREEN}{4}" } + "StopCommandNotEnabled" + { + "da" "Stop-kommandoen er ikke aktiveret." + } "BackupLoadedInfoMessage" { "da" "Backup {1} indlæst." @@ -238,7 +282,7 @@ } "TeamDecidedToSwapInfoMessage" { - "da" "{1} har besluttet at skifte." + "da" "{1} har besluttet at skifte side." } "TeamLostTimeToDecideInfoMessage" { @@ -302,7 +346,7 @@ } "MapVetoPickConfirmMenuText" { - "da" "Bekræft at du vil spille {1}:" + "da" "Bekræft, at du vil spille {1}:" } "MapVetoBanMenuText" { diff --git a/translations/de/get5.phrases.txt b/translations/de/get5.phrases.txt index 19d76863e..4937241e0 100644 --- a/translations/de/get5.phrases.txt +++ b/translations/de/get5.phrases.txt @@ -56,30 +56,18 @@ { "de" "{1} hat 10 Sekunden fertig zu werden oder sie geben auf." } - "PausePeriodSuffix" - { - "de" "für diese Hälfte" - } "MaxPausesUsedInfoMessage" { - "de" "Dein Team hatte bereits die maximal zulässigen {1} Pausen{2}." + "de" "Dein Team hatte bereits die maximal zulässigen ({1}) Pausen." } "MaxPausesTimeUsedInfoMessage" { - "de" "Dein Team hat bereits die maximalen {1} Sekunden der Pausezeit genutzt{2}." + "de" "Dein Team hat bereits die maximalen ({1}) der Pausezeit genutzt." } "MatchPausedByTeamMessage" { "de" "{1} hat das Match pausiert." } - "PauseTimeExpiration10SecInfoMessage" - { - "de" "{1} hat fast keine Pausenzeit mehr, es wird in 10 Sekunden fortgefahren." - } - "PauseTimeExpirationInfoMessage" - { - "de" "{1} hat {2} Sekunden der Pausenzeit übrig{3}." - } "PauseRunoutInfoMessage" { "de" "{1} hat keine Pausenzeit mehr, weiter gehts!" diff --git a/translations/es/get5.phrases.txt b/translations/es/get5.phrases.txt index 72ab92c19..f502ac12c 100644 --- a/translations/es/get5.phrases.txt +++ b/translations/es/get5.phrases.txt @@ -68,17 +68,13 @@ { "es" "{1} tiene 10 segundos para manifestarse listo, de lo contrario sera descalificado.." } - "PausePeriodSuffix" - { - "es" "para este corta-tiempo" - } "MaxPausesUsedInfoMessage" { - "es" "Su equipo ya utilizó su maximo de {1} pausas {2}." + "es" "Su equipo ya utilizó su maximo de {1} pausa(s)." } "MaxPausesTimeUsedInfoMessage" { - "es" "Su equipo ya utilizó su maximo de {1} segundos de pausa {2}." + "es" "Su equipo ya utilizó su maximo de {1} pausa." } "MatchPausedByTeamMessage" { @@ -88,18 +84,6 @@ { "es" "{1} pidió una pausa tecnica." } - "AdminForceTechPauseInfoMessage" - { - "es" "Un administrador ha pedido una pausa tecnica." - } - "PauseTimeExpiration10SecInfoMessage" - { - "es" "{1} pronto se termina la pausa, termino en 10 segundos." - } - "PauseTimeExpirationInfoMessage" - { - "es" "{1} aún dispone de {2} segundos de pausa{3}." - } "PauseRunoutInfoMessage" { "es" "{1} gastó todo su tiempo de pausa, reinicio de la partida." @@ -114,11 +98,7 @@ } "PausesLeftInfoMessage" { - "es" "{1} aún dispone de {2} pausa{3}." - } - "OnePauseLeftInfoMessage" - { - "es" "{1} aún dispone de {2} pausa{3}." + "es" "{1} aún dispone de {2} pausa." } "TeamFailToReadyMinPlayerCheck" { diff --git a/translations/fr/get5.phrases.txt b/translations/fr/get5.phrases.txt index ae163dbad..793d623ad 100644 --- a/translations/fr/get5.phrases.txt +++ b/translations/fr/get5.phrases.txt @@ -68,17 +68,13 @@ { "fr" "{1} a 10 secondes pour se déclarer prêt(e), sinon elle sera déclarée forfait." } - "PausePeriodSuffix" - { - "fr" "pour cette mi-temps" - } "MaxPausesUsedInfoMessage" { - "fr" "Votre équipe a déjà utilisé son maximum de {1} pauses{2}." + "fr" "Votre équipe a déjà utilisé son maximum de {1} pauses." } "MaxPausesTimeUsedInfoMessage" { - "fr" "Votre équipe a déjà utilisé son maximum de {1} secondes de pause{2}." + "fr" "Votre équipe a déjà utilisé son maximum de {1} pause." } "MatchPausedByTeamMessage" { @@ -88,18 +84,6 @@ { "fr" "{1} a demandé une pause technique." } - "AdminForceTechPauseInfoMessage" - { - "fr" "Un admin a demandé une pause technique." - } - "PauseTimeExpiration10SecInfoMessage" - { - "fr" "{1} terminera sa pause dans 10 secondes." - } - "PauseTimeExpirationInfoMessage" - { - "fr" "{1} dispose encore de {2} secondes de pause{3}." - } "PauseRunoutInfoMessage" { "fr" "{1} a épuisé son temps de pause, reprise du match." @@ -114,11 +98,7 @@ } "PausesLeftInfoMessage" { - "fr" "{1} dispose encore de {2} pauses{3}." - } - "OnePauseLeftInfoMessage" - { - "fr" "{1} dispose encore de {2} pause{3}." + "fr" "{1} dispose encore de {2} pauses." } "TeamFailToReadyMinPlayerCheck" { diff --git a/translations/get5.phrases.txt b/translations/get5.phrases.txt index d6013f2df..9b9e83ac3 100644 --- a/translations/get5.phrases.txt +++ b/translations/get5.phrases.txt @@ -78,81 +78,98 @@ "#format" "{1:s}" "en" "{1} has 10 seconds to ready up or forfeit the match." } - "PausePeriodSuffix" - { - "en" "for this half" - } "MaxPausesUsedInfoMessage" { "#format" "{1:d},{2:s}" - "en" "Your team has already used the max {1} pauses{2}." + "en" "{2} has used all their tactical pauses ({1})." } "MaxPausesTimeUsedInfoMessage" { - "#format" "{1:d},{2:s}" - "en" "Your team has already used the max {1} seconds of pause time{2}." + "#format" "{1:s},{2:s}" + "en" "{2} has used all their tactical pause time ({1})." } "MatchPausedByTeamMessage" { "#format" "{1:N}" - "en" "{1} paused the match." + "en" "{1} has called for a tactical pause." } "MatchTechPausedByTeamMessage" { "#format" "{1:N}" "en" "{1} has called for a technical pause." } - "AdminForceTechPauseInfoMessage" + "PausesNotEnabled" { - "en" "An admin has called for a technical pause." + "en" "Pauses are not enabled." } - "UserCannotUnpauseAdmin" + "TechPausesNotEnabled" { - "en" "As an admin has called for this pause, it must also be unpaused by an admin." + "en" "Technical pauses are not enabled." } - "PauseTimeExpiration10SecInfoMessage" + "TechnicalPauseMidSentence" { - "#format" "{1:s}" - "en" "{1} is almost out of pause time, unpausing in 10 seconds." + "en" "technical pause" } - "PauseTimeExpirationInfoMessage" + "TacticalPauseMidSentence" { - "#format" "{1:s},{2:d},{3:s}" - "en" "{1} has {2} seconds of pause time left{3}." + "en" "tactical pause" } - "PauseRunoutInfoMessage" + "TimeRemainingBeforeAnyoneCanUnpausePrefix" { - "#format" "{1:s}" - "en" "{1} has run out of pause time, unpausing the match." + "en" "Time remaining before anyone can unpause" } - "TechPauseRunoutInfoMessage" + "PauseTimeRemainingPrefix" { - "en" "Grace period has expired for the technical pause, anyone may unpause now." + "en" "Remaining pause time" } - "TechPauseTimeRemaining" + "AwaitingUnpause" { - "#format" "{1:d}" - "en" "{1} seconds remaining of tech pause time before anyone can resume." + "en" "Awaiting unpause" } - "TechPauseTimeRemainingMinutes" + "PausedByAdministrator" { - "#format" "{1:d}" - "en" "{1} minute(s) remaining of tech pause time before anyone can resume." + "en" "An administrator has paused the match." + } + "PausedForBackup" + { + "en" "The game was restored from a backup. Both teams must unpause to continue." + } + "UserCannotUnpauseAdmin" + { + "en" "As an admin has called for this pause, it must also be unpaused by an admin." + } + "PausingTeamCannotUnpauseUntilFreezeTime" + { + "en" "You cannot unpause before your pause has started. Pause requests cannot be canceled." + } + "PauseRunoutInfoMessage" + { + "#format" "{1:s}" + "en" "{1} has run out of pause time. Unpausing the match." + } + "TechPauseRunoutInfoMessage" + { + "en" "Maximum technical pause length has been reached. Anyone may unpause now." } "TechPauseNoTimeRemaining" { "#format" "{1:s}" - "en" "Sorry, team {1} has no more tech pause time. Please use tactical pauses." + "en" "{1} has no more tech pause time. Please use tactical pauses." + } + "TechPauseNoPausesRemaining" + { + "#format" "{1:s}" + "en" "{1} has no more tech pauses. Please use tactical pauses." } "TechPausePausesRemaining" { "#format" "{1:s},{2:d}" - "en" "Team {1} has {2} technical pause(s) remaining." + "en" "Technical pauses remaining for {1}: {2}" } "MatchUnpauseInfoMessage" { "#format" "{1:N}" - "en" "{1:N} unpaused the match." + "en" "{1} unpaused the match." } "WaitingForUnpauseInfoMessage" { @@ -161,13 +178,8 @@ } "PausesLeftInfoMessage" { - "#format" "{1:s},{2:d},{3:s}" - "en" "{1} has {2} pauses left{3}." - } - "OnePauseLeftInfoMessage" - { - "#format" "{1:s},{2:d},{3:s}" - "en" "{1} has {2} pause left{3}." + "#format" "{1:s},{2:d}" + "en" "Tactical pauses remaining for {1}: {2}" } "TeamFailToReadyMinPlayerCheck" { @@ -274,6 +286,10 @@ "#format" "{1:s},{2:d},{3:d},{4:s}" "en" "{LIGHT_GREEN}{1} {GREEN}{2} {NORMAL}- {GREEN}{3} {LIGHT_GREEN}{4}" } + "StopCommandNotEnabled" + { + "en" "The stop command is not enabled." + } "BackupLoadedInfoMessage" { "#format" "{1:s}" diff --git a/translations/pl/get5.phrases.txt b/translations/pl/get5.phrases.txt index ff0cfb074..4fda81f07 100644 --- a/translations/pl/get5.phrases.txt +++ b/translations/pl/get5.phrases.txt @@ -56,30 +56,18 @@ { "pl" "{1} ma 10 sekund aby być gotowym do meczu albo mecz zostanie oddany na korzyść drużyny przeciwnej." } - "PausePeriodSuffix" - { - "pl" "na tę połowę" - } "MaxPausesUsedInfoMessage" { - "pl" "Twoja drużyna użyła już maksymalnie {1} pauzy{2}." + "pl" "Twoja drużyna użyła już maksymalnie {1} pauzy." } "MaxPausesTimeUsedInfoMessage" { - "pl" "Twoja drużyna użyła już maksymalnie {1} sekund czasu pauzy{2}." + "pl" "Twoja drużyna użyła już maksymalnie {1} pauzy." } "MatchPausedByTeamMessage" { "pl" "{1} zatrzymało mecz." } - "PauseTimeExpiration10SecInfoMessage" - { - "pl" "{1} kończy się czas pauzy, wznowienie rozgrywki nastąpi za 10 sekund." - } - "PauseTimeExpirationInfoMessage" - { - "pl" "{1} zostało {2} sekund pauzy{3}." - } "PauseRunoutInfoMessage" { "pl" "{1} skończył się czas pauzy, wznawianie rozgrywki." @@ -94,11 +82,7 @@ } "PausesLeftInfoMessage" { - "pl" "{1} pozostały {2} pauzy{3}." - } - "OnePauseLeftInfoMessage" - { - "pl" "{1} pozostała {2} pauza{3}." + "pl" "{1} pozostały {2} pauzy." } "TeamFailToReadyMinPlayerCheck" { diff --git a/translations/pt/get5.phrases.txt b/translations/pt/get5.phrases.txt index b5eea5981..1f00fe1fc 100644 --- a/translations/pt/get5.phrases.txt +++ b/translations/pt/get5.phrases.txt @@ -64,30 +64,18 @@ { "pt" "{1} tem 10 segundos para fica prontos ou se render." } - "PausePeriodSuffix" - { - "pt" "para essa metade do jogo." - } "MaxPausesUsedInfoMessage" { - "pt" "Seu time já utilizou o máximo de {1} pausas{2}." + "pt" "Seu time já utilizou o máximo de {1} pausas." } "MaxPausesTimeUsedInfoMessage" { - "pt" "Seu time já usou o máximo de {1} segundos do tempo de pausa{2}." + "pt" "Seu time já usou o máximo de {1} pausa." } "MatchPausedByTeamMessage" { "pt" "{1} pausou a partida." } - "PauseTimeExpiration10SecInfoMessage" - { - "pt" "{1} está quase no fim do tempo de pausa, resumindo a partida em 10 segundos." - } - "PauseTimeExpirationInfoMessage" - { - "pt" "{1} tem {2} segundos faltando para resumir a partida{3}." - } "PauseRunoutInfoMessage" { "pt" "{1} chegou ao fim do tmepo de pause, resumindo a partida." @@ -102,11 +90,7 @@ } "PausesLeftInfoMessage" { - "pt" "{1} tem {2} pauses sobrando{3}." - } - "OnePauseLeftInfoMessage" - { - "pt" "{1} tem {2} pause sobrando{3}." + "pt" "{1} tem {2} pauses sobrando." } "TeamFailToReadyMinPlayerCheck" { diff --git a/translations/ru/get5.phrases.txt b/translations/ru/get5.phrases.txt index 7ceec7bbf..94925465d 100644 --- a/translations/ru/get5.phrases.txt +++ b/translations/ru/get5.phrases.txt @@ -56,30 +56,18 @@ { "ru" "{1} осталось 10 секунд, чтобы подтвердить готовность." } - "PausePeriodSuffix" - { - "ru" "для этой половины" - } "MaxPausesUsedInfoMessage" { - "ru" "Твоя команда уже израсходовала максимум {1} паузы{2}." + "ru" "Твоя команда уже израсходовала максимум {1} паузы." } "MaxPausesTimeUsedInfoMessage" { - "ru" "Твоя команда уже израсходовала максимум {1} секунд времени паузы{2}." + "ru" "Твоя команда уже израсходовала максимум {1} паузы." } "MatchPausedByTeamMessage" { "ru" "{1} поставил матч на паузу." } - "PauseTimeExpiration10SecInfoMessage" - { - "ru" "{1} уже израсходовали количество пауз, снятие с паузы через 10 секунд." - } - "PauseTimeExpirationInfoMessage" - { - "ru" "У {1} осталось {2} секунд от паузы{3}." - } "PauseRunoutInfoMessage" { "ru" "Для {1} время паузы вышло, матч снимается с паузы."