345 lines
9.9 KiB
SourcePawn
345 lines
9.9 KiB
SourcePawn
#include <sourcemod>
|
|
#include <BossHP>
|
|
#include <zombiereloaded>
|
|
#include <hlstatsx_loghelper>
|
|
|
|
ArrayList g_hStats[MAXPLAYERS+1];
|
|
|
|
bool g_bZRLoaded;
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Plugin myinfo =
|
|
{
|
|
name = "BossHP - Ranking",
|
|
author = "Neon & zaCade",
|
|
description = "",
|
|
version = "1.0.0",
|
|
};
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnPluginStart()
|
|
{
|
|
HookEvent("player_death", EventHook_PlayerDeath, EventHookMode_Pre);
|
|
|
|
for (int client = 1; client <= MaxClients; client++)
|
|
{
|
|
if (!IsClientInGame(client))
|
|
continue;
|
|
|
|
OnClientPutInServer(client);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnAllPluginsLoaded()
|
|
{
|
|
g_bZRLoaded = LibraryExists("zombiereloaded");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnLibraryAdded(const char[] sName)
|
|
{
|
|
if (strcmp(sName, "zombiereloaded", false) == 0)
|
|
g_bZRLoaded = true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnLibraryRemoved(const char[] sName)
|
|
{
|
|
if (strcmp(sName, "zombiereloaded", false) == 0)
|
|
g_bZRLoaded = false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnClientPutInServer(int client)
|
|
{
|
|
g_hStats[client] = new ArrayList(64);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnClientDisconnect(int client)
|
|
{
|
|
delete g_hStats[client];
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnBossDamaged(CBoss Boss, CConfig Config, int client, float damage)
|
|
{
|
|
if (!IsValidClient(client))
|
|
return;
|
|
|
|
int iMaxCash = GetConVarInt(FindConVar("sm_maxcash"));
|
|
|
|
if(!(GetEntProp(client, Prop_Send, "m_iAccount") >= iMaxCash))
|
|
SetEntProp(client, Prop_Send, "m_iAccount", GetEntProp(client, Prop_Send, "m_iAccount") + 2);
|
|
|
|
bool bBreakable;
|
|
CConfig _Config = view_as<CConfig>(Config);
|
|
|
|
if (_Config.IsBreakable)
|
|
bBreakable = true;
|
|
else
|
|
bBreakable = false;
|
|
|
|
delete _Config;
|
|
|
|
for (int index = 0; index < g_hStats[client].Length; index++)
|
|
{
|
|
int BossDamage[2];
|
|
g_hStats[client].GetArray(index, BossDamage, sizeof(BossDamage));
|
|
|
|
if (BossDamage[0] == view_as<int>(Boss))
|
|
{
|
|
if (bBreakable)
|
|
BossDamage[1] += RoundToNearest(damage);
|
|
else
|
|
BossDamage[1] += 1;
|
|
|
|
g_hStats[client].SetArray(index, BossDamage, sizeof(BossDamage));
|
|
return;
|
|
}
|
|
}
|
|
|
|
int BossDamage[2];
|
|
BossDamage[0] = view_as<int>(Boss);
|
|
|
|
if (bBreakable)
|
|
BossDamage[1] = RoundToNearest(damage);
|
|
else
|
|
BossDamage[1] = 1;
|
|
|
|
g_hStats[client].PushArray(BossDamage, sizeof(BossDamage));
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnBossKilled(CBoss Boss, CConfig Config, int reason)
|
|
{
|
|
if (reason == 0)
|
|
{
|
|
for (int client = 1; client <= MaxClients; client++)
|
|
{
|
|
if (!IsClientInGame(client))
|
|
continue;
|
|
|
|
for (int index = 0; index < g_hStats[client].Length; index++)
|
|
{
|
|
int BossDamage[2];
|
|
g_hStats[client].GetArray(index, BossDamage, sizeof(BossDamage));
|
|
|
|
if (BossDamage[0] == view_as<int>(Boss))
|
|
{
|
|
g_hStats[client].Erase(index);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int iSortedList[MAXPLAYERS+1][2];
|
|
int iSortedCount;
|
|
|
|
for (int client = 1; client <= MaxClients; client++)
|
|
{
|
|
if (!IsClientInGame(client))
|
|
continue;
|
|
|
|
for (int index = 0; index < g_hStats[client].Length; index++)
|
|
{
|
|
int BossDamage[2];
|
|
g_hStats[client].GetArray(index, BossDamage, sizeof(BossDamage));
|
|
|
|
if (BossDamage[0] == view_as<int>(Boss))
|
|
{
|
|
iSortedList[iSortedCount][0] = client;
|
|
iSortedList[iSortedCount][1] = BossDamage[1];
|
|
iSortedCount++;
|
|
|
|
g_hStats[client].Erase(index);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
SortCustom2D(iSortedList, iSortedCount, SortBossHitsList);
|
|
|
|
if (iSortedCount)
|
|
{
|
|
CConfig _Config = view_as<CConfig>(Config);
|
|
|
|
char sBossName[64];
|
|
_Config.GetName(sBossName, sizeof(sBossName));
|
|
|
|
char sBuffer[512];
|
|
char sType[16];
|
|
if (_Config.IsBreakable)
|
|
{
|
|
sType = "damage"
|
|
Format(sBuffer, sizeof(sBuffer), "BOSS DAMAGE [%s]:", sBossName);
|
|
}
|
|
else
|
|
{
|
|
sType = "hits"
|
|
Format(sBuffer, sizeof(sBuffer), "BOSS HITS [%s]:", sBossName);
|
|
}
|
|
delete _Config;
|
|
|
|
Format(sBuffer, sizeof(sBuffer), "%s\n*************************", sBuffer);
|
|
|
|
if (iSortedList[0][0])
|
|
{
|
|
Format(sBuffer, sizeof(sBuffer), "%s\n1. %N - %d %s", sBuffer, iSortedList[0][0], iSortedList[0][1], sType);
|
|
|
|
LH_LogPlayerEvent(iSortedList[0][0], "triggered", "ze_boss_damage_first", true);
|
|
}
|
|
if (iSortedList[1][0])
|
|
{
|
|
Format(sBuffer, sizeof(sBuffer), "%s\n2. %N - %d %s", sBuffer, iSortedList[1][0], iSortedList[1][1], sType);
|
|
|
|
LH_LogPlayerEvent(iSortedList[1][0], "triggered", "ze_boss_damage_second", true);
|
|
}
|
|
if (iSortedList[2][0])
|
|
{
|
|
Format(sBuffer, sizeof(sBuffer), "%s\n3. %N - %d %s", sBuffer, iSortedList[2][0], iSortedList[2][1], sType);
|
|
|
|
LH_LogPlayerEvent(iSortedList[2][0], "triggered", "ze_boss_damage_third", true);
|
|
}
|
|
|
|
Format(sBuffer, sizeof(sBuffer), "%s\n*************************", sBuffer);
|
|
|
|
Handle hMessage = StartMessageAll("HudMsg");
|
|
if (hMessage)
|
|
{
|
|
if (GetUserMessageType() == UM_Protobuf)
|
|
{
|
|
PbSetInt(hMessage, "channel", 50);
|
|
PbSetInt(hMessage, "effect", 0);
|
|
PbSetColor(hMessage, "clr1", {255, 255, 255, 255});
|
|
PbSetColor(hMessage, "clr2", {255, 255, 255, 255});
|
|
PbSetVector2D(hMessage, "pos", Float:{0.02, 0.45});
|
|
PbSetFloat(hMessage, "fade_in_time", 0.1);
|
|
PbSetFloat(hMessage, "fade_out_time", 0.1);
|
|
PbSetFloat(hMessage, "hold_time", 7.0);
|
|
PbSetFloat(hMessage, "fx_time", 0.0);
|
|
PbSetString(hMessage, "text", sBuffer);
|
|
EndMessage();
|
|
}
|
|
else
|
|
{
|
|
BfWriteByte(hMessage, 50);
|
|
BfWriteFloat(hMessage, 0.02);
|
|
BfWriteFloat(hMessage, 0.25);
|
|
BfWriteByte(hMessage, 255);
|
|
BfWriteByte(hMessage, 255);
|
|
BfWriteByte(hMessage, 0);
|
|
BfWriteByte(hMessage, 255);
|
|
BfWriteByte(hMessage, 255);
|
|
BfWriteByte(hMessage, 255);
|
|
BfWriteByte(hMessage, 255);
|
|
BfWriteByte(hMessage, 255);
|
|
BfWriteByte(hMessage, 0);
|
|
BfWriteFloat(hMessage, 0.1);
|
|
BfWriteFloat(hMessage, 0.1);
|
|
BfWriteFloat(hMessage, 7.0);
|
|
BfWriteFloat(hMessage, 0.0);
|
|
BfWriteString(hMessage, sBuffer);
|
|
EndMessage();
|
|
}
|
|
}
|
|
|
|
if(GetEngineVersion() == Engine_CSGO)
|
|
{
|
|
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]);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
PrintToChatAll(sBuffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Action EventHook_PlayerDeath(Event hEvent, const char[] sEventName, bool bDontBroadcast)
|
|
{
|
|
if (!g_bZRLoaded)
|
|
return Plugin_Continue;
|
|
|
|
int iClient = GetClientOfUserId(hEvent.GetInt("userid"));
|
|
|
|
if (!IsValidClient(iClient))
|
|
return Plugin_Continue;
|
|
|
|
if (IsPlayerAlive(iClient) && !ZR_IsClientHuman(iClient))
|
|
return Plugin_Continue;
|
|
|
|
int iPacked = (iClient<<16) | (GetEntProp(iClient, Prop_Send, "m_iAccount")&0xFFFF);
|
|
|
|
RequestFrame(RequestFrame_Callback, iPacked);
|
|
|
|
return Plugin_Continue;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
void RequestFrame_Callback(int iPacked)
|
|
{
|
|
int iOldCash = iPacked&0xFFFF;
|
|
int iClient = iPacked>>16;
|
|
|
|
if (!IsValidEntity(iClient) || !IsValidClient(iClient))
|
|
return;
|
|
|
|
SetEntProp(iClient, Prop_Send, "m_iAccount", iOldCash);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public int SortBossHitsList(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:
|
|
//----------------------------------------------------------------------------------------------------
|
|
stock int IsValidClient(int client, bool nobots = true)
|
|
{
|
|
if (client <= 0 || client > MaxClients || !IsClientConnected(client) || (nobots && IsFakeClient(client)))
|
|
return false;
|
|
|
|
return IsClientInGame(client);
|
|
}
|