Created
April 2, 2012 23:12
-
-
Save Subv/2287876 to your computer and use it in GitHub Desktop.
Proc Hook
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp | |
index d71f8e8..e0a589d 100755 | |
--- a/src/server/game/Entities/Unit/Unit.cpp | |
+++ b/src/server/game/Entities/Unit/Unit.cpp | |
@@ -5689,29 +5689,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere | |
} | |
break; | |
} | |
- | |
- // Hot Streak | |
- if (dummySpell->SpellIconID == 2999) | |
- { | |
- if (effIndex != 0) | |
- return false; | |
- AuraEffect* counter = triggeredByAura->GetBase()->GetEffect(EFFECT_1); | |
- if (!counter) | |
- return true; | |
- | |
- // Count spell criticals in a row in second aura | |
- if (procEx & PROC_EX_CRITICAL_HIT) | |
- { | |
- counter->SetAmount(counter->GetAmount() * 2); | |
- if (counter->GetAmount() < 100) // not enough | |
- return true; | |
- // Crititcal counted -> roll chance | |
- if (roll_chance_i(triggerAmount)) | |
- CastSpell(this, 48108, true, castItem, triggeredByAura); | |
- } | |
- counter->SetAmount(25); | |
- return true; | |
- } | |
// Burnout | |
if (dummySpell->SpellIconID == 2998) | |
{ | |
@@ -14376,13 +14353,18 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u | |
SetCantProc(true); | |
// This bool is needed till separate aura effect procs are still here | |
- bool handled = false; | |
- if (HandleAuraProc(target, damage, i->aura, procSpell, procFlag, procExtra, cooldown, &handled)) | |
+ // Prevent default effect by script, remember to set takeCharges according to the needs of the script | |
+ bool handled = i->aura->CallScriptEffectProc(this, target, damage, procSpell, procFlag, procExtra, attType, cooldown, takeCharges); | |
+ if (!handled) | |
{ | |
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), Id); | |
- takeCharges = true; | |
+ if (HandleAuraProc(target, damage, i->aura, procSpell, procFlag, procExtra, cooldown, &handled)) | |
+ { | |
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), Id); | |
+ takeCharges = true; | |
+ } | |
} | |
+ // Check again since HandleAuraProc can change the handled boolean | |
if (!handled) | |
{ | |
for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) | |
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp | |
index b6cdc00..4c09e8c 100755 | |
--- a/src/server/game/Spells/Auras/SpellAuras.cpp | |
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp | |
@@ -2303,6 +2303,24 @@ void Aura::CallScriptEffectAfterManaShieldHandlers(AuraEffect* aurEff, AuraAppli | |
} | |
} | |
+bool Aura::CallScriptEffectProc(Unit* unit, Unit* victim, uint32 damage, SpellInfo const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, uint32& cooldown, bool& takeCharges) | |
+{ | |
+ bool preventDefault = false; | |
+ for(std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr) | |
+ { | |
+ (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_PROC); | |
+ std::list<AuraScript::EffectProcHandler>::iterator effEndItr = (*scritr)->OnEffectProc.end(), effItr = (*scritr)->OnEffectProc.begin(); | |
+ | |
+ for(; effItr != effEndItr ; ++effItr) | |
+ (*effItr).Call(*scritr, unit, victim, damage, procSpell, procFlag, procExtra, attType, cooldown, takeCharges); | |
+ | |
+ if (!preventDefault) | |
+ preventDefault = (*scritr)->_IsDefaultActionPrevented(); | |
+ (*scritr)->_FinishScriptCall(); | |
+ } | |
+ return preventDefault; | |
+} | |
+ | |
UnitAura::UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, uint64 casterGUID) | |
: Aura(spellproto, owner, caster, castItem, casterGUID) | |
{ | |
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h | |
index 2f50d47..86235fa 100755 | |
--- a/src/server/game/Spells/Auras/SpellAuras.h | |
+++ b/src/server/game/Spells/Auras/SpellAuras.h | |
@@ -217,6 +217,7 @@ class Aura | |
void CallScriptEffectAfterAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount); | |
void CallScriptEffectManaShieldHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount, bool & defaultPrevented); | |
void CallScriptEffectAfterManaShieldHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount); | |
+ bool CallScriptEffectProc(Unit* unit, Unit* victim, uint32 damage, SpellInfo const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, uint32& cooldown, bool& takeCharges); | |
std::list<AuraScript*> m_loadedScripts; | |
private: | |
void _DeleteRemovedApplications(); | |
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp | |
index 81f8bbd..4d56a41 100755 | |
--- a/src/server/game/Spells/SpellScript.cpp | |
+++ b/src/server/game/Spells/SpellScript.cpp | |
@@ -740,6 +740,16 @@ void AuraScript::EffectManaShieldHandler::Call(AuraScript* auraScript, AuraEffec | |
(auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, absorbAmount); | |
} | |
+AuraScript::EffectProcHandler::EffectProcHandler(AuraEffectProcFnType effectProcScript) | |
+{ | |
+ pEffectProcScript = effectProcScript; | |
+} | |
+ | |
+void AuraScript::EffectProcHandler::Call(AuraScript* auraScript, Unit* unit, Unit* victim, uint32 damage, SpellInfo const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, uint32& cooldown, bool& takeCharges) | |
+{ | |
+ (auraScript->*pEffectProcScript)(unit, victim, damage, procSpell, procFlag, procExtra, attType, cooldown, takeCharges); | |
+} | |
+ | |
bool AuraScript::_Load(Aura* aura) | |
{ | |
m_aura = aura; | |
@@ -773,6 +783,7 @@ bool AuraScript::_IsDefaultActionPrevented() | |
case AURA_SCRIPT_HOOK_EFFECT_APPLY: | |
case AURA_SCRIPT_HOOK_EFFECT_REMOVE: | |
case AURA_SCRIPT_HOOK_EFFECT_PERIODIC: | |
+ case AURA_SCRIPT_HOOK_EFFECT_PROC: | |
return m_defaultActionPrevented; | |
default: | |
ASSERT(false && "AuraScript::_IsDefaultActionPrevented is called in a wrong place"); | |
@@ -787,6 +798,7 @@ void AuraScript::PreventDefaultAction() | |
case AURA_SCRIPT_HOOK_EFFECT_APPLY: | |
case AURA_SCRIPT_HOOK_EFFECT_REMOVE: | |
case AURA_SCRIPT_HOOK_EFFECT_PERIODIC: | |
+ case AURA_SCRIPT_HOOK_EFFECT_PROC: | |
m_defaultActionPrevented = true; | |
break; | |
default: | |
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h | |
index e84a56c..6b015fb 100755 | |
--- a/src/server/game/Spells/SpellScript.h | |
+++ b/src/server/game/Spells/SpellScript.h | |
@@ -390,6 +390,7 @@ enum AuraScriptHookType | |
AURA_SCRIPT_HOOK_CHECK_AREA_TARGET, | |
AURA_SCRIPT_HOOK_DISPEL, | |
AURA_SCRIPT_HOOK_AFTER_DISPEL, | |
+ AURA_SCRIPT_HOOK_EFFECT_PROC | |
/*AURA_SCRIPT_HOOK_APPLY, | |
AURA_SCRIPT_HOOK_REMOVE, */ | |
}; | |
@@ -413,6 +414,7 @@ class AuraScript : public _SpellScript | |
typedef void(CLASSNAME::*AuraEffectCalcPeriodicFnType)(AuraEffect const*, bool &, int32 &); \ | |
typedef void(CLASSNAME::*AuraEffectCalcSpellModFnType)(AuraEffect const*, SpellModifier* &); \ | |
typedef void(CLASSNAME::*AuraEffectAbsorbFnType)(AuraEffect*, DamageInfo &, uint32 &); \ | |
+ typedef void(CLASSNAME::*AuraEffectProcFnType)(Unit*, Unit*, uint32, SpellInfo const*, uint32, uint32, WeaponAttackType, uint32 &, bool &); \ | |
AURASCRIPT_FUNCTION_TYPE_DEFINES(AuraScript) | |
@@ -504,6 +506,14 @@ class AuraScript : public _SpellScript | |
private: | |
AuraEffectAbsorbFnType pEffectHandlerScript; | |
}; | |
+ class EffectProcHandler | |
+ { | |
+ public: | |
+ EffectProcHandler(AuraEffectProcFnType effectProcScript); | |
+ void Call(AuraScript* auraScript, Unit* unit, Unit* victim, uint32 damage, SpellInfo const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, uint32& cooldown, bool& takeCharges); | |
+ private: | |
+ AuraEffectProcFnType pEffectProcScript; | |
+ }; | |
#define AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \ | |
class CheckAreaTargetFunction : public AuraScript::CheckAreaTargetHandler { public: CheckAreaTargetFunction(AuraCheckAreaTargetFnType _pHandlerScript) : AuraScript::CheckAreaTargetHandler((AuraScript::AuraCheckAreaTargetFnType)_pHandlerScript) {} }; \ | |
@@ -516,6 +526,7 @@ class AuraScript : public _SpellScript | |
class EffectApplyHandlerFunction : public AuraScript::EffectApplyHandler { public: EffectApplyHandlerFunction(AuraEffectApplicationModeFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName, AuraEffectHandleModes _mode) : AuraScript::EffectApplyHandler((AuraScript::AuraEffectApplicationModeFnType)_pEffectHandlerScript, _effIndex, _effName, _mode) {} }; \ | |
class EffectAbsorbFunction : public AuraScript::EffectAbsorbHandler { public: EffectAbsorbFunction(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectAbsorbHandler((AuraScript::AuraEffectAbsorbFnType)_pEffectHandlerScript, _effIndex) {} }; \ | |
class EffectManaShieldFunction : public AuraScript::EffectManaShieldHandler { public: EffectManaShieldFunction(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectManaShieldHandler((AuraScript::AuraEffectAbsorbFnType)_pEffectHandlerScript, _effIndex) {} }; \ | |
+ class EffectProcHandlerFunction : public AuraScript::EffectProcHandler { public: EffectProcHandlerFunction(AuraEffectProcFnType _pEffectProcScript) : AuraScript::EffectProcHandler((AuraScript::AuraEffectProcFnType)_pEffectProcScript) {} }; \ | |
#define PrepareAuraScript(CLASSNAME) AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) | |
@@ -640,6 +651,12 @@ class AuraScript : public _SpellScript | |
// where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount); | |
HookList<EffectManaShieldHandler> AfterEffectManaShield; | |
+ // executed when aura effect proc event occurs | |
+ // example: OnEffectProc += AuraEffectProcFn(class::function); | |
+ // where function is: void function (Unit* unit, Unit* victim, uint32 damage, SpellInfo const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, uint32& cooldown, bool& takeCharges); | |
+ HookList<EffectProcHandler> OnEffectProc; | |
+ #define AuraEffectProcFn(F) EffectProcHandlerFunction(&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) | |
diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp | |
index b746c37..ac0171a 100644 | |
--- a/src/server/scripts/Spells/spell_mage.cpp | |
+++ b/src/server/scripts/Spells/spell_mage.cpp | |
@@ -340,13 +340,56 @@ public: | |
} | |
}; | |
+// Hot Streak | |
+class spell_mage_hot_streak : public SpellScriptLoader | |
+{ | |
+ public: | |
+ spell_mage_hot_streak() : SpellScriptLoader("spell_mage_hot_streak") { } | |
+ | |
+ class spell_mage_hot_streak_AuraScript : public AuraScript | |
+ { | |
+ PrepareAuraScript(spell_mage_hot_streak_AuraScript); | |
+ | |
+ void HandleProc(Unit* unit, Unit* victim, uint32 damage, SpellInfo const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, uint32& cooldown, bool& takeCharges) | |
+ { | |
+ AuraEffect* counter = GetEffect(EFFECT_1); | |
+ if (!counter) | |
+ return; | |
+ | |
+ // Count spell criticals in a row in second aura | |
+ if (procExtra & PROC_EX_CRITICAL_HIT) | |
+ { | |
+ counter->SetAmount(counter->GetAmount() * 2); | |
+ if (counter->GetAmount() < 100) // not enough | |
+ return; | |
+ // Crititcal counted -> roll chance | |
+ if (roll_chance_i(GetEffect(EFFECT_0)->GetAmount())) | |
+ unit->CastSpell(unit, 48108, true, NULL, GetEffect(EFFECT_0)); | |
+ } | |
+ counter->SetAmount(25); | |
+ } | |
+ | |
+ void Register() | |
+ { | |
+ OnEffectProc += AuraEffectProcFn(spell_mage_hot_streak_AuraScript::HandleProc); | |
+ } | |
+ }; | |
+ | |
+ AuraScript* GetAuraScript() const | |
+ { | |
+ return new spell_mage_hot_streak_AuraScript(); | |
+ } | |
+}; | |
+ | |
+ | |
void AddSC_mage_spell_scripts() | |
{ | |
- new spell_mage_blast_wave; | |
- new spell_mage_cold_snap; | |
+ new spell_mage_blast_wave(); | |
+ new spell_mage_cold_snap(); | |
new spell_mage_frost_warding_trigger(); | |
new spell_mage_incanters_absorbtion_absorb(); | |
new spell_mage_incanters_absorbtion_manashield(); | |
- new spell_mage_polymorph_cast_visual; | |
- new spell_mage_summon_water_elemental; | |
+ new spell_mage_polymorph_cast_visual(); | |
+ new spell_mage_summon_water_elemental(); | |
+ new spell_mage_hot_streak(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment