347 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
			
		
		
	
	
			347 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
| #include <sourcemod>
 | |
| #include <BossHP>
 | |
| #include <zombiereloaded>
 | |
| 
 | |
| #include "loghelper.inc"
 | |
| 
 | |
| #include <basic>
 | |
| #include "CConfig.inc"
 | |
| #include "CBoss.inc"
 | |
| 
 | |
| 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(any Boss, any Config, int client, float damage)
 | |
| {
 | |
| 	if (!IsValidClient(client))
 | |
| 		return;
 | |
| 
 | |
| 	SetEntProp(client, Prop_Send, "m_iAccount", GetEntProp(client, Prop_Send, "m_iAccount") + 1);
 | |
| 
 | |
| 	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++)
 | |
| 	{
 | |
| 		any BossDamage[2];
 | |
| 		g_hStats[client].GetArray(index, BossDamage, sizeof(BossDamage));
 | |
| 
 | |
| 		if (BossDamage[0] == Boss)
 | |
| 		{
 | |
| 			if (bBreakable)
 | |
| 				BossDamage[1] += RoundToNearest(damage);
 | |
| 			else
 | |
| 				BossDamage[1] += 1;
 | |
| 
 | |
| 			g_hStats[client].SetArray(index, BossDamage, sizeof(BossDamage));
 | |
| 			return;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	any BossDamage[2];
 | |
| 	BossDamage[0] = Boss;
 | |
| 
 | |
| 	if (bBreakable)
 | |
| 		BossDamage[1] = RoundToNearest(damage);
 | |
| 	else
 | |
| 		BossDamage[1] = 1;
 | |
| 
 | |
| 	g_hStats[client].PushArray(BossDamage, sizeof(BossDamage));
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public void OnBossKilled(any Boss, any 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++)
 | |
| 			{
 | |
| 				any BossDamage[2];
 | |
| 				g_hStats[client].GetArray(index, BossDamage, sizeof(BossDamage));
 | |
| 
 | |
| 				if (BossDamage[0] == 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++)
 | |
| 			{
 | |
| 				any BossDamage[2];
 | |
| 				g_hStats[client].GetArray(index, BossDamage, sizeof(BossDamage));
 | |
| 
 | |
| 				if (BossDamage[0] == 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);
 | |
| 
 | |
| 				LogPlayerEvent(iSortedList[0][0], "triggered", "ze_boss_damage_first");
 | |
| 			}
 | |
| 			if (iSortedList[1][0])
 | |
| 			{
 | |
| 				Format(sBuffer, sizeof(sBuffer), "%s\n2. %N - %d %s", sBuffer, iSortedList[1][0], iSortedList[1][1], sType);
 | |
| 
 | |
| 				LogPlayerEvent(iSortedList[1][0], "triggered", "ze_boss_damage_second");
 | |
| 			}
 | |
| 			if (iSortedList[2][0])
 | |
| 			{
 | |
| 				Format(sBuffer, sizeof(sBuffer), "%s\n3. %N - %d %s", sBuffer, iSortedList[2][0], iSortedList[2][1], sType);
 | |
| 
 | |
| 				LogPlayerEvent(iSortedList[2][0], "triggered", "ze_boss_damage_third");
 | |
| 			}
 | |
| 
 | |
| 			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);
 | |
| }
 |