mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-17 21:50:50 -04:00
Core/SpellScripts: implement Spell Proc Hooks and use it in old and new proc system
Hooks: - DoCheckProc: executed when aura checks if it can proc - DoPrepareProc: executed before aura procs (possibility to prevent charge drop/cooldown) - OnProc: executed when aura procs - OnEffectProc: executed when aura effect procs - AfterEffectProc: executed after aura effect proced - AfterProc: executed after aura proced and charges removed using PreventDefaultAction() in DoPrepareProc will prevent charge drop and cooldown default execution of a proc can prevented in OnEffectProc with PreventDefaultAction() Now we should be able to convert almost all procs from Unit::ProcDamageAndSpellFor to SpellScripts Notes to old proc system: - if a proc has a cooldown we must check it in spellscript and add it when we handle the proc - behavior with charge drops is possible undefined (use PreventDefaultAction() in OnEffectProc to notify that the script is executed)
This commit is contained in:
@@ -14452,7 +14452,8 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
||||
Unit* actionTarget = !isVictim ? target : this;
|
||||
|
||||
DamageInfo damageInfo = DamageInfo(actor, actionTarget, damage, procSpell, procSpell ? SpellSchoolMask(procSpell->SchoolMask) : SPELL_SCHOOL_MASK_NORMAL, SPELL_DIRECT_DAMAGE);
|
||||
ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, 0, procExtra, NULL, &damageInfo, NULL /*HealInfo*/);
|
||||
HealInfo healInfo = HealInfo(actor, actionTarget, damage, procSpell, procSpell ? SpellSchoolMask(procSpell->SchoolMask) : SPELL_SCHOOL_MASK_NORMAL);
|
||||
ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, 0, procExtra, NULL, &damageInfo, &healInfo);
|
||||
|
||||
ProcTriggeredList procTriggered;
|
||||
// Fill procTriggered list
|
||||
@@ -14483,6 +14484,10 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
|
||||
continue;
|
||||
|
||||
// AuraScript Hook
|
||||
if (!triggerData.aura->CallScriptCheckProcHandlers(itr->second, eventInfo))
|
||||
continue;
|
||||
|
||||
// Triggered spells not triggering additional spells
|
||||
bool triggered = !(spellProto->AttributesEx3 & SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED) ?
|
||||
(procExtra & PROC_EX_INTERNAL_TRIGGERED && !(procFlag & PROC_FLAG_DONE_TRAP_ACTIVATION)) : false;
|
||||
@@ -14531,15 +14536,21 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
||||
SpellInfo const* spellInfo = i->aura->GetSpellInfo();
|
||||
uint32 Id = i->aura->GetId();
|
||||
|
||||
AuraApplication const* aurApp = i->aura->GetApplicationOfTarget(GetGUID());
|
||||
|
||||
bool prepare = i->aura->CallScriptPrepareProcHandlers(aurApp, eventInfo);
|
||||
|
||||
// For players set spell cooldown if need
|
||||
uint32 cooldown = 0;
|
||||
if (GetTypeId() == TYPEID_PLAYER && i->spellProcEvent && i->spellProcEvent->cooldown)
|
||||
if (prepare && GetTypeId() == TYPEID_PLAYER && i->spellProcEvent && i->spellProcEvent->cooldown)
|
||||
cooldown = i->spellProcEvent->cooldown;
|
||||
|
||||
// Note: must SetCantProc(false) before return
|
||||
if (spellInfo->AttributesEx3 & SPELL_ATTR3_DISABLE_PROC)
|
||||
SetCantProc(true);
|
||||
|
||||
i->aura->CallScriptProcHandlers(aurApp, eventInfo);
|
||||
|
||||
// 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))
|
||||
@@ -14558,6 +14569,13 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
||||
AuraEffect* triggeredByAura = i->aura->GetEffect(effIndex);
|
||||
ASSERT(triggeredByAura);
|
||||
|
||||
bool prevented = i->aura->CallScriptEffectProcHandlers(triggeredByAura, aurApp, eventInfo);
|
||||
if (prevented)
|
||||
{
|
||||
takeCharges = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (triggeredByAura->GetAuraType())
|
||||
{
|
||||
case SPELL_AURA_PROC_TRIGGER_SPELL:
|
||||
@@ -14725,13 +14743,16 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
||||
takeCharges = true;
|
||||
break;
|
||||
} // switch (triggeredByAura->GetAuraType())
|
||||
i->aura->CallScriptAfterEffectProcHandlers(triggeredByAura, aurApp, eventInfo);
|
||||
} // for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
|
||||
} // if (!handled)
|
||||
|
||||
// Remove charge (aura can be removed by triggers)
|
||||
if (useCharges && takeCharges)
|
||||
if (prepare && useCharges && takeCharges)
|
||||
i->aura->DropCharge();
|
||||
|
||||
i->aura->CallScriptAfterProcHandlers(aurApp, eventInfo);
|
||||
|
||||
if (spellInfo->AttributesEx3 & SPELL_ATTR3_DISABLE_PROC)
|
||||
SetCantProc(false);
|
||||
}
|
||||
@@ -14752,7 +14773,7 @@ void Unit::GetProcAurasTriggeredOnEvent(std::list<AuraApplication*>& aurasTrigge
|
||||
if (!(*itr)->GetRemoveMode())
|
||||
if ((*itr)->GetBase()->IsProcTriggeredOnEvent(*itr, eventInfo))
|
||||
{
|
||||
(*itr)->GetBase()->PrepareProcToTrigger();
|
||||
(*itr)->GetBase()->PrepareProcToTrigger(*itr, eventInfo);
|
||||
aurasTriggeringProc.push_back(*itr);
|
||||
}
|
||||
}
|
||||
@@ -14764,7 +14785,7 @@ void Unit::GetProcAurasTriggeredOnEvent(std::list<AuraApplication*>& aurasTrigge
|
||||
{
|
||||
if (itr->second->GetBase()->IsProcTriggeredOnEvent(itr->second, eventInfo))
|
||||
{
|
||||
itr->second->GetBase()->PrepareProcToTrigger();
|
||||
itr->second->GetBase()->PrepareProcToTrigger(itr->second, eventInfo);
|
||||
aurasTriggeringProc.push_back(itr->second);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1274,7 +1274,10 @@ void AuraEffect::PeriodicTick(AuraApplication * aurApp, Unit* caster) const
|
||||
|
||||
void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo)
|
||||
{
|
||||
// TODO: effect script handlers here
|
||||
bool prevented = GetBase()->CallScriptEffectProcHandlers(const_cast<AuraEffect const*>(this), const_cast<AuraApplication const*>(aurApp), eventInfo);
|
||||
if (prevented)
|
||||
return;
|
||||
|
||||
switch (GetAuraType())
|
||||
{
|
||||
case SPELL_AURA_PROC_TRIGGER_SPELL:
|
||||
@@ -1295,6 +1298,8 @@ void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
GetBase()->CallScriptAfterEffectProcHandlers(const_cast<AuraEffect const*>(this), const_cast<AuraApplication const*>(aurApp), eventInfo);
|
||||
}
|
||||
|
||||
void AuraEffect::CleanupTriggeredSpells(Unit* target)
|
||||
|
||||
@@ -1940,9 +1940,12 @@ void Aura::AddProcCooldown(uint32 /*msec*/)
|
||||
//m_procCooldown = time(NULL) + msec;
|
||||
}
|
||||
|
||||
void Aura::PrepareProcToTrigger()
|
||||
void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo)
|
||||
{
|
||||
// TODO: allow scripts to prevent charge drop/cooldown
|
||||
bool prepare = CallScriptPrepareProcHandlers(aurApp, eventInfo);
|
||||
if (!prepare)
|
||||
return;
|
||||
|
||||
// take one charge, aura expiration will be handled in Aura::TriggerProcOnEvent (if needed)
|
||||
if (IsUsingCharges())
|
||||
{
|
||||
@@ -1981,14 +1984,18 @@ bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventI
|
||||
return false;
|
||||
|
||||
// do checks using conditions table
|
||||
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, GetSpellInfo()->Id);
|
||||
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, GetId());
|
||||
ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget());
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
|
||||
return false;
|
||||
|
||||
// AuraScript Hook
|
||||
bool check = const_cast<Aura*>(this)->CallScriptCheckProcHandlers(aurApp, eventInfo);
|
||||
if (!check)
|
||||
return false;
|
||||
|
||||
// TODO:
|
||||
// - add DoCheckProc() AuraScript hook
|
||||
// to allow additional requirements for procs
|
||||
// do allow additional requirements for procs
|
||||
// this is needed because this is the last moment in which you can prevent aura charge drop on proc
|
||||
// and possibly a way to prevent default checks (if there're going to be any)
|
||||
|
||||
@@ -2052,14 +2059,14 @@ float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& event
|
||||
|
||||
void Aura::TriggerProcOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo)
|
||||
{
|
||||
// TODO: OnProc hook here
|
||||
CallScriptProcHandlers(const_cast<AuraApplication const*>(aurApp), eventInfo);
|
||||
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
if (aurApp->HasEffect(i))
|
||||
// TODO: OnEffectProc hook here (allowing prevention of selected effects)
|
||||
// OnEffectProc / AfterEffectProc hooks handled in AuraEffect::HandleProc()
|
||||
GetEffect(i)->HandleProc(aurApp, eventInfo);
|
||||
// TODO: AfterEffectProc hook here
|
||||
|
||||
// TODO: AfterProc hook here
|
||||
CallScriptAfterProcHandlers(const_cast<AuraApplication const*>(aurApp), eventInfo);
|
||||
|
||||
// Remove aura if we've used last charge to proc
|
||||
if (IsUsingCharges() && !GetCharges())
|
||||
@@ -2355,6 +2362,95 @@ void Aura::CallScriptEffectSplitHandlers(AuraEffect* aurEff, AuraApplication con
|
||||
}
|
||||
}
|
||||
|
||||
bool Aura::CallScriptCheckProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo)
|
||||
{
|
||||
for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_CHECK_PROC, aurApp);
|
||||
std::list<AuraScript::CheckProcHandler>::iterator hookItrEnd = (*scritr)->DoCheckProc.end(), hookItr = (*scritr)->DoCheckProc.begin();
|
||||
for (; hookItr != hookItrEnd; ++hookItr)
|
||||
if (!(*hookItr).Call(*scritr, eventInfo))
|
||||
return false;
|
||||
(*scritr)->_FinishScriptCall();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Aura::CallScriptPrepareProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo)
|
||||
{
|
||||
bool prepare = true;
|
||||
for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_PREPARE_PROC, aurApp);
|
||||
std::list<AuraScript::AuraProcHandler>::iterator effEndItr = (*scritr)->DoPrepareProc.end(), effItr = (*scritr)->DoPrepareProc.begin();
|
||||
for (; effItr != effEndItr; ++effItr)
|
||||
(*effItr).Call(*scritr, eventInfo);
|
||||
|
||||
if (prepare && (*scritr)->_IsDefaultActionPrevented())
|
||||
prepare = false;
|
||||
(*scritr)->_FinishScriptCall();
|
||||
}
|
||||
return prepare;
|
||||
}
|
||||
|
||||
void Aura::CallScriptProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo)
|
||||
{
|
||||
for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_PROC, aurApp);
|
||||
std::list<AuraScript::AuraProcHandler>::iterator hookItrEnd = (*scritr)->OnProc.end(), hookItr = (*scritr)->OnProc.begin();
|
||||
for (; hookItr != hookItrEnd; ++hookItr)
|
||||
(*hookItr).Call(*scritr, eventInfo);
|
||||
(*scritr)->_FinishScriptCall();
|
||||
}
|
||||
}
|
||||
|
||||
void Aura::CallScriptAfterProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo)
|
||||
{
|
||||
for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_AFTER_PROC, aurApp);
|
||||
std::list<AuraScript::AuraProcHandler>::iterator hookItrEnd = (*scritr)->AfterProc.end(), hookItr = (*scritr)->AfterProc.begin();
|
||||
for (; hookItr != hookItrEnd; ++hookItr)
|
||||
(*hookItr).Call(*scritr, eventInfo);
|
||||
(*scritr)->_FinishScriptCall();
|
||||
}
|
||||
}
|
||||
|
||||
bool Aura::CallScriptEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo)
|
||||
{
|
||||
bool preventDefault = false;
|
||||
for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_PROC, aurApp);
|
||||
std::list<AuraScript::EffectProcHandler>::iterator effEndItr = (*scritr)->OnEffectProc.end(), effItr = (*scritr)->OnEffectProc.begin();
|
||||
for (; effItr != effEndItr; ++effItr)
|
||||
{
|
||||
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
|
||||
(*effItr).Call(*scritr, aurEff, eventInfo);
|
||||
}
|
||||
if (!preventDefault)
|
||||
preventDefault = (*scritr)->_IsDefaultActionPrevented();
|
||||
(*scritr)->_FinishScriptCall();
|
||||
}
|
||||
return preventDefault;
|
||||
}
|
||||
|
||||
void Aura::CallScriptAfterEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo)
|
||||
{
|
||||
for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_AFTER_PROC, aurApp);
|
||||
std::list<AuraScript::EffectProcHandler>::iterator effEndItr = (*scritr)->AfterEffectProc.end(), effItr = (*scritr)->AfterEffectProc.begin();
|
||||
for (; effItr != effEndItr; ++effItr)
|
||||
{
|
||||
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
|
||||
(*effItr).Call(*scritr, aurEff, eventInfo);
|
||||
}
|
||||
(*scritr)->_FinishScriptCall();
|
||||
}
|
||||
}
|
||||
|
||||
UnitAura::UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, uint64 casterGUID)
|
||||
: Aura(spellproto, owner, caster, castItem, casterGUID)
|
||||
{
|
||||
|
||||
@@ -194,7 +194,7 @@ class Aura
|
||||
void AddProcCooldown(uint32 msec);
|
||||
bool IsUsingCharges() const { return m_isUsingCharges; }
|
||||
void SetUsingCharges(bool val) { m_isUsingCharges = val; }
|
||||
void PrepareProcToTrigger();
|
||||
void PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo);
|
||||
bool IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo) const;
|
||||
float CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const;
|
||||
void TriggerProcOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo);
|
||||
@@ -218,6 +218,13 @@ class 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);
|
||||
// Spell Proc Hooks
|
||||
bool CallScriptCheckProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo);
|
||||
bool CallScriptPrepareProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo);
|
||||
void CallScriptProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo);
|
||||
void CallScriptAfterProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo);
|
||||
bool CallScriptEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo);
|
||||
void CallScriptAfterEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo);
|
||||
|
||||
std::list<AuraScript*> m_loadedScripts;
|
||||
private:
|
||||
|
||||
@@ -470,7 +470,7 @@ WorldLocation* SpellScript::GetHitDest()
|
||||
{
|
||||
if (!IsInEffectHook())
|
||||
{
|
||||
sLog->outError(LOG_FILTER_TSCR, "Script: `%s` Spell: `%u`: function SpellScript::GetHitGObj was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId);
|
||||
sLog->outError(LOG_FILTER_TSCR, "Script: `%s` Spell: `%u`: function SpellScript::GetHitDest was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId);
|
||||
return NULL;
|
||||
}
|
||||
return m_spell->destTarget;
|
||||
@@ -679,6 +679,30 @@ bool AuraScript::_Validate(SpellInfo const* entry)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectSplit` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
|
||||
for (std::list<CheckProcHandler>::iterator itr = DoCheckProc.begin(); itr != DoCheckProc.end(); ++itr)
|
||||
if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` of script `%s` does not have apply aura effect - handler bound to hook `DoCheckProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
|
||||
|
||||
for (std::list<AuraProcHandler>::iterator itr = DoPrepareProc.begin(); itr != DoPrepareProc.end(); ++itr)
|
||||
if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` of script `%s` does not have apply aura effect - handler bound to hook `DoPrepareProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
|
||||
|
||||
for (std::list<AuraProcHandler>::iterator itr = OnProc.begin(); itr != OnProc.end(); ++itr)
|
||||
if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` of script `%s` does not have apply aura effect - handler bound to hook `OnProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
|
||||
|
||||
for (std::list<AuraProcHandler>::iterator itr = AfterProc.begin(); itr != AfterProc.end(); ++itr)
|
||||
if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` of script `%s` does not have apply aura effect - handler bound to hook `AfterProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
|
||||
|
||||
for (std::list<EffectProcHandler>::iterator itr = OnEffectProc.begin(); itr != OnEffectProc.end(); ++itr)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectProc` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
|
||||
for (std::list<EffectProcHandler>::iterator itr = AfterEffectProc.begin(); itr != AfterEffectProc.end(); ++itr)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `AfterEffectProc` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
|
||||
return _SpellScript::_Validate(entry);
|
||||
}
|
||||
|
||||
@@ -818,6 +842,37 @@ void AuraScript::EffectSplitHandler::Call(AuraScript* auraScript, AuraEffect* au
|
||||
(auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, splitAmount);
|
||||
}
|
||||
|
||||
AuraScript::CheckProcHandler::CheckProcHandler(AuraCheckProcFnType handlerScript)
|
||||
{
|
||||
_HandlerScript = handlerScript;
|
||||
}
|
||||
|
||||
bool AuraScript::CheckProcHandler::Call(AuraScript* auraScript, ProcEventInfo& eventInfo)
|
||||
{
|
||||
return (auraScript->*_HandlerScript)(eventInfo);
|
||||
}
|
||||
|
||||
AuraScript::AuraProcHandler::AuraProcHandler(AuraProcFnType handlerScript)
|
||||
{
|
||||
_HandlerScript = handlerScript;
|
||||
}
|
||||
|
||||
void AuraScript::AuraProcHandler::Call(AuraScript* auraScript, ProcEventInfo& eventInfo)
|
||||
{
|
||||
(auraScript->*_HandlerScript)(eventInfo);
|
||||
}
|
||||
|
||||
AuraScript::EffectProcHandler::EffectProcHandler(AuraEffectProcFnType effectHandlerScript, uint8 effIndex, uint16 effName)
|
||||
: AuraScript::EffectBase(effIndex, effName)
|
||||
{
|
||||
_EffectHandlerScript = effectHandlerScript;
|
||||
}
|
||||
|
||||
void AuraScript::EffectProcHandler::Call(AuraScript* auraScript, AuraEffect const* aurEff, ProcEventInfo& eventInfo)
|
||||
{
|
||||
(auraScript->*_EffectHandlerScript)(aurEff, eventInfo);
|
||||
}
|
||||
|
||||
bool AuraScript::_Load(Aura* aura)
|
||||
{
|
||||
m_aura = aura;
|
||||
@@ -853,6 +908,8 @@ bool AuraScript::_IsDefaultActionPrevented()
|
||||
case AURA_SCRIPT_HOOK_EFFECT_PERIODIC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_ABSORB:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_SPLIT:
|
||||
case AURA_SCRIPT_HOOK_PREPARE_PROC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_PROC:
|
||||
return m_defaultActionPrevented;
|
||||
default:
|
||||
ASSERT(false && "AuraScript::_IsDefaultActionPrevented is called in a wrong place");
|
||||
@@ -869,6 +926,8 @@ void AuraScript::PreventDefaultAction()
|
||||
case AURA_SCRIPT_HOOK_EFFECT_PERIODIC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_ABSORB:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_SPLIT:
|
||||
case AURA_SCRIPT_HOOK_PREPARE_PROC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_PROC:
|
||||
m_defaultActionPrevented = true;
|
||||
break;
|
||||
default:
|
||||
@@ -1051,6 +1110,12 @@ Unit* AuraScript::GetTarget() const
|
||||
case AURA_SCRIPT_HOOK_EFFECT_MANASHIELD:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_SPLIT:
|
||||
case AURA_SCRIPT_HOOK_CHECK_PROC:
|
||||
case AURA_SCRIPT_HOOK_PREPARE_PROC:
|
||||
case AURA_SCRIPT_HOOK_PROC:
|
||||
case AURA_SCRIPT_HOOK_AFTER_PROC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_PROC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_AFTER_PROC:
|
||||
return m_auraApplication->GetTarget();
|
||||
default:
|
||||
sLog->outError(LOG_FILTER_TSCR, "Script: `%s` Spell: `%u` AuraScript::GetTarget called in a hook in which the call won't have effect!", m_scriptName->c_str(), m_scriptSpellId);
|
||||
|
||||
@@ -428,14 +428,22 @@ enum AuraScriptHookType
|
||||
AURA_SCRIPT_HOOK_EFFECT_SPLIT,
|
||||
AURA_SCRIPT_HOOK_CHECK_AREA_TARGET,
|
||||
AURA_SCRIPT_HOOK_DISPEL,
|
||||
AURA_SCRIPT_HOOK_AFTER_DISPEL
|
||||
AURA_SCRIPT_HOOK_AFTER_DISPEL,
|
||||
// Spell Proc Hooks
|
||||
AURA_SCRIPT_HOOK_CHECK_PROC,
|
||||
AURA_SCRIPT_HOOK_PREPARE_PROC,
|
||||
AURA_SCRIPT_HOOK_PROC,
|
||||
AURA_SCRIPT_HOOK_EFFECT_PROC,
|
||||
AURA_SCRIPT_HOOK_EFFECT_AFTER_PROC,
|
||||
AURA_SCRIPT_HOOK_AFTER_PROC,
|
||||
/*AURA_SCRIPT_HOOK_APPLY,
|
||||
AURA_SCRIPT_HOOK_REMOVE, */
|
||||
};
|
||||
/*
|
||||
#define HOOK_AURA_EFFECT_START HOOK_AURA_EFFECT_APPLY
|
||||
#define HOOK_AURA_EFFECT_END HOOK_AURA_EFFECT_CALC_SPELLMOD + 1
|
||||
#define HOOK_AURA_EFFECT_COUNT HOOK_AURA_EFFECT_END - HOOK_AURA_EFFECT_START
|
||||
|
||||
*/
|
||||
class AuraScript : public _SpellScript
|
||||
{
|
||||
// internal use classes & functions
|
||||
@@ -453,6 +461,9 @@ class AuraScript : public _SpellScript
|
||||
typedef void(CLASSNAME::*AuraEffectCalcSpellModFnType)(AuraEffect const*, SpellModifier* &); \
|
||||
typedef void(CLASSNAME::*AuraEffectAbsorbFnType)(AuraEffect*, DamageInfo &, uint32 &); \
|
||||
typedef void(CLASSNAME::*AuraEffectSplitFnType)(AuraEffect*, DamageInfo &, uint32 &); \
|
||||
typedef bool(CLASSNAME::*AuraCheckProcFnType)(ProcEventInfo&); \
|
||||
typedef void(CLASSNAME::*AuraProcFnType)(ProcEventInfo&); \
|
||||
typedef void(CLASSNAME::*AuraEffectProcFnType)(AuraEffect const*, ProcEventInfo&); \
|
||||
|
||||
AURASCRIPT_FUNCTION_TYPE_DEFINES(AuraScript)
|
||||
|
||||
@@ -552,6 +563,30 @@ class AuraScript : public _SpellScript
|
||||
private:
|
||||
AuraEffectSplitFnType pEffectHandlerScript;
|
||||
};
|
||||
class CheckProcHandler
|
||||
{
|
||||
public:
|
||||
CheckProcHandler(AuraCheckProcFnType handlerScript);
|
||||
bool Call(AuraScript* auraScript, ProcEventInfo& eventInfo);
|
||||
private:
|
||||
AuraCheckProcFnType _HandlerScript;
|
||||
};
|
||||
class AuraProcHandler
|
||||
{
|
||||
public:
|
||||
AuraProcHandler(AuraProcFnType handlerScript);
|
||||
void Call(AuraScript* auraScript, ProcEventInfo& eventInfo);
|
||||
private:
|
||||
AuraProcFnType _HandlerScript;
|
||||
};
|
||||
class EffectProcHandler : public EffectBase
|
||||
{
|
||||
public:
|
||||
EffectProcHandler(AuraEffectProcFnType effectHandlerScript, uint8 effIndex, uint16 effName);
|
||||
void Call(AuraScript* auraScript, AuraEffect const* aurEff, ProcEventInfo& eventInfo);
|
||||
private:
|
||||
AuraEffectProcFnType _EffectHandlerScript;
|
||||
};
|
||||
|
||||
#define AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \
|
||||
class CheckAreaTargetFunction : public AuraScript::CheckAreaTargetHandler { public: CheckAreaTargetFunction(AuraCheckAreaTargetFnType _pHandlerScript) : AuraScript::CheckAreaTargetHandler((AuraScript::AuraCheckAreaTargetFnType)_pHandlerScript) {} }; \
|
||||
@@ -565,6 +600,9 @@ class AuraScript : public _SpellScript
|
||||
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 EffectSplitFunction : public AuraScript::EffectSplitHandler { public: EffectSplitFunction(AuraEffectSplitFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectSplitHandler((AuraScript::AuraEffectSplitFnType)_pEffectHandlerScript, _effIndex) {} }; \
|
||||
class CheckProcHandlerFunction : public AuraScript::CheckProcHandler { public: CheckProcHandlerFunction(AuraCheckProcFnType handlerScript) : AuraScript::CheckProcHandler((AuraScript::AuraCheckProcFnType)handlerScript) {} }; \
|
||||
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) {} }; \
|
||||
|
||||
#define PrepareAuraScript(CLASSNAME) AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME)
|
||||
|
||||
@@ -695,6 +733,36 @@ class AuraScript : public _SpellScript
|
||||
HookList<EffectSplitHandler> OnEffectSplit;
|
||||
#define AuraEffectSplitFn(F, I) EffectSplitFunction(&F, I)
|
||||
|
||||
// executed when aura checks if it can proc
|
||||
// example: DoCheckProc += AuraCheckProcFn(class::function);
|
||||
// where function is: bool function (ProcEventInfo& eventInfo);
|
||||
HookList<CheckProcHandler> DoCheckProc;
|
||||
#define AuraCheckProcFn(F) CheckProcHandlerFunction(&F)
|
||||
|
||||
// executed before aura procs (possibility to prevent charge drop/cooldown)
|
||||
// example: DoPrepareProc += AuraProcFn(class::function);
|
||||
// where function is: void function (ProcEventInfo& eventInfo);
|
||||
HookList<AuraProcHandler> DoPrepareProc;
|
||||
// executed when aura procs
|
||||
// example: OnProc += AuraProcFn(class::function);
|
||||
// where function is: void function (ProcEventInfo& eventInfo);
|
||||
HookList<AuraProcHandler> OnProc;
|
||||
// executed after aura proced
|
||||
// example: AfterProc += AuraProcFn(class::function);
|
||||
// where function is: void function (ProcEventInfo& eventInfo);
|
||||
HookList<AuraProcHandler> AfterProc;
|
||||
#define AuraProcFn(F) AuraProcHandlerFunction(&F)
|
||||
|
||||
// executed when aura effect procs
|
||||
// example: OnEffectProc += AuraEffectProcFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
|
||||
// where function is: void function (AuraEffect const* aurEff, ProcEventInfo& procInfo);
|
||||
HookList<EffectProcHandler> OnEffectProc;
|
||||
// executed after aura effect proced
|
||||
// example: AfterEffectProc += AuraEffectProcFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
|
||||
// where function is: void function (AuraEffect const* aurEff, ProcEventInfo& procInfo);
|
||||
HookList<EffectProcHandler> AfterEffectProc;
|
||||
#define AuraEffectProcFn(F, I, N) EffectProcHandlerFunction(&F, I, N)
|
||||
|
||||
// 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)
|
||||
|
||||
Reference in New Issue
Block a user