author = "MistaGee (Modify by Snake 60) and www.MyArena.ru",
description = "Switch people to the other team now, at round end, on death",
version = TEAMSWITCH_VERSION,
url = "http://www.sourcemod.net/ and http://www.MyArena.ru/"
new Handle:hAdminMenu = INVALID_HANDLE,
bool:onRoundEndPossible = false,
bool:cstrikeExtAvail = false,
bool:switchOnRoundEnd[MAXPLAYERS+1],
bool:switchOnDeath[MAXPLAYERS+1];
TeamSwitchEvent_Immediately = 0,
TeamSwitchEvent_OnDeath = 1,
TeamSwitchEvent_OnRoundEnd = 2,
TeamSwitchEvent_ToSpec = 3
CreateConVar("teamswitch_version", TEAMSWITCH_VERSION, "TeamSwitch version", FCVAR_NOTIFY);
RegAdminCmd("teamswitch", Command_SwitchImmed, TEAMSWITCH_ADMINFLAG );
RegAdminCmd("teamswitch_death", Command_SwitchDeath, TEAMSWITCH_ADMINFLAG );
RegAdminCmd("teamswitch_roundend", Command_SwitchRend, TEAMSWITCH_ADMINFLAG );
RegAdminCmd("teamswitch_spec", Command_SwitchSpec, TEAMSWITCH_ADMINFLAG );
HookEvent("player_death", Event_PlayerDeath);
decl String:theFolder[40];
GetGameFolderName(theFolder, sizeof(theFolder));
PrintToServer( "[TS] Hooking round end events for game: %s", theFolder);
if (strcmp(theFolder, "dod", false) == 0)
HookEvent( "dod_round_win", Event_RoundEnd, EventHookMode_PostNoCopy);
onRoundEndPossible = true;
else if (strcmp(theFolder, "tf", false) == 0)
HookEvent("teamplay_round_win", Event_RoundEnd, EventHookMode_PostNoCopy);
HookEvent("teamplay_round_stalemate", Event_RoundEnd, EventHookMode_PostNoCopy);
onRoundEndPossible = true;
else if (strcmp(theFolder, "cstrike", false) == 0 || strcmp(theFolder, "csgo", false) == 0)
HookEvent("round_end", Event_RoundEnd, EventHookMode_PostNoCopy);
onRoundEndPossible = true;
if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
OnAdminMenuReady(topmenu);
cstrikeExtAvail = (GetExtensionFileStatus("game.cstrike.ext") == 1);
LoadTranslations("common.phrases");
LoadTranslations("teamswitch.phrases");
GetTeamName(2, teamName1, sizeof(teamName1));
GetTeamName(3, teamName2, sizeof(teamName2));
PrintToServer("[TS] Team Names: %s %s - OnRoundEnd available: %s", teamName1, teamName2, (onRoundEndPossible ? "yes" : "no"));
public Action:Command_SwitchImmed(client, args )
ReplyToCommand(client, "[SM] %t", "ts usage immediately" );
decl String:targetArg[64];
GetCmdArg(1, targetArg, sizeof(targetArg));
decl String:target_name[64];
new target = FindTarget(client, targetArg);
if (target > 0 && IsClientInGame(target))
GetClientName(target, target_name, sizeof(target_name));
for (new i = 1; i <= MaxClients; i++)
if (IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i))
if (GetUserFlagBits(i) == 0)
PrintToChat(i, "\x01[SM] \x01%t \x03%s \x01%t", "ts admin switch", target_name, "ts opposite team");
PrintToChat(i, "\x01[SM] \x01%t \x03%s \x01%t", "ts admins switch", client, target_name, "ts opposite team");
for (new i = 1; i <= MaxClients; i++)
if (IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i))
if (GetUserFlagBits(i) == 0)
PrintToChat(i, "[SM] %t %s %t", "ts admin switch", target_name, "ts opposite team");
PrintToChat(i, "[SM] %t %s %t", "ts admins switch", client, target_name, "ts opposite team");
public Action:Command_SwitchDeath( client, args )
ReplyToCommand( client, "[SM] %t", "ts usage death" );
decl String:targetArg[50];
GetCmdArg(1, targetArg, sizeof(targetArg));
decl String:target_name[50];
new target = FindTarget( client, targetArg );
if (target > 0 && IsClientInGame(target))
switchOnDeath[target] = !switchOnDeath[target];
GetClientName( target, target_name, sizeof(target_name));
if (switchOnDeath[target])
PrintToChatAll( "\x01[SM] \x03%s \x01%t", target_name, "ts will be switch to apposite team on death");
PrintToChatAll( "[SM] %s %t", target_name, "ts will be switch to apposite team on death" );
PrintToChatAll( "\x01[SM] \x03%s \x01%t", target_name, "ts will not be switch to apposite team on death");
PrintToChatAll( "[SM] %s %t", target_name, "ts will not be switch to apposite team on death" );
public Action:Command_SwitchRend(client, args)
ReplyToCommand( client, "[SM] %t", "ts usage roundend" );
ReplyToCommand( client, "[SM] %t", "ts usage roundend error" );
decl String:targetArg[50];
GetCmdArg(1, targetArg, sizeof(targetArg));
new target = FindTarget(client, targetArg);
if (target > 0 && IsClientInGame(target))
decl String:target_name[50];
switchOnRoundEnd[target] = !switchOnRoundEnd[target];
GetClientName(target, target_name, sizeof(target_name));
if (switchOnRoundEnd[target])
PrintToChatAll( "\x01[SM] \x03%s \x01%t", target_name, "ts will be switch to apposite team on rounend");
PrintToChatAll( "[SM] %s %t", target_name, "ts will be switch to apposite team on rounend");
PrintToChatAll( "\x01[SM] \x03%s \x01%t", target_name, "ts will not be switch to apposite team on rounend");
PrintToChatAll( "[SM] %s %t", target_name, "ts will not be switch to apposite team on rounend");
public Action:Command_SwitchSpec( client, args )
ReplyToCommand( client, "[SM] %t", "ts usage spec" );
decl String:targetArg[50];
GetCmdArg(1, targetArg, sizeof(targetArg));
decl String:target_name[50];
new target = FindTarget(client, targetArg);
GetClientName(target, target_name, sizeof(target_name));
PerformSwitch(target, true);
for (new i = 1; i <= MaxClients; i++)
if (IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i))
if (GetUserFlagBits(i) == 0)
PrintToChat(i, "\x01[SM] \x01%t \x03%s \x01%t", "ts admin switch", target_name, "ts to spectators");
PrintToChat(i, "\x01[SM] \x01%t \x03%s \x01%t", "ts admins switch", client, target_name, "ts to spectators");
for (new i = 1; i <= MaxClients; i++)
if (IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i))
if (GetUserFlagBits(i) == 0)
PrintToChat(i, "[SM] %t %s %t", "ts admin switch", target_name, "ts to spectators");
PrintToChat(i, "[SM] %t %s %t", "ts admins switch", client, target_name, "ts to spectators");
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
new victim = GetClientOfUserId(GetEventInt(event, "userid"));
if (bool:victim && switchOnDeath[victim])
if (IsClientConnected(victim) && IsClientInGame(victim))
PerformTimedSwitch(victim);
switchOnDeath[victim] = false;
public Event_RoundEnd( Handle:event, const String:name[], bool:dontBroadcast)
for (new i = 1; i <= MaxClients; i++)
switchOnRoundEnd[i] = false;
public OnLibraryRemoved(const String:name[])
if (StrEqual(name, "adminmenu"))
hAdminMenu = INVALID_HANDLE;
public OnAdminMenuReady( Handle:topmenu )
if (topmenu == hAdminMenu)
new TopMenuObject:menu_category = AddToTopMenu(hAdminMenu, "ts_commands", TopMenuObject_Category, Handle_Category, INVALID_TOPMENUOBJECT);
if (menu_category == INVALID_TOPMENUOBJECT)
AddToTopMenu(hAdminMenu, "ts_immed", TopMenuObject_Item, Handle_ModeImmed, menu_category, "ts_immed", TEAMSWITCH_ADMINFLAG);
AddToTopMenu(hAdminMenu, "ts_death", TopMenuObject_Item, Handle_ModeDeath,menu_category, "ts_death", TEAMSWITCH_ADMINFLAG);
AddToTopMenu(hAdminMenu, "ts_rend", TopMenuObject_Item, Handle_ModeRend,menu_category, "ts_rend", TEAMSWITCH_ADMINFLAG);
AddToTopMenu(hAdminMenu, "ts_spec", TopMenuObject_Item, Handle_ModeSpec, menu_category, "ts_spec", TEAMSWITCH_ADMINFLAG);
public Handle_Category( Handle:topmenu, TopMenuAction:action, TopMenuObject:object_id, param, String:buffer[], maxlength )
case TopMenuAction_DisplayTitle:
Format( buffer, maxlength, "%T", "ts when", param);
case TopMenuAction_DisplayOption:
Format( buffer, maxlength, "%T", "ts commands", param);
public Handle_ModeImmed(Handle:topmenu, TopMenuAction:action, TopMenuObject:object_id, param, String:buffer[], maxlength)
if (action == TopMenuAction_DisplayOption)
Format( buffer, maxlength, "%T", "ts immediately", param);
else if( action == TopMenuAction_SelectOption)
ShowPlayerSelectionMenu(param, TeamSwitchEvent_Immediately);
public Handle_ModeDeath(Handle:topmenu, TopMenuAction:action, TopMenuObject:object_id, param, String:buffer[], maxlength)
if (action == TopMenuAction_DisplayOption)
Format(buffer, maxlength, "%T", "ts on death", param);
else if (action == TopMenuAction_SelectOption)
ShowPlayerSelectionMenu(param, TeamSwitchEvent_OnDeath);
public Handle_ModeRend(Handle:topmenu, TopMenuAction:action, TopMenuObject:object_id, param, String:buffer[], maxlength)
if (action == TopMenuAction_DisplayOption)
Format(buffer, maxlength, "%T", "ts on round end", param);
else if (action == TopMenuAction_SelectOption)
ShowPlayerSelectionMenu(param, TeamSwitchEvent_OnRoundEnd);
public Handle_ModeSpec(Handle:topmenu, TopMenuAction:action, TopMenuObject:object_id, param, String:buffer[], maxlength)
if (action == TopMenuAction_DisplayOption)
Format(buffer, maxlength, "%T", "ts to spec", param);
else if (action == TopMenuAction_SelectOption)
ShowPlayerSelectionMenu(param, TeamSwitchEvent_ToSpec);
void:ShowPlayerSelectionMenu(client, TeamSwitchEvent:event, item = 0)
new Handle:playerMenu = INVALID_HANDLE;
case TeamSwitchEvent_Immediately:
playerMenu = CreateMenu(Handle_SwitchImmed);
case TeamSwitchEvent_OnDeath:
playerMenu = CreateMenu(Handle_SwitchDeath);
case TeamSwitchEvent_OnRoundEnd:
playerMenu = CreateMenu( Handle_SwitchRend);
case TeamSwitchEvent_ToSpec:
playerMenu = CreateMenu(Handle_SwitchSpec);
SetMenuTitle(playerMenu, "%T", "ts choose player", client);
SetMenuExitButton(playerMenu, true);
SetMenuExitBackButton(playerMenu, true);
decl String:cName[45], String:buffer[50], String:cBuffer[5];
for (new i = 1; i < MaxClients; i++)
cTeam = GetClientTeam(i);
GetClientName(i, cName, sizeof(cName));
case TeamSwitchEvent_Immediately, TeamSwitchEvent_ToSpec:
Format(buffer, sizeof(buffer), "[%s] %s", (cTeam == 2 ? teamName1 : teamName2), cName);
case TeamSwitchEvent_OnDeath:
Format(buffer, sizeof(buffer), "[%s] [%s] %s", (switchOnDeath[i] ? 'x' : ' '), (cTeam == 2 ? teamName1 : teamName2), cName);
case TeamSwitchEvent_OnRoundEnd:
Format(buffer, sizeof(buffer), "[%s] [%s] %s", (switchOnRoundEnd[i] ? 'x' : ' '), (cTeam == 2 ? teamName1 : teamName2), cName);
IntToString(i, cBuffer, sizeof(cBuffer));
AddMenuItem(playerMenu, cBuffer, buffer);
DisplayMenu(playerMenu, client, 30);
DisplayMenuAtItem(playerMenu, client, item-1, 30);
public Handle_SwitchImmed(Handle:playerMenu, MenuAction:action, client, target)
Handle_Switch(TeamSwitchEvent_Immediately, playerMenu, action, client, target);
public Handle_SwitchDeath(Handle:playerMenu, MenuAction:action, client, target)
Handle_Switch(TeamSwitchEvent_OnDeath, playerMenu, action, client, target);
public Handle_SwitchRend(Handle:playerMenu, MenuAction:action, client, target)
Handle_Switch(TeamSwitchEvent_OnRoundEnd, playerMenu, action, client, target);
public Handle_SwitchSpec(Handle:playerMenu, MenuAction:action, client, target)
Handle_Switch(TeamSwitchEvent_ToSpec, playerMenu, action, client, target);
void:Handle_Switch(TeamSwitchEvent:event, Handle:playerMenu, MenuAction:action, client, param)
GetMenuItem(playerMenu, param, info, sizeof(info));
new target = StringToInt(info, 10);
if (IsClientConnected(target) && IsClientInGame(target))
case TeamSwitchEvent_Immediately:
decl String:target_name[64];
if (GetClientName(target, target_name, sizeof(target_name)))
for (new i = 1; i <= MaxClients; i++)
if (IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i))
if (GetUserFlagBits(i) == 0)
PrintToChat(i, "\x01[SM] \x01%t \x03%s \x01%t", "ts admin switch", target_name, "ts opposite team");
PrintToChat(i, "\x01[SM] \x01%t \x03%s \x01%t", "ts admins switch", client, target_name, "ts opposite team");
decl String:target_name[64];
if (GetClientName(target, target_name, sizeof(target_name)))
for (new i = 1; i <= MaxClients; i++)
if (IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i))
if (GetUserFlagBits(i) == 0)
PrintToChat(i, "[SM] %t %s %t", "ts admin switch", target_name, "ts opposite team");
PrintToChat(i, "[SM] %t %s %t", "ts admins switch", client, target_name, "ts opposite team");
case TeamSwitchEvent_OnDeath:
if (IsPlayerAlive(target))
switchOnDeath[target] = !switchOnDeath[target];
if (switchOnDeath[target])
decl String:target_name[50];
GetClientName(target, target_name, sizeof(target_name));
PrintToChatAll("\x01[SM] \x03%s \x01%t", target_name, "ts will be switch to apposite team on death");
decl String:target_name[50];
GetClientName(target, target_name, sizeof(target_name));
PrintToChatAll("[SM] %s %t", target_name, "ts will be switch to apposite team on death" );
decl String:target_name[50];
GetClientName(target, target_name, sizeof(target_name));
PrintToChatAll("\x01[SM] \x03%s \x01%t", target_name, "ts will not be switch to apposite team on death");}
decl String:target_name[50];
GetClientName(target, target_name, sizeof(target_name));
PrintToChatAll("[SM] %s %t", target_name, "ts will not be switch to apposite team on death" );
case TeamSwitchEvent_OnRoundEnd:
switchOnRoundEnd[target] = !switchOnRoundEnd[target];
if (switchOnRoundEnd[target])
decl String:target_name[50];
GetClientName( target, target_name, sizeof(target_name) );
PrintToChatAll( "\x01[SM] \x03%s \x01%t", target_name, "ts will be switch to apposite team on rounend");
decl String:target_name[50];
GetClientName(target, target_name, sizeof(target_name));
PrintToChatAll( "[SM] %s %t", target_name, "ts will be switch to apposite team on rounend" );
decl String:target_name[50];
GetClientName(target, target_name, sizeof(target_name));
PrintToChatAll( "\x01[SM] \x03%s \x01%t", target_name, "ts will not be switch to apposite team on rounend");
decl String:target_name[50];
GetClientName(target, target_name, sizeof(target_name));
PrintToChatAll("[SM] %s %t", target_name, "ts will not be switch to apposite team on rounend" );
case TeamSwitchEvent_ToSpec:
PerformSwitch(target, true);
decl String:target_name[50];
if (GetClientName(target, target_name, sizeof(target_name)))
for (new i = 1; i <= MaxClients; i++)
if (IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i))
if (GetUserFlagBits(i) == 0)
PrintToChat(i, "\x01[SM] \x01%t \x03%s \x01%t", "ts admin switch", target_name, "ts to spectators");
PrintToChat(i, "\x01[SM] \x01%t \x03%s \x01%t", "ts admins switch", client, target_name, "ts to spectators");
decl String:target_name[50];
if (GetClientName(target, target_name, sizeof(target_name)))
for (new i = 1; i <= MaxClients; i++)
if (IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i))
if (GetUserFlagBits(i) == 0)
PrintToChat(i, "[SM] %t %s %t", "ts admin switch", target_name, "ts to spectators");
PrintToChat(i, "[SM] %t %s %t", "ts admins switch", client, target_name, "ts to spectators");
ShowPlayerSelectionMenu(client, event, target);
if (param == MenuCancel_ExitBack)
RedisplayAdminMenu(hAdminMenu, client);
void:PerformTimedSwitch(client)
CreateTimer(0.5, Timer_TeamSwitch, GetClientUserId(client));
public Action:Timer_TeamSwitch(Handle:timer, any:userid)
new client = GetClientOfUserId(userid);
if (client != 0 && IsClientConnected(client) && IsClientInGame(client))
void:PerformSwitch(client, bool:toSpec = false)
new cTeam = GetClientTeam(client), iTemp, toTeam = ( toSpec ? TEAM_SPEC : TEAM_1 + TEAM_2 - cTeam );
if (cstrikeExtAvail && !toSpec)
CS_SwitchTeam(client, toTeam);
SetEntityModel(client, "models/player/t_leet.mdl");
SetEntityModel(client, "models/player/ct_sas.mdl");
iTemp = GetPlayerWeaponSlot(client, 4);
CS_DropWeapon(client, iTemp, false, false);
ChangeClientTeam(client, toTeam);
if (GetClientName(client, sName, sizeof(sName)))
PrintToChatAll("\x01[SM] \x03%s \x01%t", sName, "ts switch by admin" );
PrintToChatAll("[SM] %s %t", sName, "ts switch by admin" );