From 1c5cb7525836d7f29b613cffe24600554ba8e03b Mon Sep 17 00:00:00 2001 From: zwayadev <99226035+zwayadev@users.noreply.github.com> Date: Tue, 9 Jun 2026 17:52:58 +0200 Subject: [PATCH 1/2] Created a timeout plugin for CS:S Signed-off-by: zwayadev <99226035+zwayadev@users.noreply.github.com> --- .../addons/sourcemod/plugins/timeouts.smx | Bin 0 -> 6229 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 config/cssource/addons/sourcemod/plugins/timeouts.smx diff --git a/config/cssource/addons/sourcemod/plugins/timeouts.smx b/config/cssource/addons/sourcemod/plugins/timeouts.smx new file mode 100644 index 0000000000000000000000000000000000000000..8bc38324571f2fd4c8f2d99a37f7384317e034bf GIT binary patch literal 6229 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

dA6RypQEbI>jQk9?xE?x7) zB2}ZWz;ME2HZ1zU-)!O)Gs)ng+(>KMqy)(sS?JCYg9LjwgSawQ!d(@+S$`Ed&`=1p zTNlc=Ti?zSE4jARF(;|3Ev>Sj21J18ThoNw!ZS^El1zgDDbO5@R>Ymp&Sp)Dwq zIW9O*lVxl1hs<~<%e?mT>OHZEI<0x_&ung7SHb1UQ()xF*zL&jH`l+%U04|>T&`7% z-=Oj^+Uy0>+EgQMrF$J_Z>}Fy;rgDp(>)clcsY`JNo|)--WY4$w_kj@00Y{of821> zAv?b)J!~R6v>kNybYQ7T-b&VgmrcS)&Ft6KJa)0AG~V)ubybdCf9~!cbtcN^j|N6% z+%G{wWvK}*t9iG;buK=KQsUh3iwZ}xfwuCq1!dD_5B*#@O}Dr%wY!*CuAg(QxM{px z+gz64KNY3UY_8a$wFt2}Oq(yg8gfil%R5leS{ot%JT$j!tbC8q=Bx^IYZ&$?U~QT} zBlMsQ)$c`=uJ?gueaM4`D=q<^qdz YE7bkwm#BF)1O4TPF*o2@(J=M@0ryS9a{vGU literal 0 HcmV?d00001 From e1acfba5ae45c5d17006126b989e8a73559624fa Mon Sep 17 00:00:00 2001 From: zwayadev <99226035+zwayadev@users.noreply.github.com> Date: Tue, 9 Jun 2026 17:57:12 +0200 Subject: [PATCH 2/2] Add files via upload Signed-off-by: zwayadev <99226035+zwayadev@users.noreply.github.com> --- .../addons/sourcemod/scripting/timeouts.sp | 268 ++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 config/cssource/addons/sourcemod/scripting/timeouts.sp diff --git a/config/cssource/addons/sourcemod/scripting/timeouts.sp b/config/cssource/addons/sourcemod/scripting/timeouts.sp new file mode 100644 index 0000000..6b5e9f9 --- /dev/null +++ b/config/cssource/addons/sourcemod/scripting/timeouts.sp @@ -0,0 +1,268 @@ +#include +#include + +public Plugin myinfo = +{ + name = "Timeout Plugin for LIGA", + author = "zwayadev", + description = "Timeouts for LIGA eSports Manager", + version = "1.0b", + url = "https://github.com/playliga" +}; + +#define TIMEOUT_DURATION 30 +#define MAX_TIMEOUTS 3 + +bool g_bTimeoutActive = false; +bool g_bFreezeTime = false; + +int g_iTimeoutsRemaining[4]; +int g_iTimeRemaining; + +Handle g_hTimeoutTimer = INVALID_HANDLE; + +MoveType g_PreviousMoveType[MAXPLAYERS + 1]; + +public void OnPluginStart() +{ + RegConsoleCmd("sm_timeout", Command_Timeout); + + HookEvent("round_start", Event_RoundStart); + HookEvent("round_freeze_end", Event_FreezeEnd, EventHookMode_PostNoCopy); + + ResetTimeouts(); + + +} + +public void OnClientPutInServer(int client) +{ + if (g_bTimeoutActive && IsPlayerAlive(client)) + { + SetEntityMoveType(client, MOVETYPE_NONE); + SetEntPropVector(client, Prop_Data, "m_vecVelocity", Float:{0.0, 0.0, 0.0}); + } + PrintToChatAll("TO CALL A TIMEOUT TYPE .timeout CT/T"); +} + +public void OnMapStart() +{ + ResetTimeouts(); +} + +void ResetTimeouts() +{ + g_iTimeoutsRemaining[2] = MAX_TIMEOUTS; // T + g_iTimeoutsRemaining[3] = MAX_TIMEOUTS; // CT +} + +public Action Event_RoundStart(Event event, const char[] name, bool dontBroadcast) +{ + g_bFreezeTime = true; + g_bTimeoutActive = false; + + return Plugin_Continue; +} + +public Action Event_FreezeEnd(Event event, const char[] name, bool dontBroadcast) +{ + if (!g_bTimeoutActive) + { + g_bFreezeTime = false; + } + + return Plugin_Continue; +} + +void FreezeAllPlayers() +{ + for (int i = 1; i <= MaxClients; i++) + { + if (!IsClientInGame(i) || !IsPlayerAlive(i)) + continue; + + // stop movement instantly + SetEntPropVector(i, Prop_Data, "m_vecVelocity", Float:{0.0, 0.0, 0.0}); + + // disable movement + SetEntityMoveType(i, MOVETYPE_NONE); + } +} + +void UnfreezeAllPlayers() +{ + for (int i = 1; i <= MaxClients; i++) + { + if (!IsClientInGame(i) || !IsPlayerAlive(i)) + continue; + + SetEntityMoveType(i, MOVETYPE_WALK); + } +} + +public Action Timer_Timeout(Handle timer) +{ + g_iTimeRemaining--; + + if (g_iTimeRemaining <= 0) + { + EndTimeout(); + return Plugin_Stop; + } + + if (g_iTimeRemaining <= 5 || g_iTimeRemaining % 5 == 0) + { + PrintCenterTextAll( + "TACTICAL TIMEOUT\n%d seconds remaining", + g_iTimeRemaining + ); + + PrintToChatAll( + "\x04[TIMEOUT]\x01 %d seconds remaining.", + g_iTimeRemaining + ); + } + + return Plugin_Continue; +} + +void EndTimeout() +{ + UnfreezeAllPlayers(); + + g_bTimeoutActive = false; + g_bFreezeTime = false; + + g_hTimeoutTimer = INVALID_HANDLE; + + PrintToChatAll( + "\x04[TIMEOUT]\x01 Timeout ended. Round live!" + ); + + PrintCenterTextAll("LIVE"); +} + +void StartTeamTimeout(int team, int client) +{ + if (g_bTimeoutActive) + { + PrintToChat(client, "[TIMEOUT] Already active."); + return; + } + + if (g_iTimeoutsRemaining[team] <= 0) + { + PrintToChat(client, "[TIMEOUT] No timeouts left for your team."); + return; + } + + g_iTimeoutsRemaining[team]--; + g_bTimeoutActive = true; + g_iTimeRemaining = 30; + + FreezeAllPlayers(); + + if (team == 2) + PrintToChatAll("[TIMEOUT] T called a timeout (%N), %d remaining timeouts for T", client, g_iTimeoutsRemaining[team]); + else + PrintToChatAll("[TIMEOUT] CT called a timeout (%N), %d remaining timeouts for T", client, g_iTimeoutsRemaining[team]); + + CreateTimer(1.0, Timer_Timeout, _, TIMER_REPEAT); +} + +public Action OnClientSayCommand(int client, const char[] command, const char[] sArgs) +{ + if (StrContains(sArgs, ".timeout", false) != 0 && + StrContains(sArgs, "!timeout", false) != 0) + { + return Plugin_Continue; + } + + char args[32]; + strcopy(args, sizeof(args), sArgs); + + ReplaceString(args, sizeof(args), ".timeout", "", false); + ReplaceString(args, sizeof(args), "!timeout", "", false); + + TrimString(args); + + if (StrEqual(args, "CT", false)) + { + StartTeamTimeout(3, client); // CT = team 3 + return Plugin_Handled; + } + + if (StrEqual(args, "T", false)) + { + StartTeamTimeout(2, client); // T = team 2 + return Plugin_Handled; + } + + PrintToChat(client, "[TIMEOUT] Usage: .timeout CT or .timeout T"); + return Plugin_Handled; +} + +public Action Command_Timeout(int client, int args) +{ + if (!IsClientInGame(client)) + return Plugin_Handled; + + int team = GetClientTeam(client); + + if (team != 2 && team != 3) + { + ReplyToCommand(client, "[Timeout] Join a team first."); + return Plugin_Handled; + } + + if (!g_bFreezeTime) + { + ReplyToCommand(client, + "[Timeout] Timeouts may only be called during freeze time."); + return Plugin_Handled; + } + + if (g_bTimeoutActive) + { + ReplyToCommand(client, + "[Timeout] A timeout is already active."); + return Plugin_Handled; + } + + if (g_iTimeoutsRemaining[team] <= 0) + { + ReplyToCommand(client, + "[Timeout] Your team has no timeouts remaining."); + return Plugin_Handled; + } + + g_iTimeoutsRemaining[team]--; + + g_bTimeoutActive = true; + g_iTimeRemaining = TIMEOUT_DURATION; + + FreezeAllPlayers(); + + PrintToChatAll( + "\x04[TIMEOUT]\x01 %N called a tactical timeout. %d remaining for this team.", + client, + g_iTimeoutsRemaining[team] + ); + + PrintToChatAll("DEBUG: timeout triggered"); + + PrintCenterTextAll( + "TACTICAL TIMEOUT\n30 seconds remaining" + ); + + g_hTimeoutTimer = CreateTimer( + 1.0, + Timer_Timeout, + _, + TIMER_REPEAT + ); + + return Plugin_Handled; +} + +