aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp2
-rwxr-xr-xsrc/server/game/Spells/SpellScript.cpp49
-rwxr-xr-xsrc/server/game/Spells/SpellScript.h24
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