diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index c3b3f0509..46b51eb95 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -821,34 +821,36 @@ namespace MaNGOS class AnyAoEVisibleTargetUnitInObjectRangeCheck { public: - AnyAoEVisibleTargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) - : i_obj(obj), i_funit(funit), i_range(range) + AnyAoEVisibleTargetUnitInObjectRangeCheck(WorldObject const* obj, WorldObject const* originalCaster, float range) + : i_obj(obj), i_originalCaster(originalCaster), i_range(range) { - Unit const* check = i_funit; - Unit const* owner = i_funit->GetOwner(); - if(owner) - check = owner; - i_targetForPlayer = ( check->GetTypeId()==TYPEID_PLAYER ); + i_targetForUnit = i_originalCaster->isType(TYPEMASK_UNIT); + i_targetForPlayer = (i_originalCaster->GetTypeId() == TYPEID_PLAYER); } bool operator()(Unit* u) { // Check contains checks for: live, non-selectable, non-attackable flags, flight check and GM check, ignore totems if (!u->isTargetableForAttack()) return false; + + // ignore totems as AoE targets if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isTotem()) return false; - if (!u->isVisibleForOrDetect(i_funit, i_funit, false)) + + // check visibility only for unit-like original casters + if (i_targetForUnit && !u->isVisibleForOrDetect((Unit const*)i_originalCaster, i_originalCaster, false)) return false; - if(( i_targetForPlayer ? !i_funit->IsFriendlyTo(u) : i_funit->IsHostileTo(u) )&& i_obj->IsWithinDistInMap(u, i_range)) + if ((i_targetForPlayer ? !i_originalCaster->IsFriendlyTo(u) : i_originalCaster->IsHostileTo(u)) && i_obj->IsWithinDistInMap(u, i_range)) return true; return false; } private: + bool i_targetForUnit; bool i_targetForPlayer; WorldObject const* i_obj; - Unit const* i_funit; + WorldObject const* i_originalCaster; float i_range; }; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 9ee5f8244..c9c334372 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1660,7 +1660,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& else { Unit* pUnitTarget = m_targets.getUnitTarget(); - Unit* originalCaster = GetAffectiveCaster(); + WorldObject* originalCaster = GetAffectiveCasterObject(); if(!pUnitTarget || !originalCaster) break; @@ -6486,6 +6486,16 @@ void Spell::FillRaidOrPartyHealthPriorityTargets(UnitList &targetUnitMap, Unit* } } +WorldObject* Spell::GetAffectiveCasterObject() const +{ + if (m_originalCasterGUID.IsEmpty()) + return m_caster; + + if (m_originalCasterGUID.IsGameobject() && m_caster->IsInWorld()) + return m_caster->GetMap()->GetGameObject(m_originalCasterGUID); + return m_originalCaster; +} + WorldObject* Spell::GetCastingObject() const { if (m_originalCasterGUID.IsGameobject()) diff --git a/src/game/Spell.h b/src/game/Spell.h index 85e8defc2..c9f394923 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -475,7 +475,9 @@ class Spell // caster types: // formal spell caster, in game source of spell affects cast Unit* GetCaster() const { return m_caster; } - // real source of cast affects, explcit caster, or DoT/HoT applier, or GO owner, etc. Can be NULL + // real source of cast affects, explcit caster, or DoT/HoT applier, or GO owner, or wild GO itself. Can be NULL + WorldObject* GetAffectiveCasterObject() const; + // limited version returning NULL in cases not Unit* caster object, need for Aura (auras currently not support non-Unit caster) Unit* GetAffectiveCaster() const { return !m_originalCasterGUID.IsEmpty() ? m_originalCaster : m_caster; } // m_originalCasterGUID can store GO guid, and in this case this is visual caster WorldObject* GetCastingObject() const; @@ -656,7 +658,7 @@ namespace MaNGOS SpellNotifierPlayer(Spell &spell, std::list &data, const uint32 &i, float radius) : i_data(data), i_spell(spell), i_index(i), i_radius(radius) { - i_originalCaster = i_spell.GetCastingObject(); + i_originalCaster = i_spell.GetAffectiveCasterObject(); } void Visit(PlayerMapType &m) @@ -694,7 +696,7 @@ namespace MaNGOS SpellTargets TargetType = SPELL_TARGETS_NOT_FRIENDLY) : i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_TargetType(TargetType) { - i_originalCaster = spell.GetCastingObject(); + i_originalCaster = i_spell.GetAffectiveCasterObject(); i_playerControled = i_originalCaster ? i_originalCaster->IsControlledByPlayer() : false; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index a9cdef1cd..a023e0350 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9849" + #define REVISION_NR "9850" #endif // __REVISION_NR_H__