diff --git a/BossHP/scripting/BossHP.sp b/BossHP/scripting/BossHP.sp index a49e9224..9703fc4a 100644 --- a/BossHP/scripting/BossHP.sp +++ b/BossHP/scripting/BossHP.sp @@ -191,6 +191,19 @@ public void OnMapStart() } } + char sHurtTrigger[64 * 2]; + int iHurtTriggerDelim; + KvConfig.GetString("hurttrigger", sHurtTrigger, sizeof(sHurtTrigger)); + if(sHurtTrigger[0]) + { + if((iHurtTriggerDelim = FindCharInString(sHurtTrigger, ':')) == -1) + { + LogError("Delimiter ':' not found in \"hurttrigger\"(%s) in \"%s\"", sHurtTrigger, sSection); + continue; + } + sHurtTrigger[iHurtTriggerDelim] = 0; + } + bool bMultiTrigger = view_as(KvConfig.GetNum("multitrigger", 0)); bool bNameFixup = view_as(KvConfig.GetNum("namefixup", 0)); int iTimeout = KvConfig.GetNum("timeout", -1); @@ -288,6 +301,12 @@ public void OnMapStart() Config.fKillTriggerDelay = fKillTriggerDelay; } + if(sHurtTrigger[0]) + { + Config.SetHurtTrigger(sHurtTrigger); + Config.SetHurtOutput(sHurtTrigger[iHurtTriggerDelim + 1]); + } + g_aConfig.Push(Config); } while(KvConfig.GotoNextKey(false)); @@ -433,6 +452,31 @@ public void OnEntitySpawned(int entity) LogMessage("Hooked killtrigger %s:%s", sKillTrigger, sKillOutput); } + + char sHurtTrigger[64]; + Config.GetHurtTrigger(sHurtTrigger, sizeof(sHurtTrigger)); + + int iHurtTriggerHammerID = -1; + if(sHurtTrigger[0] == '#') + iHurtTriggerHammerID = StringToInt(sHurtTrigger[1]); + + if((iHurtTriggerHammerID == -1 && sHurtTrigger[0] && StrEqual(sTargetname, sHurtTrigger)) || iHurtTriggerHammerID == iHammerID) + { + char sHurtOutput[64]; + Config.GetHurtOutput(sHurtOutput, sizeof(sHurtOutput)); + + if(StrEqual(sHurtOutput, "OnTakeDamage")) + { + SDKHook(entity, SDKHook_OnTakeDamagePost, OnTakeDamagePostHurt); + } + else + { + bool Once = !Config.bMultiTrigger; + HookSingleEntityOutput(entity, sHurtOutput, OnEntityOutputHurt, Once); + } + + LogMessage("Hooked hurttrigger %s:%s", sHurtTrigger, sHurtOutput); + } } } @@ -443,7 +487,7 @@ void OnTrigger(int entity, const char[] output, SDKHookType HookType = view_as(-1)) +{ + char sTargetname[64]; + GetEntPropString(entity, Prop_Data, "m_iName", sTargetname, sizeof(sTargetname)); + + int iHammerID = GetEntProp(entity, Prop_Data, "m_iHammerID"); + + int iTemplateNum = -1; + int iTemplateLoc = FindCharInString(sTargetname, '&', true); + if(iTemplateLoc != -1) + { + iTemplateNum = StringToInt(sTargetname[iTemplateLoc + 1]); + sTargetname[iTemplateLoc] = 0; + } + + for(int i = 0; i < g_aConfig.Length; i++) + { + CConfig Config = g_aConfig.Get(i); + + char sHurtTrigger[64]; + Config.GetHurtTrigger(sHurtTrigger, sizeof(sHurtTrigger)); + + if(!sHurtTrigger[0]) + continue; + + int iHurtTriggerHammerID = -1; + if(sHurtTrigger[0] == '#') + { + iHurtTriggerHammerID = StringToInt(sHurtTrigger[1]); + + if(iHurtTriggerHammerID != iHammerID) + continue; + } + else if(!sTargetname[0] || !StrEqual(sTargetname, sHurtTrigger)) + continue; + + char sHurtOutput[64]; + Config.GetHurtOutput(sHurtOutput, sizeof(sHurtOutput)); + + if(!StrEqual(output, sHurtOutput)) + continue; + + if(iHurtTriggerHammerID == -1) + LogMessage("Triggered hurt boss %s(%d) from output %s", sTargetname, entity, output); + else + LogMessage("Triggered hurt boss #%d(%d) from output %s", iHurtTriggerHammerID, entity, output); + + if(HookType != view_as(-1) && !Config.bMultiTrigger) + { + if(HookType == SDKHook_OnTakeDamagePost) + SDKUnhook(entity, SDKHook_OnTakeDamagePost, OnTakeDamagePostHurt); + } + + + + + + } +} + public void OnEnvEntityMakerEntitySpawned(const char[] output, int caller, int activator, float delay) { if(!g_aConfig) @@ -724,6 +828,11 @@ public void OnEntityOutputKill(const char[] output, int caller, int activator, f OnKillTrigger(caller, output); } +public void OnEntityOutputHurt(const char[] output, int caller, int activator, float delay) +{ + OnHurtTrigger(activator, caller, output); +} + public void OnTakeDamagePost(int victim, int attacker, int inflictor, float damage, int damagetype) { OnTrigger(victim, "OnTakeDamage", SDKHook_OnTakeDamagePost); @@ -739,6 +848,11 @@ public void OnTakeDamagePostKill(int victim, int attacker, int inflictor, float OnKillTrigger(victim, "OnTakeDamage", SDKHook_OnTakeDamagePost); } +public void OnTakeDamagePostHurt(int victim, int attacker, int inflictor, float damage, int damagetype) +{ + OnHurtTrigger(attacker, victim, "OnTakeDamage", SDKHook_OnTakeDamagePost); +} + public void OnGameFrame() { if(!g_aBoss) @@ -1051,7 +1165,8 @@ bool BossInit(CBoss _Boss) } else { - HookSingleEntityOutput(entity, sShowOutput, OnEntityOutputShow, true); + bool Once = !_Config.bMultiTrigger; + HookSingleEntityOutput(entity, sShowOutput, OnEntityOutputShow, Once); } LogMessage("Hooked showtrigger %s:%s", sShowTrigger, sShowOutput); @@ -1077,12 +1192,40 @@ bool BossInit(CBoss _Boss) } else { - HookSingleEntityOutput(entity, sKillOutput, OnEntityOutputKill, true); + bool Once = !_Config.bMultiTrigger; + HookSingleEntityOutput(entity, sKillOutput, OnEntityOutputKill, Once); } LogMessage("Hooked killtrigger %s:%s", sKillTrigger, sKillOutput); } } + + char sHurtTrigger[64]; + _Config.GetHurtTrigger(sHurtTrigger, sizeof(sHurtTrigger)); + + if(sHurtTrigger[0]) + { + Format(sHurtTrigger, sizeof(sHurtTrigger), "%s&%04d", sHurtTrigger, iTemplateNum); + + char sHurtOutput[64]; + _Config.GetHurtOutput(sHurtOutput, sizeof(sHurtOutput)); + + int entity = INVALID_ENT_REFERENCE; + while((entity = FindEntityByTargetname(entity, sHurtTrigger)) != INVALID_ENT_REFERENCE) + { + if(StrEqual(sHurtOutput, "OnTakeDamage")) + { + SDKHook(entity, SDKHook_OnTakeDamagePost, OnTakeDamagePostHurt); + } + else + { + bool Once = !_Config.bMultiTrigger; + HookSingleEntityOutput(entity, sHurtOutput, OnEntityOutputHurt, Once); + } + + LogMessage("Hooked hurttrigger %s:%s", sHurtTrigger, sHurtOutput); + } + } } char sBoss[64]; diff --git a/BossHP/scripting/CConfig.inc b/BossHP/scripting/CConfig.inc index b2079793..03013f5e 100644 --- a/BossHP/scripting/CConfig.inc +++ b/BossHP/scripting/CConfig.inc @@ -28,6 +28,8 @@ methodmap CConfig < Basic myclass.SetString("sKillTrigger", ""); myclass.SetString("sKillOutput", ""); myclass.SetFloat("fKillTriggerDelay", 0.0); + myclass.SetString("sHurtTrigger", ""); + myclass.SetString("sHurtOutput", ""); myclass.SetBool("bMultiTrigger", false); myclass.SetBool("bNameFixup", false); myclass.SetInt("iTimeout", -1); @@ -153,6 +155,26 @@ methodmap CConfig < Basic } } + public bool GetHurtTrigger(char[] buffer, int length) + { + return this.GetString("sHurtTrigger", buffer, length); + } + + public void SetHurtTrigger(const char[] buffer) + { + this.SetString("sHurtTrigger", buffer); + } + + public bool GetHurtOutput(char[] buffer, int length) + { + return this.GetString("sHurtOutput", buffer, length); + } + + public void SetHurtOutput(const char[] buffer) + { + this.SetString("sHurtOutput", buffer); + } + property bool bMultiTrigger { public get() @@ -189,9 +211,6 @@ methodmap CConfig < Basic } } - - - property bool IsBreakable { public get() { return (this.iMethod == eConfigMethod_Breakable);