From e8959b884e918b43074a8d1384140c99b38a22d5 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Mon, 29 Mar 2021 12:29:41 -0400 Subject: [PATCH] Core/Scripts: Implemented new aura script hook OnEnterLeaveCombat Port From (https://github.com/TrinityCore/TrinityCore/commit/2420f4e7a10c430ea28b2d71a17f54da0c244a54) --- Source/Framework/Constants/ScriptsConst.cs | 1 + Source/Game/Entities/Player/Player.DB.cs | 2 +- Source/Game/Entities/Player/Player.cs | 4 +++- Source/Game/Entities/Unit/Unit.Combat.cs | 19 +++++++++++++++++-- Source/Game/Scripting/SpellScript.cs | 21 ++++++++++++++++++++- Source/Game/Spells/Auras/Aura.cs | 13 +++++++++++++ 6 files changed, 55 insertions(+), 5 deletions(-) diff --git a/Source/Framework/Constants/ScriptsConst.cs b/Source/Framework/Constants/ScriptsConst.cs index 58cb3e7a4..a003e2806 100644 --- a/Source/Framework/Constants/ScriptsConst.cs +++ b/Source/Framework/Constants/ScriptsConst.cs @@ -65,6 +65,7 @@ namespace Framework.Constants CheckAreaTarget, Dispel, AfterDispel, + EnterLeaveCombat, // Spell Proc Hooks CheckProc, CheckEffectProc, diff --git a/Source/Game/Entities/Player/Player.DB.cs b/Source/Game/Entities/Player/Player.DB.cs index ae446efe4..235b0c1f4 100644 --- a/Source/Game/Entities/Player/Player.DB.cs +++ b/Source/Game/Entities/Player/Player.DB.cs @@ -2210,7 +2210,7 @@ namespace Game.Entities stmt.AddValue(index++, GetStat((Stats)i)); for (int i = 0; i < (int)SpellSchools.Max; ++i) - stmt.AddValue(index++, GetResistance((SpellSchools)i))); + stmt.AddValue(index++, GetResistance((SpellSchools)i)); stmt.AddValue(index++, (float)m_activePlayerData.BlockPercentage); stmt.AddValue(index++, (float)m_activePlayerData.DodgePercentage); diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 02cd2dbeb..7cf772222 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -3912,8 +3912,10 @@ namespace Game.Entities public static bool IsValidClass(Class _class) { return Convert.ToBoolean((1 << ((int)_class - 1)) & (int)Class.ClassMaskAllPlayable); } public static bool IsValidRace(Race _race) { return Convert.ToBoolean((ulong)SharedConst.GetMaskForRace(_race) & SharedConst.RaceMaskAllPlayable); } - public void OnCombatExit() + public override void OnCombatExit() { + base.OnCombatExit(); + UpdatePotionCooldown(); m_combatExitTime = Time.GetMSTime(); } diff --git a/Source/Game/Entities/Unit/Unit.Combat.cs b/Source/Game/Entities/Unit/Unit.Combat.cs index 86e09759b..d47f5fb62 100644 --- a/Source/Game/Entities/Unit/Unit.Combat.cs +++ b/Source/Game/Entities/Unit/Unit.Combat.cs @@ -285,8 +285,8 @@ namespace Game.Entities else if (!IsCharmed()) return; } - else - ToPlayer().OnCombatExit(); + + OnCombatExit(); RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.LeavingCombat); } @@ -328,6 +328,15 @@ namespace Game.Entities return fThreat * m_threatModifier[(int)school]; } + public virtual void OnCombatExit() + { + foreach (var pair in m_appliedAuras) + { + AuraApplication aurApp = pair.Value; + aurApp.GetBase().CallScriptEnterLeaveCombatHandlers(aurApp, false); + } + } + public bool IsTargetableForAttack(bool checkFakeDeath = true) { if (!IsAlive()) @@ -1428,6 +1437,12 @@ namespace Game.Entities foreach (var unit in m_Controlled) unit.SetInCombatState(PvP, enemy); + foreach (var pair in m_appliedAuras) + { + AuraApplication aurApp = pair.Value; + aurApp.GetBase().CallScriptEnterLeaveCombatHandlers(aurApp, true); + } + RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.EnteringCombat); ProcSkillsAndAuras(enemy, ProcFlags.EnterCombat, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null); } diff --git a/Source/Game/Scripting/SpellScript.cs b/Source/Game/Scripting/SpellScript.cs index bdbc56bc7..dcfe52a3c 100644 --- a/Source/Game/Scripting/SpellScript.cs +++ b/Source/Game/Scripting/SpellScript.cs @@ -777,6 +777,7 @@ namespace Game.Scripting public delegate bool AuraCheckEffectProcDelegate(AuraEffect aura, ProcEventInfo info); public delegate void AuraProcDelegate(ProcEventInfo info); public delegate void AuraEffectProcDelegate(AuraEffect aura, ProcEventInfo info); + public delegate void AuraEnterLeaveCombatFnType(bool isNowInCombat); public class CheckAreaTargetHandler { @@ -975,7 +976,6 @@ namespace Game.Scripting AuraCheckEffectProcDelegate _HandlerScript; } - public class AuraProcHandler { public AuraProcHandler(AuraProcDelegate handlerScript) @@ -1003,7 +1003,20 @@ namespace Game.Scripting AuraEffectProcDelegate _EffectHandlerScript; } + public class EnterLeaveCombatHandler + { + public EnterLeaveCombatHandler(AuraEnterLeaveCombatFnType handlerScript) + { + _handlerScript = handlerScript; + } + public void Call(bool isNowInCombat) + { + _handlerScript(isNowInCombat); + } + AuraEnterLeaveCombatFnType _handlerScript; + } + public AuraScript() { m_aura = null; @@ -1295,6 +1308,11 @@ namespace Game.Scripting // where function is: void function (AuraEffect aurEff, ProcEventInfo& procInfo); public List AfterEffectProc = new(); + // executed when target enters or leaves combat + // example: OnEnterLeaveCombat += AuraEnterLeaveCombatFn(class::function) + // where function is: void function (bool isNowInCombat); + public List OnEnterLeaveCombat = new(); + // AuraScript interface - hook/effect execution manipulators // prevents default action of a hook from being executed (works only while called in a hook which default action can be prevented) @@ -1413,6 +1431,7 @@ namespace Game.Scripting case AuraScriptHookType.AfterProc: case AuraScriptHookType.EffectProc: case AuraScriptHookType.EffectAfterProc: + case AuraScriptHookType.EnterLeaveCombat: return m_auraApplication.GetTarget(); default: Log.outError(LogFilter.Scripts, "Script: `{0}` Spell: `{1}` AuraScript.GetTarget called in a hook in which the call won't have effect!", m_scriptName, m_scriptSpellId); diff --git a/Source/Game/Spells/Auras/Aura.cs b/Source/Game/Spells/Auras/Aura.cs index 024f6b02f..5bd908ae1 100644 --- a/Source/Game/Spells/Auras/Aura.cs +++ b/Source/Game/Spells/Auras/Aura.cs @@ -2145,6 +2145,19 @@ namespace Game.Spells } } + public void CallScriptEnterLeaveCombatHandlers(AuraApplication aurApp, bool isNowInCombat) + { + foreach (var loadedScript in m_loadedScripts) + { + loadedScript._PrepareScriptCall(AuraScriptHookType.EnterLeaveCombat, aurApp); + + foreach (var hook in loadedScript.OnEnterLeaveCombat) + hook.Call(isNowInCombat); + + loadedScript._FinishScriptCall(); + } + } + public bool CallScriptCheckProcHandlers(AuraApplication aurApp, ProcEventInfo eventInfo) { bool result = true;