#define STYLE true
#include <morecolors>
#include <cstrike>
#if STYLE &&(SOURCEMOD_V_MAJOR>1 || SOURCEMOD_V_MINOR>6)
#pragma newdecls required
public Plugin myinfo =
#else
#undef STYLE
public Plugin:myinfo =
#endif
{
name = "Special Team Balancer",
author = "AlmazON",
description = "Специальный Балансировщик Команд",
version = "0.6.0",
url = "http://www.hlmod.ru"
}
#define CSRoundEnd_GameStart 15
#if defined STYLE
bool bP[MAXPLAYERS+1];
float fRD;
int iAF;
public void OnPluginStart()
{
ConVar c;
#else
new bool:bP[MAXPLAYERS+1], Float:fRD, iAF;
public OnPluginStart()
{
decl String:f[AdminFlags_TOTAL], Handle:c;
#endif
if(GetEngineVersion() !=Engine_CSGO)
{
HookEvent("round_end", RE);
if((c=FindConVar("mp_round_restart_delay")))
{
HookConVarChange(c, RD);
#if defined STYLE
fRD = c.FloatValue-0.1;
#else
fRD = GetConVarFloat(c)-0.1;
#endif
}else if(FileExists("cfg/sourcemod/SpecialTeamBalancer.cfg")==false) LogError("Mode simplified balancing (ConVar \"mp_round_restart_delay\" not found).");
}else HookEvent("round_prestart", RP, EventHookMode_PostNoCopy);
HookConVarChange(c=CreateConVar("stb_admin_flag", "", "Flags of administrators, excluding balancing.\n\"\" - all."), AF);
#if defined STYLE
char f[AdminFlags_TOTAL];
c.GetString(f,AdminFlags_TOTAL);
#else
GetConVarString(c,f,AdminFlags_TOTAL);
#endif
AF(c,f,f);
AutoExecConfig(_, "SpecialTeamBalancer");
}
#if defined STYLE
public void AF(ConVar C, const char[] O, const char[] N)
#else
public AF(Handle:C, String:O[], const String:N[])
#endif
{
iAF = ReadFlagString(N[0] ? N:"abcdefghijklmnopqrstz");
OnRebuildAdminCache(AdminCache_Admins);
}
#if defined STYLE
public void RD(ConVar C, const char[] O, const char[] N){fRD = C.FloatValue-0.1;}
public void OnClientPostAdminCheck(int C){bP[C] = !(GetUserFlagBits(C) &iAF);}
#if SOURCEMOD_V_MAJOR>1 || SOURCEMOD_V_MINOR>7
public void OnRebuildAdminCache(AdminCachePart P){if(P==AdminCache_Admins) for(int i=1; i<=MaxClients; ++i) if(IsClientInGame(i)) OnClientPostAdminCheck(i);}
#else
public int OnRebuildAdminCache(AdminCachePart P){if(P==AdminCache_Admins) for(int i=1; i<=MaxClients; ++i) if(IsClientInGame(i)) OnClientPostAdminCheck(i);}
#endif
public void RE(Event E, const char[] N, bool B){CreateTimer(E.GetInt("reason")!=CSRoundEnd_GameStart ? fRD:2.9, TB, _, TIMER_FLAG_NO_MAPCHANGE);}
public void RP(Event E, const char[] N, bool B){PTB();}
public Action TB(Handle T)
#else
public RD(Handle:C, String:O[], String:N[]) fRD = GetConVarFloat(C)-0.1;
public OnClientPostAdminCheck(C) bP[C] = !(GetUserFlagBits(C) &iAF);
public OnRebuildAdminCache(AdminCachePart:P) if(P==AdminCache_Admins) for(new i=1; i<=MaxClients; ++i) if(IsClientInGame(i)) OnClientPostAdminCheck(i);
public RE(Handle:E, String:N[], bool:B) CreateTimer(GetEventInt(E,"reason")!=CSRoundEnd_GameStart ? fRD:2.9, TB, _, TIMER_FLAG_NO_MAPCHANGE);
public RP(Handle:E, String:N[], bool:B) PTB();
public Action:TB(Handle:T)
#endif
{
PTB();
return Plugin_Stop;
}
#if defined STYLE
void PTB()
{
int i=MaxClients, a, b;
#else
PTB()
{
new i=MaxClients, a, b;
#endif
do if(IsClientInGame(i)) switch(GetClientTeam(i))
{
case CS_TEAM_T:++a;
case CS_TEAM_CT:++b;
}while(--i);
if((a=(a-b)/2))
{
b = MaxClients;
if(0 <a)
{
#if defined STYLE
int[] c=new int[a];
#else
decl c[a];
#endif
do if(IsClientInGame(b))
{
if(a) if(GetClientTeam(b)==CS_TEAM_T) if(bP[b]) if(IsPlayerAlive(b))
{
if(a>i) c[i++] = b;
}else
{
CS_SwitchTeam(b, CS_TEAM_CT);
--a;
}CPrintToChat(b, "{lime}[Автобаланс] {white}Лишние игроки команды {fullred}Террористов {white}перемещены.");
}while(--b);
if(a <i) i = a;
while(i)
{
--i;
CS_SwitchTeam(c[i], CS_TEAM_CT);
}
}else
{
#if defined STYLE
int[] c=new int[a=-a];
#else
decl c[a=-a];
#endif
do if(IsClientInGame(b))
{
if(a) if(GetClientTeam(b)==CS_TEAM_CT) if(bP[b]) if(IsPlayerAlive(b))
{
if(a>i) c[i++] = b;
}else
{
CS_SwitchTeam(b, CS_TEAM_T);
--a;
}CPrintToChat(b, "{lime}[Автобаланс] {white}Лишние игроки команды {fullblue}Контр-террористов {white}перемещены.");
}while(--b);
if(a <i) i = a;
while(i)
{
--i;
CS_SwitchTeam(c[i], CS_TEAM_T);
}
}
}
}