1680 lines
60 KiB
SourcePawn
1680 lines
60 KiB
SourcePawn
#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);
|
||
}
|
||
}
|
||
}
|
||
}
|