1060 lines
35 KiB
SourcePawn
1060 lines
35 KiB
SourcePawn
#include <hlstatsx_loghelper>
|
|
#include <zombiereloaded>
|
|
#include <clientprefs>
|
|
#include <multicolors>
|
|
#include <sourcemod>
|
|
#include <sdktools>
|
|
|
|
#define SPECMODE_NONE 0
|
|
#define SPECMODE_FIRSTPERSON 4
|
|
#define SPECMODE_THIRDPERSON 5
|
|
#define SPECMODE_FREELOOK 6
|
|
|
|
/* BOOLS */
|
|
bool g_bEngineCSGO;
|
|
bool g_bHideCrown[MAXPLAYERS+1];
|
|
bool g_bHideDialog[MAXPLAYERS+1];
|
|
bool g_bProtection[MAXPLAYERS+1];
|
|
|
|
/* COOKIES */
|
|
Handle g_hCookie_HideCrown;
|
|
Handle g_hCookie_HideDialog;
|
|
Handle g_hCookie_Protection;
|
|
|
|
/* CONVARS */
|
|
ConVar g_hCVar_Protection;
|
|
ConVar g_hCVar_ProtectionMinimal1;
|
|
ConVar g_hCVar_ProtectionMinimal2;
|
|
ConVar g_hCVar_ProtectionMinimal3;
|
|
ConVar g_hCVar_Grenade;
|
|
|
|
/* INTERGERS */
|
|
int g_iDialogLevel = 100000;
|
|
|
|
int g_iPlayerWinner[6];
|
|
int g_iPlayerDamage[MAXPLAYERS+1];
|
|
int g_iPlayerDamageHits[MAXPLAYERS+1];
|
|
int g_iPlayerDamageFrom1K[MAXPLAYERS + 1];
|
|
int g_iPlayerInfections[MAXPLAYERS+1];
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Plugin myinfo =
|
|
{
|
|
name = "Player Rankings",
|
|
author = "Neon & zaCade",
|
|
description = "Show Top Defenders & Infections after each round",
|
|
version = "1.1.2"
|
|
};
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
|
|
{
|
|
CreateNative("PlayerRankings_GetClientDamage", Native_GetClientDamage);
|
|
CreateNative("PlayerRankings_GetClientHits", Native_GetClientHits);
|
|
|
|
CreateNative("PlayerRankings_GetClientInfections", Native_GetClientInfections);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnPluginStart()
|
|
{
|
|
LoadTranslations("plugin.playerrankings.phrases");
|
|
|
|
g_bEngineCSGO = view_as<bool>(GetEngineVersion() == Engine_CSGO);
|
|
|
|
g_hCVar_Protection = CreateConVar("sm_topdefenders_protection", "1", "", FCVAR_NONE, true, 0.0, true, 1.0);
|
|
g_hCVar_ProtectionMinimal1 = CreateConVar("sm_topdefenders_minimal_1", "15", "", FCVAR_NONE, true, 1.0, true, 64.0);
|
|
g_hCVar_ProtectionMinimal2 = CreateConVar("sm_topdefenders_minimal_2", "30", "", FCVAR_NONE, true, 1.0, true, 64.0);
|
|
g_hCVar_ProtectionMinimal3 = CreateConVar("sm_topdefenders_minimal_3", "45", "", FCVAR_NONE, true, 1.0, true, 64.0);
|
|
g_hCVar_Grenade = CreateConVar("sm_topdefenders_grenade", "1", "", FCVAR_NONE, true, 0.0, true, 1.0);
|
|
AutoExecConfig(true);
|
|
|
|
g_hCookie_HideCrown = RegClientCookie("topdefenders_hidecrown", "", CookieAccess_Private);
|
|
g_hCookie_HideDialog = RegClientCookie("topdefenders_hidedialog", "", CookieAccess_Private);
|
|
g_hCookie_Protection = RegClientCookie("topdefenders_protection", "", CookieAccess_Private);
|
|
|
|
CreateTimer(0.1, UpdateScoreboard, INVALID_HANDLE, TIMER_REPEAT);
|
|
CreateTimer(0.1, UpdateDialog, INVALID_HANDLE, TIMER_REPEAT);
|
|
|
|
RegConsoleCmd("sm_togglecrown", OnToggleCrown);
|
|
RegConsoleCmd("sm_toggleskull", OnToggleCrown);
|
|
RegConsoleCmd("sm_toggledialog", OnToggleDialog);
|
|
RegConsoleCmd("sm_toggleimmunity", OnToggleImmunity);
|
|
|
|
HookEvent("round_start", OnRoundStart);
|
|
HookEvent("round_end", OnRoundEnding);
|
|
HookEvent("player_hurt", OnClientHurt);
|
|
HookEvent("player_spawn", OnClientSpawn);
|
|
HookEvent("player_death", OnClientDeath);
|
|
|
|
SetCookieMenuItem(MenuHandler_CookieMenu, 0, "Player Rankings");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action OnToggleCrown(int client, int args)
|
|
{
|
|
ToggleCrown(client);
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action OnToggleDialog(int client, int args)
|
|
{
|
|
ToggleDialog(client);
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action OnToggleImmunity(int client, int args)
|
|
{
|
|
ToggleImmunity(client);
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void ToggleCrown(int client)
|
|
{
|
|
g_bHideCrown[client] = !g_bHideCrown[client];
|
|
|
|
SetClientCookie(client, g_hCookie_HideCrown, g_bHideCrown[client] ? "1" : "");
|
|
|
|
CPrintToChat(client, "{cyan}%t {white}%t", "Chat Prefix", g_bHideCrown[client] ? "Crown Disabled" : "Crown Enabled");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void ToggleDialog(int client)
|
|
{
|
|
g_bHideDialog[client] = !g_bHideDialog[client];
|
|
|
|
SetClientCookie(client, g_hCookie_HideDialog, g_bHideDialog[client] ? "1" : "");
|
|
|
|
CPrintToChat(client, "{cyan}%t {white}%t", "Chat Prefix", g_bHideDialog[client] ? "Dialog Disabled" : "Dialog Enabled");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void ToggleImmunity(int client)
|
|
{
|
|
g_bProtection[client] = !g_bProtection[client];
|
|
|
|
SetClientCookie(client, g_hCookie_Protection, g_bProtection[client] ? "1" : "");
|
|
|
|
CPrintToChat(client, "{cyan}%t {white}%t", "Chat Prefix", g_bProtection[client] ? "Immunity Disabled" : "Immunity Enabled");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void ShowSettingsMenu(int client)
|
|
{
|
|
Menu menu = new Menu(MenuHandler_MainMenu);
|
|
|
|
menu.SetTitle("%T", "Cookie Menu Title", client);
|
|
|
|
AddMenuItemTranslated(menu, "0", "%t: %t", "Crown", g_bHideCrown[client] ? "Disabled" : "Enabled");
|
|
AddMenuItemTranslated(menu, "1", "%t: %t", "Dialog", g_bHideDialog[client] ? "Disabled" : "Enabled");
|
|
AddMenuItemTranslated(menu, "2", "%t: %t", "Immunity", g_bProtection[client] ? "Disabled" : "Enabled");
|
|
|
|
menu.ExitBackButton = true;
|
|
|
|
menu.Display(client, MENU_TIME_FOREVER);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void MenuHandler_CookieMenu(int client, CookieMenuAction action, any info, char[] buffer, int maxlen)
|
|
{
|
|
switch(action)
|
|
{
|
|
case(CookieMenuAction_DisplayOption):
|
|
{
|
|
Format(buffer, maxlen, "%T", "Cookie Menu", client);
|
|
}
|
|
case(CookieMenuAction_SelectOption):
|
|
{
|
|
ShowSettingsMenu(client);
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public int MenuHandler_MainMenu(Menu menu, MenuAction action, int client, int selection)
|
|
{
|
|
switch(action)
|
|
{
|
|
case(MenuAction_Select):
|
|
{
|
|
switch(selection)
|
|
{
|
|
case(0): ToggleCrown(client);
|
|
case(1): ToggleDialog(client);
|
|
case(2): ToggleImmunity(client);
|
|
}
|
|
|
|
ShowSettingsMenu(client);
|
|
}
|
|
case(MenuAction_Cancel):
|
|
{
|
|
ShowCookieMenu(client);
|
|
}
|
|
case(MenuAction_End):
|
|
{
|
|
delete menu;
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnMapStart()
|
|
{
|
|
PrecacheSound("unloze/holy.wav");
|
|
PrecacheModel("models/unloze/crown_v3.mdl");
|
|
PrecacheModel("models/unloze/skull_v3.mdl");
|
|
|
|
AddFileToDownloadsTable("sound/unloze/holy.wav");
|
|
|
|
AddFileToDownloadsTable("models/unloze/crown_v3.mdl");
|
|
AddFileToDownloadsTable("models/unloze/crown_v3.phy");
|
|
AddFileToDownloadsTable("models/unloze/crown_v3.vvd");
|
|
AddFileToDownloadsTable("models/unloze/crown_v3.sw.vtx");
|
|
AddFileToDownloadsTable("models/unloze/crown_v3.dx80.vtx");
|
|
AddFileToDownloadsTable("models/unloze/crown_v3.dx90.vtx");
|
|
AddFileToDownloadsTable("materials/models/unloze/crown/crown.vmt");
|
|
AddFileToDownloadsTable("materials/models/unloze/crown/crown.vtf");
|
|
AddFileToDownloadsTable("materials/models/unloze/crown/crown_bump.vtf");
|
|
AddFileToDownloadsTable("materials/models/unloze/crown/crown_detail.vtf");
|
|
AddFileToDownloadsTable("materials/models/unloze/crown/crown_lightwarp.vtf");
|
|
|
|
AddFileToDownloadsTable("models/unloze/skull_v3.mdl");
|
|
AddFileToDownloadsTable("models/unloze/skull_v3.phy");
|
|
AddFileToDownloadsTable("models/unloze/skull_v3.vvd");
|
|
AddFileToDownloadsTable("models/unloze/skull_v3.sw.vtx");
|
|
AddFileToDownloadsTable("models/unloze/skull_v3.dx80.vtx");
|
|
AddFileToDownloadsTable("models/unloze/skull_v3.dx90.vtx");
|
|
AddFileToDownloadsTable("materials/models/unloze/skull/skull.vmt");
|
|
AddFileToDownloadsTable("materials/models/unloze/skull/skull.vtf");
|
|
AddFileToDownloadsTable("materials/models/unloze/skull/skull_bump.vtf");
|
|
AddFileToDownloadsTable("materials/models/unloze/skull/skull_horn_b.vmt");
|
|
AddFileToDownloadsTable("materials/models/unloze/skull/skull_horn_b.vtf");
|
|
AddFileToDownloadsTable("materials/models/unloze/skull/skull_horn_b_bump.vtf");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnClientCookiesCached(int client)
|
|
{
|
|
char sBuffer[4];
|
|
GetClientCookie(client, g_hCookie_HideCrown, sBuffer, sizeof(sBuffer));
|
|
|
|
if (sBuffer[0])
|
|
g_bHideCrown[client] = true;
|
|
else
|
|
g_bHideCrown[client] = false;
|
|
|
|
GetClientCookie(client, g_hCookie_HideDialog, sBuffer, sizeof(sBuffer));
|
|
|
|
if (sBuffer[0])
|
|
g_bHideDialog[client] = true;
|
|
else
|
|
g_bHideDialog[client] = false;
|
|
|
|
GetClientCookie(client, g_hCookie_Protection, sBuffer, sizeof(sBuffer));
|
|
|
|
if (sBuffer[0])
|
|
g_bProtection[client] = true;
|
|
else
|
|
g_bProtection[client] = false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnClientDisconnect(int client)
|
|
{
|
|
g_iPlayerDamage[client] = 0;
|
|
g_iPlayerDamageHits[client] = 0;
|
|
g_iPlayerDamageFrom1K[client] = 0;
|
|
g_iPlayerInfections[client] = 0;
|
|
|
|
g_bHideCrown[client] = false;
|
|
g_bHideDialog[client] = false;
|
|
g_bProtection[client] = false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public int SortRankingsList(int[] elem1, int[] elem2, const int[][] array, Handle hndl)
|
|
{
|
|
if (elem1[1] > elem2[1]) return -1;
|
|
if (elem1[1] < elem2[1]) return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action UpdateScoreboard(Handle timer)
|
|
{
|
|
int iSortedList[MAXPLAYERS+1][2];
|
|
int iSortedCount;
|
|
|
|
for (int client = 1; client <= MaxClients; client++)
|
|
{
|
|
if (!IsClientInGame(client))
|
|
continue;
|
|
|
|
SetEntProp(client, Prop_Data, "m_iDeaths", 0);
|
|
|
|
if (!g_iPlayerDamage[client])
|
|
continue;
|
|
|
|
iSortedList[iSortedCount][0] = client;
|
|
iSortedList[iSortedCount][1] = g_iPlayerDamage[client];
|
|
iSortedCount++;
|
|
}
|
|
|
|
SortCustom2D(iSortedList, iSortedCount, SortRankingsList);
|
|
|
|
for (int rank = 0; rank < iSortedCount; rank++)
|
|
{
|
|
SetEntProp(iSortedList[rank][0], Prop_Data, "m_iDeaths", rank + 1);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action UpdateDialog(Handle timer)
|
|
{
|
|
if (g_bEngineCSGO || g_iDialogLevel <= 0)
|
|
return;
|
|
|
|
int iSortedList[MAXPLAYERS+1][2];
|
|
int iSortedCount;
|
|
|
|
for (int client = 1; client <= MaxClients; client++)
|
|
{
|
|
if (!IsClientInGame(client) || !g_iPlayerDamage[client])
|
|
continue;
|
|
|
|
iSortedList[iSortedCount][0] = client;
|
|
iSortedList[iSortedCount][1] = g_iPlayerDamage[client];
|
|
iSortedCount++;
|
|
}
|
|
|
|
SortCustom2D(iSortedList, iSortedCount, SortRankingsList);
|
|
|
|
for (int rank = 0; rank < iSortedCount; rank++)
|
|
{
|
|
switch(rank)
|
|
{
|
|
case(0): SendDialog(iSortedList[rank][0], "#%d (D: %d | P: -%d)", g_iDialogLevel, 1, rank + 1, iSortedList[rank][1], iSortedList[rank][1] - iSortedList[rank + 1][1]);
|
|
case(1): SendDialog(iSortedList[rank][0], "#%d (D: %d | N: +%d)", g_iDialogLevel, 1, rank + 1, iSortedList[rank][1], iSortedList[rank - 1][1] - iSortedList[rank][1]);
|
|
default: SendDialog(iSortedList[rank][0], "#%d (D: %d | N: +%d | F: +%d)", g_iDialogLevel, 1, rank + 1, iSortedList[rank][1], iSortedList[rank - 1][1] - iSortedList[rank][1], iSortedList[0][1] - iSortedList[rank][1]);
|
|
}
|
|
}
|
|
|
|
g_iDialogLevel--;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnRoundStart(Event hEvent, const char[] sEvent, bool bDontBroadcast)
|
|
{
|
|
g_iDialogLevel = 100000;
|
|
|
|
for (int client = 1; client <= MaxClients; client++)
|
|
{
|
|
g_iPlayerDamage[client] = 0;
|
|
g_iPlayerDamageHits[client] = 0;
|
|
g_iPlayerDamageFrom1K[client] = 0;
|
|
g_iPlayerInfections[client] = 0;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnRoundEnding(Event hEvent, const char[] sEvent, bool bDontBroadcast)
|
|
{
|
|
g_iPlayerWinner = {-1, -1, -1, -1, -1, -1};
|
|
|
|
int iSortedListDefenders[MAXPLAYERS+1][3];
|
|
int iSortedCountDefenders;
|
|
|
|
int iSortedListInfectors[MAXPLAYERS+1][2];
|
|
int iSortedCountInfectors;
|
|
|
|
for (int client = 1; client <= MaxClients; client++)
|
|
{
|
|
if (!IsClientInGame(client))
|
|
continue;
|
|
|
|
if (g_iPlayerDamage[client])
|
|
{
|
|
iSortedListDefenders[iSortedCountDefenders][0] = client;
|
|
iSortedListDefenders[iSortedCountDefenders][1] = g_iPlayerDamage[client];
|
|
iSortedListDefenders[iSortedCountDefenders][2] = g_iPlayerDamageHits[client];
|
|
iSortedCountDefenders++;
|
|
}
|
|
|
|
if (g_iPlayerInfections[client])
|
|
{
|
|
iSortedListInfectors[iSortedCountInfectors][0] = client;
|
|
iSortedListInfectors[iSortedCountInfectors][1] = g_iPlayerInfections[client];
|
|
iSortedCountInfectors++;
|
|
}
|
|
}
|
|
|
|
SortCustom2D(iSortedListDefenders, iSortedCountDefenders, SortRankingsList);
|
|
SortCustom2D(iSortedListInfectors, iSortedCountInfectors, SortRankingsList);
|
|
|
|
for (int rank = 0; rank < iSortedCountDefenders; rank++)
|
|
{
|
|
LogMessage("%d. %L - %d damage in %d hits", rank + 1, iSortedListDefenders[rank][0], iSortedListDefenders[rank][1], iSortedListDefenders[rank][2])
|
|
}
|
|
|
|
for (int rank = 0; rank < iSortedCountInfectors; rank++)
|
|
{
|
|
LogMessage("%d. %L - %d infections", rank + 1, iSortedListInfectors[rank][0], iSortedListInfectors[rank][1])
|
|
}
|
|
|
|
if (iSortedCountDefenders)
|
|
{
|
|
char sBuffer[512];
|
|
Format(sBuffer, sizeof(sBuffer), "TOP DEFENDERS:");
|
|
|
|
if (iSortedListDefenders[0][0])
|
|
{
|
|
Format(sBuffer, sizeof(sBuffer), "%s\n1. %N - %d damage in %d hits", sBuffer, iSortedListDefenders[0][0], iSortedListDefenders[0][1], iSortedListDefenders[0][2]);
|
|
|
|
g_iPlayerWinner[0] = GetSteamAccountID(iSortedListDefenders[0][0]);
|
|
|
|
LH_LogPlayerEvent(iSortedListDefenders[0][0], "triggered", "ze_defender_first", true);
|
|
}
|
|
|
|
if (iSortedListDefenders[1][0])
|
|
{
|
|
Format(sBuffer, sizeof(sBuffer), "%s\n2. %N - %d damage in %d hits", sBuffer, iSortedListDefenders[1][0], iSortedListDefenders[1][1], iSortedListDefenders[1][2]);
|
|
|
|
g_iPlayerWinner[1] = GetSteamAccountID(iSortedListDefenders[1][0]);
|
|
|
|
LH_LogPlayerEvent(iSortedListDefenders[1][0], "triggered", "ze_defender_second", true);
|
|
}
|
|
|
|
if (iSortedListDefenders[2][0])
|
|
{
|
|
Format(sBuffer, sizeof(sBuffer), "%s\n3. %N - %d damage in %d hits", sBuffer, iSortedListDefenders[2][0], iSortedListDefenders[2][1], iSortedListDefenders[2][2]);
|
|
|
|
g_iPlayerWinner[2] = GetSteamAccountID(iSortedListDefenders[2][0]);
|
|
|
|
LH_LogPlayerEvent(iSortedListDefenders[2][0], "triggered", "ze_defender_third", true);
|
|
}
|
|
|
|
if (g_bEngineCSGO)
|
|
{
|
|
int iSplits
|
|
char sSplits[16][512];
|
|
|
|
if ((iSplits = ExplodeString(sBuffer, "\n", sSplits, sizeof(sSplits), sizeof(sSplits[]))) != 0)
|
|
{
|
|
for (int iSplit; iSplit < iSplits; iSplit++)
|
|
{
|
|
PrintToChatAll(sSplits[iSplit]);
|
|
}
|
|
}
|
|
|
|
PrintToMessageHUD(0, 50, Float:{0.02, 0.45}, {0, 128, 255, 255}, {255, 255, 255, 255}, 0, 0.1, 0.1, 5.0, 0.0, sBuffer);
|
|
}
|
|
else
|
|
{
|
|
PrintToMessageHUD(0, 50, Float:{0.02, 0.25}, {0, 128, 255, 255}, {255, 255, 255, 255}, 0, 0.1, 0.1, 5.0, 0.0, sBuffer);
|
|
PrintToChatAll(sBuffer);
|
|
}
|
|
}
|
|
|
|
if (iSortedCountInfectors)
|
|
{
|
|
char sBuffer[512];
|
|
Format(sBuffer, sizeof(sBuffer), "TOP INFECTORS:");
|
|
|
|
if (iSortedListInfectors[0][0])
|
|
{
|
|
Format(sBuffer, sizeof(sBuffer), "%s\n1. %N - %d infections", sBuffer, iSortedListInfectors[0][0], iSortedListInfectors[0][1]);
|
|
|
|
g_iPlayerWinner[3] = GetSteamAccountID(iSortedListInfectors[0][0]);
|
|
|
|
LH_LogPlayerEvent(iSortedListInfectors[0][0], "triggered", "ze_infector_first", true);
|
|
}
|
|
|
|
if (iSortedListInfectors[1][0])
|
|
{
|
|
Format(sBuffer, sizeof(sBuffer), "%s\n2. %N - %d infections", sBuffer, iSortedListInfectors[1][0], iSortedListInfectors[1][1]);
|
|
|
|
g_iPlayerWinner[4] = GetSteamAccountID(iSortedListInfectors[1][0]);
|
|
|
|
LH_LogPlayerEvent(iSortedListInfectors[1][0], "triggered", "ze_infector_second", true);
|
|
}
|
|
|
|
if (iSortedListInfectors[2][0])
|
|
{
|
|
Format(sBuffer, sizeof(sBuffer), "%s\n3. %N - %d infections", sBuffer, iSortedListInfectors[2][0], iSortedListInfectors[2][1]);
|
|
|
|
g_iPlayerWinner[5] = GetSteamAccountID(iSortedListInfectors[2][0]);
|
|
|
|
LH_LogPlayerEvent(iSortedListInfectors[2][0], "triggered", "ze_infector_third", true);
|
|
}
|
|
|
|
if (g_bEngineCSGO)
|
|
{
|
|
int iSplits
|
|
char sSplits[16][512];
|
|
|
|
if ((iSplits = ExplodeString(sBuffer, "\n", sSplits, sizeof(sSplits), sizeof(sSplits[]))) != 0)
|
|
{
|
|
for (int iSplit; iSplit < iSplits; iSplit++)
|
|
{
|
|
PrintToChatAll(sSplits[iSplit]);
|
|
}
|
|
}
|
|
|
|
PrintToMessageHUD(0, 55, Float:{0.02, 0.6}, {255, 0, 0, 255}, {255, 255, 255, 255}, 0, 0.1, 0.1, 5.0, 0.0, sBuffer);
|
|
}
|
|
else
|
|
{
|
|
PrintToMessageHUD(0, 55, Float:{0.02, 0.4}, {255, 0, 0, 255}, {255, 255, 255, 255}, 0, 0.1, 0.1, 5.0, 0.0, sBuffer);
|
|
PrintToChatAll(sBuffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnClientHurt(Event hEvent, const char[] sEvent, bool bDontBroadcast)
|
|
{
|
|
int client = GetClientOfUserId(hEvent.GetInt("attacker"));
|
|
int victim = GetClientOfUserId(hEvent.GetInt("userid"));
|
|
|
|
if (client < 1 || client > MaxClients || victim < 1 || victim > MaxClients)
|
|
return;
|
|
|
|
if (client == victim || (IsPlayerAlive(client) && ZR_IsClientZombie(client)))
|
|
return;
|
|
|
|
int iDamage = hEvent.GetInt("dmg_health");
|
|
|
|
g_iPlayerDamage[client] += iDamage;
|
|
g_iPlayerDamageHits[client] += 1;
|
|
g_iPlayerDamageFrom1K[client] += iDamage;
|
|
|
|
if (g_iPlayerDamageFrom1K[client] >= 2000)
|
|
{
|
|
g_iPlayerDamageFrom1K[client] -= 2000;
|
|
|
|
LH_LogPlayerEvent(client, "triggered", "ze_damage_zombie", true);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnClientSpawn(Event hEvent, const char[] sEvent, bool bDontBroadcast)
|
|
{
|
|
int client = GetClientOfUserId(hEvent.GetInt("userid"));
|
|
|
|
int steamAccountID = GetSteamAccountID(client);
|
|
|
|
if (!g_bHideCrown[client])
|
|
{
|
|
if (g_iPlayerWinner[0] == steamAccountID)
|
|
CreateTimer(7.0, OnClientSpawnPostCrown, GetClientSerial(client), TIMER_FLAG_NO_MAPCHANGE);
|
|
else if (g_iPlayerWinner[3] == steamAccountID)
|
|
CreateTimer(7.0, OnClientSpawnPostSkull, GetClientSerial(client), TIMER_FLAG_NO_MAPCHANGE);
|
|
}
|
|
|
|
if(!g_hCVar_Grenade.BoolValue)
|
|
return;
|
|
|
|
for (int i = 0; i < sizeof(g_iPlayerWinner); i++)
|
|
{
|
|
if (g_iPlayerWinner[i] == steamAccountID)
|
|
{
|
|
CreateTimer(2.0, OnClientSpawnPostGrenade, GetClientSerial(client), TIMER_FLAG_NO_MAPCHANGE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action OnClientSpawnPostCrown(Handle timer, int serial)
|
|
{
|
|
int client;
|
|
if((client = GetClientFromSerial(serial)) == 0)
|
|
return;
|
|
|
|
if (!IsClientInGame(client) || !IsPlayerAlive(client))
|
|
return;
|
|
|
|
SpawnCrown(client);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action OnClientSpawnPostSkull(Handle timer, int serial)
|
|
{
|
|
int client;
|
|
if((client = GetClientFromSerial(serial)) == 0)
|
|
return;
|
|
|
|
if (!IsClientInGame(client) || !IsPlayerAlive(client))
|
|
return;
|
|
|
|
SpawnSkull(client);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action OnClientSpawnPostGrenade(Handle timer, int serial)
|
|
{
|
|
int client;
|
|
if((client = GetClientFromSerial(serial)) == 0)
|
|
return;
|
|
|
|
if (!IsClientInGame(client) || !IsPlayerAlive(client))
|
|
return;
|
|
|
|
if (!ZR_IsClientHuman(client))
|
|
return;
|
|
|
|
int iGrenade = GivePlayerItem(client, "weapon_hegrenade");
|
|
int PrimaryAmmoType = GetEntProp(iGrenade, Prop_Data, "m_iPrimaryAmmoType");
|
|
SetEntProp(client, Prop_Send, "m_iAmmo", 2, _, PrimaryAmmoType);
|
|
EquipPlayerWeapon(client, iGrenade);
|
|
SetEntProp(client, Prop_Send, "m_iAmmo", 2, _, PrimaryAmmoType);
|
|
CPrintToChat(client, "{cyan}%t {white}%t", "Chat Prefix", "Grenade");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
void SpawnCrown(int client)
|
|
{
|
|
int entity = INVALID_ENT_REFERENCE;
|
|
if ((entity = CreateEntityByName("prop_dynamic")) == INVALID_ENT_REFERENCE)
|
|
return;
|
|
|
|
SetEntityModel(entity, "models/unloze/crown_v3.mdl");
|
|
|
|
DispatchKeyValue(entity, "solid", "0");
|
|
DispatchKeyValue(entity, "disableshadows", "1");
|
|
DispatchKeyValue(entity, "disablereceiveshadows", "1");
|
|
DispatchKeyValue(entity, "disablebonefollowers", "1");
|
|
|
|
float fVector[3];
|
|
float fAngles[3];
|
|
GetClientAbsOrigin(client, fVector);
|
|
GetClientAbsAngles(client, fAngles);
|
|
|
|
fVector[2] += 80.0;
|
|
|
|
TeleportEntity(entity, fVector, fAngles, NULL_VECTOR);
|
|
|
|
float fDirection[3];
|
|
fDirection[0] = 0.0;
|
|
fDirection[1] = 0.0;
|
|
fDirection[2] = 1.0;
|
|
|
|
TE_SetupSparks(fVector, fDirection, 1000, 200);
|
|
TE_SendToAll();
|
|
|
|
SetVariantString("!activator");
|
|
AcceptEntityInput(entity, "SetParent", client);
|
|
|
|
if (g_bEngineCSGO)
|
|
return;
|
|
|
|
DataPack data = new DataPack();
|
|
data.WriteCell(EntIndexToEntRef(entity));
|
|
data.WriteCell(EntIndexToEntRef(client));
|
|
data.Reset();
|
|
|
|
CreateTimer(0.1, OnCrownUpdate, data, TIMER_REPEAT);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
void SpawnSkull(int client)
|
|
{
|
|
int entity = INVALID_ENT_REFERENCE;
|
|
if ((entity = CreateEntityByName("prop_dynamic")) == INVALID_ENT_REFERENCE)
|
|
return;
|
|
|
|
SetEntityModel(entity, "models/unloze/skull_v3.mdl");
|
|
|
|
DispatchKeyValue(entity, "solid", "0");
|
|
DispatchKeyValue(entity, "disableshadows", "1");
|
|
DispatchKeyValue(entity, "disablereceiveshadows", "1");
|
|
DispatchKeyValue(entity, "disablebonefollowers", "1");
|
|
|
|
float fVector[3];
|
|
float fAngles[3];
|
|
GetClientAbsOrigin(client, fVector);
|
|
GetClientAbsAngles(client, fAngles);
|
|
|
|
fVector[2] += 80.0;
|
|
|
|
TeleportEntity(entity, fVector, fAngles, NULL_VECTOR);
|
|
|
|
float fDirection[3];
|
|
fDirection[0] = 0.0;
|
|
fDirection[1] = 0.0;
|
|
fDirection[2] = 1.0;
|
|
|
|
TE_SetupSparks(fVector, fDirection, 1000, 200);
|
|
TE_SendToAll();
|
|
|
|
SetVariantString("!activator");
|
|
AcceptEntityInput(entity, "SetParent", client);
|
|
|
|
if (g_bEngineCSGO)
|
|
return;
|
|
|
|
DataPack data = new DataPack();
|
|
data.WriteCell(EntIndexToEntRef(entity));
|
|
data.WriteCell(EntIndexToEntRef(client));
|
|
data.Reset();
|
|
|
|
CreateTimer(0.1, OnSkullUpdate, data, TIMER_REPEAT);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action OnCrownUpdate(Handle timer, DataPack data)
|
|
{
|
|
data.Reset();
|
|
|
|
int entity = INVALID_ENT_REFERENCE;
|
|
if ((entity = EntRefToEntIndex(data.ReadCell())) == INVALID_ENT_REFERENCE)
|
|
return Plugin_Stop;
|
|
|
|
int client = INVALID_ENT_REFERENCE;
|
|
if ((client = EntRefToEntIndex(data.ReadCell())) == INVALID_ENT_REFERENCE)
|
|
return Plugin_Stop;
|
|
|
|
if (!IsValidEntity(entity))
|
|
return Plugin_Stop;
|
|
|
|
if (!IsClientInGame(client) || !IsPlayerAlive(client))
|
|
{
|
|
AcceptEntityInput(entity, "Kill");
|
|
return Plugin_Stop;
|
|
}
|
|
else
|
|
{
|
|
float fAngles[3];
|
|
GetClientAbsAngles(client, fAngles);
|
|
|
|
TeleportEntity(entity, NULL_VECTOR, fAngles, NULL_VECTOR);
|
|
return Plugin_Continue;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action OnSkullUpdate(Handle timer, DataPack data)
|
|
{
|
|
data.Reset();
|
|
|
|
int entity = INVALID_ENT_REFERENCE;
|
|
if ((entity = EntRefToEntIndex(data.ReadCell())) == INVALID_ENT_REFERENCE)
|
|
return Plugin_Stop;
|
|
|
|
int client = INVALID_ENT_REFERENCE;
|
|
if ((client = EntRefToEntIndex(data.ReadCell())) == INVALID_ENT_REFERENCE)
|
|
return Plugin_Stop;
|
|
|
|
if (!IsValidEntity(entity))
|
|
return Plugin_Stop;
|
|
|
|
if (!IsClientInGame(client) || !IsPlayerAlive(client))
|
|
{
|
|
AcceptEntityInput(entity, "Kill");
|
|
return Plugin_Stop;
|
|
}
|
|
else
|
|
{
|
|
float fAngles[3];
|
|
GetClientAbsAngles(client, fAngles);
|
|
|
|
TeleportEntity(entity, NULL_VECTOR, fAngles, NULL_VECTOR);
|
|
return Plugin_Continue;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action ZR_OnClientInfect(&client, &attacker, &bool:motherInfect, &bool:respawnOverride, &bool:respawn)
|
|
{
|
|
if (g_hCVar_Protection.BoolValue && motherInfect && !g_bProtection[client])
|
|
{
|
|
int steamAccountID = GetSteamAccountID(client);
|
|
|
|
if ((g_iPlayerWinner[0] == steamAccountID && GetClientCount() >= g_hCVar_ProtectionMinimal1.IntValue) ||
|
|
(g_iPlayerWinner[1] == steamAccountID && GetClientCount() >= g_hCVar_ProtectionMinimal2.IntValue) ||
|
|
(g_iPlayerWinner[2] == steamAccountID && GetClientCount() >= g_hCVar_ProtectionMinimal3.IntValue))
|
|
{
|
|
PrintToMessageHUD(client, 60, Float:{-1.0, 0.3}, {255, 255, 255, 255}, {255, 255, 255, 255}, 0, 0.1, 0.1, 5.0, 0.0, "%t", "Protected");
|
|
CPrintToChat(client, "{cyan}%t {white}%t", "Chat Prefix", "Protected");
|
|
|
|
EmitSoundToClient(client, "unloze/holy.wav", .volume=1.0);
|
|
return Plugin_Handled;
|
|
}
|
|
}
|
|
|
|
return Plugin_Continue;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
|
|
{
|
|
if (client < 1 || client > MaxClients || attacker < 1 || attacker > MaxClients)
|
|
return;
|
|
|
|
if (client == attacker || (IsPlayerAlive(attacker) && ZR_IsClientHuman(attacker)))
|
|
return;
|
|
|
|
g_iPlayerInfections[attacker] += 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnClientDeath(Event hEvent, const char[] sEvent, bool bDontBroadcast)
|
|
{
|
|
int killer = GetClientOfUserId(hEvent.GetInt("attacker"));
|
|
int victim = GetClientOfUserId(hEvent.GetInt("userid"));
|
|
|
|
char weapon[32];
|
|
hEvent.GetString("weapon", weapon, sizeof(weapon));
|
|
|
|
if (killer < 1 || killer > MaxClients || victim < 1 || victim > MaxClients)
|
|
return;
|
|
|
|
if (killer == victim || (IsPlayerAlive(killer) && ZR_IsClientHuman(killer)) || StrEqual(weapon, "zombie_claws_of_death", true))
|
|
return;
|
|
|
|
g_iPlayerInfections[killer] += 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public int Native_GetClientDamage(Handle hPlugin, int numParams)
|
|
{
|
|
int client = GetNativeCell(1);
|
|
if (client < 1 || client > MaxClients)
|
|
{
|
|
return ThrowNativeError(SP_ERROR_NATIVE, "Invalid client index %d", client);
|
|
}
|
|
|
|
if (!IsClientInGame(client))
|
|
{
|
|
return ThrowNativeError(SP_ERROR_NATIVE, "Client %d is not in game", client);
|
|
}
|
|
|
|
return g_iPlayerDamage[client];
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public int Native_GetClientHits(Handle hPlugin, int numParams)
|
|
{
|
|
int client = GetNativeCell(1);
|
|
if (client < 1 || client > MaxClients)
|
|
{
|
|
return ThrowNativeError(SP_ERROR_NATIVE, "Invalid client index %d", client);
|
|
}
|
|
|
|
if (!IsClientInGame(client))
|
|
{
|
|
return ThrowNativeError(SP_ERROR_NATIVE, "Client %d is not in game", client);
|
|
}
|
|
|
|
return g_iPlayerDamageHits[client];
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public int Native_GetClientInfections(Handle hPlugin, int numParams)
|
|
{
|
|
int client = GetNativeCell(1);
|
|
if (client < 1 || client > MaxClients)
|
|
{
|
|
return ThrowNativeError(SP_ERROR_NATIVE, "Invalid client index %d", client);
|
|
}
|
|
|
|
if (!IsClientInGame(client))
|
|
{
|
|
return ThrowNativeError(SP_ERROR_NATIVE, "Client %d is not in game", client);
|
|
}
|
|
|
|
return g_iPlayerInfections[client];
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
void AddMenuItemTranslated(Menu menu, const char[] info, const char[] display, any ...)
|
|
{
|
|
char buffer[128];
|
|
VFormat(buffer, sizeof(buffer), display, 4);
|
|
|
|
menu.AddItem(info, buffer);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
void PrintToMessageHUD(int client, int channel, float position[2], int color1[4], int color2[4], int effect, float fadein, float fadeout, float hold, float fx, const char[] text, any ...)
|
|
{
|
|
char buffer[512];
|
|
VFormat(buffer, sizeof(buffer), text, 12);
|
|
|
|
Handle hMessage = ((client == 0) ? StartMessageAll("HudMsg") : StartMessageOne("HudMsg", client));
|
|
if (hMessage)
|
|
{
|
|
if (GetUserMessageType() == UM_Protobuf)
|
|
{
|
|
PbSetInt(hMessage, "channel", channel);
|
|
PbSetInt(hMessage, "effect", effect);
|
|
|
|
PbSetVector2D(hMessage, "pos", position);
|
|
|
|
PbSetColor(hMessage, "clr1", color1);
|
|
PbSetColor(hMessage, "clr2", color2);
|
|
|
|
PbSetFloat(hMessage, "fade_in_time", fadein);
|
|
PbSetFloat(hMessage, "fade_out_time", fadeout);
|
|
PbSetFloat(hMessage, "hold_time", hold);
|
|
PbSetFloat(hMessage, "fx_time", fx);
|
|
|
|
PbSetString(hMessage, "text", buffer);
|
|
EndMessage();
|
|
}
|
|
else
|
|
{
|
|
BfWriteByte(hMessage, channel);
|
|
|
|
BfWriteFloat(hMessage, position[0]);
|
|
BfWriteFloat(hMessage, position[1]);
|
|
|
|
BfWriteByte(hMessage, color1[0]);
|
|
BfWriteByte(hMessage, color1[1]);
|
|
BfWriteByte(hMessage, color1[2]);
|
|
BfWriteByte(hMessage, color1[3]);
|
|
BfWriteByte(hMessage, color2[0]);
|
|
BfWriteByte(hMessage, color2[1]);
|
|
BfWriteByte(hMessage, color2[2]);
|
|
BfWriteByte(hMessage, color2[3]);
|
|
BfWriteByte(hMessage, effect);
|
|
|
|
BfWriteFloat(hMessage, fadein);
|
|
BfWriteFloat(hMessage, fadeout);
|
|
BfWriteFloat(hMessage, hold);
|
|
BfWriteFloat(hMessage, fx);
|
|
|
|
BfWriteString(hMessage, buffer);
|
|
EndMessage();
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
void SendDialog(int client, const char[] text, const int level, const int time, any ...)
|
|
{
|
|
char buffer[128];
|
|
VFormat(buffer, sizeof(buffer), text, 5);
|
|
|
|
KeyValues kv = new KeyValues("dialog", "title", buffer);
|
|
kv.SetColor("color", 255, 255, 255, 255);
|
|
kv.SetNum("level", level);
|
|
kv.SetNum("time", time);
|
|
|
|
if (!g_bHideDialog[client])
|
|
{
|
|
CreateDialog(client, kv, DialogType_Msg);
|
|
}
|
|
|
|
for (int spec = 1; spec <= MaxClients; spec++)
|
|
{
|
|
if (!IsClientInGame(spec) || !IsClientObserver(spec) || g_bHideDialog[spec])
|
|
continue;
|
|
|
|
int specMode = GetClientSpectatorMode(spec);
|
|
int specTarget = GetClientSpectatorTarget(spec);
|
|
|
|
if ((specMode == SPECMODE_FIRSTPERSON || specMode == SPECMODE_THIRDPERSON) && specTarget == client)
|
|
{
|
|
CreateDialog(spec, kv, DialogType_Msg);
|
|
}
|
|
}
|
|
|
|
delete kv;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
int GetClientSpectatorMode(int client)
|
|
{
|
|
return GetEntProp(client, Prop_Send, "m_iObserverMode");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
int GetClientSpectatorTarget(int client)
|
|
{
|
|
return GetEntPropEnt(client, Prop_Send, "m_hObserverTarget");
|
|
} |