aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Unit/Unit.h6
-rw-r--r--src/server/game/Spells/Spell.cpp33
2 files changed, 36 insertions, 3 deletions
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index d950b89122a..79561280d05 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1662,6 +1662,12 @@ class TC_GAME_API Unit : public WorldObject
}
void AddChannelObject(ObjectGuid guid) { AddDynamicUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ChannelObjects)) = guid; }
void SetChannelObject(uint32 slot, ObjectGuid guid) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ChannelObjects, slot), guid); }
+ void RemoveChannelObject(ObjectGuid guid)
+ {
+ int32 index = m_unitData->ChannelObjects.FindIndex(guid);
+ if (index >= 0)
+ RemoveDynamicUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ChannelObjects), index);
+ }
void ClearChannelObjects() { ClearDynamicUpdateFieldValues(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ChannelObjects)); }
void SetCurrentCastSpell(Spell* pSpell);
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 988bd60921b..754e25011d7 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -992,7 +992,7 @@ void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTa
else
{
auto const& channelObjects = m_originalCaster->m_unitData->ChannelObjects;
- WorldObject* target = channelObjects.size() > 0 ? ObjectAccessor::GetWorldObject(*m_caster, *channelObjects.begin()) : nullptr;
+ WorldObject* target = !channelObjects.empty() ? ObjectAccessor::GetWorldObject(*m_caster, *channelObjects.begin()) : nullptr;
if (target)
{
CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
@@ -2883,7 +2883,10 @@ bool Spell::UpdateChanneledTargetList()
Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
if (!unit)
+ {
+ m_caster->RemoveChannelObject(ihit->targetGUID);
continue;
+ }
if (IsValidDeadOrAliveTarget(unit))
{
@@ -2895,11 +2898,15 @@ bool Spell::UpdateChanneledTargetList()
{
ihit->effectMask &= ~aurApp->GetEffectMask();
unit->RemoveAura(aurApp);
+ m_caster->RemoveChannelObject(ihit->targetGUID);
continue;
}
}
else // aura is dispelled
+ {
+ m_caster->RemoveChannelObject(ihit->targetGUID);
continue;
+ }
}
channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
@@ -4509,9 +4516,28 @@ void Spell::SendChannelStart(uint32 duration)
}
m_timer = duration;
+
+ uint32 channelAuraMask = 0;
+ uint32 explicitTargetEffectMask = 0xFFFFFFFF;
+ // if there is an explicit target, only add channel objects from effects that also hit ut
+ if (!m_targets.GetUnitTargetGUID().IsEmpty())
+ {
+ auto explicitTargetItr = std::find_if(m_UniqueTargetInfo.begin(), m_UniqueTargetInfo.end(), [&](TargetInfo const& target)
+ {
+ return target.targetGUID == m_targets.GetUnitTargetGUID();
+ });
+ if (explicitTargetItr != m_UniqueTargetInfo.end())
+ explicitTargetEffectMask = explicitTargetItr->effectMask;
+ }
+
+ for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA && (explicitTargetEffectMask & (1u << effect->EffectIndex)))
+ channelAuraMask |= 1 << effect->EffectIndex;
+
for (TargetInfo const& target : m_UniqueTargetInfo)
{
- m_caster->AddChannelObject(target.targetGUID);
+ if (target.effectMask & channelAuraMask)
+ m_caster->AddChannelObject(target.targetGUID);
if (m_UniqueTargetInfo.size() == 1 && m_UniqueGOTargetInfo.empty())
if(target.targetGUID != m_caster->GetGUID())
@@ -4521,7 +4547,8 @@ void Spell::SendChannelStart(uint32 duration)
}
for (GOTargetInfo const& target : m_UniqueGOTargetInfo)
- m_caster->AddChannelObject(target.targetGUID);
+ if (target.effectMask & channelAuraMask)
+ m_caster->AddChannelObject(target.targetGUID);
m_caster->SetChannelSpellId(m_spellInfo->Id);
m_caster->SetChannelVisual(m_SpellVisual);