aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2016-10-11 22:01:42 -0300
committerjoschiwald <joschiwald.trinity@gmail.com>2017-09-06 11:06:03 +0200
commit9106c0f27208cc2eb15626e975b929edbf62ad84 (patch)
tree55ce714368a310cd180608a95cf5ff33b45a4207
parent09d6cc46013426d58d2b3a1246c168baa3587ec5 (diff)
Core/Auras: don't ignore SPELL_ATTR3_ONLY_TARGET_PLAYERS in area auras.
Also, start abusing the arbitrary containers for searchers introduced in 8775f8b28a5ad4403371577787131ff81f14332b (cherry picked from commit 449ec0d6ff74ccd1874bc09073353d97c1d0151c)
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h22
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp90
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h6
3 files changed, 63 insertions, 55 deletions
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index 98010ddf2cd..7aeb6ead6ff 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -28,6 +28,7 @@
#include "Packet.h"
#include "Player.h"
#include "Spell.h"
+#include "SpellInfo.h"
#include "UnitAI.h"
#include "UpdateData.h"
@@ -912,10 +913,13 @@ namespace Trinity
class AnyGroupedUnitInObjectRangeCheck
{
public:
- AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid) : _source(obj), _refUnit(funit), _range(range), _raid(raid) { }
+ AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid, bool playerOnly = false) : _source(obj), _refUnit(funit), _range(range), _raid(raid), _playerOnly(playerOnly) { }
bool operator()(Unit* u) const
{
+ if (_playerOnly && u->GetTypeId() != TYPEID_PLAYER)
+ return false;
+
if (_raid)
{
if (!_refUnit->IsInRaidWith(u))
@@ -932,6 +936,7 @@ namespace Trinity
Unit const* _refUnit;
float _range;
bool _raid;
+ bool _playerOnly;
};
class AnyUnitInObjectRangeCheck
@@ -983,11 +988,12 @@ namespace Trinity
class AnyAoETargetUnitInObjectRangeCheck
{
public:
- AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range)
- : i_obj(obj), i_funit(funit), _spellInfo(NULL), i_range(range)
+ AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, SpellInfo const* spellInfo = nullptr)
+ : i_obj(obj), i_funit(funit), _spellInfo(spellInfo), i_range(range)
{
- if (DynamicObject const* dynObj = i_obj->ToDynObject())
- _spellInfo = dynObj->GetSpellInfo();
+ if (!_spellInfo)
+ if (DynamicObject const* dynObj = i_obj->ToDynObject())
+ _spellInfo = dynObj->GetSpellInfo();
}
bool operator()(Unit* u) const
@@ -996,10 +1002,10 @@ namespace Trinity
if (u->GetTypeId() == TYPEID_UNIT && u->IsTotem())
return false;
- if (i_funit->_IsValidAttackTarget(u, _spellInfo, i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT ? i_obj : NULL) && i_obj->IsWithinDistInMap(u, i_range))
- return true;
+ if (_spellInfo && _spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS) && u->GetTypeId() != TYPEID_PLAYER)
+ return false;
- return false;
+ return i_funit->_IsValidAttackTarget(u, _spellInfo, i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT ? i_obj : nullptr) && i_obj->IsWithinDistInMap(u, i_range);
}
private:
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index ce7e2bec628..a84e8a1fcdd 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -515,37 +515,37 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
m_updateTargetMapInterval = UPDATE_TARGET_MAP_INTERVAL;
// fill up to date target list
- // target, effMask
- std::map<Unit*, uint32> targets;
+ // target, effMask
+ std::unordered_map<Unit*, uint32> targets;
FillTargetMap(targets, caster);
- UnitList targetsToRemove;
+ std::deque<Unit*> targetsToRemove;
// mark all auras as ready to remove
for (ApplicationMap::iterator appIter = m_applications.begin(); appIter != m_applications.end();++appIter)
{
- std::map<Unit*, uint32>::iterator existing = targets.find(appIter->second->GetTarget());
+ auto itr = targets.find(appIter->second->GetTarget());
// not found in current area - remove the aura
- if (existing == targets.end())
+ if (itr == targets.end())
targetsToRemove.push_back(appIter->second->GetTarget());
else
{
// needs readding - remove now, will be applied in next update cycle
// (dbcs do not have auras which apply on same type of targets but have different radius, so this is not really needed)
- if (appIter->second->GetEffectMask() != existing->second || !CanBeAppliedOn(existing->first))
+ if (appIter->second->GetEffectMask() != itr->second || !CanBeAppliedOn(itr->first))
targetsToRemove.push_back(appIter->second->GetTarget());
// nothing todo - aura already applied
// remove from auras to register list
- targets.erase(existing);
+ targets.erase(itr);
}
}
// register auras for units
- for (std::map<Unit*, uint32>::iterator itr = targets.begin(); itr!= targets.end();)
+ for (auto itr = targets.begin(); itr!= targets.end();)
{
// aura mustn't be already applied on target
- if (AuraApplication * aurApp = GetApplicationOfTarget(itr->first->GetGUID()))
+ if (AuraApplication* aurApp = GetApplicationOfTarget(itr->first->GetGUID()))
{
// the core created 2 different units with same guid
// this is a major failue, which i can't fix right now
@@ -555,7 +555,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
if (aurApp->GetTarget() != itr->first)
{
// remove from auras to register list
- targets.erase(itr++);
+ itr = targets.erase(itr);
continue;
}
else
@@ -609,7 +609,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
}
}
if (!addUnit)
- targets.erase(itr++);
+ itr = targets.erase(itr);
else
{
// owner has to be in world, or effect has to be applied to self
@@ -627,17 +627,17 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
}
// remove auras from units no longer needing them
- for (UnitList::iterator itr = targetsToRemove.begin(); itr != targetsToRemove.end();++itr)
- if (AuraApplication * aurApp = GetApplicationOfTarget((*itr)->GetGUID()))
- (*itr)->_UnapplyAura(aurApp, AURA_REMOVE_BY_DEFAULT);
+ for (Unit* unit : targetsToRemove)
+ if (AuraApplication* aurApp = GetApplicationOfTarget(unit->GetGUID()))
+ unit->_UnapplyAura(aurApp, AURA_REMOVE_BY_DEFAULT);
if (!apply)
return;
// apply aura effects for units
- for (std::map<Unit*, uint32>::iterator itr = targets.begin(); itr!= targets.end();++itr)
+ for (auto itr = targets.begin(); itr!= targets.end(); ++itr)
{
- if (AuraApplication * aurApp = GetApplicationOfTarget(itr->first->GetGUID()))
+ if (AuraApplication* aurApp = GetApplicationOfTarget(itr->first->GetGUID()))
{
// owner has to be in world, or effect has to be applied to self
ASSERT((!GetOwner()->IsInWorld() && GetOwner() == itr->first) || GetOwner()->IsInMap(itr->first));
@@ -2285,17 +2285,18 @@ void UnitAura::Remove(AuraRemoveMode removeMode)
GetUnitOwner()->RemoveOwnedAura(this, removeMode);
}
-void UnitAura::FillTargetMap(std::map<Unit*, uint32> & targets, Unit* caster)
+void UnitAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit* caster)
{
for (SpellEffectInfo const* effect : GetSpellEffectInfos())
{
if (!effect || !HasEffect(effect->EffectIndex))
continue;
- UnitList targetList;
+
+ std::deque<Unit*> units;
// non-area aura
if (effect->Effect == SPELL_EFFECT_APPLY_AURA)
{
- targetList.push_back(GetUnitOwner());
+ units.push_back(GetUnitOwner());
}
else
{
@@ -2308,48 +2309,48 @@ void UnitAura::FillTargetMap(std::map<Unit*, uint32> & targets, Unit* caster)
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
{
- targetList.push_back(GetUnitOwner());
- Trinity::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, effect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID);
- Trinity::UnitListSearcher<Trinity::AnyGroupedUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
+ units.push_back(GetUnitOwner());
+ Trinity::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, effect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS));
+ Trinity::UnitListSearcher<Trinity::AnyGroupedUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
Cell::VisitAllObjects(GetUnitOwner(), searcher, radius);
break;
}
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
{
- targetList.push_back(GetUnitOwner());
- Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius);
- Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
+ units.push_back(GetUnitOwner());
+ Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS));
+ Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
Cell::VisitAllObjects(GetUnitOwner(), searcher, radius);
break;
}
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
{
- Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius); // No GetCharmer in searcher
- Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
+ Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo); // No GetCharmer in searcher
+ Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
Cell::VisitAllObjects(GetUnitOwner(), searcher, radius);
break;
}
case SPELL_EFFECT_APPLY_AREA_AURA_PET:
- targetList.push_back(GetUnitOwner());
+ units.push_back(GetUnitOwner());
// no break
case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
{
if (Unit* owner = GetUnitOwner()->GetCharmerOrOwner())
if (GetUnitOwner()->IsWithinDistInMap(owner, radius))
- targetList.push_back(owner);
+ units.push_back(owner);
break;
}
}
}
}
- for (UnitList::iterator itr = targetList.begin(); itr!= targetList.end();++itr)
+ for (Unit* unit : units)
{
- std::map<Unit*, uint32>::iterator existing = targets.find(*itr);
- if (existing != targets.end())
- existing->second |= 1 << effect->EffectIndex;
+ auto itr = targets.find(unit);
+ if (itr != targets.end())
+ itr->second |= 1 << effect->EffectIndex;
else
- targets[*itr] = 1 << effect->EffectIndex;
+ targets[unit] = 1 << effect->EffectIndex;
}
}
}
@@ -2379,7 +2380,7 @@ void DynObjAura::Remove(AuraRemoveMode removeMode)
_Remove(removeMode);
}
-void DynObjAura::FillTargetMap(std::map<Unit*, uint32> & targets, Unit* /*caster*/)
+void DynObjAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit* /*caster*/)
{
Unit* dynObjOwnerCaster = GetDynobjOwner()->GetCaster();
float radius = GetDynobjOwner()->GetRadius();
@@ -2388,28 +2389,29 @@ void DynObjAura::FillTargetMap(std::map<Unit*, uint32> & targets, Unit* /*caster
{
if (!effect || !HasEffect(effect->EffectIndex))
continue;
- UnitList targetList;
+
+ std::deque<Unit*> units;
if (effect->TargetB.GetTarget() == TARGET_DEST_DYNOBJ_ALLY
|| effect->TargetB.GetTarget() == TARGET_UNIT_DEST_AREA_ALLY)
{
- Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
- Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetDynobjOwner(), targetList, u_check);
+ Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS));
+ Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetDynobjOwner(), units, u_check);
Cell::VisitAllObjects(GetDynobjOwner(), searcher, radius);
}
else
{
Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
- Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(GetDynobjOwner(), targetList, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(GetDynobjOwner(), units, u_check);
Cell::VisitAllObjects(GetDynobjOwner(), searcher, radius);
}
- for (UnitList::iterator itr = targetList.begin(); itr!= targetList.end();++itr)
+ for (Unit* unit : units)
{
- std::map<Unit*, uint32>::iterator existing = targets.find(*itr);
- if (existing != targets.end())
- existing->second |= 1 << effect->EffectIndex;
+ auto itr = targets.find(unit);
+ if (itr != targets.end())
+ itr->second |= 1 << effect->EffectIndex;
else
- targets[*itr] = 1 << effect->EffectIndex;
+ targets[unit] = 1 << effect->EffectIndex;
}
}
}
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index 4682f2df84f..31842d8c6d4 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -147,7 +147,7 @@ class TC_GAME_API Aura
void _Remove(AuraRemoveMode removeMode);
virtual void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) = 0;
- virtual void FillTargetMap(std::map<Unit*, uint32> & targets, Unit* caster) = 0;
+ virtual void FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit* caster) = 0;
void UpdateTargetMap(Unit* caster, bool apply = true);
void _RegisterForTargets() {Unit* caster = GetCaster(); UpdateTargetMap(caster, false);}
@@ -349,7 +349,7 @@ class TC_GAME_API UnitAura : public Aura
void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override;
- void FillTargetMap(std::map<Unit*, uint32> & targets, Unit* caster) override;
+ void FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit* caster) override;
// Allow Apply Aura Handler to modify and access m_AuraDRGroup
void SetDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; }
@@ -367,7 +367,7 @@ class TC_GAME_API DynObjAura : public Aura
void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override;
- void FillTargetMap(std::map<Unit*, uint32> & targets, Unit* caster) override;
+ void FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit* caster) override;
};
class TC_GAME_API ChargeDropEvent : public BasicEvent