aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp5
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
-rw-r--r--src/server/game/Spells/Spell.h1
-rw-r--r--src/server/game/Spells/SpellEffects.cpp40
4 files changed, 33 insertions, 15 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 0089a3f8801..7518977c4e1 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -12313,9 +12313,12 @@ uint32 Unit::GetModelForForm(ShapeshiftForm form, uint32 spellId) const
return modelid;
}
-void Unit::JumpTo(float speedXY, float speedZ, bool forward)
+void Unit::JumpTo(float speedXY, float speedZ, bool forward, Optional<Position> dest)
{
float angle = forward ? 0 : float(M_PI);
+ if (dest)
+ angle += GetRelativeAngle(*dest);
+
if (GetTypeId() == TYPEID_UNIT)
GetMotionMaster()->MoveJumpTo(angle, speedXY, speedZ);
else
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 0ba397f4551..118bab0931c 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1108,7 +1108,7 @@ class TC_GAME_API Unit : public WorldObject
void UpdateHeight(float newZ);
void KnockbackFrom(float x, float y, float speedXY, float speedZ);
- void JumpTo(float speedXY, float speedZ, bool forward = true);
+ void JumpTo(float speedXY, float speedZ, bool forward = true, Optional<Position> dest = {});
void JumpTo(WorldObject* obj, float speedZ, bool withOrientation = false);
void MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath = false, bool forceDestination = false);
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index d3359ec70f8..840dec69b0f 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -342,6 +342,7 @@ class TC_GAME_API Spell
void EffectSendTaxi(SpellEffIndex effIndex);
void EffectKnockBack(SpellEffIndex effIndex);
void EffectPullTowards(SpellEffIndex effIndex);
+ void EffectPullTowardsDest(SpellEffIndex effIndex);
void EffectDispelMechanic(SpellEffIndex effIndex);
void EffectResurrectPet(SpellEffIndex effIndex);
void EffectDestroyAllTotems(SpellEffIndex effIndex);
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 116dac3c4ab..ba29fbe875f 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -207,7 +207,7 @@ SpellEffectHandlerFn SpellEffectHandlers[TOTAL_SPELL_EFFECTS] =
&Spell::EffectTriggerSpell, //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
&Spell::EffectUnused, //143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER
&Spell::EffectKnockBack, //144 SPELL_EFFECT_KNOCK_BACK_DEST
- &Spell::EffectPullTowards, //145 SPELL_EFFECT_PULL_TOWARDS_DEST Black Hole Effect
+ &Spell::EffectPullTowardsDest, //145 SPELL_EFFECT_PULL_TOWARDS_DEST Black Hole Effect
&Spell::EffectActivateRune, //146 SPELL_EFFECT_ACTIVATE_RUNE
&Spell::EffectQuestFail, //147 SPELL_EFFECT_QUEST_FAIL quest fail
&Spell::EffectTriggerMissileSpell, //148 SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
@@ -4392,23 +4392,37 @@ void Spell::EffectPullTowards(SpellEffIndex effIndex)
if (!unitTarget)
return;
+ float speedXY = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
+ float speedZ = damage / 10.0f;
Position pos;
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
- {
- if (m_targets.HasDst())
- pos.Relocate(*destTarget);
- else
- return;
- }
- else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
+ pos.Relocate(m_caster);
+
+ unitTarget->GetMotionMaster()->MoveJump(pos, speedXY, speedZ);
+}
+
+void Spell::EffectPullTowardsDest(SpellEffIndex effIndex)
+{
+ if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
+ return;
+
+ if (!unitTarget)
+ return;
+
+ if (!m_targets.HasDst())
{
- pos.Relocate(m_caster);
+ TC_LOG_ERROR("spells", "Spell %u with SPELL_EFFECT_PULL_TOWARDS_DEST has no dest target", m_spellInfo->Id);
+ return;
}
- float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f;
- float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
+ Position const* pos = m_targets.GetDstPos();
+ // This is a blizzlike mistake: this should be 2D distance according to projectile motion formulas, but Blizzard erroneously used 3D distance
+ float distXY = unitTarget->GetExactDist(pos);
+ float distZ = pos->GetPositionZ() - unitTarget->GetPositionZ();
- unitTarget->GetMotionMaster()->MoveJump(pos, speedXY, speedZ);
+ float speedXY = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
+ float speedZ = (2 * speedXY * speedXY * distZ + Movement::gravity * distXY * distXY) / (2 * speedXY * distXY);
+
+ unitTarget->JumpTo(speedXY, speedZ, true, *pos);
}
void Spell::EffectDispelMechanic(SpellEffIndex effIndex)