aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp241
-rwxr-xr-xsrc/server/game/Spells/Spell.h41
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp99
-rw-r--r--src/server/game/Spells/SpellInfo.cpp4
-rwxr-xr-xsrc/server/game/Spells/SpellScript.cpp17
-rwxr-xr-xsrc/server/game/Spells/SpellScript.h3
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp6
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp6
8 files changed, 223 insertions, 194 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 9ae298ebb13..2ffa94371f9 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -56,6 +56,35 @@
extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS];
+SpellDestination::SpellDestination()
+{
+ _position.Relocate(0, 0, 0, 0);
+ _transportGUID = 0;
+ _transportOffset.Relocate(0, 0, 0, 0);
+}
+
+SpellDestination::SpellDestination(float x, float y, float z, float orientation, uint32 mapId)
+{
+ _position.Relocate(x, y, z, orientation);
+ _transportGUID = 0;
+ _position.m_mapId = mapId;
+}
+
+SpellDestination::SpellDestination(Position const& pos)
+{
+ _position.Relocate(pos);
+ _transportGUID = 0;
+}
+
+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());
+}
+
+
SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0)
{
m_objectTarget = NULL;
@@ -65,12 +94,6 @@ SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0)
m_itemTargetGUID = 0;
m_itemTargetEntry = 0;
- m_srcTransGUID = 0;
- m_srcTransOffset.Relocate(0, 0, 0, 0);
- m_srcPos.Relocate(0, 0, 0, 0);
- m_dstTransGUID = 0;
- m_dstTransOffset.Relocate(0, 0, 0, 0);
- m_dstPos.Relocate(0, 0, 0, 0);
m_strTarget = "";
m_targetMask = 0;
}
@@ -94,36 +117,36 @@ void SpellCastTargets::Read(ByteBuffer& data, Unit* caster)
if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION)
{
- data.readPackGUID(m_srcTransGUID);
- if (m_srcTransGUID)
- data >> m_srcTransOffset.PositionXYZStream();
+ data.readPackGUID(m_src._transportGUID);
+ if (m_src._transportGUID)
+ data >> m_src._transportOffset.PositionXYZStream();
else
- data >> m_srcPos.PositionXYZStream();
+ data >> m_src._position.PositionXYZStream();
}
else
{
- m_srcTransGUID = caster->GetTransGUID();
- if (m_srcTransGUID)
- m_srcTransOffset.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO());
+ m_src._transportGUID = caster->GetTransGUID();
+ if (m_src._transportGUID)
+ m_src._transportOffset.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO());
else
- m_srcPos.Relocate(caster);
+ m_src._position.Relocate(caster);
}
if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
{
- data.readPackGUID(m_dstTransGUID);
- if (m_dstTransGUID)
- data >> m_dstTransOffset.PositionXYZStream();
+ data.readPackGUID(m_dst._transportGUID);
+ if (m_dst._transportGUID)
+ data >> m_dst._transportOffset.PositionXYZStream();
else
- data >> m_dstPos.PositionXYZStream();
+ data >> m_dst._position.PositionXYZStream();
}
else
{
- m_dstTransGUID = caster->GetTransGUID();
- if (m_dstTransGUID)
- m_dstTransOffset.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO());
+ m_dst._transportGUID = caster->GetTransGUID();
+ if (m_dst._transportGUID)
+ m_dst._transportOffset.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO());
else
- m_dstPos.Relocate(caster);
+ m_dst._position.Relocate(caster);
}
if (m_targetMask & TARGET_FLAG_STRING)
@@ -149,20 +172,20 @@ void SpellCastTargets::Write(ByteBuffer& data)
if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION)
{
- data.appendPackGUID(m_srcTransGUID); // relative position guid here - transport for example
- if (m_srcTransGUID)
- data << m_srcTransOffset.PositionXYZStream();
+ data.appendPackGUID(m_src._transportGUID); // relative position guid here - transport for example
+ if (m_src._transportGUID)
+ data << m_src._transportOffset.PositionXYZStream();
else
- data << m_srcPos.PositionXYZStream();
+ data << m_src._position.PositionXYZStream();
}
if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
{
- data.appendPackGUID(m_dstTransGUID); // relative position guid here - transport for example
- if (m_dstTransGUID)
- data << m_dstTransOffset.PositionXYZStream();
+ data.appendPackGUID(m_dst._transportGUID); // relative position guid here - transport for example
+ if (m_dst._transportGUID)
+ data << m_dst._transportOffset.PositionXYZStream();
else
- data << m_dstPos.PositionXYZStream();
+ data << m_dst._position.PositionXYZStream();
}
if (m_targetMask & TARGET_FLAG_STRING)
@@ -295,31 +318,31 @@ void SpellCastTargets::UpdateTradeSlotItem()
}
}
-Position const* SpellCastTargets::GetSrc() const
+SpellDestination const* SpellCastTargets::GetSrc() const
+{
+ return &m_src;
+}
+
+Position const* SpellCastTargets::GetSrcPos() const
{
- return &m_srcPos;
+ return &m_src._position;
}
void SpellCastTargets::SetSrc(float x, float y, float z)
{
- m_srcPos.Relocate(x, y, z);
- m_srcTransGUID = 0;
+ m_src = SpellDestination(x, y, z);
m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
}
void SpellCastTargets::SetSrc(Position const& pos)
{
- m_srcPos.Relocate(pos);
- m_srcTransGUID = 0;
+ m_src = SpellDestination(pos);
m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
}
void SpellCastTargets::SetSrc(WorldObject const& wObj)
{
- uint64 guid = wObj.GetTransGUID();
- m_srcTransGUID = guid;
- m_srcTransOffset.Relocate(wObj.GetTransOffsetX(), wObj.GetTransOffsetY(), wObj.GetTransOffsetZ(), wObj.GetTransOffsetO());
- m_srcPos.Relocate(wObj);
+ m_src = SpellDestination(wObj);
m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
}
@@ -327,13 +350,13 @@ void SpellCastTargets::ModSrc(Position const& pos)
{
ASSERT(m_targetMask & TARGET_FLAG_SOURCE_LOCATION);
- if (m_srcTransGUID)
+ if (m_src._transportGUID)
{
Position offset;
- m_srcPos.GetPositionOffsetTo(pos, offset);
- m_srcTransOffset.RelocateOffset(offset);
+ m_src._position.GetPositionOffsetTo(pos, offset);
+ m_src._transportOffset.RelocateOffset(offset);
}
- m_srcPos.Relocate(pos);
+ m_src._position.Relocate(pos);
}
void SpellCastTargets::RemoveSrc()
@@ -341,41 +364,37 @@ void SpellCastTargets::RemoveSrc()
m_targetMask &= ~(TARGET_FLAG_SOURCE_LOCATION);
}
-WorldLocation const* SpellCastTargets::GetDst() const
+SpellDestination const* SpellCastTargets::GetDst() const
{
- return &m_dstPos;
+ return &m_dst;
+}
+
+WorldLocation const* SpellCastTargets::GetDstPos() const
+{
+ return &m_dst._position;
}
void SpellCastTargets::SetDst(float x, float y, float z, float orientation, uint32 mapId)
{
- m_dstPos.Relocate(x, y, z, orientation);
- m_dstTransGUID = 0;
+ m_dst = SpellDestination(x, y, z, orientation, mapId);
m_targetMask |= TARGET_FLAG_DEST_LOCATION;
- if (mapId != MAPID_INVALID)
- m_dstPos.m_mapId = mapId;
}
void SpellCastTargets::SetDst(Position const& pos)
{
- m_dstPos.Relocate(pos);
- m_dstTransGUID = 0;
+ m_dst = SpellDestination(pos);
m_targetMask |= TARGET_FLAG_DEST_LOCATION;
}
void SpellCastTargets::SetDst(WorldObject const& wObj)
{
- uint64 guid = wObj.GetTransGUID();
- m_dstTransGUID = guid;
- m_dstTransOffset.Relocate(wObj.GetTransOffsetX(), wObj.GetTransOffsetY(), wObj.GetTransOffsetZ(), wObj.GetTransOffsetO());
- m_dstPos.Relocate(wObj);
+ m_dst = SpellDestination(wObj);
m_targetMask |= TARGET_FLAG_DEST_LOCATION;
}
void SpellCastTargets::SetDst(SpellCastTargets const& spellTargets)
{
- m_dstTransGUID = spellTargets.m_dstTransGUID;
- m_dstTransOffset.Relocate(spellTargets.m_dstTransOffset);
- m_dstPos.Relocate(spellTargets.m_dstPos);
+ m_dst = spellTargets.m_dst;
m_targetMask |= TARGET_FLAG_DEST_LOCATION;
}
@@ -383,13 +402,13 @@ void SpellCastTargets::ModDst(Position const& pos)
{
ASSERT(m_targetMask & TARGET_FLAG_DEST_LOCATION);
- if (m_dstTransGUID)
+ if (m_dst._transportGUID)
{
Position offset;
- m_dstPos.GetPositionOffsetTo(pos, offset);
- m_dstTransOffset.RelocateOffset(offset);
+ m_dst._position.GetPositionOffsetTo(pos, offset);
+ m_dst._transportOffset.RelocateOffset(offset);
}
- m_dstPos.Relocate(pos);
+ m_dst._position.Relocate(pos);
}
void SpellCastTargets::RemoveDst()
@@ -417,21 +436,21 @@ void SpellCastTargets::Update(Unit* caster)
}
// update positions by transport move
- if (HasSrc() && m_srcTransGUID)
+ if (HasSrc() && m_src._transportGUID)
{
- if (WorldObject* transport = ObjectAccessor::GetWorldObject(*caster, m_srcTransGUID))
+ if (WorldObject* transport = ObjectAccessor::GetWorldObject(*caster, m_src._transportGUID))
{
- m_srcPos.Relocate(transport);
- m_srcPos.RelocateOffset(m_srcTransOffset);
+ m_src._position.Relocate(transport);
+ m_src._position.RelocateOffset(m_src._transportOffset);
}
}
- if (HasDst() && m_dstTransGUID)
+ if (HasDst() && m_dst._transportGUID)
{
- if (WorldObject* transport = ObjectAccessor::GetWorldObject(*caster, m_dstTransGUID))
+ if (WorldObject* transport = ObjectAccessor::GetWorldObject(*caster, m_dst._transportGUID))
{
- m_dstPos.Relocate(transport);
- m_dstPos.RelocateOffset(m_dstTransOffset);
+ m_dst._position.Relocate(transport);
+ m_dst._position.RelocateOffset(m_dst._transportOffset);
}
}
}
@@ -449,9 +468,9 @@ void SpellCastTargets::OutDebug() const
if (m_targetMask & TARGET_FLAG_TRADE_ITEM)
sLog->outString("Trade item target: " UI64FMTD, m_itemTargetGUID);
if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION)
- sLog->outString("Source location: transport guid:" UI64FMTD " trans offset: %s position: %s", m_srcTransGUID, m_srcTransOffset.ToString().c_str(), m_srcPos.ToString().c_str());
+ sLog->outString("Source location: transport guid:" UI64FMTD " trans offset: %s position: %s", m_src._transportGUID, m_src._transportOffset.ToString().c_str(), m_src._position.ToString().c_str());
if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
- sLog->outString("Destination location: transport guid:" UI64FMTD " trans offset: %s position: %s", m_dstTransGUID, m_dstTransOffset.ToString().c_str(), m_dstPos.ToString().c_str());
+ sLog->outString("Destination location: transport guid:" UI64FMTD " trans offset: %s position: %s", m_dst._transportGUID, m_dst._transportOffset.ToString().c_str(), m_dst._position.ToString().c_str());
if (m_targetMask & TARGET_FLAG_STRING)
sLog->outString("String: %s", m_strTarget.c_str());
sLog->outString("speed: %f", m_speed);
@@ -564,6 +583,11 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme
CleanupTargetList();
CleanupEffectExecuteData();
+
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ m_destTargets[i] = SpellDestination(*m_caster);
+ }
}
Spell::~Spell()
@@ -720,6 +744,9 @@ void Spell::SelectSpellTargets()
// some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
SelectEffectTypeImplicitTargets(i);
+ if (m_targets.HasDst())
+ AddDestTarget(*m_targets.GetDst(), i);
+
if (m_spellInfo->IsChanneled())
{
uint8 mask = (1 << i);
@@ -767,7 +794,7 @@ void Spell::SelectSpellTargets()
}
else if (m_spellInfo->Speed > 0.0f)
{
- float dist = m_caster->GetDistance(*m_targets.GetDst());
+ float dist = m_caster->GetDistance(*m_targets.GetDstPos());
m_delayMoment = (uint64) floor(dist / m_spellInfo->Speed * 1000.0f);
}
}
@@ -1092,10 +1119,10 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
switch (targetType.GetReferenceType())
{
case TARGET_REFERENCE_TYPE_SRC:
- center = m_targets.GetSrc();
+ center = m_targets.GetSrcPos();
break;
case TARGET_REFERENCE_TYPE_DEST:
- center = m_targets.GetDst();
+ center = m_targets.GetDstPos();
break;
case TARGET_REFERENCE_TYPE_CASTER:
case TARGET_REFERENCE_TYPE_TARGET:
@@ -1467,7 +1494,7 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT
if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
dist *= (float)rand_norm();
- Position pos = *m_targets.GetDst();
+ Position pos = *m_targets.GetDstPos();
m_caster->MovePosition(pos, dist, angle);
m_targets.ModDst(pos);
}
@@ -1581,12 +1608,12 @@ void Spell::SelectImplicitTrajTargets()
if (!dist2d)
return;
- float srcToDestDelta = m_targets.GetDst()->m_positionZ - m_targets.GetSrc()->m_positionZ;
+ float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - m_targets.GetSrcPos()->m_positionZ;
std::list<WorldObject*> targets;
- Trinity::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrc(), m_caster, m_spellInfo);
+ Trinity::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrcPos(), m_caster, m_spellInfo);
Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellTrajTargetCheck> searcher(m_caster, targets, check, GRID_MAP_TYPE_MASK_ALL);
- SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrc(), dist2d);
+ SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrcPos(), dist2d);
if (targets.empty())
return;
@@ -1609,8 +1636,8 @@ void Spell::SelectImplicitTrajTargets()
const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
// TODO: all calculation should be based on src instead of m_caster
- const float objDist2d = m_targets.GetSrc()->GetExactDist2d(*itr) * cos(m_targets.GetSrc()->GetRelativeAngle(*itr));
- const float dz = (*itr)->GetPositionZ() - m_targets.GetSrc()->m_positionZ;
+ const float objDist2d = m_targets.GetSrcPos()->GetExactDist2d(*itr) * cos(m_targets.GetSrcPos()->GetRelativeAngle(*itr));
+ const float dz = (*itr)->GetPositionZ() - m_targets.GetSrcPos()->m_positionZ;
DEBUG_TRAJ(sLog->outError("Spell::SelectTrajTargets: check %u, dist between %f %f, height between %f %f.", (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);)
@@ -1675,11 +1702,11 @@ void Spell::SelectImplicitTrajTargets()
}
}
- if (m_targets.GetSrc()->GetExactDist2d(m_targets.GetDst()) > bestDist)
+ if (m_targets.GetSrcPos()->GetExactDist2d(m_targets.GetDstPos()) > bestDist)
{
- float x = m_targets.GetSrc()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
- float y = m_targets.GetSrc()->m_positionY + sin(m_caster->GetOrientation()) * bestDist;
- float z = m_targets.GetSrc()->m_positionZ + bestDist * (a * bestDist + b);
+ float x = m_targets.GetSrcPos()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
+ float y = m_targets.GetSrcPos()->m_positionY + sin(m_caster->GetOrientation()) * bestDist;
+ float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
if (itr != targets.end())
{
@@ -2216,12 +2243,6 @@ void Spell::AddGOTarget(GameObject* go, uint32 effectMask)
m_UniqueGOTargetInfo.push_back(target);
}
-void Spell::AddGOTarget(uint64 goGUID, uint32 effectMask)
-{
- if (GameObject* go = m_caster->GetMap()->GetGameObject(goGUID))
- AddGOTarget(go, effectMask);
-}
-
void Spell::AddItemTarget(Item* item, uint32 effectMask)
{
for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
@@ -2251,6 +2272,11 @@ void Spell::AddItemTarget(Item* item, uint32 effectMask)
m_UniqueItemInfo.push_back(target);
}
+void Spell::AddDestTarget(SpellDestination const& dest, uint32 effIndex)
+{
+ m_destTargets[effIndex] = dest;
+}
+
void Spell::DoAllEffectOnTarget(TargetInfo* target)
{
if (!target || target->processed)
@@ -4577,6 +4603,7 @@ void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOT
unitTarget = pUnitTarget;
itemTarget = pItemTarget;
gameObjTarget = pGOTarget;
+ destTarget = &m_destTargets[i]._position;
uint8 eff = m_spellInfo->Effects[i].Effect;
@@ -4817,7 +4844,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if (m_targets.HasDst())
{
float x, y, z;
- m_targets.GetDst()->GetPosition(x, y, z);
+ m_targets.GetDstPos()->GetPosition(x, y, z);
if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOS(x, y, z))
return SPELL_FAILED_LINE_OF_SIGHT;
@@ -5754,9 +5781,9 @@ SpellCastResult Spell::CheckRange(bool strict)
if (m_targets.HasDst() && !m_targets.HasTraj())
{
- if (!m_caster->IsWithinDist3d(m_targets.GetDst(), max_range))
+ if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
return SPELL_FAILED_OUT_OF_RANGE;
- if (min_range && m_caster->IsWithinDist3d(m_targets.GetDst(), min_range))
+ if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
return SPELL_FAILED_TOO_CLOSE;
}
@@ -6403,6 +6430,30 @@ void Spell::UpdatePointers()
m_CastItem = m_caster->ToPlayer()->GetItemByGuid(m_castItemGUID);
m_targets.Update(m_caster);
+
+ // further actions done only for dest targets
+ if (!m_targets.HasDst())
+ return;
+
+ // cache last transport
+ WorldObject* transport = NULL;
+
+ // update effect destinations (in case of moved transport dest target)
+ for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
+ {
+ SpellDestination& dest = m_destTargets[effIndex];
+ if (!dest._transportGUID)
+ continue;
+
+ if (!transport || transport->GetGUID() != dest._transportGUID)
+ transport = ObjectAccessor::GetWorldObject(*m_caster, dest._transportGUID);
+
+ if (transport)
+ {
+ dest._position.Relocate(transport);
+ dest._position.RelocateOffset(dest._transportOffset);
+ }
+ }
}
CurrentSpellTypes Spell::GetCurrentContainer() const
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 971bc1989ab..f897092e519 100755
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -79,6 +79,18 @@ enum SpellRangeFlag
SPELL_RANGE_RANGED = 2, //hunter range and ranged weapon
};
+struct SpellDestination
+{
+ SpellDestination();
+ SpellDestination(float x, float y, float z, float orientation = 0.0f, uint32 mapId = MAPID_INVALID);
+ SpellDestination(Position const& pos);
+ SpellDestination(WorldObject const& wObj);
+
+ WorldLocation _position;
+ uint64 _transportGUID;
+ Position _transportOffset;
+};
+
class SpellCastTargets
{
public:
@@ -115,14 +127,16 @@ class SpellCastTargets
void SetTradeItemTarget(Player* caster);
void UpdateTradeSlotItem();
- Position const* GetSrc() const;
+ SpellDestination const* GetSrc() const;
+ Position const* GetSrcPos() const;
void SetSrc(float x, float y, float z);
void SetSrc(Position const& pos);
void SetSrc(WorldObject const& wObj);
void ModSrc(Position const& pos);
void RemoveSrc();
- WorldLocation const* GetDst() const;
+ SpellDestination const* GetDst() const;
+ WorldLocation const* GetDstPos() const;
void SetDst(float x, float y, float z, float orientation, uint32 mapId = MAPID_INVALID);
void SetDst(Position const& pos);
void SetDst(WorldObject const& wObj);
@@ -139,7 +153,7 @@ class SpellCastTargets
float GetSpeed() const { return m_speed; }
void SetSpeed(float speed) { m_speed = speed; }
- float GetDist2d() const { return m_srcPos.GetExactDist2d(&m_dstPos); }
+ float GetDist2d() const { return m_src._position.GetExactDist2d(&m_dst._position); }
float GetSpeedXY() const { return m_speed * cos(m_elevation); }
float GetSpeedZ() const { return m_speed * sin(m_elevation); }
@@ -158,13 +172,8 @@ class SpellCastTargets
uint64 m_itemTargetGUID;
uint32 m_itemTargetEntry;
- uint64 m_srcTransGUID;
- Position m_srcTransOffset;
- Position m_srcPos;
-
- uint64 m_dstTransGUID;
- Position m_dstTransOffset;
- WorldLocation m_dstPos;
+ SpellDestination m_src;
+ SpellDestination m_dst;
float m_elevation, m_speed;
std::string m_strTarget;
@@ -197,11 +206,6 @@ enum SpellEffectHandleMode
SPELL_EFFECT_HANDLE_HIT_TARGET,
};
-namespace Trinity
-{
- struct SpellNotifierCreatureAndPlayer;
-}
-
class Spell
{
friend void Unit::SetCurrentCastedSpell(Spell* pSpell);
@@ -529,6 +533,7 @@ class Spell
Unit* unitTarget;
Item* itemTarget;
GameObject* gameObjTarget;
+ WorldLocation* destTarget;
int32 damage;
SpellEffectHandleMode effectHandleMode;
// used in effects handlers
@@ -589,10 +594,13 @@ class Spell
};
std::list<ItemTargetInfo> m_UniqueItemInfo;
+ SpellDestination m_destTargets[MAX_SPELL_EFFECTS];
+
void AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid = true);
void AddGOTarget(GameObject* target, uint32 effectMask);
- void AddGOTarget(uint64 goGUID, uint32 effectMask);
void AddItemTarget(Item* item, uint32 effectMask);
+ void AddDestTarget(SpellDestination const& dest, uint32 effIndex);
+
void DoAllEffectOnTarget(TargetInfo* target);
SpellMissInfo DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleAura);
void DoTriggersOnSpellHit(Unit* unit, uint8 effMask);
@@ -631,7 +639,6 @@ class Spell
HitTriggerSpells m_hitTriggerSpells;
// effect helpers
- void GetSummonPosition(uint32 i, Position &pos, float radius = 0.0f, uint32 count = 0);
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const* properties, uint32 numSummons);
void CalculateJumpSpeeds(uint8 i, float dist, float & speedxy, float & speedz);
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 511d2877f24..59b6d8971cf 100755
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -800,7 +800,7 @@ void Spell::EffectDummy(SpellEffIndex effIndex)
bp = 46585;
if (m_targets.HasDst())
- targets.SetDst(*m_targets.GetDst());
+ targets.SetDst(*m_targets.GetDstPos());
else
{
targets.SetDst(*m_caster);
@@ -814,8 +814,7 @@ void Spell::EffectDummy(SpellEffIndex effIndex)
// Raise dead - take reagents and trigger summon spells
case 48289:
if (m_targets.HasDst())
- targets.SetDst(*m_targets.GetDst());
-
+ targets.SetDst(*m_targets.GetDstPos());
spell_id = CalculateDamage(0, NULL);
break;
}
@@ -1177,7 +1176,7 @@ void Spell::EffectJumpDest(SpellEffIndex effIndex)
// Init dest coordinates
float x, y, z;
- m_targets.GetDst()->GetPosition(x, y, z);
+ destTarget->GetPosition(x, y, z);
float speedXY, speedZ;
CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(x, y), speedXY, speedZ);
@@ -1250,11 +1249,11 @@ void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/)
}
// Init dest coordinates
- uint32 mapid = m_targets.GetDst()->GetMapId();
+ uint32 mapid = destTarget->GetMapId();
if (mapid == MAPID_INVALID)
mapid = unitTarget->GetMapId();
float x, y, z, orientation;
- m_targets.GetDst()->GetPosition(x, y, z, orientation);
+ destTarget->GetPosition(x, y, z, orientation);
if (!orientation && m_targets.GetUnitTarget())
orientation = m_targets.GetUnitTarget()->GetOrientation();
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell::EffectTeleportUnits - teleport unit to %u %f %f %f %f\n", mapid, x, y, z, orientation);
@@ -1883,7 +1882,7 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex)
if (!caster->IsInWorld())
return;
DynamicObject* dynObj = new DynamicObject(false);
- if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, *m_targets.GetDst(), radius, DYNAMIC_OBJECT_AREA_SPELL))
+ if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL))
{
delete dynObj;
return;
@@ -2357,9 +2356,6 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
if (Player* modOwner = m_originalCaster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
- Position pos;
- GetSummonPosition(effIndex, pos);
-
TempSummon* summon = NULL;
// determine how many units should be summoned
@@ -2413,11 +2409,11 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
// Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
case SUMMON_TYPE_VEHICLE:
case SUMMON_TYPE_VEHICLE2:
- summon = m_caster->GetMap()->SummonCreature(entry, pos, properties, duration, m_originalCaster, m_spellInfo->Id);
+ summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id);
break;
case SUMMON_TYPE_TOTEM:
{
- summon = m_caster->GetMap()->SummonCreature(entry, pos, properties, duration, m_originalCaster, m_spellInfo->Id);
+ summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id);
if (!summon || !summon->isTotem())
return;
@@ -2434,7 +2430,7 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
}
case SUMMON_TYPE_MINIPET:
{
- summon = m_caster->GetMap()->SummonCreature(entry, pos, properties, duration, m_originalCaster, m_spellInfo->Id);
+ summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id);
if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
return;
@@ -2454,9 +2450,14 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
for (uint32 count = 0; count < numSummons; ++count)
{
- GetSummonPosition(effIndex, pos, radius, count);
+ Position pos;
+ if (count == 0)
+ pos = *destTarget;
+ else
+ // randomize position for multiple summons
+ m_caster->GetRandomPoint(*destTarget, radius, pos);
- summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration);
+ summon = m_originalCaster->SummonCreature(entry, *destTarget, summonType, duration);
if (!summon)
continue;
@@ -2477,14 +2478,14 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
SummonGuardian(effIndex, entry, properties, numSummons);
break;
case SUMMON_CATEGORY_PUPPET:
- summon = m_caster->GetMap()->SummonCreature(entry, pos, properties, duration, m_originalCaster, m_spellInfo->Id);
+ summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id);
break;
case SUMMON_CATEGORY_VEHICLE:
// Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
// to cast a ride vehicle spell on the summoned unit.
float x, y, z;
m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
- summon = m_originalCaster->GetMap()->SummonCreature(entry, pos, properties, duration, m_caster, m_spellInfo->Id);
+ summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id);
if (!summon || !summon->IsVehicle())
return;
@@ -2706,7 +2707,7 @@ void Spell::EffectDistract(SpellEffIndex /*effIndex*/)
if (unitTarget->HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING))
return;
- unitTarget->SetFacingTo(unitTarget->GetAngle(m_targets.GetDst()));
+ unitTarget->SetFacingTo(unitTarget->GetAngle(destTarget));
unitTarget->ClearUnitState(UNIT_STATE_MOVING);
if (unitTarget->GetTypeId() == TYPEID_UNIT)
@@ -2745,7 +2746,7 @@ void Spell::EffectAddFarsight(SpellEffIndex effIndex)
return;
DynamicObject* dynObj = new DynamicObject(true);
- if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, *m_targets.GetDst(), radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
+ if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
{
delete dynObj;
return;
@@ -3689,7 +3690,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex)
float x, y, z;
if (m_targets.HasDst())
- m_targets.GetDst()->GetPosition(x, y, z);
+ destTarget->GetPosition(x, y, z);
else
m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
@@ -4232,7 +4233,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
float radius = m_spellInfo->Effects[effIndex].CalcRadius();
for (uint8 i = 0; i < 15; ++i)
{
- m_caster->GetRandomPoint(*m_targets.GetDst(), radius, x, y, z);
+ m_caster->GetRandomPoint(*destTarget, radius, x, y, z);
m_caster->CastSpell(x, y, z, 54522, true);
}
break;
@@ -5268,7 +5269,7 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex)
float x, y, z;
// If dest location if present
if (m_targets.HasDst())
- m_targets.GetDst()->GetPosition(x, y, z);
+ destTarget->GetPosition(x, y, z);
// Summon in random point all other units if location present
else
m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
@@ -5398,7 +5399,7 @@ void Spell::EffectLeap(SpellEffIndex /*effIndex*/)
return;
Position pos;
- m_targets.GetDst()->GetPosition(&pos);
+ destTarget->GetPosition(&pos);
unitTarget->GetFirstCollisionPosition(pos, unitTarget->GetDistance(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + 2.0f), 0.0f);
unitTarget->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), unitTarget == m_caster);
}
@@ -5569,7 +5570,7 @@ void Spell::EffectChargeDest(SpellEffIndex /*effIndex*/)
if (m_targets.HasDst())
{
Position pos;
- m_targets.GetDst()->GetPosition(&pos);
+ destTarget->GetPosition(&pos);
float angle = m_caster->GetRelativeAngle(pos.GetPositionX(), pos.GetPositionY());
float dist = m_caster->GetDistance(pos);
m_caster->GetFirstCollisionPosition(pos, dist, angle);
@@ -5620,7 +5621,7 @@ void Spell::EffectKnockBack(SpellEffIndex effIndex)
if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
{
if (m_targets.HasDst())
- m_targets.GetDst()->GetPosition(x, y);
+ destTarget->GetPosition(x, y);
else
return;
}
@@ -5708,7 +5709,7 @@ void Spell::EffectPullTowards(SpellEffIndex effIndex)
if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
{
if (m_targets.HasDst())
- pos.Relocate(*m_targets.GetDst());
+ pos.Relocate(*destTarget);
else
return;
}
@@ -5895,7 +5896,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
float fx, fy, fz;
if (m_targets.HasDst())
- m_targets.GetDst()->GetPosition(fx, fy, fz);
+ destTarget->GetPosition(fx, fy, fz);
//FIXME: this can be better check for most objects but still hack
else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
{
@@ -6476,7 +6477,11 @@ void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const*
for (uint32 count = 0; count < numGuardians; ++count)
{
Position pos;
- GetSummonPosition(i, pos, radius, count);
+ if (count == 0)
+ pos = *destTarget;
+ else
+ // randomize position for multiple summons
+ m_caster->GetRandomPoint(*destTarget, radius, pos);
TempSummon* summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id);
if (!summon)
@@ -6507,44 +6512,6 @@ void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const*
}
}
-void Spell::GetSummonPosition(uint32 i, Position &pos, float radius, uint32 count)
-{
- pos.SetOrientation(m_caster->GetOrientation());
-
- if (m_targets.HasDst())
- {
- // Summon 1 unit in dest location
- if (count == 0)
- pos.Relocate(*m_targets.GetDst());
- // Summon in random point all other units if location present
- else
- {
- //This is a workaround. Do not have time to write much about it
- switch (m_spellInfo->Effects[i].TargetA.GetTarget())
- {
- case TARGET_DEST_CASTER_SUMMON:
- case TARGET_DEST_CASTER_RANDOM:
- m_caster->GetNearPosition(pos, radius * (float)rand_norm(), (float)rand_norm()*static_cast<float>(2*M_PI));
- break;
- case TARGET_DEST_DEST_RANDOM:
- case TARGET_DEST_TARGET_RANDOM:
- m_caster->GetRandomPoint(*m_targets.GetDst(), radius, pos);
- break;
- default:
- pos.Relocate(*m_targets.GetDst());
- break;
- }
- }
- }
- // Summon if dest location not present near caster
- else
- {
- float x, y, z;
- m_caster->GetClosePoint(x, y, z, 3.0f);
- pos.Relocate(x, y, z);
- }
-}
-
void Spell::EffectRenamePet(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 5b0e453edc9..b95ee766f38 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -99,7 +99,7 @@ float SpellImplicitTargetInfo::CalcDirectionAngle() const
case TARGET_DIR_LEFT:
return static_cast<float>(M_PI/2);
case TARGET_DIR_FRONT_RIGHT:
- return static_cast<float>(M_PI/4);
+ return static_cast<float>(-M_PI/4);
case TARGET_DIR_BACK_RIGHT:
return static_cast<float>(-3*M_PI/4);
case TARGET_DIR_BACK_LEFT:
@@ -614,7 +614,7 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] =
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 66 SPELL_EFFECT_CREATE_MANA_GEM
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 68 SPELL_EFFECT_INTERRUPT_CAST
- {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 69 SPELL_EFFECT_DISTRACT
+ {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 69 SPELL_EFFECT_DISTRACT
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 70 SPELL_EFFECT_PULL
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 71 SPELL_EFFECT_PICKPOCKET
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 72 SPELL_EFFECT_ADD_FARSIGHT
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 03fea614c0d..81f8bbd78c5 100755
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -323,7 +323,7 @@ SpellInfo const* SpellScript::GetSpellInfo()
WorldLocation const* SpellScript::GetTargetDest()
{
if (m_spell->m_targets.HasDst())
- return m_spell->m_targets.GetDst();
+ return m_spell->m_targets.GetDstPos();
return NULL;
}
@@ -403,6 +403,16 @@ GameObject* SpellScript::GetHitGObj()
return m_spell->gameObjTarget;
}
+WorldLocation const* SpellScript::GetHitDest()
+{
+ if (!IsInEffectHook())
+ {
+ sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitGObj was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId);
+ return NULL;
+ }
+ return m_spell->destTarget;
+}
+
int32 SpellScript::GetHitDamage()
{
if (!IsInTargetHook())
@@ -468,11 +478,6 @@ void SpellScript::PreventHitAura()
m_spell->m_spellAura->Remove();
}
-void SpellScript::GetSummonPosition(uint32 i, Position &pos, float radius = 0.0f, uint32 count = 0)
-{
- m_spell->GetSummonPosition(i, pos, radius, count);
-}
-
void SpellScript::PreventHitEffect(SpellEffIndex effIndex)
{
if (!IsInHitPhase() && !IsInEffectHook())
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 1bf8d25adef..e84a56c8dbb 100755
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -324,6 +324,8 @@ class SpellScript : public _SpellScript
Item* GetHitItem();
// returns: target of current effect if it was GameObject otherwise NULL
GameObject* GetHitGObj();
+ // returns: destination of current effect
+ WorldLocation const* GetHitDest();
// setter/getter for for damage done by spell to target of spell hit
// returns damage calculated before hit, and real dmg done after hit
int32 GetHitDamage();
@@ -335,7 +337,6 @@ class SpellScript : public _SpellScript
void SetHitHeal(int32 heal);
void PreventHitHeal() { SetHitHeal(0); }
Spell* GetSpell() { return m_spell; }
- void GetSummonPosition(uint32 i, Position &pos, float radius, uint32 count);
// returns current spell hit target aura
Aura* GetHitAura();
// prevents applying aura on current spell hit target
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
index 408ebf3cc96..98b20f1c424 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
@@ -1756,7 +1756,7 @@ class spell_vehicle_throw_passenger : public SpellScriptLoader
if (Unit* device = seat->GetPassenger(2))
if (!device->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
{
- float dist = unit->GetExactDistSq(targets.GetDst());
+ float dist = unit->GetExactDistSq(targets.GetDstPos());
if (dist < minDist)
{
minDist = dist;
@@ -1764,13 +1764,13 @@ class spell_vehicle_throw_passenger : public SpellScriptLoader
}
}
}
- if (target && target->IsWithinDist2d(targets.GetDst(), GetSpellInfo()->Effects[effIndex].CalcRadius() * 2)) // now we use *2 because the location of the seat is not correct
+ if (target && target->IsWithinDist2d(targets.GetDstPos(), GetSpellInfo()->Effects[effIndex].CalcRadius() * 2)) // now we use *2 because the location of the seat is not correct
passenger->EnterVehicle(target, 0);
else
{
passenger->ExitVehicle();
float x, y, z;
- targets.GetDst()->GetPosition(x, y, z);
+ targets.GetDstPos()->GetPosition(x, y, z);
passenger->GetMotionMaster()->MoveJump(x, y, z, targets.GetSpeedXY(), targets.GetSpeedZ());
}
}
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index ee554f4875a..a6128591e71 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -772,13 +772,11 @@ class spell_dk_death_grip : public SpellScriptLoader
void HandleDummy(SpellEffIndex effIndex)
{
int32 damage = GetEffectValue();
- Position pos;
+ Position const* pos = GetTargetDest();
if (Unit* target = GetHitUnit())
{
- GetSummonPosition(effIndex, pos, 0.0f, 0);
-
if (!target->HasAuraType(SPELL_AURA_DEFLECT_SPELLS)) // Deterrence
- target->CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), damage, true);
+ target->CastSpell(pos->GetPositionX(), pos->GetPositionY(), pos->GetPositionZ(), damage, true);
}
}