Core/AuraScript: Add DoCheckAreaTarget hook to allow explicit area aura target selection.
This commit is contained in:
@@ -1636,50 +1636,15 @@ bool Aura::CanBeAppliedOn(Unit *target)
|
||||
// not selfcasted single target auras mustn't be applied
|
||||
if (GetCasterGUID() != GetOwner()->GetGUID() && IsSingleTargetSpell(GetSpellProto()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
else if (GetOwner() != target)
|
||||
else
|
||||
return CheckAreaTarget(target);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Aura::CheckAreaTarget(Unit *target)
|
||||
bool Aura::CheckAreaTarget(Unit* target)
|
||||
{
|
||||
// for owner check use Spell::CheckTarget
|
||||
ASSERT(GetOwner() != target);
|
||||
|
||||
// some special cases
|
||||
switch(GetId())
|
||||
{
|
||||
case 45828: // AV Marshal's HP/DMG auras
|
||||
case 45829:
|
||||
case 45830:
|
||||
case 45821:
|
||||
case 45822: // AV Warmaster's HP/DMG auras
|
||||
case 45823:
|
||||
case 45824:
|
||||
case 45826:
|
||||
switch(target->GetEntry())
|
||||
{
|
||||
// alliance
|
||||
case 14762: // Dun Baldar North Marshal
|
||||
case 14763: // Dun Baldar South Marshal
|
||||
case 14764: // Icewing Marshal
|
||||
case 14765: // Stonehearth Marshal
|
||||
case 11948: // Vandar Stormspike
|
||||
// horde
|
||||
case 14772: // East Frostwolf Warmaster
|
||||
case 14776: // Tower Point Warmaster
|
||||
case 14773: // Iceblood Warmaster
|
||||
case 14777: // West Frostwolf Warmaster
|
||||
case 11946: // Drek'thar
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
return CallScriptCheckAreaTargetHandlers(target);
|
||||
}
|
||||
|
||||
void Aura::_DeleteRemovedApplications()
|
||||
@@ -1709,6 +1674,20 @@ void Aura::LoadScripts()
|
||||
}
|
||||
}
|
||||
|
||||
bool Aura::CallScriptCheckAreaTargetHandlers(Unit* target)
|
||||
{
|
||||
for(std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_CHECK_AREA_TARGET);
|
||||
std::list<AuraScript::CheckAreaTargetHandler>::iterator hookItrEnd = (*scritr)->DoCheckAreaTarget.end(), hookItr = (*scritr)->DoCheckAreaTarget.begin();
|
||||
for (; hookItr != hookItrEnd ; ++hookItr)
|
||||
if(!(*hookItr).Call(*scritr, target))
|
||||
return false;
|
||||
(*scritr)->_FinishScriptCall();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Aura::CallScriptEffectApplyHandlers(AuraEffect const * aurEff, AuraApplication const * aurApp, AuraEffectHandleModes mode)
|
||||
{
|
||||
bool preventDefault = false;
|
||||
|
||||
@@ -170,6 +170,7 @@ class Aura
|
||||
|
||||
// AuraScript
|
||||
void LoadScripts();
|
||||
bool CallScriptCheckAreaTargetHandlers(Unit * target);
|
||||
bool CallScriptEffectApplyHandlers(AuraEffect const * aurEff, AuraApplication const * aurApp, AuraEffectHandleModes mode);
|
||||
bool CallScriptEffectRemoveHandlers(AuraEffect const * aurEff, AuraApplication const * aurApp, AuraEffectHandleModes mode);
|
||||
void CallScriptAfterEffectApplyHandlers(AuraEffect const * aurEff, AuraApplication const * aurApp, AuraEffectHandleModes mode);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "Spell.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellMgr.h"
|
||||
|
||||
bool _SpellScript::_Validate(SpellEntry const* entry)
|
||||
{
|
||||
@@ -468,6 +469,10 @@ void SpellScript::SetCustomCastResultMessage(SpellCustomErrors result)
|
||||
|
||||
bool AuraScript::_Validate(SpellEntry const * entry)
|
||||
{
|
||||
for (std::list<CheckAreaTargetHandler>::iterator itr = DoCheckAreaTarget.begin(); itr != DoCheckAreaTarget.end(); ++itr)
|
||||
if (!HasAreaAuraEffect(entry))
|
||||
sLog->outError("TSCR: Spell `%u` of script `%s` does not have area aura effect - handler bound to hook `DoCheckAreaTarget` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
|
||||
|
||||
for (std::list<EffectApplyHandler>::iterator itr = OnEffectApply.begin(); itr != OnEffectApply.end(); ++itr)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectApply` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
@@ -523,6 +528,16 @@ bool AuraScript::_Validate(SpellEntry const * entry)
|
||||
return _SpellScript::_Validate(entry);
|
||||
}
|
||||
|
||||
AuraScript::CheckAreaTargetHandler::CheckAreaTargetHandler(AuraCheckAreaTargetFnType _pHandlerScript)
|
||||
{
|
||||
pHandlerScript = _pHandlerScript;
|
||||
}
|
||||
|
||||
bool AuraScript::CheckAreaTargetHandler::Call(AuraScript* auraScript, Unit * _target)
|
||||
{
|
||||
return (auraScript->*pHandlerScript)(_target);
|
||||
}
|
||||
|
||||
AuraScript::EffectBase::EffectBase(uint8 _effIndex, uint16 _effName)
|
||||
: _SpellScript::EffectAuraNameCheck(_effName), _SpellScript::EffectHook(_effIndex)
|
||||
{
|
||||
|
||||
@@ -340,6 +340,7 @@ enum AuraScriptHookType
|
||||
AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB,
|
||||
AURA_SCRIPT_HOOK_EFFECT_MANASHIELD,
|
||||
AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD,
|
||||
AURA_SCRIPT_HOOK_CHECK_AREA_TARGET,
|
||||
/*AURA_SCRIPT_HOOK_APPLY,
|
||||
AURA_SCRIPT_HOOK_REMOVE, */
|
||||
};
|
||||
@@ -354,6 +355,7 @@ class AuraScript : public _SpellScript
|
||||
public:
|
||||
|
||||
#define AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) \
|
||||
typedef bool(CLASSNAME::*AuraCheckAreaTargetFnType)(Unit * target); \
|
||||
typedef void(CLASSNAME::*AuraEffectApplicationModeFnType)(AuraEffect const *, AuraEffectHandleModes); \
|
||||
typedef void(CLASSNAME::*AuraEffectPeriodicFnType)(AuraEffect const *); \
|
||||
typedef void(CLASSNAME::*AuraEffectUpdatePeriodicFnType)(AuraEffect *); \
|
||||
@@ -364,6 +366,14 @@ class AuraScript : public _SpellScript
|
||||
|
||||
AURASCRIPT_FUNCTION_TYPE_DEFINES(AuraScript)
|
||||
|
||||
class CheckAreaTargetHandler
|
||||
{
|
||||
public:
|
||||
CheckAreaTargetHandler(AuraCheckAreaTargetFnType pHandlerScript);
|
||||
bool Call(AuraScript* auraScript, Unit * target);
|
||||
private:
|
||||
AuraCheckAreaTargetFnType pHandlerScript;
|
||||
};
|
||||
class EffectBase : public _SpellScript::EffectAuraNameCheck, public _SpellScript::EffectHook
|
||||
{
|
||||
public:
|
||||
@@ -438,6 +448,7 @@ class AuraScript : public _SpellScript
|
||||
};
|
||||
|
||||
#define AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \
|
||||
class CheckAreaTargetFunction : public AuraScript::CheckAreaTargetHandler { public: CheckAreaTargetFunction(AuraCheckAreaTargetFnType _pHandlerScript) : AuraScript::CheckAreaTargetHandler((AuraScript::AuraCheckAreaTargetFnType)_pHandlerScript) {} }; \
|
||||
class EffectPeriodicHandlerFunction : public AuraScript::EffectPeriodicHandler { public: EffectPeriodicHandlerFunction(AuraEffectPeriodicFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : AuraScript::EffectPeriodicHandler((AuraScript::AuraEffectPeriodicFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
|
||||
class EffectUpdatePeriodicHandlerFunction : public AuraScript::EffectUpdatePeriodicHandler { public: EffectUpdatePeriodicHandlerFunction(AuraEffectUpdatePeriodicFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : AuraScript::EffectUpdatePeriodicHandler((AuraScript::AuraEffectUpdatePeriodicFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
|
||||
class EffectCalcAmountHandlerFunction : public AuraScript::EffectCalcAmountHandler { public: EffectCalcAmountHandlerFunction(AuraEffectCalcAmountFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : AuraScript::EffectCalcAmountHandler((AuraScript::AuraEffectCalcAmountFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
|
||||
@@ -480,6 +491,11 @@ class AuraScript : public _SpellScript
|
||||
// AuraScript interface
|
||||
// hooks to which you can attach your functions
|
||||
//
|
||||
// executed when area aura checks if it can be applied on target
|
||||
// example: OnEffectApply += AuraEffectApplyFn(class::function);
|
||||
// where function is: bool function (Unit * target);
|
||||
HookList<CheckAreaTargetHandler> DoCheckAreaTarget;
|
||||
#define AuraCheckAreaTargetFn(F) CheckAreaTargetFunction(&F)
|
||||
// executed when aura effect is applied with specified mode to target
|
||||
// should be used when when effect handler preventing/replacing is needed, do not use this hook for triggering spellcasts/removing auras etc - may be unsafe
|
||||
// example: OnEffectApply += AuraEffectApplyFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
|
||||
|
||||
@@ -292,6 +292,9 @@ class spell_ex_66244 : public SpellScriptLoader
|
||||
}
|
||||
};
|
||||
|
||||
// example usage of OnEffectManaShield and AfterEffectManaShield hooks
|
||||
// see spell_ex_absorb_aura, these hooks work the same as OnEffectAbsorb and AfterEffectAbsorb
|
||||
|
||||
// example usage of OnEffectAbsorb and AfterEffectAbsorb hooks
|
||||
class spell_ex_absorb_aura : public SpellScriptLoader
|
||||
{
|
||||
@@ -329,8 +332,33 @@ class spell_ex_absorb_aura : public SpellScriptLoader
|
||||
}
|
||||
};
|
||||
|
||||
// example usage of OnEffectManaShield and AfterEffectManaShield hooks
|
||||
// see spell_ex_absorb_aura, these hooks work the same as OnEffectAbsorb and AfterEffectAbsorb
|
||||
class spell_ex_463 : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ex_463() : SpellScriptLoader("spell_ex_463") { }
|
||||
|
||||
class spell_ex_463AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_ex_463AuraScript);
|
||||
|
||||
bool CheckAreaTarget(Unit* target)
|
||||
{
|
||||
sLog->outString("Area aura checks if unit is a valid target for it!");
|
||||
// in our script we allow only players to be affected
|
||||
return target->GetTypeId == TYPEID_PLAYER;
|
||||
}
|
||||
void Register()
|
||||
{
|
||||
DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_ex_463AuraScript::CheckAreaTarget);
|
||||
}
|
||||
};
|
||||
|
||||
// function which creates AuraScript
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_ex_463AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
// this function has to be added to function set in ScriptLoader.cpp
|
||||
void AddSC_example_spell_scripts()
|
||||
@@ -338,6 +366,7 @@ void AddSC_example_spell_scripts()
|
||||
new spell_ex_5581;
|
||||
new spell_ex_66244;
|
||||
new spell_ex_absorb_aura;
|
||||
new spell_ex_463;
|
||||
}
|
||||
|
||||
/* empty script for copypasting
|
||||
|
||||
Reference in New Issue
Block a user