inital commit
This commit is contained in:
194
classrestrict.sp
Normal file
194
classrestrict.sp
Normal file
@@ -0,0 +1,194 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <tf2_stocks>
|
||||
|
||||
#define PL_VERSION "0.6"
|
||||
|
||||
#define TF_CLASS_DEMOMAN 4
|
||||
#define TF_CLASS_ENGINEER 9
|
||||
#define TF_CLASS_HEAVY 6
|
||||
#define TF_CLASS_MEDIC 5
|
||||
#define TF_CLASS_PYRO 7
|
||||
#define TF_CLASS_SCOUT 1
|
||||
#define TF_CLASS_SNIPER 2
|
||||
#define TF_CLASS_SOLDIER 3
|
||||
#define TF_CLASS_SPY 8
|
||||
#define TF_CLASS_UNKNOWN 0
|
||||
|
||||
#define TF_TEAM_BLU 3
|
||||
#define TF_TEAM_RED 2
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "TF2 Class Restrictions",
|
||||
author = "Tsunami",
|
||||
description = "Restrict classes in TF2.",
|
||||
version = PL_VERSION,
|
||||
url = "http://www.tsunami-productions.nl"
|
||||
}
|
||||
|
||||
new g_iClass[MAXPLAYERS + 1];
|
||||
new Handle:g_hEnabled;
|
||||
new Handle:g_hFlags;
|
||||
new Handle:g_hImmunity;
|
||||
new Handle:g_hLimits[4][10];
|
||||
new String:g_sSounds[10][24] = {"", "vo/scout_no03.wav", "vo/sniper_no04.wav", "vo/soldier_no01.wav",
|
||||
"vo/demoman_no03.wav", "vo/medic_no03.wav", "vo/heavy_no02.wav",
|
||||
"vo/pyro_no01.wav", "vo/spy_no02.wav", "vo/engineer_no03.wav"};
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
CreateConVar("sm_classrestrict_version", PL_VERSION, "Restrict classes in TF2.", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY);
|
||||
g_hEnabled = CreateConVar("sm_classrestrict_enabled", "1", "Enable/disable restricting classes in TF2.");
|
||||
g_hFlags = CreateConVar("sm_classrestrict_flags", "", "Admin flags for restricted classes in TF2.");
|
||||
g_hImmunity = CreateConVar("sm_classrestrict_immunity", "0", "Enable/disable admins being immune for restricted classes in TF2.");
|
||||
g_hLimits[TF_TEAM_BLU][TF_CLASS_DEMOMAN] = CreateConVar("sm_classrestrict_blu_demomen", "-1", "Limit for Blu demomen in TF2.");
|
||||
g_hLimits[TF_TEAM_BLU][TF_CLASS_ENGINEER] = CreateConVar("sm_classrestrict_blu_engineers", "-1", "Limit for Blu engineers in TF2.");
|
||||
g_hLimits[TF_TEAM_BLU][TF_CLASS_HEAVY] = CreateConVar("sm_classrestrict_blu_heavies", "-1", "Limit for Blu heavies in TF2.");
|
||||
g_hLimits[TF_TEAM_BLU][TF_CLASS_MEDIC] = CreateConVar("sm_classrestrict_blu_medics", "-1", "Limit for Blu medics in TF2.");
|
||||
g_hLimits[TF_TEAM_BLU][TF_CLASS_PYRO] = CreateConVar("sm_classrestrict_blu_pyros", "-1", "Limit for Blu pyros in TF2.");
|
||||
g_hLimits[TF_TEAM_BLU][TF_CLASS_SCOUT] = CreateConVar("sm_classrestrict_blu_scouts", "-1", "Limit for Blu scouts in TF2.");
|
||||
g_hLimits[TF_TEAM_BLU][TF_CLASS_SNIPER] = CreateConVar("sm_classrestrict_blu_snipers", "-1", "Limit for Blu snipers in TF2.");
|
||||
g_hLimits[TF_TEAM_BLU][TF_CLASS_SOLDIER] = CreateConVar("sm_classrestrict_blu_soldiers", "-1", "Limit for Blu soldiers in TF2.");
|
||||
g_hLimits[TF_TEAM_BLU][TF_CLASS_SPY] = CreateConVar("sm_classrestrict_blu_spies", "-1", "Limit for Blu spies in TF2.");
|
||||
g_hLimits[TF_TEAM_RED][TF_CLASS_DEMOMAN] = CreateConVar("sm_classrestrict_red_demomen", "-1", "Limit for Red demomen in TF2.");
|
||||
g_hLimits[TF_TEAM_RED][TF_CLASS_ENGINEER] = CreateConVar("sm_classrestrict_red_engineers", "-1", "Limit for Red engineers in TF2.");
|
||||
g_hLimits[TF_TEAM_RED][TF_CLASS_HEAVY] = CreateConVar("sm_classrestrict_red_heavies", "-1", "Limit for Red heavies in TF2.");
|
||||
g_hLimits[TF_TEAM_RED][TF_CLASS_MEDIC] = CreateConVar("sm_classrestrict_red_medics", "-1", "Limit for Red medics in TF2.");
|
||||
g_hLimits[TF_TEAM_RED][TF_CLASS_PYRO] = CreateConVar("sm_classrestrict_red_pyros", "-1", "Limit for Red pyros in TF2.");
|
||||
g_hLimits[TF_TEAM_RED][TF_CLASS_SCOUT] = CreateConVar("sm_classrestrict_red_scouts", "-1", "Limit for Red scouts in TF2.");
|
||||
g_hLimits[TF_TEAM_RED][TF_CLASS_SNIPER] = CreateConVar("sm_classrestrict_red_snipers", "-1", "Limit for Red snipers in TF2.");
|
||||
g_hLimits[TF_TEAM_RED][TF_CLASS_SOLDIER] = CreateConVar("sm_classrestrict_red_soldiers", "-1", "Limit for Red soldiers in TF2.");
|
||||
g_hLimits[TF_TEAM_RED][TF_CLASS_SPY] = CreateConVar("sm_classrestrict_red_spies", "-1", "Limit for Red spies in TF2.");
|
||||
|
||||
HookEvent("player_changeclass", Event_PlayerClass);
|
||||
HookEvent("player_spawn", Event_PlayerSpawn);
|
||||
HookEvent("player_team", Event_PlayerTeam);
|
||||
|
||||
AutoExecConfig(true);
|
||||
}
|
||||
|
||||
public OnMapStart()
|
||||
{
|
||||
decl i, String:sSound[32];
|
||||
for(i = 1; i < sizeof(g_sSounds); i++)
|
||||
{
|
||||
Format(sSound, sizeof(sSound), "sound/%s", g_sSounds[i]);
|
||||
PrecacheSound(g_sSounds[i]);
|
||||
AddFileToDownloadsTable(sSound);
|
||||
}
|
||||
}
|
||||
|
||||
public OnClientPutInServer(client)
|
||||
{
|
||||
g_iClass[client] = TF_CLASS_UNKNOWN;
|
||||
}
|
||||
|
||||
public Event_PlayerClass(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
new iClient = GetClientOfUserId(GetEventInt(event, "userid")),
|
||||
iClass = GetEventInt(event, "class"),
|
||||
iTeam = GetClientTeam(iClient);
|
||||
|
||||
if(!(GetConVarBool(g_hImmunity) && IsImmune(iClient)) && IsFull(iTeam, iClass))
|
||||
{
|
||||
ShowVGUIPanel(iClient, iTeam == TF_TEAM_BLU ? "class_blue" : "class_red");
|
||||
EmitSoundToClient(iClient, g_sSounds[iClass]);
|
||||
TF2_SetPlayerClass(iClient, TFClassType:g_iClass[iClient]);
|
||||
}
|
||||
}
|
||||
|
||||
public Event_PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
new iClient = GetClientOfUserId(GetEventInt(event, "userid")),
|
||||
iTeam = GetClientTeam(iClient);
|
||||
|
||||
if(!(GetConVarBool(g_hImmunity) && IsImmune(iClient)) && IsFull(iTeam, (g_iClass[iClient] = _:TF2_GetPlayerClass(iClient))))
|
||||
{
|
||||
ShowVGUIPanel(iClient, iTeam == TF_TEAM_BLU ? "class_blue" : "class_red");
|
||||
EmitSoundToClient(iClient, g_sSounds[g_iClass[iClient]]);
|
||||
PickClass(iClient);
|
||||
}
|
||||
}
|
||||
|
||||
public Event_PlayerTeam(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
new iClient = GetClientOfUserId(GetEventInt(event, "userid")),
|
||||
iTeam = GetEventInt(event, "team");
|
||||
|
||||
if(!(GetConVarBool(g_hImmunity) && IsImmune(iClient)) && IsFull(iTeam, g_iClass[iClient]))
|
||||
{
|
||||
ShowVGUIPanel(iClient, iTeam == TF_TEAM_BLU ? "class_blue" : "class_red");
|
||||
EmitSoundToClient(iClient, g_sSounds[g_iClass[iClient]]);
|
||||
PickClass(iClient);
|
||||
}
|
||||
}
|
||||
|
||||
bool:IsFull(iTeam, iClass)
|
||||
{
|
||||
// If plugin is disabled, or team or class is invalid, class is not full
|
||||
if(!GetConVarBool(g_hEnabled) || iTeam < TF_TEAM_RED || iClass < TF_CLASS_SCOUT)
|
||||
return false;
|
||||
|
||||
// Get team's class limit
|
||||
new iLimit,
|
||||
Float:flLimit = GetConVarFloat(g_hLimits[iTeam][iClass]);
|
||||
|
||||
// If limit is a percentage, calculate real limit
|
||||
if(flLimit > 0.0 && flLimit < 1.0)
|
||||
iLimit = RoundToNearest(flLimit * GetTeamClientCount(iTeam));
|
||||
else
|
||||
iLimit = RoundToNearest(flLimit);
|
||||
|
||||
// If limit is -1, class is not full
|
||||
if(iLimit == -1)
|
||||
return false;
|
||||
// If limit is 0, class is full
|
||||
else if(iLimit == 0)
|
||||
return true;
|
||||
|
||||
// Loop through all clients
|
||||
for(new i = 1, iCount = 0; i <= MaxClients; i++)
|
||||
{
|
||||
// If client is in game, on this team, has this class and limit has been reached, class is full
|
||||
if(IsClientInGame(i) && GetClientTeam(i) == iTeam && _:TF2_GetPlayerClass(i) == iClass && ++iCount > iLimit)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool:IsImmune(iClient)
|
||||
{
|
||||
if(!iClient || !IsClientInGame(iClient))
|
||||
return false;
|
||||
|
||||
decl String:sFlags[32];
|
||||
GetConVarString(g_hFlags, sFlags, sizeof(sFlags));
|
||||
|
||||
// If flags are specified and client has generic or root flag, client is immune
|
||||
return !StrEqual(sFlags, "") && GetUserFlagBits(iClient) & (ReadFlagString(sFlags)|ADMFLAG_ROOT);
|
||||
}
|
||||
|
||||
PickClass(iClient)
|
||||
{
|
||||
// Loop through all classes, starting at random class
|
||||
for(new i = GetRandomInt(TF_CLASS_SCOUT, TF_CLASS_ENGINEER), iClass = i, iTeam = GetClientTeam(iClient);;)
|
||||
{
|
||||
// If team's class is not full, set client's class
|
||||
if(!IsFull(iTeam, i))
|
||||
{
|
||||
TF2_SetPlayerClass(iClient, TFClassType:i);
|
||||
TF2_RespawnPlayer(iClient);
|
||||
g_iClass[iClient] = i;
|
||||
break;
|
||||
}
|
||||
// If next class index is invalid, start at first class
|
||||
else if(++i > TF_CLASS_ENGINEER)
|
||||
i = TF_CLASS_SCOUT;
|
||||
// If loop has finished, stop searching
|
||||
else if(i == iClass)
|
||||
break;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user