diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/Spells/Spell.cpp | 2 | ||||
-rwxr-xr-x | src/server/game/Spells/SpellScript.cpp | 49 | ||||
-rwxr-xr-x | src/server/game/Spells/SpellScript.h | 24 |
3 files changed, 58 insertions, 17 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 6b102c25882..e9ae93751b8 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -7042,7 +7042,7 @@ void Spell::CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& ta { for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) { - (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_UNIT_TARGET_SELECT); + (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT); std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin(); for (; hookItr != hookItrEnd; ++hookItr) if ((*hookItr).IsEffectAffected(m_spellInfo, effIndex)) diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index eaccb8fc005..f033a4c043e 100755 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -203,20 +203,19 @@ void SpellScript::HitHandler::Call(SpellScript* spellScript) (spellScript->*pHitHandlerScript)(); } -SpellScript::ObjectAreaTargetSelectHandler::ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) - : _SpellScript::EffectHook(_effIndex), targetType(_targetType) +SpellScript::TargetHook::TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area) + : _SpellScript::EffectHook(_effectIndex), targetType(_targetType), area(_area) { - pObjectAreaTargetSelectHandlerScript = _pObjectAreaTargetSelectHandlerScript; } -std::string SpellScript::ObjectAreaTargetSelectHandler::ToString() +std::string SpellScript::TargetHook::ToString() { std::ostringstream oss; oss << "Index: " << EffIndexToString() << " Target: " << targetType; return oss.str(); } -bool SpellScript::ObjectAreaTargetSelectHandler::CheckEffect(SpellInfo const* spellEntry, uint8 effIndex) +bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 effIndex) { if (!targetType) return false; @@ -225,8 +224,42 @@ bool SpellScript::ObjectAreaTargetSelectHandler::CheckEffect(SpellInfo const* sp spellEntry->Effects[effIndex].TargetB.GetTarget() != targetType) return false; - // TODO: Smart check if this hook will run for this targetType - return true; + SpellImplicitTargetInfo targetType(targetType); + switch (targetType.GetSelectionCategory()) + { + case TARGET_SELECT_CATEGORY_CHANNEL: // SINGLE + return !area; + case TARGET_SELECT_CATEGORY_NEARBY: // BOTH + return true; + case TARGET_SELECT_CATEGORY_CONE: // AREA + case TARGET_SELECT_CATEGORY_AREA: // AREA + return area; + case TARGET_SELECT_CATEGORY_DEFAULT: + switch (targetType.GetObjectType()) + { + case TARGET_OBJECT_TYPE_SRC: // EMPTY + case TARGET_OBJECT_TYPE_DEST: // EMPTY + return false; + default: + switch(targetType.GetReferenceType()) + { + case TARGET_REFERENCE_TYPE_CASTER: // SINGLE + return !area; + case TARGET_REFERENCE_TYPE_TARGET: // BOTH + return true; + } + break; + } + break; + } + + return false; +} + +SpellScript::ObjectAreaTargetSelectHandler::ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) + : TargetHook(_effIndex, _targetType, true) +{ + pObjectAreaTargetSelectHandlerScript = _pObjectAreaTargetSelectHandlerScript; } void SpellScript::ObjectAreaTargetSelectHandler::Call(SpellScript* spellScript, std::list<WorldObject*>& targets) @@ -254,7 +287,7 @@ bool SpellScript::_Validate(SpellInfo const* entry) for (std::list<ObjectAreaTargetSelectHandler>::iterator itr = OnObjectAreaTargetSelect.begin(); itr != OnObjectAreaTargetSelect.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 `OnUnitTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnObjectAreaTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); return _SpellScript::_Validate(entry); } diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index a145a0b7377..9b1afd75405 100755 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -131,7 +131,7 @@ enum SpellScriptHookType SPELL_SCRIPT_HOOK_BEFORE_HIT, SPELL_SCRIPT_HOOK_HIT, SPELL_SCRIPT_HOOK_AFTER_HIT, - SPELL_SCRIPT_HOOK_UNIT_TARGET_SELECT, + SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT, SPELL_SCRIPT_HOOK_CHECK_CAST, SPELL_SCRIPT_HOOK_BEFORE_CAST, SPELL_SCRIPT_HOOK_ON_CAST, @@ -196,16 +196,24 @@ class SpellScript : public _SpellScript SpellHitFnType pHitHandlerScript; }; - class ObjectAreaTargetSelectHandler : public _SpellScript::EffectHook + class TargetHook : public _SpellScript::EffectHook { public: - ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); - std::string ToString(); + TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area); bool CheckEffect(SpellInfo const* spellEntry, uint8 targetType); + std::string ToString(); + protected: + uint16 targetType; + bool area; + }; + + class ObjectAreaTargetSelectHandler : public TargetHook + { + public: + ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); void Call(SpellScript* spellScript, std::list<WorldObject*>& targets); private: SpellObjectAreaTargetSelectFnType pObjectAreaTargetSelectHandlerScript; - uint16 targetType; }; #define SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \ @@ -267,15 +275,15 @@ class SpellScript : public _SpellScript // where function is: void function() #define SpellHitFn(F) HitHandlerFunction(&F) - // example: OnUnitTargetSelect += SpellUnitTargetFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier); - // where function is void function(std::list<Unit*>& targetList) + // example: OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier); + // where function is void function(std::list<WorldObject*>& targets) HookList<ObjectAreaTargetSelectHandler> OnObjectAreaTargetSelect; #define SpellObjectAreaTargetSelectFn(F, I, N) ObjectAreaTargetSelectHandlerFunction(&F, I, N) // hooks are executed in following order, at specified event of spell: // 1. BeforeCast - executed when spell preparation is finished (when cast bar becomes full) before cast is handled // 2. OnCheckCast - allows to override result of CheckCast function - // 3. OnUnitTargetSelect - executed just before adding selected targets to final target list + // 3a. OnObjectAreaTargetSelect - executed just before adding selected targets to final target list (for area targets) // 4. OnCast - executed just before spell is launched (creates missile) or executed // 5. AfterCast - executed after spell missile is launched and immediate spell actions are done // 6. OnEffectLaunch - executed just before specified effect handler call - when spell missile is launched |