diff options
author | joschiwald <joschiwald@online.de> | 2014-01-23 18:15:59 +0100 |
---|---|---|
committer | joschiwald <joschiwald@online.de> | 2014-01-23 18:15:59 +0100 |
commit | a5b04e06f77cd436e5a16deddcb2f218cb5319b4 (patch) | |
tree | 51e5c3bd8f633bed6e3ab8459ef91de04cb4394e | |
parent | 40b9ea3eb2f09743183aff1624764f808048a0a5 (diff) |
Core/SpellScripts: Implemeted SpellScript hook OnDestinationTargetSelect to easier modify SpellDestinations
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 220 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.h | 8 | ||||
-rw-r--r-- | src/server/game/Spells/SpellScript.cpp | 26 | ||||
-rw-r--r-- | src/server/game/Spells/SpellScript.h | 27 |
4 files changed, 178 insertions, 103 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 49eed70f57d..08e0323b491 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -85,9 +85,26 @@ SpellDestination::SpellDestination(WorldObject const& wObj) _transportGUID = wObj.GetTransGUID(); _transportOffset.Relocate(wObj.GetTransOffsetX(), wObj.GetTransOffsetY(), wObj.GetTransOffsetZ(), wObj.GetTransOffsetO()); _position.Relocate(wObj); - _position.SetOrientation(wObj.GetOrientation()); } +void SpellDestination::Relocate(Position const& pos) +{ + if (_transportGUID) + { + Position offset; + _position.GetPositionOffsetTo(pos, offset); + _transportOffset.RelocateOffset(offset); + } + _position.Relocate(pos); +} + +void SpellDestination::RelocateOffset(Position const& offset) +{ + if (_transportGUID) + _transportOffset.RelocateOffset(offset); + + _position.RelocateOffset(offset); +} SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0), m_strTarget() { @@ -350,14 +367,7 @@ void SpellCastTargets::SetSrc(WorldObject const& wObj) void SpellCastTargets::ModSrc(Position const& pos) { ASSERT(m_targetMask & TARGET_FLAG_SOURCE_LOCATION); - - if (m_src._transportGUID) - { - Position offset; - m_src._position.GetPositionOffsetTo(pos, offset); - m_src._transportOffset.RelocateOffset(offset); - } - m_src._position.Relocate(pos); + m_src.Relocate(pos); } void SpellCastTargets::RemoveSrc() @@ -393,6 +403,12 @@ void SpellCastTargets::SetDst(WorldObject const& wObj) m_targetMask |= TARGET_FLAG_DEST_LOCATION; } +void SpellCastTargets::SetDst(SpellDestination const& spellDest) +{ + m_dst = spellDest; + m_targetMask |= TARGET_FLAG_DEST_LOCATION; +} + void SpellCastTargets::SetDst(SpellCastTargets const& spellTargets) { m_dst = spellTargets.m_dst; @@ -402,14 +418,13 @@ void SpellCastTargets::SetDst(SpellCastTargets const& spellTargets) void SpellCastTargets::ModDst(Position const& pos) { ASSERT(m_targetMask & TARGET_FLAG_DEST_LOCATION); + m_dst.Relocate(pos); +} - if (m_dst._transportGUID) - { - Position offset; - m_dst._position.GetPositionOffsetTo(pos, offset); - m_dst._transportOffset.RelocateOffset(offset); - } - m_dst._position.Relocate(pos); +void SpellCastTargets::ModDst(SpellDestination const& spellDest) +{ + ASSERT(m_targetMask & TARGET_FLAG_DEST_LOCATION); + m_dst = spellDest; } void SpellCastTargets::RemoveDst() @@ -1090,24 +1105,13 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge Trinity::Containers::RandomResizeList(targets, maxTargets); } - // for compability with older code - add only unit and go targets - /// @todo remove this - std::list<Unit*> unitTargets; - std::list<GameObject*> gObjTargets; - for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) { if (Unit* unitTarget = (*itr)->ToUnit()) - unitTargets.push_back(unitTarget); + AddUnitTarget(unitTarget, effMask, false); else if (GameObject* gObjTarget = (*itr)->ToGameObject()) - gObjTargets.push_back(gObjTarget); + AddGOTarget(gObjTarget, effMask); } - - for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr) - AddUnitTarget(*itr, effMask, false); - - for (std::list<GameObject*>::iterator itr = gObjTargets.begin(); itr != gObjTargets.end(); ++itr) - AddGOTarget(*itr, effMask); } } } @@ -1395,31 +1399,32 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) { + SpellDestination dest(*m_caster); + switch (targetType.GetTarget()) { case TARGET_DEST_CASTER: - m_targets.SetDst(*m_caster); - return; + break; case TARGET_DEST_HOME: if (Player* playerCaster = m_caster->ToPlayer()) - m_targets.SetDst(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId); - return; + dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId); + break; case TARGET_DEST_DB: if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex)) { /// @todo fix this check if (m_spellInfo->HasEffect(SPELL_EFFECT_TELEPORT_UNITS) || m_spellInfo->HasEffect(SPELL_EFFECT_BIND)) - m_targets.SetDst(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId); + dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId); else if (st->target_mapId == m_caster->GetMapId()) - m_targets.SetDst(st->target_X, st->target_Y, st->target_Z, st->target_Orientation); + dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation); } else { TC_LOG_DEBUG("spells", "SPELL: unknown target coordinates for spell ID %u", m_spellInfo->Id); - WorldObject* target = m_targets.GetObjectTarget(); - m_targets.SetDst(target ? *target : *m_caster); + if (WorldObject* target = m_targets.GetObjectTarget()) + dest = SpellDestination(*target); } - return; + break; case TARGET_DEST_CASTER_FISHING: { float min_dis = m_spellInfo->GetMinRange(true); @@ -1447,60 +1452,70 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici return; } - m_targets.SetDst(x, y, liquidLevel, m_caster->GetOrientation()); - return; + dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation()); + break; } default: - break; - } + { + float dist; + float angle = targetType.CalcDirectionAngle(); + float objSize = m_caster->GetObjectSize(); + if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON) + dist = PET_FOLLOW_DIST; + else + dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); - float dist; - float angle = targetType.CalcDirectionAngle(); - float objSize = m_caster->GetObjectSize(); - if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON) - dist = PET_FOLLOW_DIST; - else - dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); + if (dist < objSize) + dist = objSize; + else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM) + dist = objSize + (dist - objSize) * float(rand_norm()); - if (dist < objSize) - dist = objSize; - else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM) - dist = objSize + (dist - objSize) * (float)rand_norm(); + Position pos = dest._position; + if (targetType.GetTarget() == TARGET_DEST_CASTER_FRONT_LEAP) + m_caster->MovePositionToFirstCollision(pos, dist, angle); + else + m_caster->MovePosition(pos, dist, angle); - Position pos; - if (targetType.GetTarget() == TARGET_DEST_CASTER_FRONT_LEAP) - m_caster->GetFirstCollisionPosition(pos, dist, angle); - else - m_caster->GetNearPosition(pos, dist, angle); - m_targets.SetDst(*m_caster); - m_targets.ModDst(pos); + dest.Relocate(pos); + break; + } + } + + CallScriptDestinationTargetSelectHandlers(dest, effIndex); + m_targets.SetDst(dest); } void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) { WorldObject* target = m_targets.GetObjectTarget(); + + SpellDestination dest(*target); + switch (targetType.GetTarget()) { case TARGET_DEST_TARGET_ENEMY: case TARGET_DEST_TARGET_ANY: - m_targets.SetDst(*target); - return; + break; default: + { + float angle = targetType.CalcDirectionAngle(); + float objSize = target->GetObjectSize(); + float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); + if (dist < objSize) + dist = objSize; + else if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM) + dist = objSize + (dist - objSize) * float(rand_norm()); + + Position pos = dest._position; + target->MovePosition(pos, dist, angle); + + dest.Relocate(pos); break; + } } - float angle = targetType.CalcDirectionAngle(); - float objSize = target->GetObjectSize(); - float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); - if (dist < objSize) - dist = objSize; - else if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM) - dist = objSize + (dist - objSize) * (float)rand_norm(); - - Position pos; - target->GetNearPosition(pos, dist, angle); - m_targets.SetDst(*target); - m_targets.ModDst(pos); + CallScriptDestinationTargetSelectHandlers(dest, effIndex); + m_targets.SetDst(dest); } void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) @@ -1509,8 +1524,9 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT // can only happen if previous destination target could not be set for some reason // (not found nearby target, or channel target for example // maybe we should abort the spell in such case? - if (!m_targets.HasDst()) - m_targets.SetDst(*m_caster); + CheckDst(); + + SpellDestination dest(*m_targets.GetDst()); switch (targetType.GetTarget()) { @@ -1520,20 +1536,25 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT case TARGET_DEST_DEST: return; case TARGET_DEST_TRAJ: - SelectImplicitTrajTargets(); + SelectImplicitTrajTargets(effIndex); return; default: + { + float angle = targetType.CalcDirectionAngle(); + float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); + if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM) + dist *= float(rand_norm()); + + Position pos = dest._position; + m_caster->MovePosition(pos, dist, angle); + + dest.Relocate(pos); break; + } } - float angle = targetType.CalcDirectionAngle(); - float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); - if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM) - dist *= (float)rand_norm(); - - Position pos = *m_targets.GetDstPos(); - m_caster->MovePosition(pos, dist, angle); - m_targets.ModDst(pos); + CallScriptDestinationTargetSelectHandlers(dest, effIndex); + m_targets.ModDst(dest); } void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) @@ -1624,14 +1645,9 @@ void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTarg // Chain primary target is added earlier CallScriptObjectAreaTargetSelectHandlers(targets, effIndex); - // for backward compability - std::list<Unit*> unitTargets; for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) if (Unit* unitTarget = (*itr)->ToUnit()) - unitTargets.push_back(unitTarget); - - for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr) - AddUnitTarget(*itr, effMask, false); + AddUnitTarget(unitTarget, effMask, false); } } @@ -1649,7 +1665,7 @@ float tangent(float x) #define DEBUG_TRAJ(a) //a -void Spell::SelectImplicitTrajTargets() +void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex) { if (!m_targets.HasTraj()) return; @@ -1778,7 +1794,11 @@ void Spell::SelectImplicitTrajTargets() Position trajDst; trajDst.Relocate(x, y, z, m_caster->GetOrientation()); - m_targets.ModDst(trajDst); + SpellDestination dest(*m_targets.GetDst()); + dest.Relocate(trajDst); + + CallScriptDestinationTargetSelectHandlers(dest, effIndex); + m_targets.ModDst(dest); } } @@ -7177,6 +7197,20 @@ void Spell::CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffI } } +void Spell::CallScriptDestinationTargetSelectHandlers(SpellDestination& target, SpellEffIndex effIndex) +{ + for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) + { + (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT); + std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin(); + for (; hookItr != hookItrEnd; ++hookItr) + if (hookItr->IsEffectAffected(m_spellInfo, effIndex)) + hookItr->Call(*scritr, target); + + (*scritr)->_FinishScriptCall(); + } +} + bool Spell::CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck) { // Skip if there are not any script diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 72bc195aec7..76be075e94d 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -87,6 +87,9 @@ struct SpellDestination SpellDestination(Position const& pos); SpellDestination(WorldObject const& wObj); + void Relocate(Position const& pos); + void RelocateOffset(Position const& offset); + WorldLocation _position; uint64 _transportGUID; Position _transportOffset; @@ -141,8 +144,10 @@ class SpellCastTargets void SetDst(float x, float y, float z, float orientation, uint32 mapId = MAPID_INVALID); void SetDst(Position const& pos); void SetDst(WorldObject const& wObj); + void SetDst(SpellDestination const& spellDest); void SetDst(SpellCastTargets const& spellTargets); void ModDst(Position const& pos); + void ModDst(SpellDestination const& spellDest); void RemoveDst(); bool HasSrc() const { return GetTargetMask() & TARGET_FLAG_SOURCE_LOCATION; } @@ -359,7 +364,7 @@ class Spell void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType); void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType); void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask); - void SelectImplicitTrajTargets(); + void SelectImplicitTrajTargets(SpellEffIndex effIndex); void SelectEffectTypeImplicitTargets(uint8 effIndex); @@ -636,6 +641,7 @@ class Spell void CallScriptAfterHitHandlers(); void CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& targets, SpellEffIndex effIndex); void CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffIndex effIndex); + void CallScriptDestinationTargetSelectHandlers(SpellDestination& target, SpellEffIndex effIndex); bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck); std::list<SpellScript*> m_loadedScripts; diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index 7301e693978..c7eebb495c0 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -203,8 +203,8 @@ void SpellScript::HitHandler::Call(SpellScript* spellScript) (spellScript->*pHitHandlerScript)(); } -SpellScript::TargetHook::TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area) - : _SpellScript::EffectHook(_effectIndex), targetType(_targetType), area(_area) { } +SpellScript::TargetHook::TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area, bool _dest) + : _SpellScript::EffectHook(_effectIndex), targetType(_targetType), area(_area), dest(_dest) { } std::string SpellScript::TargetHook::ToString() { @@ -236,8 +236,9 @@ bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 eff switch (targetInfo.GetObjectType()) { case TARGET_OBJECT_TYPE_SRC: // EMPTY - case TARGET_OBJECT_TYPE_DEST: // EMPTY return false; + case TARGET_OBJECT_TYPE_DEST: // DEST + return dest; default: switch (targetInfo.GetReferenceType()) { @@ -259,7 +260,7 @@ bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 eff } SpellScript::ObjectAreaTargetSelectHandler::ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) - : TargetHook(_effIndex, _targetType, true) + : TargetHook(_effIndex, _targetType, true, false) { pObjectAreaTargetSelectHandlerScript = _pObjectAreaTargetSelectHandlerScript; } @@ -270,7 +271,7 @@ void SpellScript::ObjectAreaTargetSelectHandler::Call(SpellScript* spellScript, } SpellScript::ObjectTargetSelectHandler::ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) - : TargetHook(_effIndex, _targetType, false) + : TargetHook(_effIndex, _targetType, false, false) { pObjectTargetSelectHandlerScript = _pObjectTargetSelectHandlerScript; } @@ -280,6 +281,17 @@ void SpellScript::ObjectTargetSelectHandler::Call(SpellScript* spellScript, Worl (spellScript->*pObjectTargetSelectHandlerScript)(target); } +SpellScript::DestinationTargetSelectHandler::DestinationTargetSelectHandler(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) + : TargetHook(_effIndex, _targetType, false, true) +{ + DestinationTargetSelectHandlerScript = _DestinationTargetSelectHandlerScript; +} + +void SpellScript::DestinationTargetSelectHandler::Call(SpellScript* spellScript, SpellDestination& target) +{ + (spellScript->*DestinationTargetSelectHandlerScript)(target); +} + bool SpellScript::_Validate(SpellInfo const* entry) { for (std::list<EffectHandler>::iterator itr = OnEffectLaunch.begin(); itr != OnEffectLaunch.end(); ++itr) @@ -306,6 +318,10 @@ bool SpellScript::_Validate(SpellInfo const* entry) if (!(*itr).GetAffectedEffectsMask(entry)) TC_LOG_ERROR("scripts", "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnObjectTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + for (std::list<DestinationTargetSelectHandler>::iterator itr = OnDestinationTargetSelect.begin(); itr != OnDestinationTargetSelect.end(); ++itr) + if (!(*itr).GetAffectedEffectsMask(entry)) + TC_LOG_ERROR("scripts", "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnDestinationTargetSelect` 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 75cf63b495b..dfa494e38e6 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -135,6 +135,7 @@ enum SpellScriptHookType SPELL_SCRIPT_HOOK_AFTER_HIT, SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT, SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT, + SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT, SPELL_SCRIPT_HOOK_CHECK_CAST, SPELL_SCRIPT_HOOK_BEFORE_CAST, SPELL_SCRIPT_HOOK_ON_CAST, @@ -158,7 +159,8 @@ class SpellScript : public _SpellScript typedef void(CLASSNAME::*SpellHitFnType)(); \ typedef void(CLASSNAME::*SpellCastFnType)(); \ typedef void(CLASSNAME::*SpellObjectAreaTargetSelectFnType)(std::list<WorldObject*>&); \ - typedef void(CLASSNAME::*SpellObjectTargetSelectFnType)(WorldObject*&); + typedef void(CLASSNAME::*SpellObjectTargetSelectFnType)(WorldObject*&); \ + typedef void(CLASSNAME::*SpellDestinationTargetSelectFnType)(SpellDestination&); SPELLSCRIPT_FUNCTION_TYPE_DEFINES(SpellScript) @@ -203,12 +205,13 @@ class SpellScript : public _SpellScript class TargetHook : public _SpellScript::EffectHook { public: - TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area); + TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area, bool _dest); bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex); std::string ToString(); protected: uint16 targetType; bool area; + bool dest; }; class ObjectAreaTargetSelectHandler : public TargetHook @@ -224,18 +227,28 @@ class SpellScript : public _SpellScript { public: ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); - void Call(SpellScript* spellScript, WorldObject*& targets); + void Call(SpellScript* spellScript, WorldObject*& target); private: SpellObjectTargetSelectFnType pObjectTargetSelectHandlerScript; }; + class DestinationTargetSelectHandler : public TargetHook + { + public: + DestinationTargetSelectHandler(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); + void Call(SpellScript* spellScript, SpellDestination& target); + private: + SpellDestinationTargetSelectFnType DestinationTargetSelectHandlerScript; + }; + #define SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \ class CastHandlerFunction : public SpellScript::CastHandler { public: CastHandlerFunction(SpellCastFnType _pCastHandlerScript) : SpellScript::CastHandler((SpellScript::SpellCastFnType)_pCastHandlerScript) { } }; \ class CheckCastHandlerFunction : public SpellScript::CheckCastHandler { public: CheckCastHandlerFunction(SpellCheckCastFnType _checkCastHandlerScript) : SpellScript::CheckCastHandler((SpellScript::SpellCheckCastFnType)_checkCastHandlerScript) { } }; \ class EffectHandlerFunction : public SpellScript::EffectHandler { public: EffectHandlerFunction(SpellEffectFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : SpellScript::EffectHandler((SpellScript::SpellEffectFnType)_pEffectHandlerScript, _effIndex, _effName) { } }; \ class HitHandlerFunction : public SpellScript::HitHandler { public: HitHandlerFunction(SpellHitFnType _pHitHandlerScript) : SpellScript::HitHandler((SpellScript::SpellHitFnType)_pHitHandlerScript) { } }; \ class ObjectAreaTargetSelectHandlerFunction : public SpellScript::ObjectAreaTargetSelectHandler { public: ObjectAreaTargetSelectHandlerFunction(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectAreaTargetSelectHandler((SpellScript::SpellObjectAreaTargetSelectFnType)_pObjectAreaTargetSelectHandlerScript, _effIndex, _targetType) { } }; \ - class ObjectTargetSelectHandlerFunction : public SpellScript::ObjectTargetSelectHandler { public: ObjectTargetSelectHandlerFunction(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectTargetSelectHandler((SpellScript::SpellObjectTargetSelectFnType)_pObjectTargetSelectHandlerScript, _effIndex, _targetType) { } }; + class ObjectTargetSelectHandlerFunction : public SpellScript::ObjectTargetSelectHandler { public: ObjectTargetSelectHandlerFunction(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectTargetSelectHandler((SpellScript::SpellObjectTargetSelectFnType)_pObjectTargetSelectHandlerScript, _effIndex, _targetType) { } }; \ + class DestinationTargetSelectHandlerFunction : public SpellScript::DestinationTargetSelectHandler { public: DestinationTargetSelectHandlerFunction(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::DestinationTargetSelectHandler((SpellScript::SpellDestinationTargetSelectFnType)_DestinationTargetSelectHandlerScript, _effIndex, _targetType) { } }; #define PrepareSpellScript(CLASSNAME) SPELLSCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) public: @@ -299,11 +312,17 @@ class SpellScript : public _SpellScript HookList<ObjectTargetSelectHandler> OnObjectTargetSelect; #define SpellObjectTargetSelectFn(F, I, N) ObjectTargetSelectHandlerFunction(&F, I, N) + // example: OnDestinationTargetSelect += SpellDestinationTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier); + // where function is void function(SpellDestination& target) + HookList<DestinationTargetSelectHandler> OnDestinationTargetSelect; + #define SpellDestinationTargetSelectFn(F, I, N) DestinationTargetSelectHandlerFunction(&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 // 3a. OnObjectAreaTargetSelect - executed just before adding selected targets to final target list (for area targets) // 3b. OnObjectTargetSelect - executed just before adding selected target to final target list (for single unit targets) + // 3c. OnDestinationTargetSelect - executed just before adding selected target to final target list (for destination 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 |