aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Player/Player.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp23
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp12
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h1
-rw-r--r--src/server/game/Spells/SpellScript.cpp11
-rw-r--r--src/server/game/Spells/SpellScript.h19
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)