#include <sourcemod>
#include <sdkhooks>
#include <sdktools>
#include <csgo_colors>
#undef REQUIRE_PLUGIN
#include <adminmenu>
bool g_iNoZoomOnly;
int g_iNoZoomOnlyRounds;
int g_iKDRounds;
bool g_iPV[MAXPLAYERS+1];
int m_flNextSecondaryAttack = -1;
int g_cRounds, g_cKDRounds;
float g_cPercent;
bool g_cPrintKills, g_cPrintAdv;
TopMenu g_hAdminMenu = null;
public Plugin myinfo =
{
name = "NoZoom System",
description = "NoZoom system for CS:GO.",
author = "DUCK (vk.com/geliydaun)",
version = "1.0.9",
url = "http://crystals.pw/"
};
public void OnPluginStart()
{
RegConsoleCmd("sm_nz", VoteZoom);
RegConsoleCmd("sm_nozoom", VoteZoom);
HookEvent("player_death", PlayerDeath);
HookEvent("round_start", RoundStart);
m_flNextSecondaryAttack = FindSendPropInfo("CBaseCombatWeapon", "m_flNextSecondaryAttack");
ConVar cvar;
cvar = CreateConVar("sm_vz_rounds", "5", "Количество раундов без прицела после голосования.");
HookConVarChange(cvar, RoundsCvarChange);
g_cRounds = GetConVarInt(cvar);
cvar = CreateConVar("sm_vz_kd_rounds", "5", "Количество раундов между голосованиями.");
HookConVarChange(cvar, KDRoundsCvarChange);
g_cKDRounds = GetConVarInt(cvar);
cvar = CreateConVar("sm_vz_percent", "0.5", "Процент от всех игроков, требуемый для начала игры без прицелов. (0.5 - 50%)");
HookConVarChange(cvar, PercentCvarChange);
g_cPercent = GetConVarFloat(cvar);
cvar = CreateConVar("sm_print_kills_to_chat", "1", "Писать в чат об убийствах без прицела? (Во время NoZoom раундов функция автоматически отключается) (1 - Да, 0 - нет).");
HookConVarChange(cvar, PrintKillsCvarChange);
g_cPrintKills = GetConVarBool(cvar);
cvar = CreateConVar("sm_print_adv", "1", "Включена ли реклама в начале раунда? 1 - Да, 0 - Нет");
HookConVarChange(cvar, PrintAdvCvarChange);
g_cPrintAdv = GetConVarBool(cvar);
AutoExecConfig(true, "NoZoom");
if (LibraryExists("adminmenu"))
{
TopMenu hTopMenu;
hTopMenu = GetAdminTopMenu();
if (hTopMenu != null)
{
OnAdminMenuReady(hTopMenu);
}
}
for (int i = 1; i <= MaxClients; ++i)
{
if (IsClientInGame(i))
{
OnClientPutInServer(i);
}
}
}
public OnLibraryRemoved(const char[] szName)
{
if (StrEqual(szName, "adminmenu"))
g_hAdminMenu = null;
}
public void OnAdminMenuReady(Handle aTopMenu)
{
TopMenu hTopMenu = TopMenu.FromHandle(aTopMenu);
if (hTopMenu == g_hAdminMenu)
return;
g_hAdminMenu = hTopMenu;
TopMenuObject hCategory = g_hAdminMenu.FindCategory("ServerCommands");
if (hCategory != INVALID_TOPMENUOBJECT)
g_hAdminMenu.AddItem("AdminStart", Handler_AdminStart, hCategory, "start_nozoom", ADMFLAG_BAN);
}
public void Handler_AdminStart(TopMenu hMenu, TopMenuAction action, TopMenuObject object_id, int iClient, char[] sBuffer, int maxlength)
{
switch (action)
{
case TopMenuAction_DisplayOption:
{
FormatEx(sBuffer, maxlength, "Начать битву без прицелов");
}
case TopMenuAction_SelectOption:
{
for (int i = 1; i <= MaxClients; ++i)
{
if (IsClientInGame(i))
{
g_iPV[i] = true;
}
}
CGOPrintToChatAll("{RED}[ {DEFAULT}NoZoom {RED}] {DEFAULT}В следующем раунде начнется битва без прицелов!");
}
}
}
public OnMapStart()
{
g_iNoZoomOnly = false;
g_iKDRounds = g_cKDRounds + 1;
}
public void OnClientPutInServer(int client)
{
SDKHook(client, SDKHook_PreThink, OnPreThink);
}
public Action OnPreThink(int client)
{
if(g_iNoZoomOnly)
{
SetNoScope(GetEntPropEnt(client, Prop_Send, "m_hActiveWeapon"));
}
return Plugin_Continue;
}
public void OnClientDisconnect(int client)
{
g_iPV[client] = false;
}
public PlayerDeath(Event hEvent, const char[] name, bool dontBroadcast)
{
if(g_cPrintKills)
{
if(!g_iNoZoomOnly)
{
int client = GetClientOfUserId(hEvent.GetInt("userid"));
int attacker = GetClientOfUserId(hEvent.GetInt("attacker"));
if (attacker > 0 && IsClientInGame(attacker))
{
if (attacker != client)
{
char weapon[32];
GetEventString(hEvent, "weapon", weapon, sizeof(weapon));
if (!GetEntProp(attacker, Prop_Send, "m_bIsScoped") && StrContains(weapon, "awp", false) != -1)
{
CGOPrintToChatAll("{LIME} » Игрок {LIGHTBLUE}%N {LIME}убил {OLIVE}%N {LIME}без прицела!", attacker, client);
}
}
}
}
}
}
public Action VoteZoom(int client, int args)
{
if (client > 0)
{
if(!g_iNoZoomOnly)
{
if(GetVotesNum() < RoundToFloor(float(GetClientCount(true)) * g_cPercent))
{
if(g_iKDRounds - 1 >= g_cKDRounds)
{
if(!g_iPV[client]) CGOPrintToChatAll("{RED}[ {DEFAULT}NoZoom {RED}] {PURPLE}%N {DEFAULT}проголосовал за битву без прицелов {OLIVE}(%i из %i){DEFAULT}.", client, GetVotesNum()+1, RoundToFloor(float(GetClientCount(true)) * g_cPercent));
else CGOPrintToChat(client, "{RED}[ {DEFAULT}NoZoom {RED}]{DEFAULT}Вы уже проголосовали за битву без прицелов!");
g_iPV[client] = true;
if(GetVotesNum() >= RoundToFloor(float(GetClientCount(true)) * g_cPercent)) CGOPrintToChatAll("{RED}[ {DEFAULT}NoZoom {RED}] {DEFAULT}В следующем раунде начнется битва без прицелов!");
}
else CGOPrintToChat(client, "{RED}[ {DEFAULT}NoZoom {RED}] {DEFAULT}Голосовать за битву без прицелов можно будет через {OLIVE}%i{DEFAULT} раундов!", g_cKDRounds - g_iKDRounds + 1);
}
else CGOPrintToChat(client, "{RED}[ {DEFAULT}NoZoom {RED}] {DEFAULT}Достаточное количество голосов уже набрано!");
}
else CGOPrintToChat(client, "{RED}[ {DEFAULT}NoZoom {RED}] {DEFAULT}Битва без прицелов уже проходит!");
}
return Plugin_Handled;
}
public RoundStart(Event hEvent, const char[] name, bool dontBroadcast)
{
if(!g_iNoZoomOnly)
{
if(g_iKDRounds - 1 < g_cKDRounds) ++g_iKDRounds;
if(GetVotesNum() >= RoundToFloor(float(GetClientCount(true)) * g_cPercent))
{
g_iNoZoomOnly = true;
}
if(g_cPrintAdv) if(g_iKDRounds - 1 >= g_cKDRounds) CGOPrintToChatAll("{RED}[ {DEFAULT}NoZoom {RED}] {DEFAULT}Используйте команду {OLIVE}!nz{DEFAULT}, чтобы проголосовать за игру без прицелов!")
}
if(g_iNoZoomOnlyRounds == g_cRounds)
{
g_iNoZoomOnly = false;
g_iNoZoomOnlyRounds = 0;
for (int i = 1; i <= MaxClients; ++i)
{
if (IsClientInGame(i))
{
g_iPV[i] = false;
}
}
g_iKDRounds = 1;
CGOPrintToChatAll("{RED}[ {DEFAULT}NoZoom {RED}] {DEFAULT}Битва без прицелов завершена!")
}
if(g_iNoZoomOnly)
{
++g_iNoZoomOnlyRounds;
CGOPrintToChatAll("{RED}[ {DEFAULT}NoZoom {RED}] {DEFAULT}Прицелы в этом раунде отключены!");
}
}
void SetNoScope(int weapon)
{
if (IsValidEdict(weapon))
{
char classname[32];
GetEdictClassname(weapon, classname, sizeof(classname));
if (!StrEqual(classname[7], "knife") && !StrEqual(classname[7], "revolver") && !StrEqual(classname[7], "hegrenade") && !StrEqual(classname[7], "incgrenade") && !StrEqual(classname[7], "molotov") && !StrEqual(classname[7], "smokegrenade") && !StrEqual(classname[7], "tagrenade") && !StrEqual(classname[7], "flashbang") && !StrEqual(classname[7], "decoy"))
{
SetEntDataFloat(weapon, m_flNextSecondaryAttack, GetGameTime() + 2.0);
}
}
}
GetVotesNum()
{
int num;
for (int i = 1; i <= MaxClients; ++i)
{
if (g_iPV[i])
{
num++;
}
}
return num;
}
public void RoundsCvarChange(Handle convar, char[] oldValue, char[] newValue) { g_cRounds = StringToInt(newValue); }
public void KDRoundsCvarChange(Handle convar, char[] oldValue, char[] newValue) { g_cKDRounds = StringToInt(newValue); }
public void PercentCvarChange(Handle convar, char[] oldValue, char[] newValue) { g_cPercent = StringToFloat(newValue); }
public void PrintKillsCvarChange(Handle convar, char[] oldValue, char[] newValue) { g_cPrintKills = view_as<bool>(StringToInt(newValue)); }
public void PrintAdvCvarChange(Handle convar, char[] oldValue, char[] newValue) { g_cPrintAdv = view_as<bool>(StringToInt(newValue)); }