sm-plugins-csgo/BossHP/scripting/BossHP.sp
2020-03-25 20:09:12 +02:00

1680 lines
60 KiB
SourcePawn
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <cstrike>
#include <clientprefs>
#include <dhooks>
#include <multicolors>
#include <outputinfo>
#undef REQUIRE_PLUGIN
#tryinclude <UIManager>
#define REQUIRE_PLUGIN
//#define DEBUG
#define LoopIngamePlayers(%1) for (int %1 = 1; %1 <= MaxClients; ++%1)\
if (IsClientInGame(%1))
public Plugin myinfo = {
name = "[ZE] BOSS HP",
author = "CrazyKid @僵尸乐园 ZombiEden.CN + PŠΣ™ SHUFEN",
description = "",
version = "2.7 PŠΣ™",
url = "http://ZombiEden.CN + https://possession.jp"
};
#define MAX_BOSS_NAME_LENGTH 32
#define MathCounterSize 32
#define MathCounterBackupSize 10
#define BreakableSize 32
#define MAX_MATHCOUNTER_NAME_LENGTH 48
#define MAX_BREAKABLE_NAME_LENGTH 48
#define DEFAULT_BOSSNAME_CSS "BOSS HP"
#define DEFAULT_BOSSNAME_CSGO "BOSS"
enum struct Array_MathCounter {
char BossName[MAX_BOSS_NAME_LENGTH];
char sHP[MAX_MATHCOUNTER_NAME_LENGTH];
char sHPBar[MAX_MATHCOUNTER_NAME_LENGTH];
char sHPInit[MAX_MATHCOUNTER_NAME_LENGTH];
int HP;
int HP_Mode;
int HP_Min;
int HP_Max;
int HP_StartValue;
int HPBar_Min;
int HPBar_Max;
int HPBar_StartValue;
int HPBar_Mode;
int HPInit;
int HPInit_Min;
int HPInit_Max;
int HPInit_StartValue;
int Multiply;
int LastHP;
int LastHPShow;
int LastValue;
float LastChangeTime;
float LastAddTime;
bool IsSetDefaultMultiply;
bool IsSetDefaultInit;
int BossHP;
int MaxBossHP;
int HpGroupCount;
}
enum struct Array_MathCounter_Group {
char sName[MAX_MATHCOUNTER_NAME_LENGTH];
int HP;
int Min;
int Max;
bool Stats; //true=enable, false=disabled
bool StartDisabled;
bool Kill;
bool RunOut;
int StartValue;
float LastAddTime;
}
enum struct Array_ClientLastShootBreakable {
char sName[MAX_BREAKABLE_NAME_LENGTH];
int EntityIndex;
}
enum struct Array_Breakable {
char BossName[MAX_BOSS_NAME_LENGTH];
char HitboxName[MAX_BREAKABLE_NAME_LENGTH];
float LastChangeTime;
int BossHP;
int MaxBossHP;
int Index;
}
enum struct Array_Count {
int Math_Counter;
int Breakable;
}
enum struct Array_BossDisplay {
ArrayList BossName;
ArrayList HP;
ArrayList MaxHP;
}
bool csgo = false;
char g_Mapname[128];
char sConfig[PLATFORM_MAX_PATH];
bool IsConfigLoad = false;
ConVar hCVAR_ForceShowBossHP = null;
ConVar hCVAR_UpperCaseInForceEnable = null;
ConVar hCVAR_RoundEndShowBossDamageRank = null;
ConVar hCVAR_ShowTopDamageDuringBOSS = null;
ConVar hCVAR_BossBeatenShowBossDamageRank = null;
ConVar hCVAR_CrosshairChannel = null;
ConVar hCVAR_BossRewardMoney = null;
ConVar hCVAR_BossHpKeepTime = null;
ConVar hCVAR_BossDieKeepTime = null;
ConVar hCVAR_DisplayWhenHPAdded = null;
ConVar hCVAR_MaxLegalBreakableHP = null;
ConVar hCVAR_MaxLegalMathCounterHP = null;
bool g_bForceShowBossHP;
bool g_bUpperCaseInForceEnable;
bool g_bRoundEndShowBossDamageRank;
bool g_bShowTopDamageDuringBOSS;
bool g_bBossBeatenShowBossDamageRank;
int g_CrosshairChannel;
int g_RewardMoney;
float g_BossHpKeepTime;
float g_BossDieKeepTime;
bool g_DisplayWhenHPAdded;
int g_MaxLegalBreakableHP;
int g_MaxLegalMathCounterHP;
Array_MathCounter g_MathCounter[MathCounterSize];
Array_MathCounter_Group g_MathCounter_HPgroup[MathCounterSize][MathCounterBackupSize];
Array_ClientLastShootBreakable g_ClientLastShootBreakable[MAXPLAYERS+1];
Array_Breakable g_Breakable[BreakableSize];
Array_BossDisplay g_BossDisplay;
Array_Count g_Count;
float LastShootHitbox[MAXPLAYERS+1];
float LastShowBossHP;
float LastForceShowBossHP;
float LastShowTopDamage;
char HPcolor[7];
float g_LastShowCenterText[MAXPLAYERS+1];
//Dhook
Handle hAcceptInput = INVALID_HANDLE;
Handle BossHP_Cookie = null;
int g_iStatus[MAXPLAYERS+1] = {0, ...};
int iLastBossEnt = -1;
bool g_bUIManager = false;
public void OnPluginStart() {
/* ====== CSGO Check ====== */
char theFolder[40];
GetGameFolderName(theFolder, sizeof(theFolder));
if (StrEqual(theFolder, "csgo")) csgo = true;
/* ====== BossDisplay Array ====== */
g_BossDisplay.BossName = new ArrayList(MAX_BOSS_NAME_LENGTH);
g_BossDisplay.HP = new ArrayList();
g_BossDisplay.MaxHP = new ArrayList();
/* ====== Hook ====== */
HookEntityOutput("math_counter", "OutValue", MathCounterHook_OutValue);
HookEntityOutput("func_physbox_multiplayer", "OnDamaged", HitboxHook_Breakable);
HookEntityOutput("func_physbox", "OnHealthChanged", HitboxHook_Breakable);
HookEntityOutput("func_breakable", "OnHealthChanged", HitboxHook_Breakable);
HookEntityOutput("prop_dynamic", "OnHealthChanged", HitboxHook);
HookUserMessage(GetUserMessageId("TextMsg"), UserMessageHook_TextMsg, true);
HookUserMessage(GetUserMessageId("HintText"), UserMessageHook_HintText, true);
/* ====== CVAR ====== */
hCVAR_ForceShowBossHP = CreateConVar("BossHP_ForceEnable", "1", "Force display math_counter and func_breakable's valve without BossHP config (bhud function)", _, true, 0.0, true, 1.0);
g_bForceShowBossHP = hCVAR_ForceShowBossHP.BoolValue;
hCVAR_ForceShowBossHP.AddChangeHook(OnConVarChange);
hCVAR_UpperCaseInForceEnable = CreateConVar("BossHP_ForceEnableUpperCase", "1", "Covert boss name to upper case in force display (bhud function)", _, true, 0.0, true, 1.0);
g_bUpperCaseInForceEnable = hCVAR_UpperCaseInForceEnable.BoolValue;
hCVAR_UpperCaseInForceEnable.AddChangeHook(OnConVarChange);
hCVAR_RoundEndShowBossDamageRank = CreateConVar("BossHP_RoundEndShowTopDamage", "0", "Show <rank of do damage to boss> OnRoundEnd", _, true, 0.0, true, 1.0);
g_bRoundEndShowBossDamageRank = hCVAR_RoundEndShowBossDamageRank.BoolValue;
hCVAR_RoundEndShowBossDamageRank.AddChangeHook(OnConVarChange);
hCVAR_ShowTopDamageDuringBOSS = CreateConVar("BossHP_ShowTopDamageDuringBOSS", "0", "Show <rank of do damage to boss> during boss fight", _, true, 0.0, true, 1.0);
g_bShowTopDamageDuringBOSS = hCVAR_ShowTopDamageDuringBOSS.BoolValue;
hCVAR_ShowTopDamageDuringBOSS.AddChangeHook(OnConVarChange);
hCVAR_BossBeatenShowBossDamageRank = CreateConVar("BossHP_BossBeatenShowTopDamage", "1", "Show <rank of do damage to boss> when boss has beaten", _, true, 0.0, true, 1.0);
g_bBossBeatenShowBossDamageRank = hCVAR_BossBeatenShowBossDamageRank.BoolValue;
hCVAR_BossBeatenShowBossDamageRank.AddChangeHook(OnConVarChange);
hCVAR_CrosshairChannel = CreateConVar("BossHP_CrosshairChannel", "4", "Crosshair marker display channel", _, true, 0.0, true, 6.0);
g_CrosshairChannel = hCVAR_CrosshairChannel.IntValue;
hCVAR_CrosshairChannel.AddChangeHook(OnConVarChange);
hCVAR_BossRewardMoney = CreateConVar("BossHP_BossRewardMoney", "10", "Reward money to players when shoot the boss (per hit)", _, true, 0.0, false, _);
g_RewardMoney = hCVAR_BossRewardMoney.IntValue;
hCVAR_BossRewardMoney.AddChangeHook(OnConVarChange);
hCVAR_BossHpKeepTime = CreateConVar("BossHP_KeepTime", "15.0", "Boss Alive HP keep time", _, true, 0.0, false, _);
g_BossHpKeepTime = hCVAR_BossHpKeepTime.FloatValue;
hCVAR_BossHpKeepTime.AddChangeHook(OnConVarChange);
hCVAR_BossDieKeepTime = CreateConVar("BossHP_DieKeepTime", "1.0", "Boss Die HP keep time (must be under Alive KeepTime)", _, true, 0.0, false, _);
g_BossDieKeepTime = hCVAR_BossDieKeepTime.FloatValue;
hCVAR_BossDieKeepTime.AddChangeHook(OnConVarChange);
hCVAR_DisplayWhenHPAdded = CreateConVar("BossHP_DisplayWhenHPAdded", "0", "Display Boss HP When Boss HP Added", _, true, 0.0, true, 1.0);
g_DisplayWhenHPAdded = hCVAR_DisplayWhenHPAdded.BoolValue;
hCVAR_DisplayWhenHPAdded.AddChangeHook(OnConVarChange);
hCVAR_MaxLegalBreakableHP = CreateConVar("BossHP_MaxLegalBreakableHP", "500000", "", _, true, 0.0, false, _);
g_MaxLegalBreakableHP = hCVAR_MaxLegalBreakableHP.IntValue;
hCVAR_MaxLegalBreakableHP.AddChangeHook(OnConVarChange);
hCVAR_MaxLegalMathCounterHP = CreateConVar("BossHP_MaxLegalMathCounterHP", "40000", "", _, true, 0.0, false, _);
g_MaxLegalMathCounterHP = hCVAR_MaxLegalMathCounterHP.IntValue;
hCVAR_MaxLegalMathCounterHP.AddChangeHook(OnConVarChange);
/* ====== Commands ====== */
RegAdminCmd("reloadbosshp", ReloadBossHP, ADMFLAG_RCON);
RegConsoleCmd("sm_bossdamage", Command_ShowTopDamage); //Allow client view boss damage rank
RegAdminCmd("sm_shp", Command_SubtractHP, ADMFLAG_RCON, "Subtract Current Boss HP");
RegAdminCmd("sm_subtracthp", Command_SubtractHP, ADMFLAG_RCON, "Subtract Current Boss HP");
/* ====== DEBUG Commands ====== */
RegAdminCmd("debug_bosshp_saveconfig", DEBUG_SaveConfig, ADMFLAG_RCON);
RegAdminCmd("debug_bosshp_getarrayinfo", DEBUG_GetArrayInfo, ADMFLAG_RCON);
RegAdminCmd("debug_bosshp_printvar", DEBUG_PrintVar, ADMFLAG_RCON);
/* ====== Events ====== */
HookEvent("round_start", OnRoundStart);
HookEvent("round_end", OnRoundEnd);
/* ====== Translate ====== */
LoadTranslations("BossHP.phrases");
/* ====== DHook ====== */
if (csgo) {
char tmpOffset[148];
switch (GetEngineVersion()) {
case Engine_CSGO:
tmpOffset = "sdktools.games\\engine.csgo";
case Engine_CSS:
tmpOffset = "sdktools.games\\engine.css";
}
Handle temp = LoadGameConfigFile(tmpOffset);
if (temp == INVALID_HANDLE) {
SetFailState("Why you no has gamedata?");
} else {
int offset = GameConfGetOffset(temp, "AcceptInput");
hAcceptInput = DHookCreate(offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, AcceptInput);
DHookAddParam(hAcceptInput, HookParamType_CharPtr);
DHookAddParam(hAcceptInput, HookParamType_CBaseEntity);
DHookAddParam(hAcceptInput, HookParamType_CBaseEntity);
DHookAddParam(hAcceptInput, HookParamType_Object, 20, DHookPass_ByVal|DHookPass_ODTOR|DHookPass_OCTOR|DHookPass_OASSIGNOP); //varaint_t is a union of 12 (float[3]) plus two int type params 12 + 8 = 20
DHookAddParam(hAcceptInput, HookParamType_Int);
}
CloseHandle(temp);
}
/* ====== Clients ====== */
RegConsoleCmd("sm_bhp", Command_BossHP, "Toggle BossHP");
RegConsoleCmd("sm_bhud", Command_BossHP, "Toggle BossHP");
RegConsoleCmd("sm_boss", Command_BossHP, "Toggle BossHP");
RegConsoleCmd("sm_bosshp", Command_BossHP, "Toggle BossHP");
RegConsoleCmd("sm_bosshud", Command_BossHP, "Toggle BossHP");
BossHP_Cookie = RegClientCookie("bosshp_status", "Status of BossHP", CookieAccess_Private);
SetCookieMenuItem(PrefMenu, 0, "Boss HP");
for(int i = 1; i <= MaxClients; i++) {
if (IsClientInGame(i)) {
if (!AreClientCookiesCached(i))
continue;
OnClientCookiesCached(i);
}
}
/* ====== Init ====== */
//GetCurrentMap(g_Mapname, sizeof(g_Mapname));
//LoadConfig();
}
public void OnAllPluginsLoaded() {
g_bUIManager = LibraryExists("UIManager");
}
public void OnLibraryAdded(const char[] name) {
if (StrEqual(name, "UIManager"))
g_bUIManager = true;
}
public void OnLibraryRemoved(const char[] name) {
if (StrEqual(name, "UIManager"))
g_bUIManager = false;
}
public void OnConVarChange(ConVar hCvar, const char[] oldValue, const char[] newValue) {
if (hCvar == hCVAR_ForceShowBossHP)
g_bForceShowBossHP = view_as<bool>(StringToInt(newValue));
else if (hCvar == hCVAR_UpperCaseInForceEnable)
g_bUpperCaseInForceEnable = view_as<bool>(StringToInt(newValue));
else if (hCvar == hCVAR_RoundEndShowBossDamageRank)
g_bRoundEndShowBossDamageRank = view_as<bool>(StringToInt(newValue));
else if (hCvar == hCVAR_ShowTopDamageDuringBOSS)
g_bShowTopDamageDuringBOSS = view_as<bool>(StringToInt(newValue));
else if (hCvar == hCVAR_BossBeatenShowBossDamageRank)
g_bBossBeatenShowBossDamageRank = view_as<bool>(StringToInt(newValue));
else if (hCvar == hCVAR_CrosshairChannel)
g_CrosshairChannel = StringToInt(newValue);
else if (hCvar == hCVAR_BossRewardMoney)
g_RewardMoney = StringToInt(newValue);
else if (hCvar == hCVAR_DisplayWhenHPAdded)
g_DisplayWhenHPAdded = view_as<bool>(StringToInt(newValue));
else if (hCvar == hCVAR_MaxLegalBreakableHP)
g_MaxLegalBreakableHP = StringToInt(newValue);
else if (hCvar == hCVAR_MaxLegalMathCounterHP)
g_MaxLegalMathCounterHP = StringToInt(newValue);
else if (hCvar == hCVAR_BossHpKeepTime) {
g_BossHpKeepTime = StringToFloat(newValue);
if (g_BossHpKeepTime == 0.0)
g_BossHpKeepTime = 0.01;
if (g_BossHpKeepTime < g_BossDieKeepTime)
g_BossDieKeepTime = g_BossHpKeepTime - 0.01;
}
else if (hCvar == hCVAR_BossDieKeepTime) {
g_BossDieKeepTime = StringToFloat(newValue);
if (g_BossHpKeepTime < g_BossDieKeepTime)
g_BossDieKeepTime = g_BossHpKeepTime - 0.01;
}
}
public void OnClientConnected(int client) {
g_iStatus[client] = 0;
}
public void OnClientCookiesCached(int client) {
char sValue[8];
GetClientCookie(client, BossHP_Cookie, sValue, sizeof(sValue));
if(sValue[0] == '\0') {
SetClientCookie(client, BossHP_Cookie, "0");
strcopy(sValue, sizeof(sValue), "0");
}
g_iStatus[client] = StringToInt(sValue);
}
public void PrefMenu(int client, CookieMenuAction actions, any info, char[] buffer, int maxlen) {
if (actions == CookieMenuAction_DisplayOption) {
switch(g_iStatus[client]) {
case 0: FormatEx(buffer, maxlen, "%T: %T", "BossHP", client, "FullEnabled", client);
case 1: FormatEx(buffer, maxlen, "%T: %T", "BossHP", client, "OnlyHP", client);
case 2: FormatEx(buffer, maxlen, "%T: %T", "BossHP", client, "OnlyHitmarker", client);
case 3: FormatEx(buffer, maxlen, "%T: %T", "BossHP", client, "Disabled", client);
}
}
if (actions == CookieMenuAction_SelectOption) {
ToggleBossHP(client);
ShowCookieMenu(client);
}
}
public Action Command_BossHP(int client, int argc) {
if(client < 1 || client > MaxClients)
return Plugin_Handled;
ToggleBossHP(client);
return Plugin_Handled;
}
void ToggleBossHP(int client) {
switch(g_iStatus[client]) {
case 0: {
g_iStatus[client] = 1;
CPrintToChat(client, "%t", "OnlyHPMsg");
}
case 1: {
g_iStatus[client] = 2;
CPrintToChat(client, "%t", "OnlyHitmarkerMsg");
}
case 2: {
g_iStatus[client] = 3;
CPrintToChat(client, "%t", "DisabledMsg");
}
case 3: {
g_iStatus[client] = 0;
CPrintToChat(client, "%t", "FullEnabledMsg");
}
}
char sCookieValue[2];
IntToString(g_iStatus[client], sCookieValue, sizeof(sCookieValue));
SetClientCookie(client, BossHP_Cookie, sCookieValue);
}
public Action Command_SubtractHP(int client, int argc) {
if (!IsValidEntity(iLastBossEnt)) {
CReplyToCommand(client, "\x04[SM]\x01 Last boss entity is invalid (ID: %i)", iLastBossEnt);
return Plugin_Handled;
}
if (argc < 1) {
CReplyToCommand(client, "\x04[SM]\x01 Usage: sm_subtracthp <health>");
return Plugin_Handled;
}
char szName[64], szType[64], arg[8];
int health;
GetEntityClassname(iLastBossEnt, szType, sizeof(szType));
GetEntPropString(iLastBossEnt, Prop_Data, "m_iName", szName, sizeof(szName));
GetCmdArg(1, arg, sizeof(arg));
SetVariantInt(StringToInt(arg));
if (StrEqual(szType, "math_counter", false)) {
static int offset = -1;
if (offset == -1)
offset = FindDataMapInfo(iLastBossEnt, "m_OutValue");
health = RoundFloat(GetEntDataFloat(iLastBossEnt, offset));
AcceptEntityInput(iLastBossEnt, "Subtract", client, client);
CReplyToCommand(client, "\x04[SM]\x01 %i health subtracted from \"%s\" (%i HP to %i HP)", StringToInt(arg), szName, health, health - StringToInt(arg));
} else {
health = GetEntProp(iLastBossEnt, Prop_Data, "m_iHealth");
AcceptEntityInput(iLastBossEnt, "RemoveHealth", client, client);
CReplyToCommand(client, "\x04[SM]\x01 %i health subtracted from \"%s\" (%i HP to %i HP)", StringToInt(arg), szName, health, health - StringToInt(arg));
}
return Plugin_Handled;
}
public void OnRoundStart(Event event, const char[] name, bool dontBroadcast) {
if (IsConfigLoad) {
for (int i = 0; i < g_Count.Math_Counter; i++) {
g_MathCounter[i].BossHP = 0;
g_MathCounter[i].MaxBossHP = 0;
g_MathCounter[i].Multiply = 1;
g_MathCounter[i].HPInit = 0;
g_MathCounter[i].IsSetDefaultMultiply = false;
g_MathCounter[i].IsSetDefaultInit = false;
g_MathCounter[i].LastValue = 0;
g_MathCounter[i].LastHP = 0;
g_MathCounter[i].LastHPShow = 0;
for (int x=0; x < g_MathCounter[i].HpGroupCount; x++) {
g_MathCounter_HPgroup[i][x].Kill = false;
g_MathCounter_HPgroup[i][x].RunOut = false;
}
}
for (int i = 0; i < g_Count.Breakable; i++) {
g_Breakable[i].MaxBossHP = 0;
g_Breakable[i].Index = -1;
}
LoopIngamePlayers(i) {
if (csgo)
CS_SetClientAssists(i, 0);
else
SetEntProp(i, Prop_Data, "m_iDeaths", 0);
g_ClientLastShootBreakable[i].EntityIndex = -1;
g_ClientLastShootBreakable[i].sName[0] = '\0';
}
CreateTimer(5.0, Timer_OnRoundStartPost);
}
}
public void OnRoundEnd(Event event, const char[] name, bool dontBroadcast) {
if (csgo && IsConfigLoad && g_bRoundEndShowBossDamageRank)
ShowBossTopDamage(0);
}
public Action Timer_OnRoundStartPost(Handle timer) {
if (csgo)
CPrintToChatAll("%t", "RoundStart_Message_CSGO");
else
CPrintToChatAll("%t", "RoundStart_Message_CSS");
return Plugin_Stop;
}
public void OnMapStart() {
GetCurrentMap(g_Mapname, sizeof(g_Mapname));
LoadConfig();
}
public void OnMapEnd() {
iLastBossEnt = -1;
}
public Action ReloadBossHP(int client, int args) {
LoadConfig();
ReplyToCommand(client, "[Z-BossHP] Config Reloaded");
return Plugin_Handled;
}
public Action DEBUG_SaveConfig(int client, int args) {
SaveConfig();
ReplyToCommand(client, "[Z-BossHP] Config Saved");
return Plugin_Handled;
}
public Action Command_ShowTopDamage(int client, int args) {
if (IsConfigLoad)
ShowBossTopDamage(client);
return Plugin_Handled;
}
stock void LoadConfig() {
g_Count.Math_Counter = 0;
g_Count.Breakable = 0;
IsConfigLoad = false;
char tempStr[16];
int tempNum;
BuildPath(Path_SM, sConfig, PLATFORM_MAX_PATH, "configs/MapBossHP/%s.txt", g_Mapname);
KeyValues kv = new KeyValues("math_counter");
kv.ImportFromFile(sConfig);
if (kv.GotoFirstSubKey()) {
do {
kv.GetSectionName(tempStr, sizeof(tempStr));
if (StrEqual(tempStr, "config", false)) {
tempNum = kv.GetNum("ForceEnable", 1);
hCVAR_ForceShowBossHP.SetBool(view_as<bool>(tempNum));
tempNum = kv.GetNum("ForceEnableUpperCase", 1);
hCVAR_UpperCaseInForceEnable.SetBool(view_as<bool>(tempNum));
tempNum = kv.GetNum("RoundEndShowTopDamage", 0);
hCVAR_RoundEndShowBossDamageRank.SetBool(view_as<bool>(tempNum));
tempNum = kv.GetNum("ShowTopDamageDuringBOSS", 0);
hCVAR_ShowTopDamageDuringBOSS.SetBool(view_as<bool>(tempNum));
tempNum = kv.GetNum("BossBeatenShowTopDamage", 1);
hCVAR_BossBeatenShowBossDamageRank.SetBool(view_as<bool>(tempNum));
tempNum = kv.GetNum("CrosshairChannel", 4);
if (tempNum >= 1 && tempNum <= 6)
hCVAR_CrosshairChannel.SetInt(tempNum);
tempNum = kv.GetNum("BossRewardMoney", 10);
if (tempNum > 0)
hCVAR_BossRewardMoney.SetInt(tempNum);
tempNum = kv.GetNum("BossHpKeepTime", 15);
hCVAR_BossHpKeepTime.SetInt(tempNum);
tempNum = kv.GetNum("BossDieKeepTime", 1);
hCVAR_BossDieKeepTime.SetInt(tempNum);
tempNum = kv.GetNum("DisplayWhenHPAdded", 0);
hCVAR_DisplayWhenHPAdded.SetBool(view_as<bool>(tempNum));
tempNum = kv.GetNum("MaxLegalBreakableHP", 500000);
hCVAR_MaxLegalBreakableHP.SetInt(tempNum);
tempNum = kv.GetNum("MaxLegalMathCounterHP", 40000);
hCVAR_MaxLegalMathCounterHP.SetInt(tempNum);
if (g_BossHpKeepTime == 0.0)
g_BossHpKeepTime = 0.01;
if (g_BossHpKeepTime < g_BossDieKeepTime)
g_BossDieKeepTime = g_BossHpKeepTime - 0.01;
} else {
kv.GetString("Type", tempStr, sizeof(tempStr));
if (StrEqual(tempStr, "breakable", false)) {
kv.GetString("BreakableName", g_Breakable[g_Count.Breakable].HitboxName, sizeof(Array_Breakable::HitboxName));
kv.GetString("CustomText", g_Breakable[g_Count.Breakable].BossName, sizeof(Array_Breakable::BossName));
if (g_Breakable[g_Count.Breakable].BossName[0] == '\0')
Format(g_Breakable[g_Count.Breakable].BossName, sizeof(Array_Breakable::BossName), "%s", csgo ? DEFAULT_BOSSNAME_CSGO : DEFAULT_BOSSNAME_CSS);
#if defined DEBUG
CPrintToChatAll("{pink}[BossHP-DEBUG] kv read: BreakableName:%s", g_Breakable[g_Count.Breakable].HitboxName); //debug
#endif
++g_Count.Breakable;
} else {
kv.GetString("HP_Counter", g_MathCounter[g_Count.Math_Counter].sHP, sizeof(Array_MathCounter::sHP));
kv.GetString("HPinit_Counter", g_MathCounter[g_Count.Math_Counter].sHPInit, sizeof(Array_MathCounter::sHPInit));
kv.GetString("HPbar_Counter", g_MathCounter[g_Count.Math_Counter].sHPBar, sizeof(Array_MathCounter::sHPBar));
kv.GetString("CustomText", g_MathCounter[g_Count.Math_Counter].BossName, sizeof(Array_MathCounter::BossName));
if (g_MathCounter[g_Count.Math_Counter].BossName[0] == '\0')
Format(g_MathCounter[g_Count.Math_Counter].BossName, sizeof(Array_MathCounter::BossName), "%s", csgo ? DEFAULT_BOSSNAME_CSGO : DEFAULT_BOSSNAME_CSS);
#if defined DEBUG
CPrintToChatAll("{pink}[BossHP-DEBUG] kv read: HP_Counter:%s", g_MathCounter[g_Count.Math_Counter].sHP); //debug
#endif
g_MathCounter[g_Count.Math_Counter].HpGroupCount = 0;
if (kv.JumpToKey("HP_Group", false)) {
for (int i = 0; i < sizeof(g_MathCounter_HPgroup[]); i++) {
IntToString(i, tempStr, sizeof(tempStr));
kv.GetString(tempStr, g_MathCounter_HPgroup[g_Count.Math_Counter][i].sName, sizeof(Array_MathCounter_Group::sName));
if (g_MathCounter_HPgroup[g_Count.Math_Counter][i].sName[0] == '\0')
break;
g_MathCounter[g_Count.Math_Counter].HpGroupCount++;
#if defined DEBUG
CPrintToChatAll("{pink}[BossHP-DEBUG] kv read: BackupCounter(%d):%s", i, g_MathCounter_HPgroup[g_Count.Math_Counter][i].sName); //debug
#endif
}
kv.GoBack();
}
++g_Count.Math_Counter;
}
}
} while (kv.GotoNextKey());
}
delete kv;
if (g_Count.Math_Counter == 0 && g_Count.Breakable == 0)
IsConfigLoad = false;
else
IsConfigLoad = true;
}
stock void SaveConfig() {
if (!IsConfigLoad)
return;
KeyValues kv = new KeyValues("math_counter");
int index = 0;
char tempStr[16];
kv.JumpToKey("config", true);
//kv.SetSectionName("config");
if (!g_bForceShowBossHP)
kv.SetNum("ForceEnable", 0);
if (!g_bUpperCaseInForceEnable)
kv.SetNum("ForceEnableUpperCase", 0);
if (g_bRoundEndShowBossDamageRank)
kv.SetNum("RoundEndShowTopDamage", 1);
if (g_bShowTopDamageDuringBOSS)
kv.SetNum("ShowTopDamageDuringBOSS", 1);
if (!g_bBossBeatenShowBossDamageRank)
kv.SetNum("BossBeatenShowTopDamage", 0);
if (g_CrosshairChannel != 4 && g_CrosshairChannel >= 1 && g_CrosshairChannel <= 6)
kv.SetNum("CrosshairChannel", g_CrosshairChannel);
if (g_RewardMoney != 10 && g_RewardMoney > 0)
kv.SetNum("BossRewardMoney", g_RewardMoney);
if (g_BossHpKeepTime != 15.0)
kv.SetFloat("BossHpKeepTime", g_BossHpKeepTime);
if (g_BossDieKeepTime != 1.0)
kv.SetFloat("BossDieKeepTime", g_BossDieKeepTime);
if (g_DisplayWhenHPAdded)
kv.SetNum("DisplayWhenHPAdded", 1);
if (g_MaxLegalBreakableHP != 500000)
kv.SetNum("MaxLegalBreakableHP", g_MaxLegalBreakableHP);
if (g_MaxLegalMathCounterHP != 40000)
kv.SetNum("MaxLegalMathCounterHP", g_MaxLegalMathCounterHP);
kv.Rewind();
for (int i = 0; i < g_Count.Breakable; i++) {
IntToString(index, tempStr, sizeof(tempStr));
kv.JumpToKey(tempStr, true);
//kv.SetSectionName(tempStr);
kv.SetString("BreakableName", g_Breakable[i].HitboxName);
if ( ( csgo && !StrEqual(g_Breakable[i].BossName, DEFAULT_BOSSNAME_CSGO) ) || (!csgo && !StrEqual(g_Breakable[i].BossName, DEFAULT_BOSSNAME_CSS) ) )
kv.SetString("CustomText", g_Breakable[i].BossName);
kv.Rewind();
index++;
}
for (int i = 0; i < g_Count.Math_Counter; i++) {
IntToString(index, tempStr, sizeof(tempStr));
kv.JumpToKey(tempStr, true);
//kv.SetSectionName(tempStr);
kv.SetString("HP_Counter", g_MathCounter[i].sHP);
kv.SetString("HPinit_Counter", g_MathCounter[i].sHPInit);
kv.SetString("HPbar_Counter", g_MathCounter[i].sHPBar);
if ( ( csgo && !StrEqual(g_MathCounter[i].BossName, DEFAULT_BOSSNAME_CSGO) ) || (!csgo && !StrEqual(g_MathCounter[i].BossName, DEFAULT_BOSSNAME_CSS) ) )
kv.SetString("CustomText", g_MathCounter[i].BossName);
if (g_MathCounter[i].HpGroupCount > 0) {
kv.JumpToKey("HP_Group", true);
for (int x = 0; x < g_MathCounter[i].HpGroupCount; x++) {
IntToString(x, tempStr, sizeof(tempStr));
kv.SetString(tempStr, g_MathCounter_HPgroup[i][x].sName);
}
kv.GoBack();
}
kv.Rewind();
index++;
}
kv.ExportToFile(sConfig);
delete kv;
}
public void HitboxHook(const char[] output, int entity, int activator, float delay) {
if (activator > 0 && activator < MAXPLAYERS)
LastShootHitbox[activator] = GetEngineTime();
}
public void HitboxHook_Breakable(const char[] output, int entity, int activator, float delay) {
if (activator < 1 || activator > MAXPLAYERS)
return;
LastShootHitbox[activator] = GetEngineTime();
int CurrentValue;
CurrentValue = GetEntProp(entity, Prop_Data, "m_iHealth");
if (CurrentValue > g_MaxLegalBreakableHP)
return;
if (IsConfigLoad) {
char targetname[MAX_BREAKABLE_NAME_LENGTH];
GetEntPropString(entity, Prop_Data, "m_iName", targetname, sizeof(targetname));
#if defined DEBUG
// CPrintToChatAll("{green}[BossHP-DEBUG] Breakable:%s Value:%d Activator:%d", g_Breakable[i].EntityName, CurrentValue, activator); //debug
#endif
for (int i = 0; i < g_Count.Breakable; i++) {
if (g_Breakable[i].Index == entity || StrEqual(targetname, g_Breakable[i].HitboxName, false)) {
if (csgo)
CS_SetClientAssists(activator, CS_GetClientAssists(activator) + 1);
else
SetEntProp(activator, Prop_Data, "m_iDeaths", GetEntProp(activator, Prop_Data, "m_iDeaths") - 1);
//Give cash to players, 1hit = $10
SetEntProp(activator, Prop_Send, "m_iAccount", GetEntProp(activator, Prop_Send, "m_iAccount") + g_RewardMoney);
//Show HitMarker when hit the boss
//if (g_iStatus[activator] == 0 || g_iStatus[activator] == 2) {
// if (g_bUIManager)
// SendHudText(activator, g_CrosshairChannel, 5, -1.0, -1.0, {255, 0, 0, 50}, {255, 0, 0, 50}, 0, 0.1, 0.1, 0.1, 0.1, "◞ ◟\n◝ ◜");
// else {
// SetHudTextParamsEx(-1.0, -1.0, 0.1, {255, 0, 0, 50}, {255, 0, 0, 50}, 0, 0.1, 0.1, 0.1);
// ShowHudText(activator, g_CrosshairChannel, "◞ ◟\n◝ ◜");
// }
//}
//Show HitMarker to player who is spectating attacker
/*
for (new x = 1; x <= MaxClients; x++) {
if (IsClientInGame(x) && !IsPlayerAlive(x)) {
if (GetEntProp(x, Prop_Send, "m_iObserverMode") == 4) {
if (activator == GetEntPropEnt(x, Prop_Send, "m_hObserverTarget")) {
if (g_iStatus[x] == 0 || g_iStatus[x] == 2) {
SetHudTextParamsEx(-1.0, -1.0, 0.1, {255, 0, 0, 50}, {255, 0, 0, 50}, 0, 0.1, 0.1, 0.1);
ShowHudText(x, g_CrosshairChannel, "◞ ◟\n◝ ◜");
}
}
}
}
}
*/
if (CurrentValue <= 0) {
iLastBossEnt = -1;
CurrentValue = 0; //to prevent from display negative number
g_Breakable[i].LastChangeTime = GetEngineTime() - ( g_BossHpKeepTime - g_BossDieKeepTime );
} else {
iLastBossEnt = entity;
g_Breakable[i].LastChangeTime = GetEngineTime();
}
if (g_DisplayWhenHPAdded || CurrentValue < g_Breakable[i].BossHP) { //Only display when BossHP is subtracted.
g_Breakable[i].BossHP = CurrentValue;
PrintHP(activator, CurrentValue);
} else {
g_Breakable[i].BossHP = CurrentValue;
}
g_Breakable[i].Index = entity; //Need to store Breakable's entity index, because if it's broke, we can't get his targetname.
return;
}
}
}
//bhud function
if (g_bForceShowBossHP &&
LastShowBossHP + 3.0 < GetEngineTime() && // If BossHP was show in the past 3sec, block this function
LastShootHitbox[activator] > GetEngineTime() - 0.2) { //if players didn't shoot to breakable, block this function
if (g_ClientLastShootBreakable[activator].EntityIndex != entity) {
GetEntPropString(entity, Prop_Data, "m_iName", g_ClientLastShootBreakable[activator].sName, sizeof(Array_ClientLastShootBreakable::sName));
if (g_ClientLastShootBreakable[activator].sName[0] == '\0')
Format(g_ClientLastShootBreakable[activator].sName, sizeof(Array_ClientLastShootBreakable::sName), "HP");
g_ClientLastShootBreakable[activator].EntityIndex = entity;
}
if (CurrentValue <= 0) { //to prevent from display negative number
iLastBossEnt = -1;
PrintHP_Force(activator, entity, g_ClientLastShootBreakable[activator].sName, 0);
} else {
iLastBossEnt = entity;
PrintHP_Force(activator, entity, g_ClientLastShootBreakable[activator].sName, CurrentValue);
}
}
}
public void MathCounterHook_OutValue(const char[] output, int entity, int activator, float delay) {
#if defined DEBUG
if (IsValidEntity(entity) || IsValidEdict(entity)) {
char targetname[32];
int offset, CurrentValue;
GetEntPropString(entity, Prop_Data, "m_iName", targetname, sizeof(targetname));
offset = FindDataMapInfo(entity, "m_OutValue");
if (offset == -1)
return;
CurrentValue = RoundFloat(GetEntDataFloat(entity, offset));
CPrintToChatAll("%s I:%d N:%s V:%d A:%d O:%d", output, entity, targetname, CurrentValue, activator, offset);
}
#endif
//if (activator < 0) return;
if (IsConfigLoad && (IsValidEntity(entity) || IsValidEdict(entity))) {
#if !defined DEBUG
char targetname[32];
int offset, CurrentValue;
GetEntPropString(entity, Prop_Data, "m_iName", targetname, sizeof(targetname));
offset = FindDataMapInfo(entity, "m_OutValue");
if (offset == -1)
return;
CurrentValue = RoundFloat(GetEntDataFloat(entity, offset));
#endif
#if defined DEBUG
CPrintToChatAll("{green}[BossHP-DEBUG] Counter:%s Value:%d Activator:%d", targetname, CurrentValue, activator); //debug
#endif
for (int i = 0; i < g_Count.Math_Counter; i++) {
if (StrEqual(targetname, g_MathCounter[i].sHP, false)) {
if (g_MathCounter[i].sHPBar[0] != '\0') { //If this boss has HPBar counter
//Need to give a default multiply value
if (!g_MathCounter[i].IsSetDefaultMultiply) {
g_MathCounter[i].IsSetDefaultMultiply = true;
if (g_MathCounter[i].HPBar_Mode == 1) { //Boss_end_relay is triggered by OnHitMin
g_MathCounter[i].Multiply = g_MathCounter[i].HPBar_StartValue - g_MathCounter[i].HPBar_Min;
}
else if (g_MathCounter[i].HPBar_Mode == 2) { //Boss_end_relay is triggered by OnHitMax
g_MathCounter[i].Multiply = g_MathCounter[i].HPBar_Max - g_MathCounter[i].HPBar_StartValue;
}
#if defined DEBUG
CPrintToChatAll("{red}[BossHP-DEBUG] Set default multiply: %d", g_MathCounter[i].Multiply); //debug
#endif
}
}
if (g_MathCounter[i].Multiply <= 0) {
g_MathCounter[i].BossHP = 0; //to prevent from display negative number
} else {
if (g_MathCounter[i].HP_Mode == 1)
g_MathCounter[i].BossHP = (g_MathCounter[i].Multiply - 1) * g_MathCounter[i].HPInit + (CurrentValue - g_MathCounter[i].HP_Min);
else
g_MathCounter[i].BossHP = (g_MathCounter[i].Multiply - 1) * g_MathCounter[i].HPInit + (g_MathCounter[i].HP_Max - CurrentValue);
}
if (g_DisplayWhenHPAdded || g_MathCounter[i].BossHP < g_MathCounter[i].LastHP) { //Only display when BossHP is subtracted.
if ((g_MathCounter[i].HP_Mode == 1 && g_MathCounter[i].BossHP <= g_MathCounter[i].HP_Min) || g_MathCounter[i].BossHP <= 1) { //in some maps like ze_Predator_ultimate, boss's math_counter MinValve is not 0 but 1.
g_MathCounter[i].LastChangeTime = GetEngineTime() - ( g_BossHpKeepTime - g_BossDieKeepTime ) ; // when BossHP hit 0, keep more 1s display time.(default value)
iLastBossEnt = -1;
g_MathCounter[i].BossHP = 0;
g_MathCounter[i].IsSetDefaultInit = false; // When a Boss die, reset it to false
} else {
iLastBossEnt = entity;
g_MathCounter[i].LastChangeTime = GetEngineTime();
if (g_MathCounter[i].BossHP < g_MaxLegalMathCounterHP && activator > 0 && activator <= MAXPLAYERS) {
if (csgo)
CS_SetClientAssists(activator, CS_GetClientAssists(activator) + 1);
else
SetEntProp(activator, Prop_Data, "m_iDeaths", GetEntProp(activator, Prop_Data, "m_iDeaths") - 1);
//Give cash to players, 1hit = $10
SetEntProp(activator, Prop_Send, "m_iAccount", GetEntProp(activator, Prop_Send, "m_iAccount") + g_RewardMoney);
////Show HitMarker when hit the boss
//if (g_iStatus[activator] == 0 || g_iStatus[activator] == 2) {
// if (g_bUIManager)
// SendHudText(activator, g_CrosshairChannel, 5, -1.0, -1.0, {255, 0, 0, 50}, {255, 0, 0, 50}, 0, 0.1, 0.1, 0.1, 0.1, "◞ ◟\n◝ ◜");
// else {
// SetHudTextParamsEx(-1.0, -1.0, 0.1, {255, 0, 0, 50}, {255, 0, 0, 50}, 0, 0.1, 0.1, 0.1);
// ShowHudText(activator, g_CrosshairChannel, "◞ ◟\n◝ ◜");
// }
//}
//Show HitMarker to player who is spectating attacker
/*
for (new z = 1; z <= MaxClients; z++) {
if (IsClientInGame(z) && !IsPlayerAlive(z)) {
if (GetEntProp(z, Prop_Send, "m_iObserverMode") == 4) {
if (activator == GetEntPropEnt(z, Prop_Send, "m_hObserverTarget")) {
if (g_iStatus[z] == 0 || g_iStatus[z] == 2) {
SetHudTextParamsEx(-1.0, -1.0, 0.1, {255, 0, 0, 50}, {255, 0, 0, 50}, 0, 0.1, 0.1, 0.1);
ShowHudText(z, g_CrosshairChannel, "◞ ◟\n◝ ◜");
}
}
}
}
}
*/
}
}
if (g_MathCounter[i].BossHP < g_MaxLegalMathCounterHP && activator > 0 && activator <= MAXPLAYERS) {
PrintHP(activator, g_MathCounter[i].BossHP);
}
g_MathCounter[i].LastHPShow = g_MathCounter[i].BossHP;
}
g_MathCounter[i].LastHP = g_MathCounter[i].BossHP;
if (!g_MathCounter[i].IsSetDefaultInit && (
(g_MathCounter[i].HP_Mode == 1 && CurrentValue > g_MathCounter[i].LastValue) || (g_MathCounter[i].HP_Mode != 1 && CurrentValue < g_MathCounter[i].LastValue)
)) {
if (g_MathCounter[i].LastHPShow < 2 /* Some maps do not have HP_Init counter, so need to transfer HPMaxValue to HPinit */
|| g_MathCounter[i].LastAddTime > GetEngineTime() - 0.1 ) { //Some maps will recalculate BossHP when HPbar is subtracted (ze_dreamin, ze_copy, ze_grau, ze_gris etc)
if (g_MathCounter[i].HP_Mode == 1 && CurrentValue - 5 >= g_MathCounter[i].LastValue) {
g_MathCounter[i].HPInit = CurrentValue;
#if defined DEBUG
CPrintToChatAll("{blue}[BossHP-DEBUG] Set HP init: %d (HP Lastshow:%d Last HPadd interval:%.2f)", g_MathCounter[i].HPInit, g_MathCounter[i].LastHPShow, GetEngineTime() - g_MathCounter[i].LastAddTime); //debug
#endif
}
else if (g_MathCounter[i].HP_Mode != 1 && CurrentValue < g_MathCounter[i].LastValue)
{
g_MathCounter[i].HPInit = g_MathCounter[i].HP_Max;
#if defined DEBUG
CPrintToChatAll("{blue}[BossHP-DEBUG] Set HP init: %d (HP Lastshow:%d Last HPadd interval:%.2f)", g_MathCounter[i].HPInit, g_MathCounter[i].LastHPShow, GetEngineTime() - g_MathCounter[i].LastAddTime); //debug
#endif
}
}
g_MathCounter[i].LastAddTime = GetEngineTime();
}
g_MathCounter[i].LastValue = CurrentValue;
break;
}
for (int x = 0; x < g_MathCounter[i].HpGroupCount; x++) {
if (StrEqual(targetname, g_MathCounter_HPgroup[i][x].sName, false)) {
if (g_MathCounter_HPgroup[i][x].RunOut)
return;
g_MathCounter_HPgroup[i][x].HP = CurrentValue;
if (CurrentValue == 0)
g_MathCounter_HPgroup[i][x].RunOut = true;
g_MathCounter[i].BossHP = 0;
for (int z = 0; z < g_MathCounter[i].HpGroupCount; z++) {
g_MathCounter[i].BossHP += g_MathCounter_HPgroup[i][z].HP;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] HPgroup(%s)'s CurrentValue:%d", g_MathCounter_HPgroup[i][z].sName, g_MathCounter_HPgroup[i][z].HP); //debug
#endif
}
if (g_DisplayWhenHPAdded || g_MathCounter[i].BossHP < g_MathCounter[i].LastHP) { //Only display when BossHP is subtracted.
if (g_MathCounter[i].BossHP <= 1) { //in some maps like ze_Predator_ultimate, boss's math_counter MinValve is not 0 but 1.
g_MathCounter[i].LastChangeTime = GetEngineTime() - ( g_BossHpKeepTime - g_BossDieKeepTime ) ; // when BossHP hit 0, keep more 1s display time.
iLastBossEnt = -1;
g_MathCounter[i].BossHP = 0;
} else {
iLastBossEnt = entity;
g_MathCounter[i].LastChangeTime = GetEngineTime();
if (g_MathCounter[i].BossHP < g_MaxLegalMathCounterHP && activator > 0 && activator <= MAXPLAYERS) {
if (csgo)
CS_SetClientAssists(activator, CS_GetClientAssists(activator) + 1);
else
SetEntProp(activator, Prop_Data, "m_iDeaths", GetEntProp(activator, Prop_Data, "m_iDeaths") - 1);
//Give cash to players, 1hit = $10
SetEntProp(activator, Prop_Send, "m_iAccount", GetEntProp(activator, Prop_Send, "m_iAccount") + g_RewardMoney);
////Crosshair when hit the boss
//if (g_iStatus[activator] == 0 || g_iStatus[activator] == 2) {
// if (g_bUIManager)
// SendHudText(activator, g_CrosshairChannel, 5, -1.0, -1.0, {255, 0, 0, 50}, {255, 0, 0, 50}, 0, 0.1, 0.1, 0.1, 0.1, "◞ ◟\n◝ ◜");
// else {
// SetHudTextParamsEx(-1.0, -1.0, 0.1, {255, 0, 0, 50}, {255, 0, 0, 50}, 0, 0.1, 0.1, 0.1);
// ShowHudText(activator, g_CrosshairChannel, "◞ ◟\n◝ ◜");
// }
//}
}
}
if (g_MathCounter[i].BossHP < g_MaxLegalMathCounterHP && activator > 0 && activator <= MAXPLAYERS) {
PrintHP(activator, g_MathCounter[i].BossHP);
}
}
g_MathCounter[i].LastHP = g_MathCounter[i].BossHP;
break;
}
}
if (StrEqual(targetname, g_MathCounter[i].sHPBar, false)) {
if (g_MathCounter[i].HPBar_Mode == 1) {
g_MathCounter[i].Multiply = CurrentValue - g_MathCounter[i].HPBar_Min;
}
else if (g_MathCounter[i].HPBar_Mode == 2)
{
g_MathCounter[i].Multiply = g_MathCounter[i].HPBar_Max - CurrentValue;
}
g_MathCounter[i].IsSetDefaultMultiply = true;
#if defined DEBUG
CPrintToChatAll("{pink}[BossHP-DEBUG] Set multiply:%d (triggered by HPbar Counter:%s)", g_MathCounter[i].Multiply, targetname); //debug
#endif
}
if (StrEqual(targetname, g_MathCounter[i].sHPInit, false)) {
g_MathCounter[i].HPInit = CurrentValue;
g_MathCounter[i].IsSetDefaultInit = true;
#if defined DEBUG
CPrintToChatAll("{blue}[BossHP-DEBUG] Set HP init:%d (triggered by HPinit Counter:%s)", g_MathCounter[i].HPInit, targetname); //debug
#endif
}
}
}
//bhud function
if (g_bForceShowBossHP &&
LastShowBossHP + 3.0 < GetEngineTime() && // If BossHP was show in the past 3sec, block this function
(IsValidEntity(entity) || IsValidEdict(entity)) &&
activator > 0 && activator <= MAXPLAYERS) {
if (LastShootHitbox[activator] < GetEngineTime() - 0.1)
return; //if players didn't shoot to hitbox, block this function
int CurrentValue = RoundFloat(GetEntDataFloat(entity, FindDataMapInfo(entity, "m_OutValue")));
GetEntPropString(entity, Prop_Data, "m_iName", g_ClientLastShootBreakable[activator].sName, sizeof(Array_ClientLastShootBreakable::sName));
g_ClientLastShootBreakable[activator].EntityIndex = 0;
if (CurrentValue > 0) {
iLastBossEnt = entity;
PrintHP_Force(activator, 0, g_ClientLastShootBreakable[activator].sName, CurrentValue);
} else{
iLastBossEnt = -1;
//PrintHP_Force(activator, 0, g_ClientLastShootBreakable[activator].sName, 0);
}
}
}
public Action UserMessageHook_TextMsg(UserMsg msg_id, Handle pb, const int[] players, int playersNum, bool reliable, bool init) {
if (csgo) {
if (PbReadInt(pb, "msg_dst") != 4)
return Plugin_Continue;
for (int i; i < playersNum; i++) {
g_LastShowCenterText[players[i]] = GetEngineTime() + 2.0;
}
}
return Plugin_Continue;
}
public Action UserMessageHook_HintText(UserMsg msg_id, Handle pb, const int[] players, int playersNum, bool reliable, bool init) {
//<font color='#00FE00'>
if (csgo) {
char szBuffer[255];
PbReadString(pb, "text", szBuffer, sizeof(szBuffer));
if (StrContains(szBuffer, "HP") > -1) {
return Plugin_Continue;
}
for (int i; i< playersNum; i++) {
g_LastShowCenterText[players[i]] = GetEngineTime();
}
}
return Plugin_Continue;
}
char PrintText_Hint[255];
//char PrintText_HUD[255];
char CurrentBossName[32];
float CurrentTime;
int CurrentHP;
int MaxHP;
int CTcount;
int count;
//bhud function
void PrintHP_Force(int client, int entity, const char[] entityname, int hp) {
CurrentTime = GetEngineTime();
if ( (LastShootHitbox[client] > CurrentTime - 3.0 && LastForceShowBossHP + 0.1 < CurrentTime) || hp == 0 ) {
count = 0;
CTcount = 0;
LoopIngamePlayers(i) {
if (GetClientTeam(i) == CS_TEAM_CT) {
CTcount++;
if (LastShootHitbox[i] > CurrentTime - 7.0 && g_ClientLastShootBreakable[i].EntityIndex == entity && StrEqual(g_ClientLastShootBreakable[i].sName, entityname)) {
count++;
}
}
}
char sBuffer[MAX_BREAKABLE_NAME_LENGTH];
strcopy(sBuffer, sizeof(sBuffer), entityname);
if (g_bUpperCaseInForceEnable) {
int and = -1;
if ((and = FindCharInString(sBuffer, '&', true)) > 0)
sBuffer[and] = '\0';
ReplaceString(sBuffer, sizeof(sBuffer), "_", " ");
for (int x = 0; x < strlen(sBuffer); x++) {
if (IsCharLower(sBuffer[x]))
sBuffer[x] = CharToUpper(sBuffer[x]);
}
}
if (count > CTcount / 2) {
if (csgo) {
LoopIngamePlayers(i) {
if (g_iStatus[i] == 0 || g_iStatus[i] == 1)
PrintHintText(i, "%s: <font size='26' color='#FF8C00'>%d</font>", sBuffer, hp);
}
} else {
LoopIngamePlayers(i) {
if (g_iStatus[i] == 0 || g_iStatus[i] == 1)
PrintHintText(i, "%s: %d", sBuffer, hp);
}
}
} else {
LoopIngamePlayers(i) {
if (g_iStatus[i] == 0 || g_iStatus[i] == 1) {
if (LastShootHitbox[i] > CurrentTime - 7.0 && g_ClientLastShootBreakable[i].EntityIndex == entity && StrEqual(g_ClientLastShootBreakable[i].sName, entityname)) {
if (csgo) {
PrintHintText(i, "%s: <font size='26' color='#FF8C00'>%d</font>", sBuffer, hp);
} else {
PrintHintText(i, "%s: %d", sBuffer, hp);
}
}
}
}
}
LastForceShowBossHP = CurrentTime;
}
}
void PrintHP(int client, int hp) {
CurrentTime = GetEngineTime();
if ( (LastShootHitbox[client] > CurrentTime - 3.0 && LastShowBossHP + 0.1 < CurrentTime) || hp == 0 || g_DisplayWhenHPAdded ) {
g_BossDisplay.BossName.Clear();
g_BossDisplay.HP.Clear();
g_BossDisplay.MaxHP.Clear();
PrintText_Hint = "";
//PrintText_HUD = "";
for (int i = 0; i < g_Count.Math_Counter; i++) {
if (g_MathCounter[i].BossHP > g_MathCounter[i].MaxBossHP)
g_MathCounter[i].MaxBossHP = g_MathCounter[i].BossHP;
if (g_MathCounter[i].LastChangeTime + g_BossHpKeepTime > CurrentTime) {
g_BossDisplay.BossName.PushString(g_MathCounter[i].BossName);
g_BossDisplay.HP.Push(g_MathCounter[i].BossHP);
g_BossDisplay.MaxHP.Push(g_MathCounter[i].MaxBossHP);
}
}
for (int i = 0; i < g_Count.Breakable; i++) {
if (g_Breakable[i].BossHP > g_Breakable[i].MaxBossHP)
g_Breakable[i].MaxBossHP = g_Breakable[i].BossHP;
if (g_Breakable[i].LastChangeTime + g_BossHpKeepTime > CurrentTime) {
g_BossDisplay.BossName.PushString(g_Breakable[i].BossName);
g_BossDisplay.HP.Push(g_Breakable[i].BossHP);
g_BossDisplay.MaxHP.Push(g_Breakable[i].MaxBossHP);
}
}
for (int i = 0; i < g_BossDisplay.HP.Length; i++) {
g_BossDisplay.BossName.GetString(i, CurrentBossName, sizeof(CurrentBossName));
CurrentHP = g_BossDisplay.HP.Get(i);
MaxHP = g_BossDisplay.MaxHP.Get(i);
if (csgo) {
float fCurrentRatio = float(CurrentHP) / float(MaxHP);
if (fCurrentRatio < 0.2)
HPcolor = "FF0000"; //red
else if (fCurrentRatio < 0.4)
HPcolor = "FFFF00"; //yellow
else
HPcolor = "00FF00"; //green
if (g_BossDisplay.HP.Length == 1) { //Single BossHP display style
int iBar = (hp == 0) ? 0 : RoundToCeil(fCurrentRatio * 20.0);
if (iBar > 20) iBar = 20;
char sBar[64], sBlank[64];
for (int j = 0; j < iBar - 1; j++)
StrCat(sBar, sizeof(sBar), ""); //░▒▓█
for (int k = 0; k < 20 - iBar; k++)
StrCat(sBlank, sizeof(sBlank), "");
//<u>%s</u>
Format(PrintText_Hint, sizeof(PrintText_Hint), "►%s◄ <font color='#%s'><span class='fontSize-xl'> HP: %d</span>\n%s%s</font><font color='#000000'>%s%s</font>\n", CurrentBossName, HPcolor, CurrentHP, sBar, CurrentHP <= 0 ? "" : (CurrentHP < MaxHP ? "" : ""), CurrentHP <= 0 ? "" : "", sBlank);
}
else if (g_BossDisplay.HP.Length <= 3) { //Mult BossHP display style
Format(PrintText_Hint, sizeof(PrintText_Hint), "%s%s: <font color='#%s'>%dHP</font>\n", PrintText_Hint, CurrentBossName, HPcolor, CurrentHP);
}
else // more than 3 BossHP display style
{
Format(PrintText_Hint, sizeof(PrintText_Hint), "%s%s: <font color='#%s'>%dHP</font>%s", PrintText_Hint, CurrentBossName, HPcolor, CurrentHP, i % 2 ? "\n" : " ");
}
} else {
Format(PrintText_Hint, sizeof(PrintText_Hint), "%s%s: %d%s", PrintText_Hint, CurrentBossName, CurrentHP, i == g_BossDisplay.HP.Length - 1 ? "" : "\n");
}
//Format(PrintText_HUD, sizeof(PrintText_HUD), "%s%s: %d%s", PrintText_HUD, CurrentBossName, CurrentHP, "HP\n");
}
LoopIngamePlayers(i) {
if (g_iStatus[i] == 0 || g_iStatus[i] == 1) {
if (CurrentTime - 3.0 < g_LastShowCenterText[i]) {
//SetHudTextParamsEx(-1.0, 0.66 - 0.03 * (g_BossDisplay.HP.Length - 1), 1.0, {255, 0, 255, 230}, {255, 0, 255, 230}, 1, 0.0, 0.1, 0.1);
//ShowHudText(i, 1, "%s", PrintText_HUD);
} else {
PrintHintText(i, "%s", PrintText_Hint);
}
}
}
LastShowBossHP = CurrentTime;
if (LastShowTopDamage + 1.0 < CurrentTime) {
if (g_bShowTopDamageDuringBOSS) {
ShowBossTopDamage(0, -1.0, 0.76);
LastShowTopDamage = CurrentTime;
} else if (g_bBossBeatenShowBossDamageRank && hp == 0) {
ShowBossTopDamage(0, -1.0, 0.76);
LastShowTopDamage = CurrentTime;
}
}
}
}
public Action DEBUG_PrintVar(int client, int args) {
if (!client)
return Plugin_Handled;
ReplyToCommand(client, "g_bForceShowBossHP: %b", g_bForceShowBossHP);
ReplyToCommand(client, "g_BossHpKeepTime: %.1f", g_BossHpKeepTime);
ReplyToCommand(client, "g_BossDieKeepTime: %.1f", g_BossDieKeepTime);
ReplyToCommand(client, "g_MaxLegalBreakableHP: %d", g_MaxLegalBreakableHP);
ReplyToCommand(client, "g_MaxLegalMathCounterHP: %d", g_MaxLegalMathCounterHP);
ReplyToCommand(client, "g_DisplayWhenHPAdded: %b", g_DisplayWhenHPAdded);
ReplyToCommand(client, "g_LastShowCenterText: %.1f", g_LastShowCenterText);
ReplyToCommand(client, "GetEngineTime(): %.2f", GetEngineTime());
return Plugin_Handled;
}
public void OnEntityCreated(int entity, const char[] classname) {
if (!IsConfigLoad) return;
if (StrEqual(classname, "math_counter", false)) {
if (hAcceptInput != INVALID_HANDLE)
DHookEntity(hAcceptInput, false, entity);
RequestFrame(Timer_InitMathCounterInfo, entity);
}
}
void Timer_InitMathCounterInfo(int entity) {
if (!IsValidEntity(entity) && !IsValidEdict(entity))
return;
char EntityName[64];
GetEntPropString(entity, Prop_Data, "m_iName", EntityName, sizeof(EntityName));
for (int i = 0; i < g_Count.Math_Counter; i++) {
if (StrEqual(EntityName, g_MathCounter[i].sHP, false)) {
g_MathCounter[i].HP_Min = RoundFloat(GetEntPropFloat(entity, Prop_Data, "m_flMin"));
g_MathCounter[i].HP_Max = RoundFloat(GetEntPropFloat(entity, Prop_Data, "m_flMax"));
g_MathCounter[i].HP_StartValue = RoundFloat(GetEntDataFloat(entity, FindDataMapInfo(entity, "m_OutValue")));
int iOnHitMinCount = GetOutputCount(entity, "m_OnHitMin");
int iOnHitMaxCount = GetOutputCount(entity, "m_OnHitMax");
g_MathCounter[i].HP_Mode = iOnHitMaxCount > iOnHitMinCount ? 2 : 1;
break;
}
for (int x = 0; x < g_MathCounter[i].HpGroupCount; x++) {
if (StrEqual(EntityName, g_MathCounter_HPgroup[i][x].sName, false)) {
g_MathCounter_HPgroup[i][x].Min = RoundFloat(GetEntPropFloat(entity, Prop_Data, "m_flMin"));
g_MathCounter_HPgroup[i][x].Max = RoundFloat(GetEntPropFloat(entity, Prop_Data, "m_flMax"));
g_MathCounter_HPgroup[i][x].HP = RoundFloat(GetEntDataFloat(entity, FindDataMapInfo(entity, "m_OutValue")));
g_MathCounter_HPgroup[i][x].StartValue = RoundFloat(GetEntDataFloat(entity, FindDataMapInfo(entity, "m_OutValue")));
g_MathCounter_HPgroup[i][x].StartDisabled = view_as<bool>(GetEntProp(entity, Prop_Data, "m_bDisabled"));
g_MathCounter_HPgroup[i][x].Stats = !g_MathCounter_HPgroup[i][x].StartDisabled;
break;
}
}
if (StrEqual(EntityName, g_MathCounter[i].sHPBar, false)) {
g_MathCounter[i].HPBar_Min = RoundFloat(GetEntPropFloat(entity, Prop_Data, "m_flMin"));
g_MathCounter[i].HPBar_Max = RoundFloat(GetEntPropFloat(entity, Prop_Data, "m_flMax"));
g_MathCounter[i].HPBar_StartValue = RoundFloat(GetEntDataFloat(entity, FindDataMapInfo(entity, "m_OutValue")));
int iOnHitMinCount = GetOutputCount(entity, "m_OnHitMin");
int iOnHitMaxCount = GetOutputCount(entity, "m_OnHitMax");
g_MathCounter[i].HPBar_Mode = iOnHitMaxCount > iOnHitMinCount ? 2 : 1;
break;
}
if (StrEqual(EntityName, g_MathCounter[i].sHPInit, false)) {
g_MathCounter[i].HPInit_Min = RoundFloat(GetEntPropFloat(entity, Prop_Data, "m_flMin"));
g_MathCounter[i].HPInit_Max = RoundFloat(GetEntPropFloat(entity, Prop_Data, "m_flMax"));
g_MathCounter[i].HPInit_StartValue = RoundFloat(GetEntDataFloat(entity, FindDataMapInfo(entity, "m_OutValue")));
break;
}
}
#if defined DEBUG
if (StrContains(EntityName, "behemoth_", false) > -1) {
PrintToChatAll("EntityName: %s", EntityName);
PrintToChatAll("m_bHitMax: %d", GetEntProp(entity, Prop_Data, "m_bHitMax"));
PrintToChatAll("m_bHitMin: %d", GetEntProp(entity, Prop_Data, "m_bHitMin"));
PrintToChatAll("m_flMin: %d", RoundFloat(GetEntPropFloat(entity, Prop_Data, "m_flMin")));
PrintToChatAll("m_flMax: %d", RoundFloat(GetEntPropFloat(entity, Prop_Data, "m_flMax")));
PrintToChatAll("m_bDisabled: %d", GetEntProp(entity, Prop_Data, "m_bDisabled"));
PrintToChatAll("m_OutValue: %d", RoundFloat(GetEntDataFloat(entity, FindDataMapInfo(entity, "m_OutValue"))));
PrintToChatAll("--");
}
#endif
}
public Action DEBUG_GetArrayInfo(int client, int args) {
if (args != 1)
return Plugin_Handled;
char Arg1[32];
GetCmdArg(1, Arg1, 32);
for (int i = 0; i < g_Count.Math_Counter; i++) {
if (StrEqual(Arg1, g_MathCounter[i].sHP, false)) {
ReplyToCommand(client, "Type: g_MathCounter[i].sHP");
ReplyToCommand(client, "Min:%d", g_MathCounter[i].HP_Min);
ReplyToCommand(client, "Max:%d", g_MathCounter[i].HP_Max);
ReplyToCommand(client, "StartValue:%d", g_MathCounter[i].HP_StartValue);
break;
}
for (int x = 0; x < g_MathCounter[i].HpGroupCount; x++) {
if (StrEqual(Arg1, g_MathCounter_HPgroup[i][x].sName, false)) {
ReplyToCommand(client, "Type: g_MathCounter_HPgroup[i][x].sName");
ReplyToCommand(client, "Min:%d", g_MathCounter_HPgroup[i][x].Min);
ReplyToCommand(client, "Max:%d", g_MathCounter_HPgroup[i][x].Max);
ReplyToCommand(client, "HP:%d", g_MathCounter_HPgroup[i][x].HP);
ReplyToCommand(client, "StartValue:%d", g_MathCounter_HPgroup[i][x].StartValue);
ReplyToCommand(client, "StartDisabled:%b", g_MathCounter_HPgroup[i][x].StartDisabled);
ReplyToCommand(client, "Stats:%d", g_MathCounter_HPgroup[i][x].Stats);
break;
}
}
if (StrEqual(Arg1, g_MathCounter[i].sHPBar, false)) {
ReplyToCommand(client, "Type: g_MathCounter[i].sHPBar");
ReplyToCommand(client, "Min:%d", g_MathCounter[i].HPBar_Min);
ReplyToCommand(client, "Max:%d", g_MathCounter[i].HPBar_Max);
ReplyToCommand(client, "StartValue:%b", g_MathCounter[i].HPBar_StartValue);
break;
}
if (StrEqual(Arg1, g_MathCounter[i].sHPInit, false)) {
ReplyToCommand(client, "Type: g_MathCounter[i].sHPInit");
ReplyToCommand(client, "Min:%d", g_MathCounter[i].HPInit_Min);
ReplyToCommand(client, "Max:%d", g_MathCounter[i].HPInit_Max);
ReplyToCommand(client, "StartValue:%b", g_MathCounter[i].HPInit_StartValue);
break;
}
}
return Plugin_Handled;
}
public MRESReturn AcceptInput(int entity, Handle hReturn, Handle hParams) {
if (!IsValidEntity(entity))
return MRES_Ignored;
char eEntityName[64], eCommand[16], eParam[16];
GetEntPropString(entity, Prop_Data, "m_iName", eEntityName, 64);
DHookGetParamString(hParams, 1, eCommand, 16);
int type = -1, Param = 0;
type = DHookGetParamObjectPtrVar(hParams, 4, 16, ObjectValueType_Int);
if (type == 1)
Param = DHookGetParamObjectPtrVar(hParams, 4, 0, ObjectValueType_Int);
else if (type == 2) {
DHookGetParamObjectPtrString(hParams, 4, 0, ObjectValueType_String, eParam, 16);
StringToIntEx(eParam, Param);
}
if (StrEqual(eCommand, "SetValueNoFire", false)) {
for (int i = 0; i < g_Count.Math_Counter; i++) {
if (StrEqual(eEntityName, g_MathCounter[i].sHPBar, false)) {
if (g_MathCounter[i].HPBar_Mode == 1)
g_MathCounter[i].Multiply = Param - g_MathCounter[i].HPBar_Min;
else if (g_MathCounter[i].HPBar_Mode == 2)
g_MathCounter[i].Multiply = g_MathCounter[i].HPBar_Max - Param;
g_MathCounter[i].IsSetDefaultMultiply = true;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] (SetValueNoFire)Set multiply:%d (triggered by HPbar Counter:%s)", g_MathCounter[i].Multiply, eEntityName); //debug
#endif
break;
}
if (StrEqual(eEntityName, g_MathCounter[i].sHPInit, false)) {
g_MathCounter[i].HPInit = Param;
g_MathCounter[i].IsSetDefaultInit = true;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] (SetValueNoFire)Set HP init:%d (triggered by HPinit Counter:%s)", g_MathCounter[i].HPInit, eEntityName); //debug
#endif
break;
}
}
}
else if (StrEqual(eCommand, "Add", false)) {
for (int i = 0; i < g_Count.Math_Counter; i++) {
for (int x = 0; x < g_MathCounter[i].HpGroupCount; x++) {
if (StrEqual(eEntityName, g_MathCounter_HPgroup[i][x].sName, false)) {
if (g_MathCounter_HPgroup[i][x].Kill || g_MathCounter_HPgroup[i][x].RunOut || g_MathCounter_HPgroup[i][x].Stats)
return MRES_Ignored;
if (g_MathCounter_HPgroup[i][x].LastAddTime < GetEngineTime() - 1.0) {
g_MathCounter_HPgroup[i][x].HP = g_MathCounter_HPgroup[i][x].StartValue;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] Set Default HPgroup(%s):%d CurrentValue:%d", eEntityName, g_MathCounter_HPgroup[i][x].StartValue, g_MathCounter_HPgroup[i][x].HP); //debug
#endif
}
g_MathCounter_HPgroup[i][x].HP += Param;
g_MathCounter_HPgroup[i][x].LastAddTime = GetEngineTime();
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] Add to HPgroup(%s):%d CurrentValue:%d", eEntityName, Param, g_MathCounter_HPgroup[i][x].HP); //debug
#endif
break;
}
}
}
}
else if (StrEqual(eCommand, "SetHitMax", false)) {
for (int i = 0; i < g_Count.Math_Counter; i++) {
if (StrEqual(eEntityName, g_MathCounter[i].sHP, false)) {
g_MathCounter[i].HP_Max = Param;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] (SetHitMax)Set HP Max:%d", Param); //debug
#endif
break;
}
if (StrEqual(eEntityName, g_MathCounter[i].sHPBar, false)) {
g_MathCounter[i].HPBar_Max = Param;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] (SetHitMax)Set HPbar Max:%d", Param); //debug
#endif
break;
}
if (StrEqual(eEntityName, g_MathCounter[i].sHPInit, false)) {
g_MathCounter[i].HPInit_Max = Param;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] (SetHitMax)Set HPInit Max:%d", Param); //debug
#endif
break;
}
for (int x = 0; x < g_MathCounter[i].HpGroupCount; x++) {
if (StrEqual(eEntityName, g_MathCounter_HPgroup[i][x].sName, false)) {
g_MathCounter_HPgroup[i][x].Max = Param;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] (SetHitMax)Set HPgroup(%d) Max:%d", x, Param); //debug
#endif
break;
}
}
}
}
else if (StrEqual(eCommand, "SetHitMin", false)) {
for (int i = 0; i < g_Count.Math_Counter; i++) {
if (StrEqual(eEntityName, g_MathCounter[i].sHP, false)) {
g_MathCounter[i].HP_Min = Param;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] (SetHitMin)Set HP Min:%d", Param); //debug
#endif
break;
}
if (StrEqual(eEntityName, g_MathCounter[i].sHPBar, false)) {
g_MathCounter[i].HPBar_Min = Param;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] (SetHitMin)Set HPbar Min:%d", Param); //debug
#endif
break;
}
if (StrEqual(eEntityName, g_MathCounter[i].sHPInit, false)) {
g_MathCounter[i].HPInit_Min = Param;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] (SetHitMin)Set HPInit Min:%d", Param); //debug
#endif
break;
}
for (int x = 0; x < g_MathCounter[i].HpGroupCount; x++) {
if (StrEqual(eEntityName, g_MathCounter_HPgroup[i][x].sName, false)) {
g_MathCounter_HPgroup[i][x].Min = Param;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] (SetHitMin)Set HPgroup(%d) Min:%d", x, Param); //debug
#endif
break;
}
}
}
}
//else if (StrEqual(eCommand, "SetMaxValueNoFire", false)) {} //(New with Portal 2, Unknown if it's exist in CSGO or CSS)
//else if (StrEqual(eCommand, "SetMinValueNoFire", false)) {} //(New with Portal 2, Unknown if it's exist in CSGO or CSS)
else if (StrEqual(eCommand, "Enable", false)) {
for (int i = 0; i < g_Count.Math_Counter; i++) {
for (int x = 0; x < g_MathCounter[i].HpGroupCount; x++) {
if (StrEqual(eEntityName, g_MathCounter_HPgroup[i][x].sName, false)) {
g_MathCounter_HPgroup[i][x].Stats = true;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] Enable HPgroup: %s", eEntityName); //debug
#endif
break;
}
}
}
}
else if (StrEqual(eCommand, "Disable", false)) {
for (int i = 0; i < g_Count.Math_Counter; i++) {
for (int x = 0; x < g_MathCounter[i].HpGroupCount; x++) {
if (StrEqual(eEntityName, g_MathCounter_HPgroup[i][x].sName, false)) {
g_MathCounter_HPgroup[i][x].Stats = false;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] Disabled(kill) HPgroup: %s", eEntityName); //debug
#endif
break;
}
}
}
}
else if (StrEqual(eCommand, "Kill", false)) {
for (int i = 0; i < g_Count.Math_Counter; i++) {
for (int x = 0; x < g_MathCounter[i].HpGroupCount; x++) {
if (StrEqual(eEntityName, g_MathCounter_HPgroup[i][x].sName, false)) {
g_MathCounter_HPgroup[i][x].Stats = false;
g_MathCounter_HPgroup[i][x].Kill = true;
#if defined DEBUG
CPrintToChatAll("{purple}[BossHP-DEBUG] Disabled HPgroup: %s", eEntityName); //debug
#endif
break;
}
}
}
}
return MRES_Ignored;
}
stock void q_sort(int[] numbers, int left, int right, int[] subarr) {
int pivot, l_hold, r_hold, subpiv;
l_hold = left;
r_hold = right;
pivot = numbers[left];
subpiv = subarr[left];
while (left < right) {
while ((numbers[right] >= pivot) && (left < right))
right--;
if (left != right) {
numbers[left] = numbers[right];
subarr[left] = subarr[right];
left++;
}
while ((numbers[left] <= pivot) && (left < right))
left++;
if (left != right) {
numbers[right] = numbers[left];
subarr[right] = subarr[left];
right--;
}
}
numbers[left] = pivot;
subarr[left] = subpiv;
pivot = left;
left = l_hold;
right = r_hold;
if (left < pivot)
q_sort(numbers, left, pivot - 1, subarr);
if (right > pivot)
q_sort(numbers, pivot + 1, right, subarr);
}
stock void QuickSort(int[] arr, int size, int[] subarr) {
q_sort(arr, 0, size - 1, subarr);
}
void ShowBossTopDamage(int client, const float x = -1.0, const float y = 0.26) {
int[] damagelist = new int[MaxClients+1];
int[] playerlist = new int[MaxClients+1];
for (int i = 1; i < MaxClients; i++) {
if (IsClientInGame(i)) {
damagelist[i] = csgo ? CS_GetClientAssists(i) : GetEntProp(i, Prop_Data, "m_iDeaths") * -1;
playerlist[i] = i;
}
}
QuickSort(damagelist, MaxClients+1, playerlist);
char damagelist_text[255];
int rank = 1;
for (int j = MaxClients; j >= 0; j--, rank++) {
if (rank > 5 || damagelist[j] < 1 || playerlist[j] < 1) break;
Format(damagelist_text, sizeof(damagelist_text), "%s\n%i. %N: %d HITs", damagelist_text, rank, playerlist[j], damagelist[j]);
}
if (damagelist_text[0] != '\0') {
if (g_bUIManager) {
//if (client == 0) {
// SendHudTextToAll(3, 5, x, y, {255, 201, 14, 230}, _, 1, 0.3, 2.0, 10.0, 0.0, "%t%s", "DamageRank_Title", damagelist_text);
//}
//else {
// SendHudText(client, 3, 5, x, y, {255, 201, 14, 230}, _, 1, 0.3, 2.0, 10.0, 0.0, "%t%s", "DamageRank_Title", damagelist_text);
//}
} else {
SetHudTextParams(x, y, 10.0, 255, 201, 14, 230, 1, 0.0, 0.3, 2.0);
char text[255];
if (client == 0) {
LoopIngamePlayers(i) {
FormatEx(text, sizeof(text), "%T", "DamageRank_Title", i);
Format(text, sizeof(text), "%s%s", text, damagelist_text);
ShowHudText(i, 3, "%s", text);
}
}
else {
FormatEx(text, sizeof(text), "%T", "DamageRank_Title", client);
Format(text, sizeof(text), "%s%s", text, damagelist_text);
ShowHudText(client, 3, "%s", text);
}
}
}
}