diff options
author | Matan Shukry <matanshukry@gmail.com> | 2021-03-23 00:21:09 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-03-23 00:46:47 +0100 |
commit | 2420f4e7a10c430ea28b2d71a17f54da0c244a54 (patch) | |
tree | af4287c6327bed6e521cd7cdc012f9886bf0ea73 /src | |
parent | 88f4d30445937b9de42f5cb25acad75fc89bdccb (diff) |
Core/Scripts: Implemented new aura script hook OnEnterLeaveCombat
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 23 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 12 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/SpellScript.cpp | 11 | ||||
-rw-r--r-- | src/server/game/Spells/SpellScript.h | 19 |
8 files changed, 67 insertions, 4 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index de9e29342fc..565c03d0fac 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -28211,6 +28211,8 @@ VoidStorageItem* Player::GetVoidStorageItem(uint64 id, uint8& slot) const void Player::OnCombatExit() { + Unit::OnCombatExit(); + UpdatePotionCooldown(); m_combatExitTime = getMSTime(); } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 6653bb857c6..8a29cc05a0c 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2413,7 +2413,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> VoidStorageItem* GetVoidStorageItem(uint8 slot) const; VoidStorageItem* GetVoidStorageItem(uint64 id, uint8& slot) const; - void OnCombatExit(); + void OnCombatExit() override; void CreateGarrison(uint32 garrSiteId); void DeleteGarrison(); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index cdec9be3caa..b81fb679c2d 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -8205,6 +8205,14 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy) controlled->SetInCombatState(PvP, enemy); } + for (auto itr = m_appliedAuras.begin(); itr != m_appliedAuras.end();) + { + AuraApplication* aurApp = itr->second; + ++itr; + + aurApp->GetBase()->CallScriptEnterLeaveCombatHandlers(aurApp, true); + } + RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::EnteringCombat); ProcSkillsAndAuras(enemy, PROC_FLAG_ENTER_COMBAT, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr); } @@ -8231,8 +8239,8 @@ void Unit::ClearInCombat() else if (!IsCharmed()) return; } - else - ToPlayer()->OnCombatExit(); + + OnCombatExit(); RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::LeavingCombat); } @@ -8244,6 +8252,17 @@ void Unit::ClearInPetCombat() owner->RemoveUnitFlag(UNIT_FLAG_PET_IN_COMBAT); } +void Unit::OnCombatExit() +{ + for (auto itr = m_appliedAuras.begin(); itr != m_appliedAuras.end();) + { + AuraApplication* aurApp = itr->second; + ++itr; + + aurApp->GetBase()->CallScriptEnterLeaveCombatHandlers(aurApp, false); + } +} + bool Unit::isTargetableForAttack(bool checkFakeDeath) const { if (!IsAlive()) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 71da844b761..70111c19fef 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1293,6 +1293,7 @@ class TC_GAME_API Unit : public WorldObject void ClearInCombat(); void ClearInPetCombat(); uint32 GetCombatTimer() const { return m_CombatTimer; } + virtual void OnCombatExit(); bool HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, flag128 familyFlags) const; bool virtual HasSpell(uint32 /*spellID*/) const { return false; } diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 6fe71dc2fec..3a86044597e 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -2140,6 +2140,18 @@ void Aura::CallScriptEffectSplitHandlers(AuraEffect* aurEff, AuraApplication con } } +void Aura::CallScriptEnterLeaveCombatHandlers(AuraApplication const* aurApp, bool isNowInCombat) +{ + for (AuraScript* loadedScript : m_loadedScripts) + { + loadedScript->_PrepareScriptCall(AURA_SCRIPT_HOOK_ENTER_LEAVE_COMBAT, aurApp); + for (AuraScript::EnterLeaveCombatHandler const& hook : loadedScript->OnEnterLeaveCombat) + hook.Call(loadedScript, isNowInCombat); + + loadedScript->_FinishScriptCall(); + } +} + bool Aura::CallScriptCheckProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo) { bool result = true; diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 410d825000d..9633865045a 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -276,6 +276,7 @@ class TC_GAME_API Aura void CallScriptEffectManaShieldHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount, bool & defaultPrevented); void CallScriptEffectAfterManaShieldHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount); void CallScriptEffectSplitHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & splitAmount); + void CallScriptEnterLeaveCombatHandlers(AuraApplication const* aurApp, bool isNowInCombat); // Spell Proc Hooks bool CallScriptCheckProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo); bool CallScriptCheckEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo); diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index de737b0d5d0..97b93e74766 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -978,6 +978,16 @@ void AuraScript::EffectProcHandler::Call(AuraScript* auraScript, AuraEffect* aur (auraScript->*_EffectHandlerScript)(aurEff, eventInfo); } +AuraScript::EnterLeaveCombatHandler::EnterLeaveCombatHandler(AuraEnterLeaveCombatFnType handlerScript) +{ + _handlerScript = handlerScript; +} + +void AuraScript::EnterLeaveCombatHandler::Call(AuraScript* auraScript, bool isNowInCombat) const +{ + (auraScript->*_handlerScript)(isNowInCombat); +} + bool AuraScript::_Load(Aura* aura) { m_aura = aura; @@ -1224,6 +1234,7 @@ Unit* AuraScript::GetTarget() const case AURA_SCRIPT_HOOK_AFTER_PROC: case AURA_SCRIPT_HOOK_EFFECT_PROC: case AURA_SCRIPT_HOOK_EFFECT_AFTER_PROC: + case AURA_SCRIPT_HOOK_ENTER_LEAVE_COMBAT: return m_auraApplication->GetTarget(); default: TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u` AuraScript::GetTarget called in a hook in which the call won't have effect!", m_scriptName->c_str(), m_scriptSpellId); diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index f7afc2b8ec8..4cc24523d0c 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -509,6 +509,7 @@ enum AuraScriptHookType AURA_SCRIPT_HOOK_CHECK_AREA_TARGET, AURA_SCRIPT_HOOK_DISPEL, AURA_SCRIPT_HOOK_AFTER_DISPEL, + AURA_SCRIPT_HOOK_ENTER_LEAVE_COMBAT, // Spell Proc Hooks AURA_SCRIPT_HOOK_CHECK_PROC, AURA_SCRIPT_HOOK_CHECK_EFFECT_PROC, @@ -546,6 +547,7 @@ class TC_GAME_API AuraScript : public _SpellScript typedef bool(CLASSNAME::*AuraCheckEffectProcFnType)(AuraEffect const*, ProcEventInfo&); \ typedef void(CLASSNAME::*AuraProcFnType)(ProcEventInfo&); \ typedef void(CLASSNAME::*AuraEffectProcFnType)(AuraEffect*, ProcEventInfo&); \ + typedef void(CLASSNAME::*AuraEnterLeaveCombatFnType)(bool); AURASCRIPT_FUNCTION_TYPE_DEFINES(AuraScript) @@ -677,6 +679,14 @@ class TC_GAME_API AuraScript : public _SpellScript private: AuraEffectProcFnType _EffectHandlerScript; }; + class TC_GAME_API EnterLeaveCombatHandler + { + public: + EnterLeaveCombatHandler(AuraEnterLeaveCombatFnType handlerScript); + void Call(AuraScript* auraScript, bool isNowInCombat) const; + private: + AuraEnterLeaveCombatFnType _handlerScript; + }; #define AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \ class CheckAreaTargetFunction : public AuraScript::CheckAreaTargetHandler { public: CheckAreaTargetFunction(AuraCheckAreaTargetFnType _pHandlerScript) : AuraScript::CheckAreaTargetHandler((AuraScript::AuraCheckAreaTargetFnType)_pHandlerScript) { } }; \ @@ -693,7 +703,8 @@ class TC_GAME_API AuraScript : public _SpellScript class CheckProcHandlerFunction : public AuraScript::CheckProcHandler { public: CheckProcHandlerFunction(AuraCheckProcFnType handlerScript) : AuraScript::CheckProcHandler((AuraScript::AuraCheckProcFnType)handlerScript) { } }; \ class CheckEffectProcHandlerFunction : public AuraScript::CheckEffectProcHandler { public: CheckEffectProcHandlerFunction(AuraCheckEffectProcFnType handlerScript, uint8 effIndex, uint16 effName) : AuraScript::CheckEffectProcHandler((AuraScript::AuraCheckEffectProcFnType)handlerScript, effIndex, effName) { } }; \ class AuraProcHandlerFunction : public AuraScript::AuraProcHandler { public: AuraProcHandlerFunction(AuraProcFnType handlerScript) : AuraScript::AuraProcHandler((AuraScript::AuraProcFnType)handlerScript) { } }; \ - class EffectProcHandlerFunction : public AuraScript::EffectProcHandler { public: EffectProcHandlerFunction(AuraEffectProcFnType effectHandlerScript, uint8 effIndex, uint16 effName) : AuraScript::EffectProcHandler((AuraScript::AuraEffectProcFnType)effectHandlerScript, effIndex, effName) { } } + class EffectProcHandlerFunction : public AuraScript::EffectProcHandler { public: EffectProcHandlerFunction(AuraEffectProcFnType effectHandlerScript, uint8 effIndex, uint16 effName) : AuraScript::EffectProcHandler((AuraScript::AuraEffectProcFnType)effectHandlerScript, effIndex, effName) { } }; \ + class EnterLeaveCombatFunction : public AuraScript::EnterLeaveCombatHandler { public: EnterLeaveCombatFunction(AuraEnterLeaveCombatFnType handlerScript) : AuraScript::EnterLeaveCombatHandler((AuraScript::AuraEnterLeaveCombatFnType)handlerScript) { } } #define PrepareAuraScript(CLASSNAME) AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) @@ -860,6 +871,12 @@ class TC_GAME_API AuraScript : public _SpellScript HookList<EffectProcHandler> AfterEffectProc; #define AuraEffectProcFn(F, I, N) EffectProcHandlerFunction(&F, I, N) + // executed when target enters or leaves combat + // example: OnEnterLeaveCombat += AuraEnterLeaveCombatFn(class::function) + // where function is: void function (bool isNowInCombat); + HookList<EnterLeaveCombatHandler> OnEnterLeaveCombat; + #define AuraEnterLeaveCombatFn(F) EnterLeaveCombatFunction(&F) + // 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) |