bool g_bAllowTeamChange[MAXPLAYERS + 1];
void MovePlayerToTeam(int iClient, int team)
{
if (GetClientTeam(iClient) == team)
return;
g_bAllowTeamChange[iClient] = true; // Allow client to pass inside Hook_ChangeTeamChange()
if (team > CS_TEAM_SPECTATOR)
{
CS_SwitchTeam(iClient, team); // Switch team using cstrike extension
if(team == CS_TEAM_CT) // Don't override hider models
CS_UpdateClientModel(iClient); // Update CT skin
}
else ChangeClientTeam(iClient, team); // Silent team change is enought, the player will die anyway if alive
g_bAllowTeamChange[iClient] = false; // We can reset this here already, the callback is instant
}
public Action Hook_ChangeTeamChange(int iClient, const char[] command, int iArgs)
{
if(!Ready())
return Plugin_Continue;
CreateTimer(1.0, Timer_CheckRestart, _, TIMER_FLAG_NO_MAPCHANGE);
if (iArgs < 1)
return Plugin_Handled;
// Bots will join anyway
if(IsFakeClient(iClient))
return Plugin_Continue;
char sArg[4];
GetCmdArg(1, sArg, sizeof(sArg));
int team_to = StringToInt(sArg);
int team_from = GetClientTeam(iClient);
if(g_bAllowTeamChange[iClient])
return Plugin_Continue; // Teamchange called by MovePlayerToTeam()
if (team_to == CS_TEAM_SPECTATOR && team_from == CS_TEAM_NONE)
return Plugin_Continue; // First team join (when player fully connected)
// Late join?
bool bCTs, bTs;
if(!g_cvDeathSwapteam.BoolValue)
{
LoopIngameClients(i)
{
if(i == iClient)
continue;
if(GetClientTeam(i) != CS_TEAM_CT)
continue;
bCTs = true;
break;
}
}
if(g_cvDeathSwapteam.BoolValue)
{
LoopIngameClients(i)
{
if(i == iClient)
continue;
if(GetClientTeam(i) != CS_TEAM_T)
continue;
bTs = true;
break;
}
}
int iHideTime = PH_CanChangeModel();
bool bAliveCTs;
if(iHideTime > 0)
{
LoopAlivePlayers(i)
{
if(i == iClient)
continue;
if(GetClientTeam(i) != CS_TEAM_CT)
continue;
bAliveCTs = true;
break;
}
if(bAliveCTs)
{
// There is another alive CTs, let him pass
if(team_to == CS_TEAM_T && !g_cvDeathSwapteam.BoolValue)
{
MovePlayerToTeam(iClient, CS_TEAM_T);
CS_RespawnPlayer(iClient);
return Plugin_Handled;
}
if(team_to > CS_TEAM_SPECTATOR && g_cvDeathSwapteam.BoolValue)
{
MovePlayerToTeam(iClient, CS_TEAM_T);
CS_RespawnPlayer(iClient);
return Plugin_Handled;
}
}
if (team_to == CS_TEAM_T && team_from == CS_TEAM_CT && !bAliveCTs)
return Plugin_Handled;
}
// From here we only handle manual team join requests
if(team_to == CS_TEAM_CT && g_cvDeathSwapteam.BoolValue || team_to == CS_TEAM_CT && !bCTs && !g_cvDeathSwapteam.BoolValue)
{
return Plugin_Continue; // Always allow joining CT (fuck team spec glow wh, force all dead players to CT)
}
if(team_to == CS_TEAM_T && !g_cvDeathSwapteam.BoolValue || team_to == CS_TEAM_T && !bTs && g_cvDeathSwapteam.BoolValue)
{
if(GetClientTeam(iClient) != CS_TEAM_CT)
return Plugin_Continue;
else if(!IsPlayerAlive(iClient))
return Plugin_Continue;
}
// Allow joining spectators and seekers always
if(team_to == CS_TEAM_SPECTATOR)
{
if(GetClientTeam(iClient) != CS_TEAM_CT)
MovePlayerToTeam(iClient, CS_TEAM_SPECTATOR);
else if(!IsPlayerAlive(iClient))
MovePlayerToTeam(iClient, CS_TEAM_SPECTATOR);
return Plugin_Handled;
}
// Don't allow to change team while alive
if(IsPlayerAlive(iClient))
return Plugin_Handled;
// Move to default
if(g_cvDeathSwapteam.BoolValue)
MovePlayerToTeam(iClient, CS_TEAM_CT);
else
MovePlayerToTeam(iClient, CS_TEAM_T);
return Plugin_Handled;
}