diff options
author | Alan Deutscher <adeutscher@gmail.com> | 2022-07-10 18:55:15 -0700 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2022-09-05 22:23:02 +0200 |
commit | ff99952dfb7d2b532de2d1aedc825fb96038f4c2 (patch) | |
tree | 3d71265e0562a366e0d358ebfe20322ec1f51a97 /src/server/game/Spells/Spell.cpp | |
parent | a1ddf5195b8d03ea87248b7037a3e50e3e793d8e (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.cpp | 51 |
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; |