sm-plugins-csgo/BossHP/scripting/BossHP.sp

1680 lines
60 KiB
SourcePawn
Raw Normal View History

2020-03-25 19:04:16 +01:00
#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);
}
}
}
}