mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 07:37:01 +00:00
[9850] Fixed target selection for area spells casted from aura at enemy.
* Spell::GetCastingObject must be use for selection visual/point cast, not for friend/enemy checks. Add extanded GetAffectiveCasterObject for proper provide for referecned checks wild gameobject casted case. * Also support chain damage spells casted by gameobjects.
This commit is contained in:
parent
d1130af777
commit
921b0d668f
4 changed files with 29 additions and 15 deletions
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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<Unit*> &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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "9849"
|
||||
#define REVISION_NR "9850"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue