aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells/Spell.cpp
diff options
context:
space:
mode:
authorAlan Deutscher <adeutscher@gmail.com>2022-07-10 18:55:15 -0700
committerShauren <shauren.trinity@gmail.com>2022-09-05 22:23:02 +0200
commitff99952dfb7d2b532de2d1aedc825fb96038f4c2 (patch)
tree3d71265e0562a366e0d358ebfe20322ec1f51a97 /src/server/game/Spells/Spell.cpp
parenta1ddf5195b8d03ea87248b7037a3e50e3e793d8e (diff)
Core/Spells: Delay combat flagging for spell targets until spell missile lands
(cherry picked from commit b59706c8b6856bdfe084a38330773725d3404f05)
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
-rw-r--r--src/server/game/Spells/Spell.cpp51
1 files changed, 46 insertions, 5 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index f49f0495339..c5b7ee28286 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2253,6 +2253,37 @@ void Spell::CleanupTargetList()
m_delayMoment = 0;
}
+class ProcImpactDelayed : public BasicEvent
+{
+public:
+ ProcImpactDelayed(Unit* owner, ObjectGuid casterGUID, const bool enterCombat, bool enablePVP) : _owner(owner), _casterGUID(casterGUID), _enterCombat(enterCombat), _enablePVP(enablePVP) { }
+
+ bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) override
+ {
+ if(!_owner)
+ return true;
+
+ Unit* caster = ObjectAccessor::GetUnit(*_owner, _casterGUID);
+ if (!caster)
+ return true;
+
+ // This will only cause combat - the target will engage once the projectile hits (in DoAllEffectOnTarget)
+ if (_enterCombat)
+ _owner->SetInCombatWith(caster);
+
+ if (_enablePVP && caster->ToPlayer())
+ caster->ToPlayer()->UpdatePvP(true);
+
+ return true;
+ }
+
+private:
+ Unit* _owner;
+ ObjectGuid _casterGUID;
+ bool _enterCombat;
+ bool _enablePVP;
+};
+
class ProcReflectDelayed : public BasicEvent
{
public:
@@ -2322,8 +2353,13 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
// Calculate hit result
WorldObject* caster = m_originalCaster ? m_originalCaster : m_caster;
+ Unit* unitCaster = m_caster->ToUnit();
targetInfo.MissCondition = caster->SpellHitResult(target, m_spellInfo, m_canReflect && !(IsPositive() && m_caster->IsFriendlyTo(target)));
+ // This will only cause combat - the target will engage once the projectile hits (in DoAllEffectOnTarget)
+ if (m_originalCaster && targetInfo.MissCondition != SPELL_MISS_EVADE && !m_originalCaster->IsFriendlyTo(target) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)) && (m_spellInfo->HasInitialAggro() || target->IsEngaged()))
+ m_originalCaster->SetInCombatWith(target, true);
+
// Spell have speed - need calculate incoming time
// Incoming time is zero for self casts. At least I think so.
if (m_caster != target)
@@ -2358,6 +2394,15 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
}
targetInfo.TimeDelay += uint64(std::floor(hitDelay * 1000.0f));
+
+ if (unitCaster && targetInfo.MissCondition != SPELL_MISS_EVADE)
+ {
+ bool enterCombat = !caster->IsFriendlyTo(target) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)) && (m_spellInfo->HasInitialAggro() || target->IsEngaged());
+ bool enablePVP = targetInfo.IsPVPEnabling();
+
+ if (enterCombat || enablePVP)
+ target->m_Events.AddEvent(new ProcImpactDelayed(target, m_originalCasterGUID, enterCombat, enablePVP), target->m_Events.CalculateTime(Milliseconds(targetInfo.TimeDelay)));
+ }
}
else
targetInfo.TimeDelay = 0ULL;
@@ -2366,7 +2411,7 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
if (targetInfo.MissCondition == SPELL_MISS_REFLECT)
{
// Calculate reflected spell result on caster (shouldn't be able to reflect gameobject spells)
- Unit* unitCaster = ASSERT_NOTNULL(m_caster->ToUnit());
+ ASSERT(unitCaster);
targetInfo.ReflectResult = unitCaster->SpellHitResult(unitCaster, m_spellInfo, false); // can't reflect twice
// Proc spell reflect aura when missile hits the original target
@@ -8181,10 +8226,6 @@ void Spell::DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, Spe
if (!unit)
return;
- // This will only cause combat - the target will engage once the projectile hits (in DoAllEffectOnTarget)
- if (m_originalCaster && targetInfo.MissCondition != SPELL_MISS_EVADE && !m_originalCaster->IsFriendlyTo(unit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)) && (m_spellInfo->HasInitialAggro() || unit->IsEngaged()))
- m_originalCaster->SetInCombatWith(unit);
-
m_damage = 0;
m_healing = 0;