diff options
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 220 |
1 files changed, 127 insertions, 93 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 |
