#define P_NAME "ReAPI AWP Limitter"
#define P_VERSION "2.2"
#define P_AUTHOR "neygomon"
#define P_CONFIG "awp_limitter"
#include <amxmodx>
#include <reapi>
#if !defined MAX_PLAYERS
const MAX_PLAYERS = 32;
#endif
#define is_immunity(%0) (g_iFlagsImmunity && get_user_flags(%0) & g_iFlagsImmunity)
new bool:g_bUseAwp[MAX_PLAYERS + 1];
new g_iAwpOnTeam[any:TEAM_SPECTATOR];
new g_pcvMinPlayers,
g_pcvAwpCT,
g_pcvAwpTT,
g_pcvImmunity;
new g_iMinPlayers,
g_iMaxAwpCT,
g_iMaxAwpTT,
g_iFlagsImmunity;
new g_szMapName[32];
public plugin_init()
{
register_plugin(P_NAME, P_VERSION, P_AUTHOR);
rh_get_mapname(g_szMapName, charsmax(g_szMapName), MNT_TRUE);
register_srvcmd("awp_lock_map_prefix", "srvCMD_LockPrefix");
RegisterHookChain(RG_CSGameRules_RestartRound, "RestartRound_Pre", false);
RegisterHookChain(RG_CBasePlayer_HasRestrictItem, "HasRestrictItem_Pre", false);
RegisterHookChain(RG_CSGameRules_CanHavePlayerItem, "CanHavePlayerItem_Pre", false);
RegisterHookChain(RG_CBasePlayer_RemovePlayerItem, "RemovePlayerItem_Post", true);
g_pcvMinPlayers = register_cvar("awp_min_players", "");
g_pcvAwpCT = register_cvar("awp_max_ct", "");
g_pcvAwpTT = register_cvar("awp_max_tt", "");
g_pcvImmunity = register_cvar("awp_immunity", "");
register_dictionary("awp_limitter.txt");
}
#if AMXX_VERSION_NUM < 183
#define client_disconnected client_disconnect
public plugin_cfg()
#else
public OnConfigsExecuted()
#endif
{
load_neygomon_config();
new szFlags[32];
get_pcvar_string(g_pcvImmunity, szFlags, charsmax(szFlags)); trim(szFlags);
if(szFlags[0] == '0') g_iFlagsImmunity = 0;
else g_iFlagsImmunity = read_flags(szFlags);
g_iMinPlayers = get_pcvar_num(g_pcvMinPlayers);
g_iMaxAwpCT = get_pcvar_num(g_pcvAwpCT);
g_iMaxAwpTT = get_pcvar_num(g_pcvAwpTT);
}
public client_disconnected(id)
{
if(is_user_connected(id))
{
if(g_bUseAwp[id])
{
g_iAwpOnTeam[get_member(id, m_iTeam)]--;
g_bUseAwp[id] = false;
}
}
}
public srvCMD_LockPrefix()
{
new szArg[32];
read_argv(1, szArg, charsmax(szArg));
if(containi(g_szMapName, szArg) != -1)
{
log_amx("Plugin stopped by mapPrefix '%s'. Current map '%s'", szArg, g_szMapName);
pause("d");
}
return PLUGIN_HANDLED;
}
public RestartRound_Pre()
{
arrayset(g_iAwpOnTeam, 0, any:TEAM_SPECTATOR);
arrayset(g_bUseAwp, false, sizeof g_bUseAwp);
new players[MAX_PLAYERS], pnum;
get_players(players, pnum, "h");
for(new i; i < pnum; i++)
{
if(get_entvar(players[i], var_weapons) & WEAPON_AWP)
{
switch(get_member(players[i], m_iTeam))
{
case TEAM_TERRORIST:
g_iAwpOnTeam[TEAM_TERRORIST]++;
case TEAM_CT:
g_iAwpOnTeam[TEAM_CT]++;
default: continue;
}
g_bUseAwp[players[i]] = true;
}
}
new limit;
limit = get_awp_limit(TEAM_TERRORIST);
if(g_iAwpOnTeam[TEAM_TERRORIST] > limit)
remove_awp_from_team(TEAM_TERRORIST, limit, "TERRORIST");
limit = get_awp_limit(TEAM_CT);
if(g_iAwpOnTeam[TEAM_CT] > limit)
remove_awp_from_team(TEAM_CT, limit, "CT");
}
public HasRestrictItem_Pre(const id, const ItemID:item, ItemRestType:type)
{
if(item == ITEM_AWP)
{
if(!is_allow_use_awp(id))
{
SetHookChainReturn(ATYPE_INTEGER, true);
return HC_SUPERCEDE;
}
}
return HC_CONTINUE;
}
public CanHavePlayerItem_Pre(const id, const pItem)
{
if(get_member(pItem, m_iId) == WEAPON_AWP)
{
if(!is_allow_use_awp(id))
{
SetHookChainReturn(ATYPE_INTEGER, false);
return HC_SUPERCEDE;
}
}
return HC_CONTINUE;
}
public RemovePlayerItem_Post(const id, const pItem)
{
if(g_bUseAwp[id])
{
if(~get_entvar(id, var_weapons) & WEAPON_AWP)
{
new team = get_member(id, m_iTeam);
g_iAwpOnTeam[team]--;
g_bUseAwp[id] = false;
}
}
}
bool:is_allow_use_awp(id)
{
static Float:fGameTime,
Float:fGameTimeId[MAX_PLAYERS + 1],
bool:bLastState[MAX_PLAYERS + 1];
fGameTime = get_gametime();
if(fGameTimeId[id] > fGameTime)
return bLastState[id];
else fGameTimeId[id] = fGameTime + 1.5;
static TeamName:team; team = get_member(id, m_iTeam);
if(team != TEAM_TERRORIST && team != TEAM_CT)
return (bLastState[id] = false);
if(!is_immunity(id))
{
static limit; limit = get_awp_limit(team);
if(limit == -2)
return (bLastState[id] = true);
if(g_iAwpOnTeam[team] >= limit)
{
if(limit == -1)
client_print(id, print_center, "%L", LANG_PLAYER, "AWP_MIN_PLAYERS", g_iMinPlayers);
else client_print(id, print_center, "%L", LANG_PLAYER, "AWP_MAX_IN_TEAM");
return (bLastState[id] = false);
}
}
if(!g_bUseAwp[id])
{
g_iAwpOnTeam[team]++;
g_bUseAwp[id] = true;
}
return (bLastState[id] = true);
}
remove_awp_from_team(TeamName:team, limit, teamName[])
{
new players[MAX_PLAYERS], pnum;
get_players(players, pnum, "eh", teamName);
new arrPlayersWithAWP[MAX_PLAYERS], num;
for(new i; i < pnum; ++i)
{
if(is_immunity(players[i]))
g_iAwpOnTeam[team]--;
else if(get_entvar(players[i], var_weapons) & WEAPON_AWP)
arrPlayersWithAWP[num++] = players[i];
}
if(num > 0 && limit > 0)
{
new rand, bool:bExclude[MAX_PLAYERS];
while(g_iAwpOnTeam[team] > limit)
{
rand = random(num);
if(bExclude[arrPlayersWithAWP[rand]])
continue;
if(rg_remove_item(arrPlayersWithAWP[rand], "weapon_awp"))
{
g_bUseAwp[arrPlayersWithAWP[rand]] = false;
bExclude[arrPlayersWithAWP[rand]] = true;
g_iAwpOnTeam[team]--;
}
}
}
}
get_awp_limit(TeamName:team)
{
new players = get_member_game(m_iNumTerrorist) + get_member_game(m_iNumCT);
if(players < g_iMinPlayers)
return -1;
new teamLimit = (team == TEAM_CT ? g_iMaxAwpCT : g_iMaxAwpTT);
if(!teamLimit)
return -2;
new limit = teamLimit - g_iAwpOnTeam[team];
return limit < 0 ? 0 : limit;
}
stock load_neygomon_config()
{
new szConfig[96];
get_localinfo("amxx_configsdir", szConfig, charsmax(szConfig));
formatex(szConfig[strlen(szConfig)], charsmax(szConfig), "/neygomon/%s.cfg", P_CONFIG);
if(file_exists(szConfig))
{
server_print("Config '%s' loaded for plugin '[%s] %s' by %s", szConfig, P_VERSION, P_NAME, P_AUTHOR);
server_cmd("exec %s", szConfig);
server_exec();
}
else log_amx("Config '%s' NOT FOUND for plugin '[%s] %s' by %s", szConfig, P_VERSION, P_NAME, P_AUTHOR);
}