mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16: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
|
class AnyAoEVisibleTargetUnitInObjectRangeCheck
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AnyAoEVisibleTargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range)
|
AnyAoEVisibleTargetUnitInObjectRangeCheck(WorldObject const* obj, WorldObject const* originalCaster, float range)
|
||||||
: i_obj(obj), i_funit(funit), i_range(range)
|
: i_obj(obj), i_originalCaster(originalCaster), i_range(range)
|
||||||
{
|
{
|
||||||
Unit const* check = i_funit;
|
i_targetForUnit = i_originalCaster->isType(TYPEMASK_UNIT);
|
||||||
Unit const* owner = i_funit->GetOwner();
|
i_targetForPlayer = (i_originalCaster->GetTypeId() == TYPEID_PLAYER);
|
||||||
if(owner)
|
|
||||||
check = owner;
|
|
||||||
i_targetForPlayer = ( check->GetTypeId()==TYPEID_PLAYER );
|
|
||||||
}
|
}
|
||||||
bool operator()(Unit* u)
|
bool operator()(Unit* u)
|
||||||
{
|
{
|
||||||
// Check contains checks for: live, non-selectable, non-attackable flags, flight check and GM check, ignore totems
|
// Check contains checks for: live, non-selectable, non-attackable flags, flight check and GM check, ignore totems
|
||||||
if (!u->isTargetableForAttack())
|
if (!u->isTargetableForAttack())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// ignore totems as AoE targets
|
||||||
if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isTotem())
|
if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isTotem())
|
||||||
return false;
|
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;
|
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 true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
bool i_targetForUnit;
|
||||||
bool i_targetForPlayer;
|
bool i_targetForPlayer;
|
||||||
WorldObject const* i_obj;
|
WorldObject const* i_obj;
|
||||||
Unit const* i_funit;
|
WorldObject const* i_originalCaster;
|
||||||
float i_range;
|
float i_range;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1660,7 +1660,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Unit* pUnitTarget = m_targets.getUnitTarget();
|
Unit* pUnitTarget = m_targets.getUnitTarget();
|
||||||
Unit* originalCaster = GetAffectiveCaster();
|
WorldObject* originalCaster = GetAffectiveCasterObject();
|
||||||
if(!pUnitTarget || !originalCaster)
|
if(!pUnitTarget || !originalCaster)
|
||||||
break;
|
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
|
WorldObject* Spell::GetCastingObject() const
|
||||||
{
|
{
|
||||||
if (m_originalCasterGUID.IsGameobject())
|
if (m_originalCasterGUID.IsGameobject())
|
||||||
|
|
|
||||||
|
|
@ -475,7 +475,9 @@ class Spell
|
||||||
// caster types:
|
// caster types:
|
||||||
// formal spell caster, in game source of spell affects cast
|
// formal spell caster, in game source of spell affects cast
|
||||||
Unit* GetCaster() const { return m_caster; }
|
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; }
|
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
|
// m_originalCasterGUID can store GO guid, and in this case this is visual caster
|
||||||
WorldObject* GetCastingObject() const;
|
WorldObject* GetCastingObject() const;
|
||||||
|
|
@ -656,7 +658,7 @@ namespace MaNGOS
|
||||||
SpellNotifierPlayer(Spell &spell, std::list<Unit*> &data, const uint32 &i, float radius)
|
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_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)
|
void Visit(PlayerMapType &m)
|
||||||
|
|
@ -694,7 +696,7 @@ namespace MaNGOS
|
||||||
SpellTargets TargetType = SPELL_TARGETS_NOT_FRIENDLY)
|
SpellTargets TargetType = SPELL_TARGETS_NOT_FRIENDLY)
|
||||||
: i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_TargetType(TargetType)
|
: 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;
|
i_playerControled = i_originalCaster ? i_originalCaster->IsControlledByPlayer() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "9849"
|
#define REVISION_NR "9850"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue