aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQAston <qaston@gmail.com>2011-05-31 20:02:55 +0200
committerQAston <qaston@gmail.com>2011-05-31 20:24:44 +0200
commit7b5b95966e8a101c84ccef8b9d37740062eefa4c (patch)
treeb7a44e189ffd8a9ef850649f14fee19ba8104a38
parent4ccb21e51a16a7eeb19760562730f890825a0a62 (diff)
Core/AuraScript: Add DoCheckAreaTarget hook to allow explicit area aura target selection.
-rw-r--r--sql/updates/world/2011_05_31_02_world_spell_script_names.sql10
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuras.cpp57
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuras.h1
-rwxr-xr-xsrc/server/game/Spells/SpellScript.cpp15
-rwxr-xr-xsrc/server/game/Spells/SpellScript.h16
-rw-r--r--src/server/scripts/Examples/example_spell.cpp33
6 files changed, 91 insertions, 41 deletions
diff --git a/sql/updates/world/2011_05_31_02_world_spell_script_names.sql b/sql/updates/world/2011_05_31_02_world_spell_script_names.sql
new file mode 100644
index 00000000000..450afc1780f
--- /dev/null
+++ b/sql/updates/world/2011_05_31_02_world_spell_script_names.sql
@@ -0,0 +1,10 @@
+DELETE FROM `spell_script_names` WHERE `ScriptName` IN('spell_gen_av_drekthar_presence','spell_ex_463');
+INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
+(463, 'spell_ex_463'),
+(45828, 'spell_gen_av_drekthar_presence'),
+(45829, 'spell_gen_av_drekthar_presence'),
+(45830, 'spell_gen_av_drekthar_presence'),
+(45822, 'spell_gen_av_drekthar_presence'),
+(45823, 'spell_gen_av_drekthar_presence'),
+(45824, 'spell_gen_av_drekthar_presence'),
+(45826, 'spell_gen_av_drekthar_presence');
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index dd704d693b3..44c5aa53fe3 100755
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -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;
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index 29e6af8c27f..8204fbb8be9 100755
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -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);
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 35c05c87a44..4645a2564a7 100755
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -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)
{
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 068673eb543..564d699c69b 100755
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -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);
diff --git a/src/server/scripts/Examples/example_spell.cpp b/src/server/scripts/Examples/example_spell.cpp
index 212c6d767bd..82808bb79c3 100644
--- a/src/server/scripts/Examples/example_spell.cpp
+++ b/src/server/scripts/Examples/example_spell.cpp
@@ -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