#pragma semicolon 1 #pragma newdecls required #include #include #include #include #include #include #include #include #undef REQUIRE_PLUGIN #tryinclude #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 OnRoundEnd", _, true, 0.0, true, 1.0); g_bRoundEndShowBossDamageRank = hCVAR_RoundEndShowBossDamageRank.BoolValue; hCVAR_RoundEndShowBossDamageRank.AddChangeHook(OnConVarChange); hCVAR_ShowTopDamageDuringBOSS = CreateConVar("BossHP_ShowTopDamageDuringBOSS", "0", "Show 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 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(StringToInt(newValue)); else if (hCvar == hCVAR_UpperCaseInForceEnable) g_bUpperCaseInForceEnable = view_as(StringToInt(newValue)); else if (hCvar == hCVAR_RoundEndShowBossDamageRank) g_bRoundEndShowBossDamageRank = view_as(StringToInt(newValue)); else if (hCvar == hCVAR_ShowTopDamageDuringBOSS) g_bShowTopDamageDuringBOSS = view_as(StringToInt(newValue)); else if (hCvar == hCVAR_BossBeatenShowBossDamageRank) g_bBossBeatenShowBossDamageRank = view_as(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(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 "); 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(tempNum)); tempNum = kv.GetNum("ForceEnableUpperCase", 1); hCVAR_UpperCaseInForceEnable.SetBool(view_as(tempNum)); tempNum = kv.GetNum("RoundEndShowTopDamage", 0); hCVAR_RoundEndShowBossDamageRank.SetBool(view_as(tempNum)); tempNum = kv.GetNum("ShowTopDamageDuringBOSS", 0); hCVAR_ShowTopDamageDuringBOSS.SetBool(view_as(tempNum)); tempNum = kv.GetNum("BossBeatenShowTopDamage", 1); hCVAR_BossBeatenShowBossDamageRank.SetBool(view_as(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(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) { // 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: %d", 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: %d", 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), "░"); //%s Format(PrintText_Hint, sizeof(PrintText_Hint), "►%s◄ HP: %d\n%s%s%s%s\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: %dHP\n", PrintText_Hint, CurrentBossName, HPcolor, CurrentHP); } else // more than 3 BossHP display style { Format(PrintText_Hint, sizeof(PrintText_Hint), "%s%s: %dHP%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(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); } } } }