mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 08:28:32 +01:00
Core/SpellScripts: Implemeted SpellScript hook OnDestinationTargetSelect to easier modify SpellDestinations
This commit is contained in:
@@ -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:
|
||||
{
|
||||
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());
|
||||
|
||||
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);
|
||||
|
||||
dest.Relocate(pos);
|
||||
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);
|
||||
|
||||
if (dist < objSize)
|
||||
dist = objSize;
|
||||
else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM)
|
||||
dist = objSize + (dist - objSize) * (float)rand_norm();
|
||||
|
||||
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);
|
||||
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;
|
||||
default:
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user