diff options
-rw-r--r-- | sql/updates/world/2011_05_31_02_world_spell_script_names.sql | 10 | ||||
-rwxr-xr-x | src/server/game/Spells/Auras/SpellAuras.cpp | 57 | ||||
-rwxr-xr-x | src/server/game/Spells/Auras/SpellAuras.h | 1 | ||||
-rwxr-xr-x | src/server/game/Spells/SpellScript.cpp | 15 | ||||
-rwxr-xr-x | src/server/game/Spells/SpellScript.h | 16 | ||||
-rw-r--r-- | src/server/scripts/Examples/example_spell.cpp | 33 |
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 |